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

Side by Side Diff: third_party/WebKit/Source/core/editing/VisibleUnits.cpp

Issue 2399663003: Reflow comments in //third_party/WebKit/Source/core/editing (Closed)
Patch Set: Created 4 years, 2 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
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
3 * reserved.
3 * 4 *
4 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
6 * are met: 7 * are met:
7 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
12 * 13 *
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 : m_rootInlineBox(0) {} 410 : m_rootInlineBox(0) {}
410 411
411 const InlineTextBox* CachedLogicallyOrderedLeafBoxes::previousTextBox( 412 const InlineTextBox* CachedLogicallyOrderedLeafBoxes::previousTextBox(
412 const RootInlineBox* root, 413 const RootInlineBox* root,
413 const InlineTextBox* box) { 414 const InlineTextBox* box) {
414 if (!root) 415 if (!root)
415 return 0; 416 return 0;
416 417
417 collectBoxes(root); 418 collectBoxes(root);
418 419
419 // If box is null, root is box's previous RootInlineBox, and previousBox is th e last logical box in root. 420 // If box is null, root is box's previous RootInlineBox, and previousBox is
421 // the last logical box in root.
420 int boxIndex = m_leafBoxes.size() - 1; 422 int boxIndex = m_leafBoxes.size() - 1;
421 if (box) 423 if (box)
422 boxIndex = boxIndexInLeaves(box) - 1; 424 boxIndex = boxIndexInLeaves(box) - 1;
423 425
424 for (int i = boxIndex; i >= 0; --i) { 426 for (int i = boxIndex; i >= 0; --i) {
425 if (m_leafBoxes[i]->isInlineTextBox()) 427 if (m_leafBoxes[i]->isInlineTextBox())
426 return toInlineTextBox(m_leafBoxes[i]); 428 return toInlineTextBox(m_leafBoxes[i]);
427 } 429 }
428 430
429 return 0; 431 return 0;
430 } 432 }
431 433
432 const InlineTextBox* CachedLogicallyOrderedLeafBoxes::nextTextBox( 434 const InlineTextBox* CachedLogicallyOrderedLeafBoxes::nextTextBox(
433 const RootInlineBox* root, 435 const RootInlineBox* root,
434 const InlineTextBox* box) { 436 const InlineTextBox* box) {
435 if (!root) 437 if (!root)
436 return 0; 438 return 0;
437 439
438 collectBoxes(root); 440 collectBoxes(root);
439 441
440 // If box is null, root is box's next RootInlineBox, and nextBox is the first logical box in root. 442 // If box is null, root is box's next RootInlineBox, and nextBox is the first
441 // Otherwise, root is box's RootInlineBox, and nextBox is the next logical box in the same line. 443 // logical box in root. Otherwise, root is box's RootInlineBox, and nextBox is
444 // the next logical box in the same line.
442 size_t nextBoxIndex = 0; 445 size_t nextBoxIndex = 0;
443 if (box) 446 if (box)
444 nextBoxIndex = boxIndexInLeaves(box) + 1; 447 nextBoxIndex = boxIndexInLeaves(box) + 1;
445 448
446 for (size_t i = nextBoxIndex; i < m_leafBoxes.size(); ++i) { 449 for (size_t i = nextBoxIndex; i < m_leafBoxes.size(); ++i) {
447 if (m_leafBoxes[i]->isInlineTextBox()) 450 if (m_leafBoxes[i]->isInlineTextBox())
448 return toInlineTextBox(m_leafBoxes[i]); 451 return toInlineTextBox(m_leafBoxes[i]);
449 } 452 }
450 453
451 return 0; 454 return 0;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 } 620 }
618 621
619 static bool isLogicalStartOfWord(TextBreakIterator* iter, 622 static bool isLogicalStartOfWord(TextBreakIterator* iter,
620 int position, 623 int position,
621 bool hardLineBreak) { 624 bool hardLineBreak) {
622 bool boundary = hardLineBreak ? true : iter->isBoundary(position); 625 bool boundary = hardLineBreak ? true : iter->isBoundary(position);
623 if (!boundary) 626 if (!boundary)
624 return false; 627 return false;
625 628
626 iter->following(position); 629 iter->following(position);
627 // isWordTextBreak returns true after moving across a word and false after mov ing across a punctuation/space. 630 // isWordTextBreak returns true after moving across a word and false after
631 // moving across a punctuation/space.
628 return isWordTextBreak(iter); 632 return isWordTextBreak(iter);
629 } 633 }
630 634
631 static bool islogicalEndOfWord(TextBreakIterator* iter, 635 static bool islogicalEndOfWord(TextBreakIterator* iter,
632 int position, 636 int position,
633 bool hardLineBreak) { 637 bool hardLineBreak) {
634 bool boundary = iter->isBoundary(position); 638 bool boundary = iter->isBoundary(position);
635 return (hardLineBreak || boundary) && isWordTextBreak(iter); 639 return (hardLineBreak || boundary) && isWordTextBreak(iter);
636 } 640 }
637 641
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 return PositionWithAffinityTemplate<Strategy>(); 1181 return PositionWithAffinityTemplate<Strategy>();
1178 } 1182 }
1179 1183
1180 Node* startNode; 1184 Node* startNode;
1181 InlineBox* startBox; 1185 InlineBox* startBox;
1182 if (mode == UseLogicalOrdering) { 1186 if (mode == UseLogicalOrdering) {
1183 startNode = rootBox->getLogicalStartBoxWithNode(startBox); 1187 startNode = rootBox->getLogicalStartBoxWithNode(startBox);
1184 if (!startNode) 1188 if (!startNode)
1185 return PositionWithAffinityTemplate<Strategy>(); 1189 return PositionWithAffinityTemplate<Strategy>();
1186 } else { 1190 } else {
1187 // Generated content (e.g. list markers and CSS :before and :after pseudoele ments) have no corresponding DOM element, 1191 // Generated content (e.g. list markers and CSS :before and :after
1188 // and so cannot be represented by a VisiblePosition. Use whatever follows i nstead. 1192 // pseudoelements) have no corresponding DOM element, and so cannot be
1193 // represented by a VisiblePosition. Use whatever follows instead.
1189 startBox = rootBox->firstLeafChild(); 1194 startBox = rootBox->firstLeafChild();
1190 while (true) { 1195 while (true) {
1191 if (!startBox) 1196 if (!startBox)
1192 return PositionWithAffinityTemplate<Strategy>(); 1197 return PositionWithAffinityTemplate<Strategy>();
1193 1198
1194 startNode = startBox->getLineLayoutItem().nonPseudoNode(); 1199 startNode = startBox->getLineLayoutItem().nonPseudoNode();
1195 if (startNode) 1200 if (startNode)
1196 break; 1201 break;
1197 1202
1198 startBox = startBox->nextLeafChild(); 1203 startBox = startBox->nextLeafChild();
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint); 1572 absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
1568 LineLayoutItem lineLayoutItem = 1573 LineLayoutItem lineLayoutItem =
1569 root->closestLeafChildForPoint(pointInLine, isEditablePosition(p)) 1574 root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))
1570 ->getLineLayoutItem(); 1575 ->getLineLayoutItem();
1571 Node* node = lineLayoutItem.node(); 1576 Node* node = lineLayoutItem.node();
1572 if (node && editingIgnoresContent(node)) 1577 if (node && editingIgnoresContent(node))
1573 return VisiblePosition::inParentBeforeNode(*node); 1578 return VisiblePosition::inParentBeforeNode(*node);
1574 return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine)); 1579 return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine));
1575 } 1580 }
1576 1581
1577 // Could not find a previous line. This means we must already be on the first line. 1582 // Could not find a previous line. This means we must already be on the first
1578 // Move to the start of the content in this block, which effectively moves us 1583 // line. Move to the start of the content in this block, which effectively
1579 // to the start of the line we're on. 1584 // moves us to the start of the line we're on.
1580 Element* rootElement = hasEditableStyle(*node, editableType) 1585 Element* rootElement = hasEditableStyle(*node, editableType)
1581 ? rootEditableElement(*node, editableType) 1586 ? rootEditableElement(*node, editableType)
1582 : node->document().documentElement(); 1587 : node->document().documentElement();
1583 if (!rootElement) 1588 if (!rootElement)
1584 return VisiblePosition(); 1589 return VisiblePosition();
1585 return VisiblePosition::firstPositionInNode(rootElement); 1590 return VisiblePosition::firstPositionInNode(rootElement);
1586 } 1591 }
1587 1592
1588 VisiblePosition nextLinePosition(const VisiblePosition& visiblePosition, 1593 VisiblePosition nextLinePosition(const VisiblePosition& visiblePosition,
1589 LayoutUnit lineDirectionPoint, 1594 LayoutUnit lineDirectionPoint,
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 VisiblePositionInFlatTree endOfSentence(const VisiblePositionInFlatTree& c) { 1705 VisiblePositionInFlatTree endOfSentence(const VisiblePositionInFlatTree& c) {
1701 return endOfSentenceAlgorithm<EditingInFlatTreeStrategy>(c); 1706 return endOfSentenceAlgorithm<EditingInFlatTreeStrategy>(c);
1702 } 1707 }
1703 1708
1704 static unsigned previousSentencePositionBoundary( 1709 static unsigned previousSentencePositionBoundary(
1705 const UChar* characters, 1710 const UChar* characters,
1706 unsigned length, 1711 unsigned length,
1707 unsigned, 1712 unsigned,
1708 BoundarySearchContextAvailability, 1713 BoundarySearchContextAvailability,
1709 bool&) { 1714 bool&) {
1710 // FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's n ot right. 1715 // FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's
1716 // not right.
1711 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); 1717 TextBreakIterator* iterator = sentenceBreakIterator(characters, length);
1712 // FIXME: The following function can return -1; we don't handle that. 1718 // FIXME: The following function can return -1; we don't handle that.
1713 return iterator->preceding(length); 1719 return iterator->preceding(length);
1714 } 1720 }
1715 1721
1716 VisiblePosition previousSentencePosition(const VisiblePosition& c) { 1722 VisiblePosition previousSentencePosition(const VisiblePosition& c) {
1717 DCHECK(c.isValid()) << c; 1723 DCHECK(c.isValid()) << c;
1718 VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary); 1724 VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary);
1719 return honorEditingBoundaryAtOrBefore(prev, c.deepEquivalent()); 1725 return honorEditingBoundaryAtOrBefore(prev, c.deepEquivalent());
1720 } 1726 }
1721 1727
1722 static unsigned nextSentencePositionBoundary(const UChar* characters, 1728 static unsigned nextSentencePositionBoundary(const UChar* characters,
1723 unsigned length, 1729 unsigned length,
1724 unsigned, 1730 unsigned,
1725 BoundarySearchContextAvailability, 1731 BoundarySearchContextAvailability,
1726 bool&) { 1732 bool&) {
1727 // FIXME: This is identical to endSentenceBoundary. This isn't right, it needs to 1733 // FIXME: This is identical to endSentenceBoundary. This isn't right, it needs
1728 // move to the equivlant position in the following sentence. 1734 // to move to the equivlant position in the following sentence.
1729 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); 1735 TextBreakIterator* iterator = sentenceBreakIterator(characters, length);
1730 return iterator->following(0); 1736 return iterator->following(0);
1731 } 1737 }
1732 1738
1733 VisiblePosition nextSentencePosition(const VisiblePosition& c) { 1739 VisiblePosition nextSentencePosition(const VisiblePosition& c) {
1734 DCHECK(c.isValid()) << c; 1740 DCHECK(c.isValid()) << c;
1735 VisiblePosition next = nextBoundary(c, nextSentencePositionBoundary); 1741 VisiblePosition next = nextBoundary(c, nextSentencePositionBoundary);
1736 return honorEditingBoundaryAtOrAfter(next, c.deepEquivalent()); 1742 return honorEditingBoundaryAtOrAfter(next, c.deepEquivalent());
1737 } 1743 }
1738 1744
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 } 1924 }
1919 const ComputedStyle& style = layoutObject->styleRef(); 1925 const ComputedStyle& style = layoutObject->styleRef();
1920 if (style.visibility() != EVisibility::Visible) { 1926 if (style.visibility() != EVisibility::Visible) {
1921 nextNodeItreator = Strategy::next(*nextNodeItreator, startBlock); 1927 nextNodeItreator = Strategy::next(*nextNodeItreator, startBlock);
1922 continue; 1928 continue;
1923 } 1929 }
1924 1930
1925 if (layoutObject->isBR() || isEnclosingBlock(nextNodeItreator)) 1931 if (layoutObject->isBR() || isEnclosingBlock(nextNodeItreator))
1926 break; 1932 break;
1927 1933
1928 // FIXME: We avoid returning a position where the layoutObject can't accept the caret. 1934 // FIXME: We avoid returning a position where the layoutObject can't accept
1935 // the caret.
1929 if (layoutObject->isText() && 1936 if (layoutObject->isText() &&
1930 toLayoutText(layoutObject)->resolvedTextLength()) { 1937 toLayoutText(layoutObject)->resolvedTextLength()) {
1931 SECURITY_DCHECK(nextNodeItreator->isTextNode()); 1938 SECURITY_DCHECK(nextNodeItreator->isTextNode());
1932 LayoutText* const text = toLayoutText(layoutObject); 1939 LayoutText* const text = toLayoutText(layoutObject);
1933 if (style.preserveNewline()) { 1940 if (style.preserveNewline()) {
1934 const int length = toLayoutText(layoutObject)->textLength(); 1941 const int length = toLayoutText(layoutObject)->textLength();
1935 for (int i = (nextNodeItreator == startNode ? candidateOffset : 0); 1942 for (int i = (nextNodeItreator == startNode ? candidateOffset : 0);
1936 i < length; ++i) { 1943 i < length; ++i) {
1937 if ((*text)[i] == '\n') 1944 if ((*text)[i] == '\n')
1938 return PositionTemplate<Strategy>(toText(nextNodeItreator), 1945 return PositionTemplate<Strategy>(toText(nextNodeItreator),
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
2903 ? PositionTemplate<Strategy>::editingPositionOf( 2910 ? PositionTemplate<Strategy>::editingPositionOf(
2904 position.anchorNode(), 2911 position.anchorNode(),
2905 Strategy::caretMaxOffset(*position.anchorNode())) 2912 Strategy::caretMaxOffset(*position.anchorNode()))
2906 : position); 2913 : position);
2907 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; 2914 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible;
2908 bool startEditable = hasEditableStyle(*startNode); 2915 bool startEditable = hasEditableStyle(*startNode);
2909 Node* lastNode = startNode; 2916 Node* lastNode = startNode;
2910 bool boundaryCrossed = false; 2917 bool boundaryCrossed = false;
2911 for (; !currentPos.atStart(); currentPos.decrement()) { 2918 for (; !currentPos.atStart(); currentPos.decrement()) {
2912 Node* currentNode = currentPos.node(); 2919 Node* currentNode = currentPos.node();
2913 // Don't check for an editability change if we haven't moved to a different node, 2920 // Don't check for an editability change if we haven't moved to a different
2914 // to avoid the expense of computing hasEditableStyle(). 2921 // node, to avoid the expense of computing hasEditableStyle().
2915 if (currentNode != lastNode) { 2922 if (currentNode != lastNode) {
2916 // Don't change editability. 2923 // Don't change editability.
2917 bool currentEditable = hasEditableStyle(*currentNode); 2924 bool currentEditable = hasEditableStyle(*currentNode);
2918 if (startEditable != currentEditable) { 2925 if (startEditable != currentEditable) {
2919 if (rule == CannotCrossEditingBoundary) 2926 if (rule == CannotCrossEditingBoundary)
2920 break; 2927 break;
2921 boundaryCrossed = true; 2928 boundaryCrossed = true;
2922 } 2929 }
2923 lastNode = currentNode; 2930 lastNode = currentNode;
2924 } 2931 }
2925 2932
2926 // If we've moved to a position that is visually distinct, return the last s aved position. There 2933 // If we've moved to a position that is visually distinct, return the last
2927 // is code below that terminates early if we're *about* to move to a visuall y distinct position. 2934 // saved position. There is code below that terminates early if we're
2935 // *about* to move to a visually distinct position.
2928 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && 2936 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) &&
2929 currentNode != boundary) 2937 currentNode != boundary)
2930 return lastVisible.deprecatedComputePosition(); 2938 return lastVisible.deprecatedComputePosition();
2931 2939
2932 // skip position in non-laid out or invisible node 2940 // skip position in non-laid out or invisible node
2933 LayoutObject* layoutObject = 2941 LayoutObject* layoutObject =
2934 associatedLayoutObjectOf(*currentNode, currentPos.offsetInLeafNode()); 2942 associatedLayoutObjectOf(*currentNode, currentPos.offsetInLeafNode());
2935 if (!layoutObject || 2943 if (!layoutObject ||
2936 layoutObject->style()->visibility() != EVisibility::Visible) 2944 layoutObject->style()->visibility() != EVisibility::Visible)
2937 continue; 2945 continue;
2938 2946
2939 if (rule == CanCrossEditingBoundary && boundaryCrossed) { 2947 if (rule == CanCrossEditingBoundary && boundaryCrossed) {
2940 lastVisible = currentPos; 2948 lastVisible = currentPos;
2941 break; 2949 break;
2942 } 2950 }
2943 2951
2944 // track last visible streamer position 2952 // track last visible streamer position
2945 if (isStreamer<Strategy>(currentPos)) 2953 if (isStreamer<Strategy>(currentPos))
2946 lastVisible = currentPos; 2954 lastVisible = currentPos;
2947 2955
2948 // Don't move past a position that is visually distinct. We could rely on c ode above to terminate and 2956 // Don't move past a position that is visually distinct. We could rely on
2949 // return lastVisible on the next iteration, but we terminate early to avoid doing a nodeIndex() call. 2957 // code above to terminate and return lastVisible on the next iteration, but
2958 // we terminate early to avoid doing a nodeIndex() call.
2950 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && 2959 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) &&
2951 currentPos.atStartOfNode()) 2960 currentPos.atStartOfNode())
2952 return lastVisible.deprecatedComputePosition(); 2961 return lastVisible.deprecatedComputePosition();
2953 2962
2954 // Return position after tables and nodes which have content that can be ign ored. 2963 // Return position after tables and nodes which have content that can be
2964 // ignored.
2955 if (Strategy::editingIgnoresContent(currentNode) || 2965 if (Strategy::editingIgnoresContent(currentNode) ||
2956 isDisplayInsideTable(currentNode)) { 2966 isDisplayInsideTable(currentNode)) {
2957 if (currentPos.atEndOfNode()) 2967 if (currentPos.atEndOfNode())
2958 return PositionTemplate<Strategy>::afterNode(currentNode); 2968 return PositionTemplate<Strategy>::afterNode(currentNode);
2959 continue; 2969 continue;
2960 } 2970 }
2961 2971
2962 // return current position if it is in laid out text 2972 // return current position if it is in laid out text
2963 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()) { 2973 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()) {
2964 LayoutText* const textLayoutObject = toLayoutText(layoutObject); 2974 LayoutText* const textLayoutObject = toLayoutText(layoutObject);
2965 const unsigned textStartOffset = textLayoutObject->textStartOffset(); 2975 const unsigned textStartOffset = textLayoutObject->textStartOffset();
2966 if (currentNode != startNode) { 2976 if (currentNode != startNode) {
2967 // This assertion fires in layout tests in the case-transform.html test because 2977 // This assertion fires in layout tests in the case-transform.html test
2968 // of a mix-up between offsets in the text in the DOM tree with text in the 2978 // because of a mix-up between offsets in the text in the DOM tree with
2969 // layout tree which can have a different length due to case transformat ion. 2979 // text in the layout tree which can have a different length due to case
2980 // transformation.
2970 // Until we resolve that, disable this so we can run the layout tests! 2981 // Until we resolve that, disable this so we can run the layout tests!
2971 // DCHECK_GE(currentOffset, layoutObject->caretMaxOffset()); 2982 // DCHECK_GE(currentOffset, layoutObject->caretMaxOffset());
2972 return PositionTemplate<Strategy>( 2983 return PositionTemplate<Strategy>(
2973 currentNode, layoutObject->caretMaxOffset() + textStartOffset); 2984 currentNode, layoutObject->caretMaxOffset() + textStartOffset);
2974 } 2985 }
2975 2986
2976 // Map offset in DOM node to offset in InlineBox. 2987 // Map offset in DOM node to offset in InlineBox.
2977 DCHECK_GE(currentPos.offsetInLeafNode(), 2988 DCHECK_GE(currentPos.offsetInLeafNode(),
2978 static_cast<int>(textStartOffset)); 2989 static_cast<int>(textStartOffset));
2979 const unsigned textOffset = 2990 const unsigned textOffset =
(...skipping 21 matching lines...) Expand all
3001 } 3012 }
3002 if (textOffset <= box->start() + box->len()) { 3013 if (textOffset <= box->start() + box->len()) {
3003 if (textOffset > box->start()) 3014 if (textOffset > box->start())
3004 return currentPos.computePosition(); 3015 return currentPos.computePosition();
3005 continue; 3016 continue;
3006 } 3017 }
3007 3018
3008 if (box == lastTextBox || textOffset != box->start() + box->len() + 1) 3019 if (box == lastTextBox || textOffset != box->start() + box->len() + 1)
3009 continue; 3020 continue;
3010 3021
3011 // The text continues on the next line only if the last text box is not on this line and 3022 // The text continues on the next line only if the last text box is not
3012 // none of the boxes on this line have a larger start offset. 3023 // on this line and none of the boxes on this line have a larger start
3024 // offset.
3013 3025
3014 bool continuesOnNextLine = true; 3026 bool continuesOnNextLine = true;
3015 InlineBox* otherBox = box; 3027 InlineBox* otherBox = box;
3016 while (continuesOnNextLine) { 3028 while (continuesOnNextLine) {
3017 otherBox = otherBox->nextLeafChild(); 3029 otherBox = otherBox->nextLeafChild();
3018 if (!otherBox) 3030 if (!otherBox)
3019 break; 3031 break;
3020 if (otherBox == lastTextBox || 3032 if (otherBox == lastTextBox ||
3021 (LineLayoutAPIShim::layoutObjectFrom( 3033 (LineLayoutAPIShim::layoutObjectFrom(
3022 otherBox->getLineLayoutItem()) == textLayoutObject && 3034 otherBox->getLineLayoutItem()) == textLayoutObject &&
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3072 ? PositionTemplate<Strategy>::editingPositionOf( 3084 ? PositionTemplate<Strategy>::editingPositionOf(
3073 position.anchorNode(), 3085 position.anchorNode(),
3074 Strategy::caretMaxOffset(*position.anchorNode())) 3086 Strategy::caretMaxOffset(*position.anchorNode()))
3075 : position); 3087 : position);
3076 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; 3088 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible;
3077 bool startEditable = hasEditableStyle(*startNode); 3089 bool startEditable = hasEditableStyle(*startNode);
3078 Node* lastNode = startNode; 3090 Node* lastNode = startNode;
3079 bool boundaryCrossed = false; 3091 bool boundaryCrossed = false;
3080 for (; !currentPos.atEnd(); currentPos.increment()) { 3092 for (; !currentPos.atEnd(); currentPos.increment()) {
3081 Node* currentNode = currentPos.node(); 3093 Node* currentNode = currentPos.node();
3082 // Don't check for an editability change if we haven't moved to a different node, 3094 // Don't check for an editability change if we haven't moved to a different
3083 // to avoid the expense of computing hasEditableStyle(). 3095 // node, to avoid the expense of computing hasEditableStyle().
3084 if (currentNode != lastNode) { 3096 if (currentNode != lastNode) {
3085 // Don't change editability. 3097 // Don't change editability.
3086 bool currentEditable = hasEditableStyle(*currentNode); 3098 bool currentEditable = hasEditableStyle(*currentNode);
3087 if (startEditable != currentEditable) { 3099 if (startEditable != currentEditable) {
3088 if (rule == CannotCrossEditingBoundary) 3100 if (rule == CannotCrossEditingBoundary)
3089 break; 3101 break;
3090 boundaryCrossed = true; 3102 boundaryCrossed = true;
3091 } 3103 }
3092 3104
3093 lastNode = currentNode; 3105 lastNode = currentNode;
3094 } 3106 }
3095 3107
3096 // stop before going above the body, up into the head 3108 // stop before going above the body, up into the head
3097 // return the last visible streamer position 3109 // return the last visible streamer position
3098 if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode()) 3110 if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode())
3099 break; 3111 break;
3100 3112
3101 // Do not move to a visually distinct position. 3113 // Do not move to a visually distinct position.
3102 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && 3114 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) &&
3103 currentNode != boundary) 3115 currentNode != boundary)
3104 return lastVisible.deprecatedComputePosition(); 3116 return lastVisible.deprecatedComputePosition();
3105 // Do not move past a visually disinct position. 3117 // Do not move past a visually disinct position.
3106 // Note: The first position after the last in a node whose ends are visually distinct 3118 // Note: The first position after the last in a node whose ends are visually
3107 // positions will be [boundary->parentNode(), originalBlock->nodeIndex() + 1 ]. 3119 // distinct positions will be [boundary->parentNode(),
3120 // originalBlock->nodeIndex() + 1].
3108 if (boundary && Strategy::parent(*boundary) == currentNode) 3121 if (boundary && Strategy::parent(*boundary) == currentNode)
3109 return lastVisible.deprecatedComputePosition(); 3122 return lastVisible.deprecatedComputePosition();
3110 3123
3111 // skip position in non-laid out or invisible node 3124 // skip position in non-laid out or invisible node
3112 LayoutObject* layoutObject = 3125 LayoutObject* layoutObject =
3113 associatedLayoutObjectOf(*currentNode, currentPos.offsetInLeafNode()); 3126 associatedLayoutObjectOf(*currentNode, currentPos.offsetInLeafNode());
3114 if (!layoutObject || 3127 if (!layoutObject ||
3115 layoutObject->style()->visibility() != EVisibility::Visible) 3128 layoutObject->style()->visibility() != EVisibility::Visible)
3116 continue; 3129 continue;
3117 3130
3118 if (rule == CanCrossEditingBoundary && boundaryCrossed) { 3131 if (rule == CanCrossEditingBoundary && boundaryCrossed) {
3119 lastVisible = currentPos; 3132 lastVisible = currentPos;
3120 break; 3133 break;
3121 } 3134 }
3122 3135
3123 // track last visible streamer position 3136 // track last visible streamer position
3124 if (isStreamer<Strategy>(currentPos)) 3137 if (isStreamer<Strategy>(currentPos))
3125 lastVisible = currentPos; 3138 lastVisible = currentPos;
3126 3139
3127 // Return position before tables and nodes which have content that can be ig nored. 3140 // Return position before tables and nodes which have content that can be
3141 // ignored.
3128 if (Strategy::editingIgnoresContent(currentNode) || 3142 if (Strategy::editingIgnoresContent(currentNode) ||
3129 isDisplayInsideTable(currentNode)) { 3143 isDisplayInsideTable(currentNode)) {
3130 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset()) 3144 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset())
3131 return PositionTemplate<Strategy>::editingPositionOf( 3145 return PositionTemplate<Strategy>::editingPositionOf(
3132 currentNode, layoutObject->caretMinOffset()); 3146 currentNode, layoutObject->caretMinOffset());
3133 continue; 3147 continue;
3134 } 3148 }
3135 3149
3136 // return current position if it is in laid out text 3150 // return current position if it is in laid out text
3137 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()) { 3151 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox()) {
(...skipping 15 matching lines...) Expand all
3153 box = box->nextTextBox()) { 3167 box = box->nextTextBox()) {
3154 if (textOffset <= box->end()) { 3168 if (textOffset <= box->end()) {
3155 if (textOffset >= box->start()) 3169 if (textOffset >= box->start())
3156 return currentPos.computePosition(); 3170 return currentPos.computePosition();
3157 continue; 3171 continue;
3158 } 3172 }
3159 3173
3160 if (box == lastTextBox || textOffset != box->start() + box->len()) 3174 if (box == lastTextBox || textOffset != box->start() + box->len())
3161 continue; 3175 continue;
3162 3176
3163 // The text continues on the next line only if the last text box is not on this line and 3177 // The text continues on the next line only if the last text box is not
3164 // none of the boxes on this line have a larger start offset. 3178 // on this line and none of the boxes on this line have a larger start
3179 // offset.
3165 3180
3166 bool continuesOnNextLine = true; 3181 bool continuesOnNextLine = true;
3167 InlineBox* otherBox = box; 3182 InlineBox* otherBox = box;
3168 while (continuesOnNextLine) { 3183 while (continuesOnNextLine) {
3169 otherBox = otherBox->nextLeafChild(); 3184 otherBox = otherBox->nextLeafChild();
3170 if (!otherBox) 3185 if (!otherBox)
3171 break; 3186 break;
3172 if (otherBox == lastTextBox || 3187 if (otherBox == lastTextBox ||
3173 (LineLayoutAPIShim::layoutObjectFrom( 3188 (LineLayoutAPIShim::layoutObjectFrom(
3174 otherBox->getLineLayoutItem()) == textLayoutObject && 3189 otherBox->getLineLayoutItem()) == textLayoutObject &&
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
3766 3781
3767 if (box->bidiLevel() > level) { 3782 if (box->bidiLevel() > level) {
3768 do { 3783 do {
3769 nextBox = nextBox->nextLeafChild(); 3784 nextBox = nextBox->nextLeafChild();
3770 } while (nextBox && nextBox->bidiLevel() > level); 3785 } while (nextBox && nextBox->bidiLevel() > level);
3771 3786
3772 if (!nextBox || nextBox->bidiLevel() < level) 3787 if (!nextBox || nextBox->bidiLevel() < level)
3773 continue; 3788 continue;
3774 } 3789 }
3775 } else { 3790 } else {
3776 // Trailing edge of a secondary run. Set to the leading edge of the enti re run. 3791 // Trailing edge of a secondary run. Set to the leading edge of the
3792 // entire run.
3777 while (true) { 3793 while (true) {
3778 while (InlineBox* prevBox = box->prevLeafChild()) { 3794 while (InlineBox* prevBox = box->prevLeafChild()) {
3779 if (prevBox->bidiLevel() < level) 3795 if (prevBox->bidiLevel() < level)
3780 break; 3796 break;
3781 box = prevBox; 3797 box = prevBox;
3782 } 3798 }
3783 if (box->bidiLevel() == level) 3799 if (box->bidiLevel() == level)
3784 break; 3800 break;
3785 level = box->bidiLevel(); 3801 level = box->bidiLevel();
3786 while (InlineBox* nextBox = box->nextLeafChild()) { 3802 while (InlineBox* nextBox = box->nextLeafChild()) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 if (visiblePosition.isNull()) 4010 if (visiblePosition.isNull())
3995 return VisiblePositionInFlatTree(); 4011 return VisiblePositionInFlatTree();
3996 visiblePosition.deepEquivalent() 4012 visiblePosition.deepEquivalent()
3997 .document() 4013 .document()
3998 ->updateStyleAndLayoutIgnorePendingStylesheets(); 4014 ->updateStyleAndLayoutIgnorePendingStylesheets();
3999 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>( 4015 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(
4000 visiblePosition.deepEquivalent(), rule); 4016 visiblePosition.deepEquivalent(), rule);
4001 } 4017 }
4002 4018
4003 } // namespace blink 4019 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/VisibleUnits.h ('k') | third_party/WebKit/Source/core/editing/VisibleUnitsTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698