Changeset 64974 in webkit
- Timestamp:
- Aug 9, 2010 4:40:10 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r64973 r64974 1 2010-05-20 MORITA Hajime <morrita@google.com> 2 3 Reviewed by Ojan Vafai. 4 5 <http://webkit.org/b/36360> 6 Double clicking page's first editable inline element cannot select a word. 7 <http://webkit.org/b/36359> 8 Double clicking page's last editable inline element causes assertion failure. 9 10 * editing/selection/doubleclick-inline-first-last-contenteditable-expected.txt: Added. 11 * editing/selection/doubleclick-inline-first-last-contenteditable.html: Added. 12 * editing/selection/script-tests/doubleclick-inline-first-last-contenteditable.js: Added. 13 1 14 2010-08-09 Ilya Tikhonovsky <loislo@chromium.org> 2 15 -
trunk/WebCore/ChangeLog
r64973 r64974 1 2010-05-27 MORITA Hajime <morrita@google.com> 2 3 Reviewed by Ojan Vafai. 4 5 <http://webkit.org/b/36359> 6 Double clicking page's last editable inline element causes assertion failure. 7 <http://webkit.org/b/36360> 8 Double clicking page's first editable inline element cannot select a word. 9 10 nextBoundary() and previousBoundary() assumed that editable 11 boundaries are on block-level elements, But it can appear on 12 inline-level elements. So we start boundary look-up from the given 13 node, instead of the containingBlock of the given node. 14 Also, added TextIteratorEndsAtEditingBoundary to 15 BackwardsCharacterIterator, otherwise, the VisiblePosition 16 returned by BackwardsCharacterIterator might cross an editing 17 boundary. 18 19 Test: editing/selection/doubleclick-inline-first-last-contenteditable.html 20 21 * dom/Position.cpp: 22 (WebCore::Position::parentEditingBoundary): Added. 23 * dom/Position.h: 24 * editing/TextIterator.cpp: 25 (WebCore::TextIterator::TextIterator): 26 (WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator): 27 (WebCore::SimplifiedBackwardsTextIterator::advance): 28 (WebCore::SimplifiedBackwardsTextIterator::crossesEditingBoundary): Added. 29 (WebCore::SimplifiedBackwardsTextIterator::setCurrentNode): Added. 30 (WebCore::SimplifiedBackwardsTextIterator::clearCurrentNode): Added. 31 (WebCore::BackwardsCharacterIterator::BackwardsCharacterIterator): 32 * editing/TextIterator.h: 33 (WebCore::): 34 * editing/visible_units.cpp: 35 (WebCore::previousBoundary): 36 (WebCore::nextBoundary): 37 1 38 2010-08-09 Ilya Tikhonovsky <loislo@chromium.org> 2 39 -
trunk/WebCore/dom/Position.cpp
r61724 r64974 329 329 } 330 330 331 Node* Position::parentEditingBoundary() const 332 { 333 if (!m_anchorNode || !m_anchorNode->document()) 334 return 0; 335 336 Node* documentElement = m_anchorNode->document()->documentElement(); 337 if (!documentElement) 338 return 0; 339 340 Node* boundary = m_anchorNode.get(); 341 while (boundary != documentElement && boundary->parentNode() && m_anchorNode->isContentEditable() == boundary->parentNode()->isContentEditable()) 342 boundary = boundary->parentNode(); 343 344 return boundary; 345 } 346 347 331 348 bool Position::atStartOfTree() const 332 349 { -
trunk/WebCore/dom/Position.h
r61441 r64974 139 139 // Returns true if the visually equivalent positions around have different editability 140 140 bool atEditingBoundary() const; 141 Node* parentEditingBoundary() const; 141 142 142 143 bool atStartOfTree() const; -
trunk/WebCore/editing/TextIterator.cpp
r58153 r64974 273 273 , m_emitsTextWithoutTranscoding(behavior & TextIteratorEmitsTextsWithoutTranscoding) 274 274 { 275 // FIXME: should support TextIteratorEndsAtEditingBoundary http://webkit.org/b/43609 276 ASSERT(behavior != TextIteratorEndsAtEditingBoundary); 277 275 278 if (!r) 276 279 return; … … 945 948 946 949 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator() 947 : m_positionNode(0) 948 { 949 } 950 951 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r) 952 : m_positionNode(0) 953 { 950 : m_behavior(TextIteratorDefaultBehavior) 951 , m_node(0) 952 , m_positionNode(0) 953 { 954 } 955 956 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, TextIteratorBehavior behavior) 957 : m_behavior(behavior) 958 , m_node(0) 959 , m_positionNode(0) 960 { 961 ASSERT(m_behavior == TextIteratorDefaultBehavior || m_behavior == TextIteratorEndsAtEditingBoundary); 962 954 963 if (!r) 955 964 return; … … 975 984 } 976 985 977 m_node = endNode;986 setCurrentNode(endNode); 978 987 setUpFullyClippedStack(m_fullyClippedStack, m_node); 979 988 m_offset = endOffset; … … 1039 1048 } 1040 1049 // Exit all other containers. 1041 next = m_node->previousSibling(); 1042 while (!next) { 1043 Node* parentNode = parentCrossingShadowBoundaries(m_node); 1044 if (!parentNode) 1050 while (!m_node->previousSibling()) { 1051 if (!setCurrentNode(parentCrossingShadowBoundaries(m_node))) 1045 1052 break; 1046 m_node = parentNode;1047 1053 m_fullyClippedStack.pop(); 1048 1054 exitNode(); … … 1052 1058 return; 1053 1059 } 1054 next = m_node->previousSibling();1055 1060 } 1061 1062 next = m_node->previousSibling(); 1056 1063 m_fullyClippedStack.pop(); 1057 1064 } 1058 1065 1059 m_node = next; 1060 if (m_node) 1066 if (m_node && setCurrentNode(next)) 1061 1067 pushFullyClippedState(m_fullyClippedStack, m_node); 1068 else 1069 clearCurrentNode(); 1070 1062 1071 // For the purpose of word boundary detection, 1063 1072 // we should iterate all visible text and trailing (collapsed) whitespaces. … … 1136 1145 m_textLength = 1; 1137 1146 m_lastCharacter = c; 1147 } 1148 1149 bool SimplifiedBackwardsTextIterator::crossesEditingBoundary(Node* node) const 1150 { 1151 return m_node && m_node->isContentEditable() != node->isContentEditable(); 1152 } 1153 1154 bool SimplifiedBackwardsTextIterator::setCurrentNode(Node* node) 1155 { 1156 if (!node) 1157 return false; 1158 if (m_behavior == TextIteratorEndsAtEditingBoundary && crossesEditingBoundary(node)) 1159 return false; 1160 m_node = node; 1161 return true; 1162 } 1163 1164 void SimplifiedBackwardsTextIterator::clearCurrentNode() 1165 { 1166 m_node = 0; 1138 1167 } 1139 1168 … … 1263 1292 } 1264 1293 1265 BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range )1294 BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextIteratorBehavior behavior) 1266 1295 : m_offset(0) 1267 1296 , m_runOffset(0) 1268 1297 , m_atBreak(true) 1269 , m_textIterator(range )1298 , m_textIterator(range, behavior) 1270 1299 { 1271 1300 while (!atEnd() && !m_textIterator.length()) -
trunk/WebCore/editing/TextIterator.h
r58149 r64974 74 74 TextIteratorEntersTextControls = 1 << 1, 75 75 TextIteratorEmitsTextsWithoutTranscoding = 1 << 2, 76 TextIteratorEndsAtEditingBoundary = 1 << 3 76 77 }; 77 78 … … 168 169 public: 169 170 SimplifiedBackwardsTextIterator(); 170 explicit SimplifiedBackwardsTextIterator(const Range* );171 explicit SimplifiedBackwardsTextIterator(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior); 171 172 172 173 bool atEnd() const { return !m_positionNode; } … … 184 185 bool handleNonTextNode(); 185 186 void emitCharacter(UChar, Node*, int startOffset, int endOffset); 186 187 bool crossesEditingBoundary(Node*) const; 188 bool setCurrentNode(Node*); 189 void clearCurrentNode(); 190 191 TextIteratorBehavior m_behavior; 187 192 // Current position, not necessarily of the text being returned, but position 188 193 // as we walk through the DOM tree. … … 248 253 public: 249 254 BackwardsCharacterIterator(); 250 explicit BackwardsCharacterIterator(const Range* );255 explicit BackwardsCharacterIterator(const Range*, TextIteratorBehavior = TextIteratorDefaultBehavior); 251 256 252 257 void advance(int); … … 257 262 258 263 private: 264 TextIteratorBehavior m_behavior; 259 265 int m_offset; 260 266 int m_runOffset; -
trunk/WebCore/editing/visible_units.cpp
r63918 r64974 76 76 { 77 77 Position pos = c.deepEquivalent(); 78 Node *n = pos.node(); 79 if (!n) 80 return VisiblePosition(); 81 Document *d = n->document(); 82 Node *de = d->documentElement(); 83 if (!de) 84 return VisiblePosition(); 85 Node *boundary = n->enclosingBlockFlowElement(); 78 Node* boundary = pos.parentEditingBoundary(); 86 79 if (!boundary) 87 80 return VisiblePosition(); 88 bool isContentEditable = boundary->isContentEditable(); 89 while (boundary && boundary != de && boundary->parentNode() && isContentEditable == boundary->parentNode()->isContentEditable()) 90 boundary = boundary->parentNode(); 91 81 82 Document* d = boundary->document(); 92 83 Position start = rangeCompliantEquivalent(Position(boundary, 0)); 93 84 Position end = rangeCompliantEquivalent(pos); … … 122 113 return VisiblePosition(); 123 114 124 SimplifiedBackwardsTextIterator it(searchRange.get() );115 SimplifiedBackwardsTextIterator it(searchRange.get(), TextIteratorEndsAtEditingBoundary); 125 116 unsigned next = 0; 126 117 bool inTextSecurityMode = start.node() && start.node()->renderer() && start.node()->renderer()->style()->textSecurity() != TSNONE; … … 157 148 else { 158 149 // Use the character iterator to translate the next value into a DOM position. 159 BackwardsCharacterIterator charIt(searchRange.get() );150 BackwardsCharacterIterator charIt(searchRange.get(), TextIteratorEndsAtEditingBoundary); 160 151 charIt.advance(string.size() - suffixLength - next); 161 152 pos = charIt.range()->endPosition(); … … 169 160 { 170 161 Position pos = c.deepEquivalent(); 171 Node *n = pos.node(); 172 if (!n) 173 return VisiblePosition(); 174 Document *d = n->document(); 175 Node *de = d->documentElement(); 176 if (!de) 177 return VisiblePosition(); 178 Node *boundary = n->enclosingBlockFlowElement(); 162 Node* boundary = pos.parentEditingBoundary(); 179 163 if (!boundary) 180 164 return VisiblePosition(); 181 bool isContentEditable = boundary->isContentEditable(); 182 while (boundary && boundary != de && boundary->parentNode() && isContentEditable == boundary->parentNode()->isContentEditable()) 183 boundary = boundary->parentNode(); 184 165 166 Document* d = boundary->document(); 185 167 RefPtr<Range> searchRange(d->createRange()); 186 168 Position start(rangeCompliantEquivalent(pos));
Note: See TracChangeset
for help on using the changeset viewer.