OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |