Memory leak alike condition in script

Consider the following simple markup:

<div.collapsible>
  ...
  <widget.myAspect>...</widget>
</div>

and let’s assume that a) content of this div changes dynamically and widget.myAspect uses the following aspect:

function MyAspect() {
   var container = this.$p(div.collapsible);
   var me = this;
   container.on("collapse", function Foo() { 
      me.doSomething();
   });
}

Note that each time you create <widget.myAspect> the aspect function gets called and  brand new “collapse” event subscription (new instance of function Foo above) gets added to div.collapsible.  Therefore list of subscriptions will grow consuming more and more memory on each DOM change inside the div. Even worse – inner function is a closure that holds me – variable that contains instance of DOM element. So after some time the memory will hold a number of disconnected DOM elements as a pure garbage.

Yes, when the div.collapsible will be removed from the DOM or the window will be destroyed or document reloaded all these dead objects will be freed, but until then your application will demonstrate memory leak alike dynamic.

Thus pay attention on components that subscribe itself to parent’s events. If you do have such situations then consider use of behavior classes instead of aspects and unsubscribe event handlers in detached method. Yet there are other options for that.

no responses

6 reasons why await blows promises away

Article by Mostafa Gaafar that defines benefits of await versus promises.

This is applicable to Sciter’s script too as it supports await, but note async modifier is not required in Sciter – function that contains await statement is asynchronous by default:

const makeRequest = function() {
  const data = await getJSON()
  if (data.needsAnotherRequest) {
    const moreData = await makeAnotherRequest(data);
    return moreData;
  } else {
    return data;
  }
}
no responses

GC in Sciter’s Script

Excellent article by Ken Fox outlining architecture of different Garbage Collection strategies.

Sciter’s script uses “Copying Collector”. Its work is visualized as:

Copying GC at work

And DOM (tree of objects without cycles) is using Reference Counting that reflects in external native DOM API by pair of SciterUseElement and SciterUnUseElement (a.k.a. AddRef/Release).

no responses
no responses

Sciter for AngularJS practitioners. Directives.

Directives in AngularJS

From AngularJS documentation :

At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.

And here is a typical AngularJS directive implementation:

app.directive('myCustomer', function() {
  return {
    template: 'Name: {{name}} Address: {{address}}', // content
    scope: { name:"", address:"" },  // internal data model
    link: function(scope, elem, attrs) { // initialization 
      elem.bind('click', function() { ... });
      elem.bind('dblclick', function() { ... });
    }
  };
});

It says that each <my-customer> element will have

  • Name: ... Address: ... content;
  • click and dblclick event handlers.

In Sciter

Behaviors

Declarative code-to-element binding in Sciter is made by CSS. Sciter’s prototype property is used for that purpose:

my-customer {
  prototype: MyCustomer url(my-customer.tis);
  display: block;
  ...
}

In plain text: all <my-customer> elements are rendered as block element and will have class MyCustomer assigned to them.  The class will be loaded from my-customer.tis file (if it was not loaded before):

class MyCustomer : Element 
{
  function attached() // called when element gets this class - "link" in terms of Angular 
  {
     // content initialization: 
     this.$content(Name: <output.name/> Address: <output.address/>);
  }
  // event handlers:
  event click { ... /* 'this' here is the element*/ }
  event dblclick { ... }
}

As the code is assigned by CSS then you can use full power of CSS selectors to assign code classes to elements.

Aspects

Another option to bind code with elements is to use so called aspects. Aspect here is just a script function that gets executed when its selector matched the element first time:

[collapsible] { aspect: Collapsible url(my-aspects.tis); }
[collapsible]:collapsed > :last-child { display:none; } // last child is invisible when collapsed

And Collapsible here is a simple function that handles click event and triggers :collapsed state flag switch:

function Collapsible() { 
  this << event click {
     if( this.state.collapsed ) this.state.expanded = true;
     else this.state.collapsed = true;    
  }
}

Having such aspect defined we can define collapsible element:

<div collapsible>
  click here to see content
  <p>Content</p>
</div>

So if you have multiple collapsible sections in your design then just add “collapsible” attribute to them.

one response

New blocknote.net application is getting its shape.

My Blocknote.net editor is getting new shape.

BN is an editor “for the rest of us on the Net” – simple WYSIWYG editor producing clean HTML that is ready to be embedded into blogs, emails, etc.

