| Index: third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.cpp
|
| diff --git a/third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.cpp b/third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.cpp
|
| index 5762342d791e277c83062282b04b168fe34e445e..3b1941b562675125e63715c39356c67196420944 100644
|
| --- a/third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.cpp
|
| +++ b/third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.cpp
|
| @@ -12,6 +12,7 @@
|
| #include "core/layout/LayoutView.h"
|
| #include "core/style/ComputedStyle.h"
|
| #include "platform/LengthFunctions.h"
|
| +#include "public/platform/WebSnapPointList.h"
|
|
|
| namespace blink {
|
|
|
| @@ -43,7 +44,7 @@ static LayoutBox* FindSnapContainer(const LayoutBox& snap_area) {
|
| return box;
|
| }
|
|
|
| -void SnapCoordinator::SnapAreaDidChange(
|
| +/*void SnapCoordinator::SnapAreaDidChange(
|
| LayoutBox& snap_area,
|
| const Vector<LengthPoint>& snap_coordinates) {
|
| if (snap_coordinates.IsEmpty()) {
|
| @@ -51,6 +52,23 @@ void SnapCoordinator::SnapAreaDidChange(
|
| return;
|
| }
|
|
|
| + if (LayoutBox* snap_container = FindSnapContainer(snap_area)) {
|
| + snap_area.SetSnapContainer(snap_container);
|
| + } else {
|
| + // TODO(majidvp): keep track of snap areas that do not have any
|
| + // container so that we check them again when a new container is
|
| + // added to the page.
|
| + }
|
| +}*/
|
| +
|
| +void SnapCoordinator::SnapAreaDidChange(LayoutBox& snap_area,
|
| + ScrollSnapAlign scroll_snap_align) {
|
| + if (scroll_snap_align.alignmentX == kSnapAlignmentNone &&
|
| + scroll_snap_align.alignmentY == kSnapAlignmentNone) {
|
| + snap_area.SetSnapContainer(nullptr);
|
| + return;
|
| + }
|
| +
|
| if (LayoutBox* snap_container = FindSnapContainer(snap_area)) {
|
| snap_area.SetSnapContainer(snap_container);
|
| } else {
|
| @@ -62,7 +80,7 @@ void SnapCoordinator::SnapAreaDidChange(
|
|
|
| void SnapCoordinator::SnapContainerDidChange(LayoutBox& snap_container,
|
| ScrollSnapType scroll_snap_type) {
|
| - if (scroll_snap_type == kScrollSnapTypeNone) {
|
| + if (scroll_snap_type.axis == kSnapAxisNone) {
|
| // TODO(majidvp): Track and report these removals to CompositorWorker
|
| // instance responsible for snapping
|
| snap_containers_.erase(&snap_container);
|
| @@ -79,29 +97,108 @@ void SnapCoordinator::SnapContainerDidChange(LayoutBox& snap_container,
|
| // container or from existing areas in orphan pool.
|
| }
|
|
|
| -// Translate local snap coordinates into snap container's scrolling content
|
| -// coordinate space.
|
| -static Vector<FloatPoint> LocalToContainerSnapCoordinates(
|
| - const LayoutBox& container_box,
|
| - const LayoutBox& snap_area) {
|
| - Vector<FloatPoint> result;
|
| - LayoutPoint scroll_offset(container_box.ScrollLeft(),
|
| - container_box.ScrollTop());
|
| -
|
| - const Vector<LengthPoint>& snap_coordinates =
|
| - snap_area.Style()->ScrollSnapCoordinate();
|
| - for (auto& coordinate : snap_coordinates) {
|
| - FloatPoint local_point =
|
| - FloatPointForLengthPoint(coordinate, FloatSize(snap_area.Size()));
|
| - FloatPoint container_point =
|
| - snap_area.LocalToAncestorPoint(local_point, &container_box);
|
| - container_point.MoveBy(scroll_offset);
|
| - result.push_back(container_point);
|
| +static float ClipInContainer(float point, float range) {
|
| + if (point < 0)
|
| + return 0;
|
| + if (point > range)
|
| + return range;
|
| + return point;
|
| +}
|
| +
|
| +static void AddSnapArea(const LayoutBox& container_box,
|
| + const LayoutBox& snap_area,
|
| + SnapOrientation orientation,
|
| + WebSnapPointList* list) {
|
| + SnapAlignment align;
|
| + float content_scroll = 0;
|
| + float content_visible = 0;
|
| + float area_size = 0;
|
| + float area_offset = 0;
|
| + float container_size = 0;
|
| +
|
| + const ComputedStyle* area_style = snap_area.Style();
|
| + const ComputedStyle* container_style = container_box.Style();
|
| + bool must_snap = (area_style->ScrollSnapStop() == EScrollSnapStop::kAlways);
|
| + // LOG(ERROR) << area_style->ScrollSnapStop();
|
| + if (orientation == kSnapX) {
|
| + align = area_style->GetScrollSnapAlign().alignmentX;
|
| + container_size = container_box.ClientWidth().ToFloat();
|
| + content_visible = container_size;
|
| + content_scroll = container_box.ScrollWidth().ToFloat();
|
| + Length pad_left = container_style->ScrollPaddingLeft();
|
| + Length pad_right = container_style->ScrollPaddingRight();
|
| + float padding_left = pad_left.IsFixed()
|
| + ? pad_left.Pixels()
|
| + : pad_left.Percent() * container_size / 100;
|
| + float padding_right = pad_right.IsFixed()
|
| + ? pad_right.Pixels()
|
| + : pad_right.Percent() * container_size / 100;
|
| + container_size -= padding_left + padding_right;
|
| +
|
| + area_offset =
|
| + snap_area.OffsetLeft(ToElement(container_box.GetNode())).ToFloat();
|
| + area_offset -= area_style->ScrollSnapMarginLeft().Pixels() + padding_left;
|
| + area_size = snap_area.OffsetWidth().ToFloat();
|
| + area_size += area_style->ScrollSnapMarginLeft().Pixels() +
|
| + area_style->ScrollSnapMarginRight().Pixels();
|
| + } else {
|
| + align = area_style->GetScrollSnapAlign().alignmentY;
|
| + container_size = container_box.ClientHeight().ToFloat();
|
| + content_visible = container_size;
|
| + content_scroll = container_box.ScrollHeight().ToFloat();
|
| + Length pad_top = container_style->ScrollPaddingTop();
|
| + Length pad_bottom = container_style->ScrollPaddingBottom();
|
| + float padding_top = pad_top.IsFixed()
|
| + ? pad_top.Pixels()
|
| + : pad_top.Percent() * container_size / 100;
|
| + float padding_bottom = pad_bottom.IsFixed()
|
| + ? pad_bottom.Pixels()
|
| + : pad_bottom.Percent() * container_size;
|
| + container_size -= padding_top + padding_bottom;
|
| +
|
| + area_offset =
|
| + snap_area.OffsetTop(ToElement(container_box.GetNode())).ToFloat();
|
| + area_offset -= area_style->ScrollSnapMarginTop().Pixels() + padding_top;
|
| + area_size = snap_area.OffsetHeight().ToFloat();
|
| + area_size += area_style->ScrollSnapMarginTop().Pixels() +
|
| + area_style->ScrollSnapMarginBottom().Pixels();
|
| }
|
| - return result;
|
| + if (align == kSnapAlignmentNone)
|
| + return;
|
| + float snap_range = content_scroll - content_visible;
|
| + float start_alignment_point = ClipInContainer(area_offset, snap_range);
|
| + float center_alignment_point = ClipInContainer(
|
| + area_offset + (area_size - container_size) / 2, snap_range);
|
| + float end_alignment_point =
|
| + ClipInContainer(area_offset + area_size - container_size, snap_range);
|
| + if (end_alignment_point > start_alignment_point) {
|
| + list->AddSnapPoint(start_alignment_point, must_snap, true, false,
|
| + orientation);
|
| + list->AddSnapPoint(end_alignment_point, must_snap, false, true,
|
| + orientation);
|
| + return;
|
| + }
|
| + if (align == kSnapAlignmentStart) {
|
| + list->AddSnapPoint(start_alignment_point, must_snap, false, false,
|
| + orientation);
|
| + return;
|
| + }
|
| + if (align == kSnapAlignmentCenter) {
|
| + list->AddSnapPoint(center_alignment_point, must_snap, false, false,
|
| + orientation);
|
| + return;
|
| + }
|
| + if (align == kSnapAlignmentEnd) {
|
| + list->AddSnapPoint(end_alignment_point, must_snap, false, false,
|
| + orientation);
|
| + return;
|
| + }
|
| +
|
| + NOTREACHED();
|
| + return;
|
| }
|
|
|
| -Vector<double> SnapCoordinator::SnapOffsets(const ContainerNode& element,
|
| +/*Vector<double> SnapCoordinator::SnapOffsets(const ContainerNode& element,
|
| ScrollbarOrientation orientation) {
|
| const ComputedStyle* style = element.GetComputedStyle();
|
| const LayoutBox* snap_container = element.GetLayoutBox();
|
| @@ -110,12 +207,20 @@ Vector<double> SnapCoordinator::SnapOffsets(const ContainerNode& element,
|
|
|
| Vector<double> result;
|
|
|
| - if (style->GetScrollSnapType() == kScrollSnapTypeNone)
|
| + SnapAxis axis = style->GetScrollSnapType().axis;
|
| + if (axis == kSnapAxisNone ||
|
| + (axis == kSnapAxisX && orientation == kVerticalScrollbar) ||
|
| + (axis == kSnapAxisY && orientation == kHorizontalScrollbar) ||
|
| + (axis == kSnapAxisInline && style->IsHorizontalWritingMode() &&
|
| + orientation == kVerticalScrollbar) ||
|
| + (axis == kSnapAxisInline && !style->IsHorizontalWritingMode() &&
|
| + orientation == kHorizontalScrollbar) ||
|
| + (axis == kSnapAxisBlock && style->IsHorizontalWritingMode() &&
|
| + orientation == kHorizontalScrollbar) ||
|
| + (axis == kSnapAxisBlock && !style->IsHorizontalWritingMode() &&
|
| + orientation == kVerticalScrollbar)) {
|
| return result;
|
| -
|
| - const ScrollSnapPoints& snap_points = (orientation == kHorizontalScrollbar)
|
| - ? style->ScrollSnapPointsX()
|
| - : style->ScrollSnapPointsY();
|
| + }
|
|
|
| LayoutUnit client_size = (orientation == kHorizontalScrollbar)
|
| ? snap_container->ClientWidth()
|
| @@ -124,31 +229,15 @@ Vector<double> SnapCoordinator::SnapOffsets(const ContainerNode& element,
|
| ? snap_container->ScrollWidth()
|
| : snap_container->ScrollHeight();
|
|
|
| - if (snap_points.has_repeat) {
|
| - LayoutUnit repeat = ValueForLength(snap_points.repeat_offset, client_size);
|
| -
|
| - // calc() values may be negative or zero in which case we clamp them to 1px.
|
| - // See: https://lists.w3.org/Archives/Public/www-style/2015Jul/0075.html
|
| - repeat = std::max<LayoutUnit>(repeat, LayoutUnit(1));
|
| - for (LayoutUnit offset = repeat; offset <= (scroll_size - client_size);
|
| - offset += repeat) {
|
| - result.push_back(offset.ToFloat());
|
| - }
|
| - }
|
| -
|
| // Compute element-based snap points by mapping the snap coordinates from
|
| // snap areas to snap container.
|
| bool did_add_snap_area_offset = false;
|
| if (SnapAreaSet* snap_areas = snap_container->SnapAreas()) {
|
| for (auto& snap_area : *snap_areas) {
|
| - Vector<FloatPoint> snap_coordinates =
|
| - LocalToContainerSnapCoordinates(*snap_container, *snap_area);
|
| - for (const FloatPoint& snap_coordinate : snap_coordinates) {
|
| - float snap_offset = (orientation == kHorizontalScrollbar)
|
| - ? snap_coordinate.X()
|
| - : snap_coordinate.Y();
|
| - if (snap_offset > scroll_size - client_size)
|
| - continue;
|
| + float snap_offset = AlignmentToContainerSnapCoordinates(
|
| + *snap_container, *snap_area, orientation);
|
| + // TODO(sunyunjia): Is the border already added?
|
| + if (snap_offset >= 0 && snap_offset <= scroll_size - client_size) {
|
| result.push_back(snap_offset);
|
| did_add_snap_area_offset = true;
|
| }
|
| @@ -159,6 +248,36 @@ Vector<double> SnapCoordinator::SnapOffsets(const ContainerNode& element,
|
| std::sort(result.begin(), result.end());
|
|
|
| return result;
|
| +}*/
|
| +
|
| +WebSnapPointList SnapCoordinator::SnapOffsets(const ContainerNode& element) {
|
| + const ComputedStyle* style = element.GetComputedStyle();
|
| + const LayoutBox* snap_container = element.GetLayoutBox();
|
| + DCHECK(style);
|
| + DCHECK(snap_container);
|
| +
|
| + WebSnapPointList result;
|
| + SnapAxis axis = style->GetScrollSnapType().axis;
|
| + bool snap_on_x =
|
| + (axis == kSnapAxisX || axis == kSnapAxisBoth ||
|
| + (axis == kSnapAxisInline && style->IsHorizontalWritingMode()) ||
|
| + (axis == kSnapAxisBlock && !style->IsHorizontalWritingMode()));
|
| + bool snap_on_y =
|
| + (axis == kSnapAxisY || axis == kSnapAxisBoth ||
|
| + (axis == kSnapAxisBlock && style->IsHorizontalWritingMode()) ||
|
| + (axis == kSnapAxisInline && !style->IsHorizontalWritingMode()));
|
| +
|
| + if (SnapAreaSet* snap_areas = snap_container->SnapAreas()) {
|
| + for (auto& snap_area : *snap_areas) {
|
| + if (snap_on_x)
|
| + AddSnapArea(*snap_container, *snap_area, kSnapX, &result);
|
| + if (snap_on_y)
|
| + AddSnapArea(*snap_container, *snap_area, kSnapY, &result);
|
| + }
|
| + }
|
| +
|
| + result.Sort();
|
| + return result;
|
| }
|
|
|
| #ifndef NDEBUG
|
|
|