Skip to content

Commit

Permalink
Shadow: define event's relatedTarget handling
Browse files Browse the repository at this point in the history
This defines the retargeting algorithm for shadow trees and more importantly event's relatedTarget handling. We avoid creating a direct dependency on UI Events by just making relatedTarget a slot for all events.

Fixes #276 and fixes #277.
  • Loading branch information
hayatoito authored and annevk committed Jul 22, 2016
1 parent 674e934 commit ef69a24
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 16 deletions.
51 changes: 42 additions & 9 deletions dom.bs
Original file line number Diff line number Diff line change
Expand Up @@ -639,10 +639,17 @@ dictionary EventInit {
<p>An {{Event}} object is simply named an <dfn export id=concept-event>event</dfn>. It allows for
signaling that something has occurred, e.g., that an image has completed downloading.</p>

<p>An <a>event</a> has an associated <dfn export for=Event>relatedTarget</dfn> (null or an
{{EventTarget}} object). Unless stated otherwise it is null.</p>

<p class="note">Other specifications use <a>relatedTarget</a> to define a <code>relatedTarget</code>
attribute. [[UIEVENTS]]

<p>An <a>event</a> has an associated <dfn export for=Event>path</dfn>. A <a for=Event>path</a> is a
list of tuples, each of which consists of an <b>item</b> (an {{EventTarget}} object) and a
<b>target</b> (null or an {{EventTarget}} object). A tuple is formatted as (<b>item</b>,
<b>target</b>). A <a for=Event>path</a> is initially the empty list.</p>
list of tuples, each of which consists of an <b>item</b> (an {{EventTarget}} object), <b>target</b>
(null or an {{EventTarget}} object), and a <b>relatedTarget</b> (null or an {{EventTarget}}
object). A tuple is formatted as (<b>item</b>, <b>target</b>, <b>relatedTarget</b>). A <a
for=Event>path</a> is initially the empty list.</p>

<dl class=domintro>
<dt><code><var>event</var> = new <a constructor lt="Event()">Event</a>(<var>type</var> [, <var>eventInitDict</var>])</code>
Expand Down Expand Up @@ -1185,7 +1192,11 @@ for discussion).
<!-- We should consider refactoring it to make it have less of a scope, since we don't really want
folks to start using it for non-legacy scenarios. -->

<li><p>Append (<var>target</var>, <var>targetOverride</var>) to <var>event</var>'s
<li>Let <var>relatedTarget</var> be the result of invoking <a>retargeting</a> <var>event</var>'s
<a>relatedTarget</a> against <var>target</var> if <var>event</var>'s <a>relatedTarget</a> is
non-null, and null otherwise.

<li><p>Append (<var>target</var>, <var>targetOverride</var>, <var>relatedTarget</var>) to <var>event</var>'s
<a for=Event>path</a>.

<li><p>Let <var>parent</var> be the result of invoking <var>target</var>'s <a>get the parent</a>
Expand All @@ -1195,15 +1206,22 @@ for discussion).
<p>While <var>parent</var> is non-null:</p>

<ol>
<li><p>Let <var>relatedTarget</var> be the result of invoking <a>retargeting</a>
<var>event</var>'s <a>relatedTarget</a> against <var>parent</var> if <var>event</var>'s
<a>relatedTarget</a> is non-null, and null otherwise.

<li><p>If <var>target</var>'s <a for=tree>root</a> is a
<a>shadow-including inclusive ancestor</a> of <var>parent</var>, then append
(<var>parent</var>, null) to <var>event</var>'s <a for=Event>path</a>.
(<var>parent</var>, null, <var>relatedTarget</var>) to <var>event</var>'s <a for=Event>path</a>.

<li><p>Otherwise, if <var>parent</var> and <var>relatedTarget</var> are identical, then set
<var>parent</var> to null.

<li><p>Otherwise, set <var>target</var> to <var>parent</var> and append
(<var>parent</var>, <var>target</var>) to <var>event</var>'s <a for=Event>path</a>.
<li><p>Otherwise, set <var>target</var> to <var>parent</var> and append (<var>parent</var>,
<var>target</var>, <var>relatedTarget</var>) to <var>event</var>'s <a for=Event>path</a>.

<li><p>Set <var>parent</var> to the result of invoking <var>parent</var>'s <a>get the parent</a>
with <var>event</var>.
<li><p>If <var>parent</var> is non-null, then set <var>parent</var> to the result of invoking
<var>parent</var>'s <a>get the parent</a> with <var>event</var>.
</ol>

<li><p>Set <var>event</var>'s {{Event/eventPhase}} attribute to {{Event/CAPTURING_PHASE}}.
Expand All @@ -1216,6 +1234,8 @@ for discussion).
in <var>event</var>'s <a for=Event>path</a>, that is either <var>tuple</var> or preceding
<var>tuple</var>, whose <b>target</b> is non-null.

<li><p>Set <var>event</var>'s <a>relatedTarget</a> to <var>tuple</var>'s <b>relatedTarget</b>.

<li><p>If <var>tuple</var>'s <b>target</b> is null, then <a>invoke</a> <var>tuple</var>'s
<b>item</b> with <var>event</var>.
</ol>
Expand All @@ -1228,6 +1248,8 @@ for discussion).
in <var>event</var>'s <a for=Event>path</a>, that is either <var>tuple</var> or preceding
<var>tuple</var>, whose <b>target</b> is non-null.

<li><p>Set <var>event</var>'s <a>relatedTarget</a> to <var>tuple</var>'s <b>relatedTarget</b>.

<li><p>If <var>tuple</var>'s <b>target</b> is non-null, then set <var>event</var>'s
{{Event/eventPhase}} attribute to {{Event/AT_TARGET}}.

Expand Down Expand Up @@ -5515,6 +5537,17 @@ or <var>A</var>'s <a for=tree>root</a> is a <a for=/>shadow root</a> whose
<a for=ShadowRoot>mode</a> is "<code>open</code>" and <a for=DocumentFragment>host</a> is an
<a>unclosed node</a> of <var>B</var>.

<p>To <dfn export lt="retarget|retargeting">retarget</dfn> an object <var>A</var> against an object
<var>B</var>, repeat these steps until they return an object:</p>

<ol>
<li><p>If <var>A</var>'s <a for=tree>root</a> is not a <a for=/>shadow root</a>, or <var>A</var>'s
<a for=tree>root</a> is a <a>shadow-including inclusive ancestor</a> of <var>B</var>, then return
<var>A</var>.

<li><p>Set <var>A</var> to <var>A</var>'s <a for=tree>root</a>'s <a for=DocumentFragment>host</a>.
</ol>

<hr>

<p class="XXX">For now you can find more information about this object in
Expand Down
35 changes: 28 additions & 7 deletions dom.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<p data-fill-with="logo"><a class="logo" href="https://whatwg.org/"> <img alt="WHATWG" height="100" src="https://resources.whatwg.org/logo-dom.svg"> </a> </p>
<hgroup>
<h1 class="p-name no-ref allcaps" id="title">DOM</h1>
<h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Living Standard — Last Updated <time class="dt-updated" datetime="2016-07-21">21 July 2016</time></span></h2>
<h2 class="no-num no-toc no-ref heading settled" id="subtitle"><span class="content">Living Standard — Last Updated <time class="dt-updated" datetime="2016-07-22">22 July 2016</time></span></h2>
</hgroup>
<div data-fill-with="spec-metadata">
<dl>
Expand Down Expand Up @@ -521,8 +521,10 @@ <h3 class="heading settled" data-level="3.2" id="interface-event"><span class="s
</pre>
<p>An <code class="idl"><a data-link-type="idl" href="#event">Event</a></code> object is simply named an <dfn data-dfn-type="dfn" data-export="" id="concept-event">event<a class="self-link" href="#concept-event"></a></dfn>. It allows for
signaling that something has occurred, e.g., that an image has completed downloading.</p>
<p>An <a data-link-type="dfn" href="#concept-event">event</a> has an associated <dfn data-dfn-for="Event" data-dfn-type="dfn" data-export="" id="event-relatedtarget">relatedTarget<a class="self-link" href="#event-relatedtarget"></a></dfn> (null or an <code class="idl"><a data-link-type="idl" href="#eventtarget">EventTarget</a></code> object). Unless stated otherwise it is null.</p>
<p class="note" role="note">Other specifications use <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> to define a <code>relatedTarget</code> attribute. <a data-link-type="biblio" href="#biblio-uievents">[UIEVENTS]</a> </p>
<p>An <a data-link-type="dfn" href="#concept-event">event</a> has an associated <dfn data-dfn-for="Event" data-dfn-type="dfn" data-export="" id="event-path">path<a class="self-link" href="#event-path"></a></dfn>. A <a data-link-type="dfn" href="#event-path">path</a> is a
list of tuples, each of which consists of an <b>item</b> (an <code class="idl"><a data-link-type="idl" href="#eventtarget">EventTarget</a></code> object) and a <b>target</b> (null or an <code class="idl"><a data-link-type="idl" href="#eventtarget">EventTarget</a></code> object). A tuple is formatted as (<b>item</b>, <b>target</b>). A <a data-link-type="dfn" href="#event-path">path</a> is initially the empty list.</p>
list of tuples, each of which consists of an <b>item</b> (an <code class="idl"><a data-link-type="idl" href="#eventtarget">EventTarget</a></code> object), <b>target</b> (null or an <code class="idl"><a data-link-type="idl" href="#eventtarget">EventTarget</a></code> object), and a <b>relatedTarget</b> (null or an <code class="idl"><a data-link-type="idl" href="#eventtarget">EventTarget</a></code> object). A tuple is formatted as (<b>item</b>, <b>target</b>, <b>relatedTarget</b>). A <a data-link-type="dfn" href="#event-path">path</a> is initially the empty list.</p>
<dl class="domintro">
<dt><code><var>event</var> = new <a class="idl-code" data-link-type="constructor" href="#dom-event-event">Event</a>(<var>type</var> [, <var>eventInitDict</var>])</code>
<dd>Returns a new <var>event</var> whose <code class="idl"><a data-link-type="idl" href="#dom-event-type">type</a></code> attribute value is set to <var>type</var>. The optional <var>eventInitDict</var> argument
Expand Down Expand Up @@ -870,21 +872,26 @@ <h3 class="heading settled" data-level="3.8" id="dispatching-events"><span class
<p>If <var>targetOverride</var> is not given, let <var>targetOverride</var> be <var>target</var>. </p>
<p class="note" role="note">The <var>targetOverride</var> argument is only used by HTML and only under very
specific circumstances. </p>
<li>Let <var>relatedTarget</var> be the result of invoking <a data-link-type="dfn" href="#retarget">retargeting</a> <var>event</var>’s <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> against <var>target</var> if <var>event</var>’s <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> is
non-null, and null otherwise.
<li>
<p>Append (<var>target</var>, <var>targetOverride</var>) to <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>. </p>
<p>Append (<var>target</var>, <var>targetOverride</var>, <var>relatedTarget</var>) to <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>. </p>
<li>
<p>Let <var>parent</var> be the result of invoking <var>target</var>’s <a data-link-type="dfn" href="#get-the-parent">get the parent</a> with <var>event</var>. </p>
<li>
<p>While <var>parent</var> is non-null:</p>
<ol>
<li>
<p>Let <var>relatedTarget</var> be the result of invoking <a data-link-type="dfn" href="#retarget">retargeting</a> <var>event</var>’s <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> against <var>parent</var> if <var>event</var>’s <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> is non-null, and null otherwise. </p>
<li>
<p>If <var>target</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a> is a <a data-link-type="dfn" href="#concept-shadow-including-inclusive-ancestor">shadow-including inclusive ancestor</a> of <var>parent</var>, then append
(<var>parent</var>, null) to <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>. </p>
(<var>parent</var>, null, <var>relatedTarget</var>) to <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>. </p>
<li>
<p>Otherwise, if <var>parent</var> and <var>relatedTarget</var> are identical, then set <var>parent</var> to null. </p>
<li>
<p>Otherwise, set <var>target</var> to <var>parent</var> and append
(<var>parent</var>, <var>target</var>) to <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>. </p>
<p>Otherwise, set <var>target</var> to <var>parent</var> and append (<var>parent</var>, <var>target</var>, <var>relatedTarget</var>) to <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>. </p>
<li>
<p>Set <var>parent</var> to the result of invoking <var>parent</var>’s <a data-link-type="dfn" href="#get-the-parent">get the parent</a> with <var>event</var>. </p>
<p>If <var>parent</var> is non-null, then set <var>parent</var> to the result of invoking <var>parent</var>’s <a data-link-type="dfn" href="#get-the-parent">get the parent</a> with <var>event</var>. </p>
</ol>
<li>
<p>Set <var>event</var>’s <code class="idl"><a data-link-type="idl" href="#dom-event-eventphase">eventPhase</a></code> attribute to <code class="idl"><a data-link-type="idl" href="#dom-event-capturing_phase">CAPTURING_PHASE</a></code>. </p>
Expand All @@ -894,6 +901,8 @@ <h3 class="heading settled" data-level="3.8" id="dispatching-events"><span class
<li>
<p>Set <var>event</var>’s <code class="idl"><a data-link-type="idl" href="#dom-event-target">target</a></code> attribute to the <b>target</b> of the last tuple
in <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>, that is either <var>tuple</var> or preceding <var>tuple</var>, whose <b>target</b> is non-null. </p>
<li>
<p>Set <var>event</var>’s <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> to <var>tuple</var>’s <b>relatedTarget</b>. </p>
<li>
<p>If <var>tuple</var>’s <b>target</b> is null, then <a data-link-type="dfn" href="#concept-event-listener-invoke">invoke</a> <var>tuple</var>’s <b>item</b> with <var>event</var>. </p>
</ol>
Expand All @@ -903,6 +912,8 @@ <h3 class="heading settled" data-level="3.8" id="dispatching-events"><span class
<li>
<p>Set <var>event</var>’s <code class="idl"><a data-link-type="idl" href="#dom-event-target">target</a></code> attribute to the <b>target</b> of the last tuple
in <var>event</var>’s <a data-link-type="dfn" href="#event-path">path</a>, that is either <var>tuple</var> or preceding <var>tuple</var>, whose <b>target</b> is non-null. </p>
<li>
<p>Set <var>event</var>’s <a data-link-type="dfn" href="#event-relatedtarget">relatedTarget</a> to <var>tuple</var>’s <b>relatedTarget</b>. </p>
<li>
<p>If <var>tuple</var>’s <b>target</b> is non-null, then set <var>event</var>’s <code class="idl"><a data-link-type="idl" href="#dom-event-eventphase">eventPhase</a></code> attribute to <code class="idl"><a data-link-type="idl" href="#dom-event-at_target">AT_TARGET</a></code>. </p>
<li>
Expand Down Expand Up @@ -3267,6 +3278,13 @@ <h3 class="heading settled" data-level="4.8" id="interface-shadowroot"><span cla
<p>A <dfn data-dfn-type="dfn" data-export="" id="concept-shadow-including-inclusive-ancestor">shadow-including inclusive ancestor<a class="self-link" href="#concept-shadow-including-inclusive-ancestor"></a></dfn> is an object or one of its <a data-link-type="dfn" href="#concept-shadow-including-ancestor">shadow-including ancestors</a>. </p>
<p>A <a data-link-type="dfn" href="#concept-node">node</a> <var>A</var> is an <dfn data-dfn-type="dfn" data-export="" id="concept-unclosed-node">unclosed node<a class="self-link" href="#concept-unclosed-node"></a></dfn> of a <a data-link-type="dfn" href="#concept-node">node</a> <var>B</var>, if <var>A</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a> is not a <a data-link-type="dfn" href="#concept-shadow-root">shadow root</a>, <var>A</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a> is a <a data-link-type="dfn" href="#concept-shadow-including-inclusive-ancestor">shadow-including inclusive ancestor</a> of <var>B</var>,
or <var>A</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a> is a <a data-link-type="dfn" href="#concept-shadow-root">shadow root</a> whose <a data-link-type="dfn" href="#shadowroot-mode">mode</a> is "<code>open</code>" and <a data-link-type="dfn" href="#concept-documentfragment-host">host</a> is an <a data-link-type="dfn" href="#concept-unclosed-node">unclosed node</a> of <var>B</var>. </p>
<p>To <dfn data-dfn-type="dfn" data-export="" data-lt="retarget|retargeting" id="retarget">retarget<a class="self-link" href="#retarget"></a></dfn> an object <var>A</var> against an object <var>B</var>, repeat these steps until they return an object:</p>
<ol>
<li>
<p>If <var>A</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a> is not a <a data-link-type="dfn" href="#concept-shadow-root">shadow root</a>, or <var>A</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a> is a <a data-link-type="dfn" href="#concept-shadow-including-inclusive-ancestor">shadow-including inclusive ancestor</a> of <var>B</var>, then return <var>A</var>. </p>
<li>
<p>Set <var>A</var> to <var>A</var>’s <a data-link-type="dfn" href="#concept-tree-root">root</a>’s <a data-link-type="dfn" href="#concept-documentfragment-host">host</a>. </p>
</ol>
<hr>
<p class="XXX">For now you can find more information about this object in <a href="https://w3c.github.io/webcomponents/spec/shadow/">Shadow DOM</a>. The DOM Standard will be
updated over time to cover more details. </p>
Expand Down Expand Up @@ -6062,6 +6080,7 @@ <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="c
<li><a href="#dom-nodeiterator-referencenode">referenceNode</a><span>, in §6.1</span>
<li><a href="#concept-reflect">reflect</a><span>, in §4.9</span>
<li><a href="#registered-observer">registered observer</a><span>, in §4.3</span>
<li><a href="#event-relatedtarget">relatedTarget</a><span>, in §3.2</span>
<li>
remove()
<ul>
Expand Down Expand Up @@ -6095,6 +6114,8 @@ <h3 class="no-num no-ref heading settled" id="index-defined-here"><span class="c
<li><a href="#dom-childnode-replacewith">replaceWith(nodes...)</a><span>, in §4.2.8</span>
<li><a href="#dom-childnode-replacewith">replaceWith(nodes)</a><span>, in §4.2.8</span>
<li><a href="#represented-by-the-collection">represented by the collection</a><span>, in §4.2.10</span>
<li><a href="#retarget">retarget</a><span>, in §4.8</span>
<li><a href="#retarget">retargeting</a><span>, in §4.8</span>
<li>
root
<ul>
Expand Down

0 comments on commit ef69a24

Please sign in to comment.