Changeset 272610 in webkit


Ignore:
Timestamp:
Feb 9, 2021 1:52:39 PM (18 months ago)
Author:
Martin Robinson
Message:

Implement scroll-snap-stop for scroll snapping
https://bugs.webkit.org/show_bug.cgi?id=197744
<rdar://problem/50708356>

LayoutTests/imported/w3c:

Reviewed by Simon Fraser.

  • web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
  • web-platform-tests/css/css-scroll-snap/inheritance-expected.txt:
  • web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-computed-expected.txt:
  • web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-valid-expected.txt:
  • web-platform-tests/css/css-scroll-snap/scroll-snap-stop-change-expected.txt:
  • web-platform-tests/css/css-scroll-snap/scroll-snap-stop-expected.txt:
  • web-platform-tests/css/css-scroll-snap/scroll-snap-type-on-root-element-expected.txt:
  • web-platform-tests/css/cssom/cssstyledeclaration-csstext-expected.txt:

Source/WebCore:

Reviewed by Simon Fraser.

No new tests. This is tested by existing, imported WPT tests:

imported/w3c/web-platform-tests/css/css-scroll-snap/inheritance-expected.txt:
imported/w3c/web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-computed-expected.txt:
imported/w3c/web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-valid-expected.txt:
imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-change-expected.txt:
imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-expected.txt:
imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-type-on-root-element-expected.txt:

  • css/CSSComputedStyleDeclaration.cpp:

(WebCore::ComputedStyleExtractor::valueForPropertyInStyle): Add support the new CSS property.

  • css/CSSPrimitiveValueMappings.h:

(WebCore::CSSPrimitiveValue::operator ScrollSnapAxisAlignType const): Ditto.
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Ditto.
(WebCore::CSSPrimitiveValue::operator ScrollSnapStop const): ditto.

  • css/CSSProperties.json: Ditto.
  • css/parser/CSSPropertyParser.cpp:

(WebCore::CSSPropertyParser::parseSingleValue): Ditto.

  • page/scrolling/ScrollSnapOffsetsInfo.cpp:

(WebCore::indicesOfNearestSnapOffsets): Update to accept SnapOffset instead of a raw
value.
(WebCore::findFirstSnapStopOffsetBetweenOriginAndDestination): Added this helper which looks
between the scroll origin and destination to find a candidate scroll offset with ScrollSnapStop::Always.
This offset will always be chosen for directional scrolls.
(WebCore::closestSnapOffsetWithOffsetsAndRanges): Use new helper to find offsets with ScrollSnapStop::Always.
(WebCore::computeAxisProximitySnapOffsetRanges): Deal with SnapOffset instead of raw values.
(WebCore::updateSnapOffsetsForScrollableArea): Ditto.
(WebCore::convertOffsetInfo): Ditto.

  • page/scrolling/ScrollSnapOffsetsInfo.h:

(WebCore::ScrollSnapOffsetsInfo::offsetsForAxis const): Ditto.
(WebCore::operator<<): Consolidated all TextStream implementations here instead of repeating
them throughout the code.

  • platform/ScrollableArea.cpp:

(WebCore::ScrollableArea::setScrollSnapOffsetInfo): Set the scroll snap offset info all at once.
(WebCore::ScrollableArea::clearSnapOffsets): We no longer clear horizontal and vertical offsets separately.
(WebCore::ScrollableArea::nearestActiveSnapPoint): Access the offset value.

  • platform/ScrollableArea.h:
  • platform/cocoa/ScrollController.mm:

(WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset): Ditto.

  • platform/cocoa/ScrollSnapAnimatorState.h:

(WebCore::ScrollSnapAnimatorState::snapOffsetsForAxis const): Deal with SnapOffsets instead of raw values.
(WebCore::ScrollSnapAnimatorState::setSnapOffsetsAndPositionRangesForAxis): Ditto.

  • platform/cocoa/ScrollSnapAnimatorState.mm:
  • rendering/RenderLayerModelObject.cpp:

(WebCore::RenderLayerModelObject::styleDidChange): Update scroll snap information when the scroll-snap-stop
property changes. Also ensure that we update everything for FrameView's instead of only some properties.

  • rendering/style/RenderStyle.cpp:

(WebCore::RenderStyle::initialScrollSnapStop): Added for new CSS property.
(WebCore::RenderStyle::scrollSnapStop const): Ditto.
(WebCore::RenderStyle::setScrollSnapStop): Ditto.

  • rendering/style/RenderStyle.h:
  • rendering/style/RenderStyleConstants.cpp:

(WebCore::operator<<): Ditto.

  • rendering/style/RenderStyleConstants.h:
  • rendering/style/StyleRareNonInheritedData.h:
  • style/StyleBuilderConverter.h:

(WebCore::Style::BuilderConverter::convertScrollSnapStop): Ditto.

  • testing/Internals.cpp:

(WebCore::appendOffsets): Handle the case where we are printing an offset with ScrollSnapStop::Always.

Source/WebKit:

Reviewed by Simon Fraser.

  • Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp: Add encoding and decoding support

for the SnapOffset struct.
(ArgumentCoder<SnapOffset<float>>::encode):
(ArgumentCoder<SnapOffset<float>>::decode):

  • UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm: Update to use SnapOffset struct.

(WebKit::RemoteScrollingCoordinatorProxy::shouldSnapForMainFrameScrolling const):
(WebKit::RemoteScrollingCoordinatorProxy::hasActiveSnapPoint const):
(WebKit::RemoteScrollingCoordinatorProxy::nearestActiveContentInsetAdjustedSnapOffset const):

LayoutTests:

Reviewed by Simon Fraser.

  • platform/ios-wk2/imported/w3c/web-platform-tests/css/cssom/cssstyledeclaration-csstext-expected.txt:
