From 72626cd3b4cee99fc87630bcf7035ec289c9b8c6 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Thu, 21 Apr 2016 15:35:17 -0400 Subject: [PATCH] Add a new section detailing the various potential realms This adds a new section under scripts detailing the entry, incumbent, current, and relevant concepts with regard to realms/global objects/ environment settings objects. This centralizes information that was previously somewhat spread out, and adds lots of details, as well as an example. This takes care of some of the pain points noted in #473, in particular fixing the definition of entry settings object to be more clearly defined in terms of the JavaScript execution context stack. There is still some work to do in that issue: namely, updating Web IDL with regard to tracking the entry settings object, and also making sure that incumbent settings object is correctly defined. This closes #167 by finally implementing the plan in https://github.com/whatwg/html/issues/167#issuecomment-195478361 for making the correspondences clear. --- source | 375 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 261 insertions(+), 114 deletions(-) diff --git a/source b/source index 7364d56f2d1..2b31e42bceb 100644 --- a/source +++ b/source @@ -3326,6 +3326,17 @@ a.setAttribute('href', 'http://example.com/'); // change the content attribute d +
Battery Status
+ +
+ +

The following features are defined in the Battery Status API specification:

+ + + +
@@ -86896,52 +86907,6 @@ interface NavigatorOnLine { implementations are free to limit its size, e.g. by removing old entries from it when new ones are added.

-
- -

A global object is a JavaScript object that is the [[GlobalObject]] field of a - JavaScript realm.

- -

In this specification, all JavaScript - realms are initialized with global objects that are either Window or - WorkerGlobalScope objects.

- -

There is always a 1:1:1 mapping between JavaScript - realms, global objects, and environment settings objects:

- - - -

The relevant settings object for a non-global platform object - o is the environment settings object whose global object is the global object of the - global environment associated with o.

- -
Fetching scripts

The various script-fetching algorithms below have two hooks that may be customized by their @@ -87347,7 +87312,7 @@ interface NavigatorOnLine { -

Calling scripts
+
Calling scripts

To run a classic script given a classic script s and an optional rethrow errors flag:

@@ -87470,7 +87435,8 @@ interface NavigatorOnLine {
    -
  1. Label settings as a candidate entry settings object.

  2. +
  3. Set settings's realm execution context's is candidate entry + execution context flag to true.

  4. Push settings's realm execution context onto the JavaScript execution context stack; it is now the running JavaScript execution @@ -87484,12 +87450,12 @@ interface NavigatorOnLine {

      -
    1. Stop labeling settings as a candidate entry settings - object.

    2. -
    3. Assert: settings's realm execution context is the running JavaScript execution context.

    4. +
    5. Set settings's realm execution context's is candidate entry + execution context flag to false.

    6. +
    7. Remove settings's realm execution context from the JavaScript execution context stack.

    8. @@ -87511,18 +87477,205 @@ interface NavigatorOnLine {
      -

      A JavaScript execution context's settings object is the - settings object of the script in the [[HostDefined]] field in the - ScriptOrModule component of the given JavaScript execution context.

      +

      Each unit of related similar-origin browsing contexts has a global script + clean-up jobs list, which must initially be empty. A global script clean-up job cannot run + scripts, and cannot be sensitive to the order in which other clean-up jobs are executed. The File + API uses this to release blob: URLs.

      + +

      When the user agent is to run the global script clean-up jobs, the user agent must + perform each of the jobs in the global script clean-up jobs list and then empty the + list.

      -

      The current settings object is the environment settings object of the current - Realm Record.

      +
      Realms, settings objects, and global objects
      + +

      A global object is a JavaScript object that is the [[GlobalObject]] field of a + JavaScript realm.

      + +

      In this specification, all JavaScript + realms are initialized with global objects that are either Window or + WorkerGlobalScope objects.

      + +

      There is always a 1:1:1 mapping between JavaScript + realms, global objects, and environment settings objects:

      + +
        +
      • A JavaScript realm has a [[HostDefined]] field, which contains the Realm's settings object.

      • + +
      • A JavaScript realm has a [[GlobalObject]] field, which contains the Realm's global object.

      • + +
      • Each global object in this specification is created during the initialization of a corresponding JavaScript + realm, known as the global object's + Realm.

      • + +
      • Each global object in this + specification is created alongside a corresponding environment settings object, + known as its relevant settings object.

        -

        The entry settings object is the settings object of the topmost entry in the JavaScript execution - context stack whose settings object is labeled as a candidate entry settings object.

        +
      • An environment settings object's realm execution context's + Realm component is the environment settings + object's Realm.

      • + +
      • An environment settings object's Realm then has a [[GlobalObject]] field, which contains the environment settings object's global + object.

      • +
      + +

      When defining algorithm steps throughout this specification, it is often important to indicate + what JavaScript realm is to be used—or, equivalently, what global object + or settings object is to be used. In general, there are four possibilities:

      + +
      +
      Entry
      +
      This corresponds to the script that initiated the currently running script action: i.e., + the script that was on the stack when the user agent called in to author code.
      + +
      Incumbent
      +
      This corresponds to the most-recently-entered author script on the stack.
      + +
      Current
      +
      This corresponds to the currently-running function object, including built-in user-agent + functions which might not be implemented as JavaScript.
      + +
      Relevant
      +
      This corresponds to the this argument on which the currently-running function object + is being applied.
      +
      + +
      + +

      Consider the following pages, with a.html being loaded in a browser + window, b.html being loaded in an iframe as shown, and c.html and d.html omitted (they can simply be empty + documents):

      + +
      <!-- a.html -->
      +<!DOCTYPE html>
      +<html lang="en">
      +<title>Entry page</title>
      +
      +<iframe src="b.html"></iframe>
      +<button onclick="frames[0].hello()">Hello</button>
      +
      +<!--b.html -->
      +<!DOCTYPE html>
      +<html lang="en">
      +<title>Incumbent page</title>
      +
      +<iframe src="c.html" id="c"></iframe>
      +<iframe src="d.html" id="d"></iframe>
      +
      +<script>
      +  const c = document.querySelector("#c").contentWindow;
      +  const d = document.querySelector("#d").contentWindow;
      +
      +  window.hello = () => {
      +    c.print.call(d);
      +  };
      +</script>
      + +

      Each page has its own browsing context, and thus its own JavaScript + realm, global object, and settings object.

      + +

      When the button is pressed in a.html, then:

      + +
        +
      • The entry settings object is that of a.html.

      • +
      • The incumbent settings object is that of b.html.

      • +
      • The current settings object is that of c.html (since + it is the print() method from c.html + whose code is running).

      • +
      • The relevant settings object of the object on which the print() method is being called is that of d.html.

      • +
      +
      + + +

      The incumbent concept should not be used by + new specifications, and we are considering whether it can be removed from the platform. See Bugzilla bug 26603. Currently, the + incumbent concept is used in some security + checks.

      + +

      There is currently discussion about whether the entry concept should be used going forward; see Bugzilla bug 27203. Currently, the + entry concept is used to obtain, amongst other + things, the API base URL to parse a URL, used in + scripts running in that unit of related similar-origin browsing contexts.

      + +

      In general, the current concept is what should + be used by specifications going forward. There is an important exception, however. If an algorithm + is creating an object that is to be persisted and returned multiple times (instead of simply + returned to author code right away, and never vended again), it should use the relevant concept with regard to the object on which + the method in question is being executed. This prevents cross-realm calls from causing an object + to store objects created in the "wrong" realm.

      + +
      +

      The navigator.getBattery() method creates + promises in the relevant Realm for the + Navigator object on which it is invoked. This has the following impact: + +

      <!DOCTYPE html>
      +<html lang="en">
      +<title>Relevant Realm demo</title>
      +
      +<iframe src="about:blank"></iframe>
      +<script>
      +  const promise = navigator.getBattery().call(frames[0].navigator);
      +
      +  console.log(promise instanceof Promise);           // logs false
      +  console.log(promise instanceof frames[0].Promise); // logs true
      +</script>
      + +

      If the algorithm for the getBattery() method + had instead used the current Realm, the results would + be reversed. The downside of such an approach would be that all future calls to that frame's + getBattery(), even ones from within the + iframe and without cross-frame shenanigans, would forever return Promise objects from the outer realm. Since this is undesirable, the algorithm + instead uses the relevant Realm.

      +
      + +
      + +

      The rest of this section deals with formally defining the entry, incumbent, current, and relevant concepts.

      + +
      Entry
      + +

      All JavaScript execution contexts must + contain a boolean flag, is candidate entry execution context, which is initially set + to false. In the process of calling scripts, this flag can be + toggled.

      + +

      With this in hand, we define the entry execution context to be the topmost entry in + the JavaScript execution context stack whose is candidate entry execution + context flag is set to true. The entry Realm is + the entry execution context's Realm component.

      + +

      Then, the entry settings object is the environment settings object of the entry Realm.

      + +

      Similarly, the entry global object is the global object of the entry + Realm.

      + +
      Incumbent

      The incumbent settings object is determined as follows:

      @@ -87536,69 +87689,59 @@ interface NavigatorOnLine { scriptOrModule's [[HostDefined]] field.

    -
    -

    The entry settings object is used to obtain, amongst other things, the API - base URL to parse a URL, used in scripts running in that - unit of related similar-origin browsing contexts.

    +

    Then, the incumbent Realm is the Realm of the incumbent settings + object.

    -

    The incumbent settings object is used in some security checks.

    -
    - -

    The incumbent settings object concept should not be used by new - specifications, and we are considering whether it can be removed from the platform. See Bugzilla bug 26603.

    +

    Similarly, the incumbent global object is the + global object of the incumbent + settings object.

    -
    +
    Current
    -

    Consider the following two pages, with the first being loaded in a browser window and the - second being loaded in the iframe of the first:

    +

    The JavaScript specification defines the current Realm Record, sometimes + abbreviated to "the current Realm".

    -
    <!-- a/a.html -->
    -<!DOCTYPE HTML>
    -<html lang="en">
    -<title>Outer page</title>
    -<iframe src="../b/b.html"></iframe>
    -<input type=button onclick="frames[0].hello()" value="Hello">
    +

    Then, the current settings object is the environment settings object of the current + Realm Record.

    -
    <!-- b/b.html -->
    -<!DOCTYPE HTML>
    -<html lang="en">
    -<title>Inner page</title>
    -<script>
    - function hello() {
    -   location.assign('c.html');
    - }
    -</script>
    +

    Similarly, the current global object is the global object of the current Realm Record.

    -

    When the button is pressed in the inner frame, the outer page runs script in the inner page. - While the hello() function is running, the entry settings - object is that of the outer file (a/a.html), and the - incumbent settings object is that of the inner file (b/b.html).

    +
    Relevant
    -

    The assign() method uses the entry settings - object to parse the URL, so we end up loading a/c.html, but it uses the incumbent settings object to establish - the source browsing context, from which the referrer is established, so the `Referer` header sent with the request for a/c.html specifies the inner file's URL (the one ending with b/b.html).

    +

    The relevant settings object for a platform object is defined as + follows:

    - +
    +
    If the object is a global object
    +
    Each global object in this specification is created alongside a corresponding + environment settings object; that is its relevant settings object.
    -
    +
    Otherwise
    +
    +

    The relevant settings object for a non-global platform object + o is the environment settings object whose global object is the global object of the + global environment associated with o.

    -
    +

    The "global environment associated with" concept is from the olden + days, before the modern JavaScript specification and its concept of realms. We expect that as the Web IDL specification gets updated, every + platform object will have a Realm associated + with it, and this definition can be re-cast in those terms.

    +
    + -

    Each unit of related similar-origin browsing contexts has a global script - clean-up jobs list, which must initially be empty. A global script clean-up job cannot run - scripts, and cannot be sensitive to the order in which other clean-up jobs are executed. The File - API uses this to release blob: URLs.

    +

    Then, the relevant Realm for a platform + object is the Realm of its + relevant settings object.

    -

    When the user agent is to run the global script clean-up jobs, the user agent must - perform each of the jobs in the global script clean-up jobs list and then empty the - list.

    +

    Similarly, the relevant global object for a + platform object is the global + object of its relevant settings object.

    Killing scripts
    @@ -87673,7 +87816,8 @@ interface NavigatorOnLine {
    1. Assert: queueName is "PromiseJobs". ("ScriptJobs" must not be used by user agents.)

    2. -
    3. Let settings be the current settings object.

    4. +
    5. Let settings be the settings + object of job.[[Realm]].

    6. Queue a microtask, on settings's responsible event loop, to perform the following steps:

      @@ -118546,6 +118690,9 @@ INSERT INTERFACES HERE
      [ATOM]
      (Non-normative) The Atom Syndication Format, M. Nottingham, R. Sayre. IETF.
      +
      [BATTERY]
      +
      (Non-normative) Battery Status API, A. Kostiainen, M. Lamouri. W3C.
      +
      [BCP47]
      Tags for Identifying Languages; Matching of Language Tags, A. Phillips, M. Davis. IETF.
      @@ -118571,7 +118718,7 @@ INSERT INTERFACES HERE
      Unicode Common Locale Data Repository. Unicode.
      [COMPOSITE]
      -
      Compositing and Blending. R. Cabanier, N. Andronikos. W3C.
      +
      Compositing and Blending, R. Cabanier, N. Andronikos. W3C.
      [COMPUTABLE]
      (Non-normative) On computable numbers, with an application to the Entscheidungsproblem, A. Turing. In Proceedings of the London Mathematical Society, series 2, volume 42, pages 230-265. London Mathematical Society, 1937.