Skip to content

Commit

Permalink
document.open() simplifications, part 1
Browse files Browse the repository at this point in the history
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 6f769b8
Showing 1 changed file with 12 additions and 79 deletions.
91 changes: 12 additions & 79 deletions source
Expand Up @@ -76882,14 +76882,11 @@ dictionary <dfn>DragEventInit</dfn> : <span>MouseEventInit</span> {

<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
Expand All @@ -76902,12 +76899,12 @@ dictionary <dfn>DragEventInit</dfn> : <span>MouseEventInit</span> {
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
Expand Down Expand Up @@ -78819,7 +78816,7 @@ callback <dfn>FrameRequestCallback</dfn> = void (<span>DOMHighResTimeStamp</span
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>
Expand Down Expand Up @@ -80582,8 +80579,7 @@ interface <dfn>History</dfn> {
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>

Expand Down Expand Up @@ -82565,7 +82561,7 @@ interface <dfn>Location</dfn> { // but see also <a href="#the-location-interface
<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
Expand Down Expand Up @@ -83494,7 +83490,6 @@ dictionary <dfn>PageTransitionEventInit</dfn> : <span>EventInit</span> {
<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
Expand Down Expand Up @@ -83612,12 +83607,7 @@ dictionary <dfn>PageTransitionEventInit</dfn> : <span>EventInit</span> {
</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
Expand Down Expand Up @@ -83674,8 +83664,7 @@ dictionary <dfn>PageTransitionEventInit</dfn> : <span>EventInit</span> {

<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
Expand All @@ -83684,9 +83673,8 @@ dictionary <dfn>PageTransitionEventInit</dfn> : <span>EventInit</span> {
</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>

Expand Down Expand Up @@ -91018,20 +91006,9 @@ document.body.appendChild(frame)</code></pre>
<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
Expand All @@ -91040,54 +91017,13 @@ document.body.appendChild(frame)</code></pre>

<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>
Expand Down Expand Up @@ -91132,9 +91068,6 @@ document.body.appendChild(frame)</code></pre>
<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>

Expand Down

0 comments on commit 6f769b8

Please sign in to comment.