[whatwg] [html5] Attaching option elements to select elements in different documents

The algorithm in the HTML5 specification for attaching an option element to
a select element is incomplete, because it doesn't describe how to handle
the case where the option element does not belong to the same document as
the select element.

It seems that HTMLOptionElement objects are immune to WRONG_DOCUMENT_ERR
exceptions on any tree modifications.  Thus the HTML5 specification also
needs to note that it is overriding the rules from DOM Core about what may
be attached to what.  I've written some proposed changes further below.

As far as I can tell, this affects: HTMLSelectElement.add(),
HTMLOptionsCollection.add(), Node.appendChild(), Node.replaceChild(),

My tests show that this isn't even confined to the cases where the new
parent node is an HTML select element - any cross-document attachment of
option elements operates as though the same-document check has been
bypassed.  In fact, the behaviour I'm seeing looks very much like an
implicit adoptNode() call has occurred.  I'm basing that suspicion on a
comparison of the (equally inconsistent) behaviour of adoptNode() in
different browsers[*]

I'm testing this from ECMAScript in my test page which is at:

In all browsers, if the insertion of the option succeeds, then the inserted
option element compares strictly equal to the option in the receiving select
element.  i.e. the option tree has not been cloned.

In some browsers, the [[Prototype]] of the HTMLOptionElement is reset to be
HTMLOptionElement.prototype of the receiving document's script context; in
others, it does not get changed.  However, in all browsers, all the nodes in
the option's subtree are affected similarly (i.e. if the option's
[[Prototype]] changes, so does the text node's)

In some browsers, you can only insert the option element if the option
element is not currently attached to anything else.

In some browsers, the option isn't inserted at the right index into the
receiving select, but I think that must just be a different bug.

I propose the following changes to the specification:

Change 1: Renumber existing step 7 to step 8 and insert a new step 7 in

"7.  If _element_ does not belong to the same document as _parent_, then act
as if the DOM Core adoptNode() method was invoked on the _parent_ node's
ownerDocument with _element_ as the parameter."

[Aside: whilst in the vicinity, shouldn't step 3 be using node rather than
element i.e. "If _before_ is a *node*, but that *node* ..."?   Otherwise, I
could legitimately insert it before any text node anywhere in the document.
Should it require that _before_ has to be an option or optgroup?]

Change 2: Append some text to section 2.2.1 (Conformance Requirements ->
Dependencies) to indicate the change to DOM Core, and include a link to the
text added by change 3:

"Some requirements in this specification are a wilful violation of
constraints imposed by the DOM Core specification [DOMCORE]:

* attaching _option_ elements to different documents is permitted"

Change 3: append explanatory text, linked from change 2's text to:

"If any attempt is made to attach an _option_ element to a node in a
Document other than the Document of the _option_ element, then the user
agent must not throw a _WRONG_DOCUMENT_ERR_ exception.  If the tree change
would otherwise succeed, then the user agent must behave as if a call to the
DOM Core adoptNode() method has been made so that the Document of the
_option_ element is updated.  This affects the DOM Core appendChild(),
insertBefore() and replaceChild() methods."

Actually, all of these changes might have to say "_option_ or _optgroup_".

[*] Opera 10.10, Chrome 5.0.307.11 beta, Firefox 3.5.8, and our own ANT
Galio 3.1.0

Stewart Brodie
Team Leader - ANT Galio Browser
ANT Software Limited

Received on Wednesday, 3 March 2010 09:11:01 UTC