Aggregation by proxy, part 1

(I was tempted to call this Integration by Parts, but I think the other calculus fans reading Planet Mozilla would raise a pitchfork or two.)

In my last blog entry, I talked briefly about an idea I had:

Aggregation by proxy, though, means you could daisy-chain several JS objects in front of the original DOM node, in terms of method and property priorities. If you need to replace a binding, you swap out one object in the daisy-chain. No __defineSetter__ mess, though pulling it off will require a bit of custom JavaScript code. I’d love to see someone else write it up for me – I see it as a trivial extension of the forwarding proxy examples.

Okay, it’s not that trivial. But I do believe it’s doable. If you exclude the DOM node and just daisy-chain a bunch of JavaScript objects, you get something like this. (Note this will only work in recent FF4 beta builds.)

Tom Van Cutsem saw my sample this way in an e-mail he sent back:

If that’s the case, I think your code here actually demonstrates two nice use cases of proxies:

  1. it shows aggregation of object properties.
  2. it shows how you can create a “side-effect-free” proxy for an object (or a graph of objects), which provides the illusion of side-effects (adding/deleting properties) to the proxy client without affecting the wrapped object.

I can imagine proxies that support only 1) or 2) to be useful in their own right. It may even make sense to separate out the functionality into two proxies and then chain them together so that we have:
client -> side-effect-free-proxy -> aggregate-proxy -> target

The version I’m posting here has Tom’s annotations in the source code.

There’s room for improvement. This code will work only with pure JavaScript objects, and can violate rules for setters. I’m thinking this design only takes me part of the way there. I imagine aggregation by proxy as meaning “I can combine implementations of two different IDL interfaces into a single callable object”. That means fun with QueryInterface, for starters. I also need to work on a SingletonHandler (hint: I’ve already prototyped that too), so that document.getElementById(“test”) returns me the same object every time.

I’d love to work on this with fellow Mozilla contributors, to build a complete aggregation by proxy script for the DOM. Anyone interested?