Working with text selection

Last week I started to implement a (still basic) low-level Text Selection API which especially the high-level form widgets like TextField and TextArea can make use of.

As some of you might already know working with the native Selection and Range / TextRange objects is not one of the things a developer dreams of :-)

However, looking at the basic implementation one thing is quite amazing. Besides a little tweak for Opera three (Gecko, Safari and Opera) of the four major browsers share the same implementation.
Sure there will be some more differences to encounter when the development of this low-level layer moves on, but the start looks quite promising.

Let there be color in the browser

I always wanted to play with the browser's canvas element but never really found the right toy project. Then I read Ariya Hidayat's blog post "Let there be color". He has implemented the HSL color pie using Qt's 2D drawing canvas. How hard would it be to put something like this into the browser? I decided to try the port of his code to JavaScript and render the pie using only canvas. If this worked out maybe I could embed it into nice little qooxdoo windows.

HSV Pie

Once I figured out how to realize "putPixel" and "getPixel" functions in canvas the port was merely a copy and paste with some minor changes. Right now I use the canvas methods "getImageData" and "putImageData" to obtain and render a pixel buffer. Unfortunately these methods are only available in Firefox. I'm still looking for an alternative for Opera and Safari. The last missing part was the conversion from HSV to RGB but luckily I could drop in a modified version of qooxdoo's hsbToRgb method.

Now the port could start. What really intrigued me was that the main algorithm was nearly the same as the C++ code. Just take this code fragment from the original code:

for (int i = 0; i < radius; i++) {
  qreal hue = 1 - init;
  qreal sat = 1 - qreal(i) / radius;
  for (int d = 0; d < depth; d++) {
    qreal value = 1 - qreal(d) / depth;
    QColor color = QColor::fromHsvF(hue, sat, value);
    img-&gt;setPixel(width / 2 - radius + i + 1, center + d, color.rgb());
  }
}

and compare it to the ported JavaScript:

for (var i = 0; i < radius; i++) {
  var hue = 1 - init;
  var sat = 1 - i / radius;
  for (var d = 0; d < depth; d++) {
    var value = 1 - d / depth;
    var color = hsbToRgb(hue, sat, value);
    setPixel(img, width / 2 - radius + i + 1, center + d, color);
  }
}

Basically only the variable declaration is different. The same is true for almost all of the relevant code. My first version was an all in one HTML file with the JavaScript code embedded. I used no framework, just plain JavaScript.

Of course I wanted to use some qooxdoo, so the next iteration was to put this into a qooxdoo application. Up to now qooxdoo had no support for embedding canvas elements into a qooxdoo widget. I used much of the new 0.8 widget infrastructure to create a canvas embedding widget. With this widget I could take the code from my first version and embed it into a qooxdoo window. You can see this application life or download the sources. This code is based on the latest qooxdoo 0.8 trunk.

Have fun!

Object disposal and the ‘destruct’ section

Recently, there was a lively thread on the mailing list concerning object disposal and the 'destruct' section of classes. While the corresponding wiki page gives most of the answers, it might be worthwhile to summarize and highlight a few aspects:

  • Generally, qooxdoo's runtime will take care of most of the issues around object disposal, so you don't have to be too anxious if you get those 'missing destruct declaration' messages from a verbose disposer run.
  • You can look at the dispose behaviour of your app if you set the disposer into a verbose mode and then invoke it deliberately while your app is running. This will usually render your app unusable, but you will get all those messages hinting you at object properties that might need to be looked after. How-To instructions can be found here. But mind that the disposer output are really hints, nothing more.
  • _disposeFields() is always a safe choice to use in the 'destruct' section of your class. And it prevents all DOM leaks which is the most important thing to do.
  • _disposeObjects() is appropriate when you want to dispose an attached qooxdoo object your class is in charge of. Whether this hold true depends on the application where objects might be shared between other class instances, so make sure you are not destroying an object some other class might want to continue to use :-) .
  • _disposeObjectDeep() is rather arcane, and you can safely ignore it in most cases. qooxdoo 0.8 will replace this method with two others, _disposeArray() and _disposeMap(), which are more straight-forward and just relieve you from using loops around iterable data structures for the dispose calls.

Hope this sheds some more light on the issue.

GUI Internals Presentation

There was planned another one for Fabian. This time a deeper insight to the internals of qooxdoo's Widget system. Because the first workshop took too long there was no more time for this one. Without the oral narrative this is quite lightweight. Hope this is still interesting for you. More detailed documentation is planned for 0.8 in the next weeks.

New Animation Layer

qooxdoo 0.8 - the next major release that includes an exciting rewrite of the GUI toolkit - will also offer a powerful animation layer with a wide range of effects. qooxdoo animation, as we call it, is to a large extent derived from the well-known effect library script.aculo.us.

To give you a small example, I will demonstrate how easy it is to build a typical One Second Spotlight in qooxdoo:
Imagine your website has an info box with the current number of your product's downloads:

Downloads today: <span id="dlAmount">10</span>.

