| 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 3e2484f8e54e686ead2e863588adec4cfa121e51..674ec43e7e6de1391063bda523020869fc8d9982 100644
|
| --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
|
| @@ -165,7 +165,8 @@ PositionInFlatTree CanonicalPositionOf(const PositionInFlatTree& position) {
|
| }
|
|
|
| template <typename Strategy>
|
| -static PositionWithAffinityTemplate<Strategy> HonorEditingBoundaryAtOrBefore(
|
| +static PositionWithAffinityTemplate<Strategy>
|
| +HonorEditingBoundaryAtOrBeforeTemplate(
|
| const PositionWithAffinityTemplate<Strategy>& pos,
|
| const PositionTemplate<Strategy>& anchor) {
|
| if (pos.IsNull())
|
| @@ -198,6 +199,18 @@ static PositionWithAffinityTemplate<Strategy> HonorEditingBoundaryAtOrBefore(
|
| *highest_root);
|
| }
|
|
|
| +PositionWithAffinity HonorEditingBoundaryAtOrBefore(
|
| + const PositionWithAffinity& pos,
|
| + const Position& anchor) {
|
| + return HonorEditingBoundaryAtOrBeforeTemplate(pos, anchor);
|
| +}
|
| +
|
| +PositionInFlatTreeWithAffinity HonorEditingBoundaryAtOrBefore(
|
| + const PositionInFlatTreeWithAffinity& pos,
|
| + const PositionInFlatTree& anchor) {
|
| + return HonorEditingBoundaryAtOrBeforeTemplate(pos, anchor);
|
| +}
|
| +
|
| template <typename Strategy>
|
| VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrBeforeAlgorithm(
|
| const VisiblePositionTemplate<Strategy>& pos,
|
| @@ -220,7 +233,7 @@ VisiblePositionInFlatTree HonorEditingBoundaryAtOrBefore(
|
| }
|
|
|
| template <typename Strategy>
|
| -static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrAfter(
|
| +static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrAfterTemplate(
|
| const VisiblePositionTemplate<Strategy>& pos,
|
| const PositionTemplate<Strategy>& anchor) {
|
| DCHECK(pos.IsValid()) << pos;
|
| @@ -255,144 +268,15 @@ static VisiblePositionTemplate<Strategy> HonorEditingBoundaryAtOrAfter(
|
| *highest_root);
|
| }
|
|
|
| -static bool HasEditableStyle(const Node& node, EditableType editable_type) {
|
| - if (editable_type == kHasEditableAXRole) {
|
| - if (AXObjectCache* cache = node.GetDocument().ExistingAXObjectCache()) {
|
| - if (cache->RootAXEditableElement(&node))
|
| - return true;
|
| - }
|
| - }
|
| -
|
| - return HasEditableStyle(node);
|
| -}
|
| -
|
| -static Element* RootEditableElement(const Node& node,
|
| - EditableType editable_type) {
|
| - if (editable_type == kHasEditableAXRole) {
|
| - if (AXObjectCache* cache = node.GetDocument().ExistingAXObjectCache())
|
| - return const_cast<Element*>(cache->RootAXEditableElement(&node));
|
| - }
|
| -
|
| - return RootEditableElement(node);
|
| -}
|
| -
|
| -static Element* RootAXEditableElementOf(const Position& position) {
|
| - Node* node = position.ComputeContainerNode();
|
| - if (!node)
|
| - return 0;
|
| -
|
| - if (IsDisplayInsideTable(node))
|
| - node = node->parentNode();
|
| -
|
| - return RootEditableElement(*node, kHasEditableAXRole);
|
| -}
|
| -
|
| -static bool HasAXEditableStyle(const Node& node) {
|
| - return HasEditableStyle(node, kHasEditableAXRole);
|
| -}
|
| -
|
| -static ContainerNode* HighestEditableRoot(const Position& position,
|
| - EditableType editable_type) {
|
| - if (editable_type == kHasEditableAXRole)
|
| - return HighestEditableRoot(position, RootAXEditableElementOf,
|
| - HasAXEditableStyle);
|
| -
|
| - return HighestEditableRoot(position);
|
| -}
|
| -
|
| -static Node* PreviousLeafWithSameEditability(Node* node,
|
| - EditableType editable_type) {
|
| - bool editable = HasEditableStyle(*node, editable_type);
|
| - node = PreviousAtomicLeafNode(*node);
|
| - while (node) {
|
| - if (editable == HasEditableStyle(*node, editable_type))
|
| - return node;
|
| - node = PreviousAtomicLeafNode(*node);
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -static Node* NextLeafWithSameEditability(
|
| - Node* node,
|
| - EditableType editable_type = kContentIsEditable) {
|
| - if (!node)
|
| - return 0;
|
| -
|
| - bool editable = HasEditableStyle(*node, editable_type);
|
| - node = NextAtomicLeafNode(*node);
|
| - while (node) {
|
| - if (editable == HasEditableStyle(*node, editable_type))
|
| - return node;
|
| - node = NextAtomicLeafNode(*node);
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -// FIXME: consolidate with code in previousLinePosition.
|
| -Position PreviousRootInlineBoxCandidatePosition(
|
| - Node* node,
|
| - const VisiblePosition& visible_position,
|
| - EditableType editable_type) {
|
| - DCHECK(visible_position.IsValid()) << visible_position;
|
| - ContainerNode* highest_root =
|
| - HighestEditableRoot(visible_position.DeepEquivalent(), editable_type);
|
| - Node* previous_node = PreviousLeafWithSameEditability(node, editable_type);
|
| -
|
| - while (previous_node &&
|
| - (!previous_node->GetLayoutObject() ||
|
| - InSameLine(
|
| - CreateVisiblePosition(FirstPositionInOrBeforeNode(previous_node)),
|
| - visible_position)))
|
| - previous_node =
|
| - PreviousLeafWithSameEditability(previous_node, editable_type);
|
| -
|
| - while (previous_node && !previous_node->IsShadowRoot()) {
|
| - if (HighestEditableRoot(FirstPositionInOrBeforeNode(previous_node),
|
| - editable_type) != highest_root)
|
| - break;
|
| -
|
| - Position pos = isHTMLBRElement(*previous_node)
|
| - ? Position::BeforeNode(previous_node)
|
| - : Position::EditingPositionOf(
|
| - previous_node, CaretMaxOffset(previous_node));
|
| -
|
| - if (IsVisuallyEquivalentCandidate(pos))
|
| - return pos;
|
| -
|
| - previous_node =
|
| - PreviousLeafWithSameEditability(previous_node, editable_type);
|
| - }
|
| - return Position();
|
| +VisiblePosition HonorEditingBoundaryAtOrAfter(const VisiblePosition& pos,
|
| + const Position& anchor) {
|
| + return HonorEditingBoundaryAtOrAfterTemplate(pos, anchor);
|
| }
|
|
|
| -Position NextRootInlineBoxCandidatePosition(
|
| - Node* node,
|
| - const VisiblePosition& visible_position,
|
| - EditableType editable_type) {
|
| - DCHECK(visible_position.IsValid()) << visible_position;
|
| - ContainerNode* highest_root =
|
| - HighestEditableRoot(visible_position.DeepEquivalent(), editable_type);
|
| - Node* next_node = NextLeafWithSameEditability(node, editable_type);
|
| - while (next_node && (!next_node->GetLayoutObject() ||
|
| - InSameLine(CreateVisiblePosition(
|
| - FirstPositionInOrBeforeNode(next_node)),
|
| - visible_position)))
|
| - next_node = NextLeafWithSameEditability(next_node, kContentIsEditable);
|
| -
|
| - while (next_node && !next_node->IsShadowRoot()) {
|
| - if (HighestEditableRoot(FirstPositionInOrBeforeNode(next_node),
|
| - editable_type) != highest_root)
|
| - break;
|
| -
|
| - Position pos;
|
| - pos = Position::EditingPositionOf(next_node, CaretMinOffset(next_node));
|
| -
|
| - if (IsVisuallyEquivalentCandidate(pos))
|
| - return pos;
|
| -
|
| - next_node = NextLeafWithSameEditability(next_node, editable_type);
|
| - }
|
| - return Position();
|
| +VisiblePositionInFlatTree HonorEditingBoundaryAtOrAfter(
|
| + const VisiblePositionInFlatTree& pos,
|
| + const PositionInFlatTree& anchor) {
|
| + return HonorEditingBoundaryAtOrAfterTemplate(pos, anchor);
|
| }
|
|
|
| template <typename Strategy>
|
| @@ -809,509 +693,6 @@ VisiblePosition NextWordPosition(const VisiblePosition& c) {
|
|
|
| // ---------
|
|
|
| -enum LineEndpointComputationMode { kUseLogicalOrdering, kUseInlineBoxOrdering };
|
| -template <typename Strategy>
|
| -static PositionWithAffinityTemplate<Strategy> StartPositionForLine(
|
| - const PositionWithAffinityTemplate<Strategy>& c,
|
| - LineEndpointComputationMode mode) {
|
| - if (c.IsNull())
|
| - return PositionWithAffinityTemplate<Strategy>();
|
| -
|
| - RootInlineBox* root_box =
|
| - RenderedPosition(c.GetPosition(), c.Affinity()).RootBox();
|
| - if (!root_box) {
|
| - // There are VisiblePositions at offset 0 in blocks without
|
| - // RootInlineBoxes, like empty editable blocks and bordered blocks.
|
| - PositionTemplate<Strategy> p = c.GetPosition();
|
| - if (p.AnchorNode()->GetLayoutObject() &&
|
| - p.AnchorNode()->GetLayoutObject()->IsLayoutBlock() &&
|
| - !p.ComputeEditingOffset())
|
| - return c;
|
| -
|
| - return PositionWithAffinityTemplate<Strategy>();
|
| - }
|
| -
|
| - Node* start_node;
|
| - InlineBox* start_box;
|
| - if (mode == kUseLogicalOrdering) {
|
| - start_node = root_box->GetLogicalStartBoxWithNode(start_box);
|
| - if (!start_node)
|
| - return PositionWithAffinityTemplate<Strategy>();
|
| - } else {
|
| - // Generated content (e.g. list markers and CSS :before and :after
|
| - // pseudoelements) have no corresponding DOM element, and so cannot be
|
| - // represented by a VisiblePosition. Use whatever follows instead.
|
| - start_box = root_box->FirstLeafChild();
|
| - while (true) {
|
| - if (!start_box)
|
| - return PositionWithAffinityTemplate<Strategy>();
|
| -
|
| - start_node = start_box->GetLineLayoutItem().NonPseudoNode();
|
| - if (start_node)
|
| - break;
|
| -
|
| - start_box = start_box->NextLeafChild();
|
| - }
|
| - }
|
| -
|
| - return PositionWithAffinityTemplate<Strategy>(
|
| - start_node->IsTextNode()
|
| - ? PositionTemplate<Strategy>(ToText(start_node),
|
| - ToInlineTextBox(start_box)->Start())
|
| - : PositionTemplate<Strategy>::BeforeNode(start_node));
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -static PositionWithAffinityTemplate<Strategy> StartOfLineAlgorithm(
|
| - const PositionWithAffinityTemplate<Strategy>& c) {
|
| - // TODO: this is the current behavior that might need to be fixed.
|
| - // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail.
|
| - PositionWithAffinityTemplate<Strategy> vis_pos =
|
| - StartPositionForLine(c, kUseInlineBoxOrdering);
|
| - return HonorEditingBoundaryAtOrBefore(vis_pos, c.GetPosition());
|
| -}
|
| -
|
| -static PositionWithAffinity StartOfLine(
|
| - const PositionWithAffinity& current_position) {
|
| - return StartOfLineAlgorithm<EditingStrategy>(current_position);
|
| -}
|
| -
|
| -static PositionInFlatTreeWithAffinity StartOfLine(
|
| - const PositionInFlatTreeWithAffinity& current_position) {
|
| - return StartOfLineAlgorithm<EditingInFlatTreeStrategy>(current_position);
|
| -}
|
| -
|
| -// FIXME: Rename this function to reflect the fact it ignores bidi levels.
|
| -VisiblePosition StartOfLine(const VisiblePosition& current_position) {
|
| - DCHECK(current_position.IsValid()) << current_position;
|
| - return CreateVisiblePosition(
|
| - StartOfLine(current_position.ToPositionWithAffinity()));
|
| -}
|
| -
|
| -VisiblePositionInFlatTree StartOfLine(
|
| - const VisiblePositionInFlatTree& current_position) {
|
| - DCHECK(current_position.IsValid()) << current_position;
|
| - return CreateVisiblePosition(
|
| - StartOfLine(current_position.ToPositionWithAffinity()));
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -static PositionWithAffinityTemplate<Strategy> LogicalStartOfLineAlgorithm(
|
| - const PositionWithAffinityTemplate<Strategy>& c) {
|
| - // TODO: this is the current behavior that might need to be fixed.
|
| - // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail.
|
| - PositionWithAffinityTemplate<Strategy> vis_pos =
|
| - StartPositionForLine(c, kUseLogicalOrdering);
|
| -
|
| - if (ContainerNode* editable_root = HighestEditableRoot(c.GetPosition())) {
|
| - if (!editable_root->contains(vis_pos.GetPosition().ComputeContainerNode()))
|
| - return PositionWithAffinityTemplate<Strategy>(
|
| - PositionTemplate<Strategy>::FirstPositionInNode(editable_root));
|
| - }
|
| -
|
| - return HonorEditingBoundaryAtOrBefore(vis_pos, c.GetPosition());
|
| -}
|
| -
|
| -VisiblePosition LogicalStartOfLine(const VisiblePosition& current_position) {
|
| - DCHECK(current_position.IsValid()) << current_position;
|
| - return CreateVisiblePosition(LogicalStartOfLineAlgorithm<EditingStrategy>(
|
| - current_position.ToPositionWithAffinity()));
|
| -}
|
| -
|
| -VisiblePositionInFlatTree LogicalStartOfLine(
|
| - const VisiblePositionInFlatTree& current_position) {
|
| - DCHECK(current_position.IsValid()) << current_position;
|
| - return CreateVisiblePosition(
|
| - LogicalStartOfLineAlgorithm<EditingInFlatTreeStrategy>(
|
| - current_position.ToPositionWithAffinity()));
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -static VisiblePositionTemplate<Strategy> EndPositionForLine(
|
| - const VisiblePositionTemplate<Strategy>& c,
|
| - LineEndpointComputationMode mode) {
|
| - DCHECK(c.IsValid()) << c;
|
| - if (c.IsNull())
|
| - return VisiblePositionTemplate<Strategy>();
|
| -
|
| - RootInlineBox* root_box = RenderedPosition(c).RootBox();
|
| - if (!root_box) {
|
| - // There are VisiblePositions at offset 0 in blocks without
|
| - // RootInlineBoxes, like empty editable blocks and bordered blocks.
|
| - const PositionTemplate<Strategy> p = c.DeepEquivalent();
|
| - if (p.AnchorNode()->GetLayoutObject() &&
|
| - p.AnchorNode()->GetLayoutObject()->IsLayoutBlock() &&
|
| - !p.ComputeEditingOffset())
|
| - return c;
|
| - return VisiblePositionTemplate<Strategy>();
|
| - }
|
| -
|
| - Node* end_node;
|
| - InlineBox* end_box;
|
| - if (mode == kUseLogicalOrdering) {
|
| - end_node = root_box->GetLogicalEndBoxWithNode(end_box);
|
| - if (!end_node)
|
| - return VisiblePositionTemplate<Strategy>();
|
| - } else {
|
| - // Generated content (e.g. list markers and CSS :before and :after
|
| - // pseudo elements) have no corresponding DOM element, and so cannot be
|
| - // represented by a VisiblePosition. Use whatever precedes instead.
|
| - end_box = root_box->LastLeafChild();
|
| - while (true) {
|
| - if (!end_box)
|
| - return VisiblePositionTemplate<Strategy>();
|
| -
|
| - end_node = end_box->GetLineLayoutItem().NonPseudoNode();
|
| - if (end_node)
|
| - break;
|
| -
|
| - end_box = end_box->PrevLeafChild();
|
| - }
|
| - }
|
| -
|
| - PositionTemplate<Strategy> pos;
|
| - if (isHTMLBRElement(*end_node)) {
|
| - pos = PositionTemplate<Strategy>::BeforeNode(end_node);
|
| - } else if (end_box->IsInlineTextBox() && end_node->IsTextNode()) {
|
| - InlineTextBox* end_text_box = ToInlineTextBox(end_box);
|
| - int end_offset = end_text_box->Start();
|
| - if (!end_text_box->IsLineBreak())
|
| - end_offset += end_text_box->Len();
|
| - pos = PositionTemplate<Strategy>(ToText(end_node), end_offset);
|
| - } else {
|
| - pos = PositionTemplate<Strategy>::AfterNode(end_node);
|
| - }
|
| -
|
| - return CreateVisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE);
|
| -}
|
| -
|
| -// TODO(yosin) Rename this function to reflect the fact it ignores bidi levels.
|
| -template <typename Strategy>
|
| -static VisiblePositionTemplate<Strategy> EndOfLineAlgorithm(
|
| - const VisiblePositionTemplate<Strategy>& current_position) {
|
| - DCHECK(current_position.IsValid()) << current_position;
|
| - // TODO(yosin) this is the current behavior that might need to be fixed.
|
| - // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail.
|
| - VisiblePositionTemplate<Strategy> vis_pos =
|
| - EndPositionForLine(current_position, kUseInlineBoxOrdering);
|
| -
|
| - // Make sure the end of line is at the same line as the given input
|
| - // position. Else use the previous position to obtain end of line. This
|
| - // condition happens when the input position is before the space character
|
| - // at the end of a soft-wrapped non-editable line. In this scenario,
|
| - // |endPositionForLine()| would incorrectly hand back a position in the next
|
| - // line instead. This fix is to account for the discrepancy between lines
|
| - // with "webkit-line-break:after-white-space" style versus lines without
|
| - // that style, which would break before a space by default.
|
| - if (!InSameLine(current_position, vis_pos)) {
|
| - vis_pos = PreviousPositionOf(current_position);
|
| - if (vis_pos.IsNull())
|
| - return VisiblePositionTemplate<Strategy>();
|
| - vis_pos = EndPositionForLine(vis_pos, kUseInlineBoxOrdering);
|
| - }
|
| -
|
| - return HonorEditingBoundaryAtOrAfter(vis_pos,
|
| - current_position.DeepEquivalent());
|
| -}
|
| -
|
| -// TODO(yosin) Rename this function to reflect the fact it ignores bidi levels.
|
| -VisiblePosition EndOfLine(const VisiblePosition& current_position) {
|
| - return EndOfLineAlgorithm<EditingStrategy>(current_position);
|
| -}
|
| -
|
| -VisiblePositionInFlatTree EndOfLine(
|
| - const VisiblePositionInFlatTree& current_position) {
|
| - return EndOfLineAlgorithm<EditingInFlatTreeStrategy>(current_position);
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -static bool InSameLogicalLine(const VisiblePositionTemplate<Strategy>& a,
|
| - const VisiblePositionTemplate<Strategy>& b) {
|
| - DCHECK(a.IsValid()) << a;
|
| - DCHECK(b.IsValid()) << b;
|
| - return a.IsNotNull() && LogicalStartOfLine(a).DeepEquivalent() ==
|
| - LogicalStartOfLine(b).DeepEquivalent();
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -VisiblePositionTemplate<Strategy> LogicalEndOfLineAlgorithm(
|
| - const VisiblePositionTemplate<Strategy>& current_position) {
|
| - DCHECK(current_position.IsValid()) << current_position;
|
| - // TODO(yosin) this is the current behavior that might need to be fixed.
|
| - // Please refer to https://bugs.webkit.org/show_bug.cgi?id=49107 for detail.
|
| - VisiblePositionTemplate<Strategy> vis_pos =
|
| - EndPositionForLine(current_position, kUseLogicalOrdering);
|
| -
|
| - // Make sure the end of line is at the same line as the given input
|
| - // position. For a wrapping line, the logical end position for the
|
| - // not-last-2-lines might incorrectly hand back the logical beginning of the
|
| - // next line. For example,
|
| - // <div contenteditable dir="rtl" style="line-break:before-white-space">xyz
|
| - // a xyz xyz xyz xyz xyz xyz xyz xyz xyz xyz </div>
|
| - // In this case, use the previous position of the computed logical end
|
| - // position.
|
| - if (!InSameLogicalLine(current_position, vis_pos))
|
| - vis_pos = PreviousPositionOf(vis_pos);
|
| -
|
| - if (ContainerNode* editable_root =
|
| - HighestEditableRoot(current_position.DeepEquivalent())) {
|
| - if (!editable_root->contains(
|
| - vis_pos.DeepEquivalent().ComputeContainerNode()))
|
| - return CreateVisiblePosition(
|
| - PositionTemplate<Strategy>::LastPositionInNode(editable_root));
|
| - }
|
| -
|
| - return HonorEditingBoundaryAtOrAfter(vis_pos,
|
| - current_position.DeepEquivalent());
|
| -}
|
| -
|
| -VisiblePosition LogicalEndOfLine(const VisiblePosition& current_position) {
|
| - return LogicalEndOfLineAlgorithm<EditingStrategy>(current_position);
|
| -}
|
| -
|
| -VisiblePositionInFlatTree LogicalEndOfLine(
|
| - const VisiblePositionInFlatTree& current_position) {
|
| - return LogicalEndOfLineAlgorithm<EditingInFlatTreeStrategy>(current_position);
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -bool InSameLineAlgorithm(
|
| - const PositionWithAffinityTemplate<Strategy>& position1,
|
| - const PositionWithAffinityTemplate<Strategy>& position2) {
|
| - if (position1.IsNull() || position2.IsNull())
|
| - return false;
|
| - DCHECK_EQ(position1.GetDocument(), position2.GetDocument());
|
| - DCHECK(!position1.GetDocument()->NeedsLayoutTreeUpdate());
|
| -
|
| - PositionWithAffinityTemplate<Strategy> start_of_line1 =
|
| - StartOfLine(position1);
|
| - PositionWithAffinityTemplate<Strategy> start_of_line2 =
|
| - StartOfLine(position2);
|
| - if (start_of_line1 == start_of_line2)
|
| - return true;
|
| - PositionTemplate<Strategy> canonicalized1 =
|
| - CanonicalPositionOf(start_of_line1.GetPosition());
|
| - if (canonicalized1 == start_of_line2.GetPosition())
|
| - return true;
|
| - return canonicalized1 == CanonicalPositionOf(start_of_line2.GetPosition());
|
| -}
|
| -
|
| -bool InSameLine(const PositionWithAffinity& a, const PositionWithAffinity& b) {
|
| - return InSameLineAlgorithm<EditingStrategy>(a, b);
|
| -}
|
| -
|
| -bool InSameLine(const PositionInFlatTreeWithAffinity& position1,
|
| - const PositionInFlatTreeWithAffinity& position2) {
|
| - return InSameLineAlgorithm<EditingInFlatTreeStrategy>(position1, position2);
|
| -}
|
| -
|
| -bool InSameLine(const VisiblePosition& position1,
|
| - const VisiblePosition& position2) {
|
| - DCHECK(position1.IsValid()) << position1;
|
| - DCHECK(position2.IsValid()) << position2;
|
| - return InSameLine(position1.ToPositionWithAffinity(),
|
| - position2.ToPositionWithAffinity());
|
| -}
|
| -
|
| -bool InSameLine(const VisiblePositionInFlatTree& position1,
|
| - const VisiblePositionInFlatTree& position2) {
|
| - DCHECK(position1.IsValid()) << position1;
|
| - DCHECK(position2.IsValid()) << position2;
|
| - return InSameLine(position1.ToPositionWithAffinity(),
|
| - position2.ToPositionWithAffinity());
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -bool IsStartOfLineAlgorithm(const VisiblePositionTemplate<Strategy>& p) {
|
| - DCHECK(p.IsValid()) << p;
|
| - return p.IsNotNull() && p.DeepEquivalent() == StartOfLine(p).DeepEquivalent();
|
| -}
|
| -
|
| -bool IsStartOfLine(const VisiblePosition& p) {
|
| - return IsStartOfLineAlgorithm<EditingStrategy>(p);
|
| -}
|
| -
|
| -bool IsStartOfLine(const VisiblePositionInFlatTree& p) {
|
| - return IsStartOfLineAlgorithm<EditingInFlatTreeStrategy>(p);
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -bool IsEndOfLineAlgorithm(const VisiblePositionTemplate<Strategy>& p) {
|
| - DCHECK(p.IsValid()) << p;
|
| - return p.IsNotNull() && p.DeepEquivalent() == EndOfLine(p).DeepEquivalent();
|
| -}
|
| -
|
| -bool IsEndOfLine(const VisiblePosition& p) {
|
| - return IsEndOfLineAlgorithm<EditingStrategy>(p);
|
| -}
|
| -
|
| -bool IsEndOfLine(const VisiblePositionInFlatTree& p) {
|
| - return IsEndOfLineAlgorithm<EditingInFlatTreeStrategy>(p);
|
| -}
|
| -
|
| -template <typename Strategy>
|
| -static bool IsLogicalEndOfLineAlgorithm(
|
| - const VisiblePositionTemplate<Strategy>& p) {
|
| - DCHECK(p.IsValid()) << p;
|
| - return p.IsNotNull() &&
|
| - p.DeepEquivalent() == LogicalEndOfLine(p).DeepEquivalent();
|
| -}
|
| -
|
| -bool IsLogicalEndOfLine(const VisiblePosition& p) {
|
| - return IsLogicalEndOfLineAlgorithm<EditingStrategy>(p);
|
| -}
|
| -
|
| -bool IsLogicalEndOfLine(const VisiblePositionInFlatTree& p) {
|
| - return IsLogicalEndOfLineAlgorithm<EditingInFlatTreeStrategy>(p);
|
| -}
|
| -
|
| -static inline LayoutPoint AbsoluteLineDirectionPointToLocalPointInBlock(
|
| - RootInlineBox* root,
|
| - LayoutUnit line_direction_point) {
|
| - DCHECK(root);
|
| - LineLayoutBlockFlow containing_block = root->Block();
|
| - FloatPoint absolute_block_point =
|
| - containing_block.LocalToAbsolute(FloatPoint());
|
| - if (containing_block.HasOverflowClip())
|
| - absolute_block_point -= FloatSize(containing_block.ScrolledContentOffset());
|
| -
|
| - if (root->Block().IsHorizontalWritingMode())
|
| - return LayoutPoint(
|
| - LayoutUnit(line_direction_point - absolute_block_point.X()),
|
| - root->BlockDirectionPointInLine());
|
| -
|
| - return LayoutPoint(
|
| - root->BlockDirectionPointInLine(),
|
| - LayoutUnit(line_direction_point - absolute_block_point.Y()));
|
| -}
|
| -
|
| -VisiblePosition PreviousLinePosition(const VisiblePosition& visible_position,
|
| - LayoutUnit line_direction_point,
|
| - EditableType editable_type) {
|
| - DCHECK(visible_position.IsValid()) << visible_position;
|
| -
|
| - Position p = visible_position.DeepEquivalent();
|
| - Node* node = p.AnchorNode();
|
| -
|
| - if (!node)
|
| - return VisiblePosition();
|
| -
|
| - LayoutObject* layout_object = node->GetLayoutObject();
|
| - if (!layout_object)
|
| - return VisiblePosition();
|
| -
|
| - RootInlineBox* root = 0;
|
| - InlineBox* box = ComputeInlineBoxPosition(visible_position).inline_box;
|
| - if (box) {
|
| - root = box->Root().PrevRootBox();
|
| - // We want to skip zero height boxes.
|
| - // This could happen in case it is a TrailingFloatsRootInlineBox.
|
| - if (!root || !root->LogicalHeight() || !root->FirstLeafChild())
|
| - root = 0;
|
| - }
|
| -
|
| - if (!root) {
|
| - Position position = PreviousRootInlineBoxCandidatePosition(
|
| - node, visible_position, editable_type);
|
| - if (position.IsNotNull()) {
|
| - RenderedPosition rendered_position((CreateVisiblePosition(position)));
|
| - root = rendered_position.RootBox();
|
| - if (!root)
|
| - return CreateVisiblePosition(position);
|
| - }
|
| - }
|
| -
|
| - if (root) {
|
| - // FIXME: Can be wrong for multi-column layout and with transforms.
|
| - LayoutPoint point_in_line = AbsoluteLineDirectionPointToLocalPointInBlock(
|
| - root, line_direction_point);
|
| - LineLayoutItem line_layout_item =
|
| - root->ClosestLeafChildForPoint(point_in_line, IsEditablePosition(p))
|
| - ->GetLineLayoutItem();
|
| - Node* node = line_layout_item.GetNode();
|
| - if (node && EditingIgnoresContent(*node))
|
| - return VisiblePosition::InParentBeforeNode(*node);
|
| - return CreateVisiblePosition(
|
| - line_layout_item.PositionForPoint(point_in_line));
|
| - }
|
| -
|
| - // Could not find a previous line. This means we must already be on the first
|
| - // line. Move to the start of the content in this block, which effectively
|
| - // moves us to the start of the line we're on.
|
| - Element* root_element = HasEditableStyle(*node, editable_type)
|
| - ? RootEditableElement(*node, editable_type)
|
| - : node->GetDocument().documentElement();
|
| - if (!root_element)
|
| - return VisiblePosition();
|
| - return VisiblePosition::FirstPositionInNode(root_element);
|
| -}
|
| -
|
| -VisiblePosition NextLinePosition(const VisiblePosition& visible_position,
|
| - LayoutUnit line_direction_point,
|
| - EditableType editable_type) {
|
| - DCHECK(visible_position.IsValid()) << visible_position;
|
| -
|
| - Position p = visible_position.DeepEquivalent();
|
| - Node* node = p.AnchorNode();
|
| -
|
| - if (!node)
|
| - return VisiblePosition();
|
| -
|
| - LayoutObject* layout_object = node->GetLayoutObject();
|
| - if (!layout_object)
|
| - return VisiblePosition();
|
| -
|
| - RootInlineBox* root = 0;
|
| - InlineBox* box = ComputeInlineBoxPosition(visible_position).inline_box;
|
| - if (box) {
|
| - root = box->Root().NextRootBox();
|
| - // We want to skip zero height boxes.
|
| - // This could happen in case it is a TrailingFloatsRootInlineBox.
|
| - if (!root || !root->LogicalHeight() || !root->FirstLeafChild())
|
| - root = 0;
|
| - }
|
| -
|
| - if (!root) {
|
| - // FIXME: We need do the same in previousLinePosition.
|
| - Node* child = NodeTraversal::ChildAt(*node, p.ComputeEditingOffset());
|
| - node = child ? child : &NodeTraversal::LastWithinOrSelf(*node);
|
| - Position position = NextRootInlineBoxCandidatePosition(
|
| - node, visible_position, editable_type);
|
| - if (position.IsNotNull()) {
|
| - RenderedPosition rendered_position((CreateVisiblePosition(position)));
|
| - root = rendered_position.RootBox();
|
| - if (!root)
|
| - return CreateVisiblePosition(position);
|
| - }
|
| - }
|
| -
|
| - if (root) {
|
| - // FIXME: Can be wrong for multi-column layout and with transforms.
|
| - LayoutPoint point_in_line = AbsoluteLineDirectionPointToLocalPointInBlock(
|
| - root, line_direction_point);
|
| - LineLayoutItem line_layout_item =
|
| - root->ClosestLeafChildForPoint(point_in_line, IsEditablePosition(p))
|
| - ->GetLineLayoutItem();
|
| - Node* node = line_layout_item.GetNode();
|
| - if (node && EditingIgnoresContent(*node))
|
| - return VisiblePosition::InParentBeforeNode(*node);
|
| - return CreateVisiblePosition(
|
| - line_layout_item.PositionForPoint(point_in_line));
|
| - }
|
| -
|
| - // Could not find a next line. This means we must already be on the last line.
|
| - // Move to the end of the content in this block, which effectively moves us
|
| - // to the end of the line we're on.
|
| - Element* root_element = HasEditableStyle(*node, editable_type)
|
| - ? RootEditableElement(*node, editable_type)
|
| - : node->GetDocument().documentElement();
|
| - if (!root_element)
|
| - return VisiblePosition();
|
| - return VisiblePosition::LastPositionInNode(root_element);
|
| -}
|
| -
|
| -// ---------
|
| -
|
| static unsigned StartSentenceBoundary(const UChar* characters,
|
| unsigned length,
|
| unsigned,
|
|
|