Skip to content

Unclear what exactly should be aborted in document.open() #3975

@TimothyGu

Description

@TimothyGu

Chrome (and probably Safari):

Here's what Blink and on a large part WebKit do when document.open() gets called

  1. If navigation is ongoing
    1. window.stop() steps, which are:
      1. Recurse to nested BCs (not in spec except for Abort step)
      2. If navigation is ongoing, cancel that navigation (including firing load event if applicable)
      3. Abort, which is:
        1. Cancel ongoing fetches
        2. Abort the parser (fires two readystatechange events if parser is active, which could maybe be observable given long pages that do setTimeout(() => document.open(), 0) near the top?)
      4. Cancel queued navigations (not in spec, Clarify how to cancel a navigation #3447)
  2. Cancel queued navigations (this handles cases like setting location.href, which in Blink/WebKit queues a task to navigate instead of navigating directly)

Firefox

not sure, but it does cancel navigation to some extent

Spec:

Currently, document.open() in spec only does:

  1. Abort
    1. Cancel fetches, including navigation
    2. Abort parser

I tried this out in Chrome (with canceling ongoing and queued navigation), it breaks a lot of tests.

Ideal 1:

This is basically Chrome's current behavior without canceling ongoing fetches.

  1. Cancel ongoing and queued navigation (would probably be merged by fixing Clarify how to cancel a navigation #3447)
  2. Abort the parser (necessary because step 16 will create a new one; maybe move to right before step 16)

Reasoning versus Chrome: it's weird that abort, which messes with fetches (not just navigations), is conditional on navigation being ongoing rather than queued.

Ideal 2:

  1. If navigation is ongoing [or queued], run the window.stop() steps:
    1. Abort, which is:
      1. Cancel ongoing fetches
      2. Abort the parser
    2. Cancel ongoing [and queued] navigation

Bracketed wording would probably be best addressed by fixing #3447)

Reasoning: more straightforward, and mostly reuses existing primitives.

Other

  • How much of this, if any, recurses into descendant BCs? (Abort does that per spec. Chrome does that only if there is an ongoing navigation)
  • We should probably move all of this after erasing the event listeners to make it less observable (e.g. to avoid the weird readystatechange issues in long documents when aborting the parser)

/cc @bzbarsky @zetafunction @natechapin

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions