| Index: third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp b/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
|
| index 40baeeb07c8448ab3af006fe57b275ac6d5ae3d5..3f147c3489f62434f5a7ec79f692fb61b8fdb747 100644
|
| --- a/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
|
| +++ b/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
|
| @@ -34,6 +34,8 @@
|
| #include "core/dom/shadow/ShadowRoot.h"
|
| #include "core/events/Event.h"
|
| #include "core/events/MouseEvent.h"
|
| +#include "core/events/TouchEvent.h"
|
| +#include "core/frame/EventHandlerRegistry.h"
|
| #include "core/frame/LocalFrame.h"
|
| #include "core/html/HTMLInputElement.h"
|
| #include "core/html/forms/StepRange.h"
|
| @@ -299,16 +301,106 @@ const AtomicString& SliderThumbElement::shadowPseudoId() const
|
|
|
| inline SliderContainerElement::SliderContainerElement(Document& document)
|
| : HTMLDivElement(document)
|
| + , m_hasTouchEventHandler(false)
|
| + , m_touchStarted(false)
|
| + , m_slidingDirection(NoMove)
|
| {
|
| + updateTouchEventHandlerRegistry();
|
| }
|
|
|
| DEFINE_NODE_FACTORY(SliderContainerElement)
|
|
|
| +HTMLInputElement* SliderContainerElement::hostInput() const
|
| +{
|
| + return toHTMLInputElement(shadowHost());
|
| +}
|
| +
|
| LayoutObject* SliderContainerElement::createLayoutObject(const ComputedStyle&)
|
| {
|
| return new LayoutSliderContainer(this);
|
| }
|
|
|
| +void SliderContainerElement::defaultEventHandler(Event* event)
|
| +{
|
| + if (event->isTouchEvent()) {
|
| + handleTouchEvent(toTouchEvent(event));
|
| + return;
|
| + }
|
| +}
|
| +
|
| +void SliderContainerElement::handleTouchEvent(TouchEvent* event)
|
| +{
|
| + HTMLInputElement* input = hostInput();
|
| + if (input->isDisabledOrReadOnly())
|
| + return;
|
| +
|
| + if (event->type() == EventTypeNames::touchend) {
|
| + input->dispatchFormControlChangeEvent();
|
| + event->setDefaultHandled();
|
| + m_slidingDirection = NoMove;
|
| + m_touchStarted = false;
|
| + return;
|
| + }
|
| +
|
| + // The direction of this series of touch actions has been determined, which is
|
| + // perpendicular to the slider, so no need to adjust the value.
|
| + if (!canSlide()) {
|
| + return;
|
| + }
|
| +
|
| + TouchList* touches = event->targetTouches();
|
| + SliderThumbElement* thumb = toSliderThumbElement(treeScope().getElementById(ShadowElementNames::sliderThumb()));
|
| + if (touches->length() == 1) {
|
| + if (event->type() == EventTypeNames::touchstart) {
|
| + m_startPoint = touches->item(0)->absoluteLocation();
|
| + m_slidingDirection = NoMove;
|
| + m_touchStarted = true;
|
| + thumb->setPositionFromPoint(touches->item(0)->absoluteLocation());
|
| + } else if (m_touchStarted) {
|
| + LayoutPoint currentPoint = touches->item(0)->absoluteLocation();
|
| + if (m_slidingDirection == NoMove) { // Still needs to update the direction.
|
| + m_slidingDirection = getDirection(currentPoint, m_startPoint);
|
| + }
|
| +
|
| + // m_slidingDirection has been updated, so check whether it's okay to slide again.
|
| + if (canSlide()) {
|
| + thumb->setPositionFromPoint(touches->item(0)->absoluteLocation());
|
| + event->setDefaultHandled();
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +SliderContainerElement::Direction SliderContainerElement::getDirection(LayoutPoint& point1, LayoutPoint& point2)
|
| +{
|
| + if (point1 == point2) {
|
| + return NoMove;
|
| + }
|
| + if ((point1.x() - point2.x()).abs() >= (point1.y() - point2.y()).abs()) {
|
| + return Horizontal;
|
| + }
|
| + return Vertical;
|
| +}
|
| +
|
| +bool SliderContainerElement::canSlide()
|
| +{
|
| + DCHECK(hostInput()->layoutObject());
|
| + const ComputedStyle& sliderStyle = hostInput()->layoutObject()->styleRef();
|
| + const TransformOperations& transforms = sliderStyle.transform();
|
| + int transformSize = transforms.size();
|
| + if (transformSize > 0) {
|
| + for (int i = 0; i < transformSize; ++i) {
|
| + if (transforms.at(i)->type() == TransformOperation::Rotate) {
|
| + return true;
|
| + }
|
| + }
|
| + }
|
| + if ((m_slidingDirection == Vertical && sliderStyle.appearance() == SliderHorizontalPart) || (m_slidingDirection == Horizontal && sliderStyle.appearance() == SliderVerticalPart)) {
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| const AtomicString& SliderContainerElement::shadowPseudoId() const
|
| {
|
| DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container"));
|
| @@ -331,4 +423,28 @@ const AtomicString& SliderContainerElement::shadowPseudoId() const
|
| }
|
| }
|
|
|
| +void SliderContainerElement::updateTouchEventHandlerRegistry()
|
| +{
|
| + if (m_hasTouchEventHandler) {
|
| + return;
|
| + }
|
| + if (document().frameHost() && document().lifecycle().state() < DocumentLifecycle::Stopping) {
|
| + EventHandlerRegistry& registry = document().frameHost()->eventHandlerRegistry();
|
| + registry.didAddEventHandler(*this, EventHandlerRegistry::TouchStartOrMoveEventPassive);
|
| + m_hasTouchEventHandler = true;
|
| + }
|
| +}
|
| +
|
| +void SliderContainerElement::didMoveToNewDocument(Document& oldDocument)
|
| +{
|
| + updateTouchEventHandlerRegistry();
|
| + HTMLElement::didMoveToNewDocument(oldDocument);
|
| +}
|
| +
|
| +void SliderContainerElement::removeAllEventListeners()
|
| +{
|
| + Node::removeAllEventListeners();
|
| + m_hasTouchEventHandler = false;
|
| +}
|
| +
|
| } // namespace blink
|
|
|