Revamp association of selections with documents
authorAryeh Gregor <ayg@aryeh.name>
Thu, 12 Jan 2012 09:18:37 -0700
changeset 686 56c83bbaa44c
parent 685 9ca0bc5d4285
child 687 0ef300a5c14f
Revamp association of selections with documents

The previous definition said every browsing context had a selection,
which was totally incorrect: non-active documents can have selections
too. Boris Zbarsky pointed out that different pages in history have
entirely different Selection objects. Ian Hickson pointed out that
document.open() already specifically says that the Selection object is
replaced, along with all other singletons, so we don't need to add
unload steps.

This re-raises the question of which documents have a selection,
exactly. I started a discussion on public-webapps (no archive link
available yet).
editing.html
preprocess
selecttest/Document-open.html
selecttest/getSelection.html
selecttest/unload.html
source.html
--- a/editing.html	Thu Jan 12 11:32:57 2012 +0100
+++ b/editing.html	Thu Jan 12 09:18:37 2012 -0700
@@ -67,7 +67,7 @@
 <body class=draft>
 <div class=head id=head>
 <h1>HTML Editing APIs</h1>
-<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-11-january-2012>Work in Progress &mdash; Last Update 11 January 2012</h2>
+<h2 class="no-num no-toc" id=work-in-progress-&mdash;-last-update-12-january-2012>Work in Progress &mdash; Last Update 12 January 2012</h2>
 <dl>
  <dt>Editor
  <dd>Aryeh Gregor &lt;<a href=mailto:[email protected]>[email protected]</a>&gt;
@@ -726,33 +726,41 @@
 make the range initially null.
 </div>
 
-<p>Every <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context title="browsing context">browsing context</a> has a <dfn id=concept-selection title=concept-selection>selection</dfn>.  Each <a href=#concept-selection title=concept-selection>selection</a> is associated with
-a single <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a>, which may be null and is initially null.  This one
-<a href=#concept-selection title=concept-selection>selection</a> must be shared by all the content of the <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context title="browsing context">browsing context</a>
-(though not by nested <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context title="browsing context">browsing contexts</a>), including any editing hosts in the
-document. <a href=#editing-host title="editing host">Editing hosts</a> that are not inside a
-document cannot have a <a href=#concept-selection title=concept-selection>selection</a>.
+<p>Every <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a> has a unique <code><a href=#selection>Selection</a></code> object associated
+with it.  <code><a href=#selection>Selection</a></code> objects are known as <dfn id=concept-selection title=concept-selection>selections</dfn>.  Each <a href=#concept-selection title=concept-selection>selection</a> is associated
+with a single <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a>, which may be null and is initially null.  This one
+<a href=#concept-selection title=concept-selection>selection</a> must be shared by all the content of the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a> (though not
+by nested <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>documents</a>), including any editing hosts in the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a>.
+<a href=#editing-host title="editing host">Editing hosts</a> that are not inside a
+<a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a> cannot have a <a href=#concept-selection title=concept-selection>selection</a>.
+
+<p class=comments>This is a requirement of the HTML spec.  IE9 and Opera Next
+12.00 alpha seem to follow it, while Firefox 12.0a1 and Chrome 17 dev seem not
+to.  See <a href=selecttest/Document-open.html>test</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=717339">Mozilla bug</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=76114">WebKit bug</a>.
+
+<p class=note>A document's selection is a singleton object associated with that
+document, so it gets replaced with a new object when <code class=external data-anolis-spec=html title=dom-Document-open><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-open>Document.open()</a></code> is called.
 
 <p class=comments>See <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=15470">bug 15470</a>.  IE9
 and Opera Next 12.00 alpha allow the user to reset the range to null after the
 fact by clicking somewhere; Firefox 12.0a1 and Chrome 17 dev do not.  I follow
 Gecko/WebKit, because it lessens the chance of getRangeAt(0) throwing.
 
-<p>The user agent should allow the user to change the <a href=#concept-selection title=concept-selection>selection</a>.  If the
-user makes any modification to the <a href=#concept-selection title=concept-selection>selection</a>, the user agent must create a
-new <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> with suitable <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-end title=concept-range-end>end</a> and associate the
-<a href=#concept-selection title=concept-selection>selection</a> with this new <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> (not modify the existing <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a>).  The
-user agent must not allow the user to set a <a href=#concept-selection title=concept-selection>selection</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> to null
-if it was not already null.
+<p>The user agent should allow the user to change the <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#active-document title="active document">active document</a>'s
+<a href=#concept-selection title=concept-selection>selection</a>.  If the user makes any modification to a <a href=#concept-selection title=concept-selection>selection</a>, the user
+agent must create a new <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> with suitable <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-start title=concept-range-start>start</a> and <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-end title=concept-range-end>end</a>
+and associate the <a href=#concept-selection title=concept-selection>selection</a> with this new <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> (not modify the
+existing <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a>).  The user agent must not allow the user to set a
+<a href=#concept-selection title=concept-selection>selection</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> to null if it was not already null.
 
 <p class=comments>This matches Firefox 12.0a1, as far as I can tell.  Chrome 17
 dev and Opera Next 12.00 alpha return copies from getRangeAt(), so the
 requirement isn't testable for them.  IE9 threw weird exceptions in my testing,
 so I match the only browser I could test.
 
-<p>Once a <a href=#concept-selection title=concept-selection>selection</a> is associated with a given <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> object, it must
-continue to be associated with that same <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> object until this
-specification requires otherwise.
+<p>Once a <a href=#concept-selection title=concept-selection>selection</a> is associated with a given <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a>, it must continue
+to be associated with that same <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> until this specification requires
+otherwise.
 
 <p class=note>For instance, if the DOM changes in a way that changes the
 <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a>'s <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary points</a>, or a script modifies the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range-bp title=concept-range-bp>boundary points</a> of
@@ -762,19 +770,6 @@
 must be associated with a new <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> object, as required elsewhere in this
 specification.
 
-<p class=comments>If the document is being unloaded, we want to clear all state
-associated with the old document.  If the selection's range was non-null, it
-will get collapsed to (document, 0) when the document's children are removed.
-This is indeed what Firefox 12.0a1 and Chrome 17 dev seem to do.  IE9 seems to
-reset the selection's range to null, at least when the document is unloaded via
-<code title="">document.open()</code>.  This makes more sense than collapsing it to the
-root.
-
-<p>As one of the <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#unloading-document-cleanup-steps>unloading document cleanup
-steps</a>, the user agent must remove any <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> from the <a href=#concept-selection title=concept-selection>selection</a>
-associated with the <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code>'s <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context title="browsing context">browsing context</a> (so the <a href=#concept-selection title=concept-selection>selection</a>'s
-<a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> is null) and set its <a href=#concept-selection-dir title=concept-selection-dir>direction</a> to <i title="">forwards</i>.
-
 <p class=comments>This paragraph is vague.  It needs to be replaced by detailed
 conformance requirements saying exactly what to do for particular keystrokes,
 like we have for backspace/delete/etc.
@@ -836,8 +831,6 @@
 selectionLanguageChange() and containsNode() are missing. They are missing
 because I couldn't work out how to define them in terms of Ranges.
 
-<p>The <code><a href=#selection>Selection</a></code> interface represents a <a href=#concept-selection title=concept-selection>selection</a>.
-
 <div class=note>
 <p>Originally, the Selection interface was a Netscape feature.  The
 original implementation was carried on into Gecko (Firefox), and the feature
@@ -859,10 +852,13 @@
 
 <p>All of the members of the <code><a href=#selection>Selection</a></code> interface are defined in
 terms of operations on the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> object (if any) represented by the object.
-These operations can raise exceptions, as defined for the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-range title=concept-range>range</a> interface;
-this can therefore result in the members of the <code><a href=#selection>Selection</a></code>
-interface raising exceptions as well, in addition to any explicitly called out
-below.
+These operations can raise exceptions, as defined for the <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#range>Range</a></code> interface; this can therefore result in the
+members of the <code><a href=#selection>Selection</a></code> interface raising exceptions as well, in
+addition to any explicitly called out below.
+
+<p class=XXX>What happens if you try to put a selection in some node that's not
+part of the selection's document?  Assuming it works, how is it presented to
+the user?
 
 <dl class=domintro>
   <dt><var title="">selection</var> . <code title=dom-Selection-anchorNode><a href=#dom-selection-anchornode>anchorNode</a></code>
@@ -1276,15 +1272,18 @@
 that).  Now, what happens if you create a Document object with no defaultView
 (say via <code title="">document.implementation.createHTMLDocument("")</code>) and call
 <code title="">getSelection()</code> on it?  IE9 seems to return a different Selection
-object.  Firefox 9.0a2 and Opera 12.00 return the same object as for the
-current window.  Chrome 16 dev returns null.  We go with Firefox/Opera, since
-it's likely the oldest behavior and makes the most sense.  TODO: Is the wording
-about prototypes the best way to identify the correct global object?
+object.  Firefox 12.0a1 and Opera Next 12.00 alpha return the same object as
+for the current window.  Chrome 17 dev returns null.  We go with IE9 for now,
+because it's the simplest to spec and understand -- we don't have to
+distinguish between different kinds of documents.  But maybe this isn't
+desired.
 
 <p>The <dfn id=dom-document-getselection title=dom-Document-getSelection><code>getSelection()</code></dfn>
-method on the <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code> interface must return the same
-<code><a href=#selection>Selection</a></code> object as calling <code title=dom-Window-getSelection><a href=#dom-window-getselection>getSelection()</a></code> on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#window>Window</a></code> object on which the <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code>'s
-prototype resides.
+method on the <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code> interface must return
+the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>'s <a href=#concept-selection title=concept-selection>selection</a>.
+
+<p class=XXX>Browsers other than IE don't actually give every document a
+selection.  Consider changing this to match Gecko or WebKit.
 
 <pre class=idl>partial interface <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#window>Window</a> {
   <a href=#selection>Selection</a> <a href=#dom-window-getselection title=dom-Window-getSelection>getSelection</a>();
@@ -1292,7 +1291,8 @@
 
 <p>The <dfn id=dom-window-getselection title=dom-Window-getSelection><code>getSelection()</code></dfn>
 method on the <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#window>Window</a></code> interface must return
-the <code><a href=#selection>Selection</a></code> object representing the <a href=#concept-selection title=concept-selection>selection</a> of that <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#window>Window</a></code> object's <a class=external data-anolis-spec=html href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context>browsing context</a>.
+the the <a href=#concept-selection title=concept-selection>selection</a> of the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a> returned by the <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#context-object>context object</a>'s
+<code class=external data-anolis-spec=html title=dom-document-0><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#dom-document-0>document</a></code> property.
 
 
 <h2 id=commands>Commands</h2>
@@ -1688,14 +1688,14 @@
 
 <p>A <dfn id=block-node>block node</dfn> is either an <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> whose "display" property
 does not have <a href=http://dev.w3.org/csswg/cssom/#resolved-value>resolved value</a> "inline" or "inline-block" or "inline-table" or
-"none", or a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code>, or a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>.
+"none", or a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a>, or a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>.
 
 <p>An <dfn id=inline-node>inline node</dfn> is a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> that is not a <a href=#block-node>block
 node</a>.
 
 <p>An <dfn id=editing-host>editing host</dfn> is a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a> that is either an <a href=#html-element>HTML
 element</a> with a <code class=external data-anolis-spec=html title=attr-contenteditable><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#attr-contenteditable>contenteditable</a></code> attribute set to the true
-state, or the <a href=#html-element>HTML element</a> <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code> whose <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#designMode>designMode</a></code> is enabled.
+state, or the <a href=#html-element>HTML element</a> <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-child title=concept-tree-child>child</a> of a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a> whose <code class=external data-anolis-spec=html><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#designMode>designMode</a></code> is enabled.
 
 <p>Something is <dfn id=editable>editable</dfn> if it is a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-node title=concept-node>node</a>; it is not an
 <a href=#editing-host>editing host</a>; it does not have a <code class=external data-anolis-spec=html title=attr-contenteditable><a href=http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#attr-contenteditable>contenteditable</a></code> attribute set to the false
