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

Unified Diff: third_party/WebKit/Source/core/editing/FrameCaret.cpp

Issue 2401363003: Use anchor node, rather than current selected node, to check editability. (Closed)
Patch Set: Feedback. 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/FrameCaret.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/editing/FrameCaret.cpp
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.cpp b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
index 33dc1ecb006e554d4b602e1264e03a285363d870..a192f9579ee168562f471020fb7081359a8b0421 100644
--- a/third_party/WebKit/Source/core/editing/FrameCaret.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
@@ -60,6 +60,7 @@ DEFINE_TRACE(FrameCaret) {
visitor->trace(m_selectionEditor);
visitor->trace(m_frame);
visitor->trace(m_previousCaretNode);
+ visitor->trace(m_previousCaretAnchorNode);
CaretBase::trace(visitor);
}
@@ -152,10 +153,22 @@ void FrameCaret::invalidateCaretRect(bool forceInvalidation) {
DCHECK(caretPositionIsValidForDocument(*m_frame->document()));
LayoutObject* layoutObject = nullptr;
LayoutRect newRect;
+ PositionWithAffinity currentCaretPosition = caretPosition();
if (isActive())
- newRect = localCaretRectOfPosition(caretPosition(), layoutObject);
+ newRect = localCaretRectOfPosition(currentCaretPosition, layoutObject);
Node* newNode = layoutObject ? layoutObject->node() : nullptr;
-
+ // The current selected node |newNode| could be a child multiple levels below
+ // its associated "anchor node" ancestor, so we reference and keep around the
+ // anchor node for checking editability.
+ // TODO(wkorman): Consider storing previous Position, rather than Node, and
+ // making use of EditingUtilies::isEditablePosition() directly.
+ Node* newAnchorNode =
yosin_UTC9 2016/10/13 03:58:47 I think we should use layout object associated Dis
+ currentCaretPosition.position().parentAnchoredEquivalent().anchorNode();
+ if (newNode && newAnchorNode && newNode != newAnchorNode &&
+ newAnchorNode->layoutObject() && newAnchorNode->layoutObject()->isBox()) {
+ newNode->layoutObject()->mapToVisualRectInAncestorSpace(
+ toLayoutBoxModelObject(newAnchorNode->layoutObject()), newRect);
+ }
// It's possible for the timer to be inactive even though we want to
// invalidate the caret. For example, when running as a layout test the
// caret blink interval could be zero and thus |m_caretBlinkTimer| will
@@ -167,11 +180,14 @@ void FrameCaret::invalidateCaretRect(bool forceInvalidation) {
m_caretVisibility == m_previousCaretVisibility)
return;
- if (m_previousCaretNode && shouldRepaintCaret(*m_previousCaretNode))
- invalidateLocalCaretRect(m_previousCaretNode.get(), m_previousCaretRect);
- if (newNode && shouldRepaintCaret(*newNode))
- invalidateLocalCaretRect(newNode, newRect);
+ if (m_previousCaretNode && shouldRepaintCaret(*m_previousCaretAnchorNode)) {
+ invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
+ m_previousCaretRect);
+ }
+ if (newNode && shouldRepaintCaret(*newAnchorNode))
+ invalidateLocalCaretRect(newAnchorNode, newRect);
m_previousCaretNode = newNode;
+ m_previousCaretAnchorNode = newAnchorNode;
m_previousCaretRect = newRect;
m_previousCaretVisibility = m_caretVisibility;
}
@@ -224,17 +240,20 @@ void FrameCaret::dataWillChange(const CharacterData& node) {
if (node == m_previousCaretNode) {
// This invalidation is eager, and intentionally uses stale state.
DisableCompositingQueryAsserts disabler;
- invalidateLocalCaretRect(m_previousCaretNode.get(), m_previousCaretRect);
+ invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
+ m_previousCaretRect);
}
}
void FrameCaret::nodeWillBeRemoved(Node& node) {
- if (node != m_previousCaretNode)
+ if (node != m_previousCaretNode && node != m_previousCaretAnchorNode)
return;
// Hits in ManualTests/caret-paint-after-last-text-is-removed.html
DisableCompositingQueryAsserts disabler;
- invalidateLocalCaretRect(m_previousCaretNode.get(), m_previousCaretRect);
+ invalidateLocalCaretRect(m_previousCaretAnchorNode.get(),
+ m_previousCaretRect);
m_previousCaretNode = nullptr;
+ m_previousCaretAnchorNode = nullptr;
m_previousCaretRect = LayoutRect();
m_previousCaretVisibility = CaretVisibility::Hidden;
}
@@ -242,6 +261,7 @@ void FrameCaret::nodeWillBeRemoved(Node& node) {
void FrameCaret::documentDetached() {
m_caretBlinkTimer.stop();
m_previousCaretNode.clear();
+ m_previousCaretAnchorNode.clear();
}
bool FrameCaret::shouldBlinkCaret() const {
@@ -268,4 +288,4 @@ void FrameCaret::caretBlinkTimerFired(TimerBase*) {
setCaretRectNeedsUpdate();
}
-} // nemaspace blink
+} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/editing/FrameCaret.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698