Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mark document.write() as obsolete #7977

Open
zcorpan opened this issue Jun 1, 2022 · 22 comments
Open

Mark document.write() as obsolete #7977

zcorpan opened this issue Jun 1, 2022 · 22 comments
Labels
impacts documentation Used by documentation communities, such as MDN, to track changes that impact documentation removal/deprecation Removing or deprecating a feature topic: parser

Comments

@zcorpan
Copy link
Member

zcorpan commented Jun 1, 2022

The document.write() API blocks the HTML parser (or rather, <script> blocks the HTML parser because the script might use document.write()) and can cause significant slowness for users (in particular when writing a <script src> which also calls document.write(), and again multiple levels deep). It's also responsible for significant implementation complexity to support (nested invocations of the parser, the need for speculative parsing...).

The spec has this warning:

This method has very idiosyncratic behavior. In some cases, this method can affect the state of the HTML parser while the parser is running, resulting in a DOM that does not correspond to the source of the document (e.g. if the string written is the string "<plaintext>" or "<!--"). In other cases, the call can clear the current page first, as if document.open() had been called. In yet more cases, the method is simply ignored, or throws an exception. Users agents are explicitly allowed to avoid executing script elements inserted via this method. And to make matters even worse, the exact behavior of this method can in some cases be dependent on network latency, which can lead to failures that are very hard to debug. For all these reasons, use of this method is strongly discouraged.

https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()

Yet, this API is not marked as an obsolete feature. Why not?

MDN doesn't specifically discourage the use of document.write(): https://developer.mozilla.org/en-US/docs/Web/API/Document/write

I'm aware of the following issue that could be argued should block obsoleting document.write():

Are there any other reasons?

(Note that I'm not suggesting that support should be removed. That would not be web-compatible.)

cc @whatwg/html-parser

@zcorpan zcorpan added removal/deprecation Removing or deprecating a feature impacts documentation Used by documentation communities, such as MDN, to track changes that impact documentation topic: parser labels Jun 1, 2022
sideshowbarker added a commit to mdn/content that referenced this issue Jun 1, 2022
Fixes #16852

See also whatwg/html#7977.

This change adds a prominent warning to the top of the document.write()
article, quoting the prominent warning from the HTML itself at
https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()
sideshowbarker added a commit to mdn/content that referenced this issue Jun 1, 2022
Fixes #16852

See also whatwg/html#7977.

This change adds a prominent warning to the top of the document.write()
article, quoting the prominent warning from the HTML itself at
https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()
sideshowbarker added a commit to mdn/content that referenced this issue Jun 1, 2022
Fixes #16852

See also whatwg/html#7977.

This change adds a prominent warning to the top of the document.write()
article, quoting the prominent warning from the HTML itself at
https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()
@domenic
Copy link
Member

domenic commented Jun 1, 2022

What are you suggesting specifically by saying "marked as an obsolete feature"?

@zcorpan
Copy link
Member Author

zcorpan commented Jun 1, 2022

That the IDL

  // dynamic markup insertion
  [CEReactions] Document open(optional DOMString unused1, optional DOMString unused2); // both arguments are ignored
  WindowProxy? open(USVString url, DOMString name, DOMString features);
  [CEReactions] undefined close();
  [CEReactions] undefined write(DOMString... text);
  [CEReactions] undefined writeln(DOMString... text);

and relevant spec text are moved into the Obsolete features section (maybe a new subsection for dynamic markup insertion).

@domenic
Copy link
Member

domenic commented Jun 1, 2022

What would the goal of such a move be?

Note also that right now the "Obsolete features" section contains:

  • Elements and attributes and their associated HTML interfaces/IDL attributes
  • Do-nothing methods and interfaces

This would be the first instance of do-something methods in that section, that aren't related to a non-conforming HTML element.

@zcorpan
Copy link
Member Author

zcorpan commented Jun 1, 2022

document.all at least is a do-something obsolete API, not associated with a particular element.

The goal is to more clearly be opinionated about the API having the same obsolete status as document.all and have that fact trickle to other documentation like MDN, BCD, and similar.

@zcorpan
Copy link
Member Author

zcorpan commented Jun 1, 2022

The user-centric goal is to drive down usage and nudge developers towards alternative patterns that don't block the HTML parser, which should make the web less slow for users.

The long-term implementer-centric goal is to drive down usage over time until it's low enough that support can be removed completely. I don't expect this to happen anytime soon, if at all, though.

@domenic
Copy link
Member

domenic commented Jun 1, 2022

document.all at least is a do-something obsolete API, not associated with a particular element.

It's not in the obsolete section.

The user-centric goal is to drive down usage and nudge developers towards alternative patterns that don't block the HTML parser, which should make the web less slow for users.

I think MDN might be the best place for that? Or we could consider adding a "this feature is in the process of being removed from the web platform. (This is a long process that takes many years.)" box like we did for document.domain, but it feels a bit early for that.

@zcorpan
Copy link
Member Author

zcorpan commented Jun 1, 2022

It's not in the obsolete section.

Yes it is: https://html.spec.whatwg.org/multipage/obsolete.html#dom-document-all

The spec for HTMLAllCollection is not in the obsolete section, though, indeed.

I think MDN might be the best place for that? Or we could consider adding a "this feature is in the process of being removed from the web platform. (This is a long process that takes many years.)" box like we did for document.domain, but it feels a bit early for that.

I think we shouldn't say that it's in the process of being removed until it actually is plausible that it can be removed. It can be marked as obsolete even if it's never removed (like <font> or document.all).

@meyerweb
Copy link
Member

meyerweb commented Jun 1, 2022

Speaking with my Open Web Docs member/MDN contributor hat on, I don’t see a problem with marking the MDN page with warnings and obsolete banners and what-all, and offer myself as tribute to add them if that’s judged to be a good idea by the group.

@zcorpan
Copy link
Member Author

zcorpan commented Jun 1, 2022

I think the spec should be the source of truth for which APIs are obsolete or not obsolete, not MDN.

@hsivonen
Copy link
Member

hsivonen commented Jun 1, 2022

Has usage in newly-authored content and the availability of reasonable alternatives with similar author ergonomics been surveyed recently?

@zcorpan
Copy link
Member Author

zcorpan commented Jun 1, 2022

The blocking=render attribute is not yet shipped by anyone per https://chromestatus.com/feature/5452774595624960

The feature proposed in #7976 would also need to be shipped for developers to have an alternative for conditionally including module scripts that block rendering.

I don't see a chromium use counter for document.write/ln. Am I missing it? If not, is there interest in adding one?

sideshowbarker added a commit to mdn/content that referenced this issue Jun 2, 2022
Fixes #16852

See also whatwg/html#7977.

This change adds a prominent warning to the top of the document.write()
and document.writeln() articles, quoting the warning from the HTML itself at
https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()
sideshowbarker added a commit to mdn/content that referenced this issue Jun 2, 2022
Fixes #16852

See also whatwg/html#7977.

This change adds a prominent warning to the top of the document.write()
and document.writeln() articles, quoting the warning from the HTML itself at
https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#document.write()
@annevk
Copy link
Member

annevk commented Jun 2, 2022

This might be the wrong place to bring this up, but similar to not liking Appendix B in ECMAScript, I'm not a fan of HTML's Obsolete features. I'd prefer we figure out some consistent terminology across WHATWG standards (harmonize legacy/deprecated/obsolete; it seems historical already got removed) and settle for inline annotations. So features are still described as part of a larger whole, but it's clear when they're best not used.

@sideshowbarker
Copy link
Contributor

I'd prefer we figure out some consistent terminology across WHATWG standards (harmonize legacy/deprecated/obsolete; it seems historical already got removed) and settle for inline annotations. So features are still described as part of a larger whole, but it's clear when they're best not used.

I’d suggest considering to harmonize on the term “discouraged”.

For MDN we’ve had a similar need, and some rough consensus around moving to “discouraged” has emerged.

If the HTML spec and MDN were to both move to using “discouraged”, that’d be some very nice harmony.

@zcorpan
Copy link
Member Author

zcorpan commented Jun 2, 2022

Would obsolete elements also be "discouraged"? Currently the spec says obsolete elements and attributes must not be used (but doesn't seem to say that APIs in that section must not be used).

@sideshowbarker
Copy link
Contributor

Would obsolete elements also be "discouraged"? Currently the spec says obsolete elements and attributes must not be used (but doesn't seem to say that APIs in that section must not be used).

For the HTML spec it seems if something’s already marked as obsolete, it’d be redundant to also mark it as “discouraged”.

(For MDN, we no longer use “obsolete” at all, and what we’re considering is to replace “deprecated” with “discouraged”.)

@zcorpan
Copy link
Member Author

zcorpan commented Jun 3, 2022

How about a WebIDL extended attribute [Obsolete] or [Legacy] which means

  • developers must not use the API
  • user agents may warn in a console

@annevk
Copy link
Member

annevk commented Jun 3, 2022

I think @domenic didn't like that last time it was suggested (by @saschanaz?) as it had no normative implications, but maybe "optionally call console.warn" suffices?

(If we go with "discouraged" though the IDL attribute should match that naming.)

@zcorpan
Copy link
Member Author

zcorpan commented Jun 3, 2022

"Discouraged" is used in HTML today for intentionally non-normative discouragement. We could change that, but I think if it means "must not use" (like obsolete elements), then "discouraged" doesn't seem like an appropriate term. But maybe such APIs should be "should not use" instead?

14 instances of "discouraged"
% git grep -i -C 3 discouraged source
source-
source-  <p>The only remaining presentational markup features in HTML are the <code
source-  data-x="attr-style">style</code> attribute and the <code>style</code> element. Use of the <code
source:  data-x="attr-style">style</code> attribute is somewhat discouraged in production environments, but
source-  it can be useful for rapid prototyping (where its rules can be directly moved into a separate
source-  style sheet later) and for providing specific styles in unusual cases where a separate style sheet
source-  would be inconvenient. Similarly, the <code>style</code> element can be useful in syndication or
--
source-
source-   <dd>
source-    <p>Some authors like to write files that can be interpreted as both XML and HTML with similar
source:    results. Though this practice is discouraged in general due to the myriad of subtle
source-    complications involved (especially when involving scripting, styling, or any kind of automated
source-    serialization), this specification has a few restrictions intended to at least somewhat mitigate
source-    the difficulties. This makes it easier for authors to use this as a transitionary step when
--
source-  <h4>Extensibility</h4>
source-
source-  <p>Vendor-specific proprietary user agent extensions to this specification are strongly
source:  discouraged. Documents must not use such extensions, as doing so reduces interoperability and
source-  fragments the user base, allowing only users of specific user agents to access the content in
source-  question.</p>
source-
--
source-
source-  <div class="example">
source-
source:   <p>For example, while strongly discouraged from doing so, an implementation could add a new IDL
source-   attribute "<code data-x="">typeTime</code>" to a control that returned the time it took the user
source-   to select the current value of a control (say). On the other hand, defining a new control that
source-   appears in a form's <code data-x="dom-form-elements">elements</code> array would be in violation
--
source-    <li><p>"From the contents of the 'simple module graph' figure..."</p></li>
source-
source-    <li><p>"In the figure below..." (but <a href="#figure-note-about-references">this is
source:    discouraged</a>)</p></li>
source-   </ul>
source-  </div>
source-
--
source-
source-  <!-- search for title-warning if modifying this paragraph -->
source-  <p class="note">Relying on the <code data-x="attr-title">title</code> attribute is currently
source:  discouraged as many user agents do not expose the attribute in an accessible manner as required by
source-  this specification (e.g., requiring a pointing device such as a mouse to cause a tooltip to
source-  appear, which excludes keyboard-only users and touch-only users, such as anyone with a modern
source-  phone or tablet).</p>
--
source- &lt;p>...&lt;/p>
source-&lt;/section></code></pre>
source-
source:     <p>In such cases it is unnecessary (and indeed discouraged) to include a reference to the
source-     presence of the image itself in the alternative text, since such text would be redundant with
source-     the browser itself reporting the presence of the image. For example, if the alternative text
source-     was "A photo of Isaac Asimov", then a conforming user agent might read that out as "(Image) A
--
source-
source-      <!-- search for title-warning if modifying this paragraph -->
source-      <p class="note">Relying on the <code data-x="attr-title">title</code> attribute is currently
source:      discouraged as many user agents do not expose the attribute in an accessible manner as
source-      required by this specification (e.g. requiring a pointing device such as a mouse to cause a
source-      tooltip to appear, which excludes keyboard-only users and touch-only users, such as anyone
source-      with a modern phone or tablet).</p>
--
source-
source-  <!-- search for title-warning if modifying this paragraph -->
source-  <p class="note">Unfortunately, relying on the <code data-x="attr-title">title</code> attribute is
source:  currently discouraged as many user agents do not expose the attribute in an accessible manner as
source-  required by this specification (e.g. requiring a pointing device such as a mouse to cause a
source-  tooltip to appear, which excludes keyboard-only users and touch-only users, such as anyone with a
source-  modern phone or tablet).</p>
--
source-   <dt><code data-x=""><var>element</var>.<span subdfn data-x="dom-blur">blur</span>()</code></dt>
source-
source-   <dd>
source:    <p>Moves the focus to the <span>viewport</span>. Use of this method is discouraged; if you want
source-    to focus the <span>viewport</span>, call the <code data-x="dom-focus">focus()</code> method on
source-    the <code>Document</code>'s <span>document element</span>.</p>
source-
--
source-  because it automatically picks the right <span>event loop</span> and, where appropriate, <span
source-  data-x="concept-task-document">document</span>. Older specifications often use <span>queue a
source-  task</span> combined with the <span>implied event loop</span> and <span>implied document</span>
source:  concepts, but this is discouraged.</p>
source-
source-  <p>Putting this all together, we can provide a template for a typical algorithm that needs to do
source-  work asynchronously:</p>
--
source-        </script>
source-
source-    -->, which can lead to failures that are very hard to debug. <strong>For all these reasons, use
source:    of this method is strongly discouraged.</strong></p>
source-
source-    <p>Throws an <span>"<code>InvalidStateError</code>"</span> <code>DOMException</code> when
source-    invoked on <span>XML documents</span>.</p>
--
source-    data-x="concept-encoding-confidence">confidence</span> <i>tentative</i>.
source-    <ref spec=UNIVCHARDET></p>
source-
source:    <p class="note">User agents are generally discouraged from attempting to autodetect encodings
source-    for resources obtained over the network, since doing so involves inherently non-interoperable
source-    heuristics. Attempting to detect encodings based on an HTML document's preamble is especially
source-    tricky since HTML markup typically uses only ASCII characters, and HTML documents tend to begin
--
source-  circumstances, conformance checkers must warn the user when the following features are used in a
source-  document. These are generally old obsolete features that have no effect, and are allowed only to
source-  distinguish between likely mistakes (regular conformance errors) and mere vestigial markup or
source:  unusual and discouraged practices (these warnings).</p>
source-
source-  <p>The following features must be categorized as described
source-  above:</p>

@saschanaz
Copy link
Member

I think @domenic didn't like that last time it was suggested (by @saschanaz?) as it had no normative implications, but maybe "optionally call console.warn" suffices?

(Yeah, that was whatwg/webidl#910 and whatwg/webidl#929.)

@domenic
Copy link
Member

domenic commented Jun 3, 2022

So we seem to be discussing a lot of related areas, all of which are worthwhile. Let me try to give a summary of the problem statement/state of things.

I'll use the word "discouraged" as a general word, and "HTML-discouraged" to refer to the specific sense the HTML spec uses it per @zcorpan's comment #7977 (comment).

  • Discouragement cues:
    • MDN wants to discourage some web platform features. They might appreciate cues from spec editors on those.
    • IDEs and other tools want to discourage some web platform features. They might appreciate cues from spec editors on those.
    • The IDE case, and maybe the MDN case too, would benefit from these cues being machine-readable. Thus suggestions of an IDL attribute.
    • It's unclear whether spec editors are a good source of determining what's discouraged. See some of my previous thoughts in Add [Historical] extended attribute webidl#929 (comment) and my following comment there.
      • I believe spec editors/implementers can say things about future removals (document.domain), or which parts of the spec are full of terrible interop and should not be used so that hopefully one day we can remove or simplify them (<embed>/<object>).
      • But I think we are bad at making judgment calls like document.charset vs. document.characterSet, or element.append() vs. element.appendChild().
      • I'm unsure about cases like document.all (interoperable, will stick around forever, but still "icky") or document.releaseEvents() (a pointless no-op, but is it hurting anyone if an old page still has some code using it?).
  • HTML spec hygeine:
    • The HTML spec has at least three types of discouragement: obsolete features, "HTML-discouraged" features, and "This feature is in the process of being removed from the web platform".
    • Probably lots of other ad-hoc discouragements also exist.
    • It's unclear what category document.write() would fall into, partially because we don't have much precedent for discouraged APIs-that-still-do-something. (But, document.all is a reasonable precedent.)
    • HTML's current division of stuff into obsolete sections is kind of not great (Mark document.write() as obsolete #7977 (comment)).
      • It's unclear on the best way to fix this for stuff like <marquee> or <frame>, where giving them the same treatment as normal elements would require writing a lot of new text, making decisions about what section to elevate them too, ...
  • Naming:
    • As mentioned above, HTML uses "discouraged", "in the process of being removed from the web platform", and "obsolete"
    • Other specs have used "historical", "legacy", and "deprecated"
    • Probably there are more such terms.
    • It's not clear a single term makes sense for all such cases; we may need a taxonomy, e.g. to capture differences in what conformance checkers should do or whether a feature is planned for removal.

@zcorpan
Copy link
Member Author

zcorpan commented Jun 3, 2022

HTML also has "obsolete but conforming", which are should not use instead of must not use, and cause warnings in conformance checkers instead of errors.

@zcorpan
Copy link
Member Author

zcorpan commented Sep 6, 2022

@jakearchibald noted in https://twitter.com/jaffathecake/status/1565289125468569601 that document.write can be used as a poor man's streaming parser API (see #2142). So maybe we need to add that to the list of blockers here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
impacts documentation Used by documentation communities, such as MDN, to track changes that impact documentation removal/deprecation Removing or deprecating a feature topic: parser
Development

No branches or pull requests

7 participants