Changeset 90763 in webkit
- Timestamp:
- Jul 11, 2011 10:55:26 AM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r90758 r90763 1 2011-07-11 Ryosuke Niwa <rniwa@webkit.org> 2 3 Move selection related code from RenderTextControl to HTMLTextFormControlElement 4 https://bugs.webkit.org/show_bug.cgi?id=64133 5 6 Reviewed by Dimitri Glazkov. 7 8 Moved selectionStart, selectionEnd, hasVisibleTextArea, setSelectionRange, setContainerAndOffsetForRange 9 and selection from RenderTextControl.cpp to HTMLFormControlElement.cpp. 10 11 This refactoring removes RenderTextControl's dependency on FrameSelection. 12 13 * accessibility/AccessibilityRenderObject.cpp: 14 (WebCore::AccessibilityRenderObject::selectedText): Calls HTMLTextFromControl::selectedText. 15 (WebCore::AccessibilityRenderObject::selectedTextRange): Calls selectionStart and selectionEnd. 16 (WebCore::AccessibilityRenderObject::setSelectedTextRange): Ditto. 17 * html/HTMLFormControlElement.cpp: 18 (WebCore::HTMLTextFormControlElement::selectedText): Extracted from AccessibilityRenderObject::selectedText. 19 (WebCore::hasVisibleTextArea): Added. 20 (WebCore::HTMLTextFormControlElement::setSelectionRange): Merged with the function of the same name in RenderTextControl. 21 (WebCore::HTMLTextFormControlElement::selectionStart): Calls computeSelectionStart instead of RenderTextControl::selectionStart. 22 (WebCore::HTMLTextFormControlElement::computeSelectionStart): Moved from RenderTextControl::selectionStart. 23 (WebCore::HTMLTextFormControlElement::selectionEnd): Calls computeSelectionEnd instead of RenderText::selectionEnd. 24 (WebCore::HTMLTextFormControlElement::computeSelectionEnd): Moved from RenderTextControl::selectionStart. 25 (WebCore::setContainerAndOffsetForRange): Moved from RenderTextControl.cpp. 26 (WebCore::HTMLTextFormControlElement::selection): Merged with the function of the same name in RenderTextControl. 27 (WebCore::HTMLTextFormControlElement::restoreCachedSelection): Calls computeSelectionStart and computeSelectionEnd instead of 28 RenderTextControl::selectionStart and RenderTextControl::selectionEnd. 29 (WebCore::HTMLTextFormControlElement::selectionChanged): Calls selectionStart and selectionEnd. 30 * html/HTMLFormControlElement.h: 31 * html/HTMLInputElement.cpp: 32 (WebCore::HTMLInputElement::setValue): Calls setSelectionRange. 33 * rendering/RenderTextControl.cpp: 34 (WebCore::RenderTextControl::textFormControlElement): Added. 35 * rendering/RenderTextControl.h: 36 1 37 2011-07-11 Andreas Kling <kling@webkit.org> 2 38 -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
r90671 r90763 1995 1995 1996 1996 if (isNativeTextControl()) { 1997 RenderTextControl* textControl = toRenderTextControl(m_renderer);1998 return textControl-> text().substring(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart());1997 HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement(); 1998 return textControl->selectedText(); 1999 1999 } 2000 2000 … … 2029 2029 AccessibilityRole ariaRole = ariaRoleAttribute(); 2030 2030 if (isNativeTextControl() && ariaRole == UnknownRole) { 2031 RenderTextControl* textControl = toRenderTextControl(m_renderer);2031 HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement(); 2032 2032 return PlainTextRange(textControl->selectionStart(), textControl->selectionEnd() - textControl->selectionStart()); 2033 2033 } … … 2042 2042 { 2043 2043 if (isNativeTextControl()) { 2044 setSelectionRange(m_renderer->node(), range.start, range.start + range.length); 2044 HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement(); 2045 textControl->setSelectionRange(range.start, range.start + range.length); 2045 2046 return; 2046 2047 } -
trunk/Source/WebCore/html/HTMLFormControlElement.cpp
r90671 r90763 663 663 } 664 664 665 String HTMLTextFormControlElement::selectedText() const 666 { 667 // FIXME: We should be able to extract selected contents even if there were no renderer. 668 if (!renderer() || renderer()->isTextControl()) 669 return String(); 670 671 RenderTextControl* textControl = toRenderTextControl(renderer()); 672 return textControl->text().substring(selectionStart(), selectionEnd() - selectionStart()); 673 } 674 665 675 void HTMLTextFormControlElement::dispatchFormControlChangeEvent() 666 676 { … … 672 682 } 673 683 684 static inline bool hasVisibleTextArea(RenderTextControl* textControl) 685 { 686 ASSERT(textControl); 687 HTMLElement* innerText = textControl->innerTextElement(); 688 return textControl->style()->visibility() == HIDDEN || !innerText || !innerText->renderer() || !innerText->renderBox()->height(); 689 } 690 674 691 void HTMLTextFormControlElement::setSelectionRange(int start, int end) 675 692 { 676 WebCore::setSelectionRange(this, start, end); 693 document()->updateLayoutIgnorePendingStylesheets(); 694 695 if (!renderer() || !renderer()->isTextControl()) 696 return; 697 698 end = max(end, 0); 699 start = min(max(start, 0), end); 700 701 RenderTextControl* control = toRenderTextControl(renderer()); 702 if (hasVisibleTextArea(control)) { 703 cacheSelection(start, end); 704 return; 705 } 706 VisiblePosition startPosition = control->visiblePositionForIndex(start); 707 VisiblePosition endPosition; 708 if (start == end) 709 endPosition = startPosition; 710 else 711 endPosition = control->visiblePositionForIndex(end); 712 713 // startPosition and endPosition can be null position for example when 714 // "-webkit-user-select: none" style attribute is specified. 715 if (startPosition.isNotNull() && endPosition.isNotNull()) { 716 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == this 717 && endPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == this); 718 } 719 VisibleSelection newSelection = VisibleSelection(startPosition, endPosition); 720 721 if (Frame* frame = document()->frame()) 722 frame->selection()->setSelection(newSelection); 677 723 } 678 724 … … 683 729 if (document()->focusedNode() != this && hasCachedSelectionStart()) 684 730 return m_cachedSelectionStart; 685 if (!renderer()) 686 return 0; 687 return toRenderTextControl(renderer())->selectionStart(); 731 732 return computeSelectionStart(); 733 } 734 735 int HTMLTextFormControlElement::computeSelectionStart() const 736 { 737 Frame* frame = document()->frame(); 738 if (!renderer() || !frame) 739 return 0; 740 741 HTMLElement* innerText = toRenderTextControl(renderer())->innerTextElement(); 742 // Do not call innerTextElement() in the function arguments as creating a VisiblePosition 743 // from frame->selection->start() can blow us from underneath. Also, function ordering is 744 // usually dependent on the compiler. 745 return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->start()); 688 746 } 689 747 … … 694 752 if (document()->focusedNode() != this && hasCachedSelectionEnd()) 695 753 return m_cachedSelectionEnd; 696 if (!renderer()) 697 return 0; 698 return toRenderTextControl(renderer())->selectionEnd(); 754 return computeSelectionEnd(); 755 } 756 757 int HTMLTextFormControlElement::computeSelectionEnd() const 758 { 759 Frame* frame = document()->frame(); 760 if (!renderer() || !frame) 761 return 0; 762 763 HTMLElement* innerText = toRenderTextControl(renderer())->innerTextElement(); 764 // Do not call innerTextElement() in the function arguments as creating a VisiblePosition 765 // from frame->selection->end() can blow us from underneath. Also, function ordering is 766 // usually dependent on the compiler. 767 return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->end()); 768 } 769 770 static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer) 771 { 772 if (node->isTextNode()) { 773 containerNode = node; 774 offsetInContainer = offset; 775 } else { 776 containerNode = node->parentNode(); 777 offsetInContainer = node->nodeIndex() + offset; 778 } 699 779 } 700 780 … … 703 783 if (!renderer() || !isTextFormControl() || !hasCachedSelectionStart() || !hasCachedSelectionEnd()) 704 784 return 0; 705 return toRenderTextControl(renderer())->selection(m_cachedSelectionStart, m_cachedSelectionEnd); 785 786 int start = m_cachedSelectionStart; 787 int end = m_cachedSelectionEnd; 788 789 ASSERT(start <= end); 790 HTMLElement* innerText = toRenderTextControl(renderer())->innerTextElement(); 791 if (!innerText) 792 return 0; 793 794 if (!innerText->firstChild()) 795 return Range::create(document(), innerText, 0, innerText, 0); 796 797 int offset = 0; 798 Node* startNode = 0; 799 Node* endNode = 0; 800 for (Node* node = innerText->firstChild(); node; node = node->traverseNextNode(innerText)) { 801 ASSERT(!node->firstChild()); 802 ASSERT(node->isTextNode() || node->hasTagName(brTag)); 803 int length = node->isTextNode() ? lastOffsetInNode(node) : 1; 804 805 if (offset <= start && start <= offset + length) 806 setContainerAndOffsetForRange(node, start - offset, startNode, start); 807 808 if (offset <= end && end <= offset + length) { 809 setContainerAndOffsetForRange(node, end - offset, endNode, end); 810 break; 811 } 812 813 offset += length; 814 } 815 816 if (!startNode || !endNode) 817 return 0; 818 819 return Range::create(document(), startNode, start, endNode, end); 706 820 } 707 821 708 822 void HTMLTextFormControlElement::restoreCachedSelection() 709 823 { 710 WebCore::setSelectionRange(this,m_cachedSelectionStart, m_cachedSelectionEnd);824 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd); 711 825 } 712 826 … … 716 830 return; 717 831 718 RenderTextControl* renderTextControl = toRenderTextControl(renderer());719 cacheSelection( renderTextControl->selectionStart(), renderTextControl->selectionEnd());832 // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus 833 cacheSelection(computeSelectionStart(), computeSelectionEnd()); 720 834 721 835 if (Frame* frame = document()->frame()) { -
trunk/Source/WebCore/html/HTMLFormControlElement.h
r90671 r90763 208 208 void setSelectionRange(int start, int end); 209 209 PassRefPtr<Range> selection() const; 210 String selectedText() const; 210 211 211 212 virtual void dispatchFormControlChangeEvent(); … … 236 237 237 238 private: 239 int computeSelectionStart() const; 240 int computeSelectionEnd() const; 241 238 242 virtual void dispatchFocusEvent(); 239 243 virtual void dispatchBlurEvent(); -
trunk/Source/WebCore/html/HTMLInputElement.cpp
r90671 r90763 1017 1017 unsigned max = visibleValue().length(); 1018 1018 if (document()->focusedNode() == this) 1019 WebCore::setSelectionRange(this,max, max);1019 setSelectionRange(max, max); 1020 1020 else 1021 1021 cacheSelection(max, max); -
trunk/Source/WebCore/rendering/RenderTextControl.cpp
r90671 r90763 83 83 } 84 84 85 HTMLTextFormControlElement* RenderTextControl::textFormControlElement() 86 { 87 return static_cast<HTMLTextFormControlElement*>(node()); 88 } 89 85 90 void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 86 91 { … … 174 179 } 175 180 176 int RenderTextControl::selectionStart() const177 {178 Frame* frame = this->frame();179 if (!frame)180 return 0;181 182 HTMLElement* innerText = innerTextElement();183 // Do not call innerTextElement() in the function arguments as creating a VisiblePosition184 // from frame->selection->start() can blow us from underneath. Also, function ordering is185 // usually dependent on the compiler.186 return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->start());187 }188 189 int RenderTextControl::selectionEnd() const190 {191 Frame* frame = this->frame();192 if (!frame)193 return 0;194 195 HTMLElement* innerText = innerTextElement();196 // Do not call innerTextElement() in the function arguments as creating a VisiblePosition197 // from frame->selection->end() can blow us from underneath. Also, function ordering is198 // usually dependent on the compiler.199 return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->end());200 }201 202 bool RenderTextControl::hasVisibleTextArea() const203 {204 HTMLElement* innerText = innerTextElement();205 return style()->visibility() == HIDDEN || !innerText || !innerText->renderer() || !innerText->renderBox()->height();206 }207 208 void setSelectionRange(Node* node, int start, int end)209 {210 ASSERT(node);211 node->document()->updateLayoutIgnorePendingStylesheets();212 213 if (!node->renderer() || !node->renderer()->isTextControl())214 return;215 216 end = max(end, 0);217 start = min(max(start, 0), end);218 219 RenderTextControl* control = toRenderTextControl(node->renderer());220 221 if (control->hasVisibleTextArea()) {222 static_cast<HTMLTextFormControlElement*>(node)->cacheSelection(start, end);223 return;224 }225 VisiblePosition startPosition = control->visiblePositionForIndex(start);226 VisiblePosition endPosition;227 if (start == end)228 endPosition = startPosition;229 else230 endPosition = control->visiblePositionForIndex(end);231 232 // startPosition and endPosition can be null position for example when233 // "-webkit-user-select: none" style attribute is specified.234 if (startPosition.isNotNull() && endPosition.isNotNull()) {235 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == node && endPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == node);236 }237 VisibleSelection newSelection = VisibleSelection(startPosition, endPosition);238 239 if (Frame* frame = node->document()->frame())240 frame->selection()->setSelection(newSelection);241 }242 243 181 bool RenderTextControl::isSelectableElement(HTMLElement* innerText, Node* node) 244 182 { … … 255 193 return shadowAncestor && (shadowAncestor->hasTagName(textareaTag) 256 194 || (shadowAncestor->hasTagName(inputTag) && static_cast<HTMLInputElement*>(shadowAncestor)->isTextField())); 257 }258 259 static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer)260 {261 if (node->isTextNode()) {262 containerNode = node;263 offsetInContainer = offset;264 } else {265 containerNode = node->parentNode();266 offsetInContainer = node->nodeIndex() + offset;267 }268 }269 270 PassRefPtr<Range> RenderTextControl::selection(int start, int end) const271 {272 ASSERT(start <= end);273 HTMLElement* innerText = innerTextElement();274 if (!innerText)275 return 0;276 277 if (!innerText->firstChild())278 return Range::create(document(), innerText, 0, innerText, 0);279 280 int offset = 0;281 Node* startNode = 0;282 Node* endNode = 0;283 for (Node* node = innerText->firstChild(); node; node = node->traverseNextNode(innerText)) {284 ASSERT(!node->firstChild());285 ASSERT(node->isTextNode() || node->hasTagName(brTag));286 int length = node->isTextNode() ? lastOffsetInNode(node) : 1;287 288 if (offset <= start && start <= offset + length)289 setContainerAndOffsetForRange(node, start - offset, startNode, start);290 291 if (offset <= end && end <= offset + length) {292 setContainerAndOffsetForRange(node, end - offset, endNode, end);293 break;294 }295 296 offset += length;297 }298 299 if (!startNode || !endNode)300 return 0;301 302 return Range::create(document(), startNode, start, endNode, end);303 195 } 304 196 -
trunk/Source/WebCore/rendering/RenderTextControl.h
r90671 r90763 27 27 namespace WebCore { 28 28 29 class HTMLTextFormControlElement; 29 30 class VisibleSelection; 30 31 class TextControlInnerElement; … … 35 36 virtual ~RenderTextControl(); 36 37 38 HTMLTextFormControlElement* textFormControlElement(); 37 39 virtual HTMLElement* innerTextElement() const = 0; 38 40 virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const = 0; … … 40 42 bool lastChangeWasUserEdit() const { return m_lastChangeWasUserEdit; } 41 43 void setLastChangeWasUserEdit(bool lastChangeWasUserEdit); 42 43 int selectionStart() const;44 int selectionEnd() const;45 PassRefPtr<Range> selection(int start, int end) const;46 44 47 45 virtual void subtreeHasChanged(); … … 97 95 virtual bool requiresForcedStyleRecalcPropagation() const { return true; } 98 96 99 bool hasVisibleTextArea() const;100 friend void setSelectionRange(Node*, int start, int end);101 97 static bool isSelectableElement(HTMLElement*, Node*); 102 98 … … 109 105 bool m_lastChangeWasUserEdit; 110 106 }; 111 112 void setSelectionRange(Node*, int start, int end);113 107 114 108 inline RenderTextControl* toRenderTextControl(RenderObject* object) -
trunk/Source/WebKit/qt/Api/qwebpage.cpp
r90671 r90763 1112 1112 hasSelection = true; 1113 1113 // A selection in the inputMethodEvent is always reflected in the visible text 1114 if (node) 1115 setSelectionRange(node, qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); 1114 if (node) { 1115 if (HTMLTextFormControlElement* textControl = toTextFormControl(node)) 1116 textControl->setSelectionRange(qMin(a.start, (a.start + a.length)), qMax(a.start, (a.start + a.length))); 1117 } 1116 1118 1117 1119 if (!ev->preeditString().isEmpty()) … … 1133 1135 int cursorPos = frame->selection()->extent().offsetInContainerNode(); 1134 1136 int start = cursorPos + ev->replacementStart(); 1135 setSelectionRange(node, start, start + ev->replacementLength()); 1137 if (HTMLTextFormControlElement* textControl = toTextFormControl(node)) 1138 textControl->setSelectionRange(start, start + ev->replacementLength()); 1136 1139 // Commit regardless of whether commitString is empty, to get rid of selection. 1137 1140 editor->confirmComposition(ev->commitString()); -
trunk/Source/WebKit/qt/ChangeLog
r90671 r90763 1 2011-07-11 Ryosuke Niwa <rniwa@webkit.org> 2 3 Move selection related code from RenderTextControl to HTMLTextFormControlElement 4 https://bugs.webkit.org/show_bug.cgi?id=64133 5 6 Reviewed by Dimitri Glazkov. 7 8 Replaced calls to WebCore::setSelectionRange by calls to HTMLTextFormControlElement::setSelectionRange. 9 10 * Api/qwebpage.cpp: 11 (QWebPagePrivate::inputMethodEvent): 12 1 13 2011-07-08 Adam Barth <abarth@webkit.org> 2 14
Note: See TracChangeset
for help on using the changeset viewer.