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

Unified Diff: Source/core/editing/FrameSelection.cpp

Issue 431983005: FrameSelection::updateApperance for caret should not cause layout. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Delay invalidation Created 6 years, 4 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
Index: Source/core/editing/FrameSelection.cpp
diff --git a/Source/core/editing/FrameSelection.cpp b/Source/core/editing/FrameSelection.cpp
index 677676fb2b75bde4fd555d637189b49b96fa3b15..5071069684c0edeae317e08d5aa352f55282e085 100644
--- a/Source/core/editing/FrameSelection.cpp
+++ b/Source/core/editing/FrameSelection.cpp
@@ -272,11 +272,9 @@ void FrameSelection::setSelection(const VisibleSelection& newSelection, SetSelec
setFocusedNodeIfNeeded();
if (!(options & DoNotUpdateAppearance)) {
- m_frame->document()->updateLayoutIgnorePendingStylesheets();
-
// Hits in compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html
DisableCompositingQueryAsserts disabler;
- updateAppearance();
+ updateAppearance(ResetCaretBlink);
}
// Always clear the x position used for vertical arrow navigation.
@@ -1233,14 +1231,16 @@ static bool isTextFormControl(const VisibleSelection& selection)
LayoutRect FrameSelection::localCaretRect()
{
if (shouldUpdateCaretRect()) {
- if (!isNonOrphanedCaret(m_selection))
+ if (!isNonOrphanedCaret(m_selection)) {
clearCaretRect();
- else if (isTextFormControl(m_selection))
- m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), PositionWithAffinity(m_selection.start().isCandidate() ? m_selection.start() : Position(), m_selection.affinity()));
- else
- m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), VisiblePosition(m_selection.start(), m_selection.affinity()));
+ } else {
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
+ if (isTextFormControl(m_selection))
+ m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), PositionWithAffinity(m_selection.start().isCandidate() ? m_selection.start() : Position(), m_selection.affinity()));
+ else
+ m_absCaretBoundsDirty |= updateCaretRect(m_frame->document(), VisiblePosition(m_selection.start(), m_selection.affinity()));
+ }
}
-
return localCaretRectWithoutUpdate();
}
@@ -1540,22 +1540,21 @@ inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame)
return frame->editor().lastEditCommand() && frame->editor().lastEditCommand()->shouldStopCaretBlinking();
}
-void FrameSelection::updateAppearance()
+void FrameSelection::updateAppearance(UpdateAppearanceOption option)
{
// Paint a block cursor instead of a caret in overtype mode unless the caret is at the end of a line (in this case
// the FrameSelection will paint a blinking caret as usual).
bool paintBlockCursor = m_shouldShowBlockCursor && m_selection.isCaret() && !isLogicalEndOfLine(m_selection.visibleEnd());
- bool caretRectChangedOrCleared = recomputeCaretRect();
bool shouldBlink = !paintBlockCursor && shouldBlinkCaret();
// If the caret moved, stop the blink timer so we can restart with a
// black caret in the new location.
- if (caretRectChangedOrCleared || !shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) {
+ if (option == ResetCaretBlink || !shouldBlink || shouldStopBlinkingDueToTypingCommand(m_frame)) {
m_caretBlinkTimer.stop();
if (!shouldBlink && m_caretPaint) {
m_caretPaint = false;
- invalidateCaretRect();
+ setCaretRectNeedsUpdate();
}
}
@@ -1567,18 +1566,28 @@ void FrameSelection::updateAppearance()
if (!m_caretPaint) {
m_caretPaint = true;
- invalidateCaretRect();
+ setCaretRectNeedsUpdate();
}
}
+ if (shouldUpdateCaretRect() && m_frame->page())
+ m_frame->page()->animator().scheduleVisualUpdate();
+
RenderView* view = m_frame->contentRenderer();
if (!view)
return;
// Construct a new VisibleSolution, since m_selection is not necessarily valid, and the following steps
// assume a valid selection. See <https://bugs.webkit.org/show_bug.cgi?id=69563> and <rdar://problem/10232866>.
- VisiblePosition endVisiblePosition = paintBlockCursor ? modifyExtendingForward(CharacterGranularity) : m_selection.visibleEnd();
- VisibleSelection selection(m_selection.visibleStart(), endVisiblePosition);
+
+ VisibleSelection selection;
+ if (isTextFormControl(m_selection)) {
+ Position endPosition = paintBlockCursor ? m_selection.extent().next() : m_selection.end();
+ selection.setWithoutValidation(m_selection.start(), endPosition);
+ } else {
+ VisiblePosition endVisiblePosition = paintBlockCursor ? modifyExtendingForward(CharacterGranularity) : m_selection.visibleEnd();
+ selection = VisibleSelection(m_selection.visibleStart(), endVisiblePosition);
+ }
if (!selection.isRange()) {
view->clearSelection();
@@ -1649,13 +1658,13 @@ void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*)
if (isCaretBlinkingSuspended() && m_caretPaint)
return;
m_caretPaint = !m_caretPaint;
- invalidateCaretRect();
+ setCaretRectNeedsUpdate();
+ if (Page* page = m_frame->page())
+ page->animator().scheduleVisualUpdate();
}
void FrameSelection::notifyRendererOfSelectionChange(EUserTriggered userTriggered)
{
- m_frame->document()->updateRenderTreeIfNeeded();
-
if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start()))
textControl->selectionChanged(userTriggered == UserTriggered);
}

Powered by Google App Engine
This is Rietveld 408576698