Changeset 34822 in webkit
- Timestamp:
- Jun 26, 2008 8:24:51 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r34816 r34822 1 2008-06-26 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 - test for <rdar://problem/3099526> Find command doesn't search form input controls (textareas and text fields) 6 http://bugs.webkit.org/show_bug.cgi?id=7023 7 8 * editing/selection/find-in-text-control-expected.txt: Added. 9 * editing/selection/find-in-text-control.html: Added. 10 1 11 2008-06-26 Beth Dakin <bdakin@apple.com> 2 12 -
trunk/WebCore/ChangeLog
r34820 r34822 1 2008-06-26 Dan Bernstein <mitz@apple.com> 2 3 Reviewed by Darin Adler. 4 5 - fix <rdar://problem/3099526> Find command doesn't search form input controls (textareas and text fields) 6 http://bugs.webkit.org/show_bug.cgi?id=7023 7 8 Test: editing/selection/find-in-text-control.html 9 10 * WebCore.base.exp: Updated the TextIterator constructor signature. 11 12 * editing/TextIterator.cpp: 13 (WebCore::TextIterator::TextIterator): Added an enterTextControls 14 boolean parameter that determines whether the iterator should visit text 15 inside text areas and text fields. Added code to initialize the 16 m_inShadowContent member variable based on whether the range is in 17 shadow content. 18 (WebCore::TextIterator::advance): Added code to step out of shadow 19 content. 20 (WebCore::TextIterator::handleReplacedElement): Added code to enter 21 text controls if desired. 22 (WebCore::CharacterIterator::CharacterIterator): Added an 23 enterTextControls boolean parameter that determines whether the iterator 24 should visit text inside text areas and text fields. This is passed to 25 the TextIterator constructor. 26 (WebCore::findPlainText): Changed to use a CharacterIterator that 27 visits text controls. 28 29 * editing/TextIterator.h: Added member variables to track whether the 30 current node is in a shadow tree and whether the iterator should visit 31 text controls. 32 33 * page/Frame.cpp: 34 (WebCore::Frame::findString): Changed to find inside text controls. 35 (WebCore::Frame::markAllMatchesForText): Ditto. 36 37 * rendering/RenderTextControl.cpp: 38 (WebCore::RenderTextControl::innerTextElement): Added. 39 * rendering/RenderTextControl.h: Added innerTextElement(), a private 40 accessor method that is accessible to TextIterator through class 41 friendship. 42 1 43 2008-06-26 Darin Adler <darin@apple.com> 2 44 -
trunk/WebCore/WebCore.base.exp
r34589 r34822 256 256 __ZN7WebCore12TextIterator26rangeFromLocationAndLengthEPNS_7ElementEiib 257 257 __ZN7WebCore12TextIterator7advanceEv 258 __ZN7WebCore12TextIteratorC1EPKNS_5RangeEb 258 __ZN7WebCore12TextIteratorC1EPKNS_5RangeEbb 259 259 __ZN7WebCore12applyCommandEN3WTF10PassRefPtrINS_11EditCommandEEE 260 260 __ZN7WebCore12cacheStorageEv -
trunk/WebCore/editing/TextIterator.cpp
r34596 r34822 38 38 #include "RenderTableCell.h" 39 39 #include "RenderTableRow.h" 40 #include "RenderTextControl.h" 40 41 #include "visible_units.h" 41 42 … … 73 74 // -------- 74 75 75 TextIterator::TextIterator() : m_startContainer(0), m_startOffset(0), m_endContainer(0), m_endOffset(0), m_positionNode(0), m_lastCharacter(0) 76 { 77 } 78 79 TextIterator::TextIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions) 80 : m_startContainer(0) 76 TextIterator::TextIterator() 77 : m_startContainer(0) 78 , m_startOffset(0) 79 , m_endContainer(0) 80 , m_endOffset(0) 81 , m_positionNode(0) 82 , m_lastCharacter(0) 83 , m_emitCharactersBetweenAllVisiblePositions(false) 84 , m_enterTextControls(false) 85 { 86 } 87 88 TextIterator::TextIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions, bool enterTextControls) 89 : m_inShadowContent(false) 90 , m_startContainer(0) 81 91 , m_startOffset(0) 82 92 , m_endContainer(0) … … 84 94 , m_positionNode(0) 85 95 , m_emitCharactersBetweenAllVisiblePositions(emitCharactersBetweenAllVisiblePositions) 96 , m_enterTextControls(enterTextControls) 86 97 { 87 98 if (!r) … … 107 118 m_endContainer = endContainer; 108 119 m_endOffset = endOffset; 109 120 121 for (Node* n = startContainer; n; n = n->parentNode()) { 122 if (n->isShadowNode()) { 123 m_inShadowContent = true; 124 break; 125 } 126 } 127 110 128 // set up the current node for processing 111 129 m_node = r->firstNode(); … … 202 220 if (!next) { 203 221 bool pastEnd = m_node->traverseNextNode() == m_pastEndNode; 204 while (!next && m_node->parentNode()) { 205 if (pastEnd && m_node->parentNode() == m_endContainer || m_endContainer->isDescendantOf(m_node->parentNode())) 222 Node* parentNode = m_node->parentNode(); 223 if (!parentNode && m_inShadowContent) { 224 m_inShadowContent = false; 225 parentNode = m_node->shadowParentNode(); 226 } 227 while (!next && parentNode) { 228 if (pastEnd && parentNode == m_endContainer || m_endContainer->isDescendantOf(parentNode)) 206 229 return; 207 230 bool haveRenderer = m_node->renderer(); 208 m_node = m_node->parentNode(); 231 m_node = parentNode; 232 parentNode = m_node->parentNode(); 233 if (!parentNode && m_inShadowContent) { 234 m_inShadowContent = false; 235 parentNode = m_node->shadowParentNode(); 236 } 209 237 if (haveRenderer) 210 238 exitNode(); … … 350 378 bool TextIterator::handleReplacedElement() 351 379 { 352 if (m_node->renderer()->style()->visibility() != VISIBLE) 380 RenderObject* renderer = m_node->renderer(); 381 if (renderer->style()->visibility() != VISIBLE) 353 382 return false; 354 383 … … 358 387 } 359 388 389 if (m_enterTextControls && (renderer->isTextArea() || renderer->isTextField())) { 390 m_node = static_cast<RenderTextControl*>(renderer)->innerTextElement(); 391 m_offset = 0; 392 m_inShadowContent = true; 393 return false; 394 } 395 360 396 m_haveEmitted = true; 361 397 362 398 if (m_emitCharactersBetweenAllVisiblePositions) { 363 399 // We want replaced elements to behave like punctuation for boundary … … 367 403 return true; 368 404 } 369 405 370 406 m_positionNode = m_node->parentNode(); 371 407 m_positionOffsetBaseNode = m_node; … … 895 931 896 932 CharacterIterator::CharacterIterator() 897 : m_offset(0), m_runOffset(0), m_atBreak(true) 898 { 899 } 900 901 CharacterIterator::CharacterIterator(const Range *r, bool emitCharactersBetweenAllVisiblePositions) 902 : m_offset(0), m_runOffset(0), m_atBreak(true), m_textIterator(r, emitCharactersBetweenAllVisiblePositions) 933 : m_offset(0) 934 , m_runOffset(0) 935 , m_atBreak(true) 936 { 937 } 938 939 CharacterIterator::CharacterIterator(const Range *r, bool emitCharactersBetweenAllVisiblePositions, bool enterTextControls) 940 : m_offset(0) 941 , m_runOffset(0) 942 , m_atBreak(true) 943 , m_textIterator(r, emitCharactersBetweenAllVisiblePositions, enterTextControls) 903 944 { 904 945 while (!atEnd() && m_textIterator.length() == 0) … … 1352 1393 { 1353 1394 CircularSearchBuffer searchBuffer(target, caseSensitive); 1354 CharacterIterator it(range );1395 CharacterIterator it(range, false, true); 1355 1396 for (;;) { 1356 1397 if (searchBuffer.isMatch()) { … … 1377 1418 1378 1419 if (matchLength) { 1379 CharacterIterator it(range );1420 CharacterIterator it(range, false, true); 1380 1421 it.advance(matchStart); 1381 1422 result->setStart(it.range()->startContainer(ec), it.range()->startOffset(ec), ec); -
trunk/WebCore/editing/TextIterator.h
r34780 r34822 57 57 public: 58 58 TextIterator(); 59 explicit TextIterator(const Range*, bool emitCharactersBetweenAllVisiblePositions = false );59 explicit TextIterator(const Range*, bool emitCharactersBetweenAllVisiblePositions = false, bool enterTextControls = false); 60 60 61 61 bool atEnd() const { return !m_positionNode; } … … 89 89 bool m_handledNode; 90 90 bool m_handledChildren; 91 bool m_inShadowContent; 91 92 92 93 // The range. … … 130 131 // moveParagraphs to not clone/destroy moved content. 131 132 bool m_emitCharactersBetweenAllVisiblePositions; 133 bool m_enterTextControls; 132 134 }; 133 135 … … 192 194 public: 193 195 CharacterIterator(); 194 explicit CharacterIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions = false );196 explicit CharacterIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions = false, bool enterTextControls = false); 195 197 196 198 void advance(int numCharacters); -
trunk/WebCore/page/Frame.cpp
r34627 r34822 1593 1593 Selection selection = this->selection()->selection(); 1594 1594 Node* selectionBaseNode = selection.base().node(); 1595 1596 // FIXME 3099526: We don't search in the shadow trees (e.g. text fields and textareas), though we'd like to 1597 // someday. If we don't explicitly skip them here, we'll miss hits in the regular content. 1595 1596 if (forward) 1597 setStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd()); 1598 else 1599 setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart()); 1600 1598 1601 bool selectionIsInMainContent = selectionBaseNode && !isInShadowTree(selectionBaseNode); 1599 1600 if (selectionIsInMainContent) { 1602 Node* shadowTreeRoot = 0; 1603 if (!selectionIsInMainContent) { 1604 shadowTreeRoot = selectionBaseNode; 1605 while (shadowTreeRoot && !shadowTreeRoot->isShadowNode()) 1606 shadowTreeRoot = shadowTreeRoot->parentNode(); 1607 } 1608 1609 if (shadowTreeRoot) { 1610 ExceptionCode ec = 0; 1601 1611 if (forward) 1602 se tStart(searchRange.get(), startInSelection ? selection.visibleStart() : selection.visibleEnd());1612 searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec); 1603 1613 else 1604 setEnd(searchRange.get(), startInSelection ? selection.visibleEnd() : selection.visibleStart()); 1605 } 1614 searchRange->setStart(shadowTreeRoot, 0, ec); 1615 } 1616 1606 1617 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, forward, caseFlag)); 1607 1618 // If we started in the selection and the found range exactly matches the existing selection, find again. 1608 1619 // Build a selection with the found range to remove collapsed whitespace. 1609 1620 // Compare ranges instead of selection objects to ignore the way that the current selection was made. 1610 if (startInSelection && selectionIsInMainContent &&*Selection(resultRange.get()).toRange() == *selection.toRange()) {1621 if (startInSelection && *Selection(resultRange.get()).toRange() == *selection.toRange()) { 1611 1622 searchRange = rangeOfContents(document()); 1612 1623 if (forward) … … 1614 1625 else 1615 1626 setEnd(searchRange.get(), selection.visibleStart()); 1627 1628 if (shadowTreeRoot) { 1629 ExceptionCode ec = 0; 1630 if (forward) 1631 searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), ec); 1632 else 1633 searchRange->setStart(shadowTreeRoot, 0, ec); 1634 } 1635 1616 1636 resultRange = findPlainText(searchRange.get(), target, forward, caseFlag); 1617 1637 } 1618 1638 1619 int exception = 0; 1620 1639 ExceptionCode exception = 0; 1640 1641 // If nothing was found in the shadow tree, search in main content following the shadow tree. 1642 if (resultRange->collapsed(exception) && shadowTreeRoot) { 1643 searchRange = rangeOfContents(document()); 1644 if (forward) 1645 searchRange->setStartAfter(shadowTreeRoot->shadowParentNode(), exception); 1646 else 1647 searchRange->setEndBefore(shadowTreeRoot->shadowParentNode(), exception); 1648 1649 resultRange = findPlainText(searchRange.get(), target, forward, caseFlag); 1650 } 1651 1621 1652 // If we didn't find anything and we're wrapping, search again in the entire document (this will 1622 1653 // redundantly re-search the area already searched in some cases). … … 1644 1675 RefPtr<Range> searchRange(rangeOfContents(document())); 1645 1676 1646 intexception = 0;1677 ExceptionCode exception = 0; 1647 1678 unsigned matchCount = 0; 1648 1679 do { 1649 1680 RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, true, caseFlag)); 1650 if (resultRange->collapsed(exception)) 1651 break; 1681 if (resultRange->collapsed(exception)) { 1682 if (!isInShadowTree(resultRange->startContainer())) 1683 break; 1684 1685 searchRange = rangeOfContents(document()); 1686 searchRange->setStartAfter(resultRange->startContainer()->shadowAncestorNode(), exception); 1687 continue; 1688 } 1652 1689 1653 1690 // A non-collapsed result range can in some funky whitespace cases still not … … 1666 1703 1667 1704 setStart(searchRange.get(), newStart); 1705 if (searchRange->collapsed(exception) && isInShadowTree(searchRange->startContainer())) { 1706 Node* shadowTreeRoot = searchRange->startContainer(); 1707 while (shadowTreeRoot && !shadowTreeRoot->isShadowNode()) 1708 shadowTreeRoot = shadowTreeRoot->parentNode(); 1709 if (shadowTreeRoot) 1710 searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception); 1711 } 1668 1712 } while (true); 1669 1713 -
trunk/WebCore/rendering/RenderTextControl.cpp
r34693 r34822 577 577 578 578 return String::adopt(result); 579 } 580 581 HTMLElement* RenderTextControl::innerTextElement() const 582 { 583 return m_innerText.get(); 579 584 } 580 585 -
trunk/WebCore/rendering/RenderTextControl.h
r34693 r34822 143 143 String finishText(Vector<UChar>&) const; 144 144 145 friend class TextIterator; 146 HTMLElement* innerTextElement() const; 147 145 148 RefPtr<HTMLTextFieldInnerElement> m_innerBlock; 146 149 RefPtr<HTMLTextFieldInnerTextElement> m_innerText;
Note: See TracChangeset
for help on using the changeset viewer.