The week in qooxdoo (2012-02-03)
Just referencing the list of bugfixes, as most team members were absent this week or busy with unresolved tasks:
BugfixesFor a complete list of tasks accomplished during the last working week, use this bugzilla query.
Have a nice weekend.
An update on Network and color values in CSS
Lots of changes in the Network inspector have now made it into an experimental build. The main purpose of the makeover is to give more insight on what happens on the Network side of Opera, with powerful new filtering and search functionality.
The type filter now lets you narrow down the view to certain types of Resources. In addition, you can also look only at the Resources that were requested via XMLHttpRequest. Also you can use CTRL/CMD + click, to combine multiple filters.

We have added an inline search, which works consistently over the URL list, table view, and in the details.

The graph view now uses specific colors to represents the different phases of resource retrieval as segments within each row. A new tooltip lets you see a sequence of internal events in Opera that occur during the retrieval and how much time was spent on each. Note that the values represent the time elapsed between two events.

Although the standard graph view is useful for visualizing the loading flow, sometimes developers may be more interested in picking out specific data about their requests. You can now switch from flow view to a table view, which can be sorted and further customized via the context menu.

Selecting each line will provide the specifics of each request in the Details view, which shows the actual request and response of each network activity, including headers and body. This view has been streamlined: headers are split into key/value pairs, and the response body is shown inline.

Most of these UI changes are still work in progress, but they should give you an indication of where we're heading. A few known issues:
- The line-height of tables can get out of sync with the list of URLs on the left-hand side
- Content tracking is not enabled by default, but available as a toggle in the Network options tab. Without tracking, the response body will sometimes not be shown in the Details view
- The search may sometimes match parts of the UI itself
- The layout in the details view sometimes breaks due to long headers or body
- Timing information in the Network view is not accurate, as it can be affected by other debugging activities in Opera. In general, the loading flow will be slower when Opera Dragonfly is running. We plan to address this issue with a special network-profiler mode, which is on the roadmap for later this year.
But wait, there's more! As a bonus, this build also includes some new features in our Style inspector. We now show color swatches next to all color values. And – as hotly requested by many of our users – it's now possible to use your preferred color format: Hex, RGB or HSL (which can be changed in Settings → Documents → Styles). Other changes include clickable links (which open in the Resources tab) and a streamlined view in the Computed Style panel.

jQuery 1.7.2 Beta 1 Released
Hey there Internets, it’s the jQuery Core team! We haven’t talked in a while, but over the holidays we were busy fixing the bugs you reported. The result of that hard work is jQuery 1.7.2 Beta 1. We decided to get a beta out by Groundhog Day so you wouldn’t be in the shadow of six more weeks of unfixed bugs.
You can get the code from the jQuery CDN:
Oh, we know what you’re thinking: “Cool, a new version of jQuery; I’ll wait until the final release has been out a few weeks and then I’ll give it a try.” Right, and then you’ll find some bug that keeps you from upgrading. Nothing makes us sadder than finishing up a release and only then seeing a report of a serious bug that could have been fixed earlier.
So please, come out of your burrow and try this beta with your code. Did we miss an old bug? Did we create a new bug that makes you feel like Bill Murray waking up to “I Got You Babe?” We want to know. You can use the bug tracker to report bugs; be sure to create a test case on jsFiddle so we can figure it out easily. If you’re not sure it’s a bug, ask on our forum or on StackOverflow.
jQuery 1.7.2b1 Change LogThe current change log of the 1.7.2b1 release.
Ajax- #10978: jQuery.param() should allow non-native constructed objects as property values
- #5571: Allow chaining when passing undefined to any setter in jQuery
- #10692: Configure the jshint options to more accurately match the style guide
- #10902: ability to test a built version of jQuery in unit tests
- #10931: Unit tests shouldn’t require internet access
- #10466: jQuery.param() mistakes wrapped primitives for deep objects
- #10639: outerWidth(true) and css(‘margin’) returning % instead of px in Webkit
- #10754: have jQuery.swap return the return of the callback instead of just executing it
- #10782: Incorrect calculating width
- #10796: Bug in IE7 with $(‘#el’).css.(‘background-position’)
- #10858: css.js regular expressions are incomplete
- #11119: The curCSS function only need 2 arguments
- #8498: Animate Hooks
- #10006: method show is not working as expected in all browsers when called for document fragment
- #10848: Animation toggling loses state tracking in certain atomic edge cases
- #8165: .live(‘click’, handler) fires on disabled buttons with child elements in Chrome
- #10819: Eliminate “this.on.call(this, “
- #10878: $(“select”).live(“change”, function(){ …broken in IE8 in jQuery 1.7
- #10961: Error in XRegExp using jQuery 1.7.1 in IE6-9
- #10970: The .on() selector parameter doesn’t work with :not(:first) selector
- #10984: Cannot off() custom events ($.event.special)
- #11021: Hover hack mangles a namespace named “hover”
- #11076: .clone(true) loses delegation filters
- #11130: jQuery.fn.on: binding map with null selector ignores data
- #11145: $(document).on() not working with name=”disabled”
- #9427: Passing undefined to .text() does not trigger setter
- #10753: inline the evalScript function in manipulation.js as it’s only used once
- #10864: text() method on a document fragment always returns the empty string
- #11055: Update HTML5 Shim elements list to support latest html5shiv
- #10952: .fired() doesn’t work on Callbacks object when it is flagged with “once”
- #11257: Wrong path to source files in test suite if PHP missing
- #11048: Support Tests affect layout for positioned elements in IE6-9
Firefox 10 is now available
Firefox 10 is now available as a free download for Windows, Mac, Linux, and Android. As always, we recommend that users keep up to date with the newest version of Firefox for the latest features and fixes. The release notes for Firefox 10 are available here.
The week in qooxdoo (2012-01-27)
Welcome back, and on to a great feature addition:
Source code? In my API Docs?It's more likely than you think, thanks to a new feature in the API Viewer. You just need to define the base URI for your SCM's web view (e.g. GitHub, ViewVC, ...) in your library's Manifest.json file and the API Viewer will automatically add links to the source file for each class. For functions, the link can optionally include a line number parameter, so the source view can jump straight to the implementation. See the API viewer manual page for details.
BugfixesFor a complete list of tasks accomplished during the last working week, use this bugzilla query.
C U around next time.
More dynamic JavaScript value inspection
For example, for a code fragment of ele.getElementsByTagName('ul')[0], you normally get a generic tooltip for the [0] array when hovering over the square bracket.

