Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "core/animation/ScrollTimeline.h" | |
| 6 | |
| 7 #include "core/dom/ExceptionCode.h" | |
| 8 #include "core/layout/LayoutBox.h" | |
| 9 #include "core/paint/PaintLayerScrollableArea.h" | |
| 10 | |
| 11 namespace blink { | |
| 12 | |
| 13 namespace { | |
| 14 bool StringToScrollDirection(String scroll_direction, | |
| 15 ScrollTimeline::ScrollDirection* result) { | |
| 16 if (scroll_direction == "auto") { | |
| 17 *result = ScrollTimeline::Auto; | |
| 18 return true; | |
| 19 } | |
| 20 if (scroll_direction == "block") { | |
| 21 *result = ScrollTimeline::Block; | |
| 22 return true; | |
| 23 } | |
| 24 if (scroll_direction == "inline") { | |
| 25 *result = ScrollTimeline::Inline; | |
| 26 return true; | |
| 27 } | |
| 28 return false; | |
| 29 } | |
| 30 } // namespace | |
| 31 | |
| 32 ScrollTimeline* ScrollTimeline::Create(const Document& document, | |
| 33 ScrollTimelineOptions options, | |
| 34 ExceptionState& exception_state) { | |
| 35 // TODO(smcgruer): The spec allows for a null scrollSource. | |
|
majidvp
2017/05/15 14:38:52
Hmmm, I presume that if the scrollSource is not sp
smcgruer
2017/05/15 15:22:54
Nope, spec defines it as follows (https://wicg.git
flackr
2017/05/15 17:29:06
Note, probably should be the document.scrollingEle
smcgruer
2017/05/16 19:24:47
Filed https://github.com/WICG/scroll-animations/is
| |
| 36 if (!options.scrollSource()) { | |
| 37 exception_state.ThrowDOMException(kNotSupportedError, | |
| 38 "A scrollSource must be specified"); | |
| 39 return nullptr; | |
| 40 } | |
| 41 | |
| 42 ScrollDirection orientation; | |
| 43 if (!StringToScrollDirection(options.orientation(), &orientation)) { | |
| 44 exception_state.ThrowDOMException(kNotSupportedError, | |
| 45 "Invalid orientation"); | |
| 46 return nullptr; | |
| 47 } | |
| 48 | |
| 49 // TODO(smcgruer): Support 'auto' value. | |
| 50 if (options.timeRange().isScrollTimelineAutoKeyword()) { | |
| 51 exception_state.ThrowDOMException( | |
| 52 kNotSupportedError, "'auto' value for timeRange not yet supported"); | |
| 53 } | |
| 54 | |
| 55 return new ScrollTimeline(document, options.scrollSource(), orientation, | |
| 56 options.timeRange().getAsDouble()); | |
| 57 } | |
| 58 | |
| 59 ScrollTimeline::ScrollTimeline(const Document& document, | |
| 60 Element* scroll_source, | |
| 61 ScrollDirection orientation, | |
| 62 double time_range) | |
| 63 : AnimationTimeline(const_cast<Document*>(&document), nullptr), | |
| 64 scroll_source_(scroll_source), | |
| 65 orientation_(orientation), | |
| 66 time_range_(time_range) {} | |
| 67 | |
| 68 double ScrollTimeline::currentTime(bool& is_null) { | |
| 69 // 1. If scrollSource does not currently have a CSS layout box, or if its | |
| 70 // layout box is not a scroll container, return an unresolved time value. | |
| 71 LayoutBox* layout_box = scroll_source_->GetLayoutBox(); | |
| 72 if (!layout_box || !layout_box->GetScrollableArea()) { | |
|
majidvp
2017/05/15 14:38:52
I don't think layout_box->GetScrollableArea() maps
smcgruer
2017/05/15 15:22:54
Ah, so looks like by the spec we just want to chec
flackr
2017/05/15 17:29:06
LayoutObject::HasOverflowClip
smcgruer
2017/05/16 19:24:47
Done.
| |
| 73 LOG(INFO) << "!layout_box || !layout_box->GetScrollableArea()"; | |
| 74 is_null = true; | |
| 75 return std::numeric_limits<double>::quiet_NaN(); | |
| 76 } | |
| 77 | |
| 78 // 2. Otherwise, let current scroll offset be the current scroll offset of | |
| 79 // scrollSource in the direction specified by orientation. | |
| 80 ScrollDirection local_orientation = orientation_; | |
| 81 if (local_orientation == Auto) { | |
| 82 // If only one direction is scrollable, selects that direction. Otherwise | |
| 83 // selects the direction along the block axis. | |
| 84 DCHECK(layout_box->HasScrollableOverflowX() || | |
| 85 layout_box->HasScrollableOverflowY()); | |
|
flackr
2017/05/15 17:29:06
I don't think this check is correct. We could have
smcgruer
2017/05/17 15:52:03
Done.
| |
| 86 local_orientation = layout_box->HasScrollableOverflowY() ? Block : Inline; | |
|
flackr
2017/05/15 17:29:06
Isn't this assuming LTR? I think you'd have to che
smcgruer
2017/05/17 15:52:02
Done.
| |
| 87 } | |
| 88 double current_scroll_offset = 0.0; | |
| 89 double max_scroll_offset = 1.0; | |
| 90 switch (local_orientation) { | |
| 91 case Block: | |
| 92 current_scroll_offset = scroll_source_->scrollTop(); | |
| 93 max_scroll_offset = | |
| 94 scroll_source_->scrollHeight() - scroll_source_->clientHeight(); | |
|
majidvp
2017/05/15 14:38:52
Shouldn't we use the logical coordinates here as o
smcgruer
2017/05/15 15:22:54
Possibly. I just wrote this based on a comment in
smcgruer
2017/05/17 15:52:02
Done.
| |
| 95 break; | |
| 96 case Inline: | |
| 97 current_scroll_offset = scroll_source_->scrollLeft(); | |
| 98 max_scroll_offset = | |
| 99 scroll_source_->scrollWidth() - scroll_source_->clientWidth(); | |
| 100 break; | |
| 101 case Auto: | |
| 102 LOG(FATAL) << "local_orientation cannot be Auto"; | |
| 103 break; | |
| 104 } | |
| 105 | |
| 106 // 3. If current scroll offset is less than startScrollOffset, return an | |
| 107 // unresolved time value if fill is none or forwards, or 0 otherwise. | |
| 108 // TODO(smcgruer): Implement |startScrollOffset| and |fill|. | |
| 109 | |
| 110 // 4. If current scroll offset is greater than or equal to endScrollOffset, | |
| 111 // return an unresolved time value if fill is none or backwards, or the | |
| 112 // effective time range otherwise. | |
| 113 // TODO(smcgruer): Implement |endScrollOffset| and |fill|. | |
| 114 | |
| 115 // 5. Return the result of evaluating the following expression: | |
| 116 // ((current scroll offset - startScrollOffset) / | |
| 117 // (endScrollOffset - startScrollOffset)) * effective time range | |
| 118 | |
| 119 is_null = false; | |
| 120 return (current_scroll_offset / max_scroll_offset) * time_range_; | |
| 121 } | |
| 122 | |
| 123 double ScrollTimeline::currentTime() { | |
| 124 bool ignored; | |
| 125 return currentTime(ignored); | |
| 126 } | |
| 127 | |
| 128 double ScrollTimeline::CurrentTimeInternal(bool& is_null) { | |
| 129 return currentTime(is_null); | |
| 130 } | |
| 131 | |
| 132 double ScrollTimeline::CurrentTimeInternal() { | |
| 133 bool ignored; | |
| 134 return currentTime(ignored); | |
| 135 } | |
| 136 | |
| 137 Element* ScrollTimeline::scrollSource() { | |
| 138 return scroll_source_.Get(); | |
| 139 } | |
| 140 | |
| 141 String ScrollTimeline::orientation() { | |
| 142 switch (orientation_) { | |
| 143 case Auto: | |
| 144 return "auto"; | |
| 145 case Block: | |
| 146 return "block"; | |
| 147 case Inline: | |
| 148 return "inline"; | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 void ScrollTimeline::timeRange(DoubleOrScrollTimelineAutoKeyword& result) { | |
| 153 result.setDouble(time_range_); | |
| 154 } | |
| 155 | |
| 156 DEFINE_TRACE(ScrollTimeline) { | |
| 157 visitor->Trace(scroll_source_); | |
| 158 AnimationTimeline::Trace(visitor); | |
| 159 } | |
| 160 | |
| 161 } // namespace blink | |
| OLD | NEW |