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

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

Issue 1212253002: [CodeHealth] Use PositionStrategy<Strategy> instead of using ::PositionType (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: nit Created 5 years, 6 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
« Source/core/dom/Position.h ('K') | « Source/core/dom/Position.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 continue; 74 continue;
75 if (!node->hasEditableStyle()) 75 if (!node->hasEditableStyle())
76 continue; 76 continue;
77 if ((layoutObject->isBox() && toLayoutBox(layoutObject)->inlineBoxWrappe r()) || (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox())) 77 if ((layoutObject->isBox() && toLayoutBox(layoutObject)->inlineBoxWrappe r()) || (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()))
78 return node; 78 return node;
79 } 79 }
80 return 0; 80 return 0;
81 } 81 }
82 82
83 template <typename Strategy> 83 template <typename Strategy>
84 const TreeScope* PositionAlgorithm<Strategy>::commonAncestorTreeScope(const Posi tionType& a, const PositionType& b) 84 const TreeScope* PositionAlgorithm<Strategy>::commonAncestorTreeScope(const Posi tionAlgorithm<Strategy>& a, const PositionAlgorithm<Strategy>& b)
85 { 85 {
86 if (!a.containerNode() || !b.containerNode()) 86 if (!a.containerNode() || !b.containerNode())
87 return nullptr; 87 return nullptr;
88 return a.containerNode()->treeScope().commonAncestorTreeScope(b.containerNod e()->treeScope()); 88 return a.containerNode()->treeScope().commonAncestorTreeScope(b.containerNod e()->treeScope());
89 } 89 }
90 90
91 template <typename Strategy> 91 template <typename Strategy>
92 PositionAlgorithm<Strategy>::PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anch orNode, LegacyEditingOffset offset) 92 PositionAlgorithm<Strategy>::PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anch orNode, LegacyEditingOffset offset)
93 : m_anchorNode(anchorNode) 93 : m_anchorNode(anchorNode)
94 , m_offset(offset.value()) 94 , m_offset(offset.value())
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 int PositionAlgorithm<Strategy>::offsetForPositionAfterAnchor() const 223 int PositionAlgorithm<Strategy>::offsetForPositionAfterAnchor() const
224 { 224 {
225 ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren); 225 ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren);
226 ASSERT(!m_isLegacyEditingPosition); 226 ASSERT(!m_isLegacyEditingPosition);
227 return Strategy::lastOffsetForEditing(m_anchorNode.get()); 227 return Strategy::lastOffsetForEditing(m_anchorNode.get());
228 } 228 }
229 229
230 // Neighbor-anchored positions are invalid DOM positions, so they need to be 230 // Neighbor-anchored positions are invalid DOM positions, so they need to be
231 // fixed up before handing them off to the Range object. 231 // fixed up before handing them off to the Range object.
232 template <typename Strategy> 232 template <typename Strategy>
233 typename Strategy::PositionType PositionAlgorithm<Strategy>::parentAnchoredEquiv alent() const 233 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::parentAnchored Equivalent() const
yosin_UTC9 2015/06/26 08:39:24 We don't need to have |typename|. Apply this comme
yoichio 2015/06/29 06:00:33 Done.
234 { 234 {
235 if (!m_anchorNode) 235 if (!m_anchorNode)
236 return PositionType(); 236 return PositionAlgorithm<Strategy>();
237 237
238 // FIXME: This should only be necessary for legacy positions, but is also ne eded for positions before and after Tables 238 // FIXME: This should only be necessary for legacy positions, but is also ne eded for positions before and after Tables
239 if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) { 239 if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
240 if (Strategy::parent(*m_anchorNode) && (Strategy::editingIgnoresContent( m_anchorNode.get()) || isRenderedHTMLTableElement(m_anchorNode.get()))) 240 if (Strategy::parent(*m_anchorNode) && (Strategy::editingIgnoresContent( m_anchorNode.get()) || isRenderedHTMLTableElement(m_anchorNode.get())))
241 return inParentBeforeNode(*m_anchorNode); 241 return inParentBeforeNode(*m_anchorNode);
242 return PositionType(m_anchorNode.get(), 0, PositionIsOffsetInAnchor); 242 return PositionAlgorithm<Strategy>(m_anchorNode.get(), 0, PositionIsOffs etInAnchor);
243 } 243 }
244 if (!m_anchorNode->offsetInCharacters() 244 if (!m_anchorNode->offsetInCharacters()
245 && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsA fterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren() ) 245 && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsA fterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren() )
246 && (Strategy::editingIgnoresContent(m_anchorNode.get()) || isRenderedHTM LTableElement(m_anchorNode.get())) 246 && (Strategy::editingIgnoresContent(m_anchorNode.get()) || isRenderedHTM LTableElement(m_anchorNode.get()))
247 && containerNode()) { 247 && containerNode()) {
248 return inParentAfterNode(*m_anchorNode); 248 return inParentAfterNode(*m_anchorNode);
249 } 249 }
250 250
251 return PositionType(containerNode(), computeOffsetInContainerNode(), Positio nIsOffsetInAnchor); 251 return PositionAlgorithm<Strategy>(containerNode(), computeOffsetInContainer Node(), PositionIsOffsetInAnchor);
252 } 252 }
253 253
254 template <typename Strategy> 254 template <typename Strategy>
255 typename Strategy::PositionType PositionAlgorithm<Strategy>::toOffsetInAnchor() const 255 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::toOffsetInAnch or() const
256 { 256 {
257 if (isNull()) 257 if (isNull())
258 return PositionType(); 258 return PositionAlgorithm<Strategy>();
259 259
260 return PositionType(containerNode(), computeOffsetInContainerNode(), Positio nIsOffsetInAnchor); 260 return PositionAlgorithm<Strategy>(containerNode(), computeOffsetInContainer Node(), PositionIsOffsetInAnchor);
261 } 261 }
262 262
263 template <typename Strategy> 263 template <typename Strategy>
264 Node* PositionAlgorithm<Strategy>::computeNodeBeforePosition() const 264 Node* PositionAlgorithm<Strategy>::computeNodeBeforePosition() const
265 { 265 {
266 if (!m_anchorNode) 266 if (!m_anchorNode)
267 return 0; 267 return 0;
268 switch (anchorType()) { 268 switch (anchorType()) {
269 case PositionIsBeforeChildren: 269 case PositionIsBeforeChildren:
270 return 0; 270 return 0;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 if (m_anchorType != PositionIsOffsetInAnchor) 339 if (m_anchorType != PositionIsOffsetInAnchor)
340 return toOffsetInAnchor().nodeAsRangePastLastNode(); 340 return toOffsetInAnchor().nodeAsRangePastLastNode();
341 if (m_anchorNode->offsetInCharacters()) 341 if (m_anchorNode->offsetInCharacters())
342 return Strategy::nextSkippingChildren(*m_anchorNode); 342 return Strategy::nextSkippingChildren(*m_anchorNode);
343 if (Node* child = Strategy::childAt(*m_anchorNode, m_offset)) 343 if (Node* child = Strategy::childAt(*m_anchorNode, m_offset))
344 return child; 344 return child;
345 return Strategy::nextSkippingChildren(*m_anchorNode); 345 return Strategy::nextSkippingChildren(*m_anchorNode);
346 } 346 }
347 347
348 template <typename Strategy> 348 template <typename Strategy>
349 Node* PositionAlgorithm<Strategy>::commonAncestorContainer(const PositionType& o ther) const 349 Node* PositionAlgorithm<Strategy>::commonAncestorContainer(const PositionAlgorit hm<Strategy>& other) const
350 { 350 {
351 return Strategy::commonAncestor(*containerNode(), *other.containerNode()); 351 return Strategy::commonAncestor(*containerNode(), *other.containerNode());
352 } 352 }
353 353
354 template <typename Strategy> 354 template <typename Strategy>
355 typename PositionAlgorithm<Strategy>::AnchorType PositionAlgorithm<Strategy>::an chorTypeForLegacyEditingPosition(Node* anchorNode, int offset) 355 typename PositionAlgorithm<Strategy>::AnchorType PositionAlgorithm<Strategy>::an chorTypeForLegacyEditingPosition(Node* anchorNode, int offset)
356 { 356 {
357 if (anchorNode && Strategy::editingIgnoresContent(anchorNode)) { 357 if (anchorNode && Strategy::editingIgnoresContent(anchorNode)) {
358 if (offset == 0) 358 if (offset == 0)
359 return PositionIsBeforeAnchor; 359 return PositionIsBeforeAnchor;
(...skipping 28 matching lines...) Expand all
388 ASSERT(positionB.isNotNull()); 388 ASSERT(positionB.isNotNull());
389 389
390 Node* containerA = positionA.containerNode(); 390 Node* containerA = positionA.containerNode();
391 Node* containerB = positionB.containerNode(); 391 Node* containerB = positionB.containerNode();
392 int offsetA = positionA.computeOffsetInContainerNode(); 392 int offsetA = positionA.computeOffsetInContainerNode();
393 int offsetB = positionB.computeOffsetInContainerNode(); 393 int offsetB = positionB.computeOffsetInContainerNode();
394 return EditingInComposedTreeStrategy::comparePositions(containerA, offsetA, containerB, offsetB); 394 return EditingInComposedTreeStrategy::comparePositions(containerA, offsetA, containerB, offsetB);
395 } 395 }
396 396
397 template <typename Strategy> 397 template <typename Strategy>
398 int PositionAlgorithm<Strategy>::compareTo(const PositionType& other) const 398 int PositionAlgorithm<Strategy>::compareTo(const PositionAlgorithm<Strategy>& ot her) const
399 { 399 {
400 return comparePositions(*this, other); 400 return comparePositions(*this, other);
401 } 401 }
402 402
403 template <typename Strategy> 403 template <typename Strategy>
404 typename Strategy::PositionType PositionAlgorithm<Strategy>::previous(PositionMo veType moveType) const 404 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::previous(Posit ionMoveType moveType) const
405 { 405 {
406 Node* node = deprecatedNode(); 406 Node* node = deprecatedNode();
407 if (!node) 407 if (!node)
408 return PositionType(*this); 408 return PositionAlgorithm<Strategy>(*this);
409 409
410 int offset = deprecatedEditingOffset(); 410 int offset = deprecatedEditingOffset();
411 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. 411 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r.
412 ASSERT(offset >= 0); 412 ASSERT(offset >= 0);
413 413
414 if (offset > 0) { 414 if (offset > 0) {
415 if (Node* child = Strategy::childAt(*node, offset - 1)) 415 if (Node* child = Strategy::childAt(*node, offset - 1))
416 return lastPositionInOrAfterNode(child); 416 return lastPositionInOrAfterNode(child);
417 417
418 // There are two reasons child might be 0: 418 // There are two reasons child might be 0:
419 // 1) The node is node like a text node that is not an element, and th erefore has no children. 419 // 1) The node is node like a text node that is not an element, and th erefore has no children.
420 // Going backward one character at a time is correct. 420 // Going backward one character at a time is correct.
421 // 2) The old offset was a bogus offset like (<br>, 1), and there is n o child. 421 // 2) The old offset was a bogus offset like (<br>, 1), and there is n o child.
422 // Going from 1 to 0 is correct. 422 // Going from 1 to 0 is correct.
423 switch (moveType) { 423 switch (moveType) {
424 case CodePoint: 424 case CodePoint:
425 return createLegacyEditingPosition(node, offset - 1); 425 return createLegacyEditingPosition(node, offset - 1);
426 case Character: 426 case Character:
427 return createLegacyEditingPosition(node, uncheckedPreviousOffset(nod e, offset)); 427 return createLegacyEditingPosition(node, uncheckedPreviousOffset(nod e, offset));
428 case BackwardDeletion: 428 case BackwardDeletion:
429 return createLegacyEditingPosition(node, uncheckedPreviousOffsetForB ackwardDeletion(node, offset)); 429 return createLegacyEditingPosition(node, uncheckedPreviousOffsetForB ackwardDeletion(node, offset));
430 } 430 }
431 } 431 }
432 432
433 if (ContainerNode* parent = Strategy::parent(*node)) 433 if (ContainerNode* parent = Strategy::parent(*node))
434 return createLegacyEditingPosition(parent, node->nodeIndex()); 434 return createLegacyEditingPosition(parent, node->nodeIndex());
435 return PositionType(*this); 435 return PositionAlgorithm<Strategy>(*this);
436 } 436 }
437 437
438 template <typename Strategy> 438 template <typename Strategy>
439 typename Strategy::PositionType PositionAlgorithm<Strategy>::next(PositionMoveTy pe moveType) const 439 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::next(PositionM oveType moveType) const
440 { 440 {
441 ASSERT(moveType != BackwardDeletion); 441 ASSERT(moveType != BackwardDeletion);
442 442
443 Node* node = deprecatedNode(); 443 Node* node = deprecatedNode();
444 if (!node) 444 if (!node)
445 return PositionType(*this); 445 return PositionAlgorithm<Strategy>(*this);
446 446
447 int offset = deprecatedEditingOffset(); 447 int offset = deprecatedEditingOffset();
448 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. 448 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r.
449 ASSERT(offset >= 0); 449 ASSERT(offset >= 0);
450 450
451 if (Node* child = Strategy::childAt(*node, offset)) 451 if (Node* child = Strategy::childAt(*node, offset))
452 return firstPositionInOrBeforeNode(child); 452 return firstPositionInOrBeforeNode(child);
453 453
454 if (!Strategy::hasChildren(*node) && offset < lastOffsetForEditing(node)) { 454 if (!Strategy::hasChildren(*node) && offset < lastOffsetForEditing(node)) {
455 // There are two reasons child might be 0: 455 // There are two reasons child might be 0:
456 // 1) The node is node like a text node that is not an element, and th erefore has no children. 456 // 1) The node is node like a text node that is not an element, and th erefore has no children.
457 // Going forward one character at a time is correct. 457 // Going forward one character at a time is correct.
458 // 2) The new offset is a bogus offset like (<br>, 1), and there is no child. 458 // 2) The new offset is a bogus offset like (<br>, 1), and there is no child.
459 // Going from 0 to 1 is correct. 459 // Going from 0 to 1 is correct.
460 return createLegacyEditingPosition(node, (moveType == Character) ? unche ckedNextOffset(node, offset) : offset + 1); 460 return createLegacyEditingPosition(node, (moveType == Character) ? unche ckedNextOffset(node, offset) : offset + 1);
461 } 461 }
462 462
463 if (ContainerNode* parent = Strategy::parent(*node)) 463 if (ContainerNode* parent = Strategy::parent(*node))
464 return createLegacyEditingPosition(parent, node->nodeIndex() + 1); 464 return createLegacyEditingPosition(parent, node->nodeIndex() + 1);
465 return PositionType(*this); 465 return PositionAlgorithm<Strategy>(*this);
466 } 466 }
467 467
468 template <typename Strategy> 468 template <typename Strategy>
469 int PositionAlgorithm<Strategy>::uncheckedPreviousOffset(const Node* n, int curr ent) 469 int PositionAlgorithm<Strategy>::uncheckedPreviousOffset(const Node* n, int curr ent)
470 { 470 {
471 return n->layoutObject() ? n->layoutObject()->previousOffset(current) : curr ent - 1; 471 return n->layoutObject() ? n->layoutObject()->previousOffset(current) : curr ent - 1;
472 } 472 }
473 473
474 template <typename Strategy> 474 template <typename Strategy>
475 int PositionAlgorithm<Strategy>::uncheckedPreviousOffsetForBackwardDeletion(cons t Node* n, int current) 475 int PositionAlgorithm<Strategy>::uncheckedPreviousOffsetForBackwardDeletion(cons t Node* n, int current)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 // A position is considered at editing boundary if one of the following is true: 517 // A position is considered at editing boundary if one of the following is true:
518 // 1. It is the first position in the node and the next visually equivalent posi tion 518 // 1. It is the first position in the node and the next visually equivalent posi tion
519 // is non editable. 519 // is non editable.
520 // 2. It is the last position in the node and the previous visually equivalent p osition 520 // 2. It is the last position in the node and the previous visually equivalent p osition
521 // is non editable. 521 // is non editable.
522 // 3. It is an editable position and both the next and previous visually equival ent 522 // 3. It is an editable position and both the next and previous visually equival ent
523 // positions are both non editable. 523 // positions are both non editable.
524 template <typename Strategy> 524 template <typename Strategy>
525 bool PositionAlgorithm<Strategy>::atEditingBoundary() const 525 bool PositionAlgorithm<Strategy>::atEditingBoundary() const
526 { 526 {
527 PositionType nextPosition = downstream(CanCrossEditingBoundary); 527 PositionAlgorithm<Strategy> nextPosition = downstream(CanCrossEditingBoundar y);
528 if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosi tion.deprecatedNode()->hasEditableStyle()) 528 if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosi tion.deprecatedNode()->hasEditableStyle())
529 return true; 529 return true;
530 530
531 PositionType prevPosition = upstream(CanCrossEditingBoundary); 531 PositionAlgorithm<Strategy> prevPosition = upstream(CanCrossEditingBoundary) ;
532 if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosit ion.deprecatedNode()->hasEditableStyle()) 532 if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosit ion.deprecatedNode()->hasEditableStyle())
533 return true; 533 return true;
534 534
535 return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditab leStyle() 535 return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditab leStyle()
536 && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditab leStyle(); 536 && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditab leStyle();
537 } 537 }
538 538
539 template <typename Strategy> 539 template <typename Strategy>
540 static ContainerNode* nonShadowBoundaryParentNode(Node* node) 540 static ContainerNode* nonShadowBoundaryParentNode(Node* node)
541 { 541 {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 return pos.atStartOfNode(); 650 return pos.atStartOfNode();
651 } 651 }
652 652
653 // This function and downstream() are used for moving back and forth between vis ually equivalent candidates. 653 // This function and downstream() are used for moving back and forth between vis ually equivalent candidates.
654 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates 654 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates
655 // that map to the VisiblePosition between 'b' and the space. This function wil l return the left candidate 655 // that map to the VisiblePosition between 'b' and the space. This function wil l return the left candidate
656 // and downstream() will return the right one. 656 // and downstream() will return the right one.
657 // Also, upstream() will return [boundary, 0] for any of the positions from [bou ndary, 0] to the first candidate 657 // Also, upstream() will return [boundary, 0] for any of the positions from [bou ndary, 0] to the first candidate
658 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true. 658 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true.
659 template <typename Strategy> 659 template <typename Strategy>
660 typename Strategy::PositionType PositionAlgorithm<Strategy>::upstream(EditingBou ndaryCrossingRule rule) const 660 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::upstream(Editi ngBoundaryCrossingRule rule) const
661 { 661 {
662 Node* startNode = deprecatedNode(); 662 Node* startNode = deprecatedNode();
663 if (!startNode) 663 if (!startNode)
664 return PositionType(); 664 return PositionAlgorithm<Strategy>();
665 665
666 // iterate backward from there, looking for a qualified position 666 // iterate backward from there, looking for a qualified position
667 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); 667 Node* boundary = enclosingVisualBoundary<Strategy>(startNode);
668 // FIXME: PositionIterator should respect Before and After positions. 668 // FIXME: PositionIterator should respect Before and After positions.
669 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionType(*this)); 669 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionAlgorithm<Strategy>(*this));
670 typename Strategy::PositionIteratorType currentPos = lastVisible; 670 typename Strategy::PositionIteratorType currentPos = lastVisible;
671 bool startEditable = startNode->hasEditableStyle(); 671 bool startEditable = startNode->hasEditableStyle();
672 Node* lastNode = startNode; 672 Node* lastNode = startNode;
673 bool boundaryCrossed = false; 673 bool boundaryCrossed = false;
674 for (; !currentPos.atStart(); currentPos.decrement()) { 674 for (; !currentPos.atStart(); currentPos.decrement()) {
675 Node* currentNode = currentPos.node(); 675 Node* currentNode = currentPos.node();
676 // Don't check for an editability change if we haven't moved to a differ ent node, 676 // Don't check for an editability change if we haven't moved to a differ ent node,
677 // to avoid the expense of computing hasEditableStyle(). 677 // to avoid the expense of computing hasEditableStyle().
678 if (currentNode != lastNode) { 678 if (currentNode != lastNode) {
679 // Don't change editability. 679 // Don't change editability.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 772 }
773 773
774 // This function and upstream() are used for moving back and forth between visua lly equivalent candidates. 774 // This function and upstream() are used for moving back and forth between visua lly equivalent candidates.
775 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates 775 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates
776 // that map to the VisiblePosition between 'b' and the space. This function wil l return the right candidate 776 // that map to the VisiblePosition between 'b' and the space. This function wil l return the right candidate
777 // and upstream() will return the left one. 777 // and upstream() will return the left one.
778 // Also, downstream() will return the last position in the last atomic node in b oundary for all of the positions 778 // Also, downstream() will return the last position in the last atomic node in b oundary for all of the positions
779 // in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPosi tions(boundary). 779 // in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPosi tions(boundary).
780 // FIXME: This function should never be called when the line box tree is dirty. See https://bugs.webkit.org/show_bug.cgi?id=97264 780 // FIXME: This function should never be called when the line box tree is dirty. See https://bugs.webkit.org/show_bug.cgi?id=97264
781 template <typename Strategy> 781 template <typename Strategy>
782 typename Strategy::PositionType PositionAlgorithm<Strategy>::downstream(EditingB oundaryCrossingRule rule) const 782 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::downstream(Edi tingBoundaryCrossingRule rule) const
783 { 783 {
784 Node* startNode = deprecatedNode(); 784 Node* startNode = deprecatedNode();
785 if (!startNode) 785 if (!startNode)
786 return PositionType(); 786 return PositionAlgorithm<Strategy>();
787 787
788 // iterate forward from there, looking for a qualified position 788 // iterate forward from there, looking for a qualified position
789 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); 789 Node* boundary = enclosingVisualBoundary<Strategy>(startNode);
790 // FIXME: PositionIterator should respect Before and After positions. 790 // FIXME: PositionIterator should respect Before and After positions.
791 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionType(*this)); 791 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionAlgorithm<Strategy>(*this));
792 typename Strategy::PositionIteratorType currentPos = lastVisible; 792 typename Strategy::PositionIteratorType currentPos = lastVisible;
793 bool startEditable = startNode->hasEditableStyle(); 793 bool startEditable = startNode->hasEditableStyle();
794 Node* lastNode = startNode; 794 Node* lastNode = startNode;
795 bool boundaryCrossed = false; 795 bool boundaryCrossed = false;
796 for (; !currentPos.atEnd(); currentPos.increment()) { 796 for (; !currentPos.atEnd(); currentPos.increment()) {
797 Node* currentNode = currentPos.node(); 797 Node* currentNode = currentPos.node();
798 // Don't check for an editability change if we haven't moved to a differ ent node, 798 // Don't check for an editability change if we haven't moved to a differ ent node,
799 // to avoid the expense of computing hasEditableStyle(). 799 // to avoid the expense of computing hasEditableStyle().
800 if (currentNode != lastNode) { 800 if (currentNode != lastNode) {
801 // Don't change editability. 801 // Don't change editability.
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 return false; 1043 return false;
1044 } 1044 }
1045 if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast <int>(box->start() + box->len())) 1045 if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast <int>(box->start() + box->len()))
1046 return true; 1046 return true;
1047 } 1047 }
1048 1048
1049 return false; 1049 return false;
1050 } 1050 }
1051 1051
1052 template <typename Strategy> 1052 template <typename Strategy>
1053 bool PositionAlgorithm<Strategy>::rendersInDifferentPosition(const PositionType &pos) const 1053 bool PositionAlgorithm<Strategy>::rendersInDifferentPosition(const PositionAlgor ithm<Strategy> &pos) const
1054 { 1054 {
1055 if (isNull() || pos.isNull()) 1055 if (isNull() || pos.isNull())
1056 return false; 1056 return false;
1057 1057
1058 LayoutObject* layoutObject = deprecatedNode()->layoutObject(); 1058 LayoutObject* layoutObject = deprecatedNode()->layoutObject();
1059 if (!layoutObject) 1059 if (!layoutObject)
1060 return false; 1060 return false;
1061 1061
1062 LayoutObject* posLayoutObject = pos.deprecatedNode()->layoutObject(); 1062 LayoutObject* posLayoutObject = pos.deprecatedNode()->layoutObject();
1063 if (!posLayoutObject) 1063 if (!posLayoutObject)
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 minOffset = caretMinOffset; 1171 minOffset = caretMinOffset;
1172 } 1172 }
1173 } 1173 }
1174 if (match) 1174 if (match)
1175 return match; 1175 return match;
1176 } 1176 }
1177 } 1177 }
1178 return 0; 1178 return 0;
1179 } 1179 }
1180 1180
1181 template <typename PositionType> 1181 template <typename Strategy>
1182 PositionType downstreamIgnoringEditingBoundaries(PositionType position) 1182 PositionAlgorithm<Strategy> downstreamIgnoringEditingBoundaries(PositionAlgorith m<Strategy> position)
1183 { 1183 {
1184 PositionType lastPosition; 1184 PositionAlgorithm<Strategy> lastPosition;
1185 while (position != lastPosition) { 1185 while (position != lastPosition) {
1186 lastPosition = position; 1186 lastPosition = position;
1187 position = position.downstream(CanCrossEditingBoundary); 1187 position = position.downstream(CanCrossEditingBoundary);
1188 } 1188 }
1189 return position; 1189 return position;
1190 } 1190 }
1191 1191
1192 template <typename PositionType> 1192 template <typename Strategy>
1193 PositionType upstreamIgnoringEditingBoundaries(PositionType position) 1193 PositionAlgorithm<Strategy> upstreamIgnoringEditingBoundaries(PositionAlgorithm< Strategy> position)
1194 { 1194 {
1195 PositionType lastPosition; 1195 PositionAlgorithm<Strategy> lastPosition;
1196 while (position != lastPosition) { 1196 while (position != lastPosition) {
1197 lastPosition = position; 1197 lastPosition = position;
1198 position = position.upstream(CanCrossEditingBoundary); 1198 position = position.upstream(CanCrossEditingBoundary);
1199 } 1199 }
1200 return position; 1200 return position;
1201 } 1201 }
1202 1202
1203 template <typename Strategy> 1203 template <typename Strategy>
1204 void PositionAlgorithm<Strategy>::getInlineBoxAndOffset(EAffinity affinity, Text Direction primaryDirection, InlineBox*& inlineBox, int& caretOffset) const 1204 void PositionAlgorithm<Strategy>::getInlineBoxAndOffset(EAffinity affinity, Text Direction primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
1205 { 1205 {
1206 caretOffset = deprecatedEditingOffset(); 1206 caretOffset = deprecatedEditingOffset();
1207 LayoutObject* layoutObject = deprecatedNode()->layoutObject(); 1207 LayoutObject* layoutObject = deprecatedNode()->layoutObject();
1208 1208
1209 if (!layoutObject->isText()) { 1209 if (!layoutObject->isText()) {
1210 inlineBox = 0; 1210 inlineBox = 0;
1211 if (canHaveChildrenForEditing(deprecatedNode()) && layoutObject->isLayou tBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { 1211 if (canHaveChildrenForEditing(deprecatedNode()) && layoutObject->isLayou tBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) {
1212 // Try a visually equivalent position with possibly opposite editabi lity. This helps in case |this| is in 1212 // Try a visually equivalent position with possibly opposite editabi lity. This helps in case |this| is in
1213 // an editable block but surrounded by non-editable positions. It ac ts to negate the logic at the beginning 1213 // an editable block but surrounded by non-editable positions. It ac ts to negate the logic at the beginning
1214 // of LayoutObject::createVisiblePosition(). 1214 // of LayoutObject::createVisiblePosition().
1215 PositionType thisPosition = PositionType(*this); 1215 PositionAlgorithm<Strategy> thisPosition = PositionAlgorithm<Strateg y>(*this);
1216 PositionType equivalent = downstreamIgnoringEditingBoundaries<typena me Strategy::PositionType>(thisPosition); 1216 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo undaries(thisPosition);
1217 if (equivalent == thisPosition) { 1217 if (equivalent == thisPosition) {
1218 equivalent = upstreamIgnoringEditingBoundaries(thisPosition); 1218 equivalent = upstreamIgnoringEditingBoundaries(thisPosition);
1219 if (equivalent == thisPosition || downstreamIgnoringEditingBound aries<typename Strategy::PositionType>(equivalent) == thisPosition) 1219 if (equivalent == thisPosition || downstreamIgnoringEditingBound aries(equivalent) == thisPosition)
1220 return; 1220 return;
1221 } 1221 }
1222 1222
1223 equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineB ox, caretOffset); 1223 equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineB ox, caretOffset);
1224 return; 1224 return;
1225 } 1225 }
1226 if (layoutObject->isBox()) { 1226 if (layoutObject->isBox()) {
1227 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper(); 1227 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper();
1228 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care tOffset < inlineBox->caretMaxOffset())) 1228 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care tOffset < inlineBox->caretMaxOffset()))
1229 return; 1229 return;
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 1545
1546 void showTree(const blink::Position* pos) 1546 void showTree(const blink::Position* pos)
1547 { 1547 {
1548 if (pos) 1548 if (pos)
1549 pos->showTreeForThis(); 1549 pos->showTreeForThis();
1550 else 1550 else
1551 fprintf(stderr, "Cannot showTree for (nil)\n"); 1551 fprintf(stderr, "Cannot showTree for (nil)\n");
1552 } 1552 }
1553 1553
1554 #endif 1554 #endif
OLDNEW
« Source/core/dom/Position.h ('K') | « Source/core/dom/Position.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698