Changeset 76147 in webkit
- Timestamp:
- Jan 19, 2011 12:17:17 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r76146 r76147 1 2011-01-14 Dimitri Glazkov <dglazkov@chromium.org> 2 3 Reviewed by Darin Adler. 4 5 Remove event forwarding logic from input[type=range], simplify event flow and thumb positioning logic. 6 https://bugs.webkit.org/show_bug.cgi?id=52464 7 8 This change has two parts: 9 10 1) Utilize shadow DOM event retargeting to get rid of forwarding events 11 via render tree; 12 2) Move thumb positioning logic from RenderSlider to SliderThumbElement. 13 14 These two are highly co-dependent. It looked ugly when I tried to 15 separate them. 16 17 No change in behavior, covered by existing tests. 18 19 * html/HTMLInputElement.cpp: 20 (WebCore::HTMLInputElement::defaultEventHandler): Added invocation of 21 InputType::handleMouseDownEvent. 22 * html/InputType.cpp: 23 (WebCore::InputType::handleMouseDownEvent): Added empty decl. 24 * html/InputType.h: Added def. 25 * html/RangeInputType.cpp: 26 (WebCore::RangeInputType::handleMouseDownEvent): Added to handle the case 27 when the user clicks on the track of the slider. Also removed the 28 forwardEvent method. 29 * html/RangeInputType.h: Added/removed defs. 30 * html/shadow/SliderThumbElement.cpp: 31 (WebCore::SliderThumbElement::dragFrom): Added a helper method to start 32 dragging from any position. 33 (WebCore::SliderThumbElement::dragTo): Added a helper method to drag to 34 specified position. 35 (WebCore::SliderThumbElement::setPosition): Collapsed most of the positioning 36 logic in RenderSlider into this method, which is now a simple calculation 37 and adjusting of thumb position based on supplied coordinates. 38 (WebCore::SliderThumbElement::startDragging): Added. 39 (WebCore::SliderThumbElement::stopDragging): Added. 40 (WebCore::SliderThumbElement::defaultEventHandler): Removed most of the 41 old position-sniffing logic and replaced with simple calls to start, 42 stop, and drag the thumb. 43 * html/shadow/SliderThumbElement.h: Added defs. 44 * rendering/RenderSlider.cpp: Removed a bunch of code that is no longer 45 necessary. 46 * rendering/RenderSlider.h: Removed defs, removed now-unnecessary friendliness. 47 1 48 2011-01-19 Shane Stephens <shanestephens@google.com> 2 49 -
trunk/Source/WebCore/html/HTMLInputElement.cpp
r76115 r76147 1037 1037 } 1038 1038 1039 if (evt->isMouseEvent() && evt->type() == eventNames().mousedownEvent) { 1040 m_inputType->handleMouseDownEvent(static_cast<MouseEvent*>(evt)); 1041 if (evt->defaultHandled()) 1042 return; 1043 } 1044 1039 1045 m_inputType->forwardEvent(evt); 1040 1046 -
trunk/Source/WebCore/html/InputType.cpp
r75749 r76147 306 306 } 307 307 308 void InputType::handleMouseDownEvent(MouseEvent*) 309 { 310 } 311 308 312 void InputType::handleDOMActivateEvent(Event*) 309 313 { -
trunk/Source/WebCore/html/InputType.h
r75749 r76147 154 154 155 155 virtual void handleClickEvent(MouseEvent*); 156 virtual void handleMouseDownEvent(MouseEvent*); 156 157 virtual PassOwnPtr<ClickHandlingState> willDispatchClick(); 157 158 virtual void didDispatchClick(Event*, const ClickHandlingState&); -
trunk/Source/WebCore/html/RangeInputType.cpp
r75749 r76147 37 37 #include "HTMLParserIdioms.h" 38 38 #include "KeyboardEvent.h" 39 #include "MouseEvent.h" 40 #include "PlatformMouseEvent.h" 39 41 #include "RenderSlider.h" 40 42 #include "SliderThumbElement.h" … … 140 142 { 141 143 return rangeStepScaleFactor; 144 } 145 146 void RangeInputType::handleMouseDownEvent(MouseEvent* event) 147 { 148 if (event->button() != LeftButton || event->target() != element()) 149 return; 150 151 if (SliderThumbElement* thumb = toSliderThumbElement(element()->shadowRoot())) 152 thumb->dragFrom(event->absoluteLocation()); 142 153 } 143 154 … … 182 193 } 183 194 184 void RangeInputType::forwardEvent(Event* event)185 {186 if (element()->renderer() && (event->isMouseEvent() || event->isDragEvent() || event->isWheelEvent()))187 toRenderSlider(element()->renderer())->forwardEvent(event);188 }189 190 195 void RangeInputType::createShadowSubtree() 191 196 { -
trunk/Source/WebCore/html/RangeInputType.h
r75749 r76147 56 56 virtual double defaultStep() const; 57 57 virtual double stepScaleFactor() const; 58 virtual void handleMouseDownEvent(MouseEvent*); 58 59 virtual void handleKeydownEvent(KeyboardEvent*); 59 virtual void forwardEvent(Event*);60 60 virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const; 61 61 virtual void createShadowSubtree(); -
trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp
r75749 r76147 36 36 #include "Event.h" 37 37 #include "Frame.h" 38 #include "HTMLInputElement.h" 39 #include "HTMLParserIdioms.h" 38 40 #include "MouseEvent.h" 39 41 #include "RenderSlider.h" 40 42 #include "RenderTheme.h" 43 #include "StepRange.h" 44 #include <wtf/MathExtras.h> 45 46 using namespace std; 41 47 42 48 namespace WebCore { … … 48 54 virtual void layout(); 49 55 }; 50 51 56 52 57 RenderSliderThumb::RenderSliderThumb(Node* node) … … 81 86 } 82 87 88 void SliderThumbElement::dragFrom(const IntPoint& point) 89 { 90 setPosition(point); 91 startDragging(); 92 } 93 94 void SliderThumbElement::setPosition(const IntPoint& point) 95 { 96 HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowHost()); 97 ASSERT(input); 98 99 if (!input->renderer() || !renderer()) 100 return; 101 102 IntPoint offset = roundedIntPoint(input->renderer()->absoluteToLocal(point, false, true)); 103 RenderStyle* sliderStyle = input->renderer()->style(); 104 bool isVertical = sliderStyle->appearance() == SliderVerticalPart || sliderStyle->appearance() == MediaVolumeSliderPart; 105 106 int trackSize; 107 int position; 108 int currentPosition; 109 if (isVertical) { 110 trackSize = input->renderBox()->contentHeight() - renderBox()->height(); 111 position = offset.y() - renderBox()->height() / 2; 112 currentPosition = renderBox()->y() - input->renderBox()->contentBoxRect().y(); 113 } else { 114 trackSize = input->renderBox()->contentWidth() - renderBox()->width(); 115 position = offset.x() - renderBox()->width() / 2; 116 currentPosition = renderBox()->x() - input->renderBox()->contentBoxRect().x(); 117 } 118 position = max(0, min(position, trackSize)); 119 if (position == currentPosition) 120 return; 121 122 StepRange range(input); 123 double fraction = static_cast<double>(position) / trackSize; 124 if (isVertical) 125 fraction = 1 - fraction; 126 double value = range.clampValue(range.valueFromProportion(fraction)); 127 128 // FIXME: This is no longer being set from renderer. Consider updating the method name. 129 input->setValueFromRenderer(serializeForNumberType(value)); 130 renderer()->setNeedsLayout(true); 131 input->dispatchFormControlChangeEvent(); 132 } 133 134 void SliderThumbElement::startDragging() 135 { 136 if (Frame* frame = document()->frame()) { 137 frame->eventHandler()->setCapturingMouseEventsNode(this); 138 m_inDragMode = true; 139 } 140 } 141 142 void SliderThumbElement::stopDragging() 143 { 144 if (!m_inDragMode) 145 return; 146 147 if (Frame* frame = document()->frame()) 148 frame->eventHandler()->setCapturingMouseEventsNode(0); 149 m_inDragMode = false; 150 } 151 83 152 void SliderThumbElement::defaultEventHandler(Event* event) 84 153 { … … 93 162 94 163 if (eventType == eventNames().mousedownEvent && isLeftButton) { 95 if (document()->frame() && renderer()) { 96 RenderSlider* slider = toRenderSlider(renderer()->parent()); 97 if (slider) { 98 if (slider->mouseEventIsInThumb(mouseEvent)) { 99 // We selected the thumb, we want the cursor to always stay at 100 // the same position relative to the thumb. 101 m_offsetToThumb = slider->mouseEventOffsetToThumb(mouseEvent); 102 } else { 103 // We are outside the thumb, move the thumb to the point were 104 // we clicked. We'll be exactly at the center of the thumb. 105 m_offsetToThumb.setX(0); 106 m_offsetToThumb.setY(0); 107 } 108 109 m_inDragMode = true; 110 document()->frame()->eventHandler()->setCapturingMouseEventsNode(shadowHost()); 111 event->setDefaultHandled(); 112 return; 113 } 114 } 164 startDragging(); 165 return; 115 166 } else if (eventType == eventNames().mouseupEvent && isLeftButton) { 116 if (m_inDragMode) { 117 if (Frame* frame = document()->frame()) 118 frame->eventHandler()->setCapturingMouseEventsNode(0); 119 m_inDragMode = false; 120 event->setDefaultHandled(); 121 return; 122 } 167 stopDragging(); 168 return; 123 169 } else if (eventType == eventNames().mousemoveEvent) { 124 if (m_inDragMode && renderer() && renderer()->parent()) { 125 RenderSlider* slider = toRenderSlider(renderer()->parent()); 126 if (slider) { 127 FloatPoint curPoint = slider->absoluteToLocal(mouseEvent->absoluteLocation(), false, true); 128 IntPoint eventOffset(curPoint.x() + m_offsetToThumb.x(), curPoint.y() + m_offsetToThumb.y()); 129 slider->setValueForPosition(slider->positionForOffset(eventOffset)); 130 event->setDefaultHandled(); 131 return; 132 } 133 } 170 if (m_inDragMode) 171 setPosition(mouseEvent->absoluteLocation()); 172 return; 134 173 } 135 174 -
trunk/Source/WebCore/html/shadow/SliderThumbElement.h
r75749 r76147 51 51 bool inDragMode() const { return m_inDragMode; } 52 52 53 void dragFrom(const IntPoint&); 53 54 virtual void defaultEventHandler(Event*); 54 55 virtual void detach(); … … 58 59 SliderThumbElement(Document*); 59 60 virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); 61 void startDragging(); 62 void stopDragging(); 63 void setPosition(const IntPoint&); 60 64 61 65 FloatPoint m_offsetToThumb; -
trunk/Source/WebCore/rendering/RenderSlider.cpp
r75749 r76147 182 182 } 183 183 184 bool RenderSlider::mouseEventIsInThumb(MouseEvent* evt)185 {186 SliderThumbElement* thumbElement = sliderThumbElement();187 if (!thumbElement || !thumbElement->renderer())188 return false;189 190 #if ENABLE(VIDEO)191 if (style()->appearance() == MediaSliderPart || style()->appearance() == MediaVolumeSliderPart) {192 MediaControlInputElement* sliderThumb = static_cast<MediaControlInputElement*>(thumbElement->renderer()->node());193 return sliderThumb->hitTest(evt->absoluteLocation());194 }195 #endif196 197 FloatPoint localPoint = thumbElement->renderBox()->absoluteToLocal(evt->absoluteLocation(), false, true);198 IntRect thumbBounds = thumbElement->renderBox()->borderBoxRect();199 return thumbBounds.contains(roundedIntPoint(localPoint));200 }201 202 FloatPoint RenderSlider::mouseEventOffsetToThumb(MouseEvent* evt)203 {204 SliderThumbElement* thumbElement = sliderThumbElement();205 ASSERT(thumbElement && thumbElement->renderer());206 FloatPoint localPoint = thumbElement->renderBox()->absoluteToLocal(evt->absoluteLocation(), false, true);207 IntRect thumbBounds = thumbElement->renderBox()->borderBoxRect();208 FloatPoint offset;209 offset.setX(thumbBounds.x() + thumbBounds.width() / 2 - localPoint.x());210 offset.setY(thumbBounds.y() + thumbBounds.height() / 2 - localPoint.y());211 return offset;212 }213 214 void RenderSlider::setValueForPosition(int position)215 {216 SliderThumbElement* thumbElement = sliderThumbElement();217 if (!thumbElement || !thumbElement->renderer())218 return;219 220 HTMLInputElement* element = static_cast<HTMLInputElement*>(node());221 222 // Calculate the new value based on the position, and send it to the element.223 StepRange range(element);224 double fraction = static_cast<double>(position) / trackSize();225 if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)226 fraction = 1 - fraction;227 double value = range.clampValue(range.valueFromProportion(fraction));228 element->setValueFromRenderer(serializeForNumberType(value));229 230 // Also update the position if appropriate.231 if (position != currentPosition()) {232 setNeedsLayout(true);233 234 // FIXME: It seems like this could send extra change events if the same value is set235 // multiple times with no layout in between.236 element->dispatchFormControlChangeEvent();237 }238 }239 240 int RenderSlider::positionForOffset(const IntPoint& p)241 {242 SliderThumbElement* thumbElement = sliderThumbElement();243 if (!thumbElement || !thumbElement->renderer())244 return 0;245 246 int position;247 if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)248 position = p.y() - thumbElement->renderBox()->height() / 2;249 else250 position = p.x() - thumbElement->renderBox()->width() / 2;251 252 return max(0, min(position, trackSize()));253 }254 255 int RenderSlider::currentPosition()256 {257 SliderThumbElement* thumbElement = sliderThumbElement();258 ASSERT(thumbElement && thumbElement->renderer());259 260 if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)261 return toRenderBox(thumbElement->renderer())->y() - contentBoxRect().y();262 return toRenderBox(thumbElement->renderer())->x() - contentBoxRect().x();263 }264 265 int RenderSlider::trackSize()266 {267 SliderThumbElement* thumbElement = sliderThumbElement();268 ASSERT(thumbElement && thumbElement->renderer());269 270 if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart)271 return contentHeight() - thumbElement->renderBox()->height();272 return contentWidth() - thumbElement->renderBox()->width();273 }274 275 void RenderSlider::forwardEvent(Event* event)276 {277 SliderThumbElement* thumbElement = sliderThumbElement();278 if (!thumbElement)279 return;280 281 if (event->isMouseEvent()) {282 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);283 if (event->type() == eventNames().mousedownEvent && mouseEvent->button() == LeftButton) {284 if (!mouseEventIsInThumb(mouseEvent)) {285 IntPoint eventOffset = roundedIntPoint(absoluteToLocal(mouseEvent->absoluteLocation(), false, true));286 setValueForPosition(positionForOffset(eventOffset));287 }288 }289 }290 291 thumbElement->defaultEventHandler(event);292 }293 294 184 bool RenderSlider::inDragMode() const 295 185 { -
trunk/Source/WebCore/rendering/RenderSlider.h
r75749 r76147 35 35 virtual ~RenderSlider(); 36 36 37 void forwardEvent(Event*);38 37 bool inDragMode() const; 39 38 IntRect thumbRect(); … … 50 49 // SliderThumbElement and accessing sliderThumbElement should not be necessary in this class. 51 50 SliderThumbElement* sliderThumbElement() const; 52 bool mouseEventIsInThumb(MouseEvent*);53 FloatPoint mouseEventOffsetToThumb(MouseEvent*);54 55 void setValueForPosition(int position);56 void setPositionFromValue();57 int positionForOffset(const IntPoint&);58 59 int currentPosition();60 51 61 52 virtual bool requiresForcedStyleRecalcPropagation() const { return true; } 62 63 int trackSize();64 65 friend class SliderThumbElement;66 53 }; 67 54
Note: See TracChangeset
for help on using the changeset viewer.