@@ -1704,9 +1704,9 @@
 element, or it is not an <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> and its <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> is an <a href=#html-element>HTML
 element</a>.
 
-<p class=note>An <a href=#editable>editable</a> node cannot be a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code> or
+<p class=note>An <a href=#editable>editable</a> node cannot be a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a> or
 <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, its <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-tree-parent title=concept-tree-parent>parent</a> cannot be null, and it must descend from
-either an <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> or a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code>.
+either an <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#element>Element</a></code> or a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a>.
 
 <p>The <dfn id=editing-host-of>editing host of</dfn> <var title="">node</var> is null if <var title="">node</var> is
 neither <a href=#editable>editable</a> nor an <a href=#editing-host>editing host</a>; <var title="">node</var>
@@ -2350,7 +2350,7 @@
   <a href=#html-element>HTML element</a> with <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-element-local-name title=concept-element-local-name>local name</a> equal to one of those, and
   <var title="">child</var> is not a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#text>Text</a></code> node, return false.
 
-  <li>If <var title="">child</var> is a <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#document>Document</a></code>, <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, or
+  <li>If <var title="">child</var> is a <a class=external data-anolis-spec=dom href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-document title=concept-document>document</a>, <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documentfragment>DocumentFragment</a></code>, or
   <code class=external data-anolis-spec=dom><a href=http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#documenttype>DocumentType</a></code>, return false.
 
   <li>If <var title="">child</var> is an <a href=#html-element>HTML element</a>, set <var title="">child</var>
--- a/preprocess	Thu Jan 12 11:32:57 2012 +0100
+++ b/preprocess	Thu Jan 12 09:18:37 2012 -0700
@@ -8,6 +8,7 @@
 
 replace = {
     'a': '<code data-anolis-spec=html title="the a element">a</code>',
+    'activedocument': '<span data-anolis-spec=html title="active document">active document</span>',
     'ancestor': '<span data-anolis-spec=dom title=concept-tree-ancestor>ancestor</span>',
     'attribute': '<span data-anolis-spec=dom title=concept-attribute>attribute</span>',
     'attrlocalname': '<span data-anolis-spec=dom title=concept-attribute-local-name>local name</span>',
@@ -40,7 +41,7 @@
     'dd': '<code data-anolis-spec=html title="the dd element">dd</code>',
     'dl': '<code data-anolis-spec=html title="the dl element">dl</code>',
     'dt': '<code data-anolis-spec=html title="the dt element">dt</code>',
-    'document': '<code data-anolis-spec=dom>Document</code>',
+    'document': '<span data-anolis-spec=dom title=concept-document>document</span>',
     'documentfragment': '<code data-anolis-spec=dom>DocumentFragment</code>',
     'documenttype': '<code data-anolis-spec=dom>DocumentType</code>',
     'element': '<code data-anolis-spec=dom>Element</code>',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/selecttest/Document-open.html	Thu Jan 12 09:18:37 2012 -0700
@@ -0,0 +1,45 @@
+<!doctype html>
+<title>Selection Document.open() tests</title>
+<div id=log></div>
+<script src=http://w3c-test.org/resources/testharness.js></script>
+<script>
+"use strict";
+
+// This tests the HTML spec requirement "Replace the Document's singleton
+// objects with new instances of those objects. (This includes in particular
+// the Window, Location, History, ApplicationCache, and Navigator, objects, the
+// various BarProp objects, the two Storage objects, the various HTMLCollection
+// objects, and objects defined by other specifications, like Selection and the
+// document's UndoManager. It also includes all the Web IDL prototypes in the
+// JavaScript binding, including the Document object's prototype.)" in the
+// document.open() algorithm.
+
+var iframe = document.createElement("iframe");
+var t = async_test("Selection must be replaced with a new object after document.open()");
+iframe.onload = function() {
+	t.step(function() {
+		var originalSelection = iframe.contentWindow.getSelection();
+		assert_equals(originalSelection.rangeCount, 0,
+			"Sanity check: rangeCount must be initially 0");
+		assert_equals(iframe.contentWindow.getSelection(), originalSelection,
+			"Sanity check: getSelection() called twice must return the same object");
+		iframe.contentDocument.body.appendChild(
+			iframe.contentDocument.createTextNode("foo"));
+		var range = iframe.contentDocument.createRange();
+		range.selectNodeContents(iframe.contentDocument.body);
+		iframe.contentWindow.getSelection().addRange(range);
+		assert_equals(iframe.contentWindow.getSelection(), originalSelection,
+			"Sanity check: getSelection() called twice with addRange() in between must return the same object");
+		assert_equals(originalSelection.rangeCount, 1,
+			"Sanity check: rangeCount must be 1 after adding a range");
+		iframe.contentDocument.open();
+		assert_not_equals(iframe.contentWindow.getSelection(), originalSelection,
+			"After document.open(), the Selection object must no longer be the same");
+		assert_equals(iframe.contentWindow.getSelection().rangeCount, 0,
+			"After document.open(), rangeCount must be 0 again");
+	});
+	t.done();
+	document.body.removeChild(iframe);
+};
+document.body.appendChild(iframe);
+</script>
--- a/selecttest/getSelection.html	Thu Jan 12 11:32:57 2012 +0100
+++ b/selecttest/getSelection.html	Thu Jan 12 09:18:37 2012 -0700
@@ -44,6 +44,8 @@
 		"document.getSelection().rangeCount must initially be 0");
 }, "Selection's range must initially be null");
 
+// Commented out pending decision on what the correct behavior is
+/*
 test(function() {
 	assert_true("Selection" in window, "window must have Selection property");
 
@@ -65,6 +67,7 @@
 	assert_equals(xmlDoc.getSelection(), document.getSelection(),
 		"getSelection() on XML document with no browsing context must be same as the window");
 }, "XML document with no browsing context");
+*/
 
 var iframe = document.createElement("iframe");
 document.body.appendChild(iframe);
@@ -81,6 +84,7 @@
 		"getSelection() inside and outside iframe must return different objects");
 }, "In an iframe");
 
+/*
 test(function() {
 	assert_true("Selection" in iframe.contentWindow, "window must have Selection property");
 
@@ -90,5 +94,6 @@
 	assert_equals(doc.getSelection(), iframe.contentDocument.getSelection(),
 		"getSelection() on HTML document with no browsing context must be same as the window");
 }, "HTML document with no browsing context inside an iframe");
+*/
 document.body.removeChild(iframe);
 </script>
--- a/selecttest/unload.html	Thu Jan 12 11:32:57 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-<!doctype html>
-<title>Selection unload tests</title>
-<div id=log></div>
-<script src=http://w3c-test.org/resources/testharness.js></script>
-<script>
-"use strict";
-
-// This tests the requirement "As one of the unloading document cleanup steps,
-// the user agent must remove any range from the selection associated with the
-// Document's browsing context (so the selection's range is null) and set its
-// direction to forwards."  To do so, it creates an iframe and runs
-// document.open().
-//
-// TODO: Test additional ways of unloading the document, like back and forward.
-// TODO: Test that selection direction is reset.
-
-var iframe = document.createElement("iframe");
-var t = async_test("Selection.rangeCount must be reset to 0 after document.open()");
-iframe.onload = function() {
-	t.step(function() {
-		assert_equals(iframe.contentWindow.getSelection().rangeCount, 0,
-			"Sanity check: rangeCount is initially 0");
-		iframe.contentDocument.body.appendChild(
-			iframe.contentDocument.createTextNode("foo"));
-		var range = iframe.contentDocument.createRange();
-		range.selectNodeContents(iframe.contentDocument.body);
-		iframe.contentWindow.getSelection().addRange(range);
-		assert_equals(iframe.contentWindow.getSelection().rangeCount, 1,
-			"Sanity check: rangeCount is 1 after adding range");
-		iframe.contentDocument.open();
-		assert_equals(iframe.contentWindow.getSelection().rangeCount, 0,
-			"All ranges must be removed from the selection on unload");
-	});
-	t.done();
-	document.body.removeChild(iframe);
-};
-document.body.appendChild(iframe);
-</script>
--- a/source.html	Thu Jan 12 11:32:57 2012 +0100
+++ b/source.html	Thu Jan 12 09:18:37 2012 -0700
@@ -664,13 +664,24 @@
 make the range initially null.
 </div>
 
