Generator functions in Sciter and tiscript.

Generator function is a function that produce sequence of values. Each call of such function returns next value of some sequence.

Here is one possible implementation of generator function that can be used in Sciter. Idea of this implementation is borrowed from LUA programming language.

Let’s say we would like to enumerate some array in backward direction using for( .. in .. ) statement:

var a = [0,1,2,3,4,5,6,7,8,9];

for(var n in backward(a)) 
    stdout.printf("%d\n", n);

Here is an implementation of such backward() function:

    function backward(a)
      var n = a.length;
      return function() { if(--n >= 0) return a[n]; }

As you may see this function initializes n variable and returns reference to the inner function.
This inner function will supply next value on each its invocation. In this example it will return a[–n] (previous element of the array) or nothing.
This implementation employs the fact that inner function has access to local variables of outer function – closure in other words.

To be able to support this in the language I have extended for(var el in collection) statement.
So collection object here can be function, array and object.

Built-in Drag and Drop support in h-smile core

As far as I understand there are two distinct drag-n-drop mechanisms:

  • Global drag-n-drop when objects are dragged from one window/application on desktop to another. In most cases this is very close to clipboard cut-n-paste but with some additional visualization.
  • Window local drag-n-drop when objects are dragged inside single window/form. For example some shopping cart implementation.

I have added support of latter one to the h-smile core – local drag-n-drop of DOM elements. Details are here.

Consider following task:

For these two select elements:

<select id="source" size="5">
<select id="destination" size="5"></select>

we would like to provide ability to drag <option> elements from #source element to the #destination. In case of htmlayout or the Sciter (both are based on h-smile core) it is enough to write following:

   select#source > option
      dragging: only-move; /* we can only move options out here*/ 
      accept-drag: selector( select#source > option ); 
                  /* we accept only options from select#source*/ 
      drop: append; 
                 /* order of items is not relevant, 
                     always append dropped option */

and this is it – our users now are able to drag items from first <select> to second.

But what about one of main principles of good UI design – “discoverability”? User should have a visual clue while dragging: where and when he/she can drop dragged item. Following additional pseudo-classes will help us in this tasks:

   option:moving /* moving (dragging ) option */
      background:blue; color:white;
   select:drop-target /* active drop target element(s) */
      background: yellow; 
      /* after D&D operation was started all active drop-targets 
          will be highlighted by yellow color */ 
   select:drag-over /* drop target element under the dragged item.*/
      outline: 1px solid green; 
      /* green outline to show that at current mouse position  
          dragged element can be dropped in this particular drop-target */ 

And that is all we need to enable drag-n-drop in our application.

Oh, forgot to add: what if we need to drag options in both directions – from #destination back to the #source? The same simple idea:

   select#destination > option
      dragging: only-move;  
      accept-drag: selector( select#destination > option ); 
      drop: append; 

And one small piece left: drop:recycle will declare element it is applied to (drop-target) as a “black hole” – all items dropped here will be deleted.