Blog Archives

A new variable for Knockout.js bindings – the DOM element

When writing knockout bindings it can sometimes be handy to reference the DOM element you are writing the element for. As an example, you may want information on a DOM property or for development reasons simply want to show the id.

I tweaked Knockout to support using an $element special variable last year, but hadn’t decided to submit it yet.  Based on the discussion in knockout issue 176 I decided to clean it up and submit it as knockout pull request 474. Mbest also updated it to work with the latest knockout changes.

Usage is simple:

<div data-bind='text: $element.tagName'></div>

Enjoy!

As an aside, I’m going to be presenting on Derby and Meteor at the NodeDC Meetup on 5/16. If you are interested in Node or just want to connect with some cool DC coders stop by!

Advertisement

Two new QUnit Test Types – Skipped and Interactive

I love unit testing, and the confident feeling I get from my code being “all green”. But sometimes there are tests that need to be skipped for a bit, perhaps due to a failing backend service or an in-progress refactoring. The easiest solution is to comment them out, but then it’s easy to forget they are being skipped. Instead, I simply added a new test type – testSkip – to QUnit using the following code. Now when the test is skipped we see it marked as SKIPPED in the QUnit results.


QUnit.testSkip = function() {
   q.test(arguments[0] + &quot; (SKIPPED)&quot;, function() {});
};

I use a similar approach for QUnit tests that involve user interaction. I run lots of tests when coding, but the interactive ones get in the way of my flow. So I have added the test type testManual which allows me to run them explicitly by simply adding testmanual to the URL parameters. A similar approach can be used for other test categories or to target tests to a particular browser.


QUnit.testManual = function() {
   if(/(\?|&amp;)testmanual($|&amp;|=)/.test(window.location.href)) {
      q.test.apply(q, arguments);
   } else {
      q.testSkip.apply(q, arguments);
   }
};

A bindOnce event listener for Backbone.js

I’m going to guess you are familiar with Backbone, the MVC framework of choice for many web developers. I use Backbone a fair amount for its Model and Event aspects both because it works and it’s often what others expect.

But there is one feature I miss with Backbone event handling – the ability to listen for an event once (like jQuery’s once). You can write your own code to simply ignore later events, but the event handling code is still there.  It would be better to unbind, but with Backbone that means holding on to the callback function so you can unbind it on the first callback, and to do that you have to assign your callback to a variable which can clutter up simple event handling code.

Or you can just write a bindOnce function that does that for you which is what I did. I feel like this should be a standard feature, so I’ve packaged it up with some tests and submitted it to the Backbone folks in pull request 663. Usage is simple and looks like this:

obj.bindOnce('event', function(){
   obj.counterA += 1;
});

Update 10/29/11

Wow, that was quick. My bindOnce is now part of Backbone with the updated name of once (which makes sense since it matches jQuery). It always speeds things up when you include the tests :)

Enabling Knockout.js to work across iframes

If you haven’t checked out Knockout yet, I highly recommend it.

Knockout allows you to create declarative bindings in your HTML that map to your underlying model’s properties. The nice thing about the bindings being in HTML is that you and your designer team can work in real HTML.

But Knockout’s real magic comes from its dependency tracking. When bound model properties change, Knockout magically updates the bound parts of the HTML that need it. It’s an approach I have used many times that gives you the real benefits of MVC by allowing the view to bind to the model rather than the other way around.

We wrote something similar in Digitalk Smalltalk back in the 90s, and then VisualWorks Smalltalk introduced Aspect Adaptors baked right in. In Knockout these model property trackers are called Observers. It also has something called a Dependency Observer that tracks any model properties accessed during a function call (for example getting the list of users), it then automatically creates observers on those properties. Very cool.

One problem with the current version of Knockout is that there are still a few hurdles preventing it from working across frames or windows: it uses a global state to do its Dependency Observer magic, it does identify class checking (which fails across frames), and it does some things relative to the window the code was loaded into rather than the current element’s window. I have written a couple of patches that cover most of these cases and have submitted a pull request to Steve Sanderson.

Update 3/21/12

After many tweaks and discussions my cross-frame changes have been accepted into Knockout 2.10. See issue 405 for details.

I was awarded a Firefox Security Bug Bounty Award!

I just received an email from the head of the Mozilla security team that I have been awarded a Security Bug Bounty Award for an sg:critical bug I found in Firefox. For those that don’t know, sg:critical is the highest level of severity and indicates the bug is an “exploitable vulnerability which can lead to the widespread compromise of many users.” That sounds pretty scary, but on the bright side sg:critical means I get the maximum bounty of $3000 (and a t-shirt :). Very cool :).

I don’t want to share more since the vulnerability hasn’t been fixed yet, but as soon as it is I’ll give a full explanation.

Update 9/27/11

The bug is (finally) fixed and has been announced as Mozilla Foundation Security Advisory 2011-43 (CVE-2011-3004), which means I can finally talk about it. The bug deals with the guts of how Firefox wraps unsecure JavaScript objects so the details are a bit complicated. People who are interested in the gritty details should follow the above link. Since the full explanation is a bit much for a blog post I’m just going to summarize it here.

In Firefox the loadSubScript function loads code into the current security context, and since it’s called from an extension the code is loaded in the secure security context. In Firefox 3.6 (and now again in Firefox 11+) any unsecure objects passed in the loadSubScript context are correctly wrapped in a XrayWrapper (XPCNWrapper in Firefox 3.6).

Wrapper ensures that secure code can’t accidently pass an unsecure object to a secure object that can be used as a privilege upgrade attack. There are surprising number ways of doing this in JavaScript without this wrapper protection.

In Firefox 4 a bug was introduced that missed adding these wrappers for loadSubScript. So the secure loaded code was handed unsecure, unwrapped objects.  If a target window (any web page) anticipated this bug they could check for the vulnerability in each user’s browser, and if they found it they could use it to do anything a Firefox extension could do (essentially gaining full access to the user’s system, files … practically everything).

See [post: Inserting JavaScript/CSS…] for one possible use case for loadSubScript (now that it is no longer a security hole).

Adding a little jQuery/Sizzle to FirePath for Firebug

FirePath is a very cool Firebug plugin that adds the ability to search the HTML tree using XPath or CSS Selectors. It filters the actual Firebug DOM tree so you can then act on that element in all the normal Firebug ways (view DOM, inspect, etc).

Here is a screenshot:

Unfortunately FirePath only supports native CSS Selectors, and most of the world (including me) actually uses jQuery’s Sizzle which gives us some really key additions like :not, :contains, and :first.

So I did a little extension hacking and added Sizzle support to FirePath. You can find the patch for it where I submitted it to the FirePath author at http://code.google.com/p/firepath/issues/detail?id=22.

Update 3/22/2011

I guess I’m not the only one who wanted to use jQuery/Sizzle. The patch was accepted and FirePath with jQuery/Sizzle is now available in Version 0.9.6.1!

%d bloggers like this: