Cheap CSS implementations?

September 2, 2010

Filed under: HTML and CSS — Andrew @ 1:26 pm

CSS3 defines [att=val] selectors . And they work in all modern browsers in static form.

But when you will try to use such a selector with attributes changed from script you will get problems.

Following works as expected in FF but does not work in Google Chrome and Opera:

<html>
<head>
  <style>

    div { display:none; }
    body[show="n1"] #n1 { display:block; }
    body[show="n2"] #n2 { display:block; }

  </style>
  <script type="text/javascript">

    function test()
    {
      document.body.setAttribute("show","n2");
    }

  </script>
</head>
<body show="n1">
  <a href="javascript:test()">Test</a>
  <div id="n1">1</div>
  <div id="n2">2</div>
</body>
</html>

I am wondering why Opera and WebKit implementations are failed on this simple test.
As for my [educated] knowledge attribute value selector has the same complexity as e.g. class selector in CSS. No idea to be honest.

C++, how to change class of object in runtime.

August 12, 2010

Filed under: How-to, Source code — Andrew @ 4:06 pm

There is a nice feature in TIScript that allows to change class of already instantiated object.
Let’s say we have two classes:

class MyWidget : Behavior { ... }
class MyWidgetReadonly : Behavior { ... }

that handle user interaction with some widget on the screen. This widget can operate in two distinct modes: normal and read-only.
These modes share the same widget state but have substantially different behavioral characteristic. So it makes sense to split these two sets of methods into two classes to avoid pollution of our code by the crowd of if(readonly) ... else ....
When needed we can switch class of the object like this:

var widget = new MyWidget();
....
if( needReadOnlyMode )
  widget.prototype = MyWidgetReadonly; // changing class of the object.
...

Pretty much all dynamic languages allow to do such things. E.g. in Python you can modify obj.__bases__.

Surprisingly you can do the same in C++ too and without any “hack”. We can use so called placement new operator to do the trick. Here is how.

Let’s define our class hierarchy as this:

class MyWidget
{
public:
  int data;  // state variables here
  virtual void on_mouse() { printf("normal on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("normal on_key\n"); }
};
class MyWidgetReadOnly: public MyWidget
{
  // no data at all here, sic!
  virtual void on_mouse() { printf("read-only on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("read-only on_key\n"); }
};

And we will switch class of our object using this helper template function:

// turn_to(A* obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
  inline void turn_to(FROM_T* p)
  {
    assert( sizeof(FROM_T) == sizeof(TO_T));
    ::new(p) TO_T(); // use of placement new
  }

Note: This will work if our class has default constructor that does not initialize any member variables.

Let’s try this small sample ( test.cpp ):

#include <new>
#include <assert.h>
// turn_to(A* obj) changes class of the object
// that means it just replaces VTBL of the object by VTBL of another class.
// NOTE: these two classes has to be ABI compatible!
template <typename TO_T, typename FROM_T>
  inline void turn_to(FROM_T* p)
  {
    assert( sizeof(FROM_T) == sizeof(TO_T));
    ::new(p) TO_T(); // use of placement new
  }

class MyWidget
{
public:
  int data;  // state variables here
  virtual void on_mouse() { printf("normal on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("normal on_key\n"); }
};
class MyWidgetReadOnly: public MyWidget
{
  // no data at all here, sic!
  virtual void on_mouse() { printf("read-only on_mouse, data=%d\n",data); }
  virtual void on_key() { printf("read-only on_key\n"); }
};

int main(int argc, char* argv[])
{
  MyWidget *w = new MyWidget();
  w->data = 123;
  w->on_mouse();
  turn_to<MyWidgetReadOnly>(w); // turning the instance to MyWidgetReadOnly class.
  w->on_mouse();
	return 0;
}

After compiling and running it we should see in console output like this:

normal on_mouse, data=123
read-only on_mouse, data=123

So it works – we are able to transform existing instance of some class to the instance of other class.

DISCLAIMER:

Be warned that this is a Jedi Sword feature. Use it responsibly, only if you know why you need it. And what are the consequences. Even mentioning of this approach in some software development companies (that usually are on the Dark Side) may damage your reputation.

TIScript: classes, decorators and events.

June 25, 2010

Filed under: Sciter, Script — Andrew @ 7:13 pm

One of differences of TIScript from JavaScript is that it has classes and namespaces.

Declaration of a class in source code looks like this:

class Baz
{
  function foo() { ... }
  property bar(v) { ... }
  // ... other functions, properties, variables,
  // constants and decorator calls ...
}

As you see class declartion in TIScript is pretty similar to the ones in Java or in C++. The only difference is that in TIScript class declaration is an executable (in runtime) entity. While parsing the class declaration above the compiler produces bytecode that is equivalent of this:

const Baz = new Class();
      Baz.foo = function() { .... }
      Baz.bar = property(v) { .... }
...

So while loading bytecodes produced by the compiler TIScript VM will execute sequence of commands to build such class object.

As class construction is an executable chunk of code then in principle we can modify/synthesize class declarations in runtime. And decorators in TIScript are just about this – they allow to execute decorator functions in context of class that is being declared.

Decorator is an ordinary function with the name starting from ‘@’ character. It should have at least one parameter that will receive reference to the object being decorated.

Example of the decorator function, the @returns decorator creates proxy function around call of declarating function and verifies its return value:

function @returns(func, returnType)
{
   return function(params..)
   {
      var r = func.apply(this,params);
      assert typeof r == returnType;
      return r;
   }
}

Having such decorator in place we can declare methods of classes with checks of their return values:

class Zum
{
   @returns #integer
     function Add(i1,i2) {...}
}

The @returns #int function()...  here is a decorator function invocation. Under the hood all this will produce following code:

const Zum = new Class();
      Zum.Add = @returns( function(i1,i2) {...}, #integer );

Call of the @returns() creates proxy for its parameter function. The result (the proxy function) will be assigned to the Add field of the class object. As you may see decorators are pretty much syntax sugar that if properly used may increase expressiveness of your code a lot.

The this environment variable inside the decorator function is getting reference to the context object of the decorator call. E.g. inside class declaration this inside decorator function body will contain reference to the class object.

TIScript supports three types of decorators in total:

  1. Function decorators:  @decorator [...params..] function() { ... }
  2. Class (or namespace) decorators: @decorator [...params..] class { ... }
  3. Empty decorators: @decorator [...params..] ;

Last one – empty decorator – is used in cases when it is a need to synthesize some properties or functions.

Here is practical example of empty decorators used to declare events in class VGrid (Sciter SDK/samples/ideas/virtual-grid/. Virtual Grid is created by Dmitrii Yakimov from http://activekitten.com).

class VGrid: Behavior
{
    const BUF_ROWS = 64;
    ...

   // Events supported by VGrid instances:

   // onCurrentRowChanged( this_grid, row )
   @DECLARE_EVENT #onCurrentRowChanged;

   // onHeaderClick( this_grid, evt, colNo, th )
   @DECLARE_EVENT #onHeaderClick;

   // onCellClick( this_grid, evt, colNo, rowNo, td)
   @DECLARE_EVENT #onCellClick;

   // onRowClick( this_grid, evt, rowNo, tr)
   @DECLARE_EVENT #onRowClick;
}

Each @DECLARE_EVENT eventName; decorator call here creates in the class these three fields:

  • property eventName(v) – that represents list of event handlers assigned to the grid instance by users of the class,
  • function notify_eventName() – function used internally by the class to "raise the event" and
  • var _eventName = [] – variable that holds a list (array) of event handlers (functions) attached to the event by users of the grid.

And here is the implementation of the @DECLARE_EVENT decorator function:

function @DECLARE_EVENT(dummy, eventName)
{
  // create symbols for the fields:
  var notify_sym = symbol( "notify_" + eventName.toString());
  var list_sym = symbol( "_" + eventName.toString());
  var prop_sym = eventName;

  // generate 'notify_' function:
  this[ notify_sym ] = // 'this' here is a class being decorated
    function(params..)
    {
      // 'this' here is VGrid *instance*
      var list = this[list_sym];
      if(typeof list == #array)
      {
        // invoke each function in subscriptions list:
        for( var f in list )
          f.apply(this, this, params); // always pass 'this' in the
                                       // first param - source element
      }
    }
  // adding property  that allows to push
  this[prop_sym] = // 'this' here is a class being decorated,
                   // generating computable property for it.
    property(v)
    {
      get { return this[list_sym] || (this[list_sym] = []); }
      set { throw String.$(Use element.{ list_sym }.push(func)
                                             to subscribe to this event); }
    }
}

The decorator function above is a bit cryptic but defintions like:

@DECLARE_EVENT #onCurrentRowChanged;
@DECLARE_EVENT #onHeaderClick;
...

allow to declare and see the whole event set in compact and convenient form.

[how-to] Add entry to Windows Explorer context “New” menu.

April 5, 2010

Filed under: How-to — Andrew @ 6:53 pm

Pretty frequently I am creating .htm and .tis files. For example for testing purposes.
Usually such files use common template like html/head/body elements, etc.

Here is the add-html-template.reg file that adds “New HTML Document” into context menu of Windows Explorer. So to create HTML file it is enough to right-click in some folder and select “New/New HTML Document” menu item.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.htm\ShellNew]
"FileName"="C:\\utils\\template.htm"

Copy block of text above into, say, file named add-html-template.reg and double-click on it to run. Registry Editor will ask permission to update registry. “Ok” on that and reboot Windows (or restart Windows Explorer). Done.

Last note: path after “FileName” – it should contain real path of the template.

V.I.Lenin with Mao balancing on his head and myself.

March 8, 2010

Filed under: Philosophy, Photos — Andrew @ 10:43 pm

Full name of this sculpture
Mysef, Lenin and Mao
is “Miss Mao Trying to Poise Herself at the Top of Lenin’s Head”. It is installed here in Richmond, BC, Canada.

Standing near it was thinking a lot. The idea has something in it. I grew up with these names everywhere in USSR. And it is history now. Sic transit gloria mundi?

HTML5 Working Drafts have been published today:

March 4, 2010

Filed under: Web Application Techologies — Andrew @ 6:40 pm

HTML5
HTML+RDFa
HTML Microdata
HTML Canvas 2D Context
HTML5 differences from HTML4
HTML: The Markup Language

Next Page »