Designing Reusable UI Components in Sciter. Color-chooser, part I.

Color chooser screenshotThis is a start of a sequence of articles explaining design and architecture of reusable components (a.k.a. scripting behaviors) in Sciter.

First of all small specification. We need a component in HTML allowing user to select and apply color.

  • Such control shall be defined in HTML as:

    < input type="color-chooser" />

  • This input element shall have value property that represents current color. Value is a string "#RRGGBB".

  • Color chooser shall allow to select color from palette and "apply" color to e.g. some selection in the text in some editor. So it shall generate two events:

    • onColorChanged – when user have changed current color;

    • onClick – either user have changed color or clicked on apply arrea ("apply" sub-button).

  • Visually such control shall look like as two buttons – one will play a role of "apply" button and other will cause popup window with palette to appear – play role of "popup" button.

Next article will explain structure of the code on the first stage of color-chooser implementation: sdk/lib/color-chooser.tis. You may see demo page of the component is sdk/samples/tests/basics/test-color-chooser.htm.

Windowless HTMLayout

Build # of HTMLayout contains new set of API functions allowing to use htmlayout in windowless mode.

There are cases where such windowless mode (to be precise HWND-less) is needed.

Think about games. They use DirectX surfaces and implement window or view structures internally. Now HTML can be used inside such internal views.

What the hell is that JSON-DB?

JSON-DB… You can, probably, guess that it’s a compound word, which consists of JSON and DB (database). And you are absolutely right! It’s a way to save javascript objects in a persistent storage.

Let’s imagine that you have a state object in javascript, which you’d love to persist. And the state consists of different objects of different types. Wouldn’t be nice to say:

db.state = state;

Or, alternatively restore the same state with:

var state = db.state;

Do you like it? How about:

db.messages[key] = 
     text: "Hello world!",
     id: 456,
     author: authorObj;

Thus, if JSON helps you to get data and easily evaluate into native javascript objects, JSON-DB allows you to seamlessly work with persistent data in javascript. Any scripting object can be persisted in the database and there is no need to use special entities like recordset, field, etc.

JSON-DB (a.k.a. persistent storage) is implemented in version 2.0 of TiScript engine:

  1. supports up to 2 GB storage size.
  2. supports transactions: commit/rollback
  3. uses lazy reads, e.g. only top level objects are loaded physically. Objects are loaded from storage on demand.
  4. storage supports indexes: storage.createIndex( String | Integer | Float ). Index object supports effective index access: [key] and range [ key1 .. key2 ]. Indexes use effective B+Tree algorithm.
  5. TiScript extended by two additional core objects: Storage and Index. Objects and Arrays got storage attribute referring to the Storage the object stored in (if any)

Persistent Storage implementation in TiScript is based on Konstantin’s Knizhnik excellent DyBase library modified to support TiScript “natively”.

Eval, JSON and curly braces.

Say, you have JSON data (object literal) stored as a string somewhere:

  "{ one:1, two:2 }"

and you want to parse (convert) this string into scripting object.

Obvious solution for this would be to write something like this:

  var dataStr = "{ one:1, two:2 }";
  var data = eval( dataStr );

Looks nice and simple but will not work. To make it work you need to wrap your string in ( ) brackets:

  var dataStr = "(" + "{ one:1, two:2 }" + ")";
  var data = eval( dataStr );

Reason is simple and I’ll try to explain it using plain words:

eval accepts sequence of statements of JavaScript and at this level JavaScript parser
interprets ‘{‘ token as a start of a block and not a start of an object literal.

When you will enclose your literal into () brackets like this: ({ one:1, two:2 })
you are switching JavaScript parser into expression parsing mode. Token ‘{‘ inside expression means start of object literal declaration so JavaScript will accept it.