Skip to content

Commit c548a9a

Browse files
authored
[cssom-view-1] Scroll methods in Element and Window return Promises (w3c#12355)
Switch the return type for the scroll methods from `undefined` to `Promise<undefined>` as per the discussion and resolution in w3c#1562 (comment).
1 parent 186bae8 commit c548a9a

File tree

1 file changed

+65
-39
lines changed

1 file changed

+65
-39
lines changed

cssom-view-1/Overview.bs

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -441,22 +441,26 @@ an associated element or [=pseudo-element=] <var>element</var> and optionally a
441441
(which is "<code>auto</code>" if omitted),
442442
the following steps must be run:
443443

444-
<ol>
445-
<li><a lt="smooth scroll aborted">Abort</a> any ongoing <a>smooth scroll</a> for <var>box</var>.
446-
<li>If the user agent honors the 'scroll-behavior' property and one of the following are true:
444+
1. <a lt="smooth scroll aborted">Abort</a> any ongoing <a>smooth scroll</a> for <var>box</var>.
445+
1. Resolve all pending scroll {{Promise}}s whose scroll container is <var>box</var>.
446+
1. Let <var>scrollPromise</var> be a new {{Promise}}.
447+
1. Return <var>scrollPromise</var>, and run the remaining steps <a>in parallel</a>.
448+
1. If the user agent honors the 'scroll-behavior' property and one of the following is true:
447449
<ul>
448450
<li><var>behavior</var> is "<code>auto</code>" and <var>element</var> is not null and its computed value of the
449-
'scroll-behavior' property is ''scroll-behavior/smooth''
451+
'scroll-behavior' property is ''scroll-behavior/smooth'', or
450452
<li><var>behavior</var> is <code>smooth</code>
451453
</ul>
452-
...then perform a <a>smooth scroll</a> of <var>box</var> to <var>position</var>. Once the position has finished updating, emit the <a event>scrollend</a> event.
453-
Otherwise, perform an <a>instant scroll</a> of <var>box</var> to <var>position</var>. After an <a>instant scroll</a> emit the <a event>scrollend</a> event.
454+
then perform a <a>smooth scroll</a> of <var>box</var> to <var>position</var>;
455+
otherwise, perform an <a>instant scroll</a> of <var>box</var> to <var>position</var>.
456+
1. Wait until either the position has finished updating, or <var>scrollPromise</var> has been resolved.
457+
1. If <var>scrollPromise</var> is still in the pending state:
458+
1. If the scroll position changed as a result of this call, emit the <a event>scrollend</a> event.
459+
1. Resolve <var>scrollPromise</var>.
454460

455461
Note: <code>behavior: "instant"</code> always performs an <a>instant scroll</a> by this algorithm.
456462

457463
Note: If the scroll position did not change as a result of the user interaction or programmatic invocation, where no translations were applied as a result, then no <a event>scrollend</a> event fires because no scrolling occurred.
458-
</ol>
459-
460464
</div>
461465

462466
<div algorithm="perform a scroll of a viewport">
@@ -481,8 +485,13 @@ When a user agent is to <dfn for="viewport" export>perform a scroll</dfn> of a <
481485
1. Let <var>element</var> be <var>doc</var>'s root element if there is one, null otherwise.
482486
1. <a for="/">Perform a scroll</a> of the <a>viewport</a>'s <a>scrolling box</a> to its current scroll position + (<var>layout dx</var>, <var>layout dy</var>) with <var>element</var> as the
483487
associated element, and <var>behavior</var> as the scroll behavior.
488+
Let <var>scrollPromise1</var> be the {{Promise}} returned from this step.
484489
1. <a for="/">Perform a scroll</a> of <var>vv</var>'s <a>scrolling box</a> to its current scroll position + (<var>visual dx</var>, <var>visual dy</var>) with <var>element</var> as the associated
485490
element, and <var>behavior</var> as the scroll behavior.
491+
Let <var>scrollPromise2</var> be the {{Promise}} returned from this step.
492+
1. Let <var>scrollPromise</var> be a new {{Promise}}.
493+
1. Return <var>scrollPromise</var>, and run the remaining steps <a>in parallel</a>.
494+
1. Resolve <var>scrollPromise</var> when both <var>scrollPromise1</var> and <var>scrollPromise2</var> have settled.
486495

487496
Note: Conceptually, the visual viewport is scrolled until it "bumps up" against the layout viewport
488497
edge and then "pushes" the layout viewport by applying the scroll delta to the layout viewport.
@@ -581,12 +590,12 @@ partial interface Window {
581590
[Replaceable] readonly attribute double pageXOffset;
582591
[Replaceable] readonly attribute double scrollY;
583592
[Replaceable] readonly attribute double pageYOffset;
584-
undefined scroll(optional ScrollToOptions options = {});
585-
undefined scroll(unrestricted double x, unrestricted double y);
586-
undefined scrollTo(optional ScrollToOptions options = {});
587-
undefined scrollTo(unrestricted double x, unrestricted double y);
588-
undefined scrollBy(optional ScrollToOptions options = {});
589-
undefined scrollBy(unrestricted double x, unrestricted double y);
593+
Promise<undefined> scroll(optional ScrollToOptions options = {});
594+
Promise<undefined> scroll(unrestricted double x, unrestricted double y);
595+
Promise<undefined> scrollTo(optional ScrollToOptions options = {});
596+
Promise<undefined> scrollTo(unrestricted double x, unrestricted double y);
597+
Promise<undefined> scrollBy(optional ScrollToOptions options = {});
598+
Promise<undefined> scrollBy(unrestricted double x, unrestricted double y);
590599

591600
// client
592601
[Replaceable] readonly attribute long screenX;
@@ -599,6 +608,8 @@ partial interface Window {
599608
};
600609
</pre>
601610

611+
Issue: Should the scroll methods above return a result object and if so what information should they provide? #12495
612+
602613
When the <dfn method for=Window caniuse=matchmedia>matchMedia(<var>query</var>)</dfn> method is invoked these steps must be run:
603614
<ol>
604615
<li>Let <var>parsed media query list</var> be the result of
@@ -715,7 +726,7 @@ steps must be run:
715726
1. Let <var>options</var> be null <a lt="converted to an IDL value">converted</a> to a {{ScrollToOptions}} dictionary. [[!WEBIDL]]
716727
1. Let <var>x</var> and <var>y</var> be the arguments, respectively.
717728
1. <a>Normalize non-finite values</a> for <var>x</var> and <var>y</var>.
718-
1. If there is no <a>viewport</a>, abort these steps.
729+
1. If there is no <a>viewport</a>, return a resolved {{Promise}} and abort the remaining steps.
719730
1. Let <var>viewport width</var> be the width of the <a>viewport</a> excluding the width of the scroll bar, if any.
720731
1. Let <var>viewport height</var> be the height of the <a>viewport</a> excluding the height of the scroll bar, if any.
721732
1.
@@ -740,11 +751,13 @@ steps must be run:
740751
and aligning the y-coordinate <var>y</var> of the <a>viewport</a> <a>scrolling area</a>
741752
with the top of the <a>viewport</a>.
742753
1. If <var>position</var> is the same as the <a>viewport’s</a> current scroll position,
743-
and the <a>viewport</a> does not have an ongoing <a>smooth scroll</a>, abort these steps.
754+
and the <a>viewport</a> does not have an ongoing <a>smooth scroll</a>, return a resolved {{Promise}} and abort the remaining steps.
744755
1. Let <var>document</var> be the <a>viewport’s</a> associated {{Document}}.
745756
1. <a for="viewport">Perform a scroll</a> of the <a>viewport</a> to <var>position</var>,
746757
<var>document</var>'s [=root element=] as the associated element, if there is one, or null otherwise,
747758
and the scroll behavior being the value of the {{ScrollOptions/behavior}} dictionary member of <var>options</var>.
759+
Let <var>scrollPromise</var> be the {{Promise}} returned from this step.
760+
1. Return <var>scrollPromise</var>.
748761

749762
Issue: User agents do not agree whether this uses the (coordinated) <a>viewport</a> <a for="viewport">perform a scroll</a> or the
750763
<a>scrolling box</a> <a for="/">perform a scroll</a> on the layout viewport's scrolling box.
@@ -774,7 +787,7 @@ user agent must run these steps:
774787
1. <a>Normalize non-finite values</a> for the {{ScrollToOptions/left}} and {{ScrollToOptions/top}} dictionary members of <var>options</var>.
775788
1. Add the value of {{scrollX}} to the {{ScrollToOptions/left}} dictionary member.
776789
1. Add the value of {{scrollY}} to the {{ScrollToOptions/top}} dictionary member.
777-
1. Act as if the {{Window/scroll()}} method was invoked with <var>options</var> as the only argument.
790+
1. Return the {{Promise}} returned from {{Window/scroll()}} after the method is invoked with <var>options</var> as the only argument.
778791

779792
The <dfn attribute for=Window>screenX</dfn> and <dfn attribute for=Window>screenLeft</dfn> attributes must return the x-coordinate,
780793
relative to the origin of the <a>Web-exposed screen area</a>, of the left of
@@ -1307,13 +1320,13 @@ partial interface Element {
13071320

13081321
boolean checkVisibility(optional CheckVisibilityOptions options = {});
13091322

1310-
undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
1311-
undefined scroll(optional ScrollToOptions options = {});
1312-
undefined scroll(unrestricted double x, unrestricted double y);
1313-
undefined scrollTo(optional ScrollToOptions options = {});
1314-
undefined scrollTo(unrestricted double x, unrestricted double y);
1315-
undefined scrollBy(optional ScrollToOptions options = {});
1316-
undefined scrollBy(unrestricted double x, unrestricted double y);
1323+
Promise<undefined> scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
1324+
Promise<undefined> scroll(optional ScrollToOptions options = {});
1325+
Promise<undefined> scroll(unrestricted double x, unrestricted double y);
1326+
Promise<undefined> scrollTo(optional ScrollToOptions options = {});
1327+
Promise<undefined> scrollTo(unrestricted double x, unrestricted double y);
1328+
Promise<undefined> scrollBy(optional ScrollToOptions options = {});
1329+
Promise<undefined> scrollBy(unrestricted double x, unrestricted double y);
13171330
attribute unrestricted double scrollTop;
13181331
attribute unrestricted double scrollLeft;
13191332
readonly attribute long scrollWidth;
@@ -1326,6 +1339,8 @@ partial interface Element {
13261339
};
13271340
</pre>
13281341

1342+
Issue: Should the scroll methods above return a result object and if so what information should they provide? #12495
1343+
13291344
Note: The {{CheckVisibilityOptions/checkOpacity}} and {{CheckVisibilityOptions/checkVisibilityCSS}} properties are historical names.
13301345
These properties have aliases that match the new naming scheme,
13311346
namely {{CheckVisibilityOptions/opacityProperty}} and {{CheckVisibilityOptions/visibilityProperty}}.
@@ -1462,10 +1477,12 @@ The <dfn method for=Element caniuse=scrollintoview>scrollIntoView(<var>arg</var>
14621477
1. Otherwise, if <var>arg</var> is false, then set <var>block</var> to "<code>end</code>".
14631478
1. If the element does not have any associated [=CSS/box=],
14641479
or is not available to user-agent features,
1465-
then return.
1480+
then return a resolved {{Promise}} and abort the remaining steps.
14661481
1. <a lt='scroll a target into view'>Scroll the element into view</a>
14671482
with <var>behavior</var>, <var>block</var>, <var>inline</var>, and <var>container</var>.
1483+
Let <var>scrollPromise</var> be the {{Promise}} returned from this step
14681484
1. Optionally perform some other action that brings the element to the user's attention.
1485+
1. Return <var>scrollPromise</var>.
14691486

14701487
<div class='example'>
14711488
A component can use scrollIntoView to scroll content of interest into the specified alignment:
@@ -1553,23 +1570,24 @@ The <dfn method for=Element lt="scroll(options)|scroll(x, y)">scroll()</dfn> met
15531570
1. Let the {{ScrollToOptions/left}} dictionary member of <var>options</var> have the value <var>x</var>.
15541571
1. Let the {{ScrollToOptions/top}} dictionary member of <var>options</var> have the value <var>y</var>.
15551572
1. Let <var>document</var> be the element's <a>node document</a>.
1556-
1. If <var>document</var> is not the <a>active document</a>, terminate these steps.
1573+
1. If <var>document</var> is not the <a>active document</a>, return a resolved {{Promise}} and abort the remaining steps.
15571574
1. Let <var>window</var> be the value of <var>document</var>'s {{Document/defaultView}} attribute.
1558-
1. If <var>window</var> is null, terminate these steps.
1559-
1. If the element is the [=root element=] and <var>document</var> is in <a>quirks mode</a>, terminate these steps.
1560-
1. If the element is the [=root element=] invoke {{Window/scroll()}} on <var>window</var> with {{Window/scrollX}} on <var>window</var> as first argument and <var>y</var> as second argument,
1561-
and terminate these steps.
1575+
1. If <var>window</var> is null, return a resolved {{Promise}} and abort the remaining steps.
1576+
1. If the element is the [=root element=] and <var>document</var> is in <a>quirks mode</a>, return a resolved {{Promise}} and abort the remaining steps.
1577+
1. If the element is the [=root element=], return the {{Promise}} returned by {{Window/scroll()}} on <var>window</var> after the method is invoked with
1578+
{{Window/scrollX}} on <var>window</var> as first argument and <var>y</var> as second argument, and abort the remaining steps.
15621579
1. If the element is <a>the <code>body</code> element</a>,
15631580
<var>document</var> is in <a>quirks mode</a>,
15641581
and the element is not <a>potentially scrollable</a>,
1565-
invoke {{Window/scroll()}} on <var>window</var> with <var>options</var> as the only argument,
1566-
and terminate these steps.
1582+
return the {{Promise}} returned by {{Window/scroll()}} on <var>window</var> after the method is invoked with
1583+
<var>options</var> as the only argument, and abort the remaining steps.
15671584
1. If the element does not have any associated [=CSS/box=],
15681585
the element has no associated <a>scrolling box</a>,
15691586
or the element has no overflow,
1570-
terminate these steps.
1587+
return a resolved {{Promise}} and abort the remaining steps.
15711588
1. <a lt='scroll an element'>Scroll the element</a> to <var>x</var>,<var>y</var>,
1572-
with the scroll behavior being the value of the {{ScrollOptions/behavior}} dictionary member of <var>options</var>.
1589+
with the scroll behavior being the value of the {{ScrollOptions/behavior}} dictionary member of <var>options</var>. Let <var>scrollPromise</var> be the {{Promise}} returned from this step.
1590+
1. Return <var>scrollPromise</var>.
15731591

15741592
When the <dfn method for=Element lt="scrollTo(options)|scrollTo(x, y)">scrollTo()</dfn> method is invoked, the
15751593
user agent must act as if the {{Element/scroll()}} method was invoked with the same arguments.
@@ -1588,7 +1606,7 @@ user agent must run these steps:
15881606
1. Let the {{ScrollToOptions/top}} dictionary member of <var>options</var> have the value <var>y</var>.
15891607
1. Add the value of {{Element/scrollLeft}} to the {{ScrollToOptions/left}} dictionary member.
15901608
1. Add the value of {{Element/scrollTop}} to the {{ScrollToOptions/top}} dictionary member.
1591-
1. Act as if the {{Element/scroll()}} method was invoked with <var>options</var> as the only argument.
1609+
1. Return the {{Promise}} returned by {{Element/scroll()}} after the method is invoked with <var>options</var> as the only argument.
15921610

15931611
<wpt>
15941612
window-scrollBy-display-change.html
@@ -1804,9 +1822,11 @@ an inline base direction position <var>inline</var>,
18041822
and an optional containing <a>Element</a> to stop scrolling after reaching <var>container</var>,
18051823
means to run these steps:
18061824

1825+
1. Let <var>ancestorPromises</var> be an empty set of {{Promise}}s.
18071826
1. For each ancestor element or <a>viewport</a> that establishes a <a>scrolling box</a> <var>scrolling box</var>,
18081827
in order of innermost to outermost <a>scrolling box</a>, run these substeps:
1809-
1. If the {{Document}} associated with <var>target</var> is not <a>same origin</a> with the {{Document}} associated with the element or <a>viewport</a> associated with <var>scrolling box</var>, terminate these steps.
1828+
1. If the {{Document}} associated with <var>target</var> is not <a>same origin</a> with the {{Document}} associated with the element or <a>viewport</a> associated with <var>scrolling box</var>,
1829+
abort any remaining iteration of this loop.
18101830
1. Let <var>position</var> be the scroll position resulting from running the steps to <a>determine the scroll-into-view position</a> of <var>target</var> with <var>behavior</var> as the |scroll behavior|,
18111831
<var>block</var> as the |block flow position|, <var>inline</var> as the |inline base direction position| and <var>scrolling box</var> as the |scrolling box|.
18121832
1. If <var>position</var> is not the same as <var>scrolling box</var>'s current scroll position, or <var>scrolling box</var> has an ongoing <a>smooth scroll</a>,
@@ -1815,18 +1835,22 @@ means to run these steps:
18151835
<dd>
18161836
<a for="/">Perform a scroll</a> of the element's <var>scrolling box</var> to <var>position</var>, with the element as the associated element and
18171837
<var>behavior</var> as the scroll behavior.
1838+
Add the {{Promise}} retured from this step to the set <var>ancestorPromises</var>.
18181839
<dt>If <var>scrolling box</var> is associated with a <a>viewport</a>
18191840
<dd>
18201841
1. Let <var>document</var> be the <a>viewport’s</a> associated {{Document}}.
18211842
1. Let <var>root element</var> be <var>document</var>'s [=root element=], if there is one, or null otherwise.
18221843
1. <a for="viewport">Perform a scroll</a> of the <a>viewport</a> to <var>position</var>, with <var>root element</var> as the associated element and <var>behavior</var>
18231844
as the scroll behavior.
1845+
Add the {{Promise}} retured from this step in the set <var>ancestorPromises</var>.
18241846
</dl>
18251847
1. If <var>container</var> is not null and either <var>scrolling box</var>
18261848
is a [=shadow-including inclusive ancestor=] of <var>container</var> or
18271849
is a <a>viewport</a> whose <a for="/">document</a> is a [=shadow-including inclusive ancestor=] of <var>container</var>,
1828-
abort the rest of these steps.
1829-
1850+
abort any remaining iteration of this loop.
1851+
1. Let <var>scrollPromise</var> be a new {{Promise}}.
1852+
1. Return <var>scrollPromise</var>, and run the remaining steps <a>in parallel</a>.
1853+
1. Resolve <var>scrollPromise</var> when all {{Promise}}s in <var>ancestorPromises</var> have settled.
18301854
</div>
18311855

18321856
<div algorithm>
@@ -1849,8 +1873,10 @@ To <dfn>scroll an element</dfn> (or [=pseudo-element=]) <var>element</var> to <v
18491873
<dd>Let <var>y</var> be min(0, max(<var>y</var>, <var>element</var> <a>padding edge</a> height - <var>element</var> <a>scrolling area</a> height)).
18501874
</dl>
18511875
1. Let <var>position</var> be the scroll position <var>box</var> would have by aligning <a>scrolling area</a> x-coordinate <var>x</var> with the left of <var>box</var> and aligning <a>scrolling area</a> y-coordinate <var>y</var> with the top of <var>box</var>.
1852-
1. If <var>position</var> is the same as <var>box</var>'s current scroll position, and <var>box</var> does not have an ongoing <a>smooth scroll</a>, abort these steps.
1876+
1. If <var>position</var> is the same as <var>box</var>'s current scroll position, and <var>box</var> does not have an ongoing <a>smooth scroll</a>, return a resolved {{Promise}} and abort the remaining steps.
18531877
1. <a for="/">Perform a scroll</a> of <var>box</var> to <var>position</var>, <var>element</var> as the associated element and <var>behavior</var> as the scroll behavior.
1878+
Let <var>scrollPromise</var> be the {{Promise}} returned from this step.
1879+
1. Return <var>scrollPromise</var>.
18541880

18551881
</div>
18561882

0 commit comments

Comments
 (0)