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

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp

Issue 2749313002: Move slider implemention to use pointer capture (Closed)
Patch Set: Created 3 years, 9 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 unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are 6 * modification, are permitted provided that the following conditions are
7 * met: 7 * met:
8 * 8 *
9 * * Redistributions of source code must retain the above copyright 9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 16 matching lines...) Expand all
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32 #include "core/html/shadow/SliderThumbElement.h" 32 #include "core/html/shadow/SliderThumbElement.h"
33 33
34 #include "core/dom/shadow/ShadowRoot.h" 34 #include "core/dom/shadow/ShadowRoot.h"
35 #include "core/events/Event.h" 35 #include "core/events/Event.h"
36 #include "core/events/MouseEvent.h" 36 #include "core/events/MouseEvent.h"
37 #include "core/events/PointerEvent.h"
37 #include "core/events/TouchEvent.h" 38 #include "core/events/TouchEvent.h"
38 #include "core/frame/EventHandlerRegistry.h" 39 #include "core/frame/EventHandlerRegistry.h"
39 #include "core/frame/LocalFrame.h" 40 #include "core/frame/LocalFrame.h"
40 #include "core/html/HTMLInputElement.h" 41 #include "core/html/HTMLInputElement.h"
41 #include "core/html/forms/StepRange.h" 42 #include "core/html/forms/StepRange.h"
42 #include "core/html/parser/HTMLParserIdioms.h" 43 #include "core/html/parser/HTMLParserIdioms.h"
43 #include "core/html/shadow/ShadowElementNames.h" 44 #include "core/html/shadow/ShadowElementNames.h"
44 #include "core/input/EventHandler.h" 45 #include "core/input/EventHandler.h"
45 #include "core/layout/LayoutSliderContainer.h" 46 #include "core/layout/LayoutSliderContainer.h"
46 #include "core/layout/LayoutSliderThumb.h" 47 #include "core/layout/LayoutSliderThumb.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 } 89 }
89 90
90 bool SliderThumbElement::matchesReadWritePseudoClass() const { 91 bool SliderThumbElement::matchesReadWritePseudoClass() const {
91 return hostInput() && hostInput()->matchesReadWritePseudoClass(); 92 return hostInput() && hostInput()->matchesReadWritePseudoClass();
92 } 93 }
93 94
94 Node* SliderThumbElement::focusDelegate() { 95 Node* SliderThumbElement::focusDelegate() {
95 return hostInput(); 96 return hostInput();
96 } 97 }
97 98
98 void SliderThumbElement::dragFrom(const LayoutPoint& point) { 99 void SliderThumbElement::dragFrom(const PointerEvent* event) {
mustaq 2017/03/15 18:15:41 Please rename |dragFrom| to something like |initia
99 startDragging(); 100 requestPointerCapture(event->pointerId());
100 setPositionFromPoint(point); 101 setPositionFromPoint(LayoutPoint(event->absoluteLocation()));
101 } 102 }
102 103
103 void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point) { 104 void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point) {
104 HTMLInputElement* input(hostInput()); 105 HTMLInputElement* input(hostInput());
105 Element* trackElement = input->userAgentShadowRoot()->getElementById( 106 Element* trackElement = input->userAgentShadowRoot()->getElementById(
106 ShadowElementNames::sliderTrack()); 107 ShadowElementNames::sliderTrack());
107 108
108 if (!input->layoutObject() || !layoutBox() || !trackElement->layoutBox()) 109 if (!input->layoutObject() || !layoutBox() || !trackElement->layoutBox())
109 return; 110 return;
110 111
111 LayoutPoint offset = LayoutPoint( 112 LayoutPoint offset = LayoutPoint(
112 input->layoutObject()->absoluteToLocal(FloatPoint(point), UseTransforms)); 113 input->layoutObject()->absoluteToLocal(FloatPoint(point), UseTransforms));
113 bool isVertical = hasVerticalAppearance(input); 114 bool isVertical = hasVerticalAppearance(input);
114 bool isLeftToRightDirection = layoutBox()->style()->isLeftToRightDirection(); 115 bool isLeftToRightDirection = layoutBox()->style()->isLeftToRightDirection();
115 LayoutUnit trackSize; 116 LayoutUnit trackSize;
116 LayoutUnit position; 117 LayoutUnit position;
117 LayoutUnit currentPosition; 118 LayoutUnit currentPosition;
118 // We need to calculate currentPosition from absolute points becaue the 119 // We need to calculate currentPosition from absolute points because the
119 // layoutObject for this node is usually on a layer and layoutBox()->x() and 120 // layoutObject for this node is usually on a layer and layoutBox()->x() and
120 // y() are unusable. 121 // y() are unusable.
121 // FIXME: This should probably respect transforms. 122 // FIXME: This should probably respect transforms.
122 LayoutPoint absoluteThumbOrigin = 123 LayoutPoint absoluteThumbOrigin =
123 layoutBox()->absoluteBoundingBoxRectIgnoringTransforms().location(); 124 layoutBox()->absoluteBoundingBoxRectIgnoringTransforms().location();
124 LayoutPoint absoluteSliderContentOrigin = 125 LayoutPoint absoluteSliderContentOrigin =
125 LayoutPoint(input->layoutObject()->localToAbsolute()); 126 LayoutPoint(input->layoutObject()->localToAbsolute());
126 IntRect trackBoundingBox = 127 IntRect trackBoundingBox =
127 trackElement->layoutObject()->absoluteBoundingBoxRectIgnoringTransforms(); 128 trackElement->layoutObject()->absoluteBoundingBoxRectIgnoringTransforms();
128 IntRect inputBoundingBox = 129 IntRect inputBoundingBox =
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 return; 169 return;
169 170
170 // FIXME: This is no longer being set from renderer. Consider updating the 171 // FIXME: This is no longer being set from renderer. Consider updating the
171 // method name. 172 // method name.
172 input->setValueFromRenderer(valueString); 173 input->setValueFromRenderer(valueString);
173 if (layoutObject()) 174 if (layoutObject())
174 layoutObject()->setNeedsLayoutAndFullPaintInvalidation( 175 layoutObject()->setNeedsLayoutAndFullPaintInvalidation(
175 LayoutInvalidationReason::SliderValueChanged); 176 LayoutInvalidationReason::SliderValueChanged);
176 } 177 }
177 178
178 void SliderThumbElement::startDragging() { 179 inline void SliderThumbElement::startDragging() {
179 if (LocalFrame* frame = document().frame()) { 180 m_inDragMode = true;
180 frame->eventHandler().setCapturingMouseEventsNode(this);
181 m_inDragMode = true;
182 }
183 } 181 }
184 182
185 void SliderThumbElement::stopDragging() { 183 void SliderThumbElement::stopDragging() {
186 if (!m_inDragMode) 184 if (!m_inDragMode)
187 return; 185 return;
188
189 if (LocalFrame* frame = document().frame())
190 frame->eventHandler().setCapturingMouseEventsNode(nullptr);
191 m_inDragMode = false; 186 m_inDragMode = false;
192 if (layoutObject()) 187 if (layoutObject())
193 layoutObject()->setNeedsLayoutAndFullPaintInvalidation( 188 layoutObject()->setNeedsLayoutAndFullPaintInvalidation(
194 LayoutInvalidationReason::SliderValueChanged); 189 LayoutInvalidationReason::SliderValueChanged);
195 if (hostInput()) 190 if (hostInput())
196 hostInput()->dispatchFormControlChangeEvent(); 191 hostInput()->dispatchFormControlChangeEvent();
197 } 192 }
198 193
194 void SliderThumbElement::requestPointerCapture(int pointerId) {
195 if (LocalFrame* frame = document().frame()) {
196 frame->eventHandler().setPointerCapture(pointerId, this);
197 m_requestedPointerIdToCapture = pointerId;
198 }
199 }
200
201 void SliderThumbElement::releasePointerCapture() {
202 if (LocalFrame* frame = document().frame()) {
203 frame->eventHandler().releasePointerCapture(m_requestedPointerIdToCapture,
204 this);
205 }
206 }
207
199 void SliderThumbElement::defaultEventHandler(Event* event) { 208 void SliderThumbElement::defaultEventHandler(Event* event) {
200 if (!event->isMouseEvent()) { 209 if (!event->isPointerEvent()) {
201 HTMLDivElement::defaultEventHandler(event); 210 HTMLDivElement::defaultEventHandler(event);
202 return; 211 return;
203 } 212 }
213 PointerEvent* pointerEvent = toPointerEvent(event);
214
215 if (pointerEvent->type() == EventTypeNames::gotpointercapture &&
216 m_requestedPointerIdToCapture == pointerEvent->pointerId()) {
217 startDragging();
218 return;
219 }
220
221 if (pointerEvent->type() == EventTypeNames::lostpointercapture) {
222 stopDragging();
223 return;
224 }
204 225
205 // FIXME: Should handle this readonly/disabled check in more general way. 226 // FIXME: Should handle this readonly/disabled check in more general way.
206 // Missing this kind of check is likely to occur elsewhere if adding it in 227 // Missing this kind of check is likely to occur elsewhere if adding it in
207 // each shadow element. 228 // each shadow element.
208 HTMLInputElement* input = hostInput(); 229 HTMLInputElement* input = hostInput();
209 if (!input || input->isDisabledFormControl()) { 230 if (!input || input->isDisabledFormControl()) {
210 stopDragging(); 231 stopDragging();
211 HTMLDivElement::defaultEventHandler(event); 232 HTMLDivElement::defaultEventHandler(event);
212 return; 233 return;
213 } 234 }
214 235
215 MouseEvent* mouseEvent = toMouseEvent(event); 236 bool isLeftButton = pointerEvent->button() ==
216 bool isLeftButton = mouseEvent->button() ==
217 static_cast<short>(WebPointerProperties::Button::Left); 237 static_cast<short>(WebPointerProperties::Button::Left);
238 bool isLeftButtonActive =
239 pointerEvent->buttons() &
240 static_cast<short>(WebPointerProperties::Button::Left);
218 const AtomicString& eventType = event->type(); 241 const AtomicString& eventType = event->type();
219 242
220 // We intentionally do not call event->setDefaultHandled() here because 243 // We intentionally do not call event->setDefaultHandled() here because
221 // MediaControlTimelineElement::defaultEventHandler() wants to handle these 244 // MediaControlTimelineElement::defaultEventHandler() wants to handle these
222 // mouse events. 245 // mouse events.
223 if (eventType == EventTypeNames::mousedown && isLeftButton) { 246 if ((eventType == EventTypeNames::pointerdown ||
224 startDragging(); 247 eventType == EventTypeNames::pointermove) &&
248 isLeftButton && isLeftButtonActive) {
249 requestPointerCapture(pointerEvent->pointerId());
mustaq 2017/03/15 18:15:41 So a chorded L-down would start dragging here, rig
225 return; 250 return;
226 } 251 }
227 if (eventType == EventTypeNames::mouseup && isLeftButton) { 252 if ((eventType == EventTypeNames::pointerup ||
mustaq 2017/03/15 18:15:41 May be just |if (!isLeftButtonActive) {} |?
228 stopDragging(); 253 eventType == EventTypeNames::pointermove) &&
254 isLeftButton && !isLeftButtonActive) {
255 releasePointerCapture();
229 return; 256 return;
230 } 257 }
231 if (eventType == EventTypeNames::mousemove) { 258 if (eventType == EventTypeNames::pointermove) {
232 if (m_inDragMode) 259 if (m_inDragMode)
233 setPositionFromPoint(LayoutPoint(mouseEvent->absoluteLocation())); 260 setPositionFromPoint(LayoutPoint(pointerEvent->absoluteLocation()));
234 return; 261 return;
235 } 262 }
236 263
237 HTMLDivElement::defaultEventHandler(event); 264 HTMLDivElement::defaultEventHandler(event);
mustaq 2017/03/15 18:15:41 Why not skip this? Is this "safe"? Passing pointer
238 } 265 }
239 266
240 bool SliderThumbElement::willRespondToMouseMoveEvents() { 267 bool SliderThumbElement::willRespondToMouseMoveEvents() {
241 const HTMLInputElement* input = hostInput(); 268 const HTMLInputElement* input = hostInput();
242 if (input && !input->isDisabledFormControl() && m_inDragMode) 269 if (input && !input->isDisabledFormControl() && m_inDragMode)
243 return true; 270 return true;
244 271
245 return HTMLDivElement::willRespondToMouseMoveEvents(); 272 return HTMLDivElement::willRespondToMouseMoveEvents();
246 } 273 }
247 274
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 HTMLInputElement* SliderContainerElement::hostInput() const { 340 HTMLInputElement* SliderContainerElement::hostInput() const {
314 return toHTMLInputElement(ownerShadowHost()); 341 return toHTMLInputElement(ownerShadowHost());
315 } 342 }
316 343
317 LayoutObject* SliderContainerElement::createLayoutObject(const ComputedStyle&) { 344 LayoutObject* SliderContainerElement::createLayoutObject(const ComputedStyle&) {
318 return new LayoutSliderContainer(this); 345 return new LayoutSliderContainer(this);
319 } 346 }
320 347
321 void SliderContainerElement::defaultEventHandler(Event* event) { 348 void SliderContainerElement::defaultEventHandler(Event* event) {
322 if (event->isTouchEvent()) { 349 if (event->isTouchEvent()) {
323 handleTouchEvent(toTouchEvent(event)); 350 handleTouchEvent(toTouchEvent(event));
mustaq 2017/03/15 18:40:41 The slider-container takes care of the TEs, which
324 return; 351 return;
325 } 352 }
326 } 353 }
327 354
328 void SliderContainerElement::handleTouchEvent(TouchEvent* event) { 355 void SliderContainerElement::handleTouchEvent(TouchEvent* event) {
329 HTMLInputElement* input = hostInput(); 356 HTMLInputElement* input = hostInput();
330 if (input->isDisabledFormControl()) 357 if (input->isDisabledFormControl())
331 return; 358 return;
332 359
333 if (event->type() == EventTypeNames::touchend) { 360 if (event->type() == EventTypeNames::touchend) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 updateTouchEventHandlerRegistry(); 474 updateTouchEventHandlerRegistry();
448 HTMLElement::didMoveToNewDocument(oldDocument); 475 HTMLElement::didMoveToNewDocument(oldDocument);
449 } 476 }
450 477
451 void SliderContainerElement::removeAllEventListeners() { 478 void SliderContainerElement::removeAllEventListeners() {
452 Node::removeAllEventListeners(); 479 Node::removeAllEventListeners();
453 m_hasTouchEventHandler = false; 480 m_hasTouchEventHandler = false;
454 } 481 }
455 482
456 } // namespace blink 483 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698