Changeset 44674 in webkit
- Timestamp:
- Jun 14, 2009 7:39:09 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r44671 r44674 1 2009-06-14 Darin Adler <darin@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 Bug 26364: Search can find text that's hidden by overflow:hidden 6 https://bugs.webkit.org/show_bug.cgi?id=26364 7 <rdar://problem/6952081> 8 9 * fast/text/find-hidden-text-expected.txt: Added. 10 * fast/text/find-hidden-text.html: Added. 11 12 * fast/block/float/crash-replaced-display-block-expected.txt: Removed a space. 13 * fast/dom/Range/acid3-surround-contents-expected.txt: Removed a blank line. 14 * fast/dom/object-embed-plugin-scripting-expected.txt: Removed four spaces. 15 * fast/parser/badentity-expected.txt: Removed a blank line. 16 * http/tests/security/local-video-poster-from-remote-expected.txt: Removed a blank line. 17 1 18 2009-06-14 Simon Fraser <simon.fraser@apple.com> 2 19 -
trunk/LayoutTests/fast/block/float/crash-replaced-display-block-expected.txt
r40431 r44674 1 1 This tests rdar://problem/6545095 ASSERTION FAILED: RenderBlock.h:519: !o || o->isRenderBlock() 2 2 3 3 -
trunk/LayoutTests/fast/dom/Range/acid3-surround-contents-expected.txt
r31090 r44674 1 2 1 The test below should report no failures, and should say PASS at the end. 3 2 -
trunk/LayoutTests/fast/dom/object-embed-plugin-scripting-expected.txt
r11962 r44674 15 15 standalone plugin <embed>: should have a plugin and does 16 16 17 17 -
trunk/LayoutTests/fast/parser/badentity-expected.txt
r21687 r44674 1 1 Test for bug 13495: REPRODUCIBLE CRASH: Referencing an undefined entity in an XHTML document. 2 2 3 4 3 If you don't crash, you pass. -
trunk/LayoutTests/http/tests/security/local-video-poster-from-remote-expected.txt
r42533 r44674 1 1 CONSOLE MESSAGE: line 0: Not allowed to load local resource: compass.jpg 2 2 CONSOLE MESSAGE: line 0: Not allowed to load local resource: compass.jpg 3 4 3 Test that a remote video element can not use a local poster 5 4 -
trunk/WebCore/ChangeLog
r44673 r44674 1 2009-06-14 Darin Adler <darin@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 Bug 26364: Search can find text that's hidden by overflow:hidden 6 https://bugs.webkit.org/show_bug.cgi?id=26364 7 <rdar://problem/6952081> 8 9 Test: fast/text/find-hidden-text.html 10 11 * editing/TextIterator.cpp: 12 (WebCore::BitStack::BitStack): Added. 13 (WebCore::BitStack::push): Added. 14 (WebCore::BitStack::pop): Added. 15 (WebCore::BitStack::top): Added. 16 (WebCore::BitStack::size): Added. 17 (WebCore::parentOrShadowParent): Added. Helper function for walking up 18 the parent node chain, crossing shadow tree boundaries. 19 (WebCore::depthCrossingShadowBoundaries): Added for use in assertions. 20 Counts the depth of a node using the parentOrShadowParent function. 21 (WebCore::fullyClipsContents): Added. Returns true for an element that 22 fully clips its contents, currently defined as a box that has zero width 23 or height and hides overflow. We can add other cases here later. 24 (WebCore::ignoresContainerClip): Added. Returns true for an element that 25 ignores its container clip, currently defined as an element with absolute 26 or fixed positioning. 27 (WebCore::pushFullyClippedState): Added. Pushes a bit on the stack indicating 28 if the node in question fully clips its contents. 29 (WebCore::setUpFullyClippedStack): Added. Pushes a bit for each ancestor of 30 a node. Used when creating an iterator. 31 (WebCore::TextIterator::TextIterator): Removed code to initialize 32 m_inShadowContent. Call setUpFullyClippedStack. 33 (WebCore::TextIterator::advance): Use parentOrShadowParent. Call pop when moving 34 up to a parent node, and also one extra time when moving to a sibling node. 35 Call pushFullyClippedState when moving to a child node, or when moving to a 36 sibling node after the aforementioned call to pop. 37 (WebCore::TextIterator::handleTextNode): Return early if the node is fully clipped. 38 (WebCore::TextIterator::handleReplacedElement): Ditto. 39 (WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator): 40 Call setUpFullyClippedStack. 41 (WebCore::SimplifiedBackwardsTextIterator::advance): Same changes as 42 TextIterator::advance above. 43 44 * editing/TextIterator.h: Added BitStack class and added m_fullyClippedStack to both 45 TextIterator and SimplifiedBackwardsTextIterator. Removed unneeded m_inShadowContent. 46 1 47 2009-06-14 David Hyatt <hyatt@apple.com> 2 48 -
trunk/WebCore/editing/TextIterator.cpp
r43533 r44674 98 98 // -------- 99 99 100 BitStack::BitStack() 101 : m_size(0) 102 { 103 } 104 105 void BitStack::push(bool bit) 106 { 107 unsigned index = m_size / 0x20; 108 unsigned shift = m_size & 0x1F; 109 if (!shift && index == m_words.size()) 110 m_words.grow(index + 1); 111 unsigned& word = m_words[index]; 112 unsigned mask = 1U << shift; 113 if (bit) 114 word |= mask; 115 else 116 word &= ~mask; 117 ++m_size; 118 } 119 120 void BitStack::pop() 121 { 122 if (m_size) 123 --m_size; 124 } 125 126 bool BitStack::top() const 127 { 128 if (!m_size) 129 return false; 130 unsigned shift = (m_size - 1) & 0x1F; 131 return m_words.last() & (1U << shift); 132 } 133 134 unsigned BitStack::size() const 135 { 136 return m_size; 137 } 138 139 // -------- 140 141 static inline Node* parentOrShadowParent(Node* node) 142 { 143 if (Node* parent = node->parentNode()) 144 return parent; 145 return node->shadowParentNode(); 146 } 147 148 #ifndef NDEBUG 149 150 static unsigned depthCrossingShadowBoundaries(Node* node) 151 { 152 unsigned depth = 0; 153 for (Node* parent = parentOrShadowParent(node); parent; parent = parentOrShadowParent(parent)) 154 ++depth; 155 return depth; 156 } 157 158 #endif 159 160 static inline bool fullyClipsContents(Node* node) 161 { 162 RenderObject* renderer = node->renderer(); 163 if (!renderer || !renderer->isBox()) 164 return false; 165 RenderStyle* style = renderer->style(); 166 if (style->overflowX() == OVISIBLE && style->overflowY() == OVISIBLE) 167 return false; 168 return toRenderBox(renderer)->size().isEmpty(); 169 } 170 171 static inline bool ignoresContainerClip(Node* node) 172 { 173 RenderObject* renderer = node->renderer(); 174 if (!renderer || renderer->isText()) 175 return false; 176 EPosition position = renderer->style()->position(); 177 return position == AbsolutePosition || position == FixedPosition; 178 } 179 180 static void pushFullyClippedState(BitStack& stack, Node* node) 181 { 182 ASSERT(stack.size() == depthCrossingShadowBoundaries(node)); 183 184 // Push true if this node full clips its contents, or if a parent already has fully 185 // clipped and this is not a node that ignores its container's clip. 186 stack.push(fullyClipsContents(node) || stack.top() && !ignoresContainerClip(node)); 187 } 188 189 static void setUpFullyClippedStack(BitStack& stack, Node* node) 190 { 191 // Put the nodes in a vector so we can iterate in reverse order. 192 Vector<Node*, 100> ancestry; 193 for (Node* parent = parentOrShadowParent(node); parent; parent = parentOrShadowParent(parent)) 194 ancestry.append(parent); 195 196 // Call pushFullyClippedState on each node starting with the earliest ancestor. 197 size_t size = ancestry.size(); 198 for (size_t i = 0; i < size; ++i) 199 pushFullyClippedState(stack, ancestry[size - i - 1]); 200 pushFullyClippedState(stack, node); 201 202 ASSERT(stack.size() == 1 + depthCrossingShadowBoundaries(node)); 203 } 204 205 // -------- 206 100 207 TextIterator::TextIterator() 101 208 : m_startContainer(0) … … 113 220 114 221 TextIterator::TextIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions, bool enterTextControls) 115 : m_inShadowContent(false) 116 , m_startContainer(0) 222 : m_startContainer(0) 117 223 , m_startOffset(0) 118 224 , m_endContainer(0) … … 145 251 m_endOffset = endOffset; 146 252 147 for (Node* n = startContainer; n; n = n->parentNode()) {148 if (n->isShadowNode()) {149 m_inShadowContent = true;150 break;151 }152 }153 154 253 // set up the current node for processing 155 254 m_node = r->firstNode(); 156 if ( m_node == 0)255 if (!m_node) 157 256 return; 257 setUpFullyClippedStack(m_fullyClippedStack, m_node); 158 258 m_offset = m_node == m_startContainer ? m_startOffset : 0; 159 259 m_handledNode = false; … … 220 320 } 221 321 222 RenderObject *renderer = m_node->renderer();322 RenderObject* renderer = m_node->renderer(); 223 323 if (!renderer) { 224 324 m_handledNode = true; … … 242 342 // find a new current node to handle in depth-first manner, 243 343 // calling exitNode() as we come back thru a parent node 244 Node *next = m_handledChildren ? 0 : m_node->firstChild();344 Node* next = m_handledChildren ? 0 : m_node->firstChild(); 245 345 m_offset = 0; 246 346 if (!next) { … … 248 348 if (!next) { 249 349 bool pastEnd = m_node->traverseNextNode() == m_pastEndNode; 250 Node* parentNode = m_node->parentNode(); 251 if (!parentNode && m_inShadowContent) { 252 m_inShadowContent = false; 253 parentNode = m_node->shadowParentNode(); 254 } 350 Node* parentNode = parentOrShadowParent(m_node); 255 351 while (!next && parentNode) { 256 352 if ((pastEnd && parentNode == m_endContainer) || m_endContainer->isDescendantOf(parentNode)) … … 258 354 bool haveRenderer = m_node->renderer(); 259 355 m_node = parentNode; 260 parentNode = m_node->parentNode(); 261 if (!parentNode && m_inShadowContent) { 262 m_inShadowContent = false; 263 parentNode = m_node->shadowParentNode(); 264 } 356 m_fullyClippedStack.pop(); 357 parentNode = parentOrShadowParent(m_node); 265 358 if (haveRenderer) 266 359 exitNode(); … … 273 366 } 274 367 } 368 m_fullyClippedStack.pop(); 275 369 } 276 370 277 371 // set the new current node 278 372 m_node = next; 373 if (m_node) 374 pushFullyClippedState(m_fullyClippedStack, m_node); 279 375 m_handledNode = false; 280 376 m_handledChildren = false; … … 286 382 } 287 383 288 static inline bool compareBoxStart(const InlineTextBox *first, const InlineTextBox *second)384 static inline bool compareBoxStart(const InlineTextBox* first, const InlineTextBox* second) 289 385 { 290 386 return first->start() < second->start(); … … 293 389 bool TextIterator::handleTextNode() 294 390 { 391 if (m_fullyClippedStack.top()) 392 return false; 393 295 394 RenderText* renderer = toRenderText(m_node->renderer()); 296 395 if (renderer->style()->visibility() != VISIBLE) … … 326 425 if (renderer->containsReversedText()) { 327 426 m_sortedTextBoxes.clear(); 328 for (InlineTextBox 427 for (InlineTextBox* textBox = renderer->firstTextBox(); textBox; textBox = textBox->nextTextBox()) { 329 428 m_sortedTextBoxes.append(textBox); 330 429 } … … 340 439 void TextIterator::handleTextBox() 341 440 { 342 RenderText *renderer = toRenderText(m_node->renderer());441 RenderText* renderer = toRenderText(m_node->renderer()); 343 442 String str = renderer->text(); 344 443 int start = m_offset; … … 349 448 350 449 // Check for collapsed space at the start of this run. 351 InlineTextBox *firstTextBox = renderer->containsReversedText() ? m_sortedTextBoxes[0] : renderer->firstTextBox();450 InlineTextBox* firstTextBox = renderer->containsReversedText() ? m_sortedTextBoxes[0] : renderer->firstTextBox(); 352 451 bool needSpace = m_lastTextNodeEndedWithCollapsedSpace 353 452 || (m_textBox == firstTextBox && textBoxStart == runStart && runStart > 0); … … 366 465 367 466 // Determine what the next text box will be, but don't advance yet 368 InlineTextBox *nextTextBox = 0;467 InlineTextBox* nextTextBox = 0; 369 468 if (renderer->containsReversedText()) { 370 469 if (m_sortedTextBoxesPosition + 1 < m_sortedTextBoxes.size()) … … 412 511 bool TextIterator::handleReplacedElement() 413 512 { 513 if (m_fullyClippedStack.top()) 514 return false; 515 414 516 RenderObject* renderer = m_node->renderer(); 415 517 if (renderer->style()->visibility() != VISIBLE) … … 423 525 if (m_enterTextControls && renderer->isTextControl()) { 424 526 m_node = toRenderTextControl(renderer)->innerTextElement(); 527 pushFullyClippedState(m_fullyClippedStack, m_node); 425 528 m_offset = 0; 426 m_inShadowContent = true;427 529 return false; 428 530 } … … 699 801 } 700 802 701 void TextIterator::emitCharacter(UChar c, Node *textNode, Node *offsetBaseNode, int textStartOffset, int textEndOffset)803 void TextIterator::emitCharacter(UChar c, Node* textNode, Node* offsetBaseNode, int textStartOffset, int textEndOffset) 702 804 { 703 805 m_haveEmitted = true; … … 779 881 } 780 882 781 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range *r)883 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r) 782 884 { 783 885 m_positionNode = 0; … … 807 909 808 910 m_node = endNode; 911 setUpFullyClippedStack(m_fullyClippedStack, m_node); 809 912 m_offset = endOffset; 810 913 m_handledNode = false; … … 846 949 // Don't handle node if we start iterating at [node, 0]. 847 950 if (!m_handledNode && !(m_node == m_endNode && m_endOffset == 0)) { 848 RenderObject *renderer = m_node->renderer();951 RenderObject* renderer = m_node->renderer(); 849 952 if (renderer && renderer->isText() && m_node->nodeType() == Node::TEXT_NODE) { 850 953 // FIXME: What about CDATA_SECTION_NODE? … … 878 981 next = m_node->previousSibling(); 879 982 while (!next) { 880 if (!m_node->parentNode()) 983 Node* parentNode = parentOrShadowParent(m_node); 984 if (!parentNode) 881 985 break; 882 m_node = m_node->parentNode(); 986 m_node = parentNode; 987 m_fullyClippedStack.pop(); 883 988 exitNode(); 884 989 if (m_positionNode) { … … 889 994 next = m_node->previousSibling(); 890 995 } 996 m_fullyClippedStack.pop(); 891 997 } 892 998 893 999 m_node = next; 1000 if (m_node) 1001 pushFullyClippedState(m_fullyClippedStack, m_node); 894 1002 m_offset = m_node ? caretMaxOffset(m_node) : 0; 895 1003 m_handledNode = false; … … 905 1013 m_lastTextNode = m_node; 906 1014 907 RenderText *renderer = toRenderText(m_node->renderer());1015 RenderText* renderer = toRenderText(m_node->renderer()); 908 1016 String str = renderer->text(); 909 1017 … … 961 1069 } 962 1070 963 void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node *node, int startOffset, int endOffset)1071 void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int startOffset, int endOffset) 964 1072 { 965 1073 m_singleCharacterBuffer = c; … … 989 1097 } 990 1098 991 CharacterIterator::CharacterIterator(const Range *r, bool emitCharactersBetweenAllVisiblePositions, bool enterTextControls)1099 CharacterIterator::CharacterIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions, bool enterTextControls) 992 1100 : m_offset(0) 993 1101 , m_runOffset(0) … … 1168 1276 1169 1277 WordAwareIterator::WordAwareIterator() 1170 : m_previousText(0), m_didLookAhead(false) 1171 { 1172 } 1173 1174 WordAwareIterator::WordAwareIterator(const Range *r) 1175 : m_previousText(0), m_didLookAhead(false), m_textIterator(r) 1176 { 1177 m_didLookAhead = true; // so we consider the first chunk from the text iterator 1178 advance(); // get in position over the first chunk of text 1278 : m_previousText(0) 1279 , m_didLookAhead(false) 1280 { 1281 } 1282 1283 WordAwareIterator::WordAwareIterator(const Range* r) 1284 : m_previousText(0) 1285 , m_didLookAhead(true) // so we consider the first chunk from the text iterator 1286 , m_textIterator(r) 1287 { 1288 advance(); // get in position over the first chunk of text 1179 1289 } 1180 1290 … … 1186 1296 // - We built up our own chunk of text from many chunks from the text iterator 1187 1297 1188 // FIXME: Perf could be bad for huge spans next to each other that don't fall on word boundaries1298 // FIXME: Performance could be bad for huge spans next to each other that don't fall on word boundaries. 1189 1299 1190 1300 void WordAwareIterator::advance() … … 1508 1618 // -------- 1509 1619 1510 int TextIterator::rangeLength(const Range *r, bool forSelectionPreservation)1620 int TextIterator::rangeLength(const Range* r, bool forSelectionPreservation) 1511 1621 { 1512 1622 int length = 0; … … 1523 1633 } 1524 1634 1525 PassRefPtr<Range> TextIterator::rangeFromLocationAndLength(Element *scope, int rangeLocation, int rangeLength, bool forSelectionPreservation)1635 PassRefPtr<Range> TextIterator::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, bool forSelectionPreservation) 1526 1636 { 1527 1637 RefPtr<Range> resultRange = scope->document()->createRange(); -
trunk/WebCore/editing/TextIterator.h
r41607 r44674 1 1 /* 2 * Copyright (C) 2004, 2006 Apple Computer, Inc.All rights reserved.2 * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 50 50 PassRefPtr<Range> findPlainText(const Range*, const String&, bool forward, bool caseSensitive); 51 51 52 class BitStack { 53 public: 54 BitStack(); 55 56 void push(bool); 57 void pop(); 58 59 bool top() const; 60 unsigned size() const; 61 62 private: 63 unsigned m_size; 64 Vector<unsigned, 1> m_words; 65 }; 66 52 67 // Iterates through the DOM range, returning all the text, and 0-length boundaries 53 68 // at points where replaced elements break up the text flow. The text comes back in … … 81 96 bool handleNonTextNode(); 82 97 void handleTextBox(); 83 void emitCharacter(UChar, Node *textNode, Node *offsetBaseNode, int textStartOffset, int textEndOffset);84 void emitText(Node *textNode, int textStartOffset, int textEndOffset);98 void emitCharacter(UChar, Node* textNode, Node* offsetBaseNode, int textStartOffset, int textEndOffset); 99 void emitText(Node* textNode, int textStartOffset, int textEndOffset); 85 100 86 101 // Current position, not necessarily of the text being returned, but position 87 102 // as we walk through the DOM tree. 88 Node *m_node;103 Node* m_node; 89 104 int m_offset; 90 105 bool m_handledNode; 91 106 bool m_handledChildren; 92 bool m_inShadowContent;107 BitStack m_fullyClippedStack; 93 108 94 109 // The range. 95 Node *m_startContainer;110 Node* m_startContainer; 96 111 int m_startOffset; 97 Node *m_endContainer;112 Node* m_endContainer; 98 113 int m_endOffset; 99 Node *m_pastEndNode;114 Node* m_pastEndNode; 100 115 101 116 // The current text and its position, in the form to be returned from the iterator. 102 Node *m_positionNode;103 mutable Node *m_positionOffsetBaseNode;117 Node* m_positionNode; 118 mutable Node* m_positionOffsetBaseNode; 104 119 mutable int m_positionStartOffset; 105 120 mutable int m_positionEndOffset; … … 110 125 // are false and 0, we go back to normal iterating. 111 126 bool m_needAnotherNewline; 112 InlineTextBox *m_textBox;127 InlineTextBox* m_textBox; 113 128 114 129 // Used to do the whitespace collapsing logic. 115 Node *m_lastTextNode;130 Node* m_lastTextNode; 116 131 bool m_lastTextNodeEndedWithCollapsedSpace; 117 132 UChar m_lastCharacter; … … 136 151 137 152 // Iterates through the DOM range, returning all the text, and 0-length boundaries 138 // at points where replaced elements break up the text flow. 153 // at points where replaced elements break up the text flow. The text comes back in 139 154 // chunks so as to optimize for performance of the iteration. 140 155 class SimplifiedBackwardsTextIterator { 141 156 public: 142 157 SimplifiedBackwardsTextIterator(); 143 explicit SimplifiedBackwardsTextIterator(const Range 158 explicit SimplifiedBackwardsTextIterator(const Range*); 144 159 145 160 bool atEnd() const { return !m_positionNode; } … … 156 171 bool handleReplacedElement(); 157 172 bool handleNonTextNode(); 158 void emitCharacter(UChar, Node *Node, int startOffset, int endOffset);173 void emitCharacter(UChar, Node*, int startOffset, int endOffset); 159 174 160 175 // Current position, not necessarily of the text being returned, but position … … 164 179 bool m_handledNode; 165 180 bool m_handledChildren; 166 181 BitStack m_fullyClippedStack; 182 167 183 // End of the range. 168 184 Node* m_startNode; … … 195 211 public: 196 212 CharacterIterator(); 197 explicit CharacterIterator(const Range* r, bool emitCharactersBetweenAllVisiblePositions = false, bool enterTextControls = false);213 explicit CharacterIterator(const Range*, bool emitCharactersBetweenAllVisiblePositions = false, bool enterTextControls = false); 198 214 199 215 void advance(int numCharacters); … … 241 257 public: 242 258 WordAwareIterator(); 243 explicit WordAwareIterator(const Range *r);259 explicit WordAwareIterator(const Range*); 244 260 245 261 bool atEnd() const { return !m_didLookAhead && m_textIterator.atEnd(); }
Note: See TracChangeset
for help on using the changeset viewer.