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