With shift, the automatic selection will also include the parentheses and you will now get a tooltip relating to the evaluated selection — in this case, the first ul element in the ele object.

Additionally you can select any text, hold down the shift key, and get a tooltip with the according evaluated value.
Selection now also works over several lines.
We have also added a new tooltip for all JavaScript inspections. For properties of type object we show the according class. If you now hover over the class name of any Element, Function, Date, RegExp, Error and Exception, you will get a tooltip with a pretty-printed representation. This also works on top of an other tooltip:
If you hover the pretty-printed tooltip of an element, the according node in the document gets scrolled into view and highlighted.
This is all available on experimental now. Take a look and tell us what you think!
MooTools 1.4.3 Released
Today we release MooTools Core 1.4.3 which is a small maintenance release. Upgrading from 1.4.2 should not cause any backward incompatibilities. We recommend that all users upgrade to 1.4.3 as soon as possible.
Fixes- #2109: IE7/8 getProperty returns functions
- #2110: Documentation: Request.JSON’s behaviour of onFailure
- #2117: Document conflicts between Array and Elements methods
- #2121: Missing Fx.options.frameSkip documentation.
- #2126: Re-add undocumented from argument to Element.fade
- #2127: Element.js memory leaks
- #2146: Add Element.NativeEvents to docs
- #2150: Add Fx.isPaused() method
- #2152: Packaging issue. Build header and Core.js yml header collide
- #2155: Add special note to Element.empty
- #2163: IE7 Crash with Mootools Core 1.4.2
- #2164: Cannot set numerical 0 values to form fields.
- #2169: Array#filter should store this[i] in a variable before calling the callback.
- #2170: propertychange on an input[type=radio] with this.checked fires standard onChange
- #2176: uid remnant which prevented proper cleaning of elements and their storage
- #2182: element.erase( ‘html’ ) sets content to text ‘undefined’
- #2129: < IE9 sets width/height attribute once, and doesn’t update on other loads
- #2130: Object.each doesn’t address IE DontEnum bugs like Object.extend and others
- #2160: Fx.Tween/Fx.Morph problem with ‘%’ unit
- #2168: Fixes 2129.
- #2175: IE Leak: Array.flatten
- #2178: IE doesn’t set value when creating element if css attributes are used
- #2183: Incorrect event.key from some keypress events in Firefox
- #2184: IE9 on Windows Server throws exception; can’t continue
- #2185: Fix #2184: IE9 on Windows Server throws exception; can’t continue
- #2188: Fixes #2178 - A input field should keep its value even when the type property is changed (in IE)
- #2189: Uncaught TypeError: Property ‘id’ of object # is not a function
- #2193: Element clone storage again
- #2194: Function#bind ES5 bug when bound function is called as part of a new expression
- #2196: it’s better for getStyle method always returns style value with px unit
- #2199: Browser.version always returns the same for Android 2-4
- … and more
These issues will be fixed subsequently prior to release of the next maintenance release, 1.4.4.
ContributeThese fixes and improvements would not have happened if you didn’t submit an issue (ticket) to the MooTools Core Issues, or reporting your problems in the MooTools User Group. Send us your (MooTools) issues (or feature requests) so that your favorite JavaScript framework keeps getting better.
Get it!- Download MooTools Core 1.4.3; Build MooTools Core 1.4.3
- Fork / clone MooTools Core 1.4.3 from GitHub, and build it yourself with Packager.
- Google CDN (will be updated soon)
- Browse the Documentation for Core & More.
The week in qooxdoo (2012-01-20)
Just a brief update on bugfixes this time, as there are mostly larger tasks still in the works.
BugfixesFor a complete list of tasks accomplished during the last working week, use this bugzilla query.
C U again next time.
The week in qooxdoo (2012-01-13)
Welcome to the weekly blog post. This time it's a short one, as we want to refer to and feature community achievements - in individual blog posts. One of those is the LIBERATED project by Derrell Lipman. Check it out to get to know about exciting new ways of client-server communication, with a corresponding, transparent programming model.
There are more individual posts about community projects and real-life app examples to be published in the future, so stay tuned.
BugfixesFor a complete list of framework tasks accomplished during the last working week, use this bugzilla query.
C U.
New Contribution: LIBERATED
Derrell Lipman, a long-term qooxdoo contributor and active supporter of the framework, has been working on a very exciting project for the past year or so, and has already based a complete application on it. We happily share the following information with the community. Great achievement, Derrell, thanks for contributing!
In traditional client-server development...Traditional web-based client-server application development has been accomplished in two separate pieces: the frontend portion which runs on the client machine has been written in HTML and JavaScript; and the backend portion which runs on the server machine has been written in PHP, ASP.net, or some other "server-side" language which typically interfaces to a database. The skill sets required for these two pieces are different, meaning that sometimes the frontend and backend are developed and tested completely independently, based purely on an interface specification. More recently, server-side JavaScript has begun to gain momentum, allowing for more overlap of skill set, but still requiring separate development and testing of the frontend and backend pieces.
Be LIBERATED from those hassles!LIBERATED is a new methodology for web-based client-server application development, in which a simulated server is built into the browser environment to run the backend code. This allows the frontend code to issue requests to the backend in either a synchronous or asynchronous fashion, step, using a debugger, directly from frontend code into backend code, and to completely test both the frontend and backend portions. That exact same backend code, now fully tested in the simulated environment, is then moved, unaltered, to a real server. Since the application-specific code has been fully tested in the simulated environment and moves unchanged to the server, it is unlikely that bugs will be encountered at the server that did not exist in the simulated environment.
Be LIBERATED!LIBERATED is a fully in-browser client and server web application debug and test environment, and qooxdoo-based backend environment. It allows (but does not require) you to write all of your code, both client- and server-side, in JavaScript, using qooxdoo coding style. It has a database abstraction layer, with existing database drivers for App Engine's object datastore and SQLite's SQL-accessed relational database. Additional database drivers can easily be written. There is also a built-in JSON-RPC Version 2.0 server. Additional handlers, such as REST, could be implemented for use instead of or in addition to JSON-RPC.
The real benefit of LIBERATED is that it allows the entire application, both frontend and backend, to be debugged and tested fully within the browser environment, running the backend code in the LIBERATED server simulator. This means you can set breakpoints with Firebug in your backend code, step through to find bugs, etc. Once all of your code is fully debugged and tested in the simulated environment, you simply move the backend code, generally with no changes, to the real server.
Architecture
The figure above shows the architecture of the development and production environment when developing with LIBERATED. The frontend code runs on the client machine (i.e., in the browser). Backend code runs on a server machine and/or on the client machine, with the exact same application code ("business logic") and application communication protocol, e.g., JSON-RPC, REST, etc., code in both environments. The actual database differs in the two cases, but the application's interface to the database is identical regardless of which backend is in use. Similarly, the application communication protocol code is the same regardless of backend, but the messages arrive from web servers unique to the backend, for parsing.
Further detailsLIBERATED is simply a "library", in qooxdoo parlance. It is installed like any qooxdoo contrib or other library by referencing its Manifest.json file in the application's config.js "libraries" section. LIBERATED currently runs in App Engine or with the Jetty web server.
As to using it, LIBERATED is described in excruciating detail in Derrell's thesis. Although that document uses the current name of the library (LIBERATED), it predates the renaming of the namespace, so anyplace you see rpcjs in the document is now called liberated.
The API documentation should be quite complete, so running ./generate.py api from the top level will provide the normal API viewer with a fair amount of useful information. In particular, for database manipulation, see liberated.dbif.Entity. Some additional and better user-level documentation would definitely be useful, and might be added over time. Derrell invites you to get familiar with LIBERATED and appreciates your feedback.
The week in qooxdoo (2012-01-06)
Hi and hello from the qooxdoo news desk! I hope you all had a nice and refreshing holiday season, and we all wish you luck and success for the new 2012. Hack away!
The new year is taking up slowly, with a couple of colleagues still away from the office. But, lo and behold!, we got some news to share nevertheless.
qooxdoo BookWe are happy to report that the first dedicated text book on qooxdoo has materialized
. Rajesh Kumar Bachu and Mohamed Raffi have written the qooxdoo Beginner's Guide, published by Packt Publishing. Thank you, guys! It focusses on RIA development and takes the reader through all the stages, from the basic OO foundations, over widgets, containers and layouts, to backend communication, theming and custom widgets, featuring a Twitter application for the demonstration. It covers qooxdoo version 1.4, but should be helpful for anybody starting with qooxdoo, even with the current 1.6 kit. If you ever longed for a comprehensive introduction into the qooxdoo framework in book form (one of those three books you would carry onto the island
), by people coming from the application development field, this book should be interesting.
In qooxdoo 1.6, the body of a request sent by invoking a resource’s action included all parameters not associated to a URL placeholder. This works when the service expects URL encoded parameters or JSON, but the automatic distribution of parameters also has its limitations. For instance, it is not possible to populate the request body with an array (or any kind of none namespaced value). Therefore, we decided to introduce another parameter to invoke() and associated methods which allows to set the request’s body directly. For better consistency, we dropped the automatic distribution, so if you've been relying on it please make sure to split the parameters. For more details, please refer to the API doc.
BugfixesFor a complete list of tasks accomplished during the last working week, use this bugzilla query.
Github via SVNSince we switched to Github for our main qooxdoo repository we recommended the "old-ish" SVN gateway that Github offers (svn.github.com), for those that used to follow our old SVN trunk and that were not ready to jump boat and embrace Git as their client VCS. Although there were new offers for SVN access from Github at that time, we found that the new interface was less reliable and often a lot slower. Meanwhile, Github has been busily working on the new interface, and recent tests show that the new interface is performing much better, even being faster than the old. So, if you are stuck with reading qooxdoo sources through SVN for the time being, you may want to give the new interface another try. Please report back how it is working for you.
To recap, here are the two interfaces again:
old: svn co http://svn.github.com/qooxdoo/qooxdoo.git
new: svn co https://github.com/qooxdoo/qooxdoo/trunk
The new interface also features checking out branches or subpaths of the repository.
MeetAndSpeak is an advanced but lean chat tool for groups. It is currently completely free for everyone to use. The user interface mimics classic desktop IRC clients.
Included are secure HTTPS connections, logging and always online functionality. Users can't miss messages. The creator of a group has full control over it. It is also possible to use MeetAndSpeak as an IRC client, connections to Freenode and IRCNet networks are possible. The main view is window-based and allows the user to easily follow several parallel discussions in different groups.
That wraps it up for this week - be in touch next time.
Looking for DojoConf in Europe? Try Web-5 in April!
The very successful and inspiring DojoConf in DC last September has led many to ask us when there will be a DojoConf EU?
While we have no immediate plans, active Dojo user “PEM” of the Web-5 Association is organizing Web-5 in Béziers, France in early April. In addition to 6 excellent Dojo talks, the conference will also include more general talks on HTML5, Mobile Web, Node.js, WebGL, performance, and general JavaScript and web application development topics.
Early registration is now open with a 33% discount available for the first batch of sign-ups. We hope to see you in beautiful Béziers, to talk about Dojo and web development:

