Commit 6f560bfd authored by yosin@chromium.org's avatar yosin@chromium.org

Move isVisuallyEquivalentCandidate() to VisibleUnits.{cpp,h} from Position.{cpp,h}

This patch moves |isVisuallyEquivalentCandidate()| to "VisibleUnits.{cpp,h} from
"Position.{cpp,h}" to consolidate |InlineBox| dependency to "VisibleUnits.cpp"
for ease of working them later.

This patch also gets rid of unused include directives from "Position.cpp".

BUG=518738
TEST=n/a; no behavior changes

Review URL: https://codereview.chromium.org/1304063002

git-svn-id: svn://svn.chromium.org/blink/trunk@200971 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 86b71ef1
...@@ -26,19 +26,11 @@ ...@@ -26,19 +26,11 @@
#include "config.h" #include "config.h"
#include "core/editing/Position.h" #include "core/editing/Position.h"
#include "core/HTMLNames.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ElementShadow.h" #include "core/dom/shadow/ElementShadow.h"
#include "core/editing/EditingUtilities.h" #include "core/editing/EditingUtilities.h"
#include "core/editing/PositionIterator.h" #include "core/editing/PositionIterator.h"
#include "core/editing/TextAffinity.h" #include "core/editing/TextAffinity.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h" #include "core/editing/VisibleUnits.h"
#include "core/editing/iterators/TextIterator.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLTableElement.h"
#include "core/layout/LayoutBlock.h" #include "core/layout/LayoutBlock.h"
#include "core/layout/LayoutInline.h" #include "core/layout/LayoutInline.h"
#include "core/layout/LayoutText.h" #include "core/layout/LayoutText.h"
...@@ -48,8 +40,6 @@ ...@@ -48,8 +40,6 @@
namespace blink { namespace blink {
using namespace HTMLNames;
#if ENABLE(ASSERT) #if ENABLE(ASSERT)
static bool canBeAnchorNode(Node* node) static bool canBeAnchorNode(Node* node)
{ {
...@@ -438,30 +428,6 @@ bool PositionAlgorithm<Strategy>::atLastEditingPositionForNode() const ...@@ -438,30 +428,6 @@ bool PositionAlgorithm<Strategy>::atLastEditingPositionForNode() const
return isAfterAnchorOrAfterChildren() || m_offset >= EditingStrategy::lastOffsetForEditing(anchorNode()); return isAfterAnchorOrAfterChildren() || m_offset >= EditingStrategy::lastOffsetForEditing(anchorNode());
} }
// Returns true if the visually equivalent positions around have different
// editability. A position is considered at editing boundary if one of the
// following is true:
// 1. It is the first position in the node and the next visually equivalent
// position is non editable.
// 2. It is the last position in the node and the previous visually equivalent
// position is non editable.
// 3. It is an editable position and both the next and previous visually
// equivalent positions are both non editable.
template <typename Strategy>
static bool atEditingBoundary(const PositionAlgorithm<Strategy> positions)
{
PositionAlgorithm<Strategy> nextPosition = positions.downstream(CanCrossEditingBoundary);
if (positions.atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.anchorNode()->hasEditableStyle())
return true;
PositionAlgorithm<Strategy> prevPosition = positions.upstream(CanCrossEditingBoundary);
if (positions.atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.anchorNode()->hasEditableStyle())
return true;
return nextPosition.isNotNull() && !nextPosition.anchorNode()->hasEditableStyle()
&& prevPosition.isNotNull() && !prevPosition.anchorNode()->hasEditableStyle();
}
template <typename Strategy> template <typename Strategy>
bool PositionAlgorithm<Strategy>::atStartOfTree() const bool PositionAlgorithm<Strategy>::atStartOfTree() const
{ {
...@@ -492,74 +458,6 @@ PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::downstream(EditingBound ...@@ -492,74 +458,6 @@ PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::downstream(EditingBound
return mostBackwardCaretPosition(*this, rule); return mostBackwardCaretPosition(*this, rule);
} }
// TODO(yosin) We should move |isVisuallyEquivalentCandidate()| to
// "VisibleUnits.cpp" to reduce |LayoutObject| dependency in "Position.cpp".
template <typename Strategy>
static bool isVisuallyEquivalentCandidateAlgorithm(const PositionAlgorithm<Strategy>& position)
{
Node* const anchorNode = position.anchorNode();
if (!anchorNode)
return false;
LayoutObject* layoutObject = anchorNode->layoutObject();
if (!layoutObject)
return false;
if (layoutObject->style()->visibility() != VISIBLE)
return false;
if (layoutObject->isBR()) {
// TODO(leviw) The condition should be
// m_anchorType == PositionAnchorType::BeforeAnchor, but for now we
// still need to support legacy positions.
if (position.isAfterAnchor())
return false;
return !position.computeEditingOffset() && !nodeIsUserSelectNone(Strategy::parent(*anchorNode));
}
if (layoutObject->isText())
return !nodeIsUserSelectNone(anchorNode) && inRenderedText(position);
if (layoutObject->isSVG()) {
// We don't consider SVG elements are contenteditable except for
// associated |layoutObject| returns |isText()| true,
// e.g. |LayoutSVGInlineText|.
return false;
}
if (isRenderedHTMLTableElement(anchorNode) || Strategy::editingIgnoresContent(anchorNode))
return (position.atFirstEditingPositionForNode() || position.atLastEditingPositionForNode()) && !nodeIsUserSelectNone(Strategy::parent(*anchorNode));
if (isHTMLHtmlElement(*anchorNode))
return false;
if (layoutObject->isLayoutBlockFlow() || layoutObject->isFlexibleBox() || layoutObject->isLayoutGrid()) {
if (toLayoutBlock(layoutObject)->logicalHeight() || isHTMLBodyElement(*anchorNode)) {
if (!hasRenderedNonAnonymousDescendantsWithHeight(layoutObject))
return position.atFirstEditingPositionForNode() && !nodeIsUserSelectNone(anchorNode);
return anchorNode->hasEditableStyle() && !nodeIsUserSelectNone(anchorNode) && atEditingBoundary(position);
}
} else {
LocalFrame* frame = anchorNode->document().frame();
bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
return (caretBrowsing || anchorNode->hasEditableStyle()) && !nodeIsUserSelectNone(anchorNode) && atEditingBoundary(position);
}
return false;
}
// TODO(yosin) We should move |inRenderedText()| to "VisibleUnits.h" for
// reduce dependency of |LayoutObject| in |Position| class.
bool isVisuallyEquivalentCandidate(const Position& position)
{
return isVisuallyEquivalentCandidateAlgorithm<EditingStrategy>(position);
}
bool isVisuallyEquivalentCandidate(const PositionInComposedTree& position)
{
return isVisuallyEquivalentCandidateAlgorithm<EditingInComposedTreeStrategy>(position);
}
template <typename Strategy> template <typename Strategy>
static bool inRenderedTextAlgorithm(const PositionAlgorithm<Strategy>& position) static bool inRenderedTextAlgorithm(const PositionAlgorithm<Strategy>& position)
{ {
......
...@@ -415,11 +415,6 @@ CORE_EXPORT bool inRenderedText(const PositionInComposedTree&); ...@@ -415,11 +415,6 @@ CORE_EXPORT bool inRenderedText(const PositionInComposedTree&);
CORE_EXPORT int uncheckedPreviousOffset(const Node*, int current); CORE_EXPORT int uncheckedPreviousOffset(const Node*, int current);
CORE_EXPORT int uncheckedNextOffset(const Node*, int current); CORE_EXPORT int uncheckedNextOffset(const Node*, int current);
// TODO(yosin) We should move |isVisuallyEquivalentCandidate()| to
// "VisibleUnits.cpp" to reduce |LayoutObject| dependency in "Position.cpp".
CORE_EXPORT bool isVisuallyEquivalentCandidate(const Position&);
CORE_EXPORT bool isVisuallyEquivalentCandidate(const PositionInComposedTree&);
} // namespace blink } // namespace blink
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#include "core/editing/iterators/CharacterIterator.h" #include "core/editing/iterators/CharacterIterator.h"
#include "core/editing/iterators/SimplifiedBackwardsTextIterator.h" #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h"
#include "core/editing/iterators/TextIterator.h" #include "core/editing/iterators/TextIterator.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLBRElement.h" #include "core/html/HTMLBRElement.h"
#include "core/layout/HitTestRequest.h" #include "core/layout/HitTestRequest.h"
#include "core/layout/HitTestResult.h" #include "core/layout/HitTestResult.h"
...@@ -2207,4 +2209,92 @@ PositionInComposedTree mostBackwardCaretPosition(const PositionInComposedTree& p ...@@ -2207,4 +2209,92 @@ PositionInComposedTree mostBackwardCaretPosition(const PositionInComposedTree& p
return mostBackwardCaretPosition<EditingInComposedTreeStrategy>(position, rule); return mostBackwardCaretPosition<EditingInComposedTreeStrategy>(position, rule);
} }
// Returns true if the visually equivalent positions around have different
// editability. A position is considered at editing boundary if one of the
// following is true:
// 1. It is the first position in the node and the next visually equivalent
// position is non editable.
// 2. It is the last position in the node and the previous visually equivalent
// position is non editable.
// 3. It is an editable position and both the next and previous visually
// equivalent positions are both non editable.
template <typename Strategy>
static bool atEditingBoundary(const PositionAlgorithm<Strategy> positions)
{
PositionAlgorithm<Strategy> nextPosition = positions.downstream(CanCrossEditingBoundary);
if (positions.atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosition.anchorNode()->hasEditableStyle())
return true;
PositionAlgorithm<Strategy> prevPosition = positions.upstream(CanCrossEditingBoundary);
if (positions.atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosition.anchorNode()->hasEditableStyle())
return true;
return nextPosition.isNotNull() && !nextPosition.anchorNode()->hasEditableStyle()
&& prevPosition.isNotNull() && !prevPosition.anchorNode()->hasEditableStyle();
} }
template <typename Strategy>
static bool isVisuallyEquivalentCandidateAlgorithm(const PositionAlgorithm<Strategy>& position)
{
Node* const anchorNode = position.anchorNode();
if (!anchorNode)
return false;
LayoutObject* layoutObject = anchorNode->layoutObject();
if (!layoutObject)
return false;
if (layoutObject->style()->visibility() != VISIBLE)
return false;
if (layoutObject->isBR()) {
// TODO(leviw) The condition should be
// m_anchorType == PositionAnchorType::BeforeAnchor, but for now we
// still need to support legacy positions.
if (position.isAfterAnchor())
return false;
return !position.computeEditingOffset() && !nodeIsUserSelectNone(Strategy::parent(*anchorNode));
}
if (layoutObject->isText())
return !nodeIsUserSelectNone(anchorNode) && inRenderedText(position);
if (layoutObject->isSVG()) {
// We don't consider SVG elements are contenteditable except for
// associated |layoutObject| returns |isText()| true,
// e.g. |LayoutSVGInlineText|.
return false;
}
if (isRenderedHTMLTableElement(anchorNode) || Strategy::editingIgnoresContent(anchorNode))
return (position.atFirstEditingPositionForNode() || position.atLastEditingPositionForNode()) && !nodeIsUserSelectNone(Strategy::parent(*anchorNode));
if (isHTMLHtmlElement(*anchorNode))
return false;
if (layoutObject->isLayoutBlockFlow() || layoutObject->isFlexibleBox() || layoutObject->isLayoutGrid()) {
if (toLayoutBlock(layoutObject)->logicalHeight() || isHTMLBodyElement(*anchorNode)) {
if (!hasRenderedNonAnonymousDescendantsWithHeight(layoutObject))
return position.atFirstEditingPositionForNode() && !nodeIsUserSelectNone(anchorNode);
return anchorNode->hasEditableStyle() && !nodeIsUserSelectNone(anchorNode) && atEditingBoundary(position);
}
} else {
LocalFrame* frame = anchorNode->document().frame();
bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
return (caretBrowsing || anchorNode->hasEditableStyle()) && !nodeIsUserSelectNone(anchorNode) && atEditingBoundary(position);
}
return false;
}
bool isVisuallyEquivalentCandidate(const Position& position)
{
return isVisuallyEquivalentCandidateAlgorithm<EditingStrategy>(position);
}
bool isVisuallyEquivalentCandidate(const PositionInComposedTree& position)
{
return isVisuallyEquivalentCandidateAlgorithm<EditingInComposedTreeStrategy>(position);
}
} // namespace blink
...@@ -82,6 +82,9 @@ CORE_EXPORT PositionInComposedTree mostForwardCaretPosition(const PositionInComp ...@@ -82,6 +82,9 @@ CORE_EXPORT PositionInComposedTree mostForwardCaretPosition(const PositionInComp
CORE_EXPORT Position mostBackwardCaretPosition(const Position &, EditingBoundaryCrossingRule = CannotCrossEditingBoundary); CORE_EXPORT Position mostBackwardCaretPosition(const Position &, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
CORE_EXPORT PositionInComposedTree mostBackwardCaretPosition(const PositionInComposedTree &, EditingBoundaryCrossingRule = CannotCrossEditingBoundary); CORE_EXPORT PositionInComposedTree mostBackwardCaretPosition(const PositionInComposedTree &, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
CORE_EXPORT bool isVisuallyEquivalentCandidate(const Position&);
CORE_EXPORT bool isVisuallyEquivalentCandidate(const PositionInComposedTree&);
// words // words
CORE_EXPORT VisiblePosition startOfWord(const VisiblePosition &, EWordSide = RightWordIfOnBoundary); CORE_EXPORT VisiblePosition startOfWord(const VisiblePosition &, EWordSide = RightWordIfOnBoundary);
CORE_EXPORT VisiblePosition endOfWord(const VisiblePosition &, EWordSide = RightWordIfOnBoundary); CORE_EXPORT VisiblePosition endOfWord(const VisiblePosition &, EWordSide = RightWordIfOnBoundary);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment