W3C home > Mailing lists > Public > www-dom@w3.org > January to March 2013

Re: [dom] Need to describe the interaction of adoptNode with prototype chains

From: Geoffrey Garen <ggaren@apple.com>
Date: Tue, 15 Jan 2013 13:59:10 -0800
Message-id: <B78E9219-B88F-44AC-BC81-DADCC8943E03@apple.com>
To: www-dom@w3.org
Hi folks.

Responding to a few things out of order:

> If it stays the old proto, then you'll have an element in the new 
> document that tests false for instanceof against things in that window, no?

FWIW, I don't buy the instanceof argument.
	(a) Passing any object between windows breaks instanceof. I'm not convinced of the value of working around that in one special case.
	(b) Once you change from Window A's prototype to Window B's, instanceof in Window B will work but instanceof in Window A will now be broken.
	(c) node.onclick instanceof Function, and instanceof any custom properties, will still fail.

> 2)  If a script adopts a node from a subframe and then unloads the 
> subframe or removes it from the DOM, remembering the proto means you 
> leak the entire global object _and_ the entire DOM of the subframe

Changing the prototype doesn't resolve this issue.

Any event listener on the node will keep the entire global object and DOM alive, through the scope chain's link to the lexical environment and its .document property.

Also, any custom properties on the node wrapper may point to the old lexical environment, directly or indirectly.

Fundamentally, the DOM is one giant memory leak.

> Well... Should the proto remain the proto associated with the window of 
> the old document, or should it become the proto associated with the 
> window of the new document?

In a way, I think this is asking the wrong question. Our task isn't to pick a prototype -- it's to pick a set of observable properties. In a prototype-based language, the prototype is just one way to associate some properties with an object. 

This:

{ y: 0 }
    ^
{ x: 0 }
    ^
{  }

is logically equivalent to this:

{ x: 0, y: 0 }

If we want to logically sever the node's relationship to its old environment, and give it a new relationship to a new environment, we should be asking about all of its properties, and not just the ones belonging to its prototypes.

If that's the goal, I think the best solution is to create a second wrapper. Direct references to the old wrapper would continue to see that wrapper's identity and custom properties (including those implemented by its prototypes), but new references returned by the DOM (e.g. via getElementById) would use a new wrapper, with a new identity and a new set of custom properties defined by its new prototypes.

You might think that it's strange for a node's identity to change when it is adopted. But I think that's the most honest way to represent the operation you're describing. If adopting a node changes its very type, it's probably right to say that it's no longer equal to what it used to be.

Geoff
Received on Tuesday, 15 January 2013 22:01:24 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Tuesday, 15 January 2013 22:01:25 GMT