Skip to content
Permalink
Browse files

document.open() simplifications, part 1

In particular, removes the realm creation, document unloading, and tasks
removal steps.

Based on the work by Anne van Kesteren in #3651, but without the parts
concerning the session history. Changes to that area will come later
(see #3818).

These changes allow us to remove several auxiliary concepts that only
existed to support document.open():

- The recycle parameter to the "unload a Document" algorithm
- The window parameter to the "set the active document" algorithm

Tests: web-platform-tests/wpt#10773
Tests: web-platform-tests/wpt#10778
Tests: web-platform-tests/wpt#10815
Tests: web-platform-tests/wpt#10818

Fixes #1698.
Fixes #3286.
Fixes #3306.
Closes #3665.
  • Loading branch information...
TimothyGu authored and domenic committed Aug 16, 2018
1 parent 92b90bd commit 6f769b8089a843066aa19f5991405bf4c84458b3
Showing with 12 additions and 79 deletions.
  1. +12 −79 source
91 source

<p class="note">In general, there is a 1-to-1 mapping from the <code>Window</code> object to the
<code>Document</code> object, as long as the <code>Document</code> object has a <span
data-x="concept-document-bc">browsing context</span>. There are two exceptions. First, a
data-x="concept-document-bc">browsing context</span>. There is one exceptions. A
<code>Window</code> can be reused for the presentation of a second <code>Document</code> in the
same <span>browsing context</span>, such that the mapping is then 1-to-2. This occurs when a
<span>browsing context</span> is <span data-x="navigate">navigated</span> from the initial
<code>about:blank</code> <code>Document</code> to another, with <span>replacement enabled</span>.
Second, a <code>Document</code> can end up being reused for several <code>Window</code> objects
when the <code data-x="dom-document-open">document.open(<var>type</var>,
<var>replace</var>)</code> method is used, such that the mapping is then many-to-1.</p>

<p class="note">A <code>Document</code> does not necessarily have a <span
data-x="concept-document-bc">browsing context</span> associated with it. In particular, data
discarded">discarded</span>.</p>

<p>To <dfn>set the active document</dfn> of a <span>browsing context</span>
<var>browsingContext</var> to a <code>Document</code> object <var>document</var>, optionally with
a <code>Window</code> object <var>window</var>, run these steps:</p>
<var>browsingContext</var> to a <code>Document</code> object <var>document</var>, run these
steps:</p>

<ol>
<li>
<p>If <var>window</var> is not given, let <var>window</var> be <var>document</var>'s <span
<p>Let <var>window</var> be <var>document</var>'s <span
data-x="concept-relevant-global">relevant global object</span>.</p>

<p class="&#x0058;&#x0058;&#x0058;">Per this standard <var>document</var> can be created before
If the user <span>refused to allow the document to be unloaded</span>, then return.</p></li>

<li><p><span data-x="unload a document">Unload</span> <var>browsingContext</var>'s <span>active
document</span> with the <var>recycle</var> parameter set to false.</p></li>
document</span>.</p></li>

<li><p>Remove <var>browsingContext</var> from the user interface (e.g., close or hide its tab in
a tabbed browser).</p></li>
unloaded</span>, then return.</p></li>

<li><p><span data-x="unload a document">Unload</span> the <span>active document</span> of the
<var>specified browsing context</var> with the <var>recycle</var> parameter
set to false.</p></li>
<var>specified browsing context</var>.</p></li>

</ol>

<li>

<p><span data-x="unload a document">Unload</span> the <code>Document</code> object of the
<span>current entry</span>, with the <var>recycle</var> parameter set to false.</p>
<span>current entry</span>.</p>

<p>If this instance of the <span data-x="navigate">navigation</span> algorithm is canceled while
this step is running the <span>unload a document</span> algorithm, then the <span>unload a
<p>Things that can cause the page to be unsalvageable include:</p>

<ul class="brief">
<li><code data-x="dom-document-open">document.open(<var>type</var>, <var>replace</var>)</code>
<li>Listening for <code data-x="event-beforeunload">beforeunload</code> events
<li>Listening for <code data-x="event-unload">unload</code> events
<li>Having <code>iframe</code>s that are not salvageable
</ol>

<p>To <dfn data-export="" data-x="unload a document" data-lt="unload a document">unload</dfn> a
<code>Document</code> <var>document</var>, given a boolean <var>recycle</var> and optionally a
<var>recursiveFlag</var>:</p>

<p class="note">The <var>recycle</var> argument indicates whether the <code>Document</code> object
is going to be reused; it is set by the <code
data-x="dom-document-open">document.open(<var>type</var>, <var>replace</var>)</code> method.</p>
<code>Document</code> <var>document</var>, optionally given a <var>recursiveFlag</var>:</p>

<ol>
<li><p>Increase the <span>event loop</span>'s <span>termination nesting level</span> by

<ol>
<li><p><span data-x="unload a document">Unload</span> the <span>active document</span> of
<var>browsingContext</var> with the <var>recycle</var> parameter set to false, and the
<var>recursiveFlag</var> set.</p></li>
<var>browsingContext</var> with the <var>recursiveFlag</var> set.</p></li>

<li><p>If the <i data-x="concept-document-salvageable">salvageable</i> state of the
<span>active document</span> of <var>browsingContext</var> is false, then set the
</ol>
</li>

<li><p>If both <var>document</var>'s <i
data-x="concept-document-salvageable">salvageable</i> state and <var>recycle</var> are false,
then <span data-x="discard a document">discard</span><var>document</var>.</p></li>
<li><p>If <var>document</var>'s <i data-x="concept-document-salvageable">salvageable</i> state
is false, then <span data-x="discard a document">discard</span><var>document</var>.</p></li>
</ol>
</li>

<code>about:blank</code> <code>Document</code> created when <var>document</var>'s <span>browsing
context</span> was <span data-x="creating a new browsing context">created</span>, and that
<code>Document</code> object has never had the <span>unload a document</span> algorithm invoked
on it (e.g., by a previous call to <code
data-x="dom-document-open">document.open(<var>type</var>, <var>replace</var>)</code>), then set
<var>replace</var> to true.</p>
on it, then set <var>replace</var> to true.</p>
</li>

<li><p>Set <var>document</var>'s <i data-x="concept-document-salvageable">salvageable</i> state
to false.</p></li>

<li><p><span>Prompt to unload</span> <var>document</var>. If the user <span>refused to allow the
document to be unloaded</span>, then return <var>document</var>.</p></li>

<li><p><span data-x="unload a document">Unload</span> <var>document</var>, with the
<var>recycle</var> parameter set to true.</p></li>

<li><p><span data-x="abort a document">Abort</span> <var>document</var>.</p></li>

<li><p>For each <span>shadow-including inclusive descendant</span> <var>node</var> of

<li><p><span>Erase all event listeners and handlers</span> given <var>window</var>.</p></li>

<li><p>Remove any <span data-x="concept-task">tasks</span> associated with <var>document</var> in
any <span>task source</span>.</p></li>
<!-- removes callbacks that fired between this algorithm starting and the times and databases
being aborted in the "unload" step above -->

<li><p><span data-x="concept-node-replace-all">Replace all</span> with null within
<var>document</var>, without firing any mutation events.</p></li>

<li>
<p>Let <var>realm execution context</var> be the result of <span>creating a new JavaScript
realm</span> with the following customizations:</p>

<ul>
<li><p>For the global object, create a new <code>Window</code> object and set
<var>window</var> to it.</p></li>

<li><p>For the global <b>this</b> binding, use <var>document</var>'s <span>browsing
context</span>'s associated <code>WindowProxy</code>.</p></li>
</ul>

<p class="&#x0058;&#x0058;&#x0058;">This is not universally implemented and can perhaps be
removed; see <a href="https://github.com/whatwg/html/issues/1698">issue #1698</a>.</p>
</li>

<li><p><span>Set up a window environment settings object</span> with <var>realm execution
context</var>.</p></li>

<li><p><span>Set the active document</span> of <var>document</var>'s <span>browsing
context</span> to <var>document</var> with <var>window</var>.</p></li>

<li><p>Replace <var>document</var>'s singleton objects with new instances of those objects,
created in <var>window</var>'s <span data-x="concept-global-object-realm">Realm</span>. (This
includes in particular the <code>History</code>, <code>ApplicationCache</code>, and
<code>Navigator</code>, objects, the various <code>BarProp</code> objects, the two
<code>Storage</code> objects, the various <code>HTMLCollection</code> objects, and objects
defined by other specifications, like <code>Selection</code>. It also includes all the Web IDL
prototypes in the JavaScript binding, including <var>document</var>'s prototype.)</p></li>

<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E...%3Ciframe%20src%3D%22document%22%3E%3C%2Fiframe%3E%0A%3Cscript%3Eonload%20%3D%20function%20()%20%7B%20f%20%3D%20document.getElementsByTagName('iframe')%5B0%5D%3B%20d%20%3D%20f.contentWindow.document%3B%20%7D%3C%2Fscript%3E%0A%3Cinput%20type%3Dbutton%20onclick%3D%22w(d.documentElement.innerHTML)%22%20value%3D%22dump%22%3E%0A%3Cinput%20type%3Dbutton%20onclick%3D%22d.open()%3B%20d.write('%3Cscript%3Evar%20x%20%3D%20new%20XMLHttpRequest()%3Bx.open(%26quot%3BGET%26quot%3B%2C%20%26quot%3BGET%26quot%3B)%3Bx.onreadystatechange%3Dfunction()%20%7B%20alert(x.readyState)%3B%20%7D%3Bx.send(null)%3B%3C%2Fscript%3E')%3Bd.close()%3B%20setTimeout(function()%20%7B%20d.open()%3B%20d.write('%3Cp%3Etest%3C%2Fp%3E')%3B%20d.close()%20%7D%2C%200)%3B%22%20value%3D%22xhr%22%3E%0A%3Cinput%20type%3Dbutton%20onclick%3D%22d.onclick%20%3D%20function()%20%7B%20w('click')%20%7D%22%20value%3D%22add%20click%20handler%22%3E%0A%3Cinput%20type%3Dbutton%20onclick%3D%22d.open()%3B%20d.write('%3Cp%3Etest%3C%2Fp%3E')%3B%20d.close()%22%20value%3D%22replace%22%3E%0A%3Cinput%20type%3Dbutton%20onclick%3D%22d.open()%3B%20d.write('%3Cp%3E%3Cscript%3Ei%20%3D%200%3B%20setTimeout(%26quot%3Bparent.w(i%2B%2B)%26quot%3B%2C%202000)%3C%2Fscript%3E%3C%2Fp%3E')%3B%20d.close()%22%20value%3D%22replace%20with%20timer%22%3E -->
<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0D%0A...%3Ciframe%3E%3C%2Fiframe%3E%0D%0A%3Cscript%3E%0D%0Aonload%20%3D%20function%20()%20%7B%0D%0A%20frames%5B0%5D.test%20%3D%201%0D%0A%20w(frames%5B0%5D.test)%3B%0D%0A%20var%20a%20%3D%20frames%5B0%5D.document.location.assign%3B%0D%0A%20w(a)%3B%0D%0A%20w(frames%5B0%5D.document.location.assign%20%3D%3D%3D%20a)%3B%0D%0A%20frames%5B0%5D.document.open()%3B%0D%0A%20frames%5B0%5D.document.write('%3Cscript%3Edocument.write(test)%3C%5C%2Fscript%3E')%3B%0D%0A%20frames%5B0%5D.document.close()%3B%0D%0A%20w(frames%5B0%5D.test)%3B%0D%0A%20w(frames%5B0%5D.document.location.assign%20%3D%3D%3D%20a)%3B%0D%0A%7D%0D%0A%3C%2Fscript%3E -->

<li><p>If <var>document</var> is <span>ready for post-load tasks</span>, then set
<var>document</var>'s <span>reload override flag</span> and set <var>document</var>'s
<span>reload override buffer</span> to the empty string.</p></li>

<li><p>Set <var>document</var>'s <i data-x="concept-document-salvageable">salvageable</i> state
back to true.</p></li>

<li><p>Change <var>document</var>'s <span data-x="concept-document-url">URL</span> to the
<span data-x="concept-document-url">URL</span> of the <span>responsible document</span> specified
by the <span>entry settings object</span>.</p></li>
<var>replace</var>)</code> call. This new entry does not have a <code>Document</code> object, so
a new one will be created if the session history is traversed to that entry.</p></li>

<li><p>Set <var>document</var>'s <span>fired unload</span> flag to false. (It could have been set
to true during the <span data-x="unload a document">unload</span> step above.)</p></li>

<li><p>Finally, set the <span>insertion point</span> to point at just before the end of the
<span>input stream</span> (which at this point will be empty).</p></li>

0 comments on commit 6f769b8

Please sign in to comment.
You can’t perform that action at this time.