Changeset 90662 in webkit
- Timestamp:
- Jul 8, 2011 1:30:58 PM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r90661 r90662 1 2011-07-07 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): 20 (WebCore::HTMLTextFormControlElement::setSelectionRange): Merged with the function of the same name in 21 RenderTextControl. 22 (WebCore::HTMLTextFormControlElement::selectionStart): Ditto. 23 (WebCore::HTMLTextFormControlElement::selectionEnd): Ditto. 24 (WebCore::setContainerAndOffsetForRange): Moved from RenderTextControl.cpp 25 (WebCore::HTMLTextFormControlElement::selection): Merged with the function of the same name in RenderTextControl. 26 (WebCore::HTMLTextFormControlElement::selectionChanged): Calls selectionStart and selectionEnd. 27 * html/HTMLFormControlElement.h: 28 (WebCore::HTMLTextFormControlElement::restoreCachedSelection): Moved from HTMLFormControlElement.cpp now that 29 all functions are self-contained in HTMLTextFormControlElement. 30 * html/HTMLInputElement.cpp: 31 (WebCore::HTMLInputElement::setValue): Calls setSelectionRange. 32 * rendering/RenderTextControl.cpp: 33 (WebCore::RenderTextControl::textFormControlElement): Added. 34 * rendering/RenderTextControl.h: 35 1 36 2011-07-08 Mike Reed <reed@google.com> 2 37 -
trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp
r90186 r90662 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
r90591 r90662 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 707 VisiblePosition startPosition = control->visiblePositionForIndex(start); 708 VisiblePosition endPosition; 709 if (start == end) 710 endPosition = startPosition; 711 else 712 endPosition = control->visiblePositionForIndex(end); 713 714 // startPosition and endPosition can be null position for example when 715 // "-webkit-user-select: none" style attribute is specified. 716 if (startPosition.isNotNull() && endPosition.isNotNull()) { 717 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == this 718 && endPosition.deepEquivalent().deprecatedNode()->shadowAncestorNode() == this); 719 } 720 721 VisibleSelection newSelection = VisibleSelection(startPosition, endPosition); 722 if (Frame* frame = document()->frame()) 723 frame->selection()->setSelection(newSelection); 677 724 } 678 725 … … 683 730 if (document()->focusedNode() != this && hasCachedSelectionStart()) 684 731 return m_cachedSelectionStart; 685 if (!renderer()) 686 return 0; 687 return toRenderTextControl(renderer())->selectionStart(); 732 733 Frame* frame = document()->frame(); 734 if (!renderer() || !frame) 735 return 0; 736 737 HTMLElement* innerText = toRenderTextControl(renderer())->innerTextElement(); 738 // Do not call innerTextElement() in the function arguments as creating a VisiblePosition 739 // from frame->selection->start() can blow us from underneath. Also, function ordering is 740 // usually dependent on the compiler. 741 return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->start()); 688 742 } 689 743 … … 694 748 if (document()->focusedNode() != this && hasCachedSelectionEnd()) 695 749 return m_cachedSelectionEnd; 696 if (!renderer()) 697 return 0; 698 return toRenderTextControl(renderer())->selectionEnd(); 750 751 Frame* frame = document()->frame(); 752 if (!renderer() || !frame) 753 return 0; 754 755 HTMLElement* innerText = toRenderTextControl(renderer())->innerTextElement(); 756 // Do not call innerTextElement() in the function arguments as creating a VisiblePosition 757 // from frame->selection->start() can blow us from underneath. Also, function ordering is 758 // usually dependent on the compiler. 759 return RenderTextControl::indexForVisiblePosition(innerText, frame->selection()->end()); 760 } 761 762 static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer) 763 { 764 if (node->isTextNode()) { 765 containerNode = node; 766 offsetInContainer = offset; 767 } else { 768 containerNode = node->parentNode(); 769 offsetInContainer = node->nodeIndex() + offset; 770 } 699 771 } 700 772 … … 703 775 if (!renderer() || !isTextFormControl() || !hasCachedSelectionStart() || !hasCachedSelectionEnd()) 704 776 return 0; 705 return toRenderTextControl(renderer())->selection(m_cachedSelectionStart, m_cachedSelectionEnd); 706 } 707 708 void HTMLTextFormControlElement::restoreCachedSelection() 709 { 710 WebCore::setSelectionRange(this, m_cachedSelectionStart, m_cachedSelectionEnd); 777 778 int start = m_cachedSelectionStart; 779 int end = m_cachedSelectionEnd; 780 781 ASSERT(start <= end); 782 HTMLElement* innerText = toRenderTextControl(renderer())->innerTextElement(); 783 if (!innerText) 784 return 0; 785 786 if (!innerText->firstChild()) 787 return Range::create(document(), innerText, 0, innerText, 0); 788 789 int offset = 0; 790 Node* startNode = 0; 791 Node* endNode = 0; 792 for (Node* node = innerText->firstChild(); node; node = node->traverseNextNode(innerText)) { 793 ASSERT(!node->firstChild()); 794 ASSERT(node->isTextNode() || node->hasTagName(brTag)); 795 int length = node->isTextNode() ? lastOffsetInNode(node) : 1; 796 797 if (offset <= start && start <= offset + length) 798 setContainerAndOffsetForRange(node, start - offset, startNode, start); 799 800 if (offset <= end && end <= offset + length) { 801 setContainerAndOffsetForRange(node, end - offset, endNode, end); 802 break; 803 } 804 805 offset += length; 806 } 807 808 if (!startNode || !endNode) 809 return 0; 810 811 return Range::create(document(), startNode, start, endNode, end); 711 812 } 712 813 … … 716 817 return; 717 818 718 RenderTextControl* renderTextControl = toRenderTextControl(renderer()); 719 cacheSelection(renderTextControl->selectionStart(), renderTextControl->selectionEnd()); 819 cacheSelection(selectionStart(), selectionEnd()); 720 820 721 821 if (Frame* frame = document()->frame()) { -
trunk/Source/WebCore/html/HTMLFormControlElement.h
r90591 r90662 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(); … … 231 232 void setTextAsOfLastFormControlChangeEvent(const String& text) { m_textAsOfLastFormControlChangeEvent = text; } 232 233 233 void restoreCachedSelection() ;234 void restoreCachedSelection() { setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd); } 234 235 bool hasCachedSelectionStart() const { return m_cachedSelectionStart >= 0; } 235 236 bool hasCachedSelectionEnd() const { return m_cachedSelectionEnd >= 0; } -
trunk/Source/WebCore/html/HTMLInputElement.cpp
r90591 r90662 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
r90600 r90662 28 28 #include "EventNames.h" 29 29 #include "Frame.h" 30 #include "FrameSelection.h"31 30 #include "HTMLBRElement.h" 32 31 #include "HTMLFormControlElement.h" … … 83 82 } 84 83 84 HTMLTextFormControlElement* RenderTextControl::textFormControlElement() 85 { 86 return static_cast<HTMLTextFormControlElement*>(node()); 87 } 88 85 89 void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) 86 90 { … … 174 178 } 175 179 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 180 bool RenderTextControl::isSelectableElement(HTMLElement* innerText, Node* node) 244 181 { … … 255 192 return shadowAncestor && (shadowAncestor->hasTagName(textareaTag) 256 193 || (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 194 } 304 195 -
trunk/Source/WebCore/rendering/RenderTextControl.h
r90591 r90662 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 97 friend void setSelectionRange(Node*, int start, int end); 101 98 static bool isSelectableElement(HTMLElement*, Node*); … … 109 106 bool m_lastChangeWasUserEdit; 110 107 }; 111 112 void setSelectionRange(Node*, int start, int end);113 108 114 109 inline RenderTextControl* toRenderTextControl(RenderObject* object) -
trunk/Source/WebKit/qt/Api/qwebpage.cpp
r89744 r90662 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
r90403 r90662 1 2011-07-08 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-05 Rafael Brandao <rafael.lobo@openbossa.org> 2 14
Note: See TracChangeset
for help on using the changeset viewer.