JxLib: An Introduction
Jon Bomgardner is a contributor to the jxlib.org project. After recently joining the MooTools Developer mailing list and sharing his experience in upgrading jxlib to MooTools 1.4.2 we asked him to share his work here on the blog.
What is JxLibJxLib is a JavaScript UI framework built on MooTools. It allows web developers and designers to quickly build user interfaces for their applications. JxLib is based on some sweet HMTL markup and strives to be fully CSS compliant. It is also a modular library allowing you to pick and choose from the available components as well as giving you the ability to override default behaviors and extend core classes.
All of this flexibility is, in large part, due to being built on MooTools. The library is heavily object-oriented with a huge number of classes inheriting from a single base. If you know how to use the MooTools class system you will quickly get up to speed on JxLib. In addition to being based on HTML and CSS, which provides an amazing amount of flexibility itself, the library’s architecture is based on a plugin system that allows additional functionality to be added to each component at the developer’s discretion.
A couple of quick examplesSo, I wanted to show a couple of easy examples of what you can do with JxLib. There’s a ton of functionality built in and for more complete examples you can check out the examples page at jxlib.org. Here are 3 quick jsfiddles that you can play around with to get a feel of some of the functionality.
Example 1: Drop Down Menu ToolbarThis example shows a simple menu toolbar with cascading menus
Example 2 : Jx.Form and Form fieldsThis example shows off Jx.Form and a lot of the bundled fields you get out of the box.
Example 3: The New Jx.Container and Jx.LayoutManager classesThis one shows off some of the new work in JxLib 3.1.1. It creates the entire layout using a single javascript object. Check out the center panel’s tabs for a look at Jx.Editor and other components.
Experiences achieving compatibility with Core 1.4.2I am happy to report that the conversion to Core 1.4.2 went relatively easily. The biggest conversion headache was when I originally worked on getting compatibility with 1.3.2 - that was a ton of work. We used many of the $ global methods ($defined, $H, $A were some of the big ones) and they were littered about the code base quite liberally. I really didn’t want to use the compatibility layer that the folks here at MooTools so graciously provided everyone because the download was big enough as it was. Hunting down all of those changes took the most time. In the process of doing so however I learned a few interesting tidbits:
First, it was best to replace $defined() with a check for undefined and null. for example:
if ($defined(some_variable)) {
became
if (some_variable !== undefined && some_variable !== null) {
I realize that the conversion docs state that checking undefined should be enough but when I tried that at first I got a LOT of weird errors. This change fixed them.
The other thing I discovered is that Object.each and Object.keys weren’t all that useful when the object you’re using them with was actually on the prototype of the class they were in. For example, in JxLib 2.0 we had this code:
processElements: function(template, classes) {
var keys = classes.getValues();
elements = this.processTemplate(template, keys);
classes.each(function(value, key) {
if (key != 'elements' && elements.get(value)) {
this[key] = elements.get(value);
}
}, this);
return elements;
}
It seems that those two functions use hasOwnProperty() which was causing the loop above to have 0 iterations because the classes variable was actually this.classes which was found on the prototype of the class. When converting to Core 1.3.2 (and subsequently 1.4.2) we had to use this:
processElements: function(template, classes) {
var keys = [],
values = [];
for (var key in classes){
if (key !== undefined) {
values.push(classes[key]);
keys.push(key);
}
}
elements = this.processTemplate(template, values);
keys.each(function(key){
if (key != 'elements' && elements[classes[key]] !== undefined && elements[classes[key]] !== null) {
this[key] = elements[classes[key]];
}
},this);
return elements;
}
Once those were figured out, and we had full compatibility with 1.3.2, moving up to 1.4.x was pretty painless. For more info on what I learned during the conversion (some of it not MooTools or even javascript related) check out my blog post.
Get More informationYou can get more information on JxLib at the following places:
- JxLib website
- JxLib github repository
- JxLib Google Group
- JxLib on Lighthouse
- Blog post on getting started with JxLib
If you have any questions or comments feel free to leave those below or in the Google group (linked above). Also, if you like what you’ve seen and read here please consider pitching in and helping to make JxLib even better. We have many plans for future releases but could always use a few extra hands.
MooTools Behavior
Those of you who follow my work over on Clientcide may already be familiar with it, but for the rest of you I wanted to write a blog posts here on MooTools.net about the work I’ve been doing on a library called Behavior - a throwback to the behavior.js library released way back in 2005 which one might consider to be philosophically an ancestor of sorts.
PurposeAll well-written web sites / apps that are interactive have the same basic pattern:

Each page of a site or app you build is esoteric. It may have any combination of interactive elements, some of which interact with each other (for example, a form validation controller might interact with an ajax controller to prevent it sending a form that isn’t valid). Typically this “glue” code exists in a DOMReady statement. It says, get this form and instantiate that class with these options. This code is brittle; if you change either the DOM or the code the state breaks easily. It’s not reusable, it only works for a specific page state. It can easily get out of hand.
Behavior attempts to abstract that DOMReady code into something you only write once and use often. It’s fast and easily customized and extended. Instead of having a DOMReady block that, say, finds all the images on a page and turns them into a gallery, and another block that searches the page for all the links on the page and turns them into tool tips, Behavior does a single search for all the elements you’ve marked. Each element is passed through the filter it names, where a filter is a function (and perhaps some configuration) that you’ve named. Each of these functions takes that element, reads properties defined on it in a prescribed manner and invokes the appropriate UI component.
Why?The nutshell is that instead of having a DOMReady function that finds the stuff in your DOM and sets up instances of classes and whatnot, you put the configuration in the HTML itself and write the code that calls new Foo(...) only once. Example:
So instead of this:
$$('form').each(function(form){
new FormValidator(form, someOptions);
new Form.Request(form, someOptions);
});
new Tips($$('.tip'));
$$('.accordion').each(function(container){
new Accordion(container.getElements('.toggler'), container.getElements('.section'), someOptions);
});
//etc
You do this:
<form data-behavior="FormValidator FormRequest" data-formvalidator-options="{someOptions}">...</form>
<a data-behavior="Tip" title="I'm a tip!">blah</a>
<div data-behavior="Accordion" data-accordion-options="{someOptions}">...</div>
Think of it as delegation (as in event delegation) for class invocation. If you use DOMReady to do your setup and you want to swap out some HTML with AJAX, you need to reapply that startup selectively to only your components that you’re updating, which is often painful. Not with Behavior, you just apply the filters to the response and call it a day.
You do a lot less DOM selection; you only ever run $$('[data-behavior]') once (though some filters may run more selectors on themselves - like Accordion finding its togglers and sections).
DOMReady setup is always closely bound to the DOM anyway, but it’s also separated from it. If you change the DOM, you might break the JS that sets it up and you always have to keep it in sync. You almost can’t do that here because the DOM and its configuration is closely bound and in the same place.
Developers who maybe aren’t interested in writing components don’t need to wade into the JS to use it. This is a big deal if you’re working with a team you must support.
Behavior is designed for apps that are constantly updating the UI with new data from the server. It’s not an MVC replacement though. It’s designed for web development that uses HTML fragments not JSON APIs (though it can play nicely with them). If you destroy a node that has a widget initialized it’s easy to make sure that widget cleans itself up. The library also allows you to create enforcement to prevent misconfiguration and an API that makes it easy to read the values of the configuration. (More on that in a bit).
There are some other nifty things you get out of it; you get essentially free specs tests and benchmarks because the code to create both of them is in the Behavior filter. Here’s an example of what it takes to write a spec for a widget and ALSO the benchmark for it’s instantiation (this uses Behavior.SpecsHelpers.js).
Behavior.addFilterTest({
filterName: 'OverText',
desc: 'Creates an instance of OverText',
content: '<input data-behavior="OverText" title="test"/>',
returns: OverText
});
This code above can be used to validate that the HTML fragment passed in does, in fact, create an OverText instance and it can also be used with Benchmark.js to see which of your filters are the most expensive.
DelegatorIncluded in the library is also a file called Delegator which is essentially the same thing except for events. For example, let’s say you have a predictable UI pattern of having a link that, when clicked, it hides a parent element. Rather than writing that code each time:
document.body.addEvent("click:a.hideParent", function(e, link){
e.preventDefault();
link.getParent().hide();
});
You register this pattern with Delegator and now you just do:
<a data-trigger="hideParent" data-hideparent-options ="{'target': '.someSelector'}">Hide Me!</a>
It provides essentially the same value as Behavior, but at event time. The above example is pretty straight forward so, you know, why bother, right? But consider how many of these little things you write to make a web app function. If you can create them once and configure them inline, you save yourself a lot of code.
BehaviorAPIThis stand-alone library facilitates reading values from element data- properties. Examples of the HTML expressions evaluated are as follows (all of the following produce the same output):
<tag data-behavior="Filter1 Filter2" data-filter1-options="{'opt1': 'foo', 'opt2': 'bar', 'selector': '.selector'}"> //prefered
<tag data-behavior="Filter1 Filter2" data-filter1-options="'opt1': 'foo', 'opt2': 'bar', 'selector': '.selector'"> //no braces on JSON
<tag data-behavior="Filter1 Filter2" data-filter1-options="{'opt1': 'foo', 'opt2': 'bar'}" data-filter1-selector=".selector">
<tag data-behavior="Filter1 Filter2" data-filter1-opt1='foo' data-filter1-opt2='false' data-filter1-selector=".selector">
The -options value is parsed as JSON first (it’s slightly more permissive in that you don’t have to wrap it in {} just for convenience). Values defined here are read as defined allowing you to express arrays, numbers, booleans, etc. Functions / callbacks are generally not used by Behavior.
If you attempt to read a value that isn’t defined in this options object, the property name is attempted to be read from the property directly (e.g. data-behaviorname-prop). This value is always a string unless you specify a type. If a type is specified the value is run through the JSON parser and validated against that type.
Even if you don’t want to use the whole Behavior suite, this library may be of use if you like the idea of including configuration inline. There’s a lot more in BehaviorAPI so it’s worth perusing the docs for it.
Documentation Stock BehaviorsCheck out these resources of available Behavior Filters provided by the author:
- https://github.com/anutron/more-behaviors
- https://github.com/anutron/clientcide
- https://github.com/anutron/mootools-bootstrap
- MooTools Bootstrap Demos and Docs
- Clientcide (click on “demos” and check out the delegators and behaviors at the bottom of the left nav)
Below are some notes regarding the implementation. The documentation should probably be read first as it gives usage examples.
- Only one selector is ever run; adding 1,000 filters doesn’t affect performance.
- Nodes can have numerous filters.
- Nodes can have an arbitrary number of supported options for each filter (data-behaviorname-foo="bar").
- Nodes can define options as JSON (this is actually the preferred implementation - data-behaviorname-options="<your JSON>").
- Elements can be retired w/ custom destruction; cleaning up an element also cleans up all the children of that element that have had behaviors applied.
- Behaviors are only ever applied once to an element; if you call myBehavior.apply(document.body) a dozen times, the elements with filters will only have those filters applied once (can be forced to override and re-apply).
- Filters are instances of classes that are applied to any number of elements. They are named uniquely.
- Filters can be namespaced. Declare a filter called Foo.Bar and reference its options as data-foo-bar-options="...".
- There are “global” filters that are registered for all instances of behavior.
- Instance filters get precedence. This allows for libraries to provide filters (like http://github.com/anutron/more-behaviors) but for a specific instance to overwrite it without affecting the global state. (This pattern is in MooTools’ Form.Validator and works pretty well).
- Due to the DOM-searching for both creation and destruction, you can’t have behavior instances inside each other.
You can find Behavior on github and also on Clientcide where you’ll also find a builder. That builder will also let you get the stock behaviors from Clientcide and the ones I’ve authored for MooTools More. If you want to get to the bootstrap builder, be sure to select “MooTools Bootstrap” in the top menu (or just clicketh hereth).
The week in qooxdoo (2011-12-16)
Here comes another weekly status update, a rather short one this time.
Regression in 1.6Just after the 1.6 release, we discovered a bug that slipped through testing. To our knowledge only Opera is affected. And only if the method getStackTraceFromError() is being used, which mainly happens in a development/debugging context, typically not in a regular app context. Due to these special preconditions, we decided this did not warrant a bugfix release. Please let us know if you notice this problem in the deployment version of an application.
Now for some detailed information: As mentioned above, it affects qx.dev.StackTrace.getStackTraceFromError: This method will throw an exception if called with a qooxdoo exception object (qx.type.BaseError, qx.core.WindowError, qx.core.GlobalError or qx.dev.unit.RequirementError) in a browser that supports the stacktrace property on error objects - apparently only Opera.
BugfixesFor a complete list of tasks accomplished during the last working week, use this bugzilla query.
That's it for today. C U again next week, then already close to Xmas.
Dojo 1.7.1 is Released!
We’re happy to announce Dojo 1.7.1 is now available for download.
Review the list of issues resolved in this release.
Please report any new issues you find in your testing with your Dojo Foundation account. Links to CDN, and an updated reference guide, web site, and tutorials for 1.7 will be available soon.
And special thanks to Colin Snover and Ken Franqueiro for managing this release!
Plugins Site Update: The Old Is New Again
We’ve gotten a lot of feedback since last week’s announcement about the plugins site’s unfortunate tumble into oblivion, and I’d like to address a few of the most important concerns that have surfaced since.
“Could you make the old backup available for posterity?”Yes. We can — and have. Over the weekend, we restored the most recent backup we had, and the original site is now living at archive.plugins.jquery.com; you should be able to browse through everything that’s there to your heart’s content. We also applied the most recent user information we had, so if you had an account on the old site at any point in the last year, it should still work. However, the site is closed to new user registrations. If you really need a new account, please get in touch with me personally and I can get that straightened out for you. We’ve also set up a redirect, so that if you should encounter any links to plugins.jquery.com in your browsing, you’ll (hopefully) end up at the corresponding page in the archive.
Just get a backup from the Wayback Machine!While the Internet Archive has cached versions of content that was updated more recently than last October, we just don’t have the people-power to re-create the lost posts manually in the new archive site. If you have an account, you can feel free to add “new” or old plugins, or update existing ones, should you desire to. However, this archive will not be indexed by search engines.
If you hate CMS-es so much, what’s with WordPress?We’re in the middle of a network-wide redesign, and WordPress offers us a valuable set of tools when it comes to theming, searching, and serving a group of sites. Our new motto, however, is pull requests, not passwords; we’re implementing theming, documentation, plugins, and more in such a way that contribution will not actually require an account on our CMS at all. As I outlined in the initial post, the plugin submission process will only involve adding a post-receive hook to your repository. In the event of a similar catastrophe, we’re made sure we’ll be able to replay the entire plugin contribution history and get the site back up to speed right away. Our goal is to leverage the WordPress features we find useful without it serving as a barrier to entry or as the canonical warehouse of content. If you are of the mind that WordPress is always a bad idea, no matter what, no matter how, you’re certainly entitled to that opinion, but at this point, it’s not particularly beneficial to the conversation.
Git(Hub) is hardThe new plugins site will serve as an index of plugins, with a simple “download” button right on each plugin’s page. You will not have to just browse around GitHub looking for jQuery plugins. If you don’t know git and only ever want to download jQuery plugins, you don’t have to learn it. However, if you want to submit plugins, you’ll have to be using some sort of source control that you can at least mirror in git. This is by design: it can be really easy to build a jQuery plugin, but that doesn’t mean it’s necessarily fit for public consumption. Requiring the use of source control and package.json are passive mechanisms that will help ensure that plugins which proliferate are authored by developers who have met a reasonable baseline (and aren’t selling batteries). We’re only targeting GitHub support for launch, but we’d like to add support for other services as well. We are actively avoiding the use of GitHub-specific features that would force us to limit the site to GithHub users permanently.
It’s A Conspiracy!Some have called into question the veracity of my account, and that’s understandable, given the timing and circumstances. But believe me, the last thing I wanted to do after spending a day manually pruning spam from the directory was turn around and cause a gigantic headache for thousands of people, including myself and my colleagues. I hope the re-launching of the last backup at least partially allays these concerns. Additionally, we’re starting off with GitHub simply because it has a very broad user base already, and it has been incredibly positive for us since we shifted to it for development of jQuery Core, UI, and Mobile.
Thanks again for bearing with us during this transition.
Welcome to Maurits Lamers and Mitch Oliver
Hot on the heels of last week’s introduction of five new team members, I’m pleased to announce that Maurits Lamers and Mitch Oliver have also signed on as SproutCore Committers. As with the people from my previous post, these names should be of no surprise to anyone who has been with SproutCore for some time.
For those that aren’t sure of the difference between Committers and Reviewers, Committers are actually required to work in their own branches in the repo and submit every change as a pull request to be accepted by a Reviewer. The Reviewers are allowed to make direct fixes, but will most likely submit anything at all substantial as a pull request too in order to get another Reviewer’s feedback and acceptance. Both roles also include the responsibility to try to move the outstanding issues and pull requests towards a resolution.
As you can tell from the above description, both roles are a lot of work and it takes people with a real dedication to the project to accept what can be a thankless and demanding task, so please take a moment to catch all of these people on #sproutcore and sproutcore@googlegroups.com and show them your support.
Dojo 1.7.1 Release Candidate 1
We’re happy to announce Dojo 1.7.1rc1 is now available for download.
Review the list of issues resolved in this release.
Please report any new issues you find in your testing with your Dojo Foundation account. The plan is to release on Monday, December 12th, unless any major issues are found between now and then.
3.2 $.Controller - Templated Event Binding
JavaScriptMVC 3.2 brings a lot of great features and enhancements. So many features that changes to $.Controller didn't make the cut for our upcoming 3.2 article. This article reviews 3.2's $.Controller and talks about templated event binding (something we neglected to write up for 3.1).
Bind and Memory LeaksNeglecting to unbind event handlers is the easiest way to create memory leaks. This is extremely common in an MVC architecture as you constantly listen for model changes:
Task.bind('created', function(ev, newTask){
// add task to list
})
If your widgets are repeatedly added and removed from the page, you must remember to unbind these event handlers. People forget it all the time! This happens because simple jQuery plugins (which people use as template and learning tools) typically will not leak.
Simple plugins bind only on elements within the element the plugin was called on. jQuery cleans up these event handlers automatically. For example, a tabs might look like:
$.fn.tabs = function(){
// listen when an li is clicked and show tab content
this.find('li').bind('click', function(){
// show tab content
})
}
$('#tabs').tabs()
If the #tabs element is removed like:
$('#tabs').remove()
jQuery will remove all event handlers on the element and in the element's children. But, if you are listening to anything outside the widget's element (say the <body> or a Model event), jQuery will not remove the event handler. Lets explore this with a leaking tooltip:
A Leaking TooltipTo understand the problem of event handler leaking, consider a simple tooltip widget. The tooltip works by calling:
$('#tooltip').tooltip("Here is the text")
This will write "Here is the text" to the bottom right of the #tooltip element. The code for this tooltip looks like:
$.fn.tooltip = function(html){
var el = $('<p>').html(html),
offset = this.offset();
el.appendTo(document.body)
el.offset({
top: offset.top + this.height(),
left: offset.left + this.width(),
position: 'absolute'
})
$(document.body).click(function(){
el.remove();
})
}
See what's wrong? This code does not error, it leaks! If you can't spot the leak, don't feel bad. We've seen this mistake many, many times.
The problem is that although the element is removed, the body's click handler is not unbound. This function is still referenced by the DOM. And worse, this function has the paragraph element in its closure. The paragraph element and its child nodes will be kept in memory until the page refreshes.
Unbind with jQueryjQuery helps you unbind event handlers in a number of ways:
Remove the bound elementIf you remove an element from the DOM, all of its event handlers will be cleaned up. For example:
$('#foo').click(function(){
// event handler code
});
// sometime later
$('#foo').remove()
However, this only works if you are using jQuery's DOM modifiers to remove the element like:
$('#foo').parent().html("");
$('#foo').parent().empty();
$('#foo').replaceWith("<p>Some Content</p>");
This is why you should rarely use direct DOM methods like:
$('#foo')[0].parentNode.removeChild( $('#foo')[0] );
If you do this, your event handler will sit around in memory forever! Also, sometimes you do not want (or can't) to remove the bound element. So jQuery has other options:
Unbind directlyjQuery, of course, lets you unbind an event handler with unbind. When our tooltip is removed, we can unbind the body's click handler like:
$(document.body).click(function(){
el.remove();
$(document.body).unbind('click', arguments.callee)
})
Note: be very careful to pass in the same function to unbind as you passed to bind (arguments.callee happens to be this function); otherwise, jQuery will not unbind your event handler and you will continue to have a leak.
If you only handle the event once, one(event, handler) will unbind call for you. We can use that to listen to body clicks and avoid leaking like:
$(document.body).one(function(){
el.remove();
})
Finally, jQuery provides namespaced event handlers. It let you unbind all event handlers on an element that match a particular namespace. We could use namespaces like:
$(document.body).bind('click.tooltip',function(){
el.remove();
$(document.body).unbind('click.tooltip')
})
Problems
So far, this might seem ok, but there are lot of potential problems. Most importantly, there's a lot of waste! For every bind, there needs to be an unbind. You are double-coding. In our experience, few think about memory leaks and cleanup until it's too late.
ControllerController has always been useful for binding and unbinding. 3.1 brought templated event binding. This lets you bind and delegate on elements outside the controller's parent element. We can rewrite tooltip like:
$.Controller('Tooltip',{
init : function(element, message){
this.element.html(message)
},
"{document.body} click" : function(){
this.element.remove();
}
})
$('#info').tooltip("Search Google!");
Notice the "{document.body} click". This does exactly what you think it does and when the controller is destroyed, it will automatically unbind the document.body click handler. No double coding!
We can change Tooltip to use different elements to hide itself too. The following accepts an optional 'hideElement' option while keeping the document.body as a default:
$.Controller('Tooltip',{
defaults : { hideElement : document.body }
},
{
init : function(element, opts){
this.element.html(opts.message)
},
"{hideElement} click" : function(){
this.element.remove();
}
})
// use clicks on document.body to hide
$('#info').tooltip({ message: "Search Google!"});
// use clicks on #contentArea to hide
$('#wikiInfo').tooltip({
hideElement: $('#contentArea'),
message: 'Search Wikipedia'
});
How it works
When controller finds {NAME} in a prototype method like "{NAME} click", it looks in two places:
- this.options - First, it uses NAME to look up a value on the controller instance's options.
- window - If a value is not found, it uses NAME to look up a value on the window object.
The match can be one of two types:
- An object - If an object is found, it binds or delegates on that object instead of using the controller's parent element. This could be another element, or any object that has events triggered on it (a Model for example).
- A string - If a string is found, it just replaces {NAME} with the value
of that string.
You can use a string template to configure the type of event that hides the element:
$.Controller('Tooltip',{
defaults : { hideElement : document.body }
},
{
init : function(element, opts){
this.element.html(opts.message)
},
"{hideElement} {hideEvent}" : function(){
this.element.remove();
}
})
// hide on hoverenter
$('#info').tooltip({
hideEvent: 'hoverenter',
message : 'stop moving to make me go away'
})
Updating options
New in 3.2 is the ability to update options and templated event handlers with controller's update(options) method. If a controller is already bound to an element, calling its jQuery helper with options calls update(options). So, we can update the hideEvent and hideElement like:
// first time, tooltip calls init
$('#info').tooltip({
message : 'stop moving to make me go away',
hideEvent: 'click'
})
// second time, tooltip calls update
$('#info').tooltip({
hideEvent: 'hoverenter',
hideElement : $('#closer')
})
If we want to update the message, we can overwrite update to do so:
$.Controller('Tooltip',{
defaults : { hideElement : document.body }
},
{
init : function(element, opts){
this.element.html(opts.message)
},
"{hideElement} {hideEvent}" : function(){
this.element.remove();
},
update : function(opts){
this._super(opts)
this.element.html(opts.message)
}
})
Templated and MVC
MVC apps are constantly listening to changes in the $.Model layer to reflect changes in the UI. Templated event handlers make it stupidly easy to write abstract widgets that work with any model. An abstract list might look like:
$.Controller('List',{
init : function(){
this.element.html(this.options.template, this.options.list)
},
update : function(options){
this._super(options)
this.element.html(this.options.template, this.options.list)
},
"{list} add" : function(list, ev, added){
this.element.append(this.options.template, added)
},
"{list} remove" : function(list, ev, removed){
removed.elements(this.element).remove()
}
"{list} updated" : function(list, ev, item){
item.elements.replaceWith(this.options.template, [item] );
}
})
You can create list widgets that respond to changes in a $.Model.List like:
Task.findAll({}, function(tasks){
$('#tasks').list({list: tasks, template: 'tasks.ejs'})
})
People.findAll({}, function(people){
$('#people').list({list: people, template: 'people.ejs'})
})
And update the list with a new list like:
Task.findAll({personId: 1}, function(tasks){
$('#tasks').list({list: tasks})
})
The PlayerMX and Todo apps are very good examples of using templated event handlers.
ConclusionTemplated event handlers have made a big difference in how we write our apps. We've abandoned OpenAjax's pub-sub for direct Model events. We rarely use callbacks on model.destroy() or model.save() like:
model.destroy(function(){
// remove element!
})
and instead listen for changes like:
"{model} destroy" : function(){
// remove element!
}
This makes the remove element! code run no matter how the model instance gets destroyed.
Finally, templated event handlers lead to some of the bigger 3.2 changes: $.Observe and $.route.
Enjoy!


