| Index: third_party/WebKit/Source/core/editing/EditingUtilities.cpp
|
| diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
|
| index 06aaa453dd6da77b4e21bf6ee1706d60941ce1b8..4674b69cea107b7895200b7857cf66dcbe401b54 100644
|
| --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
|
| +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
|
| @@ -44,6 +44,7 @@
|
| #include "core/editing/state_machines/BackspaceStateMachine.h"
|
| #include "core/editing/state_machines/BackwardGraphemeBoundaryStateMachine.h"
|
| #include "core/editing/state_machines/ForwardGraphemeBoundaryStateMachine.h"
|
| +#include "core/frame/FrameView.h"
|
| #include "core/frame/LocalFrame.h"
|
| #include "core/frame/UseCounter.h"
|
| #include "core/html/HTMLBRElement.h"
|
| @@ -65,6 +66,7 @@ namespace blink {
|
| using namespace HTMLNames;
|
|
|
| namespace {
|
| +
|
| std::ostream& operator<<(std::ostream& os, PositionMoveType type)
|
| {
|
| static const char* const texts[] = {
|
| @@ -75,8 +77,27 @@ std::ostream& operator<<(std::ostream& os, PositionMoveType type)
|
| DCHECK_LT(it, std::end(texts)) << "Unknown PositionMoveType value";
|
| return os << *it;
|
| }
|
| +
|
| } // namespace
|
|
|
| +bool needsLayoutTreeUpdate(const Node& node)
|
| +{
|
| + const Document& document = node.document();
|
| + if (document.needsLayoutTreeUpdate())
|
| + return true;
|
| + // TODO(yosin): We should make |document::needsLayoutTreeUpdate()| to
|
| + // check |LayoutView::needsLayout()|.
|
| + return document.view() && document.view()->needsLayout();
|
| +}
|
| +
|
| +bool needsLayoutTreeUpdate(const Position& position)
|
| +{
|
| + const Node* node = position.anchorNode();
|
| + if (!node)
|
| + return false;
|
| + return needsLayoutTreeUpdate(*node);
|
| +}
|
| +
|
| // Atomic means that the node has no children, or has children which are ignored for the
|
| // purposes of editing.
|
| bool isAtomicNode(const Node *node)
|
| @@ -262,15 +283,19 @@ ContainerNode* highestEditableRoot(const PositionInFlatTree& position, EditableT
|
| return highestEditableRoot(toPositionInDOMTree(position), editableType);
|
| }
|
|
|
| -bool isEditablePosition(const Position& p, EditableType editableType, EUpdateStyle updateStyle)
|
| +bool isEditablePosition(const Position& position, EditableType editableType)
|
| {
|
| - Node* node = p.parentAnchoredEquivalent().anchorNode();
|
| + Node* node = position.parentAnchoredEquivalent().anchorNode();
|
| if (!node)
|
| return false;
|
| - if (updateStyle == UpdateStyle)
|
| - node->document().updateStyleAndLayoutIgnorePendingStylesheets();
|
| - else
|
| - DCHECK_EQ(updateStyle, DoNotUpdateStyle);
|
| + DCHECK(node->document().isActive());
|
| + if (node->document().lifecycle().state() >= DocumentLifecycle::InStyleRecalc) {
|
| + // TODO(yosin): Once we change |LayoutObject::adjustStyleDifference()|
|
| + // not to call |FrameSelection::hasCaret()|, we should not assume
|
| + // calling |isEditablePosition()| in |InStyleRecalc| is safe.
|
| + } else {
|
| + DCHECK(!needsLayoutTreeUpdate(position)) << position;
|
| + }
|
|
|
| if (isDisplayInsideTable(node))
|
| node = node->parentNode();
|
| @@ -280,9 +305,9 @@ bool isEditablePosition(const Position& p, EditableType editableType, EUpdateSty
|
| return node->hasEditableStyle(editableType);
|
| }
|
|
|
| -bool isEditablePosition(const PositionInFlatTree& p, EditableType editableType, EUpdateStyle updateStyle)
|
| +bool isEditablePosition(const PositionInFlatTree& p, EditableType editableType)
|
| {
|
| - return isEditablePosition(toPositionInDOMTree(p), editableType, updateStyle);
|
| + return isEditablePosition(toPositionInDOMTree(p), editableType);
|
| }
|
|
|
| bool isAtUnsplittableElement(const Position& pos)
|
| @@ -481,6 +506,7 @@ VisiblePositionInFlatTree firstEditableVisiblePositionAfterPositionInRoot(const
|
| template <typename Strategy>
|
| PositionTemplate<Strategy> firstEditablePositionAfterPositionInRootAlgorithm(const PositionTemplate<Strategy>& position, Node& highestRoot)
|
| {
|
| + DCHECK(!needsLayoutTreeUpdate(highestRoot)) << position << ' ' << highestRoot;
|
| // position falls before highestRoot.
|
| if (position.compareTo(PositionTemplate<Strategy>::firstPositionInNode(&highestRoot)) == -1 && highestRoot.hasEditableStyle())
|
| return PositionTemplate<Strategy>::firstPositionInNode(&highestRoot);
|
| @@ -527,6 +553,7 @@ VisiblePositionInFlatTree lastEditableVisiblePositionBeforePositionInRoot(const
|
| template <typename Strategy>
|
| PositionTemplate<Strategy> lastEditablePositionBeforePositionInRootAlgorithm(const PositionTemplate<Strategy>& position, Node& highestRoot)
|
| {
|
| + DCHECK(!needsLayoutTreeUpdate(highestRoot)) << position << ' ' << highestRoot;
|
| // When position falls after highestRoot, the result is easy to compute.
|
| if (position.compareTo(PositionTemplate<Strategy>::lastPositionInNode(&highestRoot)) == 1)
|
| return PositionTemplate<Strategy>::lastPositionInNode(&highestRoot);
|
| @@ -1417,7 +1444,7 @@ static Position previousCharacterPosition(const Position& position, TextAffinity
|
| // This assumes that it starts in editable content.
|
| Position leadingWhitespacePosition(const Position& position, TextAffinity affinity, WhitespacePositionOption option)
|
| {
|
| - DCHECK(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)) << position;
|
| + DCHECK(isEditablePosition(position, ContentIsEditable)) << position;
|
| if (position.isNull())
|
| return Position();
|
|
|
| @@ -1445,7 +1472,7 @@ Position leadingWhitespacePosition(const Position& position, TextAffinity affini
|
| // This assumes that it starts in editable content.
|
| Position trailingWhitespacePosition(const Position& position, TextAffinity, WhitespacePositionOption option)
|
| {
|
| - DCHECK(isEditablePosition(position, ContentIsEditable, DoNotUpdateStyle)) << position;
|
| + DCHECK(isEditablePosition(position, ContentIsEditable)) << position;
|
| if (position.isNull())
|
| return Position();
|
|
|
|
|