Changeset 58564 in webkit
- Timestamp:
- Apr 30, 2010 1:45:49 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r58563 r58564 1 2010-04-30 Kent Tamura <tkent@chromium.org> 2 3 Reviewed by Adele Peterson. 4 5 Implement interactive behavior of spin buttons. 6 https://bugs.webkit.org/show_bug.cgi?id=27968 7 8 * platform/mac/fast/forms/input-number-click-expected.txt: Added. 9 * platform/mac/fast/forms/input-number-click.html: Added. 10 1 11 2010-04-30 Yael Aharon <yael.aharon@nokia.com> 2 12 -
trunk/WebCore/ChangeLog
r58563 r58564 1 2010-04-30 Kent Tamura <tkent@chromium.org> 2 3 Reviewed by Adele Peterson. 4 5 Implement interactive behavior of spin buttons. 6 https://bugs.webkit.org/show_bug.cgi?id=27968 7 8 Introduce SpinButtonElement. It is a shadow element class for 9 spin buttons. If the upper side of the element is clicked, calls 10 HTMLInputElement::stepUpFromRenderer(1). If the lower button is 11 clicked, calls HTMLInputElement::stepUpFromRenderer(-1). 12 13 SpinButtonElement tracks the mouse pointer position, and 14 RenderTheme sets ControlStates::SpinUpState if the pointer is on 15 the upper side. 16 17 Test: platform/mac/fast/forms/input-number-click.html 18 19 * dom/Element.h: 20 (WebCore::Element::isSpinButtonElement): 21 * editing/VisibleSelection.cpp: 22 (WebCore::VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries): 23 Remove an assertion. lastEditablePositionBeforePositionInRoot() can 24 return null in a case that m_end is at a shadow element (a spin button) 25 and baseRoot is another shadow element (inner text block) in the same 26 node (an INPUT element). 27 * html/HTMLInputElement.cpp: 28 (WebCore::HTMLInputElement::stepUpFromRenderer): 29 * html/HTMLInputElement.h: 30 (WebCore::HTMLInputElement::hasSpinButton): 31 Add types supporting step attribute except RANGE. 32 * rendering/RenderTextControlSingleLine.cpp: 33 (WebCore::RenderTextControlSingleLine::nodeAtPoint): 34 (WebCore::RenderTextControlSingleLine::forwardEvent): 35 (WebCore::RenderTextControlSingleLine::preferredContentWidth): 36 (WebCore::RenderTextControlSingleLine::createSubtreeIfNeeded): 37 * rendering/RenderTextControlSingleLine.h: 38 * rendering/RenderTheme.cpp: 39 (WebCore::RenderTheme::controlStatesForRenderer): 40 (WebCore::RenderTheme::isSpinUpButtonPartPressed): 41 (WebCore::RenderTheme::isSpinUpButtonPartHovered): 42 * rendering/RenderTheme.h: 43 * rendering/TextControlInnerElements.cpp: 44 (WebCore::SpinButtonElement::SpinButtonElement): 45 (WebCore::SpinButtonElement::defaultEventHandler): 46 * rendering/TextControlInnerElements.h: 47 (WebCore::SpinButtonElement::isSpinButtonElement): 48 (WebCore::SpinButtonElement::isEnabledFormControl): 49 (WebCore::SpinButtonElement::onUpButton): 50 1 51 2010-04-30 Yael Aharon <yael.aharon@nokia.com> 2 52 -
trunk/WebCore/css/html.css
r56629 r58564 363 363 -webkit-appearance: inner-spin-button; 364 364 display: inline-block; 365 -webkit-user-select: none; 365 366 } 366 367 … … 369 370 display: inline-block; 370 371 margin-left: 2px; 372 -webkit-user-select: none; 371 373 } 372 374 -
trunk/WebCore/dom/Element.h
r57809 r58564 253 253 virtual bool isEnabledFormControl() const { return true; } 254 254 virtual bool isReadOnlyFormControl() const { return false; } 255 virtual bool isSpinButtonElement() const { return false; } 255 256 virtual bool isTextFormControl() const { return false; } 256 257 virtual bool isOptionalFormControl() const { return false; } -
trunk/WebCore/editing/VisibleSelection.cpp
r58040 r58564 482 482 VisiblePosition last = lastEditablePositionBeforePositionInRoot(m_end, baseRoot); 483 483 m_end = last.deepEquivalent(); 484 if (m_end.isNull()) { 485 ASSERT_NOT_REACHED(); 484 if (m_end.isNull()) 486 485 m_end = m_start; 487 }488 486 } 489 487 // The selection is based in non-editable content. -
trunk/WebCore/html/HTMLInputElement.cpp
r58520 r58564 2762 2762 #endif // ENABLE(DATALIST) 2763 2763 2764 void HTMLInputElement::stepUpFromRenderer(int n) 2765 { 2766 // The difference from stepUp()/stepDown() is: 2767 // If the current value is invalid, the value will be 2768 // - the minimum value if n > 0 2769 // - the maximum value if n < 0 2770 2771 ASSERT(hasSpinButton()); 2772 if (!hasSpinButton()) 2773 return; 2774 ASSERT(n); 2775 if (!n) 2776 return; 2777 2778 const double nan = numeric_limits<double>::quiet_NaN(); 2779 double current = parseToDouble(value(), nan); 2780 if (!isfinite(current)) { 2781 setValue(serialize(n > 0 ? minimum() : maximum())); 2782 return; 2783 } 2784 ExceptionCode ec; 2785 stepUp(n, ec); 2786 } 2787 2764 2788 } // namespace -
trunk/WebCore/html/HTMLInputElement.h
r58561 r58564 122 122 void stepUp(ExceptionCode& ec) { stepUp(1, ec); } 123 123 void stepDown(ExceptionCode& ec) { stepDown(1, ec); } 124 // stepUp()/stepDown() for user-interaction. 125 void stepUpFromRenderer(int); 124 126 125 127 bool isTextButton() const { return m_type == SUBMIT || m_type == RESET || m_type == BUTTON; } … … 129 131 virtual bool isInputTypeHidden() const { return m_type == HIDDEN; } 130 132 virtual bool isPasswordField() const { return m_type == PASSWORD; } 131 virtual bool hasSpinButton() const { return m_type == NUMBER ; }133 virtual bool hasSpinButton() const { return m_type == NUMBER || m_type == DATE || m_type == DATETIME || m_type == DATETIMELOCAL || m_type == MONTH || m_type == TIME || m_type == WEEK; } 132 134 133 135 bool checked() const { return m_checked; } -
trunk/WebCore/rendering/RenderTextControlSingleLine.cpp
r58561 r58564 282 282 hitInnerTextElement(result, xPos, yPos, tx, ty); 283 283 284 // If we found a spin button, we're done. 285 if (m_outerSpinButton && result.innerNode() == m_outerSpinButton) 286 return true; 284 287 // If we're not a search field, or we already found the results or cancel buttons, we're done. 285 288 if (!m_innerBlock || result.innerNode() == m_resultsButton || result.innerNode() == m_cancelButton) … … 332 335 333 336 FloatPoint localPoint = innerTextRenderer->absoluteToLocal(static_cast<MouseEvent*>(event)->absoluteLocation(), false, true); 337 int textRight = innerTextRenderer->borderBoxRect().right(); 334 338 if (m_resultsButton && localPoint.x() < innerTextRenderer->borderBoxRect().x()) 335 339 m_resultsButton->defaultEventHandler(event); 336 else if (m_cancelButton && localPoint.x() > innerTextRenderer->borderBoxRect().right())340 else if (m_cancelButton && localPoint.x() > textRight && localPoint.x() < textRight + m_cancelButton->renderBox()->width()) 337 341 m_cancelButton->defaultEventHandler(event); 342 else if (m_outerSpinButton && localPoint.x() > textRight) 343 m_outerSpinButton->defaultEventHandler(event); 338 344 else 339 345 RenderTextControl::forwardEvent(event); … … 503 509 RenderTextControl::createSubtreeIfNeeded(m_innerBlock.get()); 504 510 if (inputElement()->hasSpinButton() && !m_outerSpinButton) { 505 // FIXME: Introduce a dedicated element for spin buttons. 506 m_outerSpinButton = new TextControlInnerElement(document(), node()); 511 m_outerSpinButton = new SpinButtonElement(document(), node()); 507 512 m_outerSpinButton->attachInnerElement(node(), createOuterSpinButtonStyle(), renderArena()); 508 513 } -
trunk/WebCore/rendering/RenderTextControlSingleLine.h
r58561 r58564 33 33 class SearchFieldResultsButtonElement; 34 34 class SearchPopupMenu; 35 class SpinButtonElement; 35 36 class TextControlInnerElement; 36 37 -
trunk/WebCore/rendering/RenderTheme.cpp
r58228 r58564 37 37 #include "SelectionController.h" 38 38 #include "Settings.h" 39 #include "TextControlInnerElements.h" 39 40 40 41 // The methods in this file are shared by all themes on every platform. … … 658 659 { 659 660 ControlStates result = 0; 660 if (isHovered(o)) 661 if (isHovered(o)) { 661 662 result |= HoverState; 662 if (isPressed(o)) 663 if (isSpinUpButtonPartHovered(o)) 664 result |= SpinUpState; 665 } 666 if (isPressed(o)) { 663 667 result |= PressedState; 668 if (isSpinUpButtonPartPressed(o)) 669 result |= SpinUpState; 670 } 664 671 if (isFocused(o) && o->style()->outlineStyleIsAuto()) 665 672 result |= FocusState; … … 745 752 } 746 753 754 bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const 755 { 756 Node* node = o->node(); 757 if (!node || !node->active() || !node->isElementNode() 758 || !static_cast<Element*>(node)->isSpinButtonElement()) 759 return false; 760 SpinButtonElement* element = static_cast<SpinButtonElement*>(node); 761 return element->onUpButton(); 762 } 763 747 764 bool RenderTheme::isReadOnlyControl(const RenderObject* o) const 748 765 { … … 758 775 return false; 759 776 return o->node()->hovered(); 777 } 778 779 bool RenderTheme::isSpinUpButtonPartHovered(const RenderObject* o) const 780 { 781 Node* node = o->node(); 782 if (!node || !node->active() || !node->isElementNode() 783 || !static_cast<Element*>(node)->isSpinButtonElement()) 784 return false; 785 SpinButtonElement* element = static_cast<SpinButtonElement*>(node); 786 return element->onUpButton(); 760 787 } 761 788 -
trunk/WebCore/rendering/RenderTheme.h
r56850 r58564 290 290 bool isFocused(const RenderObject*) const; 291 291 bool isPressed(const RenderObject*) const; 292 bool isSpinUpButtonPartPressed(const RenderObject*) const; 292 293 bool isHovered(const RenderObject*) const; 294 bool isSpinUpButtonPartHovered(const RenderObject*) const; 293 295 bool isReadOnlyControl(const RenderObject*) const; 294 296 bool isDefault(const RenderObject*) const; -
trunk/WebCore/rendering/TextControlInnerElements.cpp
r55090 r58564 212 212 } 213 213 214 } 214 SpinButtonElement::SpinButtonElement(Document* doc, Node* shadowParent) 215 : TextControlInnerElement(doc, shadowParent) 216 , m_capturing(false) 217 , m_onUpButton(false) 218 { 219 } 220 221 void SpinButtonElement::defaultEventHandler(Event* evt) 222 { 223 if (!evt->isMouseEvent()) { 224 if (!evt->defaultHandled()) 225 HTMLDivElement::defaultEventHandler(evt); 226 return; 227 } 228 const MouseEvent* mevt = static_cast<MouseEvent*>(evt); 229 if (mevt->button() != LeftButton) { 230 if (!evt->defaultHandled()) 231 HTMLDivElement::defaultEventHandler(evt); 232 return; 233 } 234 235 HTMLInputElement* input = static_cast<HTMLInputElement*>(shadowAncestorNode()); 236 IntPoint local = roundedIntPoint(renderBox()->absoluteToLocal(mevt->absoluteLocation(), false, true)); 237 if (evt->type() == eventNames().clickEvent) { 238 if (renderBox()->borderBoxRect().contains(local)) { 239 input->focus(); 240 input->select(); 241 if (local.y() < renderBox()->y() + renderBox()->height() / 2) 242 input->stepUpFromRenderer(1); 243 else 244 input->stepUpFromRenderer(-1); 245 evt->setDefaultHandled(); 246 } 247 } else if (evt->type() == eventNames().mousemoveEvent) { 248 if (renderBox()->borderBoxRect().contains(local)) { 249 if (!m_capturing) { 250 if (Frame* frame = document()->frame()) { 251 frame->eventHandler()->setCapturingMouseEventsNode(input); 252 m_capturing = true; 253 } 254 } 255 bool oldOnUpButton = m_onUpButton; 256 m_onUpButton = local.y() < renderBox()->y() + renderBox()->height() / 2; 257 if (m_onUpButton != oldOnUpButton) 258 renderer()->repaint(); 259 } else { 260 if (m_capturing) { 261 if (Frame* frame = document()->frame()) { 262 frame->eventHandler()->setCapturingMouseEventsNode(0); 263 m_capturing = false; 264 } 265 } 266 } 267 } 268 if (!evt->defaultHandled()) 269 HTMLDivElement::defaultEventHandler(evt); 270 } 271 272 } -
trunk/WebCore/rendering/TextControlInnerElements.h
r45662 r58564 69 69 }; 70 70 71 class SpinButtonElement : public TextControlInnerElement { 72 public: 73 SpinButtonElement(Document*, Node*); 74 virtual bool isSpinButtonElement() const { return true; } 75 virtual bool isEnabledFormControl() { return static_cast<Element*>(shadowAncestorNode())->isEnabledFormControl(); } 76 virtual void defaultEventHandler(Event*); 77 78 bool onUpButton() const { return m_onUpButton; } 79 static const AtomicString& spinButtonNodeName(); 80 81 private: 82 bool m_capturing; 83 bool m_onUpButton; 84 }; 85 71 86 } //namespace 72 87
Note: See TracChangeset
for help on using the changeset viewer.