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

Side by Side Diff: Source/core/editing/VisiblePosition.cpp

Issue 1314033005: Move canonicalPosition() for VisiblePosition to VisibleUnits.cpp (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-09-01T14:49:27 Created 5 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
« no previous file with comments | « Source/core/editing/VisiblePosition.h ('k') | Source/core/editing/VisiblePositionTest.cpp » ('j') | 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, 2007, 2008, 2009 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv ed.
3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved. 3 * Portions Copyright (c) 2011 Motorola Mobility, Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 456
457 // Return empty position if this position is non-editable, but pos is editab le 457 // Return empty position if this position is non-editable, but pos is editab le
458 // FIXME: Move to the next non-editable region. 458 // FIXME: Move to the next non-editable region.
459 if (!highestRoot) 459 if (!highestRoot)
460 return VisiblePosition(); 460 return VisiblePosition();
461 461
462 // Return the next position after pos that is in the same editable region as this position 462 // Return the next position after pos that is in the same editable region as this position
463 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot); 463 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
464 } 464 }
465 465
466 template <typename PositionType>
467 static PositionType canonicalizeCandidate(const PositionType& candidate)
468 {
469 if (candidate.isNull())
470 return PositionType();
471 ASSERT(isVisuallyEquivalentCandidate(candidate));
472 PositionType upstream = mostBackwardCaretPosition(candidate);
473 if (isVisuallyEquivalentCandidate(upstream))
474 return upstream;
475 return candidate;
476 }
477
478 template <typename PositionType>
479 static PositionType canonicalPosition(const PositionType& passedPosition)
480 {
481 // Sometimes updating selection positions can be extremely expensive and occ ur
482 // frequently. Often calling preventDefault on mousedown events can avoid
483 // doing unnecessary text selection work. http://crbug.com/472258.
484 TRACE_EVENT0("blink", "VisiblePosition::canonicalPosition");
485
486 // The updateLayout call below can do so much that even the position passed
487 // in to us might get changed as a side effect. Specifically, there are code
488 // paths that pass selection endpoints, and updateLayout can change the sele ction.
489 PositionType position = passedPosition;
490
491 // FIXME (9535): Canonicalizing to the leftmost candidate means that if we' re at a line wrap, we will
492 // ask layoutObjects to paint downstream carets for other layoutObjects.
493 // To fix this, we need to either a) add code to all paintCarets to pass the responsibility off to
494 // the appropriate layoutObject for VisiblePosition's like these, or b) cano nicalize to the rightmost candidate
495 // unless the affinity is upstream.
496 if (position.isNull())
497 return PositionType();
498
499 ASSERT(position.document());
500 position.document()->updateLayoutIgnorePendingStylesheets();
501
502 Node* node = position.computeContainerNode();
503
504 PositionType candidate = mostBackwardCaretPosition(position);
505 if (isVisuallyEquivalentCandidate(candidate))
506 return candidate;
507 candidate = mostForwardCaretPosition(position);
508 if (isVisuallyEquivalentCandidate(candidate))
509 return candidate;
510
511 // When neither upstream or downstream gets us to a candidate (upstream/down stream won't leave
512 // blocks or enter new ones), we search forward and backward until we find o ne.
513 PositionType next = canonicalizeCandidate(nextCandidate(position));
514 PositionType prev = canonicalizeCandidate(previousCandidate(position));
515 Node* nextNode = next.anchorNode();
516 Node* prevNode = prev.anchorNode();
517
518 // The new position must be in the same editable element. Enforce that first .
519 // Unless the descent is from a non-editable html element to an editable bod y.
520 if (isHTMLHtmlElement(node) && !node->hasEditableStyle() && node->document() .body() && node->document().body()->hasEditableStyle())
521 return next.isNotNull() ? next : prev;
522
523 Element* editingRoot = editableRootForPosition(position);
524
525 // If the html element is editable, descending into its body will look like a descent
526 // from non-editable to editable content since rootEditableElement() always stops at the body.
527 if (isHTMLHtmlElement(editingRoot) || position.anchorNode()->isDocumentNode( ))
528 return next.isNotNull() ? next : prev;
529
530 bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
531 bool nextIsInSameEditableElement = nextNode && editableRootForPosition(next) == editingRoot;
532 if (prevIsInSameEditableElement && !nextIsInSameEditableElement)
533 return prev;
534
535 if (nextIsInSameEditableElement && !prevIsInSameEditableElement)
536 return next;
537
538 if (!nextIsInSameEditableElement && !prevIsInSameEditableElement)
539 return PositionType();
540
541 // The new position should be in the same block flow element. Favor that.
542 Element* originalBlock = node ? enclosingBlockFlowElement(*node) : 0;
543 bool nextIsOutsideOriginalBlock = !nextNode->isDescendantOf(originalBlock) & & nextNode != originalBlock;
544 bool prevIsOutsideOriginalBlock = !prevNode->isDescendantOf(originalBlock) & & prevNode != originalBlock;
545 if (nextIsOutsideOriginalBlock && !prevIsOutsideOriginalBlock)
546 return prev;
547
548 return next;
549 }
550
551 Position canonicalPositionOf(const Position& position)
552 {
553 return canonicalPosition(position);
554 }
555
556 PositionInComposedTree canonicalPositionOf(const PositionInComposedTree& positio n)
557 {
558 return canonicalPosition(position);
559 }
560
561 template<typename Strategy> 466 template<typename Strategy>
562 static PositionWithAffinityTemplate<Strategy> visiblePositionOfAlgorithm(const P ositionAlgorithm<Strategy>& position, TextAffinity affinity) 467 static PositionWithAffinityTemplate<Strategy> visiblePositionOfAlgorithm(const P ositionAlgorithm<Strategy>& position, TextAffinity affinity)
563 { 468 {
564 const PositionAlgorithm<Strategy> deepPosition = canonicalPosition(position) ; 469 const PositionAlgorithm<Strategy> deepPosition = canonicalPositionOf(positio n);
565 if (deepPosition.isNull()) 470 if (deepPosition.isNull())
566 return PositionWithAffinityTemplate<Strategy>(); 471 return PositionWithAffinityTemplate<Strategy>();
567 if (affinity == TextAffinity::Downstream) 472 if (affinity == TextAffinity::Downstream)
568 return PositionWithAffinityTemplate<Strategy>(deepPosition); 473 return PositionWithAffinityTemplate<Strategy>(deepPosition);
569 474
570 // When not at a line wrap, make sure to end up with 475 // When not at a line wrap, make sure to end up with
571 // |TextAffinity::Downstream| affinity. 476 // |TextAffinity::Downstream| affinity.
572 if (inSameLine(PositionWithAffinityTemplate<Strategy>(deepPosition), Positio nWithAffinityTemplate<Strategy>(deepPosition, TextAffinity::Upstream))) 477 if (inSameLine(PositionWithAffinityTemplate<Strategy>(deepPosition), Positio nWithAffinityTemplate<Strategy>(deepPosition, TextAffinity::Upstream)))
573 return PositionWithAffinityTemplate<Strategy>(deepPosition); 478 return PositionWithAffinityTemplate<Strategy>(deepPosition);
574 return PositionWithAffinityTemplate<Strategy>(deepPosition, TextAffinity::Up stream); 479 return PositionWithAffinityTemplate<Strategy>(deepPosition, TextAffinity::Up stream);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 else 567 else
663 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n"); 568 fprintf(stderr, "Cannot showTree for (nil) VisiblePosition.\n");
664 } 569 }
665 570
666 void showTree(const blink::VisiblePosition& vpos) 571 void showTree(const blink::VisiblePosition& vpos)
667 { 572 {
668 vpos.showTreeForThis(); 573 vpos.showTreeForThis();
669 } 574 }
670 575
671 #endif 576 #endif
OLDNEW
« no previous file with comments | « Source/core/editing/VisiblePosition.h ('k') | Source/core/editing/VisiblePositionTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698