-<p>Every [[browsingcontext]] has a <dfn
-title=concept-selection>selection</dfn>.  Each [[selection]] is associated with
-a single [[range]], which may be null and is initially null.  This one
-[[selection]] must be shared by all the content of the [[browsingcontext]]
-(though not by nested [[browsingcontexts]]), including any editing hosts in the
-document. <span title="editing host">Editing hosts</span> that are not inside a
-document cannot have a [[selection]].
+<p>Every [[document]] has a unique <code>Selection</code> object associated
+with it.  <code>Selection</code> objects are known as <dfn
+title=concept-selection>selections</dfn>.  Each [[selection]] is associated
+with a single [[range]], which may be null and is initially null.  This one
+[[selection]] must be shared by all the content of the [[document]] (though not
+by nested [[documents]]), including any editing hosts in the [[document]].
+<span title="editing host">Editing hosts</span> that are not inside a
+[[document]] cannot have a [[selection]].
+
+<p class=comments>This is a requirement of the HTML spec.  IE9 and Opera Next
+12.00 alpha seem to follow it, while Firefox 12.0a1 and Chrome 17 dev seem not
+to.  See <a href=selecttest/Document-open.html>test</a>, <a
+href=https://bugzilla.mozilla.org/show_bug.cgi?id=717339>Mozilla bug</a>, <a
+href=https://bugs.webkit.org/show_bug.cgi?id=76114>WebKit bug</a>.
+
+<p class=note>A document's selection is a singleton object associated with that
+document, so it gets replaced with a new object when <code
+data-anolis-spec=html title=dom-Document-open>Document.open()</code> is called.
 
 <p class=comments>See <a
 href=https://www.w3.org/Bugs/Public/show_bug.cgi?id=15470>bug 15470</a>.  IE9
@@ -678,21 +689,21 @@
 fact by clicking somewhere; Firefox 12.0a1 and Chrome 17 dev do not.  I follow
 Gecko/WebKit, because it lessens the chance of getRangeAt(0) throwing.
 
-<p>The user agent should allow the user to change the [[selection]].  If the
-user makes any modification to the [[selection]], the user agent must create a
-new [[range]] with suitable [[rangestart]] and [[rangeend]] and associate the
-[[selection]] with this new [[range]] (not modify the existing [[range]]).  The
-user agent must not allow the user to set a [[selection]]'s [[range]] to null
-if it was not already null.
+<p>The user agent should allow the user to change the [[activedocument]]'s
+[[selection]].  If the user makes any modification to a [[selection]], the user
+agent must create a new [[range]] with suitable [[rangestart]] and [[rangeend]]
+and associate the [[selection]] with this new [[range]] (not modify the
+existing [[range]]).  The user agent must not allow the user to set a
+[[selection]]'s [[range]] to null if it was not already null.
 
 <p class=comments>This matches Firefox 12.0a1, as far as I can tell.  Chrome 17
 dev and Opera Next 12.00 alpha return copies from getRangeAt(), so the
 requirement isn't testable for them.  IE9 threw weird exceptions in my testing,
 so I match the only browser I could test.
 
-<p>Once a [[selection]] is associated with a given [[range]] object, it must
-continue to be associated with that same [[range]] object until this
-specification requires otherwise.
+<p>Once a [[selection]] is associated with a given [[range]], it must continue
+to be associated with that same [[range]] until this specification requires
+otherwise.
 
 <p class=note>For instance, if the DOM changes in a way that changes the
 [[range]]'s [[boundarypoints]], or a script modifies the [[boundarypoints]] of
@@ -702,19 +713,6 @@
 must be associated with a new [[range]] object, as required elsewhere in this
 specification.
 
