Skip to content

Commit d0b0925

Browse files
authored
Clarify and tweak <embed> processing model
This rewrites the <embed> processing model in a more modern style, along the way clarifying a few things and making some minor normative changes. * Fixes #3876 by colocating the text about notification of there being no plugin into the main algorithm, where it is more easily noticed. * Changes to not fire load events when no plugin is loaded. * Changes the SVG browsing context to get unloaded when a non-SVG is being displayed. With regard to these normative changes, browsers behave inconsistently. Indeed, they behave inconsistently in general with regard to lots of features of <embed> and <object>; see https://github.com/whatwg/html/labels/topic%3A%20embed%20and%20object. We leave a more comprehensive overhaul, including with a testing story, for later work. This revision just provides a basis for that future work.
1 parent 55c75fd commit d0b0925

File tree

1 file changed

+161
-127
lines changed

1 file changed

+161
-127
lines changed

source

Lines changed: 161 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -30322,186 +30322,220 @@ interface <dfn>HTMLEmbedElement</dfn> : <span>HTMLElement</span> {
3032230322
data-x="attr-embed-type">src</code> attribute set, changed, or removed or its <code
3032330323
data-x="attr-embed-type">type</code> attribute set, changed, or removed, the user agent must
3032430324
<span>queue a task</span> using the <dfn>embed task source</dfn> to run <span>the
30325-
<code>embed</code> element setup steps</span>.</p>
30325+
<code>embed</code> element setup steps</span> for that element.</p>
3032630326

30327-
<p><dfn>The <code>embed</code> element setup steps</dfn> are as follows:</p>
30327+
<p><dfn>The <code>embed</code> element setup steps</dfn> for a given <code>embed</code> element
30328+
<var>element</var> are as follows:</p>
3032830329

3032930330
<ol>
30330-
3033130331
<li><p>If another <span data-x="concept-task">task</span> has since been queued to run <span>the
30332-
<code>embed</code> element setup steps</span> for this element, then return.</p></li>
30332+
<code>embed</code> element setup steps</span> for <var>element</var>, then return.</p></li>
3033330333

3033430334
<li><p>If the <span>Should element be blocked <i lang="la">a priori</i> by Content Security
30335-
Policy?</span> algorithm returns "<code data-x="">Blocked</code>" when executed on the element,
30336-
then return. <ref spec="CSP"></p></li>
30335+
Policy?</span> algorithm returns "<code data-x="">Blocked</code>" when executed on
30336+
<var>element</var>, then return. <ref spec="CSP"></p></li>
3033730337

3033830338
<li>
30339+
<p>If <var>element</var> has a <code data-x="attr-embed-src">src</code> attribute set, then:</p>
3033930340

30340-
<dl class="switch">
30341+
<ol>
30342+
<li><p>Let <var>url</var> be the result of <span data-x="parse a url">parsing</span> the value
30343+
of <var>element</var>'s <code data-x="attr-embed-src">src</code> attribute, relative to
30344+
<var>element</var>'s <span>node document</span>.</p></li>
3034130345

30342-
<dt>If the element has a <code data-x="attr-embed-src">src</code> attribute set</dt>
30346+
<li><p>If <var>url</var> is failure, then return.</p></li>
3034330347

30344-
<dd>
30348+
<li><p>Let <var>request</var> be a new <span data-x="concept-request">request</span> whose
30349+
<span data-x="concept-request-url">url</span> is <var>url</var>, <span
30350+
data-x="concept-request-client">client</span> is <var>element</var>'s <span>node
30351+
document</span>'s <span>relevant settings object</span>, <span
30352+
data-x="concept-request-destination">destination</span> is "<code data-x="">embed</code>",
30353+
<span data-x="concept-request-credentials-mode">credentials mode</span> is "<code
30354+
data-x="">include</code>", and whose <span>use-URL-credentials flag</span> is set.</p></li>
3034530355

30346-
<p>The user agent must <span data-x="parse a url">parse</span> the value of the element's
30347-
<code data-x="attr-embed-src">src</code> attribute, relative to the element's <span>node
30348-
document</span>. If that is successful, the user agent should run these steps:
30356+
<li>
30357+
<p><span data-x="concept-fetch">Fetch</span> <var>request</var>.</p>
3034930358

30350-
<ol>
30351-
<!-- identical for <embed>/<object> -->
30352-
<li><p>Let <var>request</var> be a new <span data-x="concept-request">request</span> whose
30353-
<span data-x="concept-request-url">url</span> is the <span>resulting URL record</span>,
30354-
<span data-x="concept-request-client">client</span> is the element's <span>node
30355-
document</span>'s <span>relevant settings object</span>, <span
30356-
data-x="concept-request-destination">destination</span> is "<code data-x="">embed</code>",
30357-
<span data-x="concept-request-credentials-mode">credentials mode</span> is "<code
30358-
data-x="">include</code>", and whose <span>use-URL-credentials flag</span> is set.</p></li>
30359-
30360-
<!--FETCH--><li><p><span data-x="concept-fetch">Fetch</span> <var>request</var>.</p></li>
30361-
</ol>
30359+
<p>Fetching the resource must <span>delay the load event</span> of <var>element</var>'s
30360+
<span>node document</span>.</p>
3036230361

30363-
<p>The <span data-x="concept-task">task</span> that is <span
30364-
data-x="queue a task">queued</span> by the <span>networking task source</span> once the
30365-
resource has been fetched must run the following steps:</p>
30366-
<!-- Note that this doesn't happen when the base URL changes. -->
30362+
<p>To <span>process response</span> for the <span data-x="concept-response">response</span>
30363+
<var>response</var>:</p>
3036730364

3036830365
<ol>
30369-
3037030366
<li><p>If another <span data-x="concept-task">task</span> has since been queued to run
30371-
<span>the <code>embed</code> element setup steps</span> for this element, then return.</p></li>
30372-
30373-
<li>
30374-
30375-
<p>Determine the <dfn data-x="concept-embed-type">type of the content</dfn> being embedded, as
30376-
follows (stopping at the first substep that determines the type):</p>
30377-
30378-
<ol>
30367+
<span>the <code>embed</code> element setup steps</span> for <var>element</var>, then
30368+
return.</p></li>
3037930369

30380-
<li><p>If the element has a <code data-x="attr-embed-type">type</code> attribute, and that
30381-
attribute's value is a type that a <span>plugin</span> supports, then the value of the
30382-
<code data-x="attr-embed-type">type</code> attribute is the <span
30383-
data-x="concept-embed-type">content's type</span>.</p></li>
30370+
<li><p>Let <var>type</var> be the result of determining the <span
30371+
data-x="concept-embed-type">type of content</span> given <var>element</var> and
30372+
<var>response</var>.</p></li>
3038430373

30385-
<li>
30386-
30387-
<!-- if we get to this point we know we can successfully parsed the URL, since this algorithm is
30388-
only used after fetching the resource in the steps above -->
30389-
30390-
<p>Otherwise, if applying the <span>URL parser</span> algorithm to the <span>URL</span> of
30391-
the specified resource (after any redirects) results in a <span>URL record</span> whose
30392-
<span data-x="concept-url-path">path</span> component matches a pattern that a
30393-
<span>plugin</span> supports, then the <span data-x="concept-embed-type">content's
30394-
type</span> is the type that that plugin can handle.</p>
30395-
30396-
<p class="example">For example, a plugin might say that it can handle resources with <span
30397-
data-x="concept-url-path">path</span> components that end with the four character string
30398-
"<code data-x="">.swf</code>".</p>
30374+
<li>
30375+
<p>Switch on <var>type</var>:</p>
3039930376

30400-
<!-- it's sad that we have to do extension sniffing. sigh. -->
30401-
<!-- see also <object> which has a similar step -->
30377+
<dl class="switch">
30378+
<dt>null</dt>
30379+
<dd>
30380+
<ol>
30381+
<li><p><span>Display no plugin</span> for <var>element</var>.</p></li>
30382+
</ol>
30383+
</dd>
3040230384

30403-
</li>
30385+
<dt><code>image/svg+xml</code></dt>
30386+
<dd>
30387+
<ol>
30388+
<li>
30389+
<p>If <var>element</var>'s <span>nested browsing context</span> is null, then:</p>
3040430390

30405-
<li><p>Otherwise, if the specified resource has <span data-x="Content-Type">explicit
30406-
Content-Type metadata</span>, then that is the <span data-x="concept-embed-type">content's
30407-
type</span>.</p></li>
30391+
<ol>
30392+
<li><p>Set <var>element</var>'s <span>nested browsing context</span> to a <span
30393+
data-x="creating a new browsing context">newly-created browsing
30394+
context</span>.</p></li>
30395+
30396+
<li><p>If <var>element</var> has a <code data-x="attr-embed-name">name</code>
30397+
attribute, then set the <span>browsing context name</span> of <var>element</var>'s new
30398+
<span>nested browsing context</span> to the value of this attribute.</p></li>
30399+
<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2291 - dynamic
30400+
changes to 'name' don't do anything -->
30401+
</ol>
30402+
</li>
3040830403

30409-
<li><p>Otherwise, the content has no <span data-x="concept-embed-type">type</span> and there
30410-
can be no appropriate <span>plugin</span> for it.</p></li>
30404+
<li>
30405+
<p><span>Navigate</span> <var>element</var>'s <span>nested browsing context</span> to
30406+
<var>response</var>, with <span>replacement enabled</span>, and with
30407+
<var>element</var>'s <span>node document</span>'s <span
30408+
data-x="concept-document-bc">browsing context</span> as the <span>source browsing
30409+
context</span>.</p>
30410+
30411+
<p class="note"><var>element</var>'s <code data-x="attr-embed-src">src</code> attribute
30412+
does not get updated if the browsing context gets further navigated to other
30413+
locations.</p>
30414+
</li>
3041130415

30412-
<!-- This algorithm is a monument to bad design. Go legacy! -->
30416+
<li><p><var>embed</var> element now <span>represents</span> its <span>nested browsing
30417+
context</span>.</p></li>
3041330418

30414-
</ol>
30419+
<li><p>When the <code>Document</code> of the <span>nested browsing context</span> is
30420+
marked as <span>completely loaded</span>, <span>queue a task</span> to <span
30421+
data-x="concept-event-fire">fire an event</span> named <code
30422+
data-x="event-load">load</code> at <var>element</var>.</p></li>
30423+
</ol>
30424+
</dd>
3041530425

30426+
<dt>Otherwise</dt>
30427+
<dd>
30428+
<ol>
30429+
<li><p><span>Display a plugin</span> for <var>element</var>, given <var>type</var> and
30430+
<var>response</var>.</p></li>
30431+
</ol>
30432+
</dd>
30433+
</dl>
3041630434
</li>
30435+
</ol>
30436+
</li>
30437+
</ol>
30438+
</li>
3041730439

30418-
<li>
30440+
<li>
30441+
<p>Otherwise:</p>
3041930442

30420-
<p>If the previous step determined that the <span data-x="concept-embed-type">content's
30421-
type</span> is <code data-x="">image/svg+xml</code>, then run the following substeps:</p>
30443+
<ol>
30444+
<li><p>Let <var>type</var> be the value of <var>element</var>'s <code
30445+
data-x="attr-embed-type">type</code> attribute.</p></li>
3042230446

30423-
<ol>
30447+
<li><p>If <var>type</var> is a type that a <span>plugin</span> supports, then <span>display a
30448+
plugin</span> for <var>element</var> given <var>type</var>.</p></li>
3042430449

30425-
<li><p>If the <code>embed</code> element's <span>nested browsing context</span> is null,
30426-
set the element's <span>nested browsing context</span> to a <span data-x="creating a new
30427-
browsing context">newly-created browsing context</span>, and, if the element has a <code
30428-
data-x="attr-embed-name">name</code> attribute, set the <span>browsing context name</span>
30429-
of the element's new <span>nested browsing context</span> to the value of this
30430-
attribute.</p>
30431-
<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2291 - dynamic changes to 'name' don't do anything -->
30432-
30433-
<li><p><span>Navigate</span><!--DONAV embed--> the <span>nested browsing context</span> to
30434-
the fetched resource, with <span>replacement enabled</span>, and with the
30435-
<code>embed</code> element's <span>node document</span>'s <span
30436-
data-x="concept-document-bc">browsing context</span> as the <span>source browsing
30437-
context</span>. (The <code data-x="attr-embed-src">src</code> attribute of the
30438-
<code>embed</code> element doesn't get updated if the browsing context gets further
30439-
navigated to other locations.)</p></li>
30440-
30441-
<li><p>The <code>embed</code> element now <span>represents</span> its <span>nested browsing
30442-
context</span>.</p></li>
30450+
<li><p>Otherwise, <span>display no plugin</span> for <var>element</var>.</p></li>
30451+
</ol>
30452+
</li>
30453+
</ol>
3044330454

30444-
</ol>
30455+
<p>To determine the <dfn data-x="concept-embed-type">type of the content</dfn> given an
30456+
<code>embed</code> element <var>element</var> and a <span
30457+
data-x="concept-response">response</span> <var>response</var>, run the following steps:</p>
3044530458

30446-
</li>
30459+
<ol>
30460+
<li><p>If <var>element</var> has a <code data-x="attr-embed-type">type</code> attribute, and that
30461+
attribute's value is a type that a <span>plugin</span> supports, then return the value of the
30462+
<code data-x="attr-embed-type">type</code> attribute.</p></li>
3044730463

30448-
<li>
30464+
<li>
30465+
<p>If the <span data-x="concept-url-path">path</span> component of <var>response</var>'s
30466+
<span data-x="concept-response-url">url</span> matches a pattern that a <span>plugin</span>
30467+
supports, then return the type that that plugin can handle.</p>
3044930468

30450-
<p>Otherwise, find and instantiate an appropriate <span>plugin</span> based on the <span
30451-
data-x="concept-embed-type">content's type</span>, and hand that <span>plugin</span> the
30452-
content of the resource, replacing any previously instantiated plugin for the element. The
30453-
<code>embed</code> element now represents this <span>plugin</span> instance.</p>
30469+
<p class="example">For example, a plugin might say that it can handle URLs with <span
30470+
data-x="concept-url-path">path</span> components that end with the four character string
30471+
"<code data-x="">.swf</code>".</p>
3045430472

30455-
</li>
30473+
<!-- it's sad that we have to do extension sniffing. sigh. -->
30474+
<!-- see also <object> which has a similar step -->
30475+
</li>
3045630476

30457-
<li><p>Once the resource or plugin has completely loaded, <span>queue a task</span> to <span
30458-
data-x="concept-event-fire">fire an event</span> named <code data-x="event-load">load</code>
30459-
at the element.</p></li>
30477+
<li><p>If <var>response</var> has <span data-x="Content-Type">explicit Content-Type
30478+
metadata</span>, and that value is a type that a <span>plugin</span> supports, then return that
30479+
value.</p></li>
3046030480

30461-
</ol>
30481+
<li><p>Return null.</p></li>
30482+
</ol>
30483+
<!-- This algorithm is a monument to bad design. Go legacy! -->
3046230484

30463-
<p>Whether the resource is fetched successfully or not (e.g. whether the response status was
30464-
an <span>ok status</span>) must be ignored when determining the <span
30465-
data-x="concept-embed-type">content's type</span> and when handing the resource to the
30466-
plugin.</p>
30485+
<p class="note">It is intentional that the above algorithm allows <var>response</var> to be a
30486+
<span>network error</span> or to have a non-<span>ok status</span>. This allows servers to return
30487+
data for plugins even with error responses (e.g., HTTP 500 Internal Server Error codes can still
30488+
contain plugin data).</p>
3046730489

30468-
<p class="note">This allows servers to return data for plugins even with error responses (e.g.
30469-
HTTP 500 Internal Server Error codes can still contain plugin data).</p>
30490+
<p>To <dfn>display a plugin</dfn> for an <code>embed</code> element <var>element</var>, given a
30491+
string <var>type</var> and optionally a <span data-x="concept-response">response</span>
30492+
<var>response</var>:</p>
3047030493

30471-
<p>Fetching the resource must <span>delay the load event</span> of the element's <span>node document</span>.</p>
30472-
<!-- if we add load/error events, then replace the previous paragraph with the text one: -->
30473-
<!-- similar text in various places -->
30474-
<!--<p>Fetching the resource must <span>delay the load event</span> of the element's <span>node document</span>
30475-
until the final <span data-x="concept-task">task</span> that is <span data-x="queue a
30476-
task">queued</span> by the <span>networking task source</span> once the resource has been
30477-
<span data-x="fetch">fetched</span> has been run.</p>-->
30494+
<ol>
30495+
<li>
30496+
<p>If <var>element</var>'s <span>nested browsing context</span> is not null, then:</p>
3047830497

30479-
</dd>
30498+
<ol>
30499+
<li><p><span data-x="a browsing context is discarded">Discard</span> <var>element</var>'s
30500+
<span>nested browsing context</span>.</p></li>
3048030501

30481-
<dt>If the element has no <code data-x="attr-embed-src">src</code> attribute set</dt>
30502+
<li><p>Set <var>element</var>'s <span>nested browsing context</span> to null.</p></li>
30503+
</ol>
30504+
</li>
3048230505

30483-
<dd>
30506+
<li><p>Find and instantiate an appropriate <span>plugin</span> based on <var>type</var>,
30507+
replacing any previously-instantiated plugin for <var>element</var>. If <var>response</var> was
30508+
given, forward it to the plugin.</p></li>
3048430509

30485-
<p>The user agent should find and instantiate an appropriate <span>plugin</span> based on the
30486-
value of the <code data-x="attr-embed-type">type</code> attribute. The <code>embed</code>
30487-
element now represents this <span>plugin</span> instance.</p>
30510+
<li><p><var>element</var> now <span>represents</span> this <span>plugin</span> instance.</p></li>
3048830511

30489-
<p>Once the plugin is completely loaded, <span>queue a task</span> to <span
30490-
data-x="concept-event-fire">fire an event</span> named <code data-x="event-load">load</code>
30491-
at the element.</p>
30512+
<li><p>Once the plugin, and <var>response</var> if given, are completely loaded, <span>queue a
30513+
task</span> to <span data-x="concept-event-fire">fire an event</span> named <code
30514+
data-x="event-load">load</code> at <var>element</var>.</p></li>
30515+
</ol>
3049230516

30493-
</dd>
30517+
<p>To <dfn>display no plugin</dfn> for an <code>embed</code> element <var>element</var>:</p>
3049430518

30495-
</dl>
30519+
<ol>
30520+
<li>
30521+
<p>If <var>element</var>'s <span>nested browsing context</span> is not null, then:</p>
30522+
30523+
<ol>
30524+
<li><p><span data-x="a browsing context is discarded">Discard</span> <var>element</var>'s
30525+
<span>nested browsing context</span>.</p></li>
3049630526

30527+
<li><p>Set <var>element</var>'s <span>nested browsing context</span> to null.</p></li>
30528+
</ol>
3049730529
</li>
3049830530

30531+
<li><p>Display an indication that no <span>plugin</span> could be found for <var>element</var>,
30532+
replacing any previously-instantiated plugin for <var>element</var>.</p></li>
30533+
30534+
<li><p><var>element</var> now <span>represents</span> nothing.</p></li>
3049930535
</ol>
3050030536

30501-
<p>The <code>embed</code> element has no <span>fallback content</span>. If the user agent can't
30502-
find a suitable plugin when attempting to find and instantiate one for the algorithm above, then
30503-
the user agent must use a default plugin. This default could be as simple as saying "Unsupported
30504-
Format".</p>
30537+
<p class="note">The <code>embed</code> element has no <span>fallback content</span>; its
30538+
descendants are ignored.</p>
3050530539

3050630540
<p>Whenever an <code>embed</code> element that was <span data-x="concept-embed-active">potentially
3050730541
active</span> stops being <span data-x="concept-embed-active">potentially active</span>, any

0 commit comments

Comments
 (0)