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

Add the interesttarget attribute #11006

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 188 additions & 3 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -21762,6 +21762,7 @@ interface <dfn interface>HTMLDivElement</dfn> : <span>HTMLElement</span> {
<dd><code data-x="attr-hyperlink-hreflang">hreflang</code></dd>
<dd><code data-x="attr-hyperlink-type">type</code></dd>
<dd><code data-x="attr-hyperlink-referrerpolicy">referrerpolicy</code></dd>
<dd><code data-x="attr-interesttarget">interesttarget</code></dd>
<dt><span
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt>
<dd>If the element has an <code data-x="attr-hyperlink-href">href</code> attribute: <a
Expand Down Expand Up @@ -21790,7 +21791,8 @@ interface <dfn interface>HTMLAnchorElement</dfn> : <span>HTMLElement</span> {

// <a href="#HTMLAnchorElement-partial">also has obsolete members</a>
};
<span>HTMLAnchorElement</span> includes <span>HTMLHyperlinkElementUtils</span>;</code></pre>
<span>HTMLAnchorElement</span> includes <span>HTMLHyperlinkElementUtils</span>;
<span>HTMLAnchorElement</span> includes <span>InterestInvokerElement</span>;</code></pre>
</dd>
<dd w-dev>Uses <code>HTMLAnchorElement</code>.</dd>
</dl>
Expand Down Expand Up @@ -41997,6 +41999,7 @@ interface <dfn interface>HTMLMapElement</dfn> : <span>HTMLElement</span> {
<dd><code data-x="attr-hyperlink-ping">ping</code></dd>
<dd><code data-x="attr-hyperlink-rel">rel</code></dd>
<dd><code data-x="attr-hyperlink-referrerpolicy">referrerpolicy</code></dd>
<dd><code data-x="attr-interesttarget">interesttarget</code></dd>
<dt><span
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt>
<dd>If the element has an <code data-x="attr-hyperlink-href">href</code> attribute: <a
Expand All @@ -42023,7 +42026,8 @@ interface <dfn interface>HTMLAreaElement</dfn> : <span>HTMLElement</span> {

// <a href="#HTMLAreaElement-partial">also has obsolete members</a>
};
<span>HTMLAreaElement</span> includes <span>HTMLHyperlinkElementUtils</span>;</code></pre>
<span>HTMLAreaElement</span> includes <span>HTMLHyperlinkElementUtils</span>;
<span>HTMLAreaElement</span> includes <span>InterestInvokerElement</span>;</code></pre>
</dd>
<dd w-dev>Uses <code>HTMLAreaElement</code>.</dd>
</dl>
Expand Down Expand Up @@ -53429,6 +53433,7 @@ You cannot submit this form when the field is incorrect.</samp></pre>
<dd><code data-x="attr-fe-name">name</code></dd>
<dd><code data-x="attr-popovertarget">popovertarget</code></dd>
<dd><code data-x="attr-popovertargetaction">popovertargetaction</code></dd>
<dd><code data-x="attr-interesttarget">interesttarget</code></dd>
<dd><code data-x="attr-button-type">type</code></dd>
<dd><code data-x="attr-button-value">value</code></dd>
<dt><span
Expand Down Expand Up @@ -53461,7 +53466,8 @@ interface <dfn interface>HTMLButtonElement</dfn> : <span>HTMLElement</span> {

readonly attribute <span>NodeList</span> <span data-x="dom-lfe-labels">labels</span>;
};
<span>HTMLButtonElement</span> includes <span>PopoverInvokerElement</span>;</code></pre>
<span>HTMLButtonElement</span> includes <span>PopoverInvokerElement</span>;
<span>HTMLButtonElement</span> includes <span>InterestInvokerElement</span>;</code></pre>
</dd>
<dd w-dev>Uses <code>HTMLButtonElement</code>.</dd>
</dl>
Expand Down Expand Up @@ -74941,6 +74947,13 @@ contradict people?
data-x="concept-selector-active">being activated</i>.)</p>
</dd>

<dt><dfn selector noexport><code data-x="selector-has-interest">:has-interest</code></dfn></dt>
<dd>
<p>The <code data-x="selector-has-interest">:has-interest</code> <span>pseudo-class</span> is
defined to match any <span data-x="html elements">HTML element</span> whose <span>has
interest</span> is true.</p>
</dd>

<dt><dfn selector noexport><code data-x="selector-hover">:hover</code></dfn></dt>
<dd>
<p>The <code data-x="selector-hover">:hover</code> <span>pseudo-class</span> is defined to
Expand Down Expand Up @@ -87118,6 +87131,159 @@ dictionary <dfn dictionary>DragEventInit</dfn> : <span>MouseEventInit</span> {
</ol>


<h3 split-filename="interesttarget">Interest invokers</h3>

<h4>The <code data-x="attr-interesttarget">interesttarget</code> attribute</h4>

<p>The <dfn element-attr for="html-global"><code data-x="attr-interesttarget">interesttarget</code></dfn> attribute on <code>a</code>, <code>area</code>, and <code>button</code> elements TODO.</p>

<p>If specified, the <code data-x="attr-interesttarget">interesttarget</code> attribute value
must be the <span data-x="concept-ID">ID</span> of an element in the same <span>tree</span> as the
element with the <code data-x="attr-interesttarget">interesttarget</code> attribute.</p>

<span data-x="concept-element-dom">DOM interface</span>:
<pre><code class="idl">interface mixin <dfn interface>InterestInvokerElement</dfn> {
[<span>CEReactions</span>] attribute Element? <span data-x="dom-interestTargetElement">interestTargetElement</span>;
};</code></pre>

<p>The <dfn attribute for="HTMLElement"><code
data-x="dom-interestTargetElement">interestTargetElement</code></dfn> IDL attribute must
<span>reflect</span> the <code data-x="attr-interesttarget">interesttarget</code> attribute.</p>

<div class="example">
<p>The following demonstrates how one might show a tooltip for a button using the
<code data-x="attr-interesttarget">interesttarget</code> attribute to associate the button with
a <code>div</code> <code data-x="attr-popover">popover</code> representing the tooltip.</p>

<pre><code class="html">&lt;button interesttarget=tooltip>
Click me
&lt;/button>

&lt;div popover=hint id=tooltip>
I will appear
&lt;/div></code></pre>
</div>

<p>Every <span data-x="HTML elements">HTML element</span> has a <dfn>has interest</dfn>, which is a
boolean, initially set to false.</p>
<!-- TODO: or have an Element slot on Document for this since there can only be one at a time? -->

<h4>The <code>InterestEvent</code> interface</h4>

<pre><code class="idl">[Exposed=Window]
interface <dfn interface>InterestEvent</dfn> : <span>Event</span> {
constructor(DOMString type, optional <span>InterestEventInit</span> eventInitDict = {});
readonly attribute Element? source; // TODO: nullable, or require in ctor?
};

dictionary <dfn dictionary>InterestEventInit</dfn> : <span>EventInit</span> {
Element? source = null;
};</code></pre>

<dl class="domintro">
<dt><code data-x=""><var>event</var>.<span subdfn
data-x="dom-InterestEvent-source">source</span></code></dt>

<dd>
<p>Set to an interesting element TODO.</p>
</dd>
</dl>

<p>The <dfn attribute for="InterestEvent"><code
data-x="dom-InterestEvent-source">source</code></dfn> attribute must return the value it was
initialized to.</p>

<h4 id="interest-target-processing-model">Processing model</h4>

<p>To <dfn export data-x="capture-interest">capture interest</dfn>, given an <span
data-x="HTML elements">HTML element</span> <var>invoker</var>:</p>

<ol>
<li><p>Assert: <var>invoker</var> is an <code>a</code>, <code>area</code>, or <code>button</code>
element.</p></li>

<li><p>Assert: <var>invoker</var> has the <code data-x="attr-interesttarget">interesttarget</code>
attribute specified.</p></li>

<li><p>Let <var>target</var> be the result of running <var>node</var>'s <span data-x="get
the attr-associated element">get the <code data-x="">interesttarget</code>-associated
element</span>.</p></li>

<li><p>If <var>target</var> is null, then return.</p></li>

<li><p>Let <var>continue</var> be the result of <span data-x="concept-event-fire">firing an
event</span> named <code data-x="event-interest">interest</code> at <var>target</var>, using
<code>InterestEvent</code>, with the <code data-x="dom-Event-cancelable">cancelable</code> and
<code data-x="dom-Event-composed">composed</code> attributes initialized to true, and the
<code data-x="dom-InterestEvent-source">source</code> attribute initialized to
<var>invoker</var>.</p></li>
<!-- TODO: the explainer calls for composed without bubbling, does that make sense? -->

<li><p>If <var>continue</var> is false, then return.</p></li>

<li><p>Set <var>invoker</var>'s <span>has interest</span> to true.</p></li>

<!-- TODO: test that :has-interest doesn't match when the interest event is fired, but does
match when the popover toggle event fired. -->

<li><p>If <var>target</var>'s <code data-x="attr-popover">popover</code> attribute is not in the
<span data-x="attr-popover-none-state">no popover state</span>, then run <span>show popover</span>
given <var>target</var>, false, and <var>invoker</var>.</p></li>
<!-- TODO: should invoker be passed? It's used for popovertarget, might not do the right thing
if passed in here... -->

<!-- TODO: nothing to do if not a popover? how can devs show/hide it? needs another pseudo-class? -->
</ol>

<p>To <dfn export data-x="lose-interest">lose interest</dfn>, given an <span
data-x="HTML elements">HTML element</span> <var>invoker</var>:</p>

<ol>
<li><p>Assert: <var>invoker</var> is an <code>a</code>, <code>area</code>, or <code>button</code>
element.</p></li>

<li><p>Note: <var>invoker</var> may no longer have the <code
data-x="attr-interesttarget">interesttarget</code> attribute specified.</p></li>

<li><p>Let <var>target</var> be the result of running <var>node</var>'s <span data-x="get
the attr-associated element">get the <code data-x="">interesttarget</code>-associated
element</span>.</p></li>

<li><p>If <var>target</var> is null, then return.</p></li>

<!-- TODO: what state is possibly left dangling if the target wasn't found? -->

<li><p>Let <var>continue</var> be the result of <span data-x="concept-event-fire">firing an
event</span> named <code data-x="event-interest">loseinterest</code> at <var>target</var>, using
<code>InterestEvent</code>, with the <code data-x="dom-Event-cancelable">cancelable</code> and
<code data-x="dom-Event-composed">composed</code> attributes initialized to true, and the
<code data-x="dom-InterestEvent-source">source</code> attribute initialized to
<var>invoker</var>.</p></li>
<!-- TODO: the explainer calls for composed without bubbling, does that make sense? -->

<li><p>If <var>continue</var> is false, then return.</p></li>
<!-- TODO: what's the point of being able to cancel this event? -->

<li><p>If <var>target</var>'s <code data-x="attr-popover">popover</code> attribute is not in the
<span data-x="attr-popover-none-state">no popover state</span>, then <span
data-x="hide popover algorithm">hide popover</span> given <var>invoker</var>, false, true, and
false.</p></li>

<li><p>Set <var>invoker</var>'s <span>has interest</span> to false.</p></li>
<!-- TODO: is this the right time to change the state? too late? -->
</ol>

<p>TODO / questions:</p>

<ul>
<li><p>Actually invoke the capture/lose algorithms.</p></li>
<li><p>Which algorithm reads the computed style for interest-target-delay?</p></li>
<li><p>Handle removal of the interesttarget attribute, or the element that has it.</p></li>
<li><p>Handle changes of the interesttarget attribute while an element has interest.</p></li>
<li><p>Handle changes to the ID attribute referenced by an interesttarget attribute.</p></li>
</ul>


<h2 split-filename="browsers" id="browsers">Loading web pages</h2>

<div w-nodev>
Expand Down Expand Up @@ -143277,6 +143443,13 @@ interface <dfn interface>External</dfn> {
<code data-x="attr-script-integrity">script</code>
<td> Integrity metadata used in <cite>Subresource Integrity</cite> checks <ref>SRI</ref>
<td> <a href="#attribute-text">Text</a>
<tr>
<th> <code data-x="">interesttarget</code>
<td> <code data-x="attr-interesttarget">a</code>;
<code data-x="attr-interesttarget">area</code>;
<code data-x="attr-interesttarget">button</code>
<td> Targets an interesting TODO
<td> <span data-x="concept-id">ID</span>* <!-- TODO: is the asterisk needed, is it really complicated? -->
<tr>
<th> <code data-x="">is</code>
<td> <span data-x="attr-is">HTML elements</span>
Expand Down Expand Up @@ -145061,6 +145234,12 @@ INSERT INTERFACES HERE
<td> Elements
<td> Fired when the user changes the <code data-x="attr-contenteditable">contenteditable</code> element's content, or the form control's value. See also the <code data-x="event-change">change</code> event for form controls.

<tr> <!-- interest -->
<td> <dfn event for="HTMLElement"><code data-x="event-interest">interest</code></dfn>
<td> <code>InterestEvent</code>
<td> Elements
<td> Fired on interesting elements because of code <code data-x="attr-interesttarget">interesttarget</code> TODO.

<tr> <!-- invalid -->
<td> <dfn event for="HTMLElement"><code data-x="event-invalid">invalid</code></dfn>
<td> <code>Event</code>
Expand All @@ -145079,6 +145258,12 @@ INSERT INTERFACES HERE
<td> <code>Window</code>, elements
<td> Fired at the <code>Window</code> when the document has finished loading; fired at an element containing a resource (e.g. <code>img</code>, <code>embed</code>) when its resource has finished loading

<tr> <!-- loseinterest -->
<td> <dfn event for="HTMLElement"><code data-x="event-loseinterest">loseinterest</code></dfn>
<td> <code>InterestEvent</code>
<td> Elements
<td> Fired on boring elements because of code <code data-x="attr-interesttarget">interesttarget</code> TODO.

<tr> <!-- message -->
<td> <dfn event for="Window,EventSource,MessagePort,BroadcastChannel,DedicatedWorkerGlobalScope,Worker,ServiceWorkerContainer"><code data-x="event-message">message</code></dfn>
<td> <code>MessageEvent</code>
Expand Down