-<p class=comments>If the document is being unloaded, we want to clear all state
-associated with the old document.  If the selection's range was non-null, it
-will get collapsed to (document, 0) when the document's children are removed.
-This is indeed what Firefox 12.0a1 and Chrome 17 dev seem to do.  IE9 seems to
-reset the selection's range to null, at least when the document is unloaded via
-{{code|document.open()}}.  This makes more sense than collapsing it to the
-root.
-
-<p>As one of the <span data-anolis-spec=html>unloading document cleanup
-steps</span>, the user agent must remove any [[range]] from the [[selection]]
-associated with the [[document]]'s [[browsingcontext]] (so the [[selection]]'s
-[[range]] is null) and set its [[seldir]] to <i title>forwards</i>.
-
 <p class=comments>This paragraph is vague.  It needs to be replaced by detailed
 conformance requirements saying exactly what to do for particular keystrokes,
 like we have for backspace/delete/etc.
@@ -778,8 +776,6 @@
 selectionLanguageChange() and containsNode() are missing. They are missing
 because I couldn't work out how to define them in terms of Ranges.
 
-<p>The <code>Selection</code> interface represents a [[selection]].
-
 <div class=note>
 <p>Originally, the Selection interface was a Netscape feature.  The
 original implementation was carried on into Gecko (Firefox), and the feature
@@ -801,10 +797,14 @@
 
 <p>All of the members of the <code>Selection</code> interface are defined in
 terms of operations on the [[range]] object (if any) represented by the object.
-These operations can raise exceptions, as defined for the [[range]] interface;
-this can therefore result in the members of the <code>Selection</code>
-interface raising exceptions as well, in addition to any explicitly called out
-below.
+These operations can raise exceptions, as defined for the <code
+data-anolis-spec=dom>Range</code> interface; this can therefore result in the
+members of the <code>Selection</code> interface raising exceptions as well, in
+addition to any explicitly called out below.
+
+<p class=XXX>What happens if you try to put a selection in some node that's not
+part of the selection's document?  Assuming it works, how is it presented to
+the user?
 
 <dl class=domintro>
   <dt><var>selection</var> . <code title=dom-Selection-anchorNode>anchorNode</code>
@@ -1229,17 +1229,18 @@
 that).  Now, what happens if you create a Document object with no defaultView
 (say via {{code|document.implementation.createHTMLDocument("")}}) and call
 {{code|getSelection()}} on it?  IE9 seems to return a different Selection
-object.  Firefox 9.0a2 and Opera 12.00 return the same object as for the
-current window.  Chrome 16 dev returns null.  We go with Firefox/Opera, since
-it's likely the oldest behavior and makes the most sense.  TODO: Is the wording
-about prototypes the best way to identify the correct global object?
+object.  Firefox 12.0a1 and Opera Next 12.00 alpha return the same object as
+for the current window.  Chrome 17 dev returns null.  We go with IE9 for now,
+because it's the simplest to spec and understand -- we don't have to
+distinguish between different kinds of documents.  But maybe this isn't
+desired.
 
 <p>The <dfn title=dom-Document-getSelection><code>getSelection()</code></dfn>
-method on the [[document]] interface must return the same
-<code>Selection</code> object as calling <code
-title=dom-Window-getSelection>getSelection()</code> on the <code
-data-anolis-spec=html>Window</code> object on which the [[document]]'s
-prototype resides.
+method on the <code data-anolis-spec=dom>Document</code> interface must return
+the [[contextobject]]'s [[selection]].
+
+<p class=XXX>Browsers other than IE don't actually give every document a
+selection.  Consider changing this to match Gecko or WebKit.
 
 <pre class=idl>partial interface <span data-anolis-spec=html>Window</span> {
   <span>Selection</span> <span title=dom-Window-getSelection>getSelection</span>();
@@ -1247,9 +1248,8 @@
 
 <p>The <dfn title=dom-Window-getSelection><code>getSelection()</code></dfn>
 method on the <code data-anolis-spec=html>Window</code> interface must return
-the <code>Selection</code> object representing the [[selection]] of that <code
-data-anolis-spec=html>Window</code> object's <span
-data-anolis-spec=html>browsing context</span>.
+the the [[selection]] of the [[document]] returned by the [[contextobject]]'s
+<code data-anolis-spec=html title=dom-document-0>document</code> property.
 <!-- @} -->
 
 <h2>Commands</h2>