Every time a user starts a download, a function should be called to update the box. Using the Highlight effect on the element containing the number of downloads, you can easily get the user's attention:

 
  var element = document.getElementById("dlAmount");
  var attention = new qx.fx.effect.core.Highlight(element);
 
  function update(amount)
  {
    element.innerHTML = parseInt(amount);
    attention.start();
  }

See the development version of the demobrowser for some early animation demos. Please note that the animation API might still change before the final 0.8 release. The current animation layer is a low-level DOM layer that will later also be used internally to animate the high-level qooxdoo widgets when they are available in 0.8.

Rounded borders - and how to do it in IE

In qooxdoo 0.8 we will introduce the concept of widget decorators. This has already been described in an earlier blog article. Decorators allow a widget's background to be styled independent of the widget's content. To demonstrate the flexibility of the decorator concept I have written a decorator, which uses native CSS rounded borders in Firefox and Safari/Webkit and emulates the same behavior in Internet Explorer. The screenshot shows the same qooxdoo 0.8 application in Internet Explorer 7, Firefox 3 Beta 3, WebKit r30082 and Firefox 2.0.11.

Rounded borders screen shot

The widget shown in the screen shots is generated by the following snippet of qooxdoo code:

 
doc = new qx.ui.root.Application(document);
 
var border = new qx.ui.decoration.RoundedBorder().set({
  radius: [10, 20, 30, 40],
  width: [3, 10, 20, 5],
  color: ["red", "green", "yellow", "blue"],
  backgroundColor: "gray"
});
 
doc.add(new qx.ui.basic.Label().set({
  html: qx.bom.client.Engine.NAME,
  decorator : border,
  width: 140,
  height: 100,
  padding: 20
}), 10, 10);

I think the most interesting question is about the IE implementation. Since IE has no native CSS rounded border support, the borders must be rendered using a different technique. A common approach is to render the borders using pixel-sized DIV elements like e.g. RUZEE.Borders does. We have used a different and in my opinion much more powerful approach.

We use VML to render the background including the border. The VML code is dynamically created and inserted into the decoration DIV using plain innerHTML. Since the decorator is informed about size changes by the qooxdoo layout engine, it can update its borders accordingly. The rendering quality is amazing and looks pretty much like the best native browser implementation of Firefox 3. This is the code automatically generated and applied by qooxdoo:

 
<style>v\: * { behavior:url(#default#VML);display:inline-block }</style>
 
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<div style="left: 10px; width: 140px; position: absolute; top: 10px; height: 100px">
<div style="z-index: 10; left: 25px; width: 85px; position: relative; top: 23px; height: 37px" usehtml="true">mshtml</div>
<div style="z-index: 5; left: 0px; position: absolute; top: 0px">
    <v:group style="left: 0px; width: 140px; position: absolute; top: 0px; height: 100px; antialias: true" coordsize = "140,100">
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "gray" path = " m10,1 ns l120,1 qx139,20 l139,70 qy110,99 l40,99 qx1,60 l1,10 qy10,1 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "red" path = " m10,3 ns at5,3,15,13,10,3,5,3 wa0,0,20,20,0,0,10,0 wa100,0,140,40,120,0,140,0 at110,3,130,23,130,3,120,3 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "green" path = " m130,13 ns at110,3,130,23,130,13,130,3 wa100,0,140,40,140,0,140,20 wa80,40,140,100,140,70,140,100 at110,60,130,80,130,80,130,70 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "yellow" path = " m120,80 ns at110,60,130,80,120,80,130,80 wa80,40,140,100,140,100,110,100 wa0,20,80,100,40,100,0,100 at5,40,45,80,5,80,25,80 x e"></v:shape>
    <v:shape style="width: 140px; height: 100px" coordsize = "140,100" fillcolor = "blue" path = " m5,60 ns at5,40,45,80,5,60,5,80 wa0,20,80,100,0,100,0,60 wa0,0,20,20,0,10,0,0 at5,3,15,13,5,3,5,8 x e"></v:shape>
    </v:group>
  </div>
</div>
 

Generated HTML for Internet Explorer

The first two lines are required to enable VML support and are only added once into a page. Note that only one of the DIV elements contains VML code. The rest is typical HTML code generated by the qooxdoo GUI toolkit, which does all the layouting itself, just using JavaScript. It consists of a couple of nested, absolutely positioned DIV elements with the appropriate CSS styles applied.

The code for Firefox is much simpler and just sets the browser-specific CSS styles:

 
<div style="position: absolute; z-index: 0; left: 10px; top: 10px; width: 140px; height: 100px;">
<div style="position: relative; z-index: 10; left: 25px; top: 23px; width: 85px; height: 37px;">gecko</div>
<div style="border-style: solid; border-color: red green yellow blue; border-width: 3px 10px 20px 5px; z-index: 5; position: absolute; left: 0pt; top: 0pt; -moz-box-sizing: border-box; width: 100%; height: 100%; background-color: gray; -moz-border-radius-topleft: 10px; -moz-border-radius-topright: 20px; -moz-border-radius-bottomright: 30px; -moz-border-radius-bottomleft: 40px;"></div>
</div>
 

Generated HTML for Firefox

Native browser support

The quality of rounded border implementations differ a lot between browsers. The CSS3 draft defines the property border-radius and a property for each corner like border-top-left-radius. These properties take two values, one for the horizontal radius and one for the vertical radius. That way it is possible to define (quarter-)elliptical borders. If only a single value is given, the border is (quarter-)circular.

Current browser implementations

  • Firefox 2: Firefox supports only circular borders. Border definitions always take a single parameter - the radius. The CSS property is called -moz-border-radius and -moz-border-radius-topleft, respectively. -moz-border-radius supports the CSS shorthand mode. If only one parameter is given, the radius of all four border is identical. If four parameters are defined, the radius for all four corners is set individually. The rendering quality is very poor since Firefox 2 does not use anti-aliasing to render the border (cf. screen shot).
  • Firefox 3: The same as Firefox 2 but borders are rendered using anti-aliasing, which looks much better (thanks to the Cairo 2D graphics library).
  • Safari/WebKit: The CSS property names differ from the W3C spec (-webkit-border-radius and -webkit-border-top-left-radius). Besides that, WebKit implements pretty much the CSS3 standard. Rendering looks fine as long as all border widths are equal. If they differ, the rendering looks quite ugly (cf. screen shot). This has already been reported in the WebKit Bugzilla and hopefully is going to be fixed soon.
  • Opera: Opera also does not support CSS rounded borders but there is a description online on how to emulate them using SVG backgrounds.
  • Internet Explorer: No native support either. I suppose the VML approach presented here works only well in the controlled environment of the qooxdoo widget toolkit, but I may be proved wrong.

qooxdoo 0.8 Event Layer

qooxdoo 0.8 will include a new, sophisticated low-level event layer. Not only does this separate layer allow for a clean architectural design (with a high-level GUI toolkit on top), it will also make it possible to use this reduced set of low-level DOM features without qooxdoo's advanced widget system. Particularly for rather traditional web pages instead of full-featured rich internet applications, such a light-weight, standalone qooxdoo built might be more favorable. One central element for such a low-level layer is DOM event handling.

In qooxdoo 0.7, event handling is tightly integrated, rather intermingled, with the widget system. We have now taken the best parts of the old event handler, like key and mouse event normalization, and integrated them into a new standalone event layer.

This event layer has many interesting features. Unlike event layers commonly seen in other JavaScript libraries it does much more than just providing a cross-browser API wrapper for attaching event listeners:

We just did a presentation about this new event layer. Take a look at the Slides: qooxdoo 0.8 Event Layer [PDF] or at the corresponding wiki pages [5] for more information.

[1] http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow
[2] http://msdn2.microsoft.com/en-us/library/ms537630.aspx
[3] http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface
[4] http://qooxdoo.org/documentation/0.7/keyboard_events
[5] http://qooxdoo.org/documentation/general/dom_event_layer

qooxdoo.org re-org

To streamline our web site and simplify the way information is delivered to you, we have merged the blog and the news section into one, under the news label. The old blog URL (blog.qooxdoo.org) is still available, but all new posts will show up under the news URL. Please update your bookmarks and feeds.

Mysterious security zone issue in IE7

It seems that Microsoft's brand new operating system, Windows Vista, introduced at least one interesting, not to say mysterious, phenomenon. It only arises when the user is trying to open a local HTML file with so-called "active content".

After some investigation we found out that it is problematic to open local HTML pages which reference non-existing JavaScript files. During development of qooxdoo applications this could be caused by renaming or moving a class without a re-execute of "make" to re-index the available classes (to regenerate the includer script).

Annoyingly, the displayed error is not very helpful. It just says "Invalid character" in line "0". No hint about security at all. All files are stored on the local file system. No "src" attribute uses another protocol like "http://"or an address of an (external) server. Just simple, relative paths. There seems to be no reason to interpret them the way IE7 under Vista does. The files do not access remote resources. They are not stored in other security zones. We really do not know what Internet Explorer "thinks" in this case.

In all other browsers a non-existing JS file is just ignored. No warning at the error console etc. (Ok, this could be improved here, too).

Please also take a look at the corresponding bug report. Any idea if this is a real IE7/Vista bug?

qooxdoo Syntax-Highlighting for UltraEdit

I have just spend some minutes to update my wordfile for Ultraedit to correctly handle and highlight qooxdoo 0.7 JavaScript code. This is optimized for typical qooxdoo formatting and class declaration. It works well with my preferred indention of 2 spaces. For other indentions it needs a little modification to correctly detect all functions. BTW: Ultraedit has no possibility to differ between static and normal members. This is a result of the quite limited RegExp based matching. Download qooxdoo Wordfile for Ultraedit

Next Page »
 

Control

 

Categories:

Archives:

 
SourceForge.net Logo

Bad Behavior has blocked 635 access attempts in the last 7 days.