It is an editor for “Internet writers” people who produce content and so need humanistic tool rather than plain text editor with cryptic HTML or even Markdown.

BN2

Some editing tasks are easy to do in source code though. So BN supports source code view with transparent selection – text selected in WYSIWYG will be selected in source and vice versa:

BN2

3 responses

Sciter Script, hidden treasures

There is otherwise keyword in script that is used in loop statements so this:

var emptyArr = [];

for(var el in emptyArr)
  stdout.println(el);
otherwise
  stdout.println("nothing seen, array is empty!");

will print nothing seen, array is empty!.

Statement or block after otherwise will be executed if body of the loop was not executed.

no responses

Sciter technology survey

Ramon, author of Omni/OmniCode from MI Software, is making a survey about how people are using Sciter technology.

In return he is promising to provide licenses of his products to those who participated in survey.

Survey: goo.gl/forms/BKGHVjTGBTEIVMl02

More info is on misoftware.rs site.

Hope you can participate and help him to get that information.

no responses

+plus and +formation, what’s the difference?

+plus

+plus is the way to define and support mapping between DOM tree and data tree rooted at some object or namespace. So if you have these two declarations, markup:

<style>@import url(plus.css)</style>
<section model="person">
    <label>First</label> <input(name.first)>
    <label>Second</label> <input(name.last)>
    <label>Age</label> <input|integer(age)>
</section>

and script

namespace person {
  var name = { first: "Albert", last:"Einshtein" };
  var age = 53;
}

then the +plus will establish live two-way mapping (binding)  between DOM elements above and the data structure.

When the user changes value of input(name.first) field  (short form of <input name="name.first"> in Sciter) the following happens:

  1. Sciter generates “change” DOM event;
  2. +plus handles that event and
  3. updates value of person.name.first in data namespace.

And when data gets changed by some other code like

person.name.first = "Some other name";

then pretty much similar flow occurs:

  1. Sciter determines that filed first  has changed on observable object.
  2. Sciter calls attached function-observer – each object/array inside bound namespace has an observer function attached to it.
  3. And that function-observer updates bound DOM element.

As you see, in order binding to work both-ways, each data node (object, array) in bound namespace has to have corresponding observer attached to it.

+formation

The main difference from the above is that the +formation does not require separate data structure.  The formation is a data structure by itself naturally mapped to markup structure.

This markup:

<section(person)>
    <label>First</label> <input(name.first)>
    <label>Second</label> <input(name.last)>
    <label>Age</label> <input|integer(age)>
</section

gets mapped by formation() function to the [formation] tree structure:

And code can access that tree directly as:

var root = formation( self );
// setting whole formation:
root.person.value = {
   name : {
     first: "Albert",
     last: "Einshtein"
   },
   age:69
 };

// or setting particular field in the formation:
root.person.name.first.value = "Some other name";

Note: root.person.name.first is a direct reference to <input> DOM element thus .value is required.

The formation is a data structure derived from actual DOM tree (its projection)  and so you can use normal DOM events to be notified when some data changes by the user:

root.person.name.first.on("change", function() {...}) // or
self.on("change", "section[name=person]", function() {...}) // any change in person fields.

Resume

Essentially +plus and +formation are aimed to the same task – update UI from code and update/notify code about some changes in UI.

  • +plus
    • pros: Allows to bind arbitrary data structure to arbitrary DOM tree.
    • cons: Can be memory and CPU consuming on large data and DOM trees.
  • +formation
    • pros: Fast and not CPU consuming.  Yet allows to access “fields of interest” by using dot notation (“paths in formation”):  root.person.name.first.state.disabled = true;
    • cons: data structure you get (the formation tree) is bound with DOM structure. So when you change DOM structure then  formation paths in code may change.
no responses

Better use of style @set’s

In next version (4.0.0.2 and above) I am changing the way of how @set’s are applied in user’s style sheet.

Style sets will be applied before any other rules in the same style sheet.

So if you have

@set MySet {
  :root { color:red; width:*; }
}

myelement { style-set: MySet; }

And later define

myelement#test {
  color:blue;
}

then <myelement id=test>...</myelement> element will have blue color.

So you can think of style sets as definition of default styles. Ordinary CSS rules are applied on top of them allowing to style concrete elements.

no responses