Diff
Modified: trunk/LayoutTests/ChangeLog (164400 => 164401)
--- trunk/LayoutTests/ChangeLog 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/ChangeLog 2014-02-20 00:12:59 UTC (rev 164401)
@@ -1,3 +1,30 @@
+2014-02-18 Ryosuke Niwa <[email protected]>
+
+ Changing selection shouldn't synchronously update editor UI components
+ https://bugs.webkit.org/show_bug.cgi?id=129024
+
+ Reviewed by Brent Fulgham.
+
+ Many tests now calls internals.updateEditorUINowIfScheduled() to update the spellchecker states, and uses
+ setTimeout() to make things testable in the browser.
+
+ * editing/spelling/script-tests/spelling-backspace-between-lines.js:
+ (testTwoLinesMisspellings): Uses updateEditorUINowIfScheduled and setTimeout to make spellchecker recognize
+ two selection changes. This is okay since the user never moves selection multiple times in a single task.
+ * editing/spelling/spellcheck-attribute.html: Ditto.
+
+ * platform/mac/editing/deleting/deletionUI-click-on-delete-button.html: Use intenals.findEditingDeleteButton
+ which updates delete button controller states synchronously instead of getElementById which doesn't do that.
+ * platform/mac/editing/deleting/id-in-deletebutton-expected.txt:
+ * platform/mac/editing/deleting/id-in-deletebutton.html: Ditto. Also did some cleanups.
+ * platform/mac/editing/deleting/resources/deletionUI-helpers.js:
+ (deletionUIDeleteButtonForElement): Ditto.
+
+ * platform/mac/editing/spelling/editing-word-with-marker-1.html: Again, we must notify the spellchecker
+ synchronously here because we're expecting spellchecker to use the old selection set by setSelectionRange
+ in Editor::editorUIUpdateTimerFired triggered by the pasting command. This is, again, not a problem in
+ practice since user never pastes content synchronously after changing selection like this in a single task.
+
2014-02-19 Brent Fulgham <[email protected]>
Another Windows update to quiet the bots.
Modified: trunk/LayoutTests/editing/spelling/script-tests/spelling-backspace-between-lines.js (164400 => 164401)
--- trunk/LayoutTests/editing/spelling/script-tests/spelling-backspace-between-lines.js 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/editing/spelling/script-tests/spelling-backspace-between-lines.js 2014-02-20 00:12:59 UTC (rev 164401)
@@ -33,15 +33,19 @@
window.sel = setup("target1"); // ^OK
sel.modify("move", "forward", "line"); // ^OK zz OK
- for (var i = 0; i < 3; i++)
- sel.modify("move", "forward", "word");
+ if (window.internals)
+ internals.updateEditorUINowIfScheduled();
+ setTimeout(function () {
+ for (var i = 0; i < 3; i++)
+ sel.modify("move", "forward", "word");
- shouldBeEqualToString("firstLineText('target1')", "OK");
- shouldBeEqualToString("sel.anchorNode.data", "OK zz OK");
- if (window.internals)
- shouldBecomeEqual("internals.hasSpellingMarker(3, 2)", "true", done);
- else
- done();
+ shouldBeEqualToString("firstLineText('target1')", "OK");
+ shouldBeEqualToString("sel.anchorNode.data", "OK zz OK");
+ if (window.internals)
+ shouldBecomeEqual("internals.hasSpellingMarker(3, 2)", "true", done);
+ else
+ done();
+ }, 100);
}
function testMisspellingsAfterLineMergeUsingDelete()
Modified: trunk/LayoutTests/editing/spelling/spellcheck-attribute.html (164400 => 164401)
--- trunk/LayoutTests/editing/spelling/spellcheck-attribute.html 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/editing/spelling/spellcheck-attribute.html 2014-02-20 00:12:59 UTC (rev 164401)
@@ -48,14 +48,18 @@
var input = addInputElement(parentId, id, type, spellcheck);
input.focus();
// Activate spellchecking.
- moveSelectionForwardByWordCommand();
+ if (window.internals)
+ internals.updateEditorUINowIfScheduled();
+ setTimeout(function () {
+ moveSelectionForwardByWordCommand();
- logMarkup(id, spellcheck, true);
+ logMarkup(id, spellcheck, true);
- if (window.internals)
- shouldBecomeEqual('internals.hasSpellingMarker(0, 2)', shouldBeMisspelled ? 'true' : 'false', done);
- else
- done();
+ if (window.internals)
+ shouldBecomeEqual('internals.hasSpellingMarker(0, 2)', shouldBeMisspelled ? 'true' : 'false', done);
+ else
+ done();
+ }, 10);
}
function logMarkup(id, spellcheckValue, shouldCloseTag)
Modified: trunk/LayoutTests/platform/mac/editing/deleting/deletionUI-click-on-delete-button.html (164400 => 164401)
--- trunk/LayoutTests/platform/mac/editing/deleting/deletionUI-click-on-delete-button.html 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/platform/mac/editing/deleting/deletionUI-click-on-delete-button.html 2014-02-20 00:12:59 UTC (rev 164401)
@@ -14,13 +14,13 @@
sel.setPosition(li, 0);
if (window.testRunner) {
- deleteButton = document.getElementById("WebKit-Editing-Delete-Button");
+ deleteButton = internals.findEditingDeleteButton();
x = deleteButton.offsetParent.offsetLeft + deleteButton.offsetParent.offsetParent.offsetLeft + deleteButton.offsetLeft + deleteButton.offsetWidth / 2;
y = deleteButton.offsetParent.offsetTop + deleteButton.offsetParent.offsetParent.offsetTop + deleteButton.offsetTop + deleteButton.offsetHeight / 2;
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.mouseUp();
- deleteButton = document.getElementById("WebKit-Editing-Delete-Button");
+ deleteButton = internals.findEditingDeleteButton();
testContainer = document.getElementById("test");
Markup.description("There should be no visible content in the markup below. This test is for a bug where the delete button wouldn't work because it had -webkit-user-select:none instead of -webkit-user-select:ignore.");
if (deleteButton)
Modified: trunk/LayoutTests/platform/mac/editing/deleting/id-in-deletebutton-expected.txt (164400 => 164401)
--- trunk/LayoutTests/platform/mac/editing/deleting/id-in-deletebutton-expected.txt 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/platform/mac/editing/deleting/id-in-deletebutton-expected.txt 2014-02-20 00:12:59 UTC (rev 164401)
@@ -3,7 +3,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS deleteButton is non-null.
+PASS internals.findEditingDeleteButton(); document.getElementById("WebKit-Editing-Delete-Button") is non-null.
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/platform/mac/editing/deleting/id-in-deletebutton.html (164400 => 164401)
--- trunk/LayoutTests/platform/mac/editing/deleting/id-in-deletebutton.html 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/platform/mac/editing/deleting/id-in-deletebutton.html 2014-02-20 00:12:59 UTC (rev 164401)
@@ -1,12 +1,8 @@
<html>
-<head>
-<script src=""
-</head>
<body>
-
<div contenteditable="true">
<ul class="needsDeletionUI"><li>1</li><li id="li">2</li></ul>
-
+<script src=""
<script>
description('Test document.getElementById("WebKit-Editing-Delete-Button")');
@@ -14,10 +10,11 @@
li = document.getElementById("li");
sel.setPosition(li, 0);
-if (window.testRunner) {
- deleteButton = document.getElementById("WebKit-Editing-Delete-Button");
- shouldBeNonNull('deleteButton');
-}
+if (window.testRunner)
+ shouldBeNonNull('internals.findEditingDeleteButton(); document.getElementById("WebKit-Editing-Delete-Button")');
+
+var successfullyParsed = true;
+
</script>
<script src=""
</body>
Modified: trunk/LayoutTests/platform/mac/editing/deleting/resources/deletionUI-helpers.js (164400 => 164401)
--- trunk/LayoutTests/platform/mac/editing/deleting/resources/deletionUI-helpers.js 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/platform/mac/editing/deleting/resources/deletionUI-helpers.js 2014-02-20 00:12:59 UTC (rev 164401)
@@ -10,11 +10,12 @@
function deletionUIDeleteButtonForElement(id)
{
+ if (!window.internals)
+ return null;
var sel = window.getSelection();
var selElement = document.getElementById(id);
sel.setPosition(selElement, 0);
- var deleteButton = document.getElementById("WebKit-Editing-Delete-Button");
- return deleteButton;
+ return internals.findEditingDeleteButton();
}
function determineDeletionUIExistence(id)
Modified: trunk/LayoutTests/platform/mac/editing/spelling/editing-word-with-marker-1.html (164400 => 164401)
--- trunk/LayoutTests/platform/mac/editing/spelling/editing-word-with-marker-1.html 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/LayoutTests/platform/mac/editing/spelling/editing-word-with-marker-1.html 2014-02-20 00:12:59 UTC (rev 164401)
@@ -148,6 +148,8 @@
textarea.setSelectionRange(0,4);
execCopyCommand();
textarea.setSelectionRange(15, 15);
+if (window.internals)
+ internals.updateEditorUINowIfScheduled();
execPasteCommand();
if (window.internals && window.internals.hasSpellingMarker) {
if (window.internals.hasSpellingMarker(7,8) == 0) {
Modified: trunk/Source/WebCore/ChangeLog (164400 => 164401)
--- trunk/Source/WebCore/ChangeLog 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/ChangeLog 2014-02-20 00:12:59 UTC (rev 164401)
@@ -1,3 +1,49 @@
+2014-02-18 Ryosuke Niwa <[email protected]>
+
+ Changing selection shouldn't synchronously update editor UI components
+ https://bugs.webkit.org/show_bug.cgi?id=129024
+
+ Reviewed by Brent Fulgham.
+
+ Make updates to spellchecker, alternative text controller (correction pane), and delete button controller
+ asynchronous for programmatically triggered selection changes.
+
+ We continue to update their states synchronously immediately after we have applied, unapplied, or reapplied
+ editing commands to keep states in spell checker and alternative text controller consistent. We should be
+ able to make them asynchronous as well in the future but that should be done in a separate patch.
+
+ * WebCore.exp.in:
+ * editing/AlternativeTextController.cpp:
+ (WebCore::AlternativeTextController::respondToChangedSelection): This function used to enumerate all document
+ makers and call respondToMarkerAtEndOfWord on each one of them only to exit early when SetSelectionOptions
+ had DictationTriggered. This condition is now checked in Editor::respondToChangedSelection to avoid all the
+ unnecessary work and remove the dependency on SetSelectionOptions.
+ (WebCore::AlternativeTextController::respondToMarkerAtEndOfWord): Ditto.
+ * editing/AlternativeTextController.h:
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::appliedEditing): Calls updateEditorUINowIfScheduled before calling respondToAppliedEditing
+ on the alternative text controller.
+ (WebCore::Editor::unappliedEditing): Ditto.
+ (WebCore::Editor::reappliedEditing): Ditto.
+ (WebCore::Editor::Editor): Initializes newly added booleans.
+ (WebCore::Editor::respondToChangedSelection): Continue to call respondToChangedSelection (for API consistency)
+ and setStartNewKillRingSequence but defer the "editor UI updates" to spellchecker, alternative text controller
+ and delete button controller by firing a newly added one shot timer.
+ (WebCore::Editor::updateEditorUINowIfScheduled): Synchronously update the pending editor UI updates.
+ (WebCore::Editor::editorUIUpdateTimerFired): Extracted from respondToChangedSelection.
+ * editing/Editor.h:
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::markerCountForNode): Calls updateEditorUINowIfScheduled() to update document markers.
+ (WebCore::Internals::markerAt): Ditto.
+ (WebCore::Internals::updateEditorUINowIfScheduled): Added.
+ (WebCore::Internals::findEditingDeleteButton): Added. Updates delete button controller synchronously.
+ (WebCore::Internals::hasSpellingMarker): Calls updateEditorUINowIfScheduled() to update document markers.
+ (WebCore::Internals::hasAutocorrectedMarker): Ditto.
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2014-02-19 Anders Carlsson <[email protected]>
Add WTF_MAKE_FAST_ALLOCATED to more classes
Modified: trunk/Source/WebCore/WebCore.exp.in (164400 => 164401)
--- trunk/Source/WebCore/WebCore.exp.in 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/WebCore.exp.in 2014-02-20 00:12:59 UTC (rev 164401)
@@ -1116,6 +1116,7 @@
__ZN7WebCore6Editor26toggleOverwriteModeEnabledEv
__ZN7WebCore6Editor26writeSelectionToPasteboardERNS_10PasteboardE
__ZN7WebCore6Editor28replaceSelectionWithFragmentEN3WTF10PassRefPtrINS_16DocumentFragmentEEEbbb
+__ZN7WebCore6Editor28updateEditorUINowIfScheduledEv
__ZN7WebCore6Editor29canDecreaseSelectionListLevelEv
__ZN7WebCore6Editor29canIncreaseSelectionListLevelEv
__ZN7WebCore6Editor29handleAlternativeTextUIResultERKN3WTF6StringE
Modified: trunk/Source/WebCore/editing/AlternativeTextController.cpp (164400 => 164401)
--- trunk/Source/WebCore/editing/AlternativeTextController.cpp 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/editing/AlternativeTextController.cpp 2014-02-20 00:12:59 UTC (rev 164401)
@@ -440,7 +440,7 @@
return view->contentsToRootView(IntRect(boundingRect));
}
-void AlternativeTextController::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
+void AlternativeTextController::respondToChangedSelection(const VisibleSelection& oldSelection)
{
VisibleSelection currentSelection(m_frame.selection().selection());
// When user moves caret to the end of autocorrected word and pauses, we show the panel
@@ -473,7 +473,7 @@
if (!marker)
continue;
- if (respondToMarkerAtEndOfWord(*marker, position, options))
+ if (respondToMarkerAtEndOfWord(*marker, position))
break;
}
}
@@ -625,10 +625,8 @@
return (((marker.type() == DocumentMarker::Replacement && !marker.description().isNull()) || marker.type() == DocumentMarker::Spelling || marker.type() == DocumentMarker::DictationAlternatives) && static_cast<int>(marker.endOffset()) == endOffset);
}
-bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker& marker, const Position& endOfWordPosition, FrameSelection::SetSelectionOptions options)
+bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker& marker, const Position& endOfWordPosition)
{
- if (options & FrameSelection::DictationTriggered)
- return false;
if (!shouldStartTimerFor(marker, endOfWordPosition.offsetInContainerNode()))
return false;
Node* node = endOfWordPosition.containerNode();
Modified: trunk/Source/WebCore/editing/AlternativeTextController.h (164400 => 164401)
--- trunk/Source/WebCore/editing/AlternativeTextController.h 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/editing/AlternativeTextController.h 2014-02-20 00:12:59 UTC (rev 164401)
@@ -108,7 +108,7 @@
void respondToUnappliedSpellCorrection(const VisibleSelection&, const String& corrected, const String& correction) UNLESS_ENABLED({ UNUSED_PARAM(corrected); UNUSED_PARAM(correction); })
void respondToAppliedEditing(CompositeEditCommand*) UNLESS_ENABLED({ })
void respondToUnappliedEditing(EditCommandComposition*) UNLESS_ENABLED({ })
- void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions) UNLESS_ENABLED({ UNUSED_PARAM(oldSelection); })
+ void respondToChangedSelection(const VisibleSelection& oldSelection) UNLESS_ENABLED({ UNUSED_PARAM(oldSelection); })
void stopPendingCorrection(const VisibleSelection& oldSelection) UNLESS_ENABLED({ UNUSED_PARAM(oldSelection); })
void applyPendingCorrection(const VisibleSelection& selectionAfterTyping) UNLESS_ENABLED({ UNUSED_PARAM(selectionAfterTyping); })
@@ -144,7 +144,7 @@
String markerDescriptionForAppliedAlternativeText(AlternativeTextType, DocumentMarker::MarkerType);
bool shouldStartTimerFor(const DocumentMarker&, int endOffset) const;
- bool respondToMarkerAtEndOfWord(const DocumentMarker&, const Position& endOfWordPosition, FrameSelection::SetSelectionOptions);
+ bool respondToMarkerAtEndOfWord(const DocumentMarker&, const Position& endOfWordPosition);
AlternativeTextClient* alternativeTextClient();
EditorClient* editorClient();
Modified: trunk/Source/WebCore/editing/Editor.cpp (164400 => 164401)
--- trunk/Source/WebCore/editing/Editor.cpp 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/editing/Editor.cpp 2014-02-20 00:12:59 UTC (rev 164401)
@@ -1066,8 +1066,6 @@
ASSERT(composition);
VisibleSelection newSelection(cmd->endingSelection());
- m_alternativeTextController->respondToAppliedEditing(cmd.get());
-
notifyTextFromControls(composition->startingRootEditableElement(), composition->endingRootEditableElement());
// Don't clear the typing style with this selection change. We do those things elsewhere if necessary.
@@ -1075,6 +1073,10 @@
changeSelectionAfterCommand(newSelection, options);
dispatchEditableContentChangedEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement());
+ updateEditorUINowIfScheduled();
+
+ m_alternativeTextController->respondToAppliedEditing(cmd.get());
+
if (!cmd->preservesTypingStyle())
m_frame.selection().clearTypingStyle();
@@ -1102,6 +1104,8 @@
changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
+ updateEditorUINowIfScheduled();
+
m_alternativeTextController->respondToUnappliedEditing(cmd.get());
m_lastEditCommand = 0;
@@ -1119,6 +1123,8 @@
VisibleSelection newSelection(cmd->endingSelection());
changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
+
+ updateEditorUINowIfScheduled();
m_lastEditCommand = 0;
if (client())
@@ -1141,6 +1147,9 @@
, m_areMarkedTextMatchesHighlighted(false)
, m_defaultParagraphSeparator(EditorParagraphSeparatorIsDiv)
, m_overwriteModeEnabled(false)
+ , m_editorUIUpdateTimer(this, &Editor::editorUIUpdateTimerFired)
+ , m_editorUIUpdateTimerShouldCheckSpellingAndGrammar(false)
+ , m_editorUIUpdateTimerWasTriggeredByDictation(false)
{
}
@@ -3294,7 +3303,7 @@
document().markers().repaintMarkers(DocumentMarker::TextMatch);
}
-void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
+void Editor::respondToChangedSelection(const VisibleSelection&, FrameSelection::SetSelectionOptions options)
{
#if PLATFORM(IOS)
// FIXME: Should suppress selection change notifications during a composition change <https://webkit.org/b/38830>
@@ -3302,9 +3311,34 @@
return;
#endif
+ if (client())
+ client()->respondToChangedSelection(&m_frame);
+ setStartNewKillRingSequence(true);
+
+ if (m_editorUIUpdateTimer.isActive())
+ return;
+
+ // Don't check spelling and grammar if the change of selection is triggered by spelling correction itself.
+ m_editorUIUpdateTimerShouldCheckSpellingAndGrammar = options & FrameSelection::CloseTyping
+ && !(options & FrameSelection::SpellCorrectionTriggered);
+ m_editorUIUpdateTimerWasTriggeredByDictation = options & FrameSelection::DictationTriggered;
+ m_editorUIUpdateTimer.startOneShot(0);
+}
+
+void Editor::updateEditorUINowIfScheduled()
+{
+ if (!m_editorUIUpdateTimer.isActive())
+ return;
+ m_editorUIUpdateTimer.stop();
+ editorUIUpdateTimerFired(m_editorUIUpdateTimer);
+}
+
+void Editor::editorUIUpdateTimerFired(Timer<Editor>&)
+{
+ VisibleSelection oldSelection = m_oldSelectionForEditorUIUpdate;
+
m_alternativeTextController->stopPendingCorrection(oldSelection);
-
- bool closeTyping = options & FrameSelection::CloseTyping;
+
bool isContinuousSpellCheckingEnabled = this->isContinuousSpellCheckingEnabled();
bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && isGrammarCheckingEnabled();
if (isContinuousSpellCheckingEnabled) {
@@ -3331,13 +3365,10 @@
newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
}
- // Don't check spelling and grammar if the change of selection is triggered by spelling correction itself.
- bool shouldCheckSpellingAndGrammar = !(options & FrameSelection::SpellCorrectionTriggered);
-
// When typing we check spelling elsewhere, so don't redo it here.
// If this is a change in selection resulting from a delete operation,
// oldSelection may no longer be in the document.
- if (shouldCheckSpellingAndGrammar && closeTyping && oldSelection.isContentEditable() && oldSelection.start().deprecatedNode() && oldSelection.start().anchorNode()->inDocument()) {
+ if (m_editorUIUpdateTimerShouldCheckSpellingAndGrammar && oldSelection.isContentEditable() && oldSelection.start().deprecatedNode() && oldSelection.start().anchorNode()->inDocument()) {
VisiblePosition oldStart(oldSelection.visibleStart());
VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
if (oldAdjacentWords != newAdjacentWords) {
@@ -3365,13 +3396,13 @@
if (!isContinuousGrammarCheckingEnabled)
document().markers().removeMarkers(DocumentMarker::Grammar);
- if (client())
- client()->respondToChangedSelection(&m_frame);
- setStartNewKillRingSequence(true);
#if ENABLE(DELETION_UI)
m_deleteButtonController->respondToChangedSelection(oldSelection);
#endif
- m_alternativeTextController->respondToChangedSelection(oldSelection, options);
+ if (m_editorUIUpdateTimerWasTriggeredByDictation)
+ m_alternativeTextController->respondToChangedSelection(oldSelection);
+
+ m_oldSelectionForEditorUIUpdate = m_frame.selection().selection();
}
static Node* findFirstMarkable(Node* node)
Modified: trunk/Source/WebCore/editing/Editor.h (164400 => 164401)
--- trunk/Source/WebCore/editing/Editor.h 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/editing/Editor.h 2014-02-20 00:12:59 UTC (rev 164401)
@@ -362,6 +362,7 @@
IntRect firstRectForRange(Range*) const;
void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
+ void updateEditorUINowIfScheduled();
bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
unsigned countMatchesForText(const String&, Range*, FindOptions, unsigned limit, bool markMatches, Vector<RefPtr<Range>>*);
bool markedTextMatchesAreHighlighted() const;
@@ -464,6 +465,8 @@
void changeSelectionAfterCommand(const VisibleSelection& newSelection, FrameSelection::SetSelectionOptions);
+ void editorUIUpdateTimerFired(Timer<Editor>&);
+
Node* findEventTargetFromSelection() const;
bool unifiedTextCheckerEnabled() const;
@@ -495,6 +498,11 @@
bool m_areMarkedTextMatchesHighlighted;
EditorParagraphSeparator m_defaultParagraphSeparator;
bool m_overwriteModeEnabled;
+
+ VisibleSelection m_oldSelectionForEditorUIUpdate;
+ Timer<Editor> m_editorUIUpdateTimer;
+ bool m_editorUIUpdateTimerShouldCheckSpellingAndGrammar;
+ bool m_editorUIUpdateTimerWasTriggeredByDictation;
};
inline void Editor::setStartNewKillRingSequence(bool flag)
Modified: trunk/Source/WebCore/testing/Internals.cpp (164400 => 164401)
--- trunk/Source/WebCore/testing/Internals.cpp 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/testing/Internals.cpp 2014-02-20 00:12:59 UTC (rev 164401)
@@ -748,6 +748,8 @@
return 0;
}
+ node->document().frame()->editor().updateEditorUINowIfScheduled();
+
return node->document().markers().markersFor(node, markerTypes).size();
}
@@ -765,6 +767,8 @@
return 0;
}
+ node->document().frame()->editor().updateEditorUINowIfScheduled();
+
Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
if (markers.size() <= index)
return 0;
@@ -1295,12 +1299,34 @@
#endif
}
+void Internals::updateEditorUINowIfScheduled()
+{
+ if (Document* document = contextDocument()) {
+ if (Frame* frame = document->frame())
+ frame->editor().updateEditorUINowIfScheduled();
+ }
+}
+
+Node* Internals::findEditingDeleteButton()
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return 0;
+
+ updateEditorUINowIfScheduled();
+
+ // FIXME: We shouldn't pollute the id namespace with this name.
+ return document->getElementById("WebKit-Editing-Delete-Button");
+}
+
bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
{
Document* document = contextDocument();
if (!document || !document->frame())
return 0;
+ updateEditorUINowIfScheduled();
+
return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
}
@@ -1309,7 +1335,9 @@
Document* document = contextDocument();
if (!document || !document->frame())
return 0;
-
+
+ updateEditorUINowIfScheduled();
+
return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
}
Modified: trunk/Source/WebCore/testing/Internals.h (164400 => 164401)
--- trunk/Source/WebCore/testing/Internals.h 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/testing/Internals.h 2014-02-20 00:12:59 UTC (rev 164401)
@@ -169,6 +169,9 @@
String parserMetaData(Deprecated::ScriptValue = Deprecated::ScriptValue());
+ Node* findEditingDeleteButton();
+ void updateEditorUINowIfScheduled();
+
bool hasSpellingMarker(int from, int length, ExceptionCode&);
bool hasGrammarMarker(int from, int length, ExceptionCode&);
bool hasAutocorrectedMarker(int from, int length, ExceptionCode&);
Modified: trunk/Source/WebCore/testing/Internals.idl (164400 => 164401)
--- trunk/Source/WebCore/testing/Internals.idl 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebCore/testing/Internals.idl 2014-02-20 00:12:59 UTC (rev 164401)
@@ -129,6 +129,10 @@
// Calling parserMetaData() with no arguments gets the metadata for the script of the current scope.
DOMString parserMetaData(optional any func);
+ void updateEditorUINowIfScheduled();
+
+ Node findEditingDeleteButton();
+
[RaisesException] boolean hasSpellingMarker(long from, long length);
[RaisesException] boolean hasGrammarMarker(long from, long length);
[RaisesException] boolean hasAutocorrectedMarker(long from, long length);
Modified: trunk/Source/WebKit/ChangeLog (164400 => 164401)
--- trunk/Source/WebKit/ChangeLog 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebKit/ChangeLog 2014-02-20 00:12:59 UTC (rev 164401)
@@ -1,3 +1,14 @@
+2014-02-18 Ryosuke Niwa <[email protected]>
+
+ Changing selection shouldn't synchronously update editor UI components
+ https://bugs.webkit.org/show_bug.cgi?id=129024
+
+ Reviewed by Brent Fulgham.
+
+ Added symbols for internals.
+
+ * WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in:
+
2014-02-17 Sergio Correia <[email protected]>
Replace uses of PassOwnPtr/OwnPtr with std::unique_ptr in WebCore/inspector
Modified: trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in (164400 => 164401)
--- trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in 2014-02-19 23:51:34 UTC (rev 164400)
+++ trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in 2014-02-20 00:12:59 UTC (rev 164401)
@@ -204,6 +204,7 @@
symbolWithPointer(?garbageCollectDocumentResources@CachedResourceLoader@WebCore@@QAEXXZ, ?garbageCollectDocumentResources@CachedResourceLoader@WebCore@@QEAAXXZ)
symbolWithPointer(?getCachedDOMStructure@WebCore@@YAPAVStructure@JSC@@PAVJSDOMGlobalObject@1@PBUClassInfo@3@@Z, ?getCachedDOMStructure@WebCore@@YAPEAVStructure@JSC@@PEAVJSDOMGlobalObject@1@PEBUClassInfo@3@@Z)
symbolWithPointer(?getData16SlowCase@StringImpl@WTF@@ABEPB_WXZ, ?getData16SlowCase@StringImpl@WTF@@AEBAPEB_WXZ)
+ symbolWithPointer(?getElementById@TreeScope@WebCore@@QBEPAVElement@2@ABVAtomicString@WTF@@@Z)
symbolWithPointer(?getLocationAndLengthFromRange@TextIterator@WebCore@@SA_NPAVNode@2@PBVRange@2@AAI2@Z, ?getLocationAndLengthFromRange@TextIterator@WebCore@@SA_NPEAVNode@2@PEBVRange@2@AEA_K2@Z)
symbolWithPointer(?hitTest@RenderView@WebCore@@QAE_NABVHitTestRequest@2@AAVHitTestResult@2@@Z, ?hitTest@RenderView@WebCore@@QEAA_NAEBVHitTestRequest@2@AEAVHitTestResult@2@@Z)
?inputTag@HTMLNames@WebCore@@3VQualifiedName@2@B
@@ -323,6 +324,7 @@
symbolWithPointer(?toJS@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@PAVNodeList@1@@Z, ?toJS@WebCore@@YA?AVJSValue@JSC@@PEAVExecState@3@PEAVJSDOMGlobalObject@1@PEAVNodeList@1@@Z)
symbolWithPointer(?toRange@WebCore@@YAPAVRange@1@VJSValue@JSC@@@Z, ?toRange@WebCore@@YAPEAVRange@1@VJSValue@JSC@@@Z)
symbolWithPointer(?isTreeScope@Node@WebCore@@QBE_NXZ, ?isTreeScope@Node@WebCore@@QEBA_NXZ)
+ symbolWithPointer(?updateEditorUINowIfScheduled@Editor@WebCore@@QAEXXZ)
symbolWithPointer(?updateLayoutIgnorePendingStylesheets@Document@WebCore@@QAEXXZ, ?updateLayoutIgnorePendingStylesheets@Document@WebCore@@QEAAXXZ)
symbolWithPointer(?updateStyleIfNeeded@Document@WebCore@@QAEXXZ, ?updateStyleIfNeeded@Document@WebCore@@QEAAXXZ)
symbolWithPointer(?view@Document@WebCore@@QBEPAVFrameView@2@XZ, ?view@Document@WebCore@@QEBAPEAVFrameView@2@XZ)