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/TouchEvent.h" |
| 38 #include "core/frame/EventHandlerRegistry.h" |
37 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
38 #include "core/html/HTMLInputElement.h" | 40 #include "core/html/HTMLInputElement.h" |
39 #include "core/html/forms/StepRange.h" | 41 #include "core/html/forms/StepRange.h" |
40 #include "core/html/parser/HTMLParserIdioms.h" | 42 #include "core/html/parser/HTMLParserIdioms.h" |
41 #include "core/html/shadow/ShadowElementNames.h" | 43 #include "core/html/shadow/ShadowElementNames.h" |
42 #include "core/input/EventHandler.h" | 44 #include "core/input/EventHandler.h" |
43 #include "core/layout/LayoutSliderContainer.h" | 45 #include "core/layout/LayoutSliderContainer.h" |
44 #include "core/layout/LayoutSliderThumb.h" | 46 #include "core/layout/LayoutSliderThumb.h" |
45 #include "core/layout/LayoutTheme.h" | 47 #include "core/layout/LayoutTheme.h" |
46 | 48 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 return mediaSliderThumbShadowPartId(); | 294 return mediaSliderThumbShadowPartId(); |
293 default: | 295 default: |
294 return sliderThumbShadowPartId(); | 296 return sliderThumbShadowPartId(); |
295 } | 297 } |
296 } | 298 } |
297 | 299 |
298 // -------------------------------- | 300 // -------------------------------- |
299 | 301 |
300 inline SliderContainerElement::SliderContainerElement(Document& document) | 302 inline SliderContainerElement::SliderContainerElement(Document& document) |
301 : HTMLDivElement(document) | 303 : HTMLDivElement(document) |
| 304 , m_hasTouchEventHandler(false) |
| 305 , m_touchStarted(false) |
| 306 , m_slidingDirection(NoMove) |
302 { | 307 { |
| 308 updateTouchEventHandlerRegistry(); |
303 } | 309 } |
304 | 310 |
305 DEFINE_NODE_FACTORY(SliderContainerElement) | 311 DEFINE_NODE_FACTORY(SliderContainerElement) |
306 | 312 |
| 313 HTMLInputElement* SliderContainerElement::hostInput() const |
| 314 { |
| 315 return toHTMLInputElement(shadowHost()); |
| 316 } |
| 317 |
307 LayoutObject* SliderContainerElement::createLayoutObject(const ComputedStyle&) | 318 LayoutObject* SliderContainerElement::createLayoutObject(const ComputedStyle&) |
308 { | 319 { |
309 return new LayoutSliderContainer(this); | 320 return new LayoutSliderContainer(this); |
310 } | 321 } |
311 | 322 |
| 323 void SliderContainerElement::defaultEventHandler(Event* event) |
| 324 { |
| 325 if (event->isTouchEvent()) { |
| 326 handleTouchEvent(toTouchEvent(event)); |
| 327 return; |
| 328 } |
| 329 } |
| 330 |
| 331 void SliderContainerElement::handleTouchEvent(TouchEvent* event) |
| 332 { |
| 333 HTMLInputElement* input = hostInput(); |
| 334 if (input->isDisabledOrReadOnly()) |
| 335 return; |
| 336 |
| 337 if (event->type() == EventTypeNames::touchend) { |
| 338 input->dispatchFormControlChangeEvent(); |
| 339 event->setDefaultHandled(); |
| 340 m_slidingDirection = NoMove; |
| 341 m_touchStarted = false; |
| 342 return; |
| 343 } |
| 344 |
| 345 // The direction of this series of touch actions has been determined, which
is |
| 346 // perpendicular to the slider, so no need to adjust the value. |
| 347 if (!canSlide()) { |
| 348 return; |
| 349 } |
| 350 |
| 351 TouchList* touches = event->targetTouches(); |
| 352 SliderThumbElement* thumb = toSliderThumbElement(treeScope().getElementById(
ShadowElementNames::sliderThumb())); |
| 353 if (touches->length() == 1) { |
| 354 if (event->type() == EventTypeNames::touchstart) { |
| 355 m_startPoint = touches->item(0)->absoluteLocation(); |
| 356 m_slidingDirection = NoMove; |
| 357 m_touchStarted = true; |
| 358 thumb->setPositionFromPoint(touches->item(0)->absoluteLocation()); |
| 359 } else if (m_touchStarted) { |
| 360 LayoutPoint currentPoint = touches->item(0)->absoluteLocation(); |
| 361 if (m_slidingDirection == NoMove) { // Still needs to update the dir
ection. |
| 362 m_slidingDirection = getDirection(currentPoint, m_startPoint); |
| 363 } |
| 364 |
| 365 // m_slidingDirection has been updated, so check whether it's okay t
o slide again. |
| 366 if (canSlide()) { |
| 367 thumb->setPositionFromPoint(touches->item(0)->absoluteLocation()
); |
| 368 event->setDefaultHandled(); |
| 369 } |
| 370 } |
| 371 } |
| 372 } |
| 373 |
| 374 SliderContainerElement::Direction SliderContainerElement::getDirection(LayoutPoi
nt& point1, LayoutPoint& point2) |
| 375 { |
| 376 if (point1 == point2) { |
| 377 return NoMove; |
| 378 } |
| 379 if ((point1.x() - point2.x()).abs() >= (point1.y() - point2.y()).abs()) { |
| 380 return Horizontal; |
| 381 } |
| 382 return Vertical; |
| 383 } |
| 384 |
| 385 bool SliderContainerElement::canSlide() |
| 386 { |
| 387 DCHECK(hostInput()->layoutObject()); |
| 388 const ComputedStyle& sliderStyle = hostInput()->layoutObject()->styleRef(); |
| 389 const TransformOperations& transforms = sliderStyle.transform(); |
| 390 int transformSize = transforms.size(); |
| 391 if (transformSize > 0) { |
| 392 for (int i = 0; i < transformSize; ++i) { |
| 393 if (transforms.at(i)->type() == TransformOperation::Rotate) { |
| 394 return true; |
| 395 } |
| 396 } |
| 397 } |
| 398 if ((m_slidingDirection == Vertical && sliderStyle.appearance() == SliderHor
izontalPart) || (m_slidingDirection == Horizontal && sliderStyle.appearance() ==
SliderVerticalPart)) { |
| 399 return false; |
| 400 } |
| 401 return true; |
| 402 } |
| 403 |
312 const AtomicString& SliderContainerElement::shadowPseudoId() const | 404 const AtomicString& SliderContainerElement::shadowPseudoId() const |
313 { | 405 { |
314 DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-medi
a-slider-container")); | 406 DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-medi
a-slider-container")); |
315 DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-co
ntainer")); | 407 DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-co
ntainer")); |
316 | 408 |
317 if (!shadowHost() || !shadowHost()->layoutObject()) | 409 if (!shadowHost() || !shadowHost()->layoutObject()) |
318 return sliderContainer; | 410 return sliderContainer; |
319 | 411 |
320 const ComputedStyle& sliderStyle = shadowHost()->layoutObject()->styleRef(); | 412 const ComputedStyle& sliderStyle = shadowHost()->layoutObject()->styleRef(); |
321 switch (sliderStyle.appearance()) { | 413 switch (sliderStyle.appearance()) { |
322 case MediaSliderPart: | 414 case MediaSliderPart: |
323 case MediaSliderThumbPart: | 415 case MediaSliderThumbPart: |
324 case MediaVolumeSliderPart: | 416 case MediaVolumeSliderPart: |
325 case MediaVolumeSliderThumbPart: | 417 case MediaVolumeSliderThumbPart: |
326 case MediaFullScreenVolumeSliderPart: | 418 case MediaFullScreenVolumeSliderPart: |
327 case MediaFullScreenVolumeSliderThumbPart: | 419 case MediaFullScreenVolumeSliderThumbPart: |
328 return mediaSliderContainer; | 420 return mediaSliderContainer; |
329 default: | 421 default: |
330 return sliderContainer; | 422 return sliderContainer; |
331 } | 423 } |
332 } | 424 } |
333 | 425 |
| 426 void SliderContainerElement::updateTouchEventHandlerRegistry() |
| 427 { |
| 428 if (m_hasTouchEventHandler) { |
| 429 return; |
| 430 } |
| 431 if (document().frameHost() && document().lifecycle().state() < DocumentLifec
ycle::Stopping) { |
| 432 EventHandlerRegistry& registry = document().frameHost()->eventHandlerReg
istry(); |
| 433 registry.didAddEventHandler(*this, EventHandlerRegistry::TouchStartOrMov
eEventPassive); |
| 434 m_hasTouchEventHandler = true; |
| 435 } |
| 436 } |
| 437 |
| 438 void SliderContainerElement::didMoveToNewDocument(Document& oldDocument) |
| 439 { |
| 440 updateTouchEventHandlerRegistry(); |
| 441 HTMLElement::didMoveToNewDocument(oldDocument); |
| 442 } |
| 443 |
| 444 void SliderContainerElement::removeAllEventListeners() |
| 445 { |
| 446 Node::removeAllEventListeners(); |
| 447 m_hasTouchEventHandler = false; |
| 448 } |
| 449 |
334 } // namespace blink | 450 } // namespace blink |
OLD | NEW |