Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(771)

Unified Diff: third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.cpp

Issue 2767213003: First Implementation of Snapped Points
Patch Set: Rebase and format Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « third_party/WebKit/Source/core/page/scrolling/SnapCoordinator.h ('k') | third_party/WebKit/Source/core/style/ComputedStyle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698