CSS, selectors and computational complexity

CSS (Cascading style sheets) has pretty extensive set of so called selectors. Example:

ul[type="1"] > li
{
  list-style-type: decimal;
}

Selector here means the following: each li element that is immediate child of ul that has attribute type with the value "1" has that style.

Selectors and assosiated styles constitute static system of styles. And so they obey following rule (the law of CSS selectors):

At any given moment of time all elements in the DOM that satisfy set of selectors have corresponding styles applied.

Such static nature of CSS selectors establish some obvious (and not so) limitations on what could be done with selectors and what types of selectors CSS can support. For example:

  • Selectors cannot use information defined by styles. Imagine hypothetical selector and style:
    div:visible { visibility:hidden; }
    

    Such pseudo-class always fails and so breaks the rule defined above. There is simply no such moment of time when the rule above is valid.

  • Selectors can use only those features/characteristics of the DOM that can be evaluated at constant (or near) time. Otherwise observer will be able to catch moment of time when the rule will not be true.
    • Consequence of this: selectors that require scan of number of elements of the DOM unknown upfront ( have complexity O(n) in other words ) are "persons non grata" in CSS.

There is nothing wrong in principle with O(n) complexity. At the end resolution of all styles of the DOM that has n number of elements is O(n). The problem arises when you use selectors that each has O(n) complexity. Total complexity in this case will be O(n*n) and that is the cause of troubles.  In case of frequent dynamic updates each such update may require re-computation of all styles of all elements so web page may easily become non-responsive – CPU will be busy resolving styles without doing any good to the user.

Imagine that we have selector like:

ul:not-exist(a:hover) {color:red;}

where :not-exist(…) is true when DOM does not contain element in brackets.

Computation of such pseudo-class is a task of complexity O(n) where n is a number of elements in the DOM.

No one of currently supported selectors in CSS selector module (http://www.w3.org/TR/css3-selectors/) have complexity of O(n). But there are selectors like : only-of-type pseudo-class that are "not good" as in some conditions their computation are as complex as O(n).

Next article will explain what could be done in CSS to overcome complexity problem and still be able to accomplish tasks like ul:not-exist(a:hover) {color:red;}

Some numbers if you wish:

Let’s assume that we have

  1. DOM with 1000 elements and
  2. single selector that has complexity  O(n) that requre 1 microsecond for computation.

Total time requred for the DOM to get its styles will be:

1000 * 1000 * 1μS = 1000000 μS = 1 S (one second)

Lets double number of elements in the DOM so we will get:

2000 * 2000 * 1μS = 4000000 μS = 4 S.

So by simply doubling number of elements we’ve increased time needed by four.

In real time scenario (on complex sites) it will easily make such sites too heavy to deal with.

JavaScript. Private members (instance variables).

As you know JavaScript has no concept of private members in objects. Objects there are “racks of properties” that anyone can change.

Here is a simple way of making “objects” in JS that have private instance variables. Such variables can be changed only by [public] methods you provide.

Consider following code:

  function CreateMyObject()
  {
    var m_first = 0;
    var m_second = 0;

    var envelope = // our public interface
    {
        getFirst: function() { return m_first; },
        setFirst: function(v) { m_first = v; },
        getSecond: function() { return m_second; },
        setSecond: function(v) { m_second = v; }
    };    
    return envelope;
  }  
  
  var f = CreateMyObject();
  
  var n = f.getFirst(); // calling our methods 

Here we have CreateMyObject() that behaves as a constructor of our object. It returns envelope object that has four methods. Only these methods can update or retrieve state of m_first and m_second variables. There are literally no other ways to access them from anywhere else other than set of methods provided.

Under the hood: In this example each interface method that we’ve created is a closure in fact: such methods have access to environment of outer function (CreateMyObject in this case) so they can access variables in this environment. Making a closure can be a memory expensive operation so avoid their use when you expect many instances of such objects.

Sciter. Working with persistent data (database)

Here is an example of minimalistic application working with DB (persistent data) in Sciter.

Screenshot of DB form.

This sample is using three files:

  1. simple-db-form.htm – main file of our application;
  2. db.tis – open or create database;
  3. form.tis – behavior that handles showing/saving data from list of input elements on the form.

db.tis – open or create database

This file contains single procedure that will open or create new storage if does not exist:

function openDatabase(pathname = "records.db")
{
  var ndb = Storage.open(pathname);
  if(!ndb.root)
  { 
    // new db, initialize structure
    ndb.root = 
      { // root of our db is an object having single field 'records'
        records: ndb.createIndex(#integer) // main index, int -> item
      };
  }
  return ndb;
}

Structure of our storage is simple – its root node contains single field records of type Index. In our example this index maps integer – number of the record to the record itself – object that may have arbitrary structure.

form.tis – showing/saving data from input elements on a form

// Form handler class
type Form: Behavior
{
  function show(rec)
  {
    if(this.shown) this.save(); // save previously shown record.
    this.shown = rec;
    function load_value(el)
    {
      var name = el.attributes#name;
      el.value = rec[symbol(name)];
    }
    this.select(load_value, "[name]"); 
    // call load_value for each element having "name" defined.
    // De facto this means that form content defines structure of the record.
  }
  function save()
  {
    var shown = this.shown;
    function store_value(el)
    {
      var name = el.attributes#name;
      shown[symbol(name)] = el.value;
    }
    this.select(store_value, "[name]"); 
    // call store_value for each element having "name" defined.
  }
}

This behavior class has two methods:

  • show(rec) – show fields of object rec in fields of the form and
  • save() – stores content of input elements of the form in fields of last shown rec object

simple-db-form.htm – main file of our application

And last part is our main file that defines UI layout and assembles all parts together:

<html>
<head>
  <style>
    form#record 
    { 
      prototype:Form; 
    }
    ...
  </style>  
  <script type="text/tiscript">
    include "form.tis";
    include "db.tis";
    
    var form = self.select("form#record");
    var rec_no = self.select("#rec-no");
    
    var db = openDatabase();
    var no = 0;
    
    function gotoRecNo( n )
    {
      no = n;
      if( no < 0 ) no = 0;
      else if( no >= db.root.records.length ) no = db.root.records.length - 1;
      form.show( db.root.records[no] );
      rec_no.text = String.printf("%d of %d", no, db.root.records.length); rec_no.update();
    }

    function gotoNewRecord() 
    { 
      // create new record 
      var newidx = db.root.records.length;
      db.root.records[ newidx ] = { first:0, second:"", third:"<html><\/html>" };
      gotoRecNo(newidx); 
    }

    // handlers of navigatonal buttons
    function self #first .onClick() { gotoRecNo(0); }
    function self #prev  .onClick() { gotoRecNo(no - 1); }
    function self #next  .onClick() { gotoRecNo(no + 1); }
    function self #last  .onClick() { gotoRecNo(db.root.records.length - 1); }
    function self #new   .onClick() { gotoNewRecord(); }
    
    function view.onLoad()   { if(db.root.records.length) gotoRecNo(0); 
                                        else gotoNewRecord(); }
    function view.onUnload() { form.save(); db.close(); }
    
  </script>  
<head>
<body>
  <h1>Simple DB form</h1>
  <form #record>
    <table>  
      <tr><td>First (number)</td><td><input name="first" type="number"/></td></tr>
      <tr><td>Second (text)</td><td><input name="second" type="text"/></td></tr>
      <tr><td>Third (richtext(html))</td><td><richtext name="third" /></td></tr>
    </table>
  </form>
  <div #nav>
    <button #first title="to first record">|<</button>
    <button #prev title="to prev record"><</button>
    <button #next title="to next record">></button>
    <button #last title="to last record">>|</button>
    <button #new title="create new record">new</button>
    record: <span #rec-no>?</span>
  </div>
</body>
</html>

Done. We have simple form that allows us to create records with text, numeric and richtext (html) fields.


Code above is not the best one from architectural point of view – its goal is to show basic principles, not more.
You can find this sample in [Sciter SDK]/samples/ideas/db/ folder.

How I would do that Start Page.

Start Page in HTMLayoutTwo days ago I have downloaded and installed new Microsoft Visual C++ 2008 Express.

First thing that you see when you start its IDE is the Start Page (close to what you see on the right). I was intrigued how this view is made. That clearly have look and feel of a web page. Some portions of data are coming from Internet.

So I took the Spy++ application and pointed it on the view. It was a surprise for me to discover that this view is made of separate windows in old VB style. It is made of 40 (forty) child windows. That is not so good to be honest:

  • too resource greedy, e.g. without this view IDE takes 10 Mb less of memory;
  • and as you might expect scales badly on high DPI settings, see example of actual rendering:
  • VS on Large DPI

Thus I’ve decided to reproduce this screen in HTMLayout. Here are steps of how I’ve made it.

1. Images

For this particular view we need 4 ( and only four ) images:

  • Header – header background;
  • Body back background of the body section;
  • Panel back background and borders of informational panel;
  • Panel caption background – background of panel’s caption.

(I took these images from screenshot I made from Microsoft Visual Studio window. These images are probably copyrighted. In any case my respect to their authors.)

Ok, back to business…

2. HTML

Structure of HTML for such a view is simple:

<body>
  <div .header />
  <div #sidebar >
    <div .panel #recent-projects><caption>Recent projects</caption>
      <ul><include src="content/list-of-projects.htm" /></ul>
      <table>
        <tr><td>Open:</td><td href="#">Project...</td></tr>
         <tr><td>Create:</td><td href="#">Project...</td></tr>
      </table>
    </div>
    <div .panel #getting-started><caption>Getting started</caption>
      <ul><include src="content/getting-started.htm" /></ul>
    </div>
    <div .panel #headlines><caption>Headlines</caption>
      <dl><include src="content/headlines.htm" /></dl>
    </div>
  </div>
  <div .panel #msdn-news>
    <caption>MSDN: Recent news</caption>
    <dl><include src="content/msdn-recent-news.htm" /></dl>
    <p style="text-align:right;"><a href="#">More news...</a></p>
  </div>
</body>

Nothing spectacular so far I would say.

Note:

Markup above is HTMLayout specific: 1) <div .panel > is a short form of <div class=”panel” > and
<div #recent-projects > is <div id=”recent-projects” > and you can use both forms. And 2) <include src=”content/list-of-projects.htm” /> is so called client side include instruction – it allows to assemble final HTML from different source files. This include makes sense here as while parsing engine will generate HLN_LOAD_DATA notifications for each inclusion. These portions are dynamic so handling this notification we can generate HTML content fragments we need. That is close to the CGI idea.

3. Styles

Final piece left – styles. That is really simple as HTMLayout supports expandable backgrounds.
If you have read document under the link above then you should get the idea of this fragment. It defines styles for our panel and its caption:

    div.panel
    {
      background-image: url(images/panel-back.png);
      background-repeat: expand; 
      background-position: 14px 14px 14px 14px; 
          // top right bottom left offsets/margins
      padding: 0 10px 10px 10px;
      margin-bottom:20px;
    }

    div.panel > caption
    {
      background-image: url(images/panel-caption-back.png);
      background-repeat: expand stretch-left stretch-middle stretch-right; 
      background-position: 3px 3px 3px 3px; 
         // top right bottom left offsets/margins
      padding:6px 6px;
      color:white;
      font-weight:bold;
      position:relative;
      top:-0.7em;
      margin-bottom:-0.6em;
    }

Other styles are also simple as these two above.

To see this mock-up alive you can download demo browser.exe with samples and run /bin/browse.exe. Click open button and find /html_samples/MSVS-start-page/start-page.htm. This is it.

4. Epilogue

It took me one hour to design this sample (from the set of existing images).

Loaded document consumes 5 (five) times less resources than original solution.

And HTMLayout is free. For Microsoft Visual Studio Team (respect!) too 🙂

Talks about HTMLayout

Here is a translation of the interview in Russian I gave to Alexander Sergeev from the HumanoIT.


Alexander Sergeev(AS) says:

My long time dream – to write a shareware program and sell it through the Internet: cash out, Brazil, Maldives, Tokyo, beaches, skiing, casinos… ahhh. This summer I almost brought it to reality… all thanks to one wonderful graphical engine. I’ll tell you right away – I didn’t finish my program yet (simple lack of time), but the summer has not gone wasted – now I know, WHAT interfaces can be developed on the desktop. For us (in HumanoIT Group) this knowledge is equivalent to its weight in gold, since we don’t develop interfaces for the web only.


HTMLayout is currently the only embeddable HTML/CSS engine of this type.


Here are a couple of interfaces based on the HTMLayout engine:


Norton 360

Norton AntiVirus

Alawar Game Box

Nobody can tell us about HTMLayout better than its author. Hence, I present to you an interview with Andrew Fedoniouk, the author of this wonderful graphical engine.


Part 1: Ponderings about Web 2.0


What do you think about Web 2.0: what is the essence of Web 2.0 for you as a user? As a programmer?



Andrew Fedoniouk(AF): First of all, nobody knows for sure what Web 2.0 is 🙂 It’s a set of technologies and solutions at the level of a "hack" – this I will tell you. For myself, I classify Web 2.0 as a set of technologies which supports Occasionally Connected Web Applications.

Please clarify what you mean by Occasionally Connected Web Applications?



It’s an application, which has a built-in capability of working offline. I.e. Web 2.0 is more about desktop applications, than about the actual web. It’s about using web on the desktop and vice versa – giving web applications a desktop-like feeling.

Name some main differences between today’s desktop applications and Web 2.0 applications?


Storage of data. Actually – this is the age old difference between client-server and desktop applications. Web 2.0 tries to bring the "comfort" of desktop to the web.

What do you think the main differences in UI between the two are? (let’s leave HTMLayout out of the picture for now)



Inductive UI versus Productive UI. Traditionally, Web applications are ossasionally used applications. I.e. web application’s UI must be self-descriptive: any user off the street should be able to do what he needs to, without reading any docs.
Let’s take Norton Antivirus and Norton Internet Security as examples. These are applications of a "big red button" – rarely accessed (by UI), so their UI must be intuitive. This is one of the reasons Symantec uses HTMLayout in their products.

Another example is a media player application. That kind of applications are built around "Play" button. I cannot imagine anyone reading manual of, say, WinAmp.

What do you see as inductive UI? Wizards, oriented to perform user tasks?



Yes, inductive UI is a paradigm of "steps" (a wizard) – enter some data, press submit, move to the next step.

AS (Alexander Sergeev): By the way, Don Norman introduced a concept called affordance – analogous to being self-descriptive. For example, scissors – it’s obvious that the fingers go into the holes 🙂


AF (Andrew Fedoniouk): Sure.

And what do you mean by productive UI?



Inductive UI is Web 1.0. Web 2.0 – is (among other things) an attemp to make productive UI available in the web. Productive UI refers to applications used every day. A characteristic feature of such applications is an attempt to minimize the amount of efforts to achieve a desired result. Shortcuts, for example, are an obvious attribute of a productive UI. Toolbars, among other things, are as well.
But this distinction between Inductive and Productive UIs is becoming less clear. The complexity of applications is growing, so even such apps as MS Word use wizards and ribbon.

If we go down to the level of controls and widgets – what do you see as the main difference between desktop and Web 2.0 applications?


Widgets are also approaching a common denominator. Web 2.0 widget kits are striving to recreate the desktop, while desktop kits are going in the direction of compound web alike widgets.

Please name three main technologies, which you think are the basis of Web 2.0 applications? Desktop applications?




  1. AJAX (as a lightweight way of sending messages between the UI and the data model – a classic feature of desktop applications)

  2. HTML/CSS as a technology for gluing together the pieces into a final UI. There is actually a lot behind this. PHP/ASP/etc technologies as a way of putting together the UI. This is what the desktop didn’t have.

  3. Finally, scripting and HTML event propagation schema, as a way of connecting different elements between each other. In fact, this was not present in the desktop UI (typed languages).

AS: You forgot about DOM.



AF: Yes, DOM is a whole different aspect.

AS: We see Web 2.0 eye to eye from the technical perspective. For me, Web 2.0 is get, parse & display: get the data (from the server), parse/process the data and display it. Get is ajax, parse is DHTML (HTML + DOM + Javascript), display is CSS. I think that it is thanks to these technologies that we now can create rich user experience in Web 2.0 applications.



AF: Technically, if we dig deeper, this all falls under the paradigm of CGI. This is the basis of generating UI in server-terminal type systems. Terminals are just becoming more resource rich.

AS: Yes, the last point sums up the need for usability and user-orientated UI’s 🙂


What do you think web applications lack, even disregarding web-duality?



Starting from afar, there are 2 types of Internet users: "readers" and "writers". For readers, Web 1.0 is quite sufficient, and so are the current browsers. The second group – "writers" – are the people who need a different:



  1. model of security

  2. usage model (occasionally connected)

  3. capability for interaction between desktops objects and browser objects

For example, Gmail is great at everything (as that Exchange Web Client – web client of “big” Outlook), except for the fact that it’s not a desktop application 🙂 I want to be able to download email and read it when I have free time, while disconnected. This is an example #2.


The simple action "save as" in any word processor or email client. In fact, the browser disallows writing anything on the client due to security concerns. This is the right way for the "reader" use case.


About #3, let’s use the clipboard as an example. I want to insert an image I just drew in Xara into a blog entry and it’s not possible. I need some other client ( UA user agent) to accomplish that.

Part 2: HTMLayout Engine


Tell me a little about the HTMLayout library. What is it for?



HTMLayout is a unique (in its own right) embeddable html/css engine. Embeddability is the focal point here.


All operations which concern security, for example load remote resource, go through the host (notification and callback). Hence, the host application is in charge of the security policy. This is the main problem while embedding Gecko and Trident (IE, IWebBrowse).


The CSS feature set is extended in HTMLayout to support 2D layout – the HTML/CSS model in the web is an endless tape, having a fixed width only. HTML and CSS 2.1 lack a method to perform vertical alignment.


All widgets are made from DOM elements – i.e. their components are styled through CSS. For example, combobox is a DOM element and the button in it (show popup) is also a DOM element. This button can have it’s own style (think of UI themes), and additional behavior associated with it as well.


Behaviors – as a way of setting behaviors per se for conglomerates of DOM elements (aka controls). Behavior changes the state of DOM elements, while CSS displays it all.


Sinking/bubbling event propagation schema, as a simple and effective way to deal with events.


Support for OS themes – as a way to respect user preferences.

So, roughly speaking, HTMLayout is a web browser, which a Windows programmer can embed into his or her program, and base its UI on DHTML?


You can say that. If roughly 🙂

As far as I know, people in Motorola use it exactly like that. They made a specialized browser based on HTMLayout that communicates with http server.

C++ and C# is used instead of Javascript to display and process widgets (aka controls)?


Yes, the language of the host application is used to describe actions. I know about various bindings of HTMLayout in C++, C#, Ruby, Lua, Python, etc.. Imagine that you had a way to, say, extend some HTML/CSS engine with various UI elements needed for your applications (<input>, <widget>, etc). I suspect that you won’t need JS in 95% of the cases if you have the required component set.

There have always been resizing issues in Windows applications based on MFC/WTL – you had to manually adjust the size of the controls.  On the web, I have never seen a "rubber" application, which would have automatically (upon browser window resize) adjusting control size (inputs, combo boxes, etc). Is this problem resolved in HTMLayout? What features are available in the library to simplify the resizing procedure.



There are two problems about resize.
The first – implementing a rubber layout – it is in HTMLayout already by the nature of HTML and CSS. I think this kind of flexibility is not available in any other UI toolkit.
The second – "congruent UI scaling" – is not that much of a problem in my eyes. "Automatic resize of controls when the browser window is resized" – this can be done in HTMLayout, if that’s what you need. However, users usually make the window bigger to increase the working area, rather than to increase, for example, the font size.

An example from a different area. Symantec NIS (Norton Internet Security) has support for high contrast mode. It’s done simply with CSS by using different media types (normal screen and high-contrast screen settings are really different media types):
@media screen { … css declarations… }
@media high-contrast { … css declarations… }


Therefore it is no need to reprogram the host application to support accessibility.

Regarding components in HTMLayout. As far as I understand, on the web, I am working not with the control itself but rather with the control’s HTML-snippet. In HTMLayout, I can create the control beforehand, name and change it at the execution stage, depending on the current event and data?


You can write in CSS:
input[ type=”something” ] { behavior: some-behavior; }
and in HTML to use it as:
<input type=”something” />


The host application should provide a behavior implementation which can do pretty much anything. For example, it could create an embedded DOM tree and handle the events it generates. The same behaviour can be used by different style schemas, creating visually different control elements.


In essence, all input elements in HTMLayout are made this way. They are simply a set of behaviors which are assigned to different DOM elements through the master CSS style sheet.


Embeddable behaviors can be reused:
<span class=myradio name=n1 /> <span class=myradio name=n1 /> <span class=myradio name=n1 />
+ css:
span.myradio { behavior: radio; }
span.myradio:checked { background-image:….; }


Furthermore, it’s possible to glue together complex structures from simple blocks.

AS: I.e. in such a case, when the user clicks a radio button, the background image could appear.


AF: Yes.

AS: Besides, instead of outputting a simple radio button, I can show anything? (can’t think of an example of what else I could output 🙂 )


AF: Tabs, as UI control elements, are pretty much a set of radio buttons (bookmarks) augmented with a binding mechanism to the visibility panel set. I.e. it is sufficient to write a behavior, which upon receiving a BUTTON_CLICK notification from such a radio button, could set the :cuurent state flag of some corresponding div panel.


All that remains to be done is a bit of CSS:
div.tab-panel { display:none; }
div.tab-panel:current { display:block; }


There aren’t that many behavior patters like that in real applications. I.e. creating something complicated from something simple. The CSS code is used as glue, binding together state and appearance into a single entity.

AS: Thanks for the detailed example! Originally, I mistakenly thought that instead of behavior:radio; I could write behavior:"something" and instead of the radio button we would get "something" in the span. Instead, it seems that we are changing object properties here.



AF: Yes, the main purpose of behavior is changing state attributes of DOM elements in response to user actions. In the behavior::attach() handler, it’s possible to create or change the DOM structure of the element (or its surrounding), if required.

AS: So, behavior allows to manage the contol’s state.


Please provide an example of applications which use HTMLayout?



Off the top of my head – Symantec (Norton Antivirus, Norton IS, Norton 360). All games from Alawar have a "game console", which uses HTMLayout:

Part 3: UI evolution tendencies


What do you think some of the current developing tendencies for UI on the desktop?


Software vendors are striving to switch to a service model – i.e. the user paying regularly for a service, rather than once. UI’s are very different from each other. On one hand, we have typical desktop productive utilities. On the other, we have the aforementioned big red button applications. I wouldn’t try and pick out the mainstream. This is counter-productive, since I believe there is no one fit all solution here.

What if we look at the progress in the area of controls and tools for UI development? Is there progress? Do you see any tendencies here?



I see both technical and stylistic tendencies:

Stylistic – "pictographic UI’s" and "hyperlinking"

Technologic – declaraitive UI – the unfulfillable dream of all humanity

Back when I was still coding, I created interfaces with the help of Visual Studio’s resource editor. It took me a very long time. Even today, the interface UI developer should keep in mind the complexity of the task he is giving to the UI programmer.



From a developer’s perspective, I think none of the technologies offers a noticeable improvement in the time taken to develop the bare interface without any data behind it. VB(6) allowed you to quickly throw some forms together in the editor. However, that’s where it stops. How do you create a form within another, handle events in complex structures, etc.

IMHO, the web is far more advanced in this respect – the interface is almost completely separated from the business logic with the help of templates and templators. On the desktop, as far as I know, everything is much less cheesy.



Yes, there are also tendencies – UI generation from templates, CSS as an entity (stylization of existing DOM – seperation of semantic(data,code) and style). VB and MFC simply are not made for stylizing elements and combining simple elements into complex structures.

AS: Yes, it’s not so easy to change the interface styles in VB and MFC. You have to go through all properties and change the styles in each of them. In addition, in MFC you have recompile the project as well. To develop your own control, you need to study the ActiveX/COM technologies.


For me, HTMLayout is a significant step forward in separating the UI from the application’s business logic. The interface’s designer can quickly create a prototype in something like Axure (meant for web apps). Then, he or she can write the HTML code as a template for the programmer, who can add behaviors, variables, and other stuff into this template.


In my opinoin, HTMLayout does and excellent job of integrating the advantages of both desktop and web technologies.



AF: I think so. In addition, some properties of UI components cannot be changed at all in VB and MFC. HTMLayout interace provides a whole different level of control.


Rubber layout, for example. Fixed layout format is the exact offender which prevents scalable UI’s. Controls in Windows dialogs are usually fixed dead in their tracks. Set 120dpi on the screen and it’s over – the UI is unreadable even in some Microsoft applications.


Behind the layout flexibility of a rubber interface lies accessibility – not all users can use the UI with the default 96dpi.


HTMLayout ideology helps large scale development of software – the UI and logic become loosely coupled. Hence, the separation into teams of UI designers and stylists, and backend logic programmers becomes much easier.

Parts 4 and 5


I think it’s reasonable to leave these parts for the next article – too many letters, even for this blog. 🙂


What will be in the next article:



  • SW and web application aesthetics

  • MS Expression, XAML, Aurora

  • Animation in HTMLayout

Designing

I am designing <richtext> behavior for htmlayout/sciter… So far I like the way it allows to edit the text.

There are interesting usability problems bubble up sometimes… Let’s say you have following document:

<body>
  <pre>
     ....
  </pre>
  <table>
     ....
  </table>
</body>

And now imagine that you need to insert some text (paragraph) between the table and that pre block. Or insert paragraph (<p>) at the beginning of the document – before the <pre>…

I do not know any WYSIWYG HTML editor that allow to handle such operations.

So I have invented “horizontal caret” that marks start-block-position. Enter key in that position causes new paragraph to be inserted.

Here is an example of such caret – blinking black bar in top-left corner of the pre element:

richtext, horizontal caret

behavior:htmlarea (WYSIWYG editor) in h-smile core.

My initial idea was to implement behavior:htmlarea (WYSIWYG editor) as editing behavior that manipulates elements in existing DOM tree. This approach is not working for many reasons.

Main reason is following:

In presence of CSS the same rendering result (pixels in the view) can be achieved in many ways – by using various CSS attributes. (Think about spacing between paragraphs – they can be done as margins or as paddings or as trivial <br>s.)

WYSIWYG editing behavior is aimed to solve task that is somehow opposite to rendering : to change DOM structure by using current view (what user sees).

So current CSS and DOM that are good for rendering prevent good WYSIWYG implementation. I have never seen any editor based on contenteditable=”true” in browsers that I can consider as a good WYSIWYG editor. It is just impossible because of such same-DOM/multiple-ways-of-rendering-by-CSS.

Perfect WYSIWYG assumes that you can change DOM structure by using solely toolbar and keyboard – without any knowledge about underlying CSS. But current state of CSS makes perfect WYSIWYG almost impossible. Some CSS attributes and abstractions are extremely hard to present to non-css-educated user.

Solution that I am working on now:

behavior:htmlarea will be based on my blocknote editing engine.
Blocknote editing engine is using so called “flat DOM” – linear sequence of paragraphs and tables. I am just adding there limited support for CSS so htmlarea will use separate CSS file for content representation:

<htmlarea content-markup=html|wiki content-style="editing.css" />

That editing.css is a linear set of style rules that use simple tags and class selectors:

  strong { font-weight: bold; }
  strong.very { font-weight: bold; color:red; }

No other type of selectors will be allowed. Reason is simple: “predictable WYSIWYG”.
Think about following selector:

  div.some > p { margin-top:40px; } 

and user editing text with it. ENTER will cause the paragraph to be split into two:

<div.some>
      <p>first</p>
      <p></p>
  </div>

That will create margin-top:40px; spacing between them. ENTER in other paragraphs (not in div.some) will create produce different spacing. There is no way for the user to explain why here it is 40px and there it is 10px or so.

That is why HTML WYSIWYG content editing widget, I think, shall use not-exactly-html DOM and CSS.

Web Application Technologies, poll.

Poll "Web Application Technologies" on RSDN.

Poll was addressed to professional web developers with the question:


Modern Web Application uses following technologies (UA side). What do you think makes sense to improve in the very first place?

  • HTML – for example to design HTML v.5
  • CSS – for example to add layout managers.
  • Scripting (JS and  DOM) – for example to add JS2 (with classes and types) and/or getElementBySelector()
  • To develop component technologies. For example XBL (Mozilla) or HTC (Microsoft).

So far 80 professionals (registered RSDN users) participated in the poll.


Results are:

poll results graph

(Poll configured to select only 3 items max from 4 items above)

Implementation of Behaviors in Internet Explorer

Implementation below is a generalization of Ben Nolan’ idea of behaviors. Behaviors were implemented natively in Sciter and HTMLayout and here is their emulation for the Internet Explorer.

Basic principle is simple, CSS declaration like this:

li.myclass 
    { 
      prototype: MyBehavior; /* see var MyBehavior below */
    }

binds class of DOM elements with the “prototype behavior object” – collection of event handlers defined in script nearby:

var MyBehavior = 
    {
      attached:    function() { ... },
      onclick:     function() { ... },
    }

Thus after loading HTML that contains something like this:

<ul>
  <li class="myclass">Element with MyBehavior</li>
  <li>Element without behavior</li>
</ul>

first element will behave as MyBehavior.

Here is an implementation of the Behaviors Framework – HTML document that demonstrates basic principle. Implementation is based on the fact that Internet Explorer allows you to define custom attributes in CSS declarations. I will appreciate if someone will tell me how to define something like this but for other UAs (browsers).

This may be interesting too:
“Designing Reusable UI Components in Sciter: Part I, Part II and Part III“.


Here is Dave Herman’ version of original behavior.js of Ben Nolan.

Here is another sample for IE: Simple collapsible tree.