Location:
trunk
Files:
37 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r272609 r272610  
     12021-02-09  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Implement scroll-snap-stop for scroll snapping
     4        https://bugs.webkit.org/show_bug.cgi?id=197744
     5        <rdar://problem/50708356>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * platform/ios-wk2/imported/w3c/web-platform-tests/css/cssom/cssstyledeclaration-csstext-expected.txt:
     10
    1112021-02-09  Jonathan Bedard  <jbedard@apple.com>
    212
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r272572 r272610  
     12021-02-09  Martin Robinson  <mrobinson@webkit.org>
     2
     3        Implement scroll-snap-stop for scroll snapping
     4        https://bugs.webkit.org/show_bug.cgi?id=197744
     5        <rdar://problem/50708356>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt:
     10        * web-platform-tests/css/css-scroll-snap/inheritance-expected.txt:
     11        * web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-computed-expected.txt:
     12        * web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-valid-expected.txt:
     13        * web-platform-tests/css/css-scroll-snap/scroll-snap-stop-change-expected.txt:
     14        * web-platform-tests/css/css-scroll-snap/scroll-snap-stop-expected.txt:
     15        * web-platform-tests/css/css-scroll-snap/scroll-snap-type-on-root-element-expected.txt:
     16        * web-platform-tests/css/cssom/cssstyledeclaration-csstext-expected.txt:
     17
    1182021-02-09  Manuel Rego Casasnovas  <rego@igalia.com>
    219
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml-expected.txt

    r272035 r272610  
    242242PASS scroll-padding-top
    243243PASS scroll-snap-align
     244PASS scroll-snap-stop
    244245PASS scroll-snap-type
    245246PASS shape-image-threshold
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/inheritance-expected.txt

    r272366 r272610  
    3434PASS Property scroll-snap-align has initial value none
    3535PASS Property scroll-snap-align does not inherit
    36 FAIL Property scroll-snap-stop has initial value normal assert_true: scroll-snap-stop doesn't seem to be supported in the computed style expected true got false
    37 FAIL Property scroll-snap-stop does not inherit assert_true: expected true got false
     36PASS Property scroll-snap-stop has initial value normal
     37PASS Property scroll-snap-stop does not inherit
    3838PASS Property scroll-snap-type has initial value none
    3939PASS Property scroll-snap-type does not inherit
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-computed-expected.txt

    r268250 r272610  
    11
    2 FAIL Property scroll-snap-stop value 'normal' assert_true: scroll-snap-stop doesn't seem to be supported in the computed style expected true got false
    3 FAIL Property scroll-snap-stop value 'always' assert_true: scroll-snap-stop doesn't seem to be supported in the computed style expected true got false
     2PASS Property scroll-snap-stop value 'normal'
     3PASS Property scroll-snap-stop value 'always'
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-valid-expected.txt

    r268250 r272610  
    11
    2 FAIL e.style['scroll-snap-stop'] = "normal" should set the property value assert_not_equals: property should be set got disallowed value ""
    3 FAIL e.style['scroll-snap-stop'] = "always" should set the property value assert_not_equals: property should be set got disallowed value ""
     2PASS e.style['scroll-snap-stop'] = "normal" should set the property value
     3PASS e.style['scroll-snap-stop'] = "always" should set the property value
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-change-expected.txt

    r268250 r272610  
    11
    2 FAIL scroll-snap-stop for areas on HTML should control snapping behavior and changing it takes effect assert_equals: scrollBy should not skip area with stop always expected 100 but got 500
    3 FAIL scroll-snap-stop for areas on DIV should control snapping behavior and changing it takes effect assert_equals: scrollBy should not skip area with stop always expected 100 but got 500
     2PASS scroll-snap-stop for areas on HTML should control snapping behavior and changing it takes effect
     3PASS scroll-snap-stop for areas on DIV should control snapping behavior and changing it takes effect
    44
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-expected.txt

    r271439 r272610  
    11
    2 FAIL A scroll with intended direction and end position should not pass a snap area with scroll-snap-stop: always. assert_equals: expected 100 but got 200
     2PASS A scroll with intended direction and end position should not pass a snap area with scroll-snap-stop: always.
    33PASS A scroll with intended end position should always choose the closest snap position regardless of the scroll-snap-stop value.
    4 FAIL A scroll outside bounds in the snapping axis with intended direction and end position should not pass a snap area with scroll-snap-stop: always. assert_equals: expected 100 but got 200
    5 FAIL A scroll outside bounds in the non-snapping axis with intended direction and end position should not pass a snap area with scroll-snap-stop: always. assert_equals: expected 100 but got 200
     4PASS A scroll outside bounds in the snapping axis with intended direction and end position should not pass a snap area with scroll-snap-stop: always.
     5PASS A scroll outside bounds in the non-snapping axis with intended direction and end position should not pass a snap area with scroll-snap-stop: always.
    66
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-type-on-root-element-expected.txt

    r271480 r272610  
    11
    2 FAIL The scroll-snap-type on the root element is applied assert_equals: expected 515 but got 800
     2PASS The scroll-snap-type on the root element is applied
    33FAIL The writing-mode (vertical-lr) on the body is used assert_equals: inline should snap expected 515 but got 800
    44PASS The writing-mode (horizontal-tb) on the body is used
  • trunk/LayoutTests/imported/w3c/web-platform-tests/css/cssom/cssstyledeclaration-csstext-expected.txt

    r272366 r272610  
    88PASS whitespaces in value
    99PASS invalid property does not appear
    10 FAIL cssText on computed style declaration returns the empty string assert_equals: cssText is empty expected "" but got "align-content: normal; align-items: normal; align-self: auto; alignment-baseline: auto; all: ; alt: \"\"; animation-delay: 0s; animation-direction: normal; animation-duration: 0s; animation-fill-mode: none; animation-iteration-count: 1; animation-name: none; animation-play-state: running; animation-timing-function: ease; aspect-ratio: auto; background-attachment: scroll; background-blend-mode: normal; background-clip: border-box; background-color: rgba(0, 0, 0, 0); background-image: none; background-origin: padding-box; background-position-x: 0%; background-position-y: 0%; background-repeat: repeat; background-size: auto; baseline-shift: baseline; block-size: 0px; border-block-end-color: rgb(255, 0, 0); border-block-end-style: none; border-block-end-width: 0px; border-block-start-color: rgb(255, 0, 0); border-block-start-style: none; border-block-start-width: 0px; border-bottom-color: rgb(255, 0, 0); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; border-bottom-style: none; border-bottom-width: 0px; border-collapse: separate; border-end-end-radius: 0px; border-end-start-radius: 0px; border-image-outset: 0px; border-image-repeat: stretch; border-image-slice: 100%; border-image-source: none; border-image-width: 1; border-inline-end-color: rgb(255, 0, 0); border-inline-end-style: none; border-inline-end-width: 0px; border-inline-start-color: rgb(255, 0, 0); border-inline-start-style: none; border-inline-start-width: 0px; border-left-color: rgb(255, 0, 0); border-left-style: none; border-left-width: 0px; border-right-color: rgb(255, 0, 0); border-right-style: none; border-right-width: 0px; border-start-end-radius: 0px; border-start-start-radius: 0px; border-top-color: rgb(255, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-top-style: none; border-top-width: 0px; bottom: auto; box-shadow: none; box-sizing: content-box; break-after: auto; break-before: auto; break-inside: auto; buffered-rendering: auto; caption-side: top; caret-color: rgb(255, 0, 0); clear: none; clip: auto; clip-path: none; clip-rule: nonzero; color: rgb(255, 0, 0); color-interpolation: sRGB; color-interpolation-filters: linearRGB; color-rendering: auto; color-scheme: auto; column-count: auto; column-fill: balance; column-gap: normal; column-rule-color: rgb(255, 0, 0); column-rule-style: none; column-rule-width: 0px; column-span: none; column-width: auto; content: ; counter-increment: none; counter-reset: none; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: block; dominant-baseline: auto; empty-cells: show; fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; filter: none; flex-basis: auto; flex-direction: row; flex-grow: 0; flex-shrink: 1; flex-wrap: nowrap; float: none; flood-color: rgb(0, 0, 0); flood-opacity: 1; font-family: -webkit-standard; font-feature-settings: normal; font-optical-sizing: auto; font-size: 13.333333015441895px; font-stretch: normal; font-style: normal; font-synthesis: style weight small-caps; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; font-weight: normal; glyph-orientation-horizontal: 0deg; glyph-orientation-vertical: auto; grid-auto-columns: auto; grid-auto-flow: row; grid-auto-rows: auto; grid-column-end: auto; grid-column-start: auto; grid-row-end: auto; grid-row-start: auto; grid-template-areas: none; grid-template-columns: none; grid-template-rows: none; hanging-punctuation: none; height: 0px; image-orientation: from-image; image-rendering: auto; inline-size: 784px; inset-block-end: auto; inset-block-start: auto; inset-inline-end: auto; inset-inline-start: auto; isolation: auto; justify-content: normal; justify-items: normal; justify-self: auto; kerning: 0; left: auto; letter-spacing: normal; lighting-color: rgb(255, 255, 255); line-break: auto; line-height: normal; list-style-image: none; list-style-position: outside; list-style-type: disc; margin-block-end: 0px; margin-block-start: 0px; margin-bottom: 0px; margin-inline-end: 0px; margin-inline-start: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; marker-end: none; marker-mid: none; marker-start: none; mask: none; mask-type: luminance; math-style: normal; max-block-size: none; max-height: none; max-inline-size: none; max-width: none; min-block-size: 0px; min-height: 0px; min-inline-size: 0px; min-width: 0px; mix-blend-mode: normal; object-fit: fill; object-position: 50% 50%; opacity: 1; order: 0; orphans: auto; outline-color: rgb(255, 0, 0); outline-offset: 0px; outline-style: none; outline-width: 0px; overflow-wrap: normal; overflow-x: visible; overflow-y: visible; overscroll-behavior-x: auto; overscroll-behavior-y: auto; padding-block-end: 0px; padding-block-start: 0px; padding-bottom: 0px; padding-inline-end: 0px; padding-inline-start: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; page-break-after: auto; page-break-before: auto; page-break-inside: auto; paint-order: normal; perspective: none; perspective-origin-x: ; perspective-origin-y: ; pointer-events: auto; position: static; quotes: auto; r: 0px; resize: none; right: auto; rotate: none; row-gap: normal; rx: auto; ry: auto; scale: none; scroll-behavior: auto; scroll-margin-block: 0px; scroll-margin-bottom: 0px; scroll-margin-inline: 0px; scroll-margin-left: 0px; scroll-margin-right: 0px; scroll-margin-top: 0px; scroll-padding-block: auto; scroll-padding-bottom: auto; scroll-padding-inline: auto; scroll-padding-left: auto; scroll-padding-right: auto; scroll-padding-top: auto; scroll-snap-align: none; scroll-snap-type: none; shape-image-threshold: 0; shape-margin: 0px; shape-outside: none; shape-rendering: auto; size: ; speak-as: normal; stop-color: rgb(0, 0, 0); stop-opacity: 1; stroke: none; stroke-color: rgba(0, 0, 0, 0); stroke-dasharray: none; stroke-dashoffset: 0px; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 1px; tab-size: 8; table-layout: auto; text-align: start; text-anchor: start; text-decoration: none; text-decoration-color: rgb(255, 0, 0); text-decoration-line: none; text-decoration-skip: auto; text-decoration-style: solid; text-decoration-thickness: auto; text-indent: 0px; text-orientation: mixed; text-overflow: clip; text-rendering: auto; text-shadow: none; text-transform: none; text-underline-offset: auto; text-underline-position: auto; top: auto; touch-action: auto; transform: none; transform-box: view-box; transform-origin-x: ; transform-origin-y: ; transform-origin-z: ; transform-style: flat; transition-delay: 0s; transition-duration: 0s; transition-property: all; transition-timing-function: ease; translate: none; unicode-bidi: normal; vector-effect: none; vertical-align: baseline; visibility: visible; white-space: normal; widows: auto; width: 784px; will-change: auto; word-break: normal; word-spacing: 0px; word-wrap: normal; writing-mode: horizontal-tb; x: 0px; y: 0px; z-index: auto; zoom: 1; -apple-color-filter: none; -apple-pay-button-style: black; -apple-pay-button-type: plain; -apple-trailing-word: auto; -webkit-appearance: none; -webkit-backdrop-filter: none; -webkit-backface-visibility: visible; -webkit-background-clip: border-box; -webkit-background-composite: source-over; -webkit-background-origin: padding-box; -webkit-background-size: auto; -webkit-border-fit: border; -webkit-border-horizontal-spacing: 0px; -webkit-border-image: none; -webkit-border-vertical-spacing: 0px; -webkit-box-align: stretch; -webkit-box-decoration-break: slice; -webkit-box-direction: normal; -webkit-box-flex: 0; -webkit-box-flex-group: 1; -webkit-box-lines: single; -webkit-box-ordinal-group: 1; -webkit-box-orient: horizontal; -webkit-box-pack: start; -webkit-box-reflect: none; -webkit-box-shadow: none; -webkit-column-axis: auto; -webkit-column-break-after: auto; -webkit-column-break-before: auto; -webkit-column-break-inside: auto; -webkit-column-progression: normal; -webkit-cursor-visibility: auto; -webkit-font-kerning: auto; -webkit-font-smoothing: auto; -webkit-hyphenate-character: auto; -webkit-hyphenate-limit-after: auto; -webkit-hyphenate-limit-before: auto; -webkit-hyphenate-limit-lines: no-limit; -webkit-hyphens: manual; -webkit-initial-letter: normal; -webkit-line-align: none; -webkit-line-box-contain: block inline replaced; -webkit-line-clamp: none; -webkit-line-grid: none; -webkit-line-snap: none; -webkit-locale: auto; -webkit-margin-after-collapse: collapse; -webkit-margin-before-collapse: collapse; -webkit-margin-bottom-collapse: collapse; -webkit-margin-top-collapse: collapse; -webkit-mask-box-image: none; -webkit-mask-box-image-outset: 0px; -webkit-mask-box-image-repeat: stretch; -webkit-mask-box-image-slice: 0 fill; -webkit-mask-box-image-source: none; -webkit-mask-box-image-width: auto; -webkit-mask-clip: border-box; -webkit-mask-composite: source-over; -webkit-mask-image: none; -webkit-mask-origin: border-box; -webkit-mask-position-x: 0%; -webkit-mask-position-y: 0%; -webkit-mask-repeat: repeat; -webkit-mask-size: auto; -webkit-mask-source-type: alpha; -webkit-nbsp-mode: normal; -webkit-print-color-adjust: economy; -webkit-rtl-ordering: logical; -webkit-ruby-position: before; -webkit-text-combine: none; -webkit-text-emphasis-color: rgb(255, 0, 0); -webkit-text-emphasis-position: over right; -webkit-text-emphasis-style: none; -webkit-text-fill-color: rgb(255, 0, 0); -webkit-text-orientation: mixed; -webkit-text-security: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-color: rgb(255, 0, 0); -webkit-text-stroke-width: 0px; -webkit-text-zoom: normal; -webkit-transform-style: flat; -webkit-user-drag: auto; -webkit-user-modify: read-only; -webkit-user-select: text;"
     10FAIL cssText on computed style declaration returns the empty string assert_equals: cssText is empty expected "" but got "align-content: normal; align-items: normal; align-self: auto; alignment-baseline: auto; all: ; alt: \"\"; animation-delay: 0s; animation-direction: normal; animation-duration: 0s; animation-fill-mode: none; animation-iteration-count: 1; animation-name: none; animation-play-state: running; animation-timing-function: ease; aspect-ratio: auto; background-attachment: scroll; background-blend-mode: normal; background-clip: border-box; background-color: rgba(0, 0, 0, 0); background-image: none; background-origin: padding-box; background-position-x: 0%; background-position-y: 0%; background-repeat: repeat; background-size: auto; baseline-shift: baseline; block-size: 0px; border-block-end-color: rgb(255, 0, 0); border-block-end-style: none; border-block-end-width: 0px; border-block-start-color: rgb(255, 0, 0); border-block-start-style: none; border-block-start-width: 0px; border-bottom-color: rgb(255, 0, 0); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; border-bottom-style: none; border-bottom-width: 0px; border-collapse: separate; border-end-end-radius: 0px; border-end-start-radius: 0px; border-image-outset: 0px; border-image-repeat: stretch; border-image-slice: 100%; border-image-source: none; border-image-width: 1; border-inline-end-color: rgb(255, 0, 0); border-inline-end-style: none; border-inline-end-width: 0px; border-inline-start-color: rgb(255, 0, 0); border-inline-start-style: none; border-inline-start-width: 0px; border-left-color: rgb(255, 0, 0); border-left-style: none; border-left-width: 0px; border-right-color: rgb(255, 0, 0); border-right-style: none; border-right-width: 0px; border-start-end-radius: 0px; border-start-start-radius: 0px; border-top-color: rgb(255, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-top-style: none; border-top-width: 0px; bottom: auto; box-shadow: none; box-sizing: content-box; break-after: auto; break-before: auto; break-inside: auto; buffered-rendering: auto; caption-side: top; caret-color: rgb(255, 0, 0); clear: none; clip: auto; clip-path: none; clip-rule: nonzero; color: rgb(255, 0, 0); color-interpolation: sRGB; color-interpolation-filters: linearRGB; color-rendering: auto; color-scheme: auto; column-count: auto; column-fill: balance; column-gap: normal; column-rule-color: rgb(255, 0, 0); column-rule-style: none; column-rule-width: 0px; column-span: none; column-width: auto; content: ; counter-increment: none; counter-reset: none; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: block; dominant-baseline: auto; empty-cells: show; fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; filter: none; flex-basis: auto; flex-direction: row; flex-grow: 0; flex-shrink: 1; flex-wrap: nowrap; float: none; flood-color: rgb(0, 0, 0); flood-opacity: 1; font-family: -webkit-standard; font-feature-settings: normal; font-optical-sizing: auto; font-size: 13.333333015441895px; font-stretch: normal; font-style: normal; font-synthesis: style weight small-caps; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; font-weight: normal; glyph-orientation-horizontal: 0deg; glyph-orientation-vertical: auto; grid-auto-columns: auto; grid-auto-flow: row; grid-auto-rows: auto; grid-column-end: auto; grid-column-start: auto; grid-row-end: auto; grid-row-start: auto; grid-template-areas: none; grid-template-columns: none; grid-template-rows: none; hanging-punctuation: none; height: 0px; image-orientation: from-image; image-rendering: auto; inline-size: 784px; inset-block-end: auto; inset-block-start: auto; inset-inline-end: auto; inset-inline-start: auto; isolation: auto; justify-content: normal; justify-items: normal; justify-self: auto; kerning: 0; left: auto; letter-spacing: normal; lighting-color: rgb(255, 255, 255); line-break: auto; line-height: normal; list-style-image: none; list-style-position: outside; list-style-type: disc; margin-block-end: 0px; margin-block-start: 0px; margin-bottom: 0px; margin-inline-end: 0px; margin-inline-start: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; marker-end: none; marker-mid: none; marker-start: none; mask: none; mask-type: luminance; math-style: normal; max-block-size: none; max-height: none; max-inline-size: none; max-width: none; min-block-size: 0px; min-height: 0px; min-inline-size: 0px; min-width: 0px; mix-blend-mode: normal; object-fit: fill; object-position: 50% 50%; opacity: 1; order: 0; orphans: auto; outline-color: rgb(255, 0, 0); outline-offset: 0px; outline-style: none; outline-width: 0px; overflow-wrap: normal; overflow-x: visible; overflow-y: visible; overscroll-behavior-x: auto; overscroll-behavior-y: auto; padding-block-end: 0px; padding-block-start: 0px; padding-bottom: 0px; padding-inline-end: 0px; padding-inline-start: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; page-break-after: auto; page-break-before: auto; page-break-inside: auto; paint-order: normal; perspective: none; perspective-origin-x: ; perspective-origin-y: ; pointer-events: auto; position: static; quotes: auto; r: 0px; resize: none; right: auto; rotate: none; row-gap: normal; rx: auto; ry: auto; scale: none; scroll-behavior: auto; scroll-margin-block: 0px; scroll-margin-bottom: 0px; scroll-margin-inline: 0px; scroll-margin-left: 0px; scroll-margin-right: 0px; scroll-margin-top: 0px; scroll-padding-block: auto; scroll-padding-bottom: auto; scroll-padding-inline: auto; scroll-padding-left: auto; scroll-padding-right: auto; scroll-padding-top: auto; scroll-snap-align: none; scroll-snap-stop: normal; scroll-snap-type: none; shape-image-threshold: 0; shape-margin: 0px; shape-outside: none; shape-rendering: auto; size: ; speak-as: normal; stop-color: rgb(0, 0, 0); stop-opacity: 1; stroke: none; stroke-color: rgba(0, 0, 0, 0); stroke-dasharray: none; stroke-dashoffset: 0px; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 1px; tab-size: 8; table-layout: auto; text-align: start; text-anchor: start; text-decoration: none; text-decoration-color: rgb(255, 0, 0); text-decoration-line: none; text-decoration-skip: auto; text-decoration-style: solid; text-decoration-thickness: auto; text-indent: 0px; text-orientation: mixed; text-overflow: clip; text-rendering: auto; text-shadow: none; text-transform: none; text-underline-offset: auto; text-underline-position: auto; top: auto; touch-action: auto; transform: none; transform-box: view-box; transform-origin-x: ; transform-origin-y: ; transform-origin-z: ; transform-style: flat; transition-delay: 0s; transition-duration: 0s; transition-property: all; transition-timing-function: ease; translate: none; unicode-bidi: normal; vector-effect: none; vertical-align: baseline; visibility: visible; white-space: normal; widows: auto; width: 784px; will-change: auto; word-break: normal; word-spacing: 0px; word-wrap: normal; writing-mode: horizontal-tb; x: 0px; y: 0px; z-index: auto; zoom: 1; -apple-color-filter: none; -apple-pay-button-style: black; -apple-pay-button-type: plain; -apple-trailing-word: auto; -webkit-appearance: none; -webkit-backdrop-filter: none; -webkit-backface-visibility: visible; -webkit-background-clip: border-box; -webkit-background-composite: source-over; -webkit-background-origin: padding-box; -webkit-background-size: auto; -webkit-border-fit: border; -webkit-border-horizontal-spacing: 0px; -webkit-border-image: none; -webkit-border-vertical-spacing: 0px; -webkit-box-align: stretch; -webkit-box-decoration-break: slice; -webkit-box-direction: normal; -webkit-box-flex: 0; -webkit-box-flex-group: 1; -webkit-box-lines: single; -webkit-box-ordinal-group: 1; -webkit-box-orient: horizontal; -webkit-box-pack: start; -webkit-box-reflect: none; -webkit-box-shadow: none; -webkit-column-axis: auto; -webkit-column-break-after: auto; -webkit-column-break-before: auto; -webkit-column-break-inside: auto; -webkit-column-progression: normal; -webkit-cursor-visibility: auto; -webkit-font-kerning: auto; -webkit-font-smoothing: auto; -webkit-hyphenate-character: auto; -webkit-hyphenate-limit-after: auto; -webkit-hyphenate-limit-before: auto; -webkit-hyphenate-limit-lines: no-limit; -webkit-hyphens: manual; -webkit-initial-letter: normal; -webkit-line-align: none; -webkit-line-box-contain: block inline replaced; -webkit-line-clamp: none; -webkit-line-grid: none; -webkit-line-snap: none; -webkit-locale: auto; -webkit-margin-after-collapse: collapse; -webkit-margin-before-collapse: collapse; -webkit-margin-bottom-collapse: collapse; -webkit-margin-top-collapse: collapse; -webkit-mask-box-image: none; -webkit-mask-box-image-outset: 0px; -webkit-mask-box-image-repeat: stretch; -webkit-mask-box-image-slice: 0 fill; -webkit-mask-box-image-source: none; -webkit-mask-box-image-width: auto; -webkit-mask-clip: border-box; -webkit-mask-composite: source-over; -webkit-mask-image: none; -webkit-mask-origin: border-box; -webkit-mask-position-x: 0%; -webkit-mask-position-y: 0%; -webkit-mask-repeat: repeat; -webkit-mask-size: auto; -webkit-mask-source-type: alpha; -webkit-nbsp-mode: normal; -webkit-print-color-adjust: economy; -webkit-rtl-ordering: logical; -webkit-ruby-position: before; -webkit-text-combine: none; -webkit-text-emphasis-color: rgb(255, 0, 0); -webkit-text-emphasis-position: over right; -webkit-text-emphasis-style: none; -webkit-text-fill-color: rgb(255, 0, 0); -webkit-text-orientation: mixed; -webkit-text-security: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-color: rgb(255, 0, 0); -webkit-text-stroke-width: 0px; -webkit-text-zoom: normal; -webkit-transform-style: flat; -webkit-user-drag: auto; -webkit-user-modify: read-only; -webkit-user-select: text;"
    1111
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-type-on-root-element-expected.txt

    r271480 r272610  
    11
    2 FAIL The scroll-snap-type on the root element is applied assert_equals: expected 500 but got 800
     2PASS The scroll-snap-type on the root element is applied
    33FAIL The writing-mode (vertical-lr) on the body is used assert_equals: inline should snap expected 500 but got 800
    44PASS The writing-mode (horizontal-tb) on the body is used
  • trunk/LayoutTests/platform/ios-wk2/imported/w3c/web-platform-tests/css/cssom/cssstyledeclaration-csstext-expected.txt

    r272366 r272610  
    88PASS whitespaces in value
    99PASS invalid property does not appear
    10 FAIL cssText on computed style declaration returns the empty string assert_equals: cssText is empty expected "" but got "align-content: normal; align-items: normal; align-self: auto; alignment-baseline: auto; all: ; alt: \"\"; animation-delay: 0s; animation-direction: normal; animation-duration: 0s; animation-fill-mode: none; animation-iteration-count: 1; animation-name: none; animation-play-state: running; animation-timing-function: ease; aspect-ratio: auto; background-attachment: scroll; background-blend-mode: normal; background-clip: border-box; background-color: rgba(0, 0, 0, 0); background-image: none; background-origin: padding-box; background-position-x: 0%; background-position-y: 0%; background-repeat: repeat; background-size: auto; baseline-shift: baseline; block-size: 0px; border-block-end-color: rgb(255, 0, 0); border-block-end-style: none; border-block-end-width: 0px; border-block-start-color: rgb(255, 0, 0); border-block-start-style: none; border-block-start-width: 0px; border-bottom-color: rgb(255, 0, 0); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; border-bottom-style: none; border-bottom-width: 0px; border-collapse: separate; border-end-end-radius: 0px; border-end-start-radius: 0px; border-image-outset: 0px; border-image-repeat: stretch; border-image-slice: 100%; border-image-source: none; border-image-width: 1; border-inline-end-color: rgb(255, 0, 0); border-inline-end-style: none; border-inline-end-width: 0px; border-inline-start-color: rgb(255, 0, 0); border-inline-start-style: none; border-inline-start-width: 0px; border-left-color: rgb(255, 0, 0); border-left-style: none; border-left-width: 0px; border-right-color: rgb(255, 0, 0); border-right-style: none; border-right-width: 0px; border-start-end-radius: 0px; border-start-start-radius: 0px; border-top-color: rgb(255, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-top-style: none; border-top-width: 0px; bottom: auto; box-shadow: none; box-sizing: content-box; break-after: auto; break-before: auto; break-inside: auto; buffered-rendering: auto; caption-side: top; caret-color: rgb(255, 0, 0); clear: none; clip: auto; clip-path: none; clip-rule: nonzero; color: rgb(255, 0, 0); color-interpolation: sRGB; color-interpolation-filters: linearRGB; color-rendering: auto; color-scheme: auto; column-count: auto; column-fill: balance; column-gap: normal; column-rule-color: rgb(255, 0, 0); column-rule-style: none; column-rule-width: 0px; column-span: none; column-width: auto; content: ; counter-increment: none; counter-reset: none; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: block; dominant-baseline: auto; empty-cells: show; fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; filter: none; flex-basis: auto; flex-direction: row; flex-grow: 0; flex-shrink: 1; flex-wrap: nowrap; float: none; flood-color: rgb(0, 0, 0); flood-opacity: 1; font-family: -webkit-standard; font-feature-settings: normal; font-optical-sizing: auto; font-size: 13.333333015441895px; font-stretch: normal; font-style: normal; font-synthesis: style weight small-caps; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; font-weight: normal; glyph-orientation-horizontal: 0deg; glyph-orientation-vertical: auto; grid-auto-columns: auto; grid-auto-flow: row; grid-auto-rows: auto; grid-column-end: auto; grid-column-start: auto; grid-row-end: auto; grid-row-start: auto; grid-template-areas: none; grid-template-columns: none; grid-template-rows: none; hanging-punctuation: none; height: 0px; image-orientation: from-image; image-rendering: auto; inline-size: 784px; inset-block-end: auto; inset-block-start: auto; inset-inline-end: auto; inset-inline-start: auto; isolation: auto; justify-content: normal; justify-items: normal; justify-self: auto; kerning: 0; left: auto; letter-spacing: normal; lighting-color: rgb(255, 255, 255); line-break: auto; line-height: normal; list-style-image: none; list-style-position: outside; list-style-type: disc; margin-block-end: 0px; margin-block-start: 0px; margin-bottom: 0px; margin-inline-end: 0px; margin-inline-start: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; marker-end: none; marker-mid: none; marker-start: none; mask: none; mask-type: luminance; math-style: normal; max-block-size: none; max-height: none; max-inline-size: none; max-width: none; min-block-size: 0px; min-height: 0px; min-inline-size: 0px; min-width: 0px; mix-blend-mode: normal; object-fit: fill; object-position: 50% 50%; opacity: 1; order: 0; orphans: auto; outline-color: rgb(255, 0, 0); outline-offset: 0px; outline-style: none; outline-width: 0px; overflow-wrap: normal; overflow-x: visible; overflow-y: visible; overscroll-behavior-x: auto; overscroll-behavior-y: auto; padding-block-end: 0px; padding-block-start: 0px; padding-bottom: 0px; padding-inline-end: 0px; padding-inline-start: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; page-break-after: auto; page-break-before: auto; page-break-inside: auto; paint-order: normal; perspective: none; perspective-origin-x: ; perspective-origin-y: ; pointer-events: auto; position: static; quotes: auto; r: 0px; resize: none; right: auto; rotate: none; row-gap: normal; rx: auto; ry: auto; scale: none; scroll-behavior: auto; scroll-margin-block: 0px; scroll-margin-bottom: 0px; scroll-margin-inline: 0px; scroll-margin-left: 0px; scroll-margin-right: 0px; scroll-margin-top: 0px; scroll-padding-block: auto; scroll-padding-bottom: auto; scroll-padding-inline: auto; scroll-padding-left: auto; scroll-padding-right: auto; scroll-padding-top: auto; scroll-snap-align: none; scroll-snap-type: none; shape-image-threshold: 0; shape-margin: 0px; shape-outside: none; shape-rendering: auto; size: ; speak-as: normal; stop-color: rgb(0, 0, 0); stop-opacity: 1; stroke: none; stroke-color: rgba(0, 0, 0, 0); stroke-dasharray: none; stroke-dashoffset: 0px; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 1px; tab-size: 8; table-layout: auto; text-align: start; text-anchor: start; text-decoration: none; text-decoration-color: rgb(255, 0, 0); text-decoration-line: none; text-decoration-skip: auto; text-decoration-style: solid; text-decoration-thickness: auto; text-indent: 0px; text-orientation: mixed; text-overflow: clip; text-rendering: auto; text-shadow: none; text-transform: none; text-underline-offset: auto; text-underline-position: auto; top: auto; touch-action: auto; transform: none; transform-box: view-box; transform-origin-x: ; transform-origin-y: ; transform-origin-z: ; transform-style: flat; transition-delay: 0s; transition-duration: 0s; transition-property: all; transition-timing-function: ease; translate: none; unicode-bidi: normal; vector-effect: none; vertical-align: baseline; visibility: visible; white-space: normal; widows: auto; width: 784px; will-change: auto; word-break: normal; word-spacing: 0px; word-wrap: normal; writing-mode: horizontal-tb; x: 0px; y: 0px; z-index: auto; zoom: 1; -apple-color-filter: none; -apple-pay-button-style: black; -apple-pay-button-type: plain; -apple-trailing-word: auto; -webkit-appearance: none; -webkit-backdrop-filter: none; -webkit-backface-visibility: visible; -webkit-background-clip: border-box; -webkit-background-composite: source-over; -webkit-background-origin: padding-box; -webkit-background-size: auto; -webkit-border-fit: border; -webkit-border-horizontal-spacing: 0px; -webkit-border-image: none; -webkit-border-vertical-spacing: 0px; -webkit-box-align: stretch; -webkit-box-decoration-break: slice; -webkit-box-direction: normal; -webkit-box-flex: 0; -webkit-box-flex-group: 1; -webkit-box-lines: single; -webkit-box-ordinal-group: 1; -webkit-box-orient: horizontal; -webkit-box-pack: start; -webkit-box-reflect: none; -webkit-box-shadow: none; -webkit-column-axis: auto; -webkit-column-break-after: auto; -webkit-column-break-before: auto; -webkit-column-break-inside: auto; -webkit-column-progression: normal; -webkit-cursor-visibility: auto; -webkit-font-kerning: auto; -webkit-font-smoothing: auto; -webkit-hyphenate-character: auto; -webkit-hyphenate-limit-after: auto; -webkit-hyphenate-limit-before: auto; -webkit-hyphenate-limit-lines: no-limit; -webkit-hyphens: manual; -webkit-initial-letter: normal; -webkit-line-align: none; -webkit-line-box-contain: block inline replaced; -webkit-line-clamp: none; -webkit-line-grid: none; -webkit-line-snap: none; -webkit-locale: auto; -webkit-margin-after-collapse: collapse; -webkit-margin-before-collapse: collapse; -webkit-margin-bottom-collapse: collapse; -webkit-margin-top-collapse: collapse; -webkit-mask-box-image: none; -webkit-mask-box-image-outset: 0px; -webkit-mask-box-image-repeat: stretch; -webkit-mask-box-image-slice: 0 fill; -webkit-mask-box-image-source: none; -webkit-mask-box-image-width: auto; -webkit-mask-clip: border-box; -webkit-mask-composite: source-over; -webkit-mask-image: none; -webkit-mask-origin: border-box; -webkit-mask-position-x: 0%; -webkit-mask-position-y: 0%; -webkit-mask-repeat: repeat; -webkit-mask-size: auto; -webkit-mask-source-type: alpha; -webkit-nbsp-mode: normal; -webkit-overflow-scrolling: auto; -webkit-print-color-adjust: economy; -webkit-rtl-ordering: logical; -webkit-ruby-position: before; -webkit-text-combine: none; -webkit-text-emphasis-color: rgb(255, 0, 0); -webkit-text-emphasis-position: over right; -webkit-text-emphasis-style: none; -webkit-text-fill-color: rgb(255, 0, 0); -webkit-text-orientation: mixed; -webkit-text-security: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-color: rgb(255, 0, 0); -webkit-text-stroke-width: 0px; -webkit-text-zoom: normal; -webkit-touch-callout: default; -webkit-transform-style: flat; -webkit-user-drag: auto; -webkit-user-modify: read-only; -webkit-user-select: text;"
     10FAIL cssText on computed style declaration returns the empty string assert_equals: cssText is empty expected "" but got "align-content: normal; align-items: normal; align-self: auto; alignment-baseline: auto; all: ; alt: \"\"; animation-delay: 0s; animation-direction: normal; animation-duration: 0s; animation-fill-mode: none; animation-iteration-count: 1; animation-name: none; animation-play-state: running; animation-timing-function: ease; aspect-ratio: auto; background-attachment: scroll; background-blend-mode: normal; background-clip: border-box; background-color: rgba(0, 0, 0, 0); background-image: none; background-origin: padding-box; background-position-x: 0%; background-position-y: 0%; background-repeat: repeat; background-size: auto; baseline-shift: baseline; block-size: 0px; border-block-end-color: rgb(255, 0, 0); border-block-end-style: none; border-block-end-width: 0px; border-block-start-color: rgb(255, 0, 0); border-block-start-style: none; border-block-start-width: 0px; border-bottom-color: rgb(255, 0, 0); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px; border-bottom-style: none; border-bottom-width: 0px; border-collapse: separate; border-end-end-radius: 0px; border-end-start-radius: 0px; border-image-outset: 0px; border-image-repeat: stretch; border-image-slice: 100%; border-image-source: none; border-image-width: 1; border-inline-end-color: rgb(255, 0, 0); border-inline-end-style: none; border-inline-end-width: 0px; border-inline-start-color: rgb(255, 0, 0); border-inline-start-style: none; border-inline-start-width: 0px; border-left-color: rgb(255, 0, 0); border-left-style: none; border-left-width: 0px; border-right-color: rgb(255, 0, 0); border-right-style: none; border-right-width: 0px; border-start-end-radius: 0px; border-start-start-radius: 0px; border-top-color: rgb(255, 0, 0); border-top-left-radius: 0px; border-top-right-radius: 0px; border-top-style: none; border-top-width: 0px; bottom: auto; box-shadow: none; box-sizing: content-box; break-after: auto; break-before: auto; break-inside: auto; buffered-rendering: auto; caption-side: top; caret-color: rgb(255, 0, 0); clear: none; clip: auto; clip-path: none; clip-rule: nonzero; color: rgb(255, 0, 0); color-interpolation: sRGB; color-interpolation-filters: linearRGB; color-rendering: auto; color-scheme: auto; column-count: auto; column-fill: balance; column-gap: normal; column-rule-color: rgb(255, 0, 0); column-rule-style: none; column-rule-width: 0px; column-span: none; column-width: auto; content: ; counter-increment: none; counter-reset: none; cursor: auto; cx: 0px; cy: 0px; direction: ltr; display: block; dominant-baseline: auto; empty-cells: show; fill: rgb(0, 0, 0); fill-opacity: 1; fill-rule: nonzero; filter: none; flex-basis: auto; flex-direction: row; flex-grow: 0; flex-shrink: 1; flex-wrap: nowrap; float: none; flood-color: rgb(0, 0, 0); flood-opacity: 1; font-family: -webkit-standard; font-feature-settings: normal; font-optical-sizing: auto; font-size: 13.333333015441895px; font-stretch: normal; font-style: normal; font-synthesis: style weight small-caps; font-variant-alternates: normal; font-variant-caps: normal; font-variant-east-asian: normal; font-variant-ligatures: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; font-weight: normal; glyph-orientation-horizontal: 0deg; glyph-orientation-vertical: auto; grid-auto-columns: auto; grid-auto-flow: row; grid-auto-rows: auto; grid-column-end: auto; grid-column-start: auto; grid-row-end: auto; grid-row-start: auto; grid-template-areas: none; grid-template-columns: none; grid-template-rows: none; hanging-punctuation: none; height: 0px; image-orientation: from-image; image-rendering: auto; inline-size: 784px; inset-block-end: auto; inset-block-start: auto; inset-inline-end: auto; inset-inline-start: auto; isolation: auto; justify-content: normal; justify-items: normal; justify-self: auto; kerning: 0; left: auto; letter-spacing: normal; lighting-color: rgb(255, 255, 255); line-break: auto; line-height: normal; list-style-image: none; list-style-position: outside; list-style-type: disc; margin-block-end: 0px; margin-block-start: 0px; margin-bottom: 0px; margin-inline-end: 0px; margin-inline-start: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; marker-end: none; marker-mid: none; marker-start: none; mask: none; mask-type: luminance; math-style: normal; max-block-size: none; max-height: none; max-inline-size: none; max-width: none; min-block-size: 0px; min-height: 0px; min-inline-size: 0px; min-width: 0px; mix-blend-mode: normal; object-fit: fill; object-position: 50% 50%; opacity: 1; order: 0; orphans: auto; outline-color: rgb(255, 0, 0); outline-offset: 0px; outline-style: none; outline-width: 0px; overflow-wrap: normal; overflow-x: visible; overflow-y: visible; overscroll-behavior-x: auto; overscroll-behavior-y: auto; padding-block-end: 0px; padding-block-start: 0px; padding-bottom: 0px; padding-inline-end: 0px; padding-inline-start: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; page-break-after: auto; page-break-before: auto; page-break-inside: auto; paint-order: normal; perspective: none; perspective-origin-x: ; perspective-origin-y: ; pointer-events: auto; position: static; quotes: auto; r: 0px; resize: none; right: auto; rotate: none; row-gap: normal; rx: auto; ry: auto; scale: none; scroll-behavior: auto; scroll-margin-block: 0px; scroll-margin-bottom: 0px; scroll-margin-inline: 0px; scroll-margin-left: 0px; scroll-margin-right: 0px; scroll-margin-top: 0px; scroll-padding-block: auto; scroll-padding-bottom: auto; scroll-padding-inline: auto; scroll-padding-left: auto; scroll-padding-right: auto; scroll-padding-top: auto; scroll-snap-align: none; scroll-snap-stop: normal; scroll-snap-type: none; shape-image-threshold: 0; shape-margin: 0px; shape-outside: none; shape-rendering: auto; size: ; speak-as: normal; stop-color: rgb(0, 0, 0); stop-opacity: 1; stroke: none; stroke-color: rgba(0, 0, 0, 0); stroke-dasharray: none; stroke-dashoffset: 0px; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 1px; tab-size: 8; table-layout: auto; text-align: start; text-anchor: start; text-decoration: none; text-decoration-color: rgb(255, 0, 0); text-decoration-line: none; text-decoration-skip: auto; text-decoration-style: solid; text-decoration-thickness: auto; text-indent: 0px; text-orientation: mixed; text-overflow: clip; text-rendering: auto; text-shadow: none; text-transform: none; text-underline-offset: auto; text-underline-position: auto; top: auto; touch-action: auto; transform: none; transform-box: view-box; transform-origin-x: ; transform-origin-y: ; transform-origin-z: ; transform-style: flat; transition-delay: 0s; transition-duration: 0s; transition-property: all; transition-timing-function: ease; translate: none; unicode-bidi: normal; vector-effect: none; vertical-align: baseline; visibility: visible; white-space: normal; widows: auto; width: 784px; will-change: auto; word-break: normal; word-spacing: 0px; word-wrap: normal; writing-mode: horizontal-tb; x: 0px; y: 0px; z-index: auto; zoom: 1; -apple-color-filter: none; -apple-pay-button-style: black; -apple-pay-button-type: plain; -apple-trailing-word: auto; -webkit-appearance: none; -webkit-backdrop-filter: none; -webkit-backface-visibility: visible; -webkit-background-clip: border-box; -webkit-background-composite: source-over; -webkit-background-origin: padding-box; -webkit-background-size: auto; -webkit-border-fit: border; -webkit-border-horizontal-spacing: 0px; -webkit-border-image: none; -webkit-border-vertical-spacing: 0px; -webkit-box-align: stretch; -webkit-box-decoration-break: slice; -webkit-box-direction: normal; -webkit-box-flex: 0; -webkit-box-flex-group: 1; -webkit-box-lines: single; -webkit-box-ordinal-group: 1; -webkit-box-orient: horizontal; -webkit-box-pack: start; -webkit-box-reflect: none; -webkit-box-shadow: none; -webkit-column-axis: auto; -webkit-column-break-after: auto; -webkit-column-break-before: auto; -webkit-column-break-inside: auto; -webkit-column-progression: normal; -webkit-cursor-visibility: auto; -webkit-font-kerning: auto; -webkit-font-smoothing: auto; -webkit-hyphenate-character: auto; -webkit-hyphenate-limit-after: auto; -webkit-hyphenate-limit-before: auto; -webkit-hyphenate-limit-lines: no-limit; -webkit-hyphens: manual; -webkit-initial-letter: normal; -webkit-line-align: none; -webkit-line-box-contain: block inline replaced; -webkit-line-clamp: none; -webkit-line-grid: none; -webkit-line-snap: none; -webkit-locale: auto; -webkit-margin-after-collapse: collapse; -webkit-margin-before-collapse: collapse; -webkit-margin-bottom-collapse: collapse; -webkit-margin-top-collapse: collapse; -webkit-mask-box-image: none; -webkit-mask-box-image-outset: 0px; -webkit-mask-box-image-repeat: stretch; -webkit-mask-box-image-slice: 0 fill; -webkit-mask-box-image-source: none; -webkit-mask-box-image-width: auto; -webkit-mask-clip: border-box; -webkit-mask-composite: source-over; -webkit-mask-image: none; -webkit-mask-origin: border-box; -webkit-mask-position-x: 0%; -webkit-mask-position-y: 0%; -webkit-mask-repeat: repeat; -webkit-mask-size: auto; -webkit-mask-source-type: alpha; -webkit-nbsp-mode: normal; -webkit-overflow-scrolling: auto; -webkit-print-color-adjust: economy; -webkit-rtl-ordering: logical; -webkit-ruby-position: before; -webkit-text-combine: none; -webkit-text-emphasis-color: rgb(255, 0, 0); -webkit-text-emphasis-position: over right; -webkit-text-emphasis-style: none; -webkit-text-fill-color: rgb(255, 0, 0); -webkit-text-orientation: mixed; -webkit-text-security: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-color: rgb(255, 0, 0); -webkit-text-stroke-width: 0px; -webkit-text-zoom: normal; -webkit-touch-callout: default; -webkit-transform-style: flat; -webkit-user-drag: auto; -webkit-user-modify: read-only; -webkit-user-select: text;"
    1111
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r272490 r272610  
    451451# WebKit1 frames use native scrollbars causing these tests to fail.
    452452imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-target-padding-001.html [ ImageOnlyFailure ]
     453imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-change.html [ Failure ]
    453454css3/scroll-snap/scroll-padding-mainframe-paging.html [ Failure ]
    454455
  • trunk/Source/WebCore/ChangeLog

    r272607 r272610  
     12021-02-09  Martin Robinson  <mrobinson@webkit.org>
     2
     3        Implement scroll-snap-stop for scroll snapping
     4        https://bugs.webkit.org/show_bug.cgi?id=197744
     5        <rdar://problem/50708356>
     6
     7        Reviewed by Simon Fraser.
     8
     9        No new tests. This is tested by existing, imported WPT tests:
     10            imported/w3c/web-platform-tests/css/css-scroll-snap/inheritance-expected.txt:
     11            imported/w3c/web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-computed-expected.txt:
     12            imported/w3c/web-platform-tests/css/css-scroll-snap/parsing/scroll-snap-stop-valid-expected.txt:
     13            imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-change-expected.txt:
     14            imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-stop-expected.txt:
     15            imported/w3c/web-platform-tests/css/css-scroll-snap/scroll-snap-type-on-root-element-expected.txt:
     16
     17        * css/CSSComputedStyleDeclaration.cpp:
     18        (WebCore::ComputedStyleExtractor::valueForPropertyInStyle): Add support the new CSS property.
     19        * css/CSSPrimitiveValueMappings.h:
     20        (WebCore::CSSPrimitiveValue::operator ScrollSnapAxisAlignType const): Ditto.
     21        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue): Ditto.
     22        (WebCore::CSSPrimitiveValue::operator ScrollSnapStop const): ditto.
     23        * css/CSSProperties.json: Ditto.
     24        * css/parser/CSSPropertyParser.cpp:
     25        (WebCore::CSSPropertyParser::parseSingleValue): Ditto.
     26        * page/scrolling/ScrollSnapOffsetsInfo.cpp:
     27        (WebCore::indicesOfNearestSnapOffsets): Update to accept SnapOffset instead of a raw
     28        value.
     29        (WebCore::findFirstSnapStopOffsetBetweenOriginAndDestination): Added this helper which looks
     30        between the scroll origin and destination to find a candidate scroll offset with ScrollSnapStop::Always.
     31        This offset will always be chosen for directional scrolls.
     32        (WebCore::closestSnapOffsetWithOffsetsAndRanges): Use new helper to find offsets with ScrollSnapStop::Always.
     33        (WebCore::computeAxisProximitySnapOffsetRanges): Deal with SnapOffset instead of raw values.
     34        (WebCore::updateSnapOffsetsForScrollableArea): Ditto.
     35        (WebCore::convertOffsetInfo): Ditto.
     36        * page/scrolling/ScrollSnapOffsetsInfo.h:
     37        (WebCore::ScrollSnapOffsetsInfo::offsetsForAxis const): Ditto.
     38        (WebCore::operator<<): Consolidated all TextStream implementations here instead of repeating
     39        them throughout the code.
     40        * platform/ScrollableArea.cpp:
     41        (WebCore::ScrollableArea::setScrollSnapOffsetInfo): Set the scroll snap offset info all at once.
     42        (WebCore::ScrollableArea::clearSnapOffsets): We no longer clear horizontal and vertical offsets separately.
     43        (WebCore::ScrollableArea::nearestActiveSnapPoint): Access the offset value.
     44        * platform/ScrollableArea.h:
     45        * platform/cocoa/ScrollController.mm:
     46        (WebCore::ScrollController::setNearestScrollSnapIndexForAxisAndOffset): Ditto.
     47        * platform/cocoa/ScrollSnapAnimatorState.h:
     48        (WebCore::ScrollSnapAnimatorState::snapOffsetsForAxis const): Deal with SnapOffsets instead of raw values.
     49        (WebCore::ScrollSnapAnimatorState::setSnapOffsetsAndPositionRangesForAxis): Ditto.
     50        * platform/cocoa/ScrollSnapAnimatorState.mm:
     51        * rendering/RenderLayerModelObject.cpp:
     52        (WebCore::RenderLayerModelObject::styleDidChange): Update scroll snap information when the `scroll-snap-stop`
     53        property changes. Also ensure that we update everything for FrameView's instead of only some properties.
     54        * rendering/style/RenderStyle.cpp:
     55        (WebCore::RenderStyle::initialScrollSnapStop): Added for new CSS property.
     56        (WebCore::RenderStyle::scrollSnapStop const): Ditto.
     57        (WebCore::RenderStyle::setScrollSnapStop): Ditto.
     58        * rendering/style/RenderStyle.h:
     59        * rendering/style/RenderStyleConstants.cpp:
     60        (WebCore::operator<<): Ditto.
     61        * rendering/style/RenderStyleConstants.h:
     62        * rendering/style/StyleRareNonInheritedData.h:
     63        * style/StyleBuilderConverter.h:
     64        (WebCore::Style::BuilderConverter::convertScrollSnapStop): Ditto.
     65        * testing/Internals.cpp:
     66        (WebCore::appendOffsets): Handle the case where we are printing an offset with ScrollSnapStop::Always.
     67
    1682021-02-09  Chris Dumez  <cdumez@apple.com>
    269
  • trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp

    r272366 r272610  
    38483848            return getCSSPropertyValuesFor2SidesShorthand(scrollPaddingInlineShorthand());
    38493849#if ENABLE(CSS_SCROLL_SNAP)
     3850        case CSSPropertyScrollSnapAlign:
     3851            return valueForScrollSnapAlignment(style.scrollSnapAlign());
     3852        case CSSPropertyScrollSnapStop:
     3853            return CSSPrimitiveValue::create(style.scrollSnapStop());
    38503854        case CSSPropertyScrollSnapType:
    38513855            return valueForScrollSnapType(style.scrollSnapType());
    3852         case CSSPropertyScrollSnapAlign:
    3853             return valueForScrollSnapAlignment(style.scrollSnapAlign());
    38543856#endif
    38553857
  • trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h

    r272117 r272610  
    54085408}
    54095409
     5410template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ScrollSnapStop snapStop)
     5411    : CSSValue(PrimitiveClass)
     5412{
     5413    setPrimitiveUnitType(CSSUnitType::CSS_VALUE_ID);
     5414    switch (snapStop) {
     5415    case ScrollSnapStop::Normal:
     5416        m_value.valueID = CSSValueNormal;
     5417        break;
     5418    case ScrollSnapStop::Always:
     5419        m_value.valueID = CSSValueAlways;
     5420        break;
     5421    }
     5422}
     5423
     5424template<> inline CSSPrimitiveValue::operator ScrollSnapStop() const
     5425{
     5426    ASSERT(isValueID());
     5427    switch (m_value.valueID) {
     5428    case CSSValueNormal:
     5429        return ScrollSnapStop::Normal;
     5430    case CSSValueAlways:
     5431        return ScrollSnapStop::Always;
     5432    default:
     5433        ASSERT_NOT_REACHED();
     5434        return ScrollSnapStop::Normal;
     5435    }
     5436}
     5437
    54105438#endif
    54115439
  • trunk/Source/WebCore/css/CSSProperties.json

    r272117 r272610  
    69906990            }
    69916991        },
     6992        "scroll-snap-stop": {
     6993            "codegen-properties": {
     6994                "converter": "ScrollSnapStop",
     6995                "enable-if": "ENABLE_CSS_SCROLL_SNAP"
     6996            },
     6997            "specification": {
     6998                "category": "css-scroll-snap",
     6999                "url": "https://drafts.csswg.org/css-scroll-snap-1/#propdef-scroll-snap-stop"
     7000            }
     7001        },
    69927002        "shape-outside": {
    69937003            "codegen-properties": {
  • trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp

    r272366 r272610  
    41764176    case CSSPropertyScrollSnapAlign:
    41774177        return consumeScrollSnapAlign(m_range);
     4178    case CSSPropertyScrollSnapStop:
     4179        return consumeIdent<CSSValueAlways, CSSValueNormal>(m_range);
    41784180    case CSSPropertyScrollSnapType:
    41794181        return consumeScrollSnapType(m_range);
  • trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.cpp

    r272035 r272610  
    8080
    8181template <typename LayoutType>
    82 static void indicesOfNearestSnapOffsets(LayoutType offset, const Vector<LayoutType>& snapOffsets, unsigned& lowerIndex, unsigned& upperIndex)
     82static void indicesOfNearestSnapOffsets(LayoutType offset, const Vector<SnapOffset<LayoutType>>& snapOffsets, unsigned& lowerIndex, unsigned& upperIndex)
    8383{
    8484    lowerIndex = 0;
     
    8686    while (lowerIndex < upperIndex - 1) {
    8787        int middleIndex = (lowerIndex + upperIndex) / 2;
    88         auto middleOffset = snapOffsets[middleIndex];
     88        auto middleOffset = snapOffsets[middleIndex].offset;
    8989        if (offset == middleOffset) {
    9090            upperIndex = middleIndex;
     
    101101
    102102template <typename LayoutType>
    103 static std::pair<LayoutType, unsigned> closestSnapOffsetWithOffsetsAndRanges(const Vector<LayoutType>& snapOffsets, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, LayoutType scrollDestinationOffset, float velocity, Optional<LayoutType> originalOffsetForDirectionalSnapping)
     103static Optional<unsigned> findFirstSnapStopOffsetBetweenOriginAndDestination(const Vector<SnapOffset<LayoutType>>& snapOffsets, LayoutType scrollOriginOffset, LayoutType scrollDestinationOffset)
     104{
     105    LayoutType difference = scrollDestinationOffset - scrollOriginOffset;
     106    if (!difference)
     107        return WTF::nullopt;
     108
     109    unsigned searchStartOffset = 0;
     110    size_t iteration = 1;
     111    if (difference < 0) {
     112        searchStartOffset = snapOffsets.size() - 1;
     113        iteration = -1;
     114    }
     115
     116    auto isPast = [difference](LayoutType mark, LayoutType candidate) {
     117        return (difference > 0 && candidate > mark) || (difference < 0 && candidate < mark);
     118    };
     119
     120    for (size_t i = searchStartOffset; i >= 0 && i < snapOffsets.size(); i += iteration) {
     121        auto offset = snapOffsets[i].offset;
     122        if (isPast(scrollDestinationOffset, offset))
     123            break;
     124        if (snapOffsets[i].stop != ScrollSnapStop::Always)
     125            continue;
     126        if (isPast(scrollOriginOffset, offset))
     127            return i;
     128    }
     129
     130    return WTF::nullopt;
     131}
     132
     133template <typename LayoutType>
     134static std::pair<LayoutType, unsigned> closestSnapOffsetWithOffsetsAndRanges(const Vector<SnapOffset<LayoutType>>& snapOffsets, const Vector<ScrollOffsetRange<LayoutType>>& snapOffsetRanges, LayoutType scrollDestinationOffset, float velocity, Optional<LayoutType> originalOffsetForDirectionalSnapping)
    104135{
    105136    if (snapOffsets.isEmpty())
    106137        return std::make_pair(scrollDestinationOffset, invalidSnapOffsetIndex);
     138
     139    if (originalOffsetForDirectionalSnapping.hasValue()) {
     140        auto firstSnapStopOffsetIndex = findFirstSnapStopOffsetBetweenOriginAndDestination(snapOffsets, *originalOffsetForDirectionalSnapping, scrollDestinationOffset);
     141        if (firstSnapStopOffsetIndex.hasValue())
     142            return std::make_pair(snapOffsets[*firstSnapStopOffsetIndex].offset, *firstSnapStopOffsetIndex);
     143    }
    107144
    108145    unsigned lowerSnapOffsetRangeIndex;
     
    112149        return std::make_pair(scrollDestinationOffset, invalidSnapOffsetIndex);
    113150
    114     if (scrollDestinationOffset <= snapOffsets.first())
    115         return std::make_pair(snapOffsets.first(), 0u);
    116 
    117     if (scrollDestinationOffset >= snapOffsets.last())
    118         return std::make_pair(snapOffsets.last(), snapOffsets.size() - 1);
     151    if (scrollDestinationOffset <= snapOffsets.first().offset)
     152        return std::make_pair(snapOffsets.first().offset, 0u);
     153
     154    if (scrollDestinationOffset >= snapOffsets.last().offset)
     155        return std::make_pair(snapOffsets.last().offset, snapOffsets.size() - 1);
    119156
    120157    unsigned lowerIndex;
    121158    unsigned upperIndex;
    122159    indicesOfNearestSnapOffsets<LayoutType>(scrollDestinationOffset, snapOffsets, lowerIndex, upperIndex);
    123     LayoutType lowerSnapPosition = snapOffsets[lowerIndex];
    124     LayoutType upperSnapPosition = snapOffsets[upperIndex];
     160    LayoutType lowerSnapPosition = snapOffsets[lowerIndex].offset;
     161    LayoutType upperSnapPosition = snapOffsets[upperIndex].offset;
    125162    if (!std::abs(velocity)) {
    126163        bool isCloserToLowerSnapPosition = scrollDestinationOffset - lowerSnapPosition <= upperSnapPosition - scrollDestinationOffset;
     
    183220}
    184221
    185 template<typename T>
    186 TextStream& operator<<(TextStream& ts, const ScrollOffsetRange<T>& range)
    187 {
    188     ts << "start: " << range.start << " end: " << range.end;
    189     return ts;
    190 }
    191 
    192 static void computeAxisProximitySnapOffsetRanges(const Vector<LayoutUnit>& snapOffsets, Vector<ScrollOffsetRange<LayoutUnit>>& offsetRanges, LayoutUnit scrollPortAxisLength)
     222static void computeAxisProximitySnapOffsetRanges(const Vector<SnapOffset<LayoutUnit>>& snapOffsets, Vector<ScrollOffsetRange<LayoutUnit>>& offsetRanges, LayoutUnit scrollPortAxisLength)
    193223{
    194224    // This is an arbitrary choice for what it means to be "in proximity" of a snap offset. We should play around with
     
    207237    LayoutUnit proximityDistance { ratioOfScrollPortAxisLengthToBeConsideredForProximity * scrollPortAxisLength };
    208238    for (size_t index = 1; index < snapOffsets.size(); ++index) {
    209         auto startOffset = snapOffsets[index - 1] + proximityDistance;
    210         auto endOffset = snapOffsets[index] - proximityDistance;
     239        auto startOffset = snapOffsets[index - 1].offset + proximityDistance;
     240        auto endOffset = snapOffsets[index].offset - proximityDistance;
    211241        if (startOffset < endOffset)
    212242            offsetRanges.append({ startOffset, endOffset });
     
    223253    }
    224254
    225     Vector<LayoutUnit> verticalSnapOffsets;
    226     Vector<LayoutUnit> horizontalSnapOffsets;
    227     Vector<ScrollOffsetRange<LayoutUnit>> verticalSnapOffsetRanges;
    228     Vector<ScrollOffsetRange<LayoutUnit>> horizontalSnapOffsetRanges;
    229     HashSet<float> seenVerticalSnapOffsets;
    230     HashSet<float> seenHorizontalSnapOffsets;
     255    auto addOrUpdateStopForSnapOffset = [](HashMap<float, SnapOffset<LayoutUnit>>& offsets, SnapOffset<LayoutUnit> newOffset)
     256    {
     257        // If the offset already exists, we ensure that it has ScrollSnapStop::Always, when appropriate.
     258        auto addResult = offsets.add(newOffset.offset, newOffset);
     259        if (newOffset.stop == ScrollSnapStop::Always)
     260            addResult.iterator->value.stop = ScrollSnapStop::Always;
     261    };
     262
     263    HashMap<float, SnapOffset<LayoutUnit>> verticalSnapOffsetsMap;
     264    HashMap<float, SnapOffset<LayoutUnit>> horizontalSnapOffsetsMap;
    231265    bool hasHorizontalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::XAxis || scrollSnapType.axis == ScrollSnapAxis::Inline;
    232266    bool hasVerticalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::YAxis || scrollSnapType.axis == ScrollSnapAxis::Block;
     
    256290        LOG_WITH_STREAM(ScrollSnap, stream << "    Considering scroll snap target area " << scrollSnapArea);
    257291        auto alignment = child->style().scrollSnapAlign();
     292        auto stop = child->style().scrollSnapStop();
    258293        if (hasHorizontalSnapOffsets && alignment.x != ScrollSnapAxisAlignType::None) {
    259294            auto absoluteScrollXPosition = computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.maxX(), alignment.x, scrollerIsRTL) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.maxX(), alignment.x, scrollerIsRTL);
    260295            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ roundToInt(absoluteScrollXPosition), 0 }).x(), 0, maxScrollOffset.x());
    261             if (!seenHorizontalSnapOffsets.contains(absoluteScrollOffset)) {
    262                 seenHorizontalSnapOffsets.add(absoluteScrollOffset);
    263                 horizontalSnapOffsets.append(absoluteScrollOffset);
    264             }
     296            addOrUpdateStopForSnapOffset(horizontalSnapOffsetsMap, { absoluteScrollOffset, stop });
    265297        }
    266298        if (hasVerticalSnapOffsets && alignment.y != ScrollSnapAxisAlignType::None) {
    267299            auto absoluteScrollYPosition = computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.maxY(), alignment.y, false) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.maxY(), alignment.y, false);
    268300            auto absoluteScrollOffset = clampTo<int>(scrollableArea.scrollOffsetFromPosition({ 0, roundToInt(absoluteScrollYPosition) }).y(), 0, maxScrollOffset.y());
    269             if (!seenVerticalSnapOffsets.contains(absoluteScrollOffset)) {
    270                 seenVerticalSnapOffsets.add(absoluteScrollOffset);
    271                 verticalSnapOffsets.append(absoluteScrollOffset);
    272             }
     301            addOrUpdateStopForSnapOffset(verticalSnapOffsetsMap, { absoluteScrollOffset, stop });
    273302        }
    274303    }
    275304
     305    auto compareSnapOffsets = [](const SnapOffset<LayoutUnit>& a, const SnapOffset<LayoutUnit>& b)
     306    {
     307        return a.offset < b.offset;
     308    };
     309
     310    Vector<SnapOffset<LayoutUnit>> horizontalSnapOffsets = copyToVector(horizontalSnapOffsetsMap.values());
     311    Vector<ScrollOffsetRange<LayoutUnit>> horizontalSnapOffsetRanges;
    276312    if (!horizontalSnapOffsets.isEmpty()) {
    277         std::sort(horizontalSnapOffsets.begin(), horizontalSnapOffsets.end());
     313        std::sort(horizontalSnapOffsets.begin(), horizontalSnapOffsets.end(), compareSnapOffsets);
    278314        if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity)
    279315            computeAxisProximitySnapOffsetRanges(horizontalSnapOffsets, horizontalSnapOffsetRanges, scrollSnapPort.width());
     
    281317        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed horizontal scroll snap offsets: " << horizontalSnapOffsets);
    282318        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed horizontal scroll snap offset ranges: " << horizontalSnapOffsetRanges);
    283 
    284         scrollableArea.setHorizontalSnapOffsets(horizontalSnapOffsets);
    285         scrollableArea.setHorizontalSnapOffsetRanges(horizontalSnapOffsetRanges);
    286     } else
    287         scrollableArea.clearHorizontalSnapOffsets();
    288 
     319    }
     320
     321    Vector<SnapOffset<LayoutUnit>> verticalSnapOffsets = copyToVector(verticalSnapOffsetsMap.values());
     322    Vector<ScrollOffsetRange<LayoutUnit>> verticalSnapOffsetRanges;
    289323    if (!verticalSnapOffsets.isEmpty()) {
    290         std::sort(verticalSnapOffsets.begin(), verticalSnapOffsets.end());
     324        std::sort(verticalSnapOffsets.begin(), verticalSnapOffsets.end(), compareSnapOffsets);
    291325        if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity)
    292326            computeAxisProximitySnapOffsetRanges(verticalSnapOffsets, verticalSnapOffsetRanges, scrollSnapPort.height());
     
    294328        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed vertical scroll snap offsets: " << verticalSnapOffsets);
    295329        LOG_WITH_STREAM(ScrollSnap, stream << " => Computed vertical scroll snap offset ranges: " << verticalSnapOffsetRanges);
    296 
    297         scrollableArea.setVerticalSnapOffsets(verticalSnapOffsets);
    298         scrollableArea.setVerticalSnapOffsetRanges(verticalSnapOffsetRanges);
    299     } else
    300         scrollableArea.clearVerticalSnapOffsets();
     330    }
     331
     332    scrollableArea.setScrollSnapOffsetInfo({
     333        horizontalSnapOffsets,
     334        verticalSnapOffsets,
     335        horizontalSnapOffsetRanges,
     336        verticalSnapOffsetRanges
     337    });
    301338}
    302339
     
    314351static ScrollSnapOffsetsInfo<OutputType> convertOffsetInfo(const ScrollSnapOffsetsInfo<InputType>& input, float scaleFactor = 0.0)
    315352{
    316     auto convertOffsets = [scaleFactor](const Vector<InputType>& input)
     353    auto convertOffsets = [scaleFactor](const Vector<SnapOffset<InputType>>& input)
    317354    {
    318         Vector<OutputType> output;
     355        Vector<SnapOffset<OutputType>> output;
    319356        output.reserveInitialCapacity(input.size());
    320357        for (auto& offset : input)
    321             output.uncheckedAppend(convertOffsetUnit(offset, scaleFactor));
     358            output.uncheckedAppend({ convertOffsetUnit(offset.offset, scaleFactor), offset.stop });
    322359        return output;
    323360    };
  • trunk/Source/WebCore/page/scrolling/ScrollSnapOffsetsInfo.h

    r272019 r272610  
    3333#include <utility>
    3434#include <wtf/Vector.h>
    35 #include <wtf/Vector.h>
    3635
    3736namespace WebCore {
     
    4140class RenderBox;
    4241class RenderStyle;
     42
     43template <typename T>
     44struct SnapOffset {
     45    T offset;
     46    ScrollSnapStop stop;
     47};
    4348
    4449template <typename T>
     
    5156struct ScrollSnapOffsetsInfo {
    5257    WTF_MAKE_STRUCT_FAST_ALLOCATED;
    53     Vector<T> horizontalSnapOffsets;
    54     Vector<T> verticalSnapOffsets;
     58    Vector<SnapOffset<T>> horizontalSnapOffsets;
     59    Vector<SnapOffset<T>> verticalSnapOffsets;
    5560
    5661    // Snap offset ranges represent non-empty ranges of scroll offsets in which scrolling may rest after scroll snapping.
     
    7176    }
    7277
    73     Vector<T> offsetsForAxis(ScrollEventAxis axis) const
     78    Vector<SnapOffset<T>> offsetsForAxis(ScrollEventAxis axis) const
    7479    {
    7580        return axis == ScrollEventAxis::Vertical ? verticalSnapOffsets : horizontalSnapOffsets;
     
    102107void updateSnapOffsetsForScrollableArea(ScrollableArea&, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle, LayoutRect viewportRectInBorderBoxCoordinates);
    103108
     109template <typename T> WTF::TextStream& operator<<(WTF::TextStream& ts, SnapOffset<T> offset)
     110{
     111    ts << offset.offset;
     112    if (offset.stop == ScrollSnapStop::Always)
     113        ts << " (always)";
     114    return ts;
     115}
     116
     117template<typename T>
     118TextStream& operator<<(TextStream& ts, const ScrollOffsetRange<T>& range)
     119{
     120    ts << "start: " << range.start << " end: " << range.end;
     121    return ts;
     122}
     123
    104124}; // namespace WebCore
    105125
  • trunk/Source/WebCore/platform/ScrollableArea.cpp

    r271658 r272610  
    488488}
    489489
    490 void ScrollableArea::setHorizontalSnapOffsets(const Vector<LayoutUnit>& horizontalSnapOffsets)
    491 {
     490void ScrollableArea::setScrollSnapOffsetInfo(const ScrollSnapOffsetsInfo<LayoutUnit>& info)
     491{
     492    if (info.isEmpty()) {
     493        clearSnapOffsets();
     494        return;
     495    }
     496
    492497    // Consider having a non-empty set of snap offsets as a cue to initialize the ScrollAnimator.
    493     if (horizontalSnapOffsets.size())
    494         scrollAnimator();
    495 
    496     ensureSnapOffsetsInfo().horizontalSnapOffsets = horizontalSnapOffsets;
    497 }
    498 
    499 void ScrollableArea::setVerticalSnapOffsets(const Vector<LayoutUnit>& verticalSnapOffsets)
    500 {
    501     // Consider having a non-empty set of snap offsets as a cue to initialize the ScrollAnimator.
    502     if (verticalSnapOffsets.size())
    503         scrollAnimator();
    504 
    505     ensureSnapOffsetsInfo().verticalSnapOffsets = verticalSnapOffsets;
    506 }
    507 
    508 void ScrollableArea::setHorizontalSnapOffsetRanges(const Vector<ScrollOffsetRange<LayoutUnit>>& horizontalRanges)
    509 {
    510     ensureSnapOffsetsInfo().horizontalSnapOffsetRanges = horizontalRanges;
    511 }
    512 
    513 void ScrollableArea::setVerticalSnapOffsetRanges(const Vector<ScrollOffsetRange<LayoutUnit>>& verticalRanges)
    514 {
    515     ensureSnapOffsetsInfo().verticalSnapOffsetRanges = verticalRanges;
     498    scrollAnimator();
     499    ensureSnapOffsetsInfo() = info;
    516500}
    517501
    518502void ScrollableArea::clearSnapOffsets()
    519503{
    520     clearHorizontalSnapOffsets();
    521     clearVerticalSnapOffsets();
    522 }
    523 
    524 void ScrollableArea::clearHorizontalSnapOffsets()
    525 {
    526     if (!m_snapOffsetsInfo)
    527         return;
    528 
    529     m_snapOffsetsInfo->horizontalSnapOffsets = { };
    530     m_snapOffsetsInfo->horizontalSnapOffsetRanges = { };
    531     m_currentHorizontalSnapPointIndex = 0;
    532 }
    533 
    534 void ScrollableArea::clearVerticalSnapOffsets()
    535 {
    536     if (!m_snapOffsetsInfo)
    537         return;
    538 
    539     m_snapOffsetsInfo->verticalSnapOffsets = { };
    540     m_snapOffsetsInfo->verticalSnapOffsetRanges = { };
    541     m_currentVerticalSnapPointIndex = 0;
     504    m_snapOffsetsInfo = nullptr;
    542505}
    543506
     
    560523    size_t activeHorizontalIndex = currentHorizontalSnapPointIndex();
    561524    if (activeHorizontalIndex < horizontal.size())
    562         correctedPosition.setX(horizontal[activeHorizontalIndex].toInt());
     525        correctedPosition.setX(horizontal[activeHorizontalIndex].offset.toInt());
    563526
    564527    const auto& vertical = m_snapOffsetsInfo->verticalSnapOffsets;
    565528    size_t activeVerticalIndex = currentVerticalSnapPointIndex();
    566529    if (activeVerticalIndex < vertical.size())
    567         correctedPosition.setY(vertical[activeVerticalIndex].toInt());
     530        correctedPosition.setY(vertical[activeVerticalIndex].offset.toInt());
    568531
    569532    return correctedPosition;
  • trunk/Source/WebCore/platform/ScrollableArea.h

    r271658 r272610  
    9292    WEBCORE_EXPORT const ScrollSnapOffsetsInfo<LayoutUnit>* snapOffsetInfo() const;
    9393    virtual void updateSnapOffsets() { };
    94     void setHorizontalSnapOffsets(const Vector<LayoutUnit>&);
    95     void setVerticalSnapOffsets(const Vector<LayoutUnit>&);
    96     void setHorizontalSnapOffsetRanges(const Vector<ScrollOffsetRange<LayoutUnit>>&);
    97     void setVerticalSnapOffsetRanges(const Vector<ScrollOffsetRange<LayoutUnit>>&);
     94    void setScrollSnapOffsetInfo(const ScrollSnapOffsetsInfo<LayoutUnit>&);
    9895    void clearSnapOffsets();
    99     void clearHorizontalSnapOffsets();
    100     void clearVerticalSnapOffsets();
    10196    unsigned currentHorizontalSnapPointIndex() const { return m_currentHorizontalSnapPointIndex; }
    10297    void setCurrentHorizontalSnapPointIndex(unsigned index) { m_currentHorizontalSnapPointIndex = index; }
  • trunk/Source/WebCore/platform/cocoa/ScrollController.mm

    r272019 r272610  
    882882        return;
    883883
    884     LayoutUnit clampedOffset = std::min(std::max(LayoutUnit(offset / scaleFactor), snapOffsets.first()), snapOffsets.last());
     884    LayoutUnit clampedOffset = std::min(std::max(LayoutUnit(offset / scaleFactor), snapOffsets.first().offset), snapOffsets.last().offset);
    885885
    886886    unsigned activeIndex = snapState.snapOffsetInfo().closestSnapOffset(axis, clampedOffset, 0).second;
  • trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.h

    r272019 r272610  
    5353    WTF_MAKE_FAST_ALLOCATED;
    5454public:
    55     const Vector<LayoutUnit>& snapOffsetsForAxis(ScrollEventAxis axis) const
     55    const Vector<SnapOffset<LayoutUnit>>& snapOffsetsForAxis(ScrollEventAxis axis) const
    5656    {
    5757        return axis == ScrollEventAxis::Horizontal ? m_snapOffsetsInfo.horizontalSnapOffsets : m_snapOffsetsInfo.verticalSnapOffsets;
     
    6666    void setSnapOffsetInfo(const ScrollSnapOffsetsInfo<LayoutUnit>& newInfo) { m_snapOffsetsInfo = newInfo; }
    6767
    68     void setSnapOffsetsAndPositionRangesForAxis(ScrollEventAxis axis, const Vector<LayoutUnit>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges)
     68    void setSnapOffsetsAndPositionRangesForAxis(ScrollEventAxis axis, const Vector<SnapOffset<LayoutUnit>>& snapOffsets, const Vector<ScrollOffsetRange<LayoutUnit>>& snapOffsetRanges)
    6969    {
    7070        if (axis == ScrollEventAxis::Horizontal) {
  • trunk/Source/WebCore/platform/cocoa/ScrollSnapAnimatorState.mm

    r272019 r272610  
    101101}
    102102
    103 template<typename T>
    104 TextStream& operator<<(TextStream& ts, const ScrollOffsetRange<T>& range)
    105 {
    106     ts << "start: " << range.start << " end: " << range.end;
    107     return ts;
    108 }
    109 
    110103TextStream& operator<<(TextStream& ts, const ScrollSnapAnimatorState& state)
    111104{
  • trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp

    r271814 r272610  
    197197    }
    198198
    199     bool scrollMarginChanged =
    200         oldStyle && oldStyle->scrollMargin() != newStyle.scrollMargin();
    201     bool scrollAlignChanged =
    202         oldStyle && oldStyle->scrollSnapAlign() != newStyle.scrollSnapAlign();
    203     if (scrollMarginChanged || scrollAlignChanged) {
     199    bool scrollMarginChanged = oldStyle && oldStyle->scrollMargin() != newStyle.scrollMargin();
     200    bool scrollAlignChanged = oldStyle && oldStyle->scrollSnapAlign() != newStyle.scrollSnapAlign();
     201    bool scrollSnapStopChanged = oldStyle && oldStyle->scrollSnapStop() != newStyle.scrollSnapStop();
     202    if (scrollMarginChanged || scrollAlignChanged || scrollSnapStopChanged) {
    204203        auto* scrollSnapBox = enclosingScrollableContainerForSnapping();
    205204        if (scrollSnapBox && scrollSnapBox->layer()) {
     
    211210                }
    212211                if (scrollSnapBox->isBody() || scrollSnapBox->isDocumentElementRenderer())
     212                    scrollSnapBox->view().frameView().updateSnapOffsets();
     213                    scrollSnapBox->view().frameView().updateScrollSnapState();
    213214                    scrollSnapBox->view().frameView().updateScrollingCoordinatorScrollSnapProperties();
    214215            }
  • trunk/Source/WebCore/rendering/style/RenderStyle.cpp

    r270849 r272610  
    24992499}
    25002500
     2501ScrollSnapStop RenderStyle::initialScrollSnapStop()
     2502{
     2503    return ScrollSnapStop::Normal;
     2504}
     2505
    25012506const ScrollSnapType RenderStyle::scrollSnapType() const
    25022507{
     
    25092514}
    25102515
     2516ScrollSnapStop RenderStyle::scrollSnapStop() const
     2517{
     2518    return m_rareNonInheritedData->scrollSnapStop;
     2519}
     2520
    25112521void RenderStyle::setScrollSnapType(const ScrollSnapType type)
    25122522{
     
    25172527{
    25182528    SET_VAR(m_rareNonInheritedData, scrollSnapAlign, alignment);
     2529}
     2530
     2531void RenderStyle::setScrollSnapStop(const ScrollSnapStop stop)
     2532{
     2533    SET_VAR(m_rareNonInheritedData, scrollSnapStop, stop);
    25192534}
    25202535
  • trunk/Source/WebCore/rendering/style/RenderStyle.h

    r272569 r272610  
    752752    const ScrollSnapType scrollSnapType() const;
    753753    const ScrollSnapAlign& scrollSnapAlign() const;
     754    ScrollSnapStop scrollSnapStop() const;
    754755#endif
    755756
     
    12941295    void setScrollSnapType(const ScrollSnapType);
    12951296    void setScrollSnapAlign(const ScrollSnapAlign&);
     1297    void setScrollSnapStop(const ScrollSnapStop);
    12961298#endif
    12971299
     
    17001702    static ScrollSnapType initialScrollSnapType();
    17011703    static ScrollSnapAlign initialScrollSnapAlign();
     1704    static ScrollSnapStop initialScrollSnapStop();
    17021705#endif
    17031706
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.cpp

    r271948 r272610  
    10401040    return ts;
    10411041}
     1042
     1043TextStream& operator<<(TextStream& ts, ScrollSnapStop stop)
     1044{
     1045    switch (stop) {
     1046    case ScrollSnapStop::Normal: ts << "normal"; break;
     1047    case ScrollSnapStop::Always: ts << "always"; break;
     1048    }
     1049    return ts;
     1050}
    10421051#endif
    10431052
  • trunk/Source/WebCore/rendering/style/RenderStyleConstants.h

    r271948 r272610  
    2727
    2828#include <initializer_list>
     29#include <wtf/EnumTraits.h>
    2930
    3031namespace WTF {
     
    11281129    End
    11291130};
     1131
     1132enum class ScrollSnapStop : uint8_t {
     1133    Normal,
     1134    Always,
     1135};
    11301136#endif
    11311137
     
    12851291WTF::TextStream& operator<<(WTF::TextStream&, ScrollSnapAxis);
    12861292WTF::TextStream& operator<<(WTF::TextStream&, ScrollSnapAxisAlignType);
     1293WTF::TextStream& operator<<(WTF::TextStream&, ScrollSnapStop);
    12871294WTF::TextStream& operator<<(WTF::TextStream&, ScrollSnapStrictness);
    12881295#endif
     
    13161323
    13171324} // namespace WebCore
     1325
     1326#if ENABLE(CSS_SCROLL_SNAP)
     1327namespace WTF {
     1328template<> struct EnumTraits<WebCore::ScrollSnapStop> {
     1329    using values = EnumValues<
     1330        WebCore::ScrollSnapStop,
     1331        WebCore::ScrollSnapStop::Normal,
     1332        WebCore::ScrollSnapStop::Always
     1333    >;
     1334};
     1335}
     1336#endif
  • trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.cpp

    r270613 r272610  
    142142    , scrollSnapType(o.scrollSnapType)
    143143    , scrollSnapAlign(o.scrollSnapAlign)
     144    , scrollSnapStop(o.scrollSnapStop)
    144145#endif
    145146    , overscrollBehaviorX(o.overscrollBehaviorX)
     
    248249        && scrollSnapType == o.scrollSnapType
    249250        && scrollSnapAlign == o.scrollSnapAlign
     251        && scrollSnapStop == o.scrollSnapStop
    250252#endif
    251253        && overscrollBehaviorX == o.overscrollBehaviorX
  • trunk/Source/WebCore/rendering/style/StyleRareNonInheritedData.h

    r272035 r272610  
    137137    ScrollSnapType scrollSnapType;
    138138    ScrollSnapAlign scrollSnapAlign;
     139    ScrollSnapStop scrollSnapStop { ScrollSnapStop::Normal };
    139140#endif
    140141
  • trunk/Source/WebCore/style/StyleBuilderConverter.h

    r271480 r272610  
    112112    static ScrollSnapType convertScrollSnapType(BuilderState&, const CSSValue&);
    113113    static ScrollSnapAlign convertScrollSnapAlign(BuilderState&, const CSSValue&);
     114    static ScrollSnapStop convertScrollSnapStop(BuilderState&, const CSSValue&);
    114115#endif
    115116    static GridTrackSize convertGridTrackSize(BuilderState&, const CSSValue&);
     
    931932}
    932933
     934inline ScrollSnapStop BuilderConverter::convertScrollSnapStop(BuilderState&, const CSSValue& value)
     935{
     936    ASSERT(is<CSSPrimitiveValue>(value));
     937    return downcast<CSSPrimitiveValue>(value);
     938}
     939
    933940#endif
    934941
  • trunk/Source/WebCore/testing/Internals.cpp

    r272206 r272610  
    46384638#if ENABLE(CSS_SCROLL_SNAP)
    46394639
    4640 static void appendOffsets(StringBuilder& builder, const Vector<LayoutUnit>& snapOffsets)
     4640static void appendOffsets(StringBuilder& builder, const Vector<SnapOffset<LayoutUnit>>& snapOffsets)
    46414641{
    46424642    bool justStarting = true;
     
    46494649            justStarting = false;
    46504650
    4651         builder.appendNumber(coordinate.toUnsigned());
     4651        builder.appendNumber(coordinate.offset.toUnsigned());
     4652        if (coordinate.stop == ScrollSnapStop::Always)
     4653            builder.appendLiteral(" (always)");
     4654
    46524655    }
    46534656    builder.appendLiteral(" }");
  • trunk/Source/WebKit/ChangeLog

    r272608 r272610  
     12021-02-09  Martin Robinson  <mrobinson@webkit.org>
     2
     3        Implement scroll-snap-stop for scroll snapping
     4        https://bugs.webkit.org/show_bug.cgi?id=197744
     5        <rdar://problem/50708356>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp: Add encoding and decoding support
     10        for the SnapOffset struct.
     11        (ArgumentCoder<SnapOffset<float>>::encode):
     12        (ArgumentCoder<SnapOffset<float>>::decode):
     13        * UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm: Update to use SnapOffset struct.
     14        (WebKit::RemoteScrollingCoordinatorProxy::shouldSnapForMainFrameScrolling const):
     15        (WebKit::RemoteScrollingCoordinatorProxy::hasActiveSnapPoint const):
     16        (WebKit::RemoteScrollingCoordinatorProxy::nearestActiveContentInsetAdjustedSnapOffset const):
     17
    1182021-02-09  Per Arne  <pvollan@apple.com>
    219
  • trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp

    r271937 r272610  
    103103    static WARN_UNUSED_RETURN bool decode(Decoder&, ScrollSnapOffsetsInfo<float>&);
    104104};
     105
     106template<> struct ArgumentCoder<SnapOffset<float>> {
     107    static void encode(Encoder&, const SnapOffset<float>&);
     108    static WARN_UNUSED_RETURN bool decode(Decoder&, SnapOffset<float>&);
     109};
     110
    105111
    106112} // namespace IPC
     
    523529}
    524530
     531void ArgumentCoder<SnapOffset<float>>::encode(Encoder& encoder, const SnapOffset<float>& offset)
     532{
     533    encoder << offset.offset;
     534    encoder << offset.stop;
     535}
     536
     537bool ArgumentCoder<SnapOffset<float>>::decode(Decoder& decoder, SnapOffset<float>& offset)
     538{
     539    if (!decoder.decode(offset.offset))
     540        return false;
     541    if (!decoder.decode(offset.stop))
     542        return false;
     543    return true;
     544}
     545
     546
    525547void ArgumentCoder<ScrollSnapOffsetsInfo<float>>::encode(Encoder& encoder, const ScrollSnapOffsetsInfo<float>& info)
    526548{
  • trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm

    r272019 r272610  
    215215    if (root && root->isFrameScrollingNode()) {
    216216        ScrollingTreeFrameScrollingNode* rootScrollingNode = static_cast<ScrollingTreeFrameScrollingNode*>(root);
    217         const Vector<float>& snapOffsets = rootScrollingNode->snapOffsetsInfo().offsetsForAxis(axis);
     217        const auto& snapOffsets = rootScrollingNode->snapOffsetsInfo().offsetsForAxis(axis);
    218218        unsigned currentIndex = axis == ScrollEventAxis::Horizontal ? m_currentHorizontalSnapPointIndex : m_currentVerticalSnapPointIndex;
    219219        return snapOffsets.size() && (currentIndex < snapOffsets.size() || currentIndex == invalidSnapOffsetIndex);
     
    245245
    246246    ScrollingTreeFrameScrollingNode& rootScrollingNode = downcast<ScrollingTreeFrameScrollingNode>(*root);
    247     const Vector<float>& horizontal = rootScrollingNode.snapOffsetsInfo().horizontalSnapOffsets;
    248     const Vector<float>& vertical = rootScrollingNode.snapOffsetsInfo().verticalSnapOffsets;
     247    const auto& horizontal = rootScrollingNode.snapOffsetsInfo().horizontalSnapOffsets;
     248    const auto& vertical = rootScrollingNode.snapOffsetsInfo().verticalSnapOffsets;
    249249
    250250    if (horizontal.isEmpty() && vertical.isEmpty())
     
    266266    ASSERT(root && is<ScrollingTreeFrameScrollingNode>(root));
    267267    ScrollingTreeFrameScrollingNode& rootScrollingNode = downcast<ScrollingTreeFrameScrollingNode>(*root);
    268     const Vector<float>& horizontal = rootScrollingNode.snapOffsetsInfo().horizontalSnapOffsets;
    269     const Vector<float>& vertical = rootScrollingNode.snapOffsetsInfo().verticalSnapOffsets;
     268    const auto& horizontal = rootScrollingNode.snapOffsetsInfo().horizontalSnapOffsets;
     269    const auto& vertical = rootScrollingNode.snapOffsetsInfo().verticalSnapOffsets;
    270270
    271271    // The bounds checking with maxScrollOffsets is to ensure that we won't interfere with rubber-banding when scrolling to the edge of the page.
    272272    if (!horizontal.isEmpty() && m_currentHorizontalSnapPointIndex < horizontal.size())
    273         activePoint.x = horizontal[m_currentHorizontalSnapPointIndex] * m_webPageProxy.displayedContentScale();
     273        activePoint.x = horizontal[m_currentHorizontalSnapPointIndex].offset * m_webPageProxy.displayedContentScale();
    274274
    275275    if (!vertical.isEmpty() && m_currentVerticalSnapPointIndex < vertical.size()) {
    276         float potentialSnapPosition = vertical[m_currentVerticalSnapPointIndex] * m_webPageProxy.displayedContentScale();
     276        float potentialSnapPosition = vertical[m_currentVerticalSnapPointIndex].offset * m_webPageProxy.displayedContentScale();
    277277        potentialSnapPosition -= topInset;
    278278        activePoint.y = potentialSnapPosition;
Note: See TracChangeset for help on using the changeset viewer.