Skip to content

Commit

Permalink
Merge pull request #411 from szager-chromium/document-root
Browse files Browse the repository at this point in the history
Allow the 'root' argument to be a Document.
  • Loading branch information
szager-chromium authored Jan 28, 2020
2 parents d3eece4 + 6515fa7 commit e626248
Showing 1 changed file with 36 additions and 29 deletions.
65 changes: 36 additions & 29 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ urlPrefix: https://heycam.github.io/webidl/
urlPrefix: #idl-; type:interface; text: double
url: #hierarchyrequesterror; type: exception; text: HierarchyRequestError
urlPrefix: https://drafts.csswg.org/css-box/
url: #viewport; type: dfn; text: viewport
url: #containing-block; type: dfn; text: containing block
url: #content-area; type: dfn; text: content area
urlPrefix: https://drafts.csswg.org/css-display/
Expand All @@ -59,6 +58,8 @@ urlPrefix: http://www.w3.org/TR/css-masking-1/
url: #propdef-clip-path; type:dfn; text: clip-path
urlPrefix: https://drafts.csswg.org/cssom-view-1/
url: #pinch-zoom; type:dfn; text: pinch zoom
urlPrefix: https://drafts.csswg.org/css2/visuren.html
url: #viewport; type:dfn; text: viewport
</pre>

<pre class="link-defaults">
Expand Down Expand Up @@ -97,7 +98,7 @@ These use-cases have several common properties:
1. They can be represented as passive "queries"
about the state of individual elements
with respect to some other element
(or the global viewport).
(or the global <a>viewport</a>).
2. They do not impose hard latency requirements;
that is to say, the information can be delivered asynchronously
(e.g. from another thread)
Expand All @@ -114,7 +115,7 @@ and without perfect compositing-result data.

The Intersection Observer API addresses the above issues
by giving developers a new method to asynchronously query the position of an element
with respect to other elements or the global viewport.
with respect to other elements or the global <a>viewport</a>.
The asynchronous delivery eliminates the need for costly DOM and style queries,
continuous polling,
and use of custom plugins.
Expand Down Expand Up @@ -168,11 +169,11 @@ The IntersectionObserver interface</h3>
The {{IntersectionObserver}} interface can be used to observe changes in the
intersection of an <a>intersection root</a> and one or more <a>target</a> {{Element}}s.

An {{IntersectionObserver}} with a {{IntersectionObserver/root}} {{Element}} can
An {{IntersectionObserver}} with a {{IntersectionObserver/root}} {{Node}} can
observe any <a>target</a> {{Element}} that is a descendant of the
{{IntersectionObserver/root}} in the <a>containing block chain</a>.

An {{IntersectionObserver}} with no {{IntersectionObserver/root}} {{Element}}
An {{IntersectionObserver}} with no {{IntersectionObserver/root}} {{Node}}
will automatically observe intersections with the <a>implicit root</a>,
and valid <a>targets</a> include any {{Element}} in the
<a>top-level browsing context</a>, as well as any {{Element}} in any
Expand All @@ -195,7 +196,7 @@ introduces a need for it.
[Constructor(IntersectionObserverCallback callback, optional IntersectionObserverInit options),
Exposed=Window]
interface IntersectionObserver {
readonly attribute Element? root;
readonly attribute Node? root;
readonly attribute DOMString rootMargin;
readonly attribute FrozenArray&lt;double&gt; thresholds;
void observe(Element target);
Expand Down Expand Up @@ -271,11 +272,11 @@ interface IntersectionObserver {
<div dfn-type="attribute" dfn-for="IntersectionObserver">
: <dfn>root</dfn>
::
The root {{Element}} to use for intersection, or <code>null</code> if the
The root {{Node}} to use for intersection, or <code>null</code> if the
observer uses the <a>implicit root</a>.
: <dfn>rootMargin</dfn>
::
Offsets applied to the <a>intersection root's</a> bounding box,
Offsets applied to the <a>root intersection rectangle</a>,
effectively growing or shrinking the box that is used to calculate intersections.
Note that {{IntersectionObserver/rootMargin}} is only applied
for <a>targets</a> which belong to the same <a>unit of related similar-origin browsing contexts</a>
Expand All @@ -300,7 +301,7 @@ interface IntersectionObserver {

The <dfn for="IntersectionObserver">intersection root</dfn>
for an {{IntersectionObserver}} is the value of its {{IntersectionObserver/root}} attribute,
or else the <a>top-level browsing context</a>'s <a>document</a> node
or else the <a>top-level browsing context</a>'s {{document}} node
(referred to as the <dfn for="IntersectionObserver">implicit root</dfn>) if
the {{IntersectionObserver/root}} attribute is <code>null</code>.

Expand All @@ -310,9 +311,12 @@ is the rectangle we'll use to check against the targets.

<dl class=switch>
<dt>If the <a>intersection root</a> is the <a>implicit root</a>,
<dd>it's the viewport's size.
<dd>it's treated as if the root were the <a>top-level browsing context</a>'s {{document}}, according to the following rule for {{document}}.

<dt>If the <a>intersection root</a> has an overflow clip,
<dt>If the <a>intersection root</a> is a {{document}},
<dd>it's the size of the {{document}}'s <a>viewport</a> (note that this processing step can only be reached if the {{document}} is <a>fully active</a>).

<dt>Otherwise, if the <a>intersection root</a> has an overflow clip,
<dd>it's the element's <a>content area</a>.

<dt>Otherwise,
Expand Down Expand Up @@ -444,7 +448,7 @@ The IntersectionObserverInit dictionary</h3>

<pre class="idl">
dictionary IntersectionObserverInit {
Element? root = null;
(Element or Document)? root = null;
DOMString rootMargin = "0px";
(double or sequence&lt;double>) threshold = 0;
};
Expand Down Expand Up @@ -494,7 +498,7 @@ Internal Slot Definitions</h3>
<h4 id='document-defines'>
Document</h4>

Each <a>Document</a> has an
Each {{document}} has an
<dfn for="Document">IntersectionObserverTaskQueued</dfn> flag
which is initialized to false.

Expand Down Expand Up @@ -528,18 +532,18 @@ Algorithms</h2>
<h4 id='queue-intersection-observer-task'>
Queue an Intersection Observer Task</h4>

To <dfn>queue an intersection observer task</dfn> for a <a>Document</a> |document|,
To <dfn>queue an intersection observer task</dfn> for a {{document}} |document|,
run these steps:

1. If |document|'s <a>IntersectionObserverTaskQueued</a> flag is set to true,
return.
2. Set |document|'s <a>IntersectionObserverTaskQueued</a> flag to true.
3. <a>Queue a task</a> to the <a>document</a>'s <a>event loop</a> to <a>notify intersection observers</a>.
3. <a>Queue a task</a> to the {{document}}'s <a>event loop</a> to <a>notify intersection observers</a>.

<h4 id='notify-intersection-observers-algo'>
Notify Intersection Observers</h4>

To <dfn>notify intersection observers</dfn> for a <a>Document</a> |document|,
To <dfn>notify intersection observers</dfn> for a {{document}} |document|,
run these steps:

1. Set |document|'s <a>IntersectionObserverTaskQueued</a> flag to false.
Expand All @@ -561,7 +565,7 @@ run these steps:
Queue an IntersectionObserverEntry</h4>

To <dfn>queue an IntersectionObserverEntry</dfn> for an {{IntersectionObserver}} |observer|, given a
<a>Document</a> |document|; {{DOMHighResTimeStamp}} |time|;
{{document}} |document|; {{DOMHighResTimeStamp}} |time|;
{{DOMRect}}s |rootBounds|, |boundingClientRect|, |intersectionRect|, and |isIntersecting| flag;
and an {{Element}} |target|;
run these steps:
Expand All @@ -580,35 +584,38 @@ run these steps:
1. Let |intersectionRect| be the result of running the {{Element/getBoundingClientRect()}} algorithm on the <a>target</a>.
2. Let |container| be the <a>containing block</a> of the <a>target</a>.
3. While |container| is not the <a>intersection root</a>:
1. Map |intersectionRect| to the coordinate space of |container|.
2. If |container| has overflow clipping or a css <a>clip-path</a> property,
1. If |container| is the {{document}} of a <a>nested browsing context</a>,
update |intersectionRect| by clipping to the <a>viewport</a>
of the {{document}}, and update |container| to be
the <a>browsing context container</a> of |container|.
2. Map |intersectionRect| to the coordinate space of |container|.
3. If |container| has overflow clipping or a css <a>clip-path</a> property,
update |intersectionRect| by applying |container|'s clip.
3. If |container| is the root element of a <a>nested browsing context</a>,
update |container| to be the <a>browsing context container</a> of |container|,
and update |intersectionRect| by clipping to the <a>viewport</a> of the
<a>nested browsing context</a>.
Otherwise, update |container| to be the <a>containing block</a> of |container|.
4. If |container| is the root element of a <a>browsing context</a>,
update |container| to be the <a>browsing context</a>'s {{document}};
otherwise, update |container| to be the <a>containing block</a>
of |container|.
4. Map |intersectionRect| to the coordinate space of the <a>intersection root</a>.
5. Update |intersectionRect| by intersecting it with the <a>root intersection rectangle</a>.
6. Map |intersectionRect| to the coordinate space of the viewport of the <a>Document</a> containing the <a>target</a>.
6. Map |intersectionRect| to the coordinate space of the <a>viewport</a> of the {{document}} containing the <a>target</a>.

<h4 id='update-intersection-observations-algo'>
Run the Update Intersection Observations Steps</h4>

To <dfn>run the update intersection observations steps</dfn> for a
<a>Document</a> |document| given a timestamp |time|, run these steps:
{{document}} |document| given a timestamp |time|, run these steps:

1. Let |observer list| be a list of all {{IntersectionObserver}}s
whose {{IntersectionObserver/root}} is in the DOM tree of |document|.
2. For each |observer| in |observer list|:
1. Let |rootBounds| be |observer|'s <a>root intersection rectangle</a>.
2. For each |target| in |observer|'s internal {{[[ObservationTargets]]}} slot, processed in the same order that {{observe()}} was called on each |target|:
1. If the <a>intersection root</a> is not the <a>implicit root</a>
1. If the <a>intersection root</a> is an {{Element}},
and |target| is not a descendant of the <a>intersection root</a>
in the <a>containing block chain</a>,
skip further processing for |target|.
2. If the <a>intersection root</a> is not the <a>implicit root</a>,
and |target| is not in the same <a>Document</a> as the <a>intersection root</a>,
and |target| is not in the same {{document}} as the <a>intersection root</a>,
skip further processing for |target|.
3. Let |targetRect| be a {{DOMRectReadOnly}} obtained
by running the {{Element/getBoundingClientRect()}} algorithm on |target|.
Expand Down Expand Up @@ -664,7 +671,7 @@ in the in the <a>HTML Processing Model</a>.
This step is:

<ol start="10">
<li>For each <a>fully active</a> <a>Document</a> in |docs|, <a>Run the update intersection observations steps</a> for each {{IntersectionObserver}} whose {{IntersectionObserver/root}} is in the DOMtree of that <a>Document</a>.</li>
<li>For each <a>fully active</a> {{document}} in |docs|, <a>Run the update intersection observations steps</a> for each {{IntersectionObserver}} whose {{IntersectionObserver/root}} is in the DOMtree of that {{document}}.</li>
</ol>

<!-- ============================================================ -->
Expand Down

0 comments on commit e626248

Please sign in to comment.