Chromium Code Reviews| 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..5e7772c247636e0b3e3ce0895486f1ed2d9ca590 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,101 @@ const AtomicString& SliderThumbElement::shadowPseudoId() const |
| inline SliderContainerElement::SliderContainerElement(Document& document) |
| : HTMLDivElement(document) |
| + , m_hasTouchEventHandler(false) |
| + , m_touchStarted(false) |
| + , m_slidingDirection(NoMove) |
| { |
| } |
| 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 = toHTMLInputElement(shadowHost()); |
|
tkent
2016/08/22 06:00:48
HTMLInputElement* input = hostInput();
|
| + if (input->isDisabledOrReadOnly()) |
| + return; |
| + |
| + if (event->type() == EventTypeNames::touchend) { |
| + input->dispatchFormControlChangeEvent(); |
| + event->setDefaultHandled(); |
| + m_slidingDirection = NoMove; |
| + m_touchStarted = false; |
| + return; |
| + } |
| + |
| + if (!canSlide()) { |
| + return; |
| + } |
| + |
| + TouchList* touches = event->targetTouches(); |
| + SliderThumbElement* thumb = toSliderThumbElement(input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb())); |
|
tkent
2016/08/22 06:00:48
toSliderThumbElement(treeScope()->getElementById(S
|
| + 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) { |
| + m_slidingDirection = getDirection(currentPoint, m_startPoint); |
| + } |
| + if (m_slidingDirection != NoMove && canSlide()) { |
|
tkent
2016/08/22 06:00:48
m_slidingDirection==NoMove was already check. So
|
| + 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 +418,34 @@ 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::parseAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& value) |
| +{ |
| + HTMLElement::parseAttribute(name, oldValue, value); |
| + updateTouchEventHandlerRegistry(); |
|
tkent
2016/08/22 06:00:48
I think we can move this to RangeInputType::create
|
| +} |
| + |
| +void SliderContainerElement::removeAllEventListeners() |
| +{ |
| + Node::removeAllEventListeners(); |
| + m_hasTouchEventHandler = false; |
| +} |
| + |
| } // namespace blink |