Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1079)

Side by Side Diff: Source/core/dom/Position.cpp

Issue 24278008: [oilpan] Handlify Nodes in htmlediting (Closed) Base URL: svn://svn.chromium.org/blink/branches/oilpan
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 Position::Position(const Handle<Node>& anchorNode, AnchorType anchorType) 91 Position::Position(const Handle<Node>& anchorNode, AnchorType anchorType)
92 : m_anchorNode(anchorNode) 92 : m_anchorNode(anchorNode)
93 , m_offset(0) 93 , m_offset(0)
94 , m_anchorType(anchorType) 94 , m_anchorType(anchorType)
95 , m_isLegacyEditingPosition(false) 95 , m_isLegacyEditingPosition(false)
96 { 96 {
97 ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement()); 97 ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
98 98
99 ASSERT(anchorType != PositionIsOffsetInAnchor); 99 ASSERT(anchorType != PositionIsOffsetInAnchor);
100 ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIs AfterChildren) 100 ASSERT(!((anchorType == PositionIsBeforeChildren || anchorType == PositionIs AfterChildren)
101 && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNod e.raw())))); 101 && (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNod e))));
102 } 102 }
103 103
104 Position::Position(const Handle<Node>& anchorNode, int offset, AnchorType anchor Type) 104 Position::Position(const Handle<Node>& anchorNode, int offset, AnchorType anchor Type)
105 : m_anchorNode(anchorNode) 105 : m_anchorNode(anchorNode)
106 , m_offset(offset) 106 , m_offset(offset)
107 , m_anchorType(anchorType) 107 , m_anchorType(anchorType)
108 , m_isLegacyEditingPosition(false) 108 , m_isLegacyEditingPosition(false)
109 { 109 {
110 ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement()); 110 ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
111 111
112 ASSERT(anchorType == PositionIsOffsetInAnchor); 112 ASSERT(anchorType == PositionIsOffsetInAnchor);
113 } 113 }
114 114
115 Position::Position(const Handle<Text>& textNode, unsigned offset) 115 Position::Position(const Handle<Text>& textNode, unsigned offset)
116 : m_anchorNode(textNode) 116 : m_anchorNode(textNode)
117 , m_offset(static_cast<int>(offset)) 117 , m_offset(static_cast<int>(offset))
118 , m_anchorType(PositionIsOffsetInAnchor) 118 , m_anchorType(PositionIsOffsetInAnchor)
119 , m_isLegacyEditingPosition(false) 119 , m_isLegacyEditingPosition(false)
120 { 120 {
121 ASSERT(m_anchorNode); 121 ASSERT(m_anchorNode);
122 } 122 }
123 123
124 void Position::moveToPosition(const Handle<Node>& node, int offset) 124 void Position::moveToPosition(const Handle<Node>& node, int offset)
125 { 125 {
126 ASSERT(!editingIgnoresContent(node.raw())); 126 ASSERT(!editingIgnoresContent(node));
127 ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition ); 127 ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition );
128 m_anchorNode = node; 128 m_anchorNode = node;
129 m_offset = offset; 129 m_offset = offset;
130 if (m_isLegacyEditingPosition) 130 if (m_isLegacyEditingPosition)
131 m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode, m_offset ); 131 m_anchorType = anchorTypeForLegacyEditingPosition(m_anchorNode, m_offset );
132 } 132 }
133 void Position::moveToOffset(int offset) 133 void Position::moveToOffset(int offset)
134 { 134 {
135 ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition ); 135 ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition );
136 m_offset = offset; 136 m_offset = offset;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 return m_anchorNode->nodeIndex() + 1; 191 return m_anchorNode->nodeIndex() + 1;
192 } 192 }
193 ASSERT_NOT_REACHED(); 193 ASSERT_NOT_REACHED();
194 return 0; 194 return 0;
195 } 195 }
196 196
197 int Position::offsetForPositionAfterAnchor() const 197 int Position::offsetForPositionAfterAnchor() const
198 { 198 {
199 ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren); 199 ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren);
200 ASSERT(!m_isLegacyEditingPosition); 200 ASSERT(!m_isLegacyEditingPosition);
201 return lastOffsetForEditing(m_anchorNode.raw()); 201 return lastOffsetForEditing(m_anchorNode);
202 } 202 }
203 203
204 // Neighbor-anchored positions are invalid DOM positions, so they need to be 204 // Neighbor-anchored positions are invalid DOM positions, so they need to be
205 // fixed up before handing them off to the Range object. 205 // fixed up before handing them off to the Range object.
206 Position Position::parentAnchoredEquivalent() const 206 Position Position::parentAnchoredEquivalent() const
207 { 207 {
208 if (!m_anchorNode) 208 if (!m_anchorNode)
209 return Position(); 209 return Position();
210 210
211 // FIXME: This should only be necessary for legacy positions, but is also ne eded for positions before and after Tables 211 // FIXME: This should only be necessary for legacy positions, but is also ne eded for positions before and after Tables
212 if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) { 212 if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
213 if (findParent(m_anchorNode) && (editingIgnoresContent(m_anchorNode.raw( )) || isTableElement(m_anchorNode.raw()))) 213 if (findParent(m_anchorNode) && (editingIgnoresContent(m_anchorNode) || isTableElement(m_anchorNode)))
214 return positionInParentBeforeNode(m_anchorNode); 214 return positionInParentBeforeNode(m_anchorNode);
215 return Position(m_anchorNode, 0, PositionIsOffsetInAnchor); 215 return Position(m_anchorNode, 0, PositionIsOffsetInAnchor);
216 } 216 }
217 if (!m_anchorNode->offsetInCharacters() 217 if (!m_anchorNode->offsetInCharacters()
218 && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsA fterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount( )) 218 && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsA fterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount( ))
219 && (editingIgnoresContent(m_anchorNode.raw()) || isTableElement(m_anchor Node.raw())) 219 && (editingIgnoresContent(m_anchorNode) || isTableElement(m_anchorNode))
220 && containerNode()) { 220 && containerNode()) {
221 return positionInParentAfterNode(m_anchorNode); 221 return positionInParentAfterNode(m_anchorNode);
222 } 222 }
223 223
224 return Position(containerNode(), computeOffsetInContainerNode(), PositionIsO ffsetInAnchor); 224 return Position(containerNode(), computeOffsetInContainerNode(), PositionIsO ffsetInAnchor);
225 } 225 }
226 226
227 Result<Node> Position::computeNodeBeforePosition() const 227 Result<Node> Position::computeNodeBeforePosition() const
228 { 228 {
229 if (!m_anchorNode) 229 if (!m_anchorNode)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 return m_anchorNode; 261 return m_anchorNode;
262 case PositionIsAfterAnchor: 262 case PositionIsAfterAnchor:
263 return m_anchorNode->nextSibling(); 263 return m_anchorNode->nextSibling();
264 } 264 }
265 ASSERT_NOT_REACHED(); 265 ASSERT_NOT_REACHED();
266 return nullptr; 266 return nullptr;
267 } 267 }
268 268
269 Position::AnchorType Position::anchorTypeForLegacyEditingPosition(const Handle<N ode>& anchorNode, int offset) 269 Position::AnchorType Position::anchorTypeForLegacyEditingPosition(const Handle<N ode>& anchorNode, int offset)
270 { 270 {
271 if (anchorNode && editingIgnoresContent(anchorNode.raw())) { 271 if (anchorNode && editingIgnoresContent(anchorNode)) {
272 if (offset == 0) 272 if (offset == 0)
273 return Position::PositionIsBeforeAnchor; 273 return Position::PositionIsBeforeAnchor;
274 return Position::PositionIsAfterAnchor; 274 return Position::PositionIsAfterAnchor;
275 } 275 }
276 return Position::PositionIsOffsetInAnchor; 276 return Position::PositionIsOffsetInAnchor;
277 } 277 }
278 278
279 // FIXME: This method is confusing (does it return anchorNode() or containerNode ()?) and should be renamed or removed 279 // FIXME: This method is confusing (does it return anchorNode() or containerNode ()?) and should be renamed or removed
280 Result<Element> Position::element() const 280 Result<Element> Position::element() const
281 { 281 {
(...skipping 19 matching lines...) Expand all
301 if (!n) 301 if (!n)
302 return *this; 302 return *this;
303 303
304 int o = deprecatedEditingOffset(); 304 int o = deprecatedEditingOffset();
305 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. 305 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r.
306 ASSERT(o >= 0); 306 ASSERT(o >= 0);
307 307
308 if (o > 0) { 308 if (o > 0) {
309 Handle<Node> child = n->childNode(o - 1); 309 Handle<Node> child = n->childNode(o - 1);
310 if (child) 310 if (child)
311 return lastPositionInOrAfterNode(child.raw()); 311 return lastPositionInOrAfterNode(child);
312 312
313 // There are two reasons child might be 0: 313 // There are two reasons child might be 0:
314 // 1) The node is node like a text node that is not an element, and th erefore has no children. 314 // 1) The node is node like a text node that is not an element, and th erefore has no children.
315 // Going backward one character at a time is correct. 315 // Going backward one character at a time is correct.
316 // 2) The old offset was a bogus offset like (<br>, 1), and there is n o child. 316 // 2) The old offset was a bogus offset like (<br>, 1), and there is n o child.
317 // Going from 1 to 0 is correct. 317 // Going from 1 to 0 is correct.
318 switch (moveType) { 318 switch (moveType) {
319 case CodePoint: 319 case CodePoint:
320 return createLegacyEditingPosition(n, o - 1); 320 return createLegacyEditingPosition(n, o - 1);
321 case Character: 321 case Character:
(...skipping 16 matching lines...) Expand all
338 338
339 Handle<Node> n = deprecatedNode(); 339 Handle<Node> n = deprecatedNode();
340 if (!n) 340 if (!n)
341 return *this; 341 return *this;
342 342
343 int o = deprecatedEditingOffset(); 343 int o = deprecatedEditingOffset();
344 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. 344 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r.
345 ASSERT(o >= 0); 345 ASSERT(o >= 0);
346 346
347 Handle<Node> child = n->childNode(o); 347 Handle<Node> child = n->childNode(o);
348 if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n.raw()))) { 348 if (child || (!n->hasChildNodes() && o < lastOffsetForEditing(n))) {
349 if (child) 349 if (child)
350 return firstPositionInOrBeforeNode(child.raw()); 350 return firstPositionInOrBeforeNode(child);
351 351
352 // There are two reasons child might be 0: 352 // There are two reasons child might be 0:
353 // 1) The node is node like a text node that is not an element, and th erefore has no children. 353 // 1) The node is node like a text node that is not an element, and th erefore has no children.
354 // Going forward one character at a time is correct. 354 // Going forward one character at a time is correct.
355 // 2) The new offset is a bogus offset like (<br>, 1), and there is no child. 355 // 2) The new offset is a bogus offset like (<br>, 1), and there is no child.
356 // Going from 0 to 1 is correct. 356 // Going from 0 to 1 is correct.
357 return createLegacyEditingPosition(n, (moveType == Character) ? unchecke dNextOffset(n, o) : o + 1); 357 return createLegacyEditingPosition(n, (moveType == Character) ? unchecke dNextOffset(n, o) : o + 1);
358 } 358 }
359 359
360 Handle<ContainerNode> parent = findParent(n); 360 Handle<ContainerNode> parent = findParent(n);
(...skipping 25 matching lines...) Expand all
386 // FIXME: Position before anchor shouldn't be considered as at the first edi ting position for node 386 // FIXME: Position before anchor shouldn't be considered as at the first edi ting position for node
387 // since that position resides outside of the node. 387 // since that position resides outside of the node.
388 switch (m_anchorType) { 388 switch (m_anchorType) {
389 case PositionIsOffsetInAnchor: 389 case PositionIsOffsetInAnchor:
390 return m_offset <= 0; 390 return m_offset <= 0;
391 case PositionIsBeforeChildren: 391 case PositionIsBeforeChildren:
392 case PositionIsBeforeAnchor: 392 case PositionIsBeforeAnchor:
393 return true; 393 return true;
394 case PositionIsAfterChildren: 394 case PositionIsAfterChildren:
395 case PositionIsAfterAnchor: 395 case PositionIsAfterAnchor:
396 return !lastOffsetForEditing(deprecatedNode().handle().raw()); 396 return !lastOffsetForEditing(deprecatedNode());
397 } 397 }
398 ASSERT_NOT_REACHED(); 398 ASSERT_NOT_REACHED();
399 return false; 399 return false;
400 } 400 }
401 401
402 bool Position::atLastEditingPositionForNode() const 402 bool Position::atLastEditingPositionForNode() const
403 { 403 {
404 if (isNull()) 404 if (isNull())
405 return true; 405 return true;
406 // FIXME: Position after anchor shouldn't be considered as at the first edit ing position for node 406 // FIXME: Position after anchor shouldn't be considered as at the first edit ing position for node
407 // since that position resides outside of the node. 407 // since that position resides outside of the node.
408 return m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren || m_offset >= lastOffsetForEditing(deprecatedNode().handle().raw()) ; 408 return m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren || m_offset >= lastOffsetForEditing(deprecatedNode());
409 } 409 }
410 410
411 // A position is considered at editing boundary if one of the following is true: 411 // A position is considered at editing boundary if one of the following is true:
412 // 1. It is the first position in the node and the next visually equivalent posi tion 412 // 1. It is the first position in the node and the next visually equivalent posi tion
413 // is non editable. 413 // is non editable.
414 // 2. It is the last position in the node and the previous visually equivalent p osition 414 // 2. It is the last position in the node and the previous visually equivalent p osition
415 // is non editable. 415 // is non editable.
416 // 3. It is an editable position and both the next and previous visually equival ent 416 // 3. It is an editable position and both the next and previous visually equival ent
417 // positions are both non editable. 417 // positions are both non editable.
418 bool Position::atEditingBoundary() const 418 bool Position::atEditingBoundary() const
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 if (isNull()) 454 if (isNull())
455 return true; 455 return true;
456 return !findParent(deprecatedNode()) && m_offset <= 0; 456 return !findParent(deprecatedNode()) && m_offset <= 0;
457 } 457 }
458 458
459 bool Position::atEndOfTree() const 459 bool Position::atEndOfTree() const
460 { 460 {
461 HandleScope scope; 461 HandleScope scope;
462 if (isNull()) 462 if (isNull())
463 return true; 463 return true;
464 return !findParent(deprecatedNode()) && m_offset >= lastOffsetForEditing(dep recatedNode().handle().raw()); 464 return !findParent(deprecatedNode()) && m_offset >= lastOffsetForEditing(dep recatedNode());
465 } 465 }
466 466
467 int Position::renderedOffset() const 467 int Position::renderedOffset() const
468 { 468 {
469 if (!deprecatedNode()->isTextNode()) 469 if (!deprecatedNode()->isTextNode())
470 return m_offset; 470 return m_offset;
471 471
472 if (!deprecatedNode()->renderer()) 472 if (!deprecatedNode()->renderer())
473 return m_offset; 473 return m_offset;
474 474
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 return false; 555 return false;
556 556
557 if (!node->renderer()->isInline()) 557 if (!node->renderer()->isInline())
558 return true; 558 return true;
559 559
560 // Don't include inline tables. 560 // Don't include inline tables.
561 if (node->hasTagName(tableTag)) 561 if (node->hasTagName(tableTag))
562 return false; 562 return false;
563 563
564 // There is a VisiblePosition inside an empty inline-block container. 564 // There is a VisiblePosition inside an empty inline-block container.
565 return node->renderer()->isReplaced() && canHaveChildrenForEditing(node.raw( )) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild(); 565 return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild();
566 } 566 }
567 567
568 static Result<Node> enclosingVisualBoundary(const Handle<Node>& node) 568 static Result<Node> enclosingVisualBoundary(const Handle<Node>& node)
569 { 569 {
570 Handle<Node> current = node; 570 Handle<Node> current = node;
571 NoHandleScope scope; 571 NoHandleScope scope;
572 while (current && !endsOfNodeAreVisuallyDistinctPositions(current)) { 572 while (current && !endsOfNodeAreVisuallyDistinctPositions(current)) {
573 current = current->parentNode(); 573 current = current->parentNode();
574 } 574 }
575 575
576 return current; 576 return current;
577 } 577 }
578 578
579 // upstream() and downstream() want to return positions that are either in a 579 // upstream() and downstream() want to return positions that are either in a
580 // text node or at just before a non-text node. This method checks for that. 580 // text node or at just before a non-text node. This method checks for that.
581 static bool isStreamer(const PositionIterator& pos) 581 static bool isStreamer(const PositionIterator& pos)
582 { 582 {
583 if (!pos.node()) 583 if (!pos.node())
584 return true; 584 return true;
585 585
586 if (isAtomicNode(pos.node().handle().raw())) 586 if (isAtomicNode(pos.node()))
587 return true; 587 return true;
588 588
589 return pos.atStartOfNode(); 589 return pos.atStartOfNode();
590 } 590 }
591 591
592 // This function and downstream() are used for moving back and forth between vis ually equivalent candidates. 592 // This function and downstream() are used for moving back and forth between vis ually equivalent candidates.
593 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates 593 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates
594 // that map to the VisiblePosition between 'b' and the space. This function wil l return the left candidate 594 // that map to the VisiblePosition between 'b' and the space. This function wil l return the left candidate
595 // and downstream() will return the right one. 595 // and downstream() will return the right one.
596 // Also, upstream() will return [boundary, 0] for any of the positions from [bou ndary, 0] to the first candidate 596 // Also, upstream() will return [boundary, 0] for any of the positions from [bou ndary, 0] to the first candidate
597 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true. 597 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
598 Position Position::upstream(EditingBoundaryCrossingRule rule) const 598 Position Position::upstream(EditingBoundaryCrossingRule rule) const
599 { 599 {
600 HandleScope scope; 600 HandleScope scope;
601 Handle<Node> startNode = deprecatedNode(); 601 Handle<Node> startNode = deprecatedNode();
602 if (!startNode) 602 if (!startNode)
603 return Position(); 603 return Position();
604 604
605 // iterate backward from there, looking for a qualified position 605 // iterate backward from there, looking for a qualified position
606 Handle<Node> boundary = enclosingVisualBoundary(startNode); 606 Handle<Node> boundary = enclosingVisualBoundary(startNode);
607 // FIXME: PositionIterator should respect Before and After positions. 607 // FIXME: PositionIterator should respect Before and After positions.
608 PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? creat eLegacyEditingPosition(m_anchorNode, caretMaxOffset(m_anchorNode.raw())) : *this ; 608 PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? creat eLegacyEditingPosition(m_anchorNode, caretMaxOffset(m_anchorNode)) : *this;
609 PositionIterator currentPos = lastVisible; 609 PositionIterator currentPos = lastVisible;
610 bool startEditable = startNode->rendererIsEditable(); 610 bool startEditable = startNode->rendererIsEditable();
611 Handle<Node> lastNode = startNode; 611 Handle<Node> lastNode = startNode;
612 bool boundaryCrossed = false; 612 bool boundaryCrossed = false;
613 Handle<Node> currentNode; 613 Handle<Node> currentNode;
614 for (; !currentPos.atStart(); currentPos.decrement()) { 614 for (; !currentPos.atStart(); currentPos.decrement()) {
615 HandleScope scope; 615 HandleScope scope;
616 currentNode = currentPos.node(); 616 currentNode = currentPos.node();
617 617
618 // Don't check for an editability change if we haven't moved to a differ ent node, 618 // Don't check for an editability change if we haven't moved to a differ ent node,
(...skipping 27 matching lines...) Expand all
646 // track last visible streamer position 646 // track last visible streamer position
647 if (isStreamer(currentPos)) 647 if (isStreamer(currentPos))
648 lastVisible = currentPos; 648 lastVisible = currentPos;
649 649
650 // Don't move past a position that is visually distinct. We could rely on code above to terminate and 650 // Don't move past a position that is visually distinct. We could rely on code above to terminate and
651 // return lastVisible on the next iteration, but we terminate early to a void doing a nodeIndex() call. 651 // return lastVisible on the next iteration, but we terminate early to a void doing a nodeIndex() call.
652 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.at StartOfNode()) 652 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.at StartOfNode())
653 return lastVisible; 653 return lastVisible;
654 654
655 // Return position after tables and nodes which have content that can be ignored. 655 // Return position after tables and nodes which have content that can be ignored.
656 if (editingIgnoresContent(currentNode.raw()) || isTableElement(currentNo de.raw())) { 656 if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
657 if (currentPos.atEndOfNode()) 657 if (currentPos.atEndOfNode())
658 return positionAfterNode(currentNode); 658 return positionAfterNode(currentNode);
659 continue; 659 continue;
660 } 660 }
661 661
662 // return current position if it is in rendered text 662 // return current position if it is in rendered text
663 if (renderer->isText() && toRenderText(renderer)->firstTextBox()) { 663 if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
664 if (currentNode != startNode) { 664 if (currentNode != startNode) {
665 // This assertion fires in layout tests in the case-transform.ht ml test because 665 // This assertion fires in layout tests in the case-transform.ht ml test because
666 // of a mix-up between offsets in the text in the DOM tree with text in the 666 // of a mix-up between offsets in the text in the DOM tree with text in the
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 Position Position::downstream(EditingBoundaryCrossingRule rule) const 724 Position Position::downstream(EditingBoundaryCrossingRule rule) const
725 { 725 {
726 HandleScope scope; 726 HandleScope scope;
727 Handle<Node> startNode = deprecatedNode(); 727 Handle<Node> startNode = deprecatedNode();
728 if (!startNode) 728 if (!startNode)
729 return Position(); 729 return Position();
730 730
731 // iterate forward from there, looking for a qualified position 731 // iterate forward from there, looking for a qualified position
732 Handle<Node> boundary = enclosingVisualBoundary(startNode); 732 Handle<Node> boundary = enclosingVisualBoundary(startNode);
733 // FIXME: PositionIterator should respect Before and After positions. 733 // FIXME: PositionIterator should respect Before and After positions.
734 PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? creat eLegacyEditingPosition(m_anchorNode, caretMaxOffset(m_anchorNode.raw())) : *this ; 734 PositionIterator lastVisible = m_anchorType == PositionIsAfterAnchor ? creat eLegacyEditingPosition(m_anchorNode, caretMaxOffset(m_anchorNode)) : *this;
735 PositionIterator currentPos = lastVisible; 735 PositionIterator currentPos = lastVisible;
736 bool startEditable = startNode->rendererIsEditable(); 736 bool startEditable = startNode->rendererIsEditable();
737 Handle<Node> lastNode = startNode; 737 Handle<Node> lastNode = startNode;
738 bool boundaryCrossed = false; 738 bool boundaryCrossed = false;
739 Handle<Node> currentNode; 739 Handle<Node> currentNode;
740 for (; !currentPos.atEnd(); currentPos.increment()) { 740 for (; !currentPos.atEnd(); currentPos.increment()) {
741 HandleScope scope; 741 HandleScope scope;
742 currentNode = currentPos.node(); 742 currentNode = currentPos.node();
743 743
744 // Don't check for an editability change if we haven't moved to a differ ent node, 744 // Don't check for an editability change if we haven't moved to a differ ent node,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 if (rule == CanCrossEditingBoundary && boundaryCrossed) { 777 if (rule == CanCrossEditingBoundary && boundaryCrossed) {
778 lastVisible = currentPos; 778 lastVisible = currentPos;
779 break; 779 break;
780 } 780 }
781 781
782 // track last visible streamer position 782 // track last visible streamer position
783 if (isStreamer(currentPos)) 783 if (isStreamer(currentPos))
784 lastVisible = currentPos; 784 lastVisible = currentPos;
785 785
786 // Return position before tables and nodes which have content that can b e ignored. 786 // Return position before tables and nodes which have content that can b e ignored.
787 if (editingIgnoresContent(currentNode.raw()) || isTableElement(currentNo de.raw())) { 787 if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
788 if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset()) 788 if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
789 return createLegacyEditingPosition(currentNode, renderer->caretM inOffset()); 789 return createLegacyEditingPosition(currentNode, renderer->caretM inOffset());
790 continue; 790 continue;
791 } 791 }
792 792
793 // return current position if it is in rendered text 793 // return current position if it is in rendered text
794 if (renderer->isText() && toRenderText(renderer)->firstTextBox()) { 794 if (renderer->isText() && toRenderText(renderer)->firstTextBox()) {
795 if (currentNode != startNode) { 795 if (currentNode != startNode) {
796 ASSERT(currentPos.atStartOfNode()); 796 ASSERT(currentPos.atStartOfNode());
797 return createLegacyEditingPosition(currentNode, renderer->caretM inOffset()); 797 return createLegacyEditingPosition(currentNode, renderer->caretM inOffset());
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 if (renderer->style()->visibility() != VISIBLE) 912 if (renderer->style()->visibility() != VISIBLE)
913 return false; 913 return false;
914 914
915 if (renderer->isBR()) 915 if (renderer->isBR())
916 // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor , but for now we still need to support legacy positions. 916 // FIXME: The condition should be m_anchorType == PositionIsBeforeAnchor , but for now we still need to support legacy positions.
917 return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUser SelectNone(deprecatedNode()->parentNode()); 917 return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUser SelectNone(deprecatedNode()->parentNode());
918 918
919 if (renderer->isText()) 919 if (renderer->isText())
920 return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText(); 920 return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
921 921
922 if (isTableElement(deprecatedNode().handle().raw()) || editingIgnoresContent (deprecatedNode().handle().raw())) 922 if (isTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode ()))
923 return (atFirstEditingPositionForNode() || atLastEditingPositionForNode( )) && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); 923 return (atFirstEditingPositionForNode() || atLastEditingPositionForNode( )) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
924 924
925 if (m_anchorNode->hasTagName(htmlTag)) 925 if (m_anchorNode->hasTagName(htmlTag))
926 return false; 926 return false;
927 927
928 if (renderer->isBlockFlow()) { 928 if (renderer->isBlockFlow()) {
929 if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName (bodyTag)) { 929 if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName (bodyTag)) {
930 if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer )) 930 if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer ))
931 return atFirstEditingPositionForNode() && !Position::nodeIsUserS electNone(deprecatedNode()); 931 return atFirstEditingPositionForNode() && !Position::nodeIsUserS electNone(deprecatedNode());
932 return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSe lectNone(deprecatedNode()) && atEditingBoundary(); 932 return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSe lectNone(deprecatedNode()) && atEditingBoundary();
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 int ignoredCaretOffset; 1040 int ignoredCaretOffset;
1041 InlineBox* b1; 1041 InlineBox* b1;
1042 getInlineBoxAndOffset(DOWNSTREAM, b1, ignoredCaretOffset); 1042 getInlineBoxAndOffset(DOWNSTREAM, b1, ignoredCaretOffset);
1043 InlineBox* b2; 1043 InlineBox* b2;
1044 pos.getInlineBoxAndOffset(DOWNSTREAM, b2, ignoredCaretOffset); 1044 pos.getInlineBoxAndOffset(DOWNSTREAM, b2, ignoredCaretOffset);
1045 1045
1046 LOG(Editing, "renderer: %p [%p]\n", renderer, b1); 1046 LOG(Editing, "renderer: %p [%p]\n", renderer, b1);
1047 LOG(Editing, "thisRenderedOffset: %d\n", thisRenderedOffset); 1047 LOG(Editing, "thisRenderedOffset: %d\n", thisRenderedOffset);
1048 LOG(Editing, "posRenderer: %p [%p]\n", posRenderer, b2); 1048 LOG(Editing, "posRenderer: %p [%p]\n", posRenderer, b2);
1049 LOG(Editing, "posRenderedOffset: %d\n", posRenderedOffset); 1049 LOG(Editing, "posRenderedOffset: %d\n", posRenderedOffset);
1050 LOG(Editing, "node min/max: %d:%d\n", caretMinOffset(deprecatedNod e().handle().raw()), caretMaxOffset(deprecatedNode().handle().raw())); 1050 LOG(Editing, "node min/max: %d:%d\n", caretMinOffset(deprecatedNod e()), caretMaxOffset(deprecatedNode()));
1051 LOG(Editing, "pos node min/max: %d:%d\n", caretMinOffset(pos.deprecate dNode().handle().raw()), caretMaxOffset(pos.deprecatedNode().handle().raw())); 1051 LOG(Editing, "pos node min/max: %d:%d\n", caretMinOffset(pos.deprecate dNode()), caretMaxOffset(pos.deprecatedNode()));
1052 LOG(Editing, "-------------------------------------------------------------- --------\n"); 1052 LOG(Editing, "-------------------------------------------------------------- --------\n");
1053 1053
1054 if (!b1 || !b2) { 1054 if (!b1 || !b2) {
1055 return false; 1055 return false;
1056 } 1056 }
1057 1057
1058 if (b1->root() != b2->root()) { 1058 if (b1->root() != b2->root()) {
1059 return true; 1059 return true;
1060 } 1060 }
1061 1061
1062 if (nextRenderedEditable(deprecatedNode()) == pos.deprecatedNode() 1062 if (nextRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
1063 && thisRenderedOffset == caretMaxOffset(deprecatedNode().handle().raw()) && !posRenderedOffset) { 1063 && thisRenderedOffset == caretMaxOffset(deprecatedNode()) && !posRendere dOffset) {
1064 return false; 1064 return false;
1065 } 1065 }
1066 1066
1067 if (previousRenderedEditable(deprecatedNode()) == pos.deprecatedNode() 1067 if (previousRenderedEditable(deprecatedNode()) == pos.deprecatedNode()
1068 && !thisRenderedOffset && posRenderedOffset == caretMaxOffset(pos.deprec atedNode().handle().raw())) { 1068 && !thisRenderedOffset && posRenderedOffset == caretMaxOffset(pos.deprec atedNode())) {
1069 return false; 1069 return false;
1070 } 1070 }
1071 1071
1072 return true; 1072 return true;
1073 } 1073 }
1074 1074
1075 // This assumes that it starts in editable content. 1075 // This assumes that it starts in editable content.
1076 Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo nCollapsibleWhitespace) const 1076 Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo nCollapsibleWhitespace) const
1077 { 1077 {
1078 ASSERT(isEditablePosition(*this)); 1078 ASSERT(isEditablePosition(*this));
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 return position; 1173 return position;
1174 } 1174 }
1175 1175
1176 void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi rection, InlineBox*& inlineBox, int& caretOffset) const 1176 void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi rection, InlineBox*& inlineBox, int& caretOffset) const
1177 { 1177 {
1178 caretOffset = deprecatedEditingOffset(); 1178 caretOffset = deprecatedEditingOffset();
1179 RenderObject* renderer = deprecatedNode()->renderer(); 1179 RenderObject* renderer = deprecatedNode()->renderer();
1180 1180
1181 if (!renderer->isText()) { 1181 if (!renderer->isText()) {
1182 inlineBox = 0; 1182 inlineBox = 0;
1183 if (canHaveChildrenForEditing(deprecatedNode().handle().raw()) && render er->isBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) { 1183 if (canHaveChildrenForEditing(deprecatedNode()) && renderer->isBlockFlow () && hasRenderedNonAnonymousDescendantsWithHeight(renderer)) {
1184 // Try a visually equivalent position with possibly opposite editabi lity. This helps in case |this| is in 1184 // Try a visually equivalent position with possibly opposite editabi lity. This helps in case |this| is in
1185 // an editable block but surrounded by non-editable positions. It ac ts to negate the logic at the beginning 1185 // an editable block but surrounded by non-editable positions. It ac ts to negate the logic at the beginning
1186 // of RenderObject::createVisiblePosition(). 1186 // of RenderObject::createVisiblePosition().
1187 Position equivalent = downstreamIgnoringEditingBoundaries(*this); 1187 Position equivalent = downstreamIgnoringEditingBoundaries(*this);
1188 if (equivalent == *this) { 1188 if (equivalent == *this) {
1189 equivalent = upstreamIgnoringEditingBoundaries(*this); 1189 equivalent = upstreamIgnoringEditingBoundaries(*this);
1190 if (equivalent == *this || downstreamIgnoringEditingBoundaries(e quivalent) == *this) 1190 if (equivalent == *this || downstreamIgnoringEditingBoundaries(e quivalent) == *this)
1191 return; 1191 return;
1192 } 1192 }
1193 1193
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 pos.showTreeForThis(); 1411 pos.showTreeForThis();
1412 } 1412 }
1413 1413
1414 void showTree(const WebCore::Position* pos) 1414 void showTree(const WebCore::Position* pos)
1415 { 1415 {
1416 if (pos) 1416 if (pos)
1417 pos->showTreeForThis(); 1417 pos->showTreeForThis();
1418 } 1418 }
1419 1419
1420 #endif 1420 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698