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); |
} |