| Index: third_party/WebKit/Source/core/editing/VisibleUnits.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
|
| index 017aa6fc170a7a73589f65d7d9475e1673cd3bb7..411ce6cb4db36c90beabc8e0ab869d1940434cb7 100644
|
| --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
|
| @@ -1476,80 +1476,84 @@ VisiblePosition nextSentencePosition(const VisiblePosition& c)
|
| }
|
|
|
| template <typename Strategy>
|
| -VisiblePositionTemplate<Strategy> startOfParagraphAlgorithm(const VisiblePositionTemplate<Strategy>& c, EditingBoundaryCrossingRule boundaryCrossingRule)
|
| +PositionTemplate<Strategy> startOfParagraphAlgorithm(const PositionTemplate<Strategy>& position, EditingBoundaryCrossingRule boundaryCrossingRule)
|
| {
|
| - const PositionTemplate<Strategy> p = c.deepEquivalent();
|
| - Node* startNode = p.anchorNode();
|
| + Node* const startNode = position.anchorNode();
|
|
|
| if (!startNode)
|
| - return VisiblePositionTemplate<Strategy>();
|
| + return PositionTemplate<Strategy>();
|
|
|
| if (isRenderedAsNonInlineTableImageOrHR(startNode))
|
| - return createVisiblePosition(PositionTemplate<Strategy>::beforeNode(startNode));
|
| + return PositionTemplate<Strategy>::beforeNode(startNode);
|
|
|
| - Element* startBlock = enclosingBlock(PositionTemplate<Strategy>::firstPositionInOrBeforeNode(startNode), CannotCrossEditingBoundary);
|
| + Element* const startBlock = enclosingBlock(PositionTemplate<Strategy>::firstPositionInOrBeforeNode(startNode), CannotCrossEditingBoundary);
|
| + ContainerNode* const highestRoot = highestEditableRoot(position);
|
| + const bool startNodeIsEditable = hasEditableStyle(*startNode);
|
|
|
| - Node* node = startNode;
|
| - ContainerNode* highestRoot = highestEditableRoot(p);
|
| - int offset = p.computeEditingOffset();
|
| - PositionAnchorType type = p.anchorType();
|
| + Node* candidateNode = startNode;
|
| + PositionAnchorType candidateType = position.anchorType();
|
| + int candidateOffset = position.computeEditingOffset();
|
|
|
| - Node* n = startNode;
|
| - bool startNodeIsEditable = hasEditableStyle(*startNode);
|
| - while (n) {
|
| - if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSelectAll(n) && hasEditableStyle(*n) != startNodeIsEditable)
|
| + Node* prevousNodeIterator = startNode;
|
| + while (prevousNodeIterator) {
|
| + if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSelectAll(prevousNodeIterator) && hasEditableStyle(*prevousNodeIterator) != startNodeIsEditable)
|
| break;
|
| if (boundaryCrossingRule == CanSkipOverEditingBoundary) {
|
| - while (n && hasEditableStyle(*n) != startNodeIsEditable)
|
| - n = Strategy::previousPostOrder(*n, startBlock);
|
| - if (!n || !n->isDescendantOf(highestRoot))
|
| + while (prevousNodeIterator && hasEditableStyle(*prevousNodeIterator) != startNodeIsEditable)
|
| + prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterator, startBlock);
|
| + if (!prevousNodeIterator || !prevousNodeIterator->isDescendantOf(highestRoot))
|
| break;
|
| }
|
| - LayoutObject* r = n->layoutObject();
|
| - LayoutItem ri = LayoutItem(r);
|
| - if (ri.isNull()) {
|
| - n = Strategy::previousPostOrder(*n, startBlock);
|
| +
|
| + const LayoutItem layoutItem = LayoutItem(prevousNodeIterator->layoutObject());
|
| + if (layoutItem.isNull()) {
|
| + prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterator, startBlock);
|
| continue;
|
| }
|
| - const ComputedStyle& style = ri.styleRef();
|
| + const ComputedStyle& style = layoutItem.styleRef();
|
| if (style.visibility() != VISIBLE) {
|
| - n = Strategy::previousPostOrder(*n, startBlock);
|
| + prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterator, startBlock);
|
| continue;
|
| }
|
|
|
| - if (ri.isBR() || isEnclosingBlock(n))
|
| + if (layoutItem.isBR() || isEnclosingBlock(prevousNodeIterator))
|
| break;
|
|
|
| - if (ri.isText() && toLayoutText(r)->resolvedTextLength()) {
|
| - ASSERT_WITH_SECURITY_IMPLICATION(n->isTextNode());
|
| - type = PositionAnchorType::OffsetInAnchor;
|
| + if (layoutItem.isText() && toLayoutText(prevousNodeIterator->layoutObject())->resolvedTextLength()) {
|
| + SECURITY_DCHECK(prevousNodeIterator->isTextNode());
|
| if (style.preserveNewline()) {
|
| - LayoutText* text = toLayoutText(r);
|
| - int i = text->textLength();
|
| - int o = offset;
|
| - if (n == startNode && o < i)
|
| - i = max(0, o);
|
| - while (--i >= 0) {
|
| - if ((*text)[i] == '\n')
|
| - return createVisiblePosition(PositionTemplate<Strategy>(toText(n), i + 1));
|
| + LayoutText* text = toLayoutText(prevousNodeIterator->layoutObject());
|
| + int index = text->textLength();
|
| + if (prevousNodeIterator == startNode && candidateOffset < index)
|
| + index = max(0, candidateOffset);
|
| + while (--index >= 0) {
|
| + if ((*text)[index] == '\n')
|
| + return PositionTemplate<Strategy>(toText(prevousNodeIterator), index + 1);
|
| }
|
| }
|
| - node = n;
|
| - offset = 0;
|
| - n = Strategy::previousPostOrder(*n, startBlock);
|
| - } else if (editingIgnoresContent(n) || isDisplayInsideTable(n)) {
|
| - node = n;
|
| - type = PositionAnchorType::BeforeAnchor;
|
| - n = n->previousSibling() ? n->previousSibling() : Strategy::previousPostOrder(*n, startBlock);
|
| + candidateNode = prevousNodeIterator;
|
| + candidateType = PositionAnchorType::OffsetInAnchor;
|
| + candidateOffset = 0;
|
| + prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterator, startBlock);
|
| + } else if (editingIgnoresContent(prevousNodeIterator) || isDisplayInsideTable(prevousNodeIterator)) {
|
| + candidateNode = prevousNodeIterator;
|
| + candidateType = PositionAnchorType::BeforeAnchor;
|
| + prevousNodeIterator = prevousNodeIterator->previousSibling() ? prevousNodeIterator->previousSibling() : Strategy::previousPostOrder(*prevousNodeIterator, startBlock);
|
| } else {
|
| - n = Strategy::previousPostOrder(*n, startBlock);
|
| + prevousNodeIterator = Strategy::previousPostOrder(*prevousNodeIterator, startBlock);
|
| }
|
| }
|
|
|
| - if (type == PositionAnchorType::OffsetInAnchor)
|
| - return createVisiblePosition(PositionTemplate<Strategy>(node, offset));
|
| + if (candidateType == PositionAnchorType::OffsetInAnchor)
|
| + return PositionTemplate<Strategy>(candidateNode, candidateOffset);
|
|
|
| - return createVisiblePosition(PositionTemplate<Strategy>(node, type));
|
| + return PositionTemplate<Strategy>(candidateNode, candidateType);
|
| +}
|
| +
|
| +template <typename Strategy>
|
| +VisiblePositionTemplate<Strategy> startOfParagraphAlgorithm(const VisiblePositionTemplate<Strategy>& visiblePosition, EditingBoundaryCrossingRule boundaryCrossingRule)
|
| +{
|
| + return createVisiblePosition(startOfParagraphAlgorithm(visiblePosition.deepEquivalent(), boundaryCrossingRule));
|
| }
|
|
|
| VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossingRule boundaryCrossingRule)
|
|
|