Rename DataTransferAccessPolicy to match spec and refactor related node
[WebKit-https.git] / Source / WebCore / editing / Editor.cpp
1 /*
2  * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "Editor.h"
29
30 #include "AXObjectCache.h"
31 #include "AlternativeTextController.h"
32 #include "ApplyStyleCommand.h"
33 #include "CSSComputedStyleDeclaration.h"
34 #include "CSSPropertyNames.h"
35 #include "CachedResourceLoader.h"
36 #include "ClipboardEvent.h"
37 #include "CompositionEvent.h"
38 #include "CreateLinkCommand.h"
39 #include "DataTransfer.h"
40 #include "DeleteSelectionCommand.h"
41 #include "DictationAlternative.h"
42 #include "DictationCommand.h"
43 #include "DocumentFragment.h"
44 #include "DocumentMarkerController.h"
45 #include "Editing.h"
46 #include "EditorClient.h"
47 #include "EventHandler.h"
48 #include "EventNames.h"
49 #include "FocusController.h"
50 #include "Frame.h"
51 #include "FrameLoader.h"
52 #include "FrameTree.h"
53 #include "FrameView.h"
54 #include "GraphicsContext.h"
55 #include "HTMLCollection.h"
56 #include "HTMLFormControlElement.h"
57 #include "HTMLFrameOwnerElement.h"
58 #include "HTMLImageElement.h"
59 #include "HTMLInputElement.h"
60 #include "HTMLNames.h"
61 #include "HTMLSpanElement.h"
62 #include "HitTestResult.h"
63 #include "IndentOutdentCommand.h"
64 #include "InputEvent.h"
65 #include "InsertListCommand.h"
66 #include "InsertTextCommand.h"
67 #include "KeyboardEvent.h"
68 #include "Logging.h"
69 #include "MainFrame.h"
70 #include "ModifySelectionListLevel.h"
71 #include "NodeList.h"
72 #include "NodeTraversal.h"
73 #include "Page.h"
74 #include "Pasteboard.h"
75 #include "Range.h"
76 #include "RemoveFormatCommand.h"
77 #include "RenderBlock.h"
78 #include "RenderTextControl.h"
79 #include "RenderedDocumentMarker.h"
80 #include "RenderedPosition.h"
81 #include "ReplaceRangeWithTextCommand.h"
82 #include "ReplaceSelectionCommand.h"
83 #include "Settings.h"
84 #include "ShadowRoot.h"
85 #include "SimplifyMarkupCommand.h"
86 #include "SpellChecker.h"
87 #include "SpellingCorrectionCommand.h"
88 #include "StyleProperties.h"
89 #include "TelephoneNumberDetector.h"
90 #include "Text.h"
91 #include "TextCheckerClient.h"
92 #include "TextCheckingHelper.h"
93 #include "TextEvent.h"
94 #include "TextIterator.h"
95 #include "TypingCommand.h"
96 #include "UserTypingGestureIndicator.h"
97 #include "VisibleUnits.h"
98 #include "markup.h"
99 #include <pal/system/Sound.h>
100 #include <pal/text/KillRing.h>
101 #include <wtf/unicode/CharacterNames.h>
102
103 #if PLATFORM(MAC)
104 #include "ServicesOverlayController.h"
105 #endif
106
107 namespace WebCore {
108
109 static bool dispatchBeforeInputEvent(Element& element, const AtomicString& inputType, const String& data = { }, RefPtr<DataTransfer>&& dataTransfer = nullptr, const Vector<RefPtr<StaticRange>>& targetRanges = { }, bool cancelable = true)
110 {
111     if (!element.document().settings().inputEventsEnabled())
112         return true;
113
114     return element.dispatchEvent(InputEvent::create(eventNames().beforeinputEvent, inputType, true, cancelable, element.document().defaultView(), data, WTFMove(dataTransfer), targetRanges, 0));
115 }
116
117 static void dispatchInputEvent(Element& element, const AtomicString& inputType, const String& data = { }, RefPtr<DataTransfer>&& dataTransfer = nullptr, const Vector<RefPtr<StaticRange>>& targetRanges = { })
118 {
119     if (element.document().settings().inputEventsEnabled()) {
120         // FIXME: We should not be dispatching to the scoped queue here. Normally, input events are dispatched in CompositeEditCommand::apply after the end of the scope,
121         // but TypingCommands are special in that existing TypingCommands that are applied again fire input events *from within* the scope by calling typingAddedToOpenCommand.
122         // Instead, TypingCommands should always dispatch events synchronously after the end of the scoped queue in CompositeEditCommand::apply. To work around this for the
123         // time being, just revert back to calling dispatchScopedEvent.
124         element.dispatchScopedEvent(InputEvent::create(eventNames().inputEvent, inputType, true, false, element.document().defaultView(), data, WTFMove(dataTransfer), targetRanges, 0));
125     } else
126         element.dispatchInputEvent();
127 }
128
129 static String inputEventDataForEditingStyleAndAction(const StyleProperties* style, EditAction action)
130 {
131     if (!style)
132         return { };
133
134     switch (action) {
135     case EditActionSetColor:
136         return style->getPropertyValue(CSSPropertyColor);
137     case EditActionSetWritingDirection:
138         return style->getPropertyValue(CSSPropertyDirection);
139     default:
140         return { };
141     }
142 }
143
144 static String inputEventDataForEditingStyleAndAction(EditingStyle& style, EditAction action)
145 {
146     return inputEventDataForEditingStyleAndAction(style.style(), action);
147 }
148
149 class ClearTextCommand : public DeleteSelectionCommand {
150 public:
151     ClearTextCommand(Document& document);
152     static void CreateAndApply(const RefPtr<Frame> frame);
153     
154 private:
155     EditAction editingAction() const override;
156 };
157
158 ClearTextCommand::ClearTextCommand(Document& document)
159     : DeleteSelectionCommand(document, false, true, false, false, true)
160 {
161 }
162
163 EditAction ClearTextCommand::editingAction() const
164 {
165     return EditActionDelete;
166 }
167
168 void ClearTextCommand::CreateAndApply(const RefPtr<Frame> frame)
169 {
170     if (frame->selection().isNone())
171         return;
172
173     // Don't leave around stale composition state.
174     frame->editor().clear();
175     
176     const VisibleSelection oldSelection = frame->selection().selection();
177     frame->selection().selectAll();
178     auto clearCommand = adoptRef(*new ClearTextCommand(*frame->document()));
179     clearCommand->setStartingSelection(oldSelection);
180     clearCommand->apply();
181 }
182
183 using namespace HTMLNames;
184 using namespace WTF;
185 using namespace Unicode;
186
187 TemporarySelectionChange::TemporarySelectionChange(Frame& frame, std::optional<VisibleSelection> temporarySelection, TemporarySelectionOptions options)
188     : m_frame(frame)
189     , m_options(options)
190     , m_wasIgnoringSelectionChanges(frame.editor().ignoreSelectionChanges())
191 #if PLATFORM(IOS)
192     , m_appearanceUpdatesWereEnabled(frame.selection().isUpdateAppearanceEnabled())
193 #endif
194 {
195 #if PLATFORM(IOS)
196     if (options & TemporarySelectionOptionEnableAppearanceUpdates)
197         frame.selection().setUpdateAppearanceEnabled(true);
198 #endif
199
200     if (options & TemporarySelectionOptionIgnoreSelectionChanges)
201         frame.editor().setIgnoreSelectionChanges(true);
202
203     if (temporarySelection) {
204         m_selectionToRestore = frame.selection().selection();
205         frame.selection().setSelection(temporarySelection.value());
206     }
207 }
208
209 TemporarySelectionChange::~TemporarySelectionChange()
210 {
211     if (m_selectionToRestore)
212         m_frame->selection().setSelection(m_selectionToRestore.value());
213
214     if (m_options & TemporarySelectionOptionIgnoreSelectionChanges) {
215         auto revealSelection = m_options & TemporarySelectionOptionRevealSelection ? Editor::RevealSelection::Yes : Editor::RevealSelection::No;
216         m_frame->editor().setIgnoreSelectionChanges(m_wasIgnoringSelectionChanges, revealSelection);
217     }
218
219 #if PLATFORM(IOS)
220     if (m_options & TemporarySelectionOptionEnableAppearanceUpdates)
221         m_frame->selection().setUpdateAppearanceEnabled(m_appearanceUpdatesWereEnabled);
222 #endif
223 }
224
225 // When an event handler has moved the selection outside of a text control
226 // we should use the target control's selection for this editing operation.
227 VisibleSelection Editor::selectionForCommand(Event* event)
228 {
229     VisibleSelection selection = m_frame.selection().selection();
230     if (!event)
231         return selection;
232     // If the target is a text control, and the current selection is outside of its shadow tree,
233     // then use the saved selection for that text control.
234     HTMLTextFormControlElement* textFormControlOfSelectionStart = enclosingTextFormControl(selection.start());
235     HTMLTextFormControlElement* textFromControlOfTarget = is<HTMLTextFormControlElement>(*event->target()->toNode()) ? downcast<HTMLTextFormControlElement>(event->target()->toNode()) : nullptr;
236     if (textFromControlOfTarget && (selection.start().isNull() || textFromControlOfTarget != textFormControlOfSelectionStart)) {
237         if (RefPtr<Range> range = textFromControlOfTarget->selection())
238             return VisibleSelection(*range, DOWNSTREAM, selection.isDirectional());
239     }
240     return selection;
241 }
242
243 // Function considers Mac editing behavior a fallback when Page or Settings is not available.
244 EditingBehavior Editor::behavior() const
245 {
246     return EditingBehavior(m_frame.settings().editingBehaviorType());
247 }
248
249 EditorClient* Editor::client() const
250 {
251     if (Page* page = m_frame.page())
252         return &page->editorClient();
253     return nullptr;
254 }
255
256 TextCheckerClient* Editor::textChecker() const
257 {
258     if (EditorClient* owner = client())
259         return owner->textChecker();
260     return 0;
261 }
262
263 void Editor::handleKeyboardEvent(KeyboardEvent& event)
264 {
265     if (EditorClient* c = client())
266         c->handleKeyboardEvent(&event);
267 }
268
269 void Editor::handleInputMethodKeydown(KeyboardEvent& event)
270 {
271     if (EditorClient* c = client())
272         c->handleInputMethodKeydown(&event);
273 }
274
275 bool Editor::handleTextEvent(TextEvent& event)
276 {
277     LOG(Editing, "Editor %p handleTextEvent (data %s)", this, event.data().utf8().data());
278
279     // Default event handling for Drag and Drop will be handled by DragController
280     // so we leave the event for it.
281     if (event.isDrop())
282         return false;
283
284     if (event.isPaste()) {
285         if (event.pastingFragment()) {
286 #if PLATFORM(IOS)
287             if (client()->performsTwoStepPaste(event.pastingFragment()))
288                 return true;
289 #endif
290             replaceSelectionWithFragment(*event.pastingFragment(), false, event.shouldSmartReplace(), event.shouldMatchStyle(), EditActionPaste, event.mailBlockquoteHandling());
291         } else
292             replaceSelectionWithText(event.data(), false, event.shouldSmartReplace(), EditActionPaste);
293         return true;
294     }
295
296     String data = event.data();
297     if (data == "\n") {
298         if (event.isLineBreak())
299             return insertLineBreak();
300         return insertParagraphSeparator();
301     }
302
303     return insertTextWithoutSendingTextEvent(data, false, &event);
304 }
305
306 bool Editor::canEdit() const
307 {
308     return m_frame.selection().selection().rootEditableElement();
309 }
310
311 bool Editor::canEditRichly() const
312 {
313     return m_frame.selection().selection().isContentRichlyEditable();
314 }
315
316 // Returns whether caller should continue with "the default processing", which is the same as
317 // the event handler NOT setting the return value to false
318 // https://w3c.github.io/clipboard-apis/#fire-a-clipboard-event
319 static bool dispatchClipboardEvent(RefPtr<Element>&& target, const AtomicString& eventType)
320 {
321     // FIXME: Move the target selection code here.
322     if (!target)
323         return true;
324
325     DataTransfer::StoreMode storeMode;
326     if (eventType == eventNames().pasteEvent)
327         storeMode = DataTransfer::StoreMode::Readonly;
328     else if (eventType == eventNames().copyEvent || eventType == eventNames().cutEvent)
329         storeMode = DataTransfer::StoreMode::ReadWrite;
330     else {
331         ASSERT(eventType == eventNames().beforecutEvent || eventType == eventNames().beforecopyEvent || eventType == eventNames().beforepasteEvent);
332         storeMode = DataTransfer::StoreMode::Invalid;
333     }
334
335     auto dataTransfer = DataTransfer::createForCopyAndPaste(storeMode);
336
337     ClipboardEvent::Init init;
338     init.bubbles = true;
339     init.cancelable = true;
340     init.clipboardData = dataTransfer.ptr();
341     auto event = ClipboardEvent::create(eventType, init, Event::IsTrusted::Yes);
342
343     target->dispatchEvent(event);
344     bool noDefaultProcessing = event->defaultPrevented();
345     if (noDefaultProcessing && storeMode == DataTransfer::StoreMode::ReadWrite) {
346         auto pasteboard = Pasteboard::createForCopyAndPaste();
347         pasteboard->clear();
348         pasteboard->writePasteboard(dataTransfer->pasteboard());
349     }
350
351     dataTransfer->makeInvalidForSecurity();
352
353     return !noDefaultProcessing;
354 }
355
356 // WinIE uses onbeforecut and onbeforepaste to enables the cut and paste menu items.  They
357 // also send onbeforecopy, apparently for symmetry, but it doesn't affect the menu items.
358 // We need to use onbeforecopy as a real menu enabler because we allow elements that are not
359 // normally selectable to implement copy/paste (like divs, or a document body).
360
361 bool Editor::canDHTMLCut()
362 {
363     if (m_frame.selection().selection().isInPasswordField())
364         return false;
365
366     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().beforecutEvent);
367 }
368
369 bool Editor::canDHTMLCopy()
370 {
371     if (m_frame.selection().selection().isInPasswordField())
372         return false;
373     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().beforecopyEvent);
374 }
375
376 bool Editor::canDHTMLPaste()
377 {
378     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().beforepasteEvent);
379 }
380
381 bool Editor::canCut() const
382 {
383     return canCopy() && canDelete();
384 }
385
386 static HTMLImageElement* imageElementFromImageDocument(Document& document)
387 {
388     if (!document.isImageDocument())
389         return nullptr;
390     
391     HTMLElement* body = document.bodyOrFrameset();
392     if (!body)
393         return nullptr;
394     
395     Node* node = body->firstChild();
396     if (!is<HTMLImageElement>(node))
397         return nullptr;
398     return downcast<HTMLImageElement>(node);
399 }
400
401 bool Editor::canCopy() const
402 {
403     if (imageElementFromImageDocument(document()))
404         return true;
405     const VisibleSelection& selection = m_frame.selection().selection();
406     return selection.isRange() && !selection.isInPasswordField();
407 }
408
409 bool Editor::canPaste() const
410 {
411     return canEdit();
412 }
413
414 bool Editor::canDelete() const
415 {
416     const VisibleSelection& selection = m_frame.selection().selection();
417     return selection.isRange() && selection.rootEditableElement();
418 }
419
420 bool Editor::canDeleteRange(Range* range) const
421 {
422     Node& startContainer = range->startContainer();
423     Node& endContainer = range->endContainer();
424     
425     if (!startContainer.hasEditableStyle() || !endContainer.hasEditableStyle())
426         return false;
427
428     if (range->collapsed()) {
429         VisiblePosition start(range->startPosition(), DOWNSTREAM);
430         VisiblePosition previous = start.previous();
431         // FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.
432         if (previous.isNull() || previous.deepEquivalent().deprecatedNode()->rootEditableElement() != startContainer.rootEditableElement())
433             return false;
434     }
435     return true;
436 }
437
438 bool Editor::smartInsertDeleteEnabled()
439 {   
440     return client() && client()->smartInsertDeleteEnabled();
441 }
442     
443 bool Editor::canSmartCopyOrDelete()
444 {
445     return client() && client()->smartInsertDeleteEnabled() && m_frame.selection().granularity() == WordGranularity;
446 }
447
448 bool Editor::isSelectTrailingWhitespaceEnabled() const
449 {
450     return client() && client()->isSelectTrailingWhitespaceEnabled();
451 }
452
453 bool Editor::deleteWithDirection(SelectionDirection direction, TextGranularity granularity, bool shouldAddToKillRing, bool isTypingAction)
454 {
455     if (!canEdit())
456         return false;
457
458     if (m_frame.selection().isRange()) {
459         if (isTypingAction) {
460             TypingCommand::deleteKeyPressed(document(), canSmartCopyOrDelete() ? TypingCommand::SmartDelete : 0, granularity);
461             revealSelectionAfterEditingOperation();
462         } else {
463             if (shouldAddToKillRing)
464                 addRangeToKillRing(*selectedRange().get(), KillRingInsertionMode::AppendText);
465             deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
466             // Implicitly calls revealSelectionAfterEditingOperation().
467         }
468     } else {
469         TypingCommand::Options options = 0;
470         if (canSmartCopyOrDelete())
471             options |= TypingCommand::SmartDelete;
472         if (shouldAddToKillRing)
473             options |= TypingCommand::AddsToKillRing;
474         switch (direction) {
475         case DirectionForward:
476         case DirectionRight:
477             TypingCommand::forwardDeleteKeyPressed(document(), options, granularity);
478             break;
479         case DirectionBackward:
480         case DirectionLeft:
481             TypingCommand::deleteKeyPressed(document(), options, granularity);
482             break;
483         }
484         revealSelectionAfterEditingOperation();
485     }
486
487     // FIXME: We should to move this down into deleteKeyPressed.
488     // clear the "start new kill ring sequence" setting, because it was set to true
489     // when the selection was updated by deleting the range
490     if (shouldAddToKillRing)
491         setStartNewKillRingSequence(false);
492
493     return true;
494 }
495
496 void Editor::deleteSelectionWithSmartDelete(bool smartDelete, EditAction editingAction)
497 {
498     if (m_frame.selection().isNone())
499         return;
500
501     DeleteSelectionCommand::create(document(), smartDelete, true, false, false, true, editingAction)->apply();
502 }
503
504 void Editor::clearText()
505 {
506     ClearTextCommand::CreateAndApply(&m_frame);
507 }
508
509 void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace)
510 {
511     Element* target = findEventTargetFromSelection();
512     if (!target)
513         return;
514     target->dispatchEvent(TextEvent::createForPlainTextPaste(document().domWindow(), pastingText, smartReplace));
515 }
516
517 void Editor::pasteAsFragment(Ref<DocumentFragment>&& pastingFragment, bool smartReplace, bool matchStyle, MailBlockquoteHandling respectsMailBlockquote)
518 {
519     Element* target = findEventTargetFromSelection();
520     if (!target)
521         return;
522     target->dispatchEvent(TextEvent::createForFragmentPaste(document().domWindow(), WTFMove(pastingFragment), smartReplace, matchStyle, respectsMailBlockquote));
523 }
524
525 void Editor::pasteAsPlainTextBypassingDHTML()
526 {
527     pasteAsPlainTextWithPasteboard(*Pasteboard::createForCopyAndPaste());
528 }
529
530 void Editor::pasteAsPlainTextWithPasteboard(Pasteboard& pasteboard)
531 {
532     String text = readPlainTextFromPasteboard(pasteboard);
533     if (client() && client()->shouldInsertText(text, selectedRange().get(), EditorInsertAction::Pasted))
534         pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard));
535 }
536
537 String Editor::readPlainTextFromPasteboard(Pasteboard& pasteboard)
538 {
539     PasteboardPlainText text;
540     pasteboard.read(text);
541     return plainTextFromPasteboard(text);
542 }
543
544 #if !PLATFORM(MAC)
545
546 String Editor::plainTextFromPasteboard(const PasteboardPlainText& text)
547 {
548     return text.text;
549 }
550
551 #endif
552
553 bool Editor::canSmartReplaceWithPasteboard(Pasteboard& pasteboard)
554 {
555     return client() && client()->smartInsertDeleteEnabled() && pasteboard.canSmartReplace();
556 }
557
558 bool Editor::shouldInsertFragment(DocumentFragment& fragment, Range* replacingDOMRange, EditorInsertAction givenAction)
559 {
560     if (!client())
561         return false;
562     
563     auto* child = fragment.firstChild();
564     if (is<CharacterData>(child) && fragment.lastChild() == child)
565         return client()->shouldInsertText(downcast<CharacterData>(*child).data(), replacingDOMRange, givenAction);
566
567     return client()->shouldInsertNode(&fragment, replacingDOMRange, givenAction);
568 }
569
570 void Editor::replaceSelectionWithFragment(DocumentFragment& fragment, bool selectReplacement, bool smartReplace, bool matchStyle, EditAction editingAction, MailBlockquoteHandling mailBlockquoteHandling)
571 {
572     VisibleSelection selection = m_frame.selection().selection();
573     if (selection.isNone() || !selection.isContentEditable())
574         return;
575
576     AccessibilityReplacedText replacedText;
577     if (AXObjectCache::accessibilityEnabled() && editingAction == EditActionPaste)
578         replacedText = AccessibilityReplacedText(selection);
579
580     ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::PreventNesting | ReplaceSelectionCommand::SanitizeFragment;
581     if (selectReplacement)
582         options |= ReplaceSelectionCommand::SelectReplacement;
583     if (smartReplace)
584         options |= ReplaceSelectionCommand::SmartReplace;
585     if (matchStyle)
586         options |= ReplaceSelectionCommand::MatchStyle;
587     if (mailBlockquoteHandling == MailBlockquoteHandling::IgnoreBlockquote)
588         options |= ReplaceSelectionCommand::IgnoreMailBlockquote;
589
590     auto command = ReplaceSelectionCommand::create(document(), &fragment, options, editingAction);
591     command->apply();
592     revealSelectionAfterEditingOperation();
593
594     selection = m_frame.selection().selection();
595     if (selection.isInPasswordField())
596         return;
597
598     if (AXObjectCache::accessibilityEnabled() && editingAction == EditActionPaste) {
599         String text = AccessibilityObject::stringForVisiblePositionRange(command->visibleSelectionForInsertedText());
600         replacedText.postTextStateChangeNotification(document().existingAXObjectCache(), AXTextEditTypePaste, text, m_frame.selection().selection());
601         command->composition()->setRangeDeletedByUnapply(replacedText.replacedRange());
602     }
603
604     if (!isContinuousSpellCheckingEnabled())
605         return;
606
607     Node* nodeToCheck = selection.rootEditableElement();
608     if (!nodeToCheck)
609         return;
610
611     auto rangeToCheck = Range::create(document(), firstPositionInNode(nodeToCheck), lastPositionInNode(nodeToCheck));
612     if (auto request = SpellCheckRequest::create(resolveTextCheckingTypeMask(*nodeToCheck, TextCheckingTypeSpelling | TextCheckingTypeGrammar), TextCheckingProcessBatch, rangeToCheck.copyRef(), rangeToCheck.copyRef()))
613         m_spellChecker->requestCheckingFor(request.releaseNonNull());
614 }
615
616 void Editor::replaceSelectionWithText(const String& text, bool selectReplacement, bool smartReplace, EditAction editingAction)
617 {
618     RefPtr<Range> range = selectedRange();
619     if (!range)
620         return;
621
622     replaceSelectionWithFragment(createFragmentFromText(*range, text), selectReplacement, smartReplace, true, editingAction);
623 }
624
625 RefPtr<Range> Editor::selectedRange()
626 {
627     return m_frame.selection().toNormalizedRange();
628 }
629
630 bool Editor::shouldDeleteRange(Range* range) const
631 {
632     if (!range || range->collapsed())
633         return false;
634     
635     if (!canDeleteRange(range))
636         return false;
637
638     return client() && client()->shouldDeleteRange(range);
639 }
640
641 bool Editor::tryDHTMLCopy()
642 {   
643     if (m_frame.selection().selection().isInPasswordField())
644         return false;
645
646     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().copyEvent);
647 }
648
649 bool Editor::tryDHTMLCut()
650 {
651     if (m_frame.selection().selection().isInPasswordField())
652         return false;
653     
654     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().cutEvent);
655 }
656
657 bool Editor::tryDHTMLPaste()
658 {
659     return !dispatchClipboardEvent(findEventTargetFromSelection(), eventNames().pasteEvent);
660 }
661
662 bool Editor::shouldInsertText(const String& text, Range* range, EditorInsertAction action) const
663 {
664     if (m_frame.mainFrame().loader().shouldSuppressKeyboardInput() && action == EditorInsertAction::Typed)
665         return false;
666
667     return client() && client()->shouldInsertText(text, range, action);
668 }
669
670 void Editor::respondToChangedContents(const VisibleSelection& endingSelection)
671 {
672     if (AXObjectCache::accessibilityEnabled()) {
673         Node* node = endingSelection.start().deprecatedNode();
674         if (AXObjectCache* cache = document().existingAXObjectCache())
675             cache->postNotification(node, AXObjectCache::AXValueChanged, TargetObservableParent);
676     }
677
678     updateMarkersForWordsAffectedByEditing(true);
679
680     if (client())
681         client()->respondToChangedContents();
682 }
683
684 bool Editor::hasBidiSelection() const
685 {
686     if (m_frame.selection().isNone())
687         return false;
688
689     Node* startNode;
690     if (m_frame.selection().isRange()) {
691         startNode = m_frame.selection().selection().start().downstream().deprecatedNode();
692         Node* endNode = m_frame.selection().selection().end().upstream().deprecatedNode();
693         if (enclosingBlock(startNode) != enclosingBlock(endNode))
694             return false;
695     } else
696         startNode = m_frame.selection().selection().visibleStart().deepEquivalent().deprecatedNode();
697
698     if (!startNode)
699         return false;
700
701     auto renderer = startNode->renderer();
702     while (renderer && !is<RenderBlockFlow>(*renderer))
703         renderer = renderer->parent();
704
705     if (!renderer)
706         return false;
707
708     if (!renderer->style().isLeftToRightDirection())
709         return true;
710
711     return downcast<RenderBlockFlow>(*renderer).containsNonZeroBidiLevel();
712 }
713
714 TriState Editor::selectionUnorderedListState() const
715 {
716     if (m_frame.selection().isCaret()) {
717         if (enclosingElementWithTag(m_frame.selection().selection().start(), ulTag))
718             return TrueTriState;
719     } else if (m_frame.selection().isRange()) {
720         auto* startNode = enclosingElementWithTag(m_frame.selection().selection().start(), ulTag);
721         auto* endNode = enclosingElementWithTag(m_frame.selection().selection().end(), ulTag);
722         if (startNode && endNode && startNode == endNode)
723             return TrueTriState;
724     }
725
726     return FalseTriState;
727 }
728
729 TriState Editor::selectionOrderedListState() const
730 {
731     if (m_frame.selection().isCaret()) {
732         if (enclosingElementWithTag(m_frame.selection().selection().start(), olTag))
733             return TrueTriState;
734     } else if (m_frame.selection().isRange()) {
735         auto* startNode = enclosingElementWithTag(m_frame.selection().selection().start(), olTag);
736         auto* endNode = enclosingElementWithTag(m_frame.selection().selection().end(), olTag);
737         if (startNode && endNode && startNode == endNode)
738             return TrueTriState;
739     }
740
741     return FalseTriState;
742 }
743
744 RefPtr<Node> Editor::insertOrderedList()
745 {
746     if (!canEditRichly())
747         return nullptr;
748         
749     RefPtr<Node> newList = InsertListCommand::insertList(document(), InsertListCommand::OrderedList);
750     revealSelectionAfterEditingOperation();
751     return newList;
752 }
753
754 RefPtr<Node> Editor::insertUnorderedList()
755 {
756     if (!canEditRichly())
757         return nullptr;
758         
759     RefPtr<Node> newList = InsertListCommand::insertList(document(), InsertListCommand::UnorderedList);
760     revealSelectionAfterEditingOperation();
761     return newList;
762 }
763
764 bool Editor::canIncreaseSelectionListLevel()
765 {
766     return canEditRichly() && IncreaseSelectionListLevelCommand::canIncreaseSelectionListLevel(&document());
767 }
768
769 bool Editor::canDecreaseSelectionListLevel()
770 {
771     return canEditRichly() && DecreaseSelectionListLevelCommand::canDecreaseSelectionListLevel(&document());
772 }
773
774 RefPtr<Node> Editor::increaseSelectionListLevel()
775 {
776     if (!canEditRichly() || m_frame.selection().isNone())
777         return nullptr;
778     
779     RefPtr<Node> newList = IncreaseSelectionListLevelCommand::increaseSelectionListLevel(&document());
780     revealSelectionAfterEditingOperation();
781     return newList;
782 }
783
784 RefPtr<Node> Editor::increaseSelectionListLevelOrdered()
785 {
786     if (!canEditRichly() || m_frame.selection().isNone())
787         return nullptr;
788     
789     RefPtr<Node> newList = IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered(&document());
790     revealSelectionAfterEditingOperation();
791     return newList;
792 }
793
794 RefPtr<Node> Editor::increaseSelectionListLevelUnordered()
795 {
796     if (!canEditRichly() || m_frame.selection().isNone())
797         return nullptr;
798     
799     RefPtr<Node> newList = IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered(&document());
800     revealSelectionAfterEditingOperation();
801     return newList;
802 }
803
804 void Editor::decreaseSelectionListLevel()
805 {
806     if (!canEditRichly() || m_frame.selection().isNone())
807         return;
808     
809     DecreaseSelectionListLevelCommand::decreaseSelectionListLevel(&document());
810     revealSelectionAfterEditingOperation();
811 }
812
813 void Editor::removeFormattingAndStyle()
814 {
815     RemoveFormatCommand::create(document())->apply();
816 }
817
818 void Editor::clearLastEditCommand() 
819 {
820     m_lastEditCommand = nullptr;
821 }
822
823 Element* Editor::findEventTargetFrom(const VisibleSelection& selection) const
824 {
825     Element* target = selection.start().element();
826     if (!target)
827         target = document().bodyOrFrameset();
828     if (!target)
829         return nullptr;
830
831     return target;
832 }
833
834 Element* Editor::findEventTargetFromSelection() const
835 {
836     return findEventTargetFrom(m_frame.selection().selection());
837 }
838
839 void Editor::applyStyle(StyleProperties* style, EditAction editingAction)
840 {
841     if (style)
842         applyStyle(EditingStyle::create(style), editingAction);
843 }
844
845 void Editor::applyStyle(RefPtr<EditingStyle>&& style, EditAction editingAction)
846 {
847     if (!style)
848         return;
849
850     auto selectionType = m_frame.selection().selection().selectionType();
851     if (selectionType == VisibleSelection::NoSelection)
852         return;
853
854     String inputTypeName = inputTypeNameForEditingAction(editingAction);
855     String inputEventData = inputEventDataForEditingStyleAndAction(*style, editingAction);
856     RefPtr<Element> element = m_frame.selection().selection().rootEditableElement();
857     if (element && !dispatchBeforeInputEvent(*element, inputTypeName, inputEventData))
858         return;
859
860     switch (selectionType) {
861     case VisibleSelection::CaretSelection:
862         computeAndSetTypingStyle(*style, editingAction);
863         break;
864     case VisibleSelection::RangeSelection:
865         ApplyStyleCommand::create(document(), style.get(), editingAction)->apply();
866         break;
867     default:
868         break;
869     }
870
871     client()->didApplyStyle();
872     if (element)
873         dispatchInputEvent(*element, inputTypeName, inputEventData);
874 }
875     
876 bool Editor::shouldApplyStyle(StyleProperties* style, Range* range)
877 {   
878     return client()->shouldApplyStyle(style, range);
879 }
880     
881 void Editor::applyParagraphStyle(StyleProperties* style, EditAction editingAction)
882 {
883     if (!style)
884         return;
885
886     auto selectionType = m_frame.selection().selection().selectionType();
887     if (selectionType == VisibleSelection::NoSelection)
888         return;
889
890     String inputTypeName = inputTypeNameForEditingAction(editingAction);
891     String inputEventData = inputEventDataForEditingStyleAndAction(style, editingAction);
892     RefPtr<Element> element = m_frame.selection().selection().rootEditableElement();
893     if (element && !dispatchBeforeInputEvent(*element, inputTypeName, inputEventData))
894         return;
895
896     ApplyStyleCommand::create(document(), EditingStyle::create(style).ptr(), editingAction, ApplyStyleCommand::ForceBlockProperties)->apply();
897     client()->didApplyStyle();
898     if (element)
899         dispatchInputEvent(*element, inputTypeName, inputEventData);
900 }
901
902 void Editor::applyStyleToSelection(StyleProperties* style, EditAction editingAction)
903 {
904     if (!style || style->isEmpty() || !canEditRichly())
905         return;
906
907     if (!client() || !client()->shouldApplyStyle(style, m_frame.selection().toNormalizedRange().get()))
908         return;
909     applyStyle(style, editingAction);
910 }
911
912 void Editor::applyStyleToSelection(Ref<EditingStyle>&& style, EditAction editingAction)
913 {
914     if (style->isEmpty() || !canEditRichly())
915         return;
916
917     // FIXME: This is wrong for text decorations since m_mutableStyle is empty.
918     if (!client() || !client()->shouldApplyStyle(style->styleWithResolvedTextDecorations().ptr(), m_frame.selection().toNormalizedRange().get()))
919         return;
920
921     applyStyle(WTFMove(style), editingAction);
922 }
923
924 void Editor::applyParagraphStyleToSelection(StyleProperties* style, EditAction editingAction)
925 {
926     if (!style || style->isEmpty() || !canEditRichly())
927         return;
928     
929     if (client() && client()->shouldApplyStyle(style, m_frame.selection().toNormalizedRange().get()))
930         applyParagraphStyle(style, editingAction);
931 }
932
933 bool Editor::selectionStartHasStyle(CSSPropertyID propertyID, const String& value) const
934 {
935     return EditingStyle::create(propertyID, value)->triStateOfStyle(
936         EditingStyle::styleAtSelectionStart(m_frame.selection().selection(), propertyID == CSSPropertyBackgroundColor).get());
937 }
938
939 TriState Editor::selectionHasStyle(CSSPropertyID propertyID, const String& value) const
940 {
941     return EditingStyle::create(propertyID, value)->triStateOfStyle(m_frame.selection().selection());
942 }
943
944 String Editor::selectionStartCSSPropertyValue(CSSPropertyID propertyID)
945 {
946     RefPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(m_frame.selection().selection(),
947         propertyID == CSSPropertyBackgroundColor);
948     if (!selectionStyle || !selectionStyle->style())
949         return String();
950
951     if (propertyID == CSSPropertyFontSize)
952         return String::number(selectionStyle->legacyFontSize(&document()));
953     return selectionStyle->style()->getPropertyValue(propertyID);
954 }
955
956 void Editor::indent()
957 {
958     IndentOutdentCommand::create(document(), IndentOutdentCommand::Indent)->apply();
959 }
960
961 void Editor::outdent()
962 {
963     IndentOutdentCommand::create(document(), IndentOutdentCommand::Outdent)->apply();
964 }
965
966 static void notifyTextFromControls(Element* startRoot, Element* endRoot)
967 {
968     HTMLTextFormControlElement* startingTextControl = enclosingTextFormControl(firstPositionInOrBeforeNode(startRoot));
969     HTMLTextFormControlElement* endingTextControl = enclosingTextFormControl(firstPositionInOrBeforeNode(endRoot));
970     if (startingTextControl)
971         startingTextControl->didEditInnerTextValue();
972     if (endingTextControl && startingTextControl != endingTextControl)
973         endingTextControl->didEditInnerTextValue();
974 }
975
976 static bool dispatchBeforeInputEvents(RefPtr<Element> startRoot, RefPtr<Element> endRoot, const AtomicString& inputTypeName, const String& data = { }, RefPtr<DataTransfer>&& dataTransfer = nullptr, const Vector<RefPtr<StaticRange>>& targetRanges = { }, bool cancelable = true)
977 {
978     bool continueWithDefaultBehavior = true;
979     if (startRoot)
980         continueWithDefaultBehavior &= dispatchBeforeInputEvent(*startRoot, inputTypeName, data, WTFMove(dataTransfer), targetRanges, cancelable);
981     if (endRoot && endRoot != startRoot)
982         continueWithDefaultBehavior &= dispatchBeforeInputEvent(*endRoot, inputTypeName, data, WTFMove(dataTransfer), targetRanges, cancelable);
983     return continueWithDefaultBehavior;
984 }
985
986 static void dispatchInputEvents(RefPtr<Element> startRoot, RefPtr<Element> endRoot, const AtomicString& inputTypeName, const String& data = { }, RefPtr<DataTransfer>&& dataTransfer = nullptr, const Vector<RefPtr<StaticRange>>& targetRanges = { })
987 {
988     if (startRoot)
989         dispatchInputEvent(*startRoot, inputTypeName, data, WTFMove(dataTransfer), targetRanges);
990     if (endRoot && endRoot != startRoot)
991         dispatchInputEvent(*endRoot, inputTypeName, data, WTFMove(dataTransfer), targetRanges);
992 }
993
994 bool Editor::willApplyEditing(CompositeEditCommand& command, Vector<RefPtr<StaticRange>>&& targetRanges) const
995 {
996     if (!command.shouldDispatchInputEvents())
997         return true;
998
999     auto* composition = command.composition();
1000     if (!composition)
1001         return true;
1002
1003     return dispatchBeforeInputEvents(composition->startingRootEditableElement(), composition->endingRootEditableElement(), command.inputEventTypeName(), command.inputEventData(), command.inputEventDataTransfer(), targetRanges, command.isBeforeInputEventCancelable());
1004 }
1005
1006 void Editor::appliedEditing(CompositeEditCommand& command)
1007 {
1008     LOG(Editing, "Editor %p appliedEditing", this);
1009
1010     document().updateLayout();
1011
1012     ASSERT(command.composition());
1013     auto& composition = *command.composition();
1014     VisibleSelection newSelection(command.endingSelection());
1015
1016     notifyTextFromControls(composition.startingRootEditableElement(), composition.endingRootEditableElement());
1017
1018     if (command.isTopLevelCommand()) {
1019         // Don't clear the typing style with this selection change. We do those things elsewhere if necessary.
1020         FrameSelection::SetSelectionOptions options = command.isDictationCommand() ? FrameSelection::DictationTriggered : 0;
1021
1022         changeSelectionAfterCommand(newSelection, options);
1023     }
1024
1025     if (command.shouldDispatchInputEvents())
1026         dispatchInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), command.inputEventTypeName(), command.inputEventData(), command.inputEventDataTransfer());
1027
1028     if (command.isTopLevelCommand()) {
1029         updateEditorUINowIfScheduled();
1030
1031         m_alternativeTextController->respondToAppliedEditing(&command);
1032
1033         if (!command.preservesTypingStyle())
1034             m_frame.selection().clearTypingStyle();
1035
1036         // Command will be equal to last edit command only in the case of typing
1037         if (m_lastEditCommand.get() == &command)
1038             ASSERT(command.isTypingCommand());
1039         else {
1040             // Only register a new undo command if the command passed in is
1041             // different from the last command
1042             m_lastEditCommand = &command;
1043             if (client())
1044                 client()->registerUndoStep(m_lastEditCommand->ensureComposition());
1045         }
1046         respondToChangedContents(newSelection);
1047     }
1048 }
1049
1050 bool Editor::willUnapplyEditing(const EditCommandComposition& composition) const
1051 {
1052     return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyUndo");
1053 }
1054
1055 void Editor::unappliedEditing(EditCommandComposition& composition)
1056 {
1057     document().updateLayout();
1058
1059     notifyTextFromControls(composition.startingRootEditableElement(), composition.endingRootEditableElement());
1060
1061     VisibleSelection newSelection(composition.startingSelection());
1062     changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1063     dispatchInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyUndo");
1064
1065     updateEditorUINowIfScheduled();
1066
1067     m_alternativeTextController->respondToUnappliedEditing(&composition);
1068
1069     m_lastEditCommand = nullptr;
1070     if (auto* client = this->client())
1071         client->registerRedoStep(composition);
1072     respondToChangedContents(newSelection);
1073 }
1074
1075 bool Editor::willReapplyEditing(const EditCommandComposition& composition) const
1076 {
1077     return dispatchBeforeInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyRedo");
1078 }
1079
1080 void Editor::reappliedEditing(EditCommandComposition& composition)
1081 {
1082     document().updateLayout();
1083
1084     notifyTextFromControls(composition.startingRootEditableElement(), composition.endingRootEditableElement());
1085
1086     VisibleSelection newSelection(composition.endingSelection());
1087     changeSelectionAfterCommand(newSelection, FrameSelection::defaultSetSelectionOptions());
1088     dispatchInputEvents(composition.startingRootEditableElement(), composition.endingRootEditableElement(), "historyRedo");
1089     
1090     updateEditorUINowIfScheduled();
1091
1092     m_lastEditCommand = nullptr;
1093     if (auto* client = this->client())
1094         client->registerUndoStep(composition);
1095     respondToChangedContents(newSelection);
1096 }
1097
1098 Editor::Editor(Frame& frame)
1099     : m_frame(frame)
1100     , m_killRing(std::make_unique<PAL::KillRing>())
1101     , m_spellChecker(std::make_unique<SpellChecker>(frame))
1102     , m_alternativeTextController(std::make_unique<AlternativeTextController>(frame))
1103     , m_editorUIUpdateTimer(*this, &Editor::editorUIUpdateTimerFired)
1104 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS)
1105     , m_telephoneNumberDetectionUpdateTimer(*this, &Editor::scanSelectionForTelephoneNumbers)
1106 #endif
1107 {
1108 }
1109
1110 Editor::~Editor()
1111 {
1112 }
1113
1114 void Editor::clear()
1115 {
1116     if (m_compositionNode) {
1117         m_compositionNode = nullptr;
1118         if (EditorClient* client = this->client())
1119             client->discardedComposition(&m_frame);
1120     }
1121     m_customCompositionUnderlines.clear();
1122     m_shouldStyleWithCSS = false;
1123     m_defaultParagraphSeparator = EditorParagraphSeparatorIsDiv;
1124 }
1125
1126 bool Editor::insertText(const String& text, Event* triggeringEvent, TextEventInputType inputType)
1127 {
1128     return m_frame.eventHandler().handleTextInputEvent(text, triggeringEvent, inputType);
1129 }
1130
1131 bool Editor::insertTextForConfirmedComposition(const String& text)
1132 {
1133     return m_frame.eventHandler().handleTextInputEvent(text, 0, TextEventInputComposition);
1134 }
1135
1136 bool Editor::insertDictatedText(const String& text, const Vector<DictationAlternative>& dictationAlternatives, Event* triggeringEvent)
1137 {
1138     return m_alternativeTextController->insertDictatedText(text, dictationAlternatives, triggeringEvent);
1139 }
1140
1141 bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectInsertedText, TextEvent* triggeringEvent)
1142 {
1143     if (text.isEmpty())
1144         return false;
1145
1146     VisibleSelection selection = selectionForCommand(triggeringEvent);
1147     if (!selection.isContentEditable())
1148         return false;
1149     RefPtr<Range> range = selection.toNormalizedRange();
1150
1151     if (!shouldInsertText(text, range.get(), EditorInsertAction::Typed))
1152         return true;
1153
1154     updateMarkersForWordsAffectedByEditing(isSpaceOrNewline(text[0]));
1155
1156     bool shouldConsiderApplyingAutocorrection = false;
1157     if (text == " " || text == "\t")
1158         shouldConsiderApplyingAutocorrection = true;
1159
1160     if (text.length() == 1 && u_ispunct(text[0]) && !isAmbiguousBoundaryCharacter(text[0]))
1161         shouldConsiderApplyingAutocorrection = true;
1162
1163     bool autocorrectionWasApplied = shouldConsiderApplyingAutocorrection && m_alternativeTextController->applyAutocorrectionBeforeTypingIfAppropriate();
1164
1165     // Get the selection to use for the event that triggered this insertText.
1166     // If the event handler changed the selection, we may want to use a different selection
1167     // that is contained in the event target.
1168     selection = selectionForCommand(triggeringEvent);
1169     if (selection.isContentEditable()) {
1170         if (Node* selectionStart = selection.start().deprecatedNode()) {
1171             Ref<Document> document(selectionStart->document());
1172
1173             // Insert the text
1174             if (triggeringEvent && triggeringEvent->isDictation())
1175                 DictationCommand::insertText(document, text, triggeringEvent->dictationAlternatives(), selection);
1176             else {
1177                 TypingCommand::Options options = 0;
1178                 if (selectInsertedText)
1179                     options |= TypingCommand::SelectInsertedText;
1180                 if (autocorrectionWasApplied)
1181                     options |= TypingCommand::RetainAutocorrectionIndicator;
1182                 if (triggeringEvent && triggeringEvent->isAutocompletion())
1183                     options |= TypingCommand::IsAutocompletion;
1184                 TypingCommand::insertText(document, text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionFinal : TypingCommand::TextCompositionNone);
1185             }
1186
1187             // Reveal the current selection
1188             if (Frame* editedFrame = document->frame())
1189                 if (Page* page = editedFrame->page()) {
1190 #if PLATFORM(IOS)
1191                     SelectionRevealMode revealMode = SelectionRevealMode::RevealUpToMainFrame;
1192 #else
1193                     SelectionRevealMode revealMode = SelectionRevealMode::Reveal;
1194 #endif
1195                     page->focusController().focusedOrMainFrame().selection().revealSelection(revealMode, ScrollAlignment::alignCenterIfNeeded);
1196                 }
1197         }
1198     }
1199
1200     return true;
1201 }
1202
1203 bool Editor::insertLineBreak()
1204 {
1205     if (!canEdit())
1206         return false;
1207
1208     if (!shouldInsertText("\n", m_frame.selection().toNormalizedRange().get(), EditorInsertAction::Typed))
1209         return true;
1210
1211     VisiblePosition caret = m_frame.selection().selection().visibleStart();
1212     bool alignToEdge = isEndOfEditableOrNonEditableContent(caret);
1213     bool autocorrectionIsApplied = m_alternativeTextController->applyAutocorrectionBeforeTypingIfAppropriate();
1214     TypingCommand::insertLineBreak(document(), autocorrectionIsApplied ? TypingCommand::RetainAutocorrectionIndicator : 0);
1215     revealSelectionAfterEditingOperation(alignToEdge ? ScrollAlignment::alignToEdgeIfNeeded : ScrollAlignment::alignCenterIfNeeded);
1216
1217     return true;
1218 }
1219
1220 bool Editor::insertParagraphSeparator()
1221 {
1222     if (!canEdit())
1223         return false;
1224
1225     if (!canEditRichly())
1226         return insertLineBreak();
1227
1228     if (!shouldInsertText("\n", m_frame.selection().toNormalizedRange().get(), EditorInsertAction::Typed))
1229         return true;
1230
1231     VisiblePosition caret = m_frame.selection().selection().visibleStart();
1232     bool alignToEdge = isEndOfEditableOrNonEditableContent(caret);
1233     bool autocorrectionIsApplied = m_alternativeTextController->applyAutocorrectionBeforeTypingIfAppropriate();
1234     TypingCommand::insertParagraphSeparator(document(), autocorrectionIsApplied ? TypingCommand::RetainAutocorrectionIndicator : 0);
1235     revealSelectionAfterEditingOperation(alignToEdge ? ScrollAlignment::alignToEdgeIfNeeded : ScrollAlignment::alignCenterIfNeeded);
1236
1237     return true;
1238 }
1239
1240 bool Editor::insertParagraphSeparatorInQuotedContent()
1241 {
1242     // FIXME: Why is this missing calls to canEdit, canEditRichly, etc.?
1243     TypingCommand::insertParagraphSeparatorInQuotedContent(document());
1244     revealSelectionAfterEditingOperation();
1245     return true;
1246 }
1247
1248 void Editor::cut()
1249 {
1250     if (tryDHTMLCut())
1251         return; // DHTML did the whole operation
1252     if (!canCut()) {
1253         PAL::systemBeep();
1254         return;
1255     }
1256
1257     performCutOrCopy(CutAction);
1258 }
1259
1260 void Editor::copy()
1261 {
1262     if (tryDHTMLCopy())
1263         return; // DHTML did the whole operation
1264     if (!canCopy()) {
1265         PAL::systemBeep();
1266         return;
1267     }
1268
1269     performCutOrCopy(CopyAction);
1270 }
1271
1272 void Editor::postTextStateChangeNotificationForCut(const String& text, const VisibleSelection& selection)
1273 {
1274     if (!AXObjectCache::accessibilityEnabled())
1275         return;
1276     if (!text.length())
1277         return;
1278     AXObjectCache* cache = document().existingAXObjectCache();
1279     if (!cache)
1280         return;
1281     cache->postTextStateChangeNotification(selection.start().anchorNode(), AXTextEditTypeCut, text, selection.start());
1282 }
1283
1284 void Editor::performCutOrCopy(EditorActionSpecifier action)
1285 {
1286     RefPtr<Range> selection = selectedRange();
1287     willWriteSelectionToPasteboard(selection.get());
1288     if (action == CutAction) {
1289         if (!shouldDeleteRange(selection.get()))
1290             return;
1291
1292         updateMarkersForWordsAffectedByEditing(true);
1293     }
1294
1295     if (enclosingTextFormControl(m_frame.selection().selection().start()))
1296         Pasteboard::createForCopyAndPaste()->writePlainText(selectedTextForDataTransfer(), canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
1297     else {
1298         HTMLImageElement* imageElement = nullptr;
1299         if (action == CopyAction)
1300             imageElement = imageElementFromImageDocument(document());
1301
1302         if (imageElement) {
1303 #if PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)
1304             writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *imageElement, document().url(), document().title());
1305 #else
1306             Pasteboard::createForCopyAndPaste()->writeImage(*imageElement, document().url(), document().title());
1307 #endif
1308         } else {
1309 #if PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)
1310             writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
1311 #else
1312             // FIXME: Convert all other platforms to match Mac and delete this.
1313             Pasteboard::createForCopyAndPaste()->writeSelection(*selection, canSmartCopyOrDelete(), m_frame, IncludeImageAltTextForDataTransfer);
1314 #endif
1315         }
1316     }
1317
1318     didWriteSelectionToPasteboard();
1319     if (action == CutAction) {
1320         String text;
1321         if (AXObjectCache::accessibilityEnabled())
1322             text = AccessibilityObject::stringForVisiblePositionRange(m_frame.selection().selection());
1323         deleteSelectionWithSmartDelete(canSmartCopyOrDelete(), EditActionCut);
1324         if (AXObjectCache::accessibilityEnabled())
1325             postTextStateChangeNotificationForCut(text, m_frame.selection().selection());
1326     }
1327 }
1328
1329 void Editor::paste()
1330 {
1331     paste(*Pasteboard::createForCopyAndPaste());
1332 }
1333
1334 void Editor::paste(Pasteboard& pasteboard)
1335 {
1336     if (tryDHTMLPaste())
1337         return; // DHTML did the whole operation
1338     if (!canPaste())
1339         return;
1340     updateMarkersForWordsAffectedByEditing(false);
1341     ResourceCacheValidationSuppressor validationSuppressor(document().cachedResourceLoader());
1342     if (m_frame.selection().selection().isContentRichlyEditable())
1343         pasteWithPasteboard(&pasteboard, true);
1344     else
1345         pasteAsPlainTextWithPasteboard(pasteboard);
1346 }
1347
1348 void Editor::pasteAsPlainText()
1349 {
1350     if (tryDHTMLPaste())
1351         return;
1352     if (!canPaste())
1353         return;
1354     updateMarkersForWordsAffectedByEditing(false);
1355     pasteAsPlainTextWithPasteboard(*Pasteboard::createForCopyAndPaste());
1356 }
1357
1358 void Editor::performDelete()
1359 {
1360     if (!canDelete()) {
1361         PAL::systemBeep();
1362         return;
1363     }
1364
1365     addRangeToKillRing(*selectedRange().get(), KillRingInsertionMode::AppendText);
1366     deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
1367
1368     // clear the "start new kill ring sequence" setting, because it was set to true
1369     // when the selection was updated by deleting the range
1370     setStartNewKillRingSequence(false);
1371 }
1372
1373 void Editor::simplifyMarkup(Node* startNode, Node* endNode)
1374 {
1375     if (!startNode)
1376         return;
1377     if (endNode) {
1378         if (&startNode->document() != &endNode->document())
1379             return;
1380         // check if start node is before endNode
1381         Node* node = startNode;
1382         while (node && node != endNode)
1383             node = NodeTraversal::next(*node);
1384         if (!node)
1385             return;
1386     }
1387     
1388     SimplifyMarkupCommand::create(document(), startNode, endNode ? NodeTraversal::next(*endNode) : nullptr)->apply();
1389 }
1390
1391 void Editor::copyURL(const URL& url, const String& title)
1392 {
1393     copyURL(url, title, *Pasteboard::createForCopyAndPaste());
1394 }
1395
1396 void Editor::copyURL(const URL& url, const String& title, Pasteboard& pasteboard)
1397 {
1398     PasteboardURL pasteboardURL;
1399     pasteboardURL.url = url;
1400     pasteboardURL.title = title;
1401
1402 #if PLATFORM(MAC)
1403     pasteboardURL.userVisibleForm = userVisibleString(url);
1404 #endif
1405
1406     pasteboard.write(pasteboardURL);
1407 }
1408
1409 PasteboardWriterData::URL Editor::pasteboardWriterURL(const URL& url, const String& title)
1410 {
1411     PasteboardWriterData::URL result;
1412
1413     result.url = url;
1414     result.title = title;
1415 #if PLATFORM(MAC)
1416     result.userVisibleForm = userVisibleString(url);
1417 #endif
1418
1419     return result;
1420 }
1421
1422 #if !PLATFORM(IOS)
1423
1424 void Editor::copyImage(const HitTestResult& result)
1425 {
1426     Element* element = result.innerNonSharedElement();
1427     if (!element)
1428         return;
1429
1430     URL url = result.absoluteLinkURL();
1431     if (url.isEmpty())
1432         url = result.absoluteImageURL();
1433
1434 #if PLATFORM(COCOA) || PLATFORM(GTK) || PLATFORM(WPE)
1435     writeImageToPasteboard(*Pasteboard::createForCopyAndPaste(), *element, url, result.altDisplayString());
1436 #else
1437     Pasteboard::createForCopyAndPaste()->writeImage(*element, url, result.altDisplayString());
1438 #endif
1439 }
1440
1441 #endif
1442
1443 bool Editor::isContinuousSpellCheckingEnabled() const
1444 {
1445     return client() && client()->isContinuousSpellCheckingEnabled();
1446 }
1447
1448 void Editor::toggleContinuousSpellChecking()
1449 {
1450     if (client())
1451         client()->toggleContinuousSpellChecking();
1452 }
1453
1454 bool Editor::isGrammarCheckingEnabled()
1455 {
1456     return client() && client()->isGrammarCheckingEnabled();
1457 }
1458
1459 void Editor::toggleGrammarChecking()
1460 {
1461     if (client())
1462         client()->toggleGrammarChecking();
1463 }
1464
1465 int Editor::spellCheckerDocumentTag()
1466 {
1467     return client() ? client()->spellCheckerDocumentTag() : 0;
1468 }
1469
1470 #if USE(APPKIT)
1471
1472 void Editor::uppercaseWord()
1473 {
1474     if (client())
1475         client()->uppercaseWord();
1476 }
1477
1478 void Editor::lowercaseWord()
1479 {
1480     if (client())
1481         client()->lowercaseWord();
1482 }
1483
1484 void Editor::capitalizeWord()
1485 {
1486     if (client())
1487         client()->capitalizeWord();
1488 }
1489     
1490 #endif
1491
1492 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1493
1494 void Editor::showSubstitutionsPanel()
1495 {
1496     if (!client()) {
1497         LOG_ERROR("No NSSpellChecker");
1498         return;
1499     }
1500
1501     if (client()->substitutionsPanelIsShowing()) {
1502         client()->showSubstitutionsPanel(false);
1503         return;
1504     }
1505     client()->showSubstitutionsPanel(true);
1506 }
1507
1508 bool Editor::substitutionsPanelIsShowing()
1509 {
1510     if (!client())
1511         return false;
1512     return client()->substitutionsPanelIsShowing();
1513 }
1514
1515 void Editor::toggleSmartInsertDelete()
1516 {
1517     if (client())
1518         client()->toggleSmartInsertDelete();
1519 }
1520
1521 bool Editor::isAutomaticQuoteSubstitutionEnabled()
1522 {
1523     return client() && client()->isAutomaticQuoteSubstitutionEnabled();
1524 }
1525
1526 void Editor::toggleAutomaticQuoteSubstitution()
1527 {
1528     if (client())
1529         client()->toggleAutomaticQuoteSubstitution();
1530 }
1531
1532 bool Editor::isAutomaticLinkDetectionEnabled()
1533 {
1534     return client() && client()->isAutomaticLinkDetectionEnabled();
1535 }
1536
1537 void Editor::toggleAutomaticLinkDetection()
1538 {
1539     if (client())
1540         client()->toggleAutomaticLinkDetection();
1541 }
1542
1543 bool Editor::isAutomaticDashSubstitutionEnabled()
1544 {
1545     return client() && client()->isAutomaticDashSubstitutionEnabled();
1546 }
1547
1548 void Editor::toggleAutomaticDashSubstitution()
1549 {
1550     if (client())
1551         client()->toggleAutomaticDashSubstitution();
1552 }
1553
1554 bool Editor::isAutomaticTextReplacementEnabled()
1555 {
1556     return client() && client()->isAutomaticTextReplacementEnabled();
1557 }
1558
1559 void Editor::toggleAutomaticTextReplacement()
1560 {
1561     if (client())
1562         client()->toggleAutomaticTextReplacement();
1563 }
1564
1565 bool Editor::isAutomaticSpellingCorrectionEnabled()
1566 {
1567     return m_alternativeTextController->isAutomaticSpellingCorrectionEnabled();
1568 }
1569
1570 void Editor::toggleAutomaticSpellingCorrection()
1571 {
1572     if (client())
1573         client()->toggleAutomaticSpellingCorrection();
1574 }
1575
1576 #endif
1577
1578 bool Editor::shouldEndEditing(Range* range)
1579 {
1580     return client() && client()->shouldEndEditing(range);
1581 }
1582
1583 bool Editor::shouldBeginEditing(Range* range)
1584 {
1585     return client() && client()->shouldBeginEditing(range);
1586 }
1587
1588 void Editor::clearUndoRedoOperations()
1589 {
1590     if (client())
1591         client()->clearUndoRedoOperations();
1592 }
1593
1594 bool Editor::canUndo()
1595 {
1596     return client() && client()->canUndo();
1597 }
1598
1599 void Editor::undo()
1600 {
1601     if (client())
1602         client()->undo();
1603 }
1604
1605 bool Editor::canRedo()
1606 {
1607     return client() && client()->canRedo();
1608 }
1609
1610 void Editor::redo()
1611 {
1612     if (client())
1613         client()->redo();
1614 }
1615
1616 void Editor::didBeginEditing()
1617 {
1618     if (client())
1619         client()->didBeginEditing();
1620 }
1621
1622 void Editor::didEndEditing()
1623 {
1624     if (client())
1625         client()->didEndEditing();
1626 }
1627
1628 void Editor::willWriteSelectionToPasteboard(Range* range)
1629 {
1630     if (client())
1631         client()->willWriteSelectionToPasteboard(range);
1632 }
1633
1634 void Editor::didWriteSelectionToPasteboard()
1635 {
1636     if (client())
1637         client()->didWriteSelectionToPasteboard();
1638 }
1639
1640 void Editor::toggleBold()
1641 {
1642     command("ToggleBold").execute();
1643 }
1644
1645 void Editor::toggleUnderline()
1646 {
1647     command("ToggleUnderline").execute();
1648 }
1649
1650 void Editor::setBaseWritingDirection(WritingDirection direction)
1651 {
1652 #if PLATFORM(IOS)
1653     if (inSameParagraph(m_frame.selection().selection().visibleStart(), m_frame.selection().selection().visibleEnd()) && 
1654         baseWritingDirectionForSelectionStart() == direction)
1655         return;
1656 #endif
1657         
1658     Element* focusedElement = document().focusedElement();
1659     if (is<HTMLTextFormControlElement>(focusedElement)) {
1660         if (direction == NaturalWritingDirection)
1661             return;
1662
1663         auto& focusedFormElement = downcast<HTMLTextFormControlElement>(*focusedElement);
1664         auto directionValue = direction == LeftToRightWritingDirection ? "ltr" : "rtl";
1665         auto writingDirectionInputTypeName = inputTypeNameForEditingAction(EditActionSetWritingDirection);
1666         if (!dispatchBeforeInputEvent(focusedFormElement, writingDirectionInputTypeName, directionValue))
1667             return;
1668
1669         focusedFormElement.setAttributeWithoutSynchronization(dirAttr, directionValue);
1670         dispatchInputEvent(focusedFormElement, writingDirectionInputTypeName, directionValue);
1671         document().updateStyleIfNeeded();
1672         return;
1673     }
1674
1675     RefPtr<MutableStyleProperties> style = MutableStyleProperties::create();
1676     style->setProperty(CSSPropertyDirection, direction == LeftToRightWritingDirection ? "ltr" : direction == RightToLeftWritingDirection ? "rtl" : "inherit", false);
1677     applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection);
1678 }
1679
1680 WritingDirection Editor::baseWritingDirectionForSelectionStart() const
1681 {
1682     WritingDirection result = LeftToRightWritingDirection;
1683
1684     Position pos = m_frame.selection().selection().visibleStart().deepEquivalent();
1685     Node* node = pos.deprecatedNode();
1686     if (!node)
1687         return result;
1688
1689     auto renderer = node->renderer();
1690     if (!renderer)
1691         return result;
1692
1693     if (!renderer->isRenderBlockFlow()) {
1694         renderer = renderer->containingBlock();
1695         if (!renderer)
1696             return result;
1697     }
1698
1699     switch (renderer->style().direction()) {
1700     case LTR:
1701         return LeftToRightWritingDirection;
1702     case RTL:
1703         return RightToLeftWritingDirection;
1704     }
1705     
1706     return result;
1707 }
1708
1709 void Editor::selectComposition()
1710 {
1711     RefPtr<Range> range = compositionRange();
1712     if (!range)
1713         return;
1714     
1715     // The composition can start inside a composed character sequence, so we have to override checks.
1716     // See <http://bugs.webkit.org/show_bug.cgi?id=15781>
1717     VisibleSelection selection;
1718     selection.setWithoutValidation(range->startPosition(), range->endPosition());
1719     m_frame.selection().setSelection(selection, 0);
1720 }
1721
1722 void Editor::confirmComposition()
1723 {
1724     if (!m_compositionNode)
1725         return;
1726     setComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), ConfirmComposition);
1727 }
1728
1729 void Editor::cancelComposition()
1730 {
1731     if (!m_compositionNode)
1732         return;
1733     setComposition(emptyString(), CancelComposition);
1734 }
1735
1736 bool Editor::cancelCompositionIfSelectionIsInvalid()
1737 {
1738     unsigned start;
1739     unsigned end;
1740     if (!hasComposition() || ignoreSelectionChanges() || getCompositionSelection(start, end))
1741         return false;
1742
1743     cancelComposition();
1744     return true;
1745 }
1746
1747 void Editor::confirmComposition(const String& text)
1748 {
1749     setComposition(text, ConfirmComposition);
1750 }
1751
1752 void Editor::setComposition(const String& text, SetCompositionMode mode)
1753 {
1754     ASSERT(mode == ConfirmComposition || mode == CancelComposition);
1755     UserTypingGestureIndicator typingGestureIndicator(m_frame);
1756
1757     setIgnoreSelectionChanges(true);
1758
1759     if (mode == CancelComposition)
1760         ASSERT(text == emptyString());
1761     else
1762         selectComposition();
1763
1764     m_compositionNode = nullptr;
1765     m_customCompositionUnderlines.clear();
1766
1767     if (m_frame.selection().isNone()) {
1768         setIgnoreSelectionChanges(false);
1769         return;
1770     }
1771
1772     // Always delete the current composition before inserting the finalized composition text if we're confirming our composition.
1773     // Our default behavior (if the beforeinput event is not prevented) is to insert the finalized composition text back in.
1774     // We pass TypingCommand::TextCompositionPending here to indicate that we are deleting the pending composition.
1775     if (mode != CancelComposition)
1776         TypingCommand::deleteSelection(document(), 0, TypingCommand::TextCompositionPending);
1777
1778     insertTextForConfirmedComposition(text);
1779
1780     if (auto* target = document().focusedElement())
1781         target->dispatchEvent(CompositionEvent::create(eventNames().compositionendEvent, document().domWindow(), text));
1782
1783     if (mode == CancelComposition) {
1784         // An open typing command that disagrees about current selection would cause issues with typing later on.
1785         TypingCommand::closeTyping(&m_frame);
1786     }
1787
1788     setIgnoreSelectionChanges(false);
1789 }
1790
1791 void Editor::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, unsigned selectionStart, unsigned selectionEnd)
1792 {
1793     Ref<Frame> protection(m_frame);
1794
1795     UserTypingGestureIndicator typingGestureIndicator(m_frame);
1796
1797     setIgnoreSelectionChanges(true);
1798
1799     // Updates styles before setting selection for composition to prevent
1800     // inserting the previous composition text into text nodes oddly.
1801     // See https://bugs.webkit.org/show_bug.cgi?id=46868
1802     document().updateStyleIfNeeded();
1803
1804     selectComposition();
1805
1806     if (m_frame.selection().isNone()) {
1807         setIgnoreSelectionChanges(false);
1808         return;
1809     }
1810
1811     String originalText = selectedText();
1812     bool isStartingToRecomposeExistingRange = !text.isEmpty() && selectionStart < selectionEnd && !hasComposition();
1813     if (isStartingToRecomposeExistingRange) {
1814         // We pass TypingCommand::TextCompositionFinal here to indicate that we are removing composition text that has been finalized.
1815         TypingCommand::deleteSelection(document(), 0, TypingCommand::TextCompositionFinal);
1816         const VisibleSelection& currentSelection = m_frame.selection().selection();
1817         if (currentSelection.isRange()) {
1818             // If deletion was prevented, then we need to collapse the selection to the end so that the original text will not be recomposed.
1819             m_frame.selection().setSelection({ currentSelection.end(), currentSelection.end() });
1820         }
1821     }
1822
1823 #if PLATFORM(IOS)
1824     client()->startDelayingAndCoalescingContentChangeNotifications();
1825 #endif
1826
1827     Element* target = document().focusedElement();
1828     if (target) {
1829         // Dispatch an appropriate composition event to the focused node.
1830         // We check the composition status and choose an appropriate composition event since this
1831         // function is used for three purposes:
1832         // 1. Starting a new composition.
1833         //    Send a compositionstart and a compositionupdate event when this function creates
1834         //    a new composition node, i.e.
1835         //    m_compositionNode == 0 && !text.isEmpty().
1836         //    Sending a compositionupdate event at this time ensures that at least one
1837         //    compositionupdate event is dispatched.
1838         // 2. Updating the existing composition node.
1839         //    Send a compositionupdate event when this function updates the existing composition
1840         //    node, i.e. m_compositionNode != 0 && !text.isEmpty().
1841         // 3. Canceling the ongoing composition.
1842         //    Send a compositionend event when function deletes the existing composition node, i.e.
1843         //    m_compositionNode != 0 && test.isEmpty().
1844         RefPtr<CompositionEvent> event;
1845         if (!m_compositionNode) {
1846             // We should send a compositionstart event only when the given text is not empty because this
1847             // function doesn't create a composition node when the text is empty.
1848             if (!text.isEmpty()) {
1849                 target->dispatchEvent(CompositionEvent::create(eventNames().compositionstartEvent, document().domWindow(), originalText));
1850                 event = CompositionEvent::create(eventNames().compositionupdateEvent, document().domWindow(), text);
1851             }
1852         } else if (!text.isEmpty())
1853             event = CompositionEvent::create(eventNames().compositionupdateEvent, document().domWindow(), text);
1854
1855         if (event)
1856             target->dispatchEvent(*event);
1857     }
1858
1859     // If text is empty, then delete the old composition here.  If text is non-empty, InsertTextCommand::input
1860     // will delete the old composition with an optimized replace operation.
1861     if (text.isEmpty()) {
1862         TypingCommand::deleteSelection(document(), TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionPending);
1863         if (target)
1864             target->dispatchEvent(CompositionEvent::create(eventNames().compositionendEvent, document().domWindow(), text));
1865     }
1866
1867     m_compositionNode = nullptr;
1868     m_customCompositionUnderlines.clear();
1869
1870     if (!text.isEmpty()) {
1871         TypingCommand::insertText(document(), text, TypingCommand::SelectInsertedText | TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionPending);
1872
1873         // Find out what node has the composition now.
1874         Position base = m_frame.selection().selection().base().downstream();
1875         Position extent = m_frame.selection().selection().extent();
1876         Node* baseNode = base.deprecatedNode();
1877         unsigned baseOffset = base.deprecatedEditingOffset();
1878         Node* extentNode = extent.deprecatedNode();
1879         unsigned extentOffset = extent.deprecatedEditingOffset();
1880
1881         if (is<Text>(baseNode) && baseNode == extentNode && baseOffset + text.length() == extentOffset) {
1882             m_compositionNode = downcast<Text>(baseNode);
1883             m_compositionStart = baseOffset;
1884             m_compositionEnd = extentOffset;
1885             m_customCompositionUnderlines = underlines;
1886             for (auto& underline : m_customCompositionUnderlines) {
1887                 underline.startOffset += baseOffset;
1888                 underline.endOffset += baseOffset;
1889             }
1890             if (baseNode->renderer())
1891                 baseNode->renderer()->repaint();
1892
1893             unsigned start = std::min(baseOffset + selectionStart, extentOffset);
1894             unsigned end = std::min(std::max(start, baseOffset + selectionEnd), extentOffset);
1895             RefPtr<Range> selectedRange = Range::create(baseNode->document(), baseNode, start, baseNode, end);
1896             m_frame.selection().setSelectedRange(selectedRange.get(), DOWNSTREAM, false);
1897         }
1898     }
1899
1900     setIgnoreSelectionChanges(false);
1901
1902 #if PLATFORM(IOS)        
1903     client()->stopDelayingAndCoalescingContentChangeNotifications();
1904 #endif
1905 }
1906
1907 void Editor::ignoreSpelling()
1908 {
1909     if (!client())
1910         return;
1911         
1912     RefPtr<Range> selectedRange = m_frame.selection().toNormalizedRange();
1913     if (selectedRange)
1914         document().markers().removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
1915
1916     String text = selectedText();
1917     ASSERT(text.length());
1918     textChecker()->ignoreWordInSpellDocument(text);
1919 }
1920
1921 void Editor::learnSpelling()
1922 {
1923     if (!client())
1924         return;
1925         
1926     // FIXME: On Mac OS X, when use "learn" button on "Spelling and Grammar" panel, we don't call this function. It should remove misspelling markers around the learned word, see <rdar://problem/5396072>.
1927
1928     RefPtr<Range> selectedRange = m_frame.selection().toNormalizedRange();
1929     if (selectedRange)
1930         document().markers().removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
1931
1932     String text = selectedText();
1933     ASSERT(text.length());
1934     textChecker()->learnWord(text);
1935 }
1936
1937 #if !PLATFORM(IOS)
1938
1939 void Editor::advanceToNextMisspelling(bool startBeforeSelection)
1940 {
1941     Ref<Frame> protection(m_frame);
1942
1943     // The basic approach is to search in two phases - from the selection end to the end of the doc, and
1944     // then we wrap and search from the doc start to (approximately) where we started.
1945     
1946     // Start at the end of the selection, search to edge of document.  Starting at the selection end makes
1947     // repeated "check spelling" commands work.
1948     VisibleSelection selection(m_frame.selection().selection());
1949     Ref<Range> spellingSearchRange = rangeOfContents(document());
1950
1951     bool startedWithSelection = false;
1952     if (selection.start().deprecatedNode()) {
1953         startedWithSelection = true;
1954         if (startBeforeSelection) {
1955             VisiblePosition start(selection.visibleStart());
1956             // We match AppKit's rule: Start 1 character before the selection.
1957             VisiblePosition oneBeforeStart = start.previous();
1958             setStart(spellingSearchRange.ptr(), oneBeforeStart.isNotNull() ? oneBeforeStart : start);
1959         } else
1960             setStart(spellingSearchRange.ptr(), selection.visibleEnd());
1961     }
1962
1963     Position position = spellingSearchRange->startPosition();
1964     if (!isEditablePosition(position)) {
1965         // This shouldn't happen in very often because the Spelling menu items aren't enabled unless the
1966         // selection is editable.
1967         // This can happen in Mail for a mix of non-editable and editable content (like Stationary), 
1968         // when spell checking the whole document before sending the message.
1969         // In that case the document might not be editable, but there are editable pockets that need to be spell checked.
1970
1971         position = VisiblePosition(firstEditablePositionAfterPositionInRoot(position, document().documentElement())).deepEquivalent();
1972         if (position.isNull())
1973             return;
1974         
1975         Position rangeCompliantPosition = position.parentAnchoredEquivalent();
1976         if (rangeCompliantPosition.deprecatedNode())
1977             spellingSearchRange->setStart(*rangeCompliantPosition.deprecatedNode(), rangeCompliantPosition.deprecatedEditingOffset());
1978         startedWithSelection = false; // won't need to wrap
1979     }
1980     
1981     // topNode defines the whole range we want to operate on 
1982     auto* topNode = highestEditableRoot(position);
1983     // FIXME: lastOffsetForEditing() is wrong here if editingIgnoresContent(highestEditableRoot()) returns true (e.g. a <table>)
1984     if (topNode)
1985         spellingSearchRange->setEnd(*topNode, lastOffsetForEditing(*topNode));
1986
1987     // If spellingSearchRange starts in the middle of a word, advance to the next word so we start checking
1988     // at a word boundary. Going back by one char and then forward by a word does the trick.
1989     if (startedWithSelection) {
1990         VisiblePosition oneBeforeStart = startVisiblePosition(spellingSearchRange.ptr(), DOWNSTREAM).previous();
1991         if (oneBeforeStart.isNotNull())
1992             setStart(spellingSearchRange.ptr(), endOfWord(oneBeforeStart));
1993         // else we were already at the start of the editable node
1994     }
1995
1996     if (spellingSearchRange->collapsed())
1997         return; // nothing to search in
1998     
1999     // Get the spell checker if it is available
2000     if (!client())
2001         return;
2002         
2003     // We go to the end of our first range instead of the start of it, just to be sure
2004     // we don't get foiled by any word boundary problems at the start.  It means we might
2005     // do a tiny bit more searching.
2006     Node& searchEndNodeAfterWrap = spellingSearchRange->endContainer();
2007     int searchEndOffsetAfterWrap = spellingSearchRange->endOffset();
2008     
2009     int misspellingOffset = 0;
2010     GrammarDetail grammarDetail;
2011     int grammarPhraseOffset = 0;
2012     RefPtr<Range> grammarSearchRange;
2013     String badGrammarPhrase;
2014     String misspelledWord;
2015
2016     bool isSpelling = true;
2017     int foundOffset = 0;
2018     String foundItem;
2019     RefPtr<Range> firstMisspellingRange;
2020     if (unifiedTextCheckerEnabled()) {
2021         grammarSearchRange = spellingSearchRange->cloneRange();
2022         foundItem = TextCheckingHelper(*client(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
2023         if (isSpelling) {
2024             misspelledWord = foundItem;
2025             misspellingOffset = foundOffset;
2026         } else {
2027             badGrammarPhrase = foundItem;
2028             grammarPhraseOffset = foundOffset;
2029         }
2030     } else {
2031         misspelledWord = TextCheckingHelper(*client(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange);
2032
2033 #if USE(GRAMMAR_CHECKING)
2034         grammarSearchRange = spellingSearchRange->cloneRange();
2035         if (!misspelledWord.isEmpty()) {
2036             // Stop looking at start of next misspelled word
2037             CharacterIterator chars(*grammarSearchRange);
2038             chars.advance(misspellingOffset);
2039             grammarSearchRange->setEnd(chars.range()->startContainer(), chars.range()->startOffset());
2040         }
2041     
2042         if (isGrammarCheckingEnabled())
2043             badGrammarPhrase = TextCheckingHelper(*client(), *grammarSearchRange).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false);
2044 #endif
2045     }
2046     
2047     // If we found neither bad grammar nor a misspelled word, wrap and try again (but don't bother if we started at the beginning of the
2048     // block rather than at a selection).
2049     if (startedWithSelection && !misspelledWord && !badGrammarPhrase) {
2050         if (topNode)
2051             spellingSearchRange->setStart(*topNode, 0);
2052         // going until the end of the very first chunk we tested is far enough
2053         spellingSearchRange->setEnd(searchEndNodeAfterWrap, searchEndOffsetAfterWrap);
2054         
2055         if (unifiedTextCheckerEnabled()) {
2056             grammarSearchRange = spellingSearchRange->cloneRange();
2057             foundItem = TextCheckingHelper(*client(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
2058             if (isSpelling) {
2059                 misspelledWord = foundItem;
2060                 misspellingOffset = foundOffset;
2061             } else {
2062                 badGrammarPhrase = foundItem;
2063                 grammarPhraseOffset = foundOffset;
2064             }
2065         } else {
2066             misspelledWord = TextCheckingHelper(*client(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange);
2067
2068 #if USE(GRAMMAR_CHECKING)
2069             grammarSearchRange = spellingSearchRange->cloneRange();
2070             if (!misspelledWord.isEmpty()) {
2071                 // Stop looking at start of next misspelled word
2072                 CharacterIterator chars(*grammarSearchRange);
2073                 chars.advance(misspellingOffset);
2074                 grammarSearchRange->setEnd(chars.range()->startContainer(), chars.range()->startOffset());
2075             }
2076
2077             if (isGrammarCheckingEnabled())
2078                 badGrammarPhrase = TextCheckingHelper(*client(), *grammarSearchRange).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false);
2079 #endif
2080         }
2081     }
2082     
2083 #if !USE(GRAMMAR_CHECKING)
2084     ASSERT(badGrammarPhrase.isEmpty());
2085     UNUSED_PARAM(grammarPhraseOffset);
2086 #else
2087     if (!badGrammarPhrase.isEmpty()) {
2088         // We found bad grammar. Since we only searched for bad grammar up to the first misspelled word, the bad grammar
2089         // takes precedence and we ignore any potential misspelled word. Select the grammar detail, update the spelling
2090         // panel, and store a marker so we draw the green squiggle later.
2091         
2092         ASSERT(badGrammarPhrase.length() > 0);
2093         ASSERT(grammarDetail.location != -1 && grammarDetail.length > 0);
2094         
2095         // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
2096         RefPtr<Range> badGrammarRange = TextIterator::subrange(*grammarSearchRange, grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
2097         m_frame.selection().setSelection(VisibleSelection(*badGrammarRange, SEL_DEFAULT_AFFINITY));
2098         m_frame.selection().revealSelection();
2099         
2100         client()->updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail);
2101         document().markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
2102     } else
2103 #endif
2104     if (!misspelledWord.isEmpty()) {
2105         // We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store
2106         // a marker so we draw the red squiggle later.
2107         
2108         auto misspellingRange = TextIterator::subrange(spellingSearchRange, misspellingOffset, misspelledWord.length());
2109         m_frame.selection().setSelection(VisibleSelection(misspellingRange, DOWNSTREAM));
2110         m_frame.selection().revealSelection();
2111         
2112         client()->updateSpellingUIWithMisspelledWord(misspelledWord);
2113         document().markers().addMarker(misspellingRange.ptr(), DocumentMarker::Spelling);
2114     }
2115 }
2116
2117 #endif // !PLATFORM(IOS)
2118
2119 String Editor::misspelledWordAtCaretOrRange(Node* clickedNode) const
2120 {
2121     if (!isContinuousSpellCheckingEnabled() || !clickedNode || !isSpellCheckingEnabledFor(clickedNode))
2122         return String();
2123
2124     VisibleSelection selection = m_frame.selection().selection();
2125     if (!selection.isContentEditable() || selection.isNone())
2126         return String();
2127
2128     VisibleSelection wordSelection(selection.base());
2129     wordSelection.expandUsingGranularity(WordGranularity);
2130     RefPtr<Range> wordRange = wordSelection.toNormalizedRange();
2131
2132     // In compliance with GTK+ applications, additionally allow to provide suggestions when the current
2133     // selection exactly match the word selection.
2134     if (selection.isRange() && !areRangesEqual(wordRange.get(), selection.toNormalizedRange().get()))
2135         return String();
2136
2137     String word = wordRange->text();
2138     if (word.isEmpty() || !client())
2139         return String();
2140
2141     int wordLength = word.length();
2142     int misspellingLocation = -1;
2143     int misspellingLength = 0;
2144     textChecker()->checkSpellingOfString(word, &misspellingLocation, &misspellingLength);
2145
2146     return misspellingLength == wordLength ? word : String();
2147 }
2148
2149 String Editor::misspelledSelectionString() const
2150 {
2151     String selectedString = selectedText();
2152     int length = selectedString.length();
2153     if (!length || !client())
2154         return String();
2155
2156     int misspellingLocation = -1;
2157     int misspellingLength = 0;
2158     textChecker()->checkSpellingOfString(selectedString, &misspellingLocation, &misspellingLength);
2159     
2160     // The selection only counts as misspelled if the selected text is exactly one misspelled word
2161     if (misspellingLength != length)
2162         return String();
2163     
2164     // Update the spelling panel to be displaying this error (whether or not the spelling panel is on screen).
2165     // This is necessary to make a subsequent call to [NSSpellChecker ignoreWord:inSpellDocumentWithTag:] work
2166     // correctly; that call behaves differently based on whether the spelling panel is displaying a misspelling
2167     // or a grammar error.
2168     client()->updateSpellingUIWithMisspelledWord(selectedString);
2169     
2170     return selectedString;
2171 }
2172
2173 bool Editor::isSelectionUngrammatical()
2174 {
2175 #if USE(GRAMMAR_CHECKING)
2176     RefPtr<Range> range = m_frame.selection().toNormalizedRange();
2177     if (!range || !client())
2178         return false;
2179     return TextCheckingHelper(*client(), *range).isUngrammatical();
2180 #else
2181     return false;
2182 #endif
2183 }
2184
2185 Vector<String> Editor::guessesForMisspelledWord(const String& word) const
2186 {
2187     ASSERT(word.length());
2188
2189     Vector<String> guesses;
2190     if (client())
2191         textChecker()->getGuessesForWord(word, String(), m_frame.selection().selection(), guesses);
2192     return guesses;
2193 }
2194
2195 Vector<String> Editor::guessesForMisspelledOrUngrammatical(bool& misspelled, bool& ungrammatical)
2196 {
2197     if (unifiedTextCheckerEnabled()) {
2198         RefPtr<Range> range;
2199         VisibleSelection selection = m_frame.selection().selection();
2200         if (selection.isCaret() && behavior().shouldAllowSpellingSuggestionsWithoutSelection()) {
2201             VisibleSelection wordSelection = VisibleSelection(selection.base());
2202             wordSelection.expandUsingGranularity(WordGranularity);
2203             range = wordSelection.toNormalizedRange();
2204         } else
2205             range = selection.toNormalizedRange();
2206         if (!range || !client())
2207             return Vector<String>();
2208         return TextCheckingHelper(*client(), *range).guessesForMisspelledOrUngrammaticalRange(isGrammarCheckingEnabled(), misspelled, ungrammatical);
2209     }
2210
2211     String misspelledWord = behavior().shouldAllowSpellingSuggestionsWithoutSelection() ? misspelledWordAtCaretOrRange(document().focusedElement()) : misspelledSelectionString();
2212     misspelled = !misspelledWord.isEmpty();
2213     // Only unified text checker supports guesses for ungrammatical phrases.
2214     ungrammatical = false;
2215
2216     if (misspelled)
2217         return guessesForMisspelledWord(misspelledWord);
2218     return Vector<String>();
2219 }
2220
2221 void Editor::showSpellingGuessPanel()
2222 {
2223     if (!client()) {
2224         LOG_ERROR("No NSSpellChecker");
2225         return;
2226     }
2227
2228     if (client()->spellingUIIsShowing()) {
2229         client()->showSpellingUI(false);
2230         return;
2231     }
2232
2233 #if !PLATFORM(IOS)
2234     advanceToNextMisspelling(true);
2235 #endif
2236     client()->showSpellingUI(true);
2237 }
2238
2239 bool Editor::spellingPanelIsShowing()
2240 {
2241     if (!client())
2242         return false;
2243     return client()->spellingUIIsShowing();
2244 }
2245
2246 void Editor::clearMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
2247 {
2248     RefPtr<Range> selectedRange = movingSelection.toNormalizedRange();
2249     if (selectedRange) {
2250         document().markers().removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
2251         document().markers().removeMarkers(selectedRange.get(), DocumentMarker::Grammar);
2252     }
2253 }
2254
2255 void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
2256 {
2257     markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnabled() && isGrammarCheckingEnabled(), movingSelection);
2258 }
2259
2260 void Editor::markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement)
2261 {
2262     Ref<Frame> protection(m_frame);
2263
2264 #if PLATFORM(IOS)
2265     UNUSED_PARAM(selectionAfterTyping);
2266     UNUSED_PARAM(doReplacement);
2267     TextCheckingTypeMask textCheckingOptions = 0;
2268     if (isContinuousSpellCheckingEnabled())
2269         textCheckingOptions |= TextCheckingTypeSpelling;
2270     if (!(textCheckingOptions & TextCheckingTypeSpelling))
2271         return;
2272
2273     VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
2274     markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedRange().get(), adjacentWords.toNormalizedRange().get());
2275 #else
2276 #if !USE(AUTOMATIC_TEXT_REPLACEMENT)
2277     UNUSED_PARAM(doReplacement);
2278 #endif
2279
2280     if (unifiedTextCheckerEnabled()) {
2281         m_alternativeTextController->applyPendingCorrection(selectionAfterTyping);
2282
2283         TextCheckingTypeMask textCheckingOptions = 0;
2284
2285         if (isContinuousSpellCheckingEnabled())
2286             textCheckingOptions |= TextCheckingTypeSpelling;
2287
2288 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2289         if (doReplacement
2290             && (isAutomaticQuoteSubstitutionEnabled()
2291                 || isAutomaticLinkDetectionEnabled()
2292                 || isAutomaticDashSubstitutionEnabled()
2293                 || isAutomaticTextReplacementEnabled()
2294                 || ((textCheckingOptions & TextCheckingTypeSpelling) && isAutomaticSpellingCorrectionEnabled())))
2295             textCheckingOptions |= TextCheckingTypeReplacement;
2296 #endif
2297         if (!(textCheckingOptions & (TextCheckingTypeSpelling | TextCheckingTypeReplacement)))
2298             return;
2299
2300         if (isGrammarCheckingEnabled())
2301             textCheckingOptions |= TextCheckingTypeGrammar;
2302
2303         VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
2304         if (textCheckingOptions & TextCheckingTypeGrammar) {
2305             VisibleSelection selectedSentence = VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart));
2306             markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedRange().get(), selectedSentence.toNormalizedRange().get());
2307         } else
2308             markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedRange().get(), adjacentWords.toNormalizedRange().get());
2309         return;
2310     }
2311
2312     if (!isContinuousSpellCheckingEnabled())
2313         return;
2314
2315     // Check spelling of one word
2316     RefPtr<Range> misspellingRange;
2317     markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange);
2318
2319     // Autocorrect the misspelled word.
2320     if (!misspellingRange)
2321         return;
2322     
2323     // Get the misspelled word.
2324     const String misspelledWord = plainText(misspellingRange.get());
2325     String autocorrectedString = textChecker()->getAutoCorrectSuggestionForMisspelledWord(misspelledWord);
2326
2327     // If autocorrected word is non empty, replace the misspelled word by this word.
2328     if (!autocorrectedString.isEmpty()) {
2329         VisibleSelection newSelection(*misspellingRange, DOWNSTREAM);
2330         if (newSelection != m_frame.selection().selection()) {
2331             if (!m_frame.selection().shouldChangeSelection(newSelection))
2332                 return;
2333             m_frame.selection().setSelection(newSelection);
2334         }
2335
2336         if (!m_frame.editor().shouldInsertText(autocorrectedString, misspellingRange.get(), EditorInsertAction::Typed))
2337             return;
2338         m_frame.editor().replaceSelectionWithText(autocorrectedString, false, false, EditActionInsert);
2339
2340         // Reset the charet one character further.
2341         m_frame.selection().moveTo(m_frame.selection().selection().end());
2342         m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
2343     }
2344
2345     if (!isGrammarCheckingEnabled())
2346         return;
2347     
2348     // Check grammar of entire sentence
2349     markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart)));
2350 #endif
2351 }
2352     
2353 void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtr<Range>& firstMisspellingRange)
2354 {
2355 #if !PLATFORM(IOS)
2356     // This function is called with a selection already expanded to word boundaries.
2357     // Might be nice to assert that here.
2358     
2359     // This function is used only for as-you-type checking, so if that's off we do nothing. Note that
2360     // grammar checking can only be on if spell checking is also on.
2361     if (!isContinuousSpellCheckingEnabled())
2362         return;
2363     
2364     RefPtr<Range> searchRange(selection.toNormalizedRange());
2365     if (!searchRange)
2366         return;
2367     
2368     // If we're not in an editable node, bail.
2369     Node& editableNode = searchRange->startContainer();
2370     if (!editableNode.hasEditableStyle())
2371         return;
2372
2373     if (!isSpellCheckingEnabledFor(&editableNode))
2374         return;
2375
2376     // Get the spell checker if it is available
2377     if (!client())
2378         return;
2379     
2380     TextCheckingHelper checker(*client(), *searchRange);
2381     if (checkSpelling)
2382         checker.markAllMisspellings(firstMisspellingRange);
2383     else {
2384 #if USE(GRAMMAR_CHECKING)
2385         if (isGrammarCheckingEnabled())
2386             checker.markAllBadGrammar();
2387 #else
2388         ASSERT_NOT_REACHED();
2389 #endif
2390     }    
2391 #else
2392         UNUSED_PARAM(selection);
2393         UNUSED_PARAM(checkSpelling);
2394         UNUSED_PARAM(firstMisspellingRange);
2395 #endif // !PLATFORM(IOS)
2396 }
2397
2398 bool Editor::isSpellCheckingEnabledFor(Node* node) const
2399 {
2400     if (!node)
2401         return false;
2402     Element* element = is<Element>(*node) ? downcast<Element>(node) : node->parentElement();
2403     if (!element)
2404         return false;
2405     if (element->isInUserAgentShadowTree()) {
2406         if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(firstPositionInOrBeforeNode(element)))
2407             return textControl->isSpellCheckingEnabled();
2408     }
2409     return element->isSpellCheckingEnabled();
2410 }
2411
2412 bool Editor::isSpellCheckingEnabledInFocusedNode() const
2413 {
2414     return isSpellCheckingEnabledFor(m_frame.selection().selection().start().deprecatedNode());
2415 }
2416
2417 void Editor::markMisspellings(const VisibleSelection& selection, RefPtr<Range>& firstMisspellingRange)
2418 {
2419     markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange);
2420 }
2421     
2422 void Editor::markBadGrammar(const VisibleSelection& selection)
2423 {
2424 #if USE(GRAMMAR_CHECKING)
2425     RefPtr<Range> firstMisspellingRange;
2426     markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange);
2427 #else
2428     ASSERT_NOT_REACHED();
2429 #endif
2430 }
2431
2432 void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, Range* spellingRange, Range* grammarRange)
2433 {
2434     ASSERT(unifiedTextCheckerEnabled());
2435
2436     // There shouldn't be pending autocorrection at this moment.
2437     ASSERT(!m_alternativeTextController->hasPendingCorrection());
2438
2439     bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
2440     bool shouldShowCorrectionPanel = textCheckingOptions & TextCheckingTypeShowCorrectionPanel;
2441
2442     // This function is called with selections already expanded to word boundaries.
2443     if (!client() || !spellingRange || (shouldMarkGrammar && !grammarRange))
2444         return;
2445
2446     // If we're not in an editable node, bail.
2447     Node& editableNode = spellingRange->startContainer();
2448     if (!editableNode.hasEditableStyle())
2449         return;
2450
2451     if (!isSpellCheckingEnabledFor(&editableNode))
2452         return;
2453
2454     Range& rangeToCheck = shouldMarkGrammar ? *grammarRange : *spellingRange;
2455     TextCheckingParagraph paragraphToCheck(rangeToCheck);
2456     if (paragraphToCheck.isEmpty())
2457         return;
2458     Ref<Range> paragraphRange = paragraphToCheck.paragraphRange();
2459
2460     bool asynchronous = m_frame.settings().asynchronousSpellCheckingEnabled() && !shouldShowCorrectionPanel;
2461
2462     // In asynchronous mode, we intentionally check paragraph-wide sentence.
2463     const auto resolvedOptions = resolveTextCheckingTypeMask(editableNode, textCheckingOptions);
2464     auto request = SpellCheckRequest::create(resolvedOptions, TextCheckingProcessIncremental, asynchronous ? paragraphRange.get() : rangeToCheck, paragraphRange.copyRef());
2465     if (!request)
2466         return;
2467
2468     if (asynchronous) {
2469         m_spellChecker->requestCheckingFor(request.releaseNonNull());
2470         return;
2471     }
2472
2473     Vector<TextCheckingResult> results;
2474     checkTextOfParagraph(*textChecker(), paragraphToCheck.text(), resolvedOptions, results, m_frame.selection().selection());
2475     markAndReplaceFor(request.releaseNonNull(), results);
2476 }
2477
2478 static bool isAutomaticTextReplacementType(TextCheckingType type)
2479 {
2480     switch (type) {
2481     case TextCheckingTypeNone:
2482     case TextCheckingTypeSpelling:
2483     case TextCheckingTypeGrammar:
2484         return false;
2485     case TextCheckingTypeLink:
2486     case TextCheckingTypeQuote:
2487     case TextCheckingTypeDash:
2488     case TextCheckingTypeReplacement:
2489     case TextCheckingTypeCorrection:
2490     case TextCheckingTypeShowCorrectionPanel:
2491         return true;
2492     }
2493     ASSERT_NOT_REACHED();
2494     return false;
2495 }
2496
2497 static void correctSpellcheckingPreservingTextCheckingParagraph(TextCheckingParagraph& paragraph, Range& rangeToReplace, const String& replacement, int resultLocation, int resultLength)
2498 {
2499     auto& scope = downcast<ContainerNode>(paragraph.paragraphRange().startContainer().rootNode());
2500
2501     size_t paragraphLocation;
2502     size_t paragraphLength;
2503     TextIterator::getLocationAndLengthFromRange(&scope, &paragraph.paragraphRange(), paragraphLocation, paragraphLength);
2504
2505     SpellingCorrectionCommand::create(rangeToReplace, replacement)->apply();
2506
2507     // TextCheckingParagraph may be orphaned after SpellingCorrectionCommand mutated DOM.
2508     // See <rdar://10305315>, http://webkit.org/b/89526.
2509
2510     RefPtr<Range> newParagraphRange = TextIterator::rangeFromLocationAndLength(&scope, paragraphLocation, paragraphLength + replacement.length() - resultLength);
2511
2512     paragraph = TextCheckingParagraph(TextIterator::subrange(*newParagraphRange, resultLocation, replacement.length()), newParagraphRange.get());
2513 }
2514
2515 void Editor::markAndReplaceFor(const SpellCheckRequest& request, const Vector<TextCheckingResult>& results)
2516 {
2517     Ref<Frame> protection(m_frame);
2518
2519     TextCheckingTypeMask textCheckingOptions = request.data().mask();
2520     TextCheckingParagraph paragraph(request.checkingRange(), &request.paragraphRange());
2521
2522     const bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
2523     const bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
2524     const bool shouldMarkLink = textCheckingOptions & TextCheckingTypeLink;
2525     const bool shouldPerformReplacement = textCheckingOptions & (TextCheckingTypeQuote | TextCheckingTypeDash | TextCheckingTypeReplacement);
2526     const bool shouldShowCorrectionPanel = textCheckingOptions & TextCheckingTypeShowCorrectionPanel;
2527     const bool shouldCheckForCorrection = shouldShowCorrectionPanel || (textCheckingOptions & TextCheckingTypeCorrection);
2528 #if !USE(AUTOCORRECTION_PANEL)
2529     ASSERT(!shouldShowCorrectionPanel);
2530 #endif
2531
2532     // Expand the range to encompass entire paragraphs, since text checking needs that much context.
2533     int selectionOffset = 0;
2534     bool useAmbiguousBoundaryOffset = false;
2535     bool selectionChanged = false;
2536     bool restoreSelectionAfterChange = false;
2537     bool adjustSelectionForParagraphBoundaries = false;
2538
2539     if (shouldPerformReplacement || shouldMarkSpelling || shouldCheckForCorrection) {
2540         if (m_frame.selection().selection().selectionType() == VisibleSelection::CaretSelection) {
2541             // Attempt to save the caret position so we can restore it later if needed
2542             Position caretPosition = m_frame.selection().selection().end();
2543             selectionOffset = paragraph.offsetTo(caretPosition).releaseReturnValue();
2544             restoreSelectionAfterChange = true;
2545             if (selectionOffset > 0 && (selectionOffset > paragraph.textLength() || paragraph.textCharAt(selectionOffset - 1) == newlineCharacter))
2546                 adjustSelectionForParagraphBoundaries = true;
2547             if (selectionOffset > 0 && selectionOffset <= paragraph.textLength() && isAmbiguousBoundaryCharacter(paragraph.textCharAt(selectionOffset - 1)))
2548                 useAmbiguousBoundaryOffset = true;
2549         }
2550     }
2551
2552     int offsetDueToReplacement = 0;
2553
2554     for (unsigned i = 0; i < results.size(); i++) {
2555         const int spellingRangeEndOffset = paragraph.checkingEnd() + offsetDueToReplacement;
2556         const TextCheckingType resultType = results[i].type;
2557         const int resultLocation = results[i].location + offsetDueToReplacement;
2558         const int resultLength = results[i].length;
2559         const int resultEndLocation = resultLocation + resultLength;
2560         const String& replacement = results[i].replacement;
2561         const bool resultEndsAtAmbiguousBoundary = useAmbiguousBoundaryOffset && selectionOffset - 1 <= resultEndLocation;
2562
2563         // Only mark misspelling if:
2564         // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false.
2565         // 2. Result falls within spellingRange.
2566         // 3. The word in question doesn't end at an ambiguous boundary. For instance, we would not mark
2567         //    "wouldn'" as misspelled right after apostrophe is typed.
2568         if (shouldMarkSpelling && !shouldShowCorrectionPanel && resultType == TextCheckingTypeSpelling
2569             && resultLocation >= paragraph.checkingStart() && resultEndLocation <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) {
2570             ASSERT(resultLength > 0 && resultLocation >= 0);
2571             auto misspellingRange = paragraph.subrange(resultLocation, resultLength);
2572             if (!m_alternativeTextController->isSpellingMarkerAllowed(misspellingRange))
2573                 continue;
2574             misspellingRange->startContainer().document().markers().addMarker(misspellingRange.ptr(), DocumentMarker::Spelling, replacement);
2575         } else if (shouldMarkGrammar && resultType == TextCheckingTypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) {
2576             ASSERT(resultLength > 0 && resultLocation >= 0);
2577             for (auto& detail : results[i].details) {
2578                 ASSERT(detail.length > 0 && detail.location >= 0);
2579                 if (paragraph.checkingRangeCovers(resultLocation + detail.location, detail.length)) {
2580                     auto badGrammarRange = paragraph.subrange(resultLocation + detail.location, detail.length);
2581                     badGrammarRange->startContainer().document().markers().addMarker(badGrammarRange.ptr(), DocumentMarker::Grammar, detail.userDescription);
2582                 }
2583             }
2584         } else if (resultEndLocation <= spellingRangeEndOffset && resultEndLocation >= paragraph.checkingStart()
2585             && isAutomaticTextReplacementType(resultType)) {
2586             // In this case the result range just has to touch the spelling range, so we can handle replacing non-word text such as punctuation.
2587             ASSERT(resultLength > 0 && resultLocation >= 0);
2588
2589             if (shouldShowCorrectionPanel && (resultEndLocation < spellingRangeEndOffset
2590                 || !(resultType & (TextCheckingTypeReplacement | TextCheckingTypeCorrection))))
2591                 continue;
2592
2593             // Apply replacement if:
2594             // 1. The replacement length is non-zero.
2595             // 2. The result doesn't end at an ambiguous boundary.
2596             //    (FIXME: this is required until 6853027 is fixed and text checking can do this for us
2597             bool doReplacement = replacement.length() > 0 && !resultEndsAtAmbiguousBoundary;
2598             auto rangeToReplace = paragraph.subrange(resultLocation, resultLength);
2599
2600             // adding links should be done only immediately after they are typed
2601             if (resultType == TextCheckingTypeLink && selectionOffset != resultEndLocation + 1)
2602                 continue;
2603
2604             if (!(shouldPerformReplacement || shouldCheckForCorrection || shouldMarkLink) || !doReplacement)
2605                 continue;
2606
2607             String replacedString = plainText(rangeToReplace.ptr());
2608             const bool existingMarkersPermitReplacement = m_alternativeTextController->processMarkersOnTextToBeReplacedByResult(results[i], rangeToReplace, replacedString);
2609             if (!existingMarkersPermitReplacement)
2610                 continue;
2611
2612             if (shouldShowCorrectionPanel) {
2613                 if (resultEndLocation == spellingRangeEndOffset) {
2614                     // We only show the correction panel on the last word.
2615                     m_alternativeTextController->show(rangeToReplace, replacement);
2616                     break;
2617                 }
2618                 // If this function is called for showing correction panel, we ignore other correction or replacement.
2619                 continue;
2620             }
2621
2622             VisibleSelection selectionToReplace(rangeToReplace, DOWNSTREAM);
2623             if (selectionToReplace != m_frame.selection().selection()) {
2624                 if (!m_frame.selection().shouldChangeSelection(selectionToReplace))
2625                     continue;
2626             }
2627
2628             if (resultType == TextCheckingTypeLink) {
2629                 m_frame.selection().setSelection(selectionToReplace);
2630                 selectionChanged = true;
2631                 restoreSelectionAfterChange = false;
2632                 if (canEditRichly())
2633                     CreateLinkCommand::create(document(), replacement)->apply();
2634             } else if (canEdit() && shouldInsertText(replacement, rangeToReplace.ptr(), EditorInsertAction::Typed)) {
2635                 correctSpellcheckingPreservingTextCheckingParagraph(paragraph, rangeToReplace, replacement, resultLocation, resultLength);
2636
2637                 if (AXObjectCache* cache = document().existingAXObjectCache()) {
2638                     if (Element* root = m_frame.selection().selection().rootEditableElement())
2639                         cache->postNotification(root, AXObjectCache::AXAutocorrectionOccured);
2640                 }
2641
2642                 // Skip all other results for the replaced text.
2643                 while (i + 1 < results.size() && results[i + 1].location + offsetDueToReplacement <= resultLocation)
2644                     i++;
2645
2646                 selectionChanged = true;
2647                 offsetDueToReplacement += replacement.length() - resultLength;
2648                 if (resultLocation < selectionOffset)
2649                     selectionOffset += replacement.length() - resultLength;
2650
2651                 if (resultType == TextCheckingTypeCorrection) {
2652                     auto replacementRange = paragraph.subrange(resultLocation, replacement.length());
2653                     m_alternativeTextController->recordAutocorrectionResponse(AutocorrectionResponse::Accepted, replacedString, replacementRange.ptr());
2654
2655                     // Add a marker so that corrections can easily be undone and won't be re-corrected.
2656                     m_alternativeTextController->markCorrection(replacementRange, replacedString);
2657                 }
2658             }
2659         }
2660     }
2661
2662     if (selectionChanged) {
2663         TextCheckingParagraph extendedParagraph(WTFMove(paragraph));
2664         // Restore the caret position if we have made any replacements
2665         extendedParagraph.expandRangeToNextEnd();
2666         if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffset <= extendedParagraph.rangeLength()) {
2667             auto selectionRange = extendedParagraph.subrange(0, selectionOffset);
2668             m_frame.selection().moveTo(selectionRange->endPosition(), DOWNSTREAM);
2669             if (adjustSelectionForParagraphBoundaries)
2670                 m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
2671         } else {
2672             // If this fails for any reason, the fallback is to go one position beyond the last replacement
2673             m_frame.selection().moveTo(m_frame.selection().selection().end());
2674             m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
2675         }
2676     }
2677 }
2678
2679 void Editor::changeBackToReplacedString(const String& replacedString)
2680 {
2681 #if !PLATFORM(IOS)
2682     ASSERT(unifiedTextCheckerEnabled());
2683
2684     if (replacedString.isEmpty())
2685         return;
2686
2687     RefPtr<Range> selection = selectedRange();
2688     if (!shouldInsertText(replacedString, selection.get(), EditorInsertAction::Pasted))
2689         return;
2690     
2691     m_alternativeTextController->recordAutocorrectionResponse(AutocorrectionResponse::Reverted, replacedString, selection.get());
2692     TextCheckingParagraph paragraph(*selection);
2693     replaceSelectionWithText(replacedString, false, false, EditActionInsert);
2694     auto changedRange = paragraph.subrange(paragraph.checkingStart(), replacedString.length());
2695     changedRange->startContainer().document().markers().addMarker(changedRange.ptr(), DocumentMarker::Replacement, String());
2696     m_alternativeTextController->markReversed(changedRange);
2697 #else
2698     ASSERT_NOT_REACHED();
2699     UNUSED_PARAM(replacedString);
2700 #endif // !PLATFORM(IOS)
2701 }
2702
2703
2704 void Editor::markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection)
2705 {
2706     if (unifiedTextCheckerEnabled()) {
2707         if (!isContinuousSpellCheckingEnabled())
2708             return;
2709
2710         // markMisspellingsAndBadGrammar() is triggered by selection change, in which case we check spelling and grammar, but don't autocorrect misspellings.
2711         TextCheckingTypeMask textCheckingOptions = TextCheckingTypeSpelling;
2712         if (markGrammar && isGrammarCheckingEnabled())
2713             textCheckingOptions |= TextCheckingTypeGrammar;
2714         markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellingSelection.toNormalizedRange().get(), grammarSelection.toNormalizedRange().get());
2715         return;
2716     }
2717
2718     RefPtr<Range> firstMisspellingRange;
2719     markMisspellings(spellingSelection, firstMisspellingRange);
2720     if (markGrammar)
2721         markBadGrammar(grammarSelection);
2722 }
2723
2724 void Editor::unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction)
2725 {
2726     m_alternativeTextController->respondToUnappliedSpellCorrection(selectionOfCorrected, corrected, correction);
2727 }
2728
2729 void Editor::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionAtWordBoundary)
2730 {
2731     if (!document().markers().hasMarkers())
2732         return;
2733
2734     if (!m_alternativeTextController->shouldRemoveMarkersUponEditing() && (!textChecker() || textChecker()->shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)))
2735         return;
2736
2737     // We want to remove the markers from a word if an editing command will change the word. This can happen in one of
2738     // several scenarios:
2739     // 1. Insert in the middle of a word.
2740     // 2. Appending non whitespace at the beginning of word.
2741     // 3. Appending non whitespace at the end of word.
2742     // Note that, appending only whitespaces at the beginning or end of word won't change the word, so we don't need to
2743     // remove the markers on that word.
2744     // Of course, if current selection is a range, we potentially will edit two words that fall on the boundaries of
2745     // selection, and remove words between the selection boundaries.
2746     //
2747     VisiblePosition startOfSelection = m_frame.selection().selection().start();
2748     VisiblePosition endOfSelection = m_frame.selection().selection().end();
2749     if (startOfSelection.isNull())
2750         return;
2751     // First word is the word that ends after or on the start of selection.
2752     VisiblePosition startOfFirstWord = startOfWord(startOfSelection, LeftWordIfOnBoundary);
2753     VisiblePosition endOfFirstWord = endOfWord(startOfSelection, LeftWordIfOnBoundary);
2754     // Last word is the word that begins before or on the end of selection
2755     VisiblePosition startOfLastWord = startOfWord(endOfSelection, RightWordIfOnBoundary);
2756     VisiblePosition endOfLastWord = endOfWord(endOfSelection, RightWordIfOnBoundary);
2757
2758     if (startOfFirstWord.isNull()) {
2759         startOfFirstWord = startOfWord(startOfSelection, RightWordIfOnBoundary);
2760         endOfFirstWord = endOfWord(startOfSelection, RightWordIfOnBoundary);
2761     }
2762     
2763     if (endOfLastWord.isNull()) {
2764         startOfLastWord = startOfWord(endOfSelection, LeftWordIfOnBoundary);
2765         endOfLastWord = endOfWord(endOfSelection, LeftWordIfOnBoundary);
2766     }
2767
2768     // If doNotRemoveIfSelectionAtWordBoundary is true, and first word ends at the start of selection,
2769     // we choose next word as the first word.
2770     if (doNotRemoveIfSelectionAtWordBoundary && endOfFirstWord == startOfSelection) {
2771         startOfFirstWord = nextWordPosition(startOfFirstWord);
2772         endOfFirstWord = endOfWord(startOfFirstWord, RightWordIfOnBoundary);
2773         if (startOfFirstWord == endOfSelection)
2774             return;
2775     }
2776
2777     // If doNotRemoveIfSelectionAtWordBoundary is true, and last word begins at the end of selection,
2778     // we choose previous word as the last word.
2779     if (doNotRemoveIfSelectionAtWordBoundary && startOfLastWord == endOfSelection) {
2780         startOfLastWord = previousWordPosition(startOfLastWord);
2781         endOfLastWord = endOfWord(startOfLastWord, RightWordIfOnBoundary);
2782         if (endOfLastWord == startOfSelection)
2783             return;
2784     }
2785
2786     if (startOfFirstWord.isNull() || endOfFirstWord.isNull() || startOfLastWord.isNull() || endOfLastWord.isNull())
2787         return;
2788
2789     // Now we remove markers on everything between startOfFirstWord and endOfLastWord.
2790     // However, if an autocorrection change a single word to multiple words, we want to remove correction mark from all the
2791     // resulted words even we only edit one of them. For example, assuming autocorrection changes "avantgarde" to "avant
2792     // garde", we will have CorrectionIndicator marker on both words and on the whitespace between them. If we then edit garde,
2793     // we would like to remove the marker from word "avant" and whitespace as well. So we need to get the continous range of
2794     // of marker that contains the word in question, and remove marker on that whole range.
2795     auto wordRange = Range::create(document(), startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());
2796
2797     Vector<RenderedDocumentMarker*> markers = document().markers().markersInRange(wordRange, DocumentMarker::DictationAlternatives);
2798     for (auto* marker : markers)
2799         m_alternativeTextController->removeDictationAlternativesForMarker(*marker);
2800
2801     OptionSet<DocumentMarker::MarkerType> markerTypesToRemove {
2802         DocumentMarker::CorrectionIndicator,
2803         DocumentMarker::DictationAlternatives,
2804         DocumentMarker::SpellCheckingExemption,
2805         DocumentMarker::Spelling,
2806 #if !PLATFORM(IOS)
2807         DocumentMarker::Grammar,
2808 #endif
2809     };
2810     document().markers().removeMarkers(wordRange.ptr(), markerTypesToRemove, DocumentMarkerController::RemovePartiallyOverlappingMarker);
2811     document().markers().clearDescriptionOnMarkersIntersectingRange(wordRange, DocumentMarker::Replacement);
2812 }
2813
2814 void Editor::deletedAutocorrectionAtPosition(const Position& position, const String& originalString)
2815 {
2816     m_alternativeTextController->deletedAutocorrectionAtPosition(position, originalString);
2817 }
2818
2819 RefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
2820 {
2821     Document* document = m_frame.documentAtPoint(windowPoint);
2822     if (!document)
2823         return nullptr;
2824     
2825     Frame* frame = document->frame();
2826     ASSERT(frame);
2827     FrameView* frameView = frame->view();
2828     if (!frameView)
2829         return nullptr;
2830     IntPoint framePoint = frameView->windowToContents(windowPoint);
2831     VisibleSelection selection(frame->visiblePositionForPoint(framePoint));
2832
2833     return selection.toNormalizedRange();
2834 }
2835
2836 void Editor::revealSelectionAfterEditingOperation(const ScrollAlignment& alignment, RevealExtentOption revealExtentOption)
2837 {
2838     if (m_ignoreSelectionChanges)
2839         return;
2840
2841 #if PLATFORM(IOS)
2842     SelectionRevealMode revealMode = SelectionRevealMode::RevealUpToMainFrame;
2843 #else
2844     SelectionRevealMode revealMode = SelectionRevealMode::Reveal;
2845 #endif
2846
2847     m_frame.selection().revealSelection(revealMode, alignment, revealExtentOption);
2848 }
2849
2850 void Editor::setIgnoreSelectionChanges(bool ignore, RevealSelection shouldRevealExistingSelection)
2851 {
2852     if (m_ignoreSelectionChanges == ignore)
2853         return;
2854
2855     m_ignoreSelectionChanges = ignore;
2856 #if PLATFORM(IOS)
2857     // FIXME: Should suppress selection change notifications during a composition change <https://webkit.org/b/38830> 
2858     if (!ignore)
2859         respondToChangedSelection(m_frame.selection().selection(), 0);
2860 #endif
2861     if (!ignore && shouldRevealExistingSelection == RevealSelection::Yes)
2862         revealSelectionAfterEditingOperation(ScrollAlignment::alignToEdgeIfNeeded, RevealExtent);
2863 }
2864
2865 RefPtr<Range> Editor::compositionRange() const
2866 {
2867     if (!m_compositionNode)
2868         return nullptr;
2869     unsigned length = m_compositionNode->length();
2870     unsigned start = std::min(m_compositionStart, length);
2871     unsigned end = std::min(std::max(start, m_compositionEnd), length);
2872     if (start >= end)
2873         return nullptr;
2874     return Range::create(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);
2875 }
2876
2877 bool Editor::getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const
2878 {
2879     if (!m_compositionNode)
2880         return false;
2881     const VisibleSelection& selection = m_frame.selection().selection();
2882     Position start = selection.start();
2883     if (start.deprecatedNode() != m_compositionNode)
2884         return false;
2885     Position end = selection.end();
2886     if (end.deprecatedNode() != m_compositionNode)
2887         return false;
2888
2889     if (static_cast<unsigned>(start.deprecatedEditingOffset()) < m_compositionStart)
2890         return false;
2891     if (static_cast<unsigned>(end.deprecatedEditingOffset()) > m_compositionEnd)
2892         return false;
2893
2894     selectionStart = start.deprecatedEditingOffset() - m_compositionStart;
2895     selectionEnd = start.deprecatedEditingOffset() - m_compositionEnd;
2896     return true;
2897 }
2898
2899 void Editor::transpose()
2900 {
2901     if (!canEdit())
2902         return;
2903
2904     VisibleSelection selection = m_frame.selection().selection();
2905     if (!selection.isCaret())
2906         return;
2907
2908     // Make a selection that goes back one character and forward two characters.
2909     VisiblePosition caret = selection.visibleStart();
2910     VisiblePosition next = isEndOfParagraph(caret) ? caret : caret.next();
2911     VisiblePosition previous = next.previous();
2912     if (next == previous)
2913         return;
2914     previous = previous.previous();
2915     if (!inSameParagraph(next, previous))
2916         return;
2917     RefPtr<Range> range = makeRange(previous, next);
2918     if (!range)
2919         return;
2920     VisibleSelection newSelection(*range, DOWNSTREAM);
2921
2922     // Transpose the two characters.
2923     String text = plainText(range.get());
2924     if (text.length() != 2)
2925         return;
2926     String transposed = text.right(1) + text.left(1);
2927
2928     // Select the two characters.
2929     if (newSelection != m_frame.selection().selection()) {
2930         if (!m_frame.selection().shouldChangeSelection(newSelection))
2931             return;
2932         m_frame.selection().setSelection(newSelection);
2933     }
2934
2935     // Insert the transposed characters.
2936     if (!shouldInsertText(transposed, range.get(), EditorInsertAction::Typed))
2937         return;
2938     replaceSelectionWithText(transposed, false, false, EditActionInsert);
2939 }
2940
2941 void Editor::addRangeToKillRing(const Range& range, KillRingInsertionMode mode)
2942 {
2943     addTextToKillRing(plainText(&range), mode);
2944 }
2945
2946 void Editor::addTextToKillRing(const String& text, KillRingInsertionMode mode)
2947 {
2948     if (m_shouldStartNewKillRingSequence)
2949         killRing().startNewSequence();
2950
2951     m_shouldStartNewKillRingSequence = false;
2952
2953     // If the kill was from a backwards motion, prepend to the kill ring.
2954     // This will ensure that alternating forward and backward kills will
2955     // build up the original string in the kill ring without permuting it.
2956     switch (mode) {
2957     case KillRingInsertionMode::PrependText:
2958         killRing().prepend(text);
2959         break;
2960     case KillRingInsertionMode::AppendText:
2961         killRing().append(text);
2962         break;
2963     }
2964 }
2965
2966 void Editor::startAlternativeTextUITimer()
2967 {
2968     m_alternativeTextController->startAlternativeTextUITimer(AlternativeTextTypeCorrection);
2969 }
2970
2971 void Editor::handleAlternativeTextUIResult(const String& correction)
2972 {
2973     m_alternativeTextController->handleAlternativeTextUIResult(correction);
2974 }
2975
2976
2977 void Editor::dismissCorrectionPanelAsIgnored()
2978 {
2979     m_alternativeTextController->dismiss(ReasonForDismissingAlternativeTextIgnored);
2980 }
2981
2982 void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection, FrameSelection::SetSelectionOptions options)
2983 {
2984     Ref<Frame> protection(m_frame);
2985
2986     // If the new selection is orphaned, then don't update the selection.
2987     if (newSelection.start().isOrphan() || newSelection.end().isOrphan())
2988         return;
2989
2990     // If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
2991     // because there is work that it must do in this situation.
2992     // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
2993     // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
2994     bool selectionDidNotChangeDOMPosition = newSelection == m_frame.selection().selection();
2995     if (selectionDidNotChangeDOMPosition || m_frame.selection().shouldChangeSelection(newSelection))
2996         m_frame.selection().setSelection(newSelection, options);
2997
2998     // Some editing operations change the selection visually without affecting its position within the DOM.
2999     // For example when you press return in the following (the caret is marked by ^):
3000     // <div contentEditable="true"><div>^Hello</div></div>
3001     // WebCore inserts <div><br></div> *before* the current block, which correctly moves the paragraph down but which doesn't
3002     // change the caret's DOM position (["hello", 0]). In these situations the above FrameSelection::setSelection call
3003     // does not call EditorClient::respondToChangedSelection(), which, on the Mac, sends selection change notifications and
3004     // starts a new kill ring sequence, but we want to do these things (matches AppKit).
3005 #if PLATFORM(IOS)
3006     // FIXME: Should suppress selection change notifications during a composition change <https://webkit.org/b/38830>
3007     if (m_ignoreSelectionChanges)
3008         return;
3009 #endif
3010     if (selectionDidNotChangeDOMPosition && client())
3011         client()->respondToChangedSelection(&m_frame);
3012 }
3013
3014 String Editor::selectedText() const
3015 {
3016     return selectedText(TextIteratorDefaultBehavior);
3017 }
3018
3019 String Editor::selectedTextForDataTransfer() const
3020 {
3021     return selectedText(TextIteratorEmitsImageAltText);
3022 }
3023
3024 String Editor::selectedText(TextIteratorBehavior behavior) const
3025 {
3026     // We remove '\0' characters because they are not visibly rendered to the user.
3027     return plainText(m_frame.selection().toNormalizedRange().get(), behavior).replaceWithLiteral('\0', "");
3028 }
3029
3030 static inline void collapseCaretWidth(IntRect& rect)
3031 {
3032     // FIXME: Width adjustment doesn't work for rotated text.
3033     if (rect.width() == caretWidth)
3034         rect.setWidth(0);
3035     else if (rect.height() == caretWidth)
3036         rect.setHeight(0);
3037 }
3038
3039 IntRect Editor::firstRectForRange(Range* range) const
3040 {
3041     VisiblePosition startVisiblePosition(range->startPosition(), DOWNSTREAM);
3042
3043     if (range->collapsed()) {
3044         // FIXME: Getting caret rect and removing caret width is a very roundabout way to get collapsed range location.
3045         // In particular, width adjustment doesn't work for rotated text.
3046         IntRect startCaretRect = RenderedPosition(startVisiblePosition).absoluteRect();
3047         collapseCaretWidth(startCaretRect);
3048         return startCaretRect;
3049     }
3050
3051     VisiblePosition endVisiblePosition(range->endPosition(), UPSTREAM);
3052
3053     if (inSameLine(startVisiblePosition, endVisiblePosition))
3054         return enclosingIntRect(RenderObject::absoluteBoundingBoxRectForRange(range));
3055
3056     LayoutUnit extraWidthToEndOfLine = 0;
3057     IntRect startCaretRect = RenderedPosition(startVisiblePosition).absoluteRect(&extraWidthToEndOfLine);
3058     if (startCaretRect == IntRect())
3059         return IntRect();
3060
3061     // When start and end aren't on the same line, we want to go from start to the end of its line.
3062     bool textIsHorizontal = startCaretRect.width() == caretWidth;
3063     return textIsHorizontal ?
3064         IntRect(startCaretRect.x(),
3065             startCaretRect.y(),
3066             startCaretRect.width() + extraWidthToEndOfLine,
3067             startCaretRect.height()) :
3068         IntRect(startCaretRect.x(),
3069             startCaretRect.y(),
3070             startCaretRect.width(),
3071             startCaretRect.height() + extraWidthToEndOfLine);
3072 }
3073
3074 bool Editor::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
3075 {
3076 #if PLATFORM(IOS)
3077     if (m_frame.selectionChangeCallbacksDisabled())
3078         return true;
3079 #endif
3080     return client() && client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting);
3081 }
3082
3083 void Editor::computeAndSetTypingStyle(EditingStyle& style, EditAction editingAction)
3084 {
3085     if (style.isEmpty()) {
3086         m_frame.selection().clearTypingStyle();
3087         return;
3088     }
3089
3090     // Calculate the current typing style.
3091     RefPtr<EditingStyle> typingStyle;
3092     if (auto existingTypingStyle = m_frame.selection().typingStyle())
3093         typingStyle = existingTypingStyle->copy();
3094     else
3095         typingStyle = EditingStyle::create();
3096     typingStyle->overrideTypingStyleAt(style, m_frame.selection().selection().visibleStart().deepEquivalent());
3097
3098     // Handle block styles, substracting these from the typing style.
3099     RefPtr<EditingStyle> blockStyle = typingStyle->extractAndRemoveBlockProperties();
3100     if (!blockStyle->isEmpty())
3101         ApplyStyleCommand::create(document(), blockStyle.get(), editingAction)->apply();
3102
3103     // Set the remaining style as the typing style.
3104     m_frame.selection().setTypingStyle(WTFMove(typingStyle));
3105 }
3106
3107 void Editor::computeAndSetTypingStyle(StyleProperties& properties, EditAction editingAction)
3108 {
3109     return computeAndSetTypingStyle(EditingStyle::create(&properties), editingAction);
3110 }
3111
3112 void Editor::textFieldDidBeginEditing(Element* e)
3113 {
3114     if (client())
3115         client()->textFieldDidBeginEditing(e);
3116 }
3117
3118 void Editor::textFieldDidEndEditing(Element* e)
3119 {
3120     dismissCorrectionPanelAsIgnored();
3121     if (client())
3122         client()->textFieldDidEndEditing(e);
3123 }
3124
3125 void Editor::textDidChangeInTextField(Element* e)
3126 {
3127     if (client())
3128         client()->textDidChangeInTextField(e);
3129 }
3130
3131 bool Editor::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
3132 {
3133     if (client())
3134         return client()->doTextFieldCommandFromEvent(e, ke);
3135
3136     return false;
3137 }
3138
3139 void Editor::textWillBeDeletedInTextField(Element* input)
3140 {
3141     if (client())
3142         client()->textWillBeDeletedInTextField(input);
3143 }
3144
3145 void Editor::textDidChangeInTextArea(Element* e)
3146 {
3147     if (client())
3148         client()->textDidChangeInTextArea(e);
3149 }
3150
3151 void Editor::applyEditingStyleToBodyElement() const
3152 {
3153     auto collection = document().getElementsByTagName(HTMLNames::bodyTag.localName());
3154     unsigned length = collection->length();
3155     for (unsigned i = 0; i < length; ++i)
3156         applyEditingStyleToElement(collection->item(i));
3157 }
3158
3159 void Editor::applyEditingStyleToElement(Element* element) const
3160 {
3161     ASSERT(!element || is<StyledElement>(*element));
3162     if (!is<StyledElement>(element))
3163         return;
3164
3165     // Mutate using the CSSOM wrapper so we get the same event behavior as a script.
3166     auto& style = downcast<StyledElement>(*element).cssomStyle();
3167     style.setPropertyInternal(CSSPropertyWordWrap, "break-word", false);
3168     style.setPropertyInternal(CSSPropertyWebkitNbspMode, "space", false);
3169     style.setPropertyInternal(CSSPropertyLineBreak, "after-white-space", false);
3170 }
3171
3172 bool Editor::findString(const String& target, FindOptions options)
3173 {
3174     Ref<Frame> protection(m_frame);
3175
3176     VisibleSelection selection = m_frame.selection().selection();
3177
3178     RefPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options);
3179
3180     if (!resultRange)
3181         return false;
3182
3183     m_frame.selection().setSelection(VisibleSelection(*resultRange, DOWNSTREAM));
3184
3185     if (!(options & DoNotRevealSelection))
3186         m_frame.selection().revealSelection();
3187
3188     return true;
3189 }
3190
3191 RefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
3192 {
3193     if (target.isEmpty())
3194         return nullptr;
3195
3196     // Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge
3197     // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
3198     RefPtr<Range> searchRange(rangeOfContents(document()));
3199
3200     bool forward = !(options & Backwards);
3201     bool startInReferenceRange = referenceRange && (options & StartInSelection);
3202     if (referenceRange) {
3203         if (forward)
3204             searchRange->setStart(startInReferenceRange ? referenceRange->startPosition() : referenceRange->endPosition());
3205         else
3206             searchRange->setEnd(startInReferenceRange ? referenceRange->endPosition() : referenceRange->startPosition());
3207     }
3208
3209     RefPtr<ShadowRoot> shadowTreeRoot = referenceRange ? referenceRange->startContainer().containingShadowRoot() : nullptr;
3210     if (shadowTreeRoot) {
3211         if (forward)
3212             searchRange->setEnd(*shadowTreeRoot, shadowTreeRoot->countChildNodes());
3213         else
3214             searchRange->setStart(*shadowTreeRoot, 0);
3215     }
3216
3217     RefPtr<Range> resultRange = findPlainText(*searchRange, target, options);
3218     // If we started in the reference range and the found range exactly matches the reference range, find again.
3219     // Build a selection with the found range to remove collapsed whitespace.
3220     // Compare ranges instead of selection objects to ignore the way that the current selection was made.
3221     if (startInReferenceRange && areRangesEqual(VisibleSelection(*resultRange).toNormalizedRange().get(), referenceRange)) {
3222         searchRange = rangeOfContents(document());
3223         if (forward)
3224             searchRange->setStart(referenceRange->endPosition());
3225         else
3226             searchRange->setEnd(referenceRange->startPosition());
3227
3228         if (shadowTreeRoot) {
3229             if (forward)
3230                 searchRange->setEnd(*shadowTreeRoot, shadowTreeRoot->countChildNodes());
3231             else
3232                 searchRange->setStart(*shadowTreeRoot, 0);
3233         }
3234
3235         resultRange = findPlainText(*searchRange, target, options);
3236     }
3237
3238     // If nothing was found in the shadow tree, search in main content following the shadow tree.
3239     if (resultRange->collapsed() && shadowTreeRoot) {
3240         searchRange = rangeOfContents(document());
3241         if (shadowTreeRoot->shadowHost()) {
3242             if (forward)
3243                 searchRange->setStartAfter(*shadowTreeRoot->shadowHost());
3244             else
3245                 searchRange->setEndBefore(*shadowTreeRoot->shadowHost());
3246         }
3247
3248         resultRange = findPlainText(*searchRange, target, options);
3249     }
3250
3251     // If we didn't find anything and we're wrapping, search again in the entire document (this will
3252     // redundantly re-search the area already searched in some cases).
3253     if (resultRange->collapsed() && options & WrapAround) {
3254         searchRange = rangeOfContents(document());
3255         resultRange = findPlainText(*searchRange, target, options);
3256         // We used to return false here if we ended up with the same range that we started with
3257         // (e.g., the reference range was already the only instance of this text). But we decided that
3258         // this should be a success case instead, so we'll just fall through in that case.
3259     }
3260
3261     return resultRange->collapsed() ? nullptr : resultRange;
3262 }
3263
3264 static bool isFrameInRange(Frame& frame, Range& range)
3265 {
3266     for (auto* ownerElement = frame.ownerElement(); ownerElement; ownerElement = ownerElement->document().ownerElement()) {
3267         if (&ownerElement->document() == &range.ownerDocument()) {
3268             auto result = range.intersectsNode(*ownerElement);
3269             return !result.hasException() && result.releaseReturnValue();
3270         }
3271     }
3272     return false;
3273 }
3274
3275 unsigned Editor::countMatchesForText(const String& target, Range* range, FindOptions options, unsigned limit, bool markMatches, Vector<RefPtr<Range>>* matches)
3276 {
3277     if (target.isEmpty())
3278         return 0;
3279
3280     RefPtr<Range> searchRange;
3281     if (range) {
3282         if (&range->ownerDocument() == &document())
3283             searchRange = range;
3284         else if (!isFrameInRange(m_frame, *range))
3285             return 0;
3286     }
3287     if (!searchRange)
3288         searchRange = rangeOfContents(document());
3289
3290     Node& originalEndContainer = searchRange->endContainer();
3291     int originalEndOffset = searchRange->endOffset();
3292
3293     unsigned matchCount = 0;
3294     do {
3295         RefPtr<Range> resultRange(findPlainText(*searchRange, target, options & ~Backwards));
3296         if (resultRange->collapsed()) {
3297             if (!resultRange->startContainer().isInShadowTree())
3298                 break;
3299
3300             searchRange->setStartAfter(*resultRange->startContainer().shadowHost());
3301             searchRange->setEnd(originalEndContainer, originalEndOffset);
3302             continue;
3303         }
3304
3305         ++matchCount;
3306         if (matches)
3307             matches->append(resultRange);
3308         
3309         if (markMatches)
3310             document().markers().addMarker(resultRange.get(), DocumentMarker::TextMatch);
3311
3312         // Stop looking if we hit the specified limit. A limit of 0 means no limit.
3313         if (limit > 0 && matchCount >= limit)
3314             break;
3315
3316         // Set the new start for the search range to be the end of the previous
3317         // result range. There is no need to use a VisiblePosition here,
3318         // since findPlainText will use a TextIterator to go over the visible
3319         // text nodes. 
3320         searchRange->setStart(resultRange->endContainer(), resultRange->endOffset());
3321
3322         Node* shadowTreeRoot = searchRange->shadowRoot();
3323         if (searchRange->collapsed() && shadowTreeRoot)
3324             searchRange->setEnd(*shadowTreeRoot, shadowTreeRoot->countChildNodes());
3325     } while (true);
3326
3327     return matchCount;
3328 }
3329
3330 void Editor::setMarkedTextMatchesAreHighlighted(bool flag)
3331 {
3332     if (flag == m_areMarkedTextMatchesHighlighted)
3333         return;
3334
3335     m_areMarkedTextMatchesHighlighted = flag;
3336     document().markers().repaintMarkers(DocumentMarker::TextMatch);
3337 }
3338
3339 #if !PLATFORM(MAC)
3340 void Editor::selectionWillChange()
3341 {
3342 }
3343 #endif
3344
3345 void Editor::respondToChangedSelection(const VisibleSelection&, FrameSelection::SetSelectionOptions options)
3346 {
3347 #if PLATFORM(IOS)
3348     // FIXME: Should suppress selection change notifications during a composition change <https://webkit.org/b/38830> 
3349     if (m_ignoreSelectionChanges)
3350         return;
3351 #endif
3352
3353     if (client())
3354         client()->respondToChangedSelection(&m_frame);
3355
3356 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS)
3357     if (shouldDetectTelephoneNumbers())
3358         m_telephoneNumberDetectionUpdateTimer.startOneShot(0_s);
3359 #endif
3360
3361     setStartNewKillRingSequence(true);
3362
3363     if (m_editorUIUpdateTimer.isActive())
3364         return;
3365
3366     // Don't check spelling and grammar if the change of selection is triggered by spelling correction itself.
3367     m_editorUIUpdateTimerShouldCheckSpellingAndGrammar = options & FrameSelection::CloseTyping
3368         && !(options & FrameSelection::SpellCorrectionTriggered);
3369     m_editorUIUpdateTimerWasTriggeredByDictation = options & FrameSelection::DictationTriggered;
3370     m_editorUIUpdateTimer.startOneShot(0_s);
3371 }
3372
3373 #if ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS)
3374
3375 bool Editor::shouldDetectTelephoneNumbers()
3376 {
3377     if (!m_frame.document())
3378         return false;
3379     return document().isTelephoneNumberParsingEnabled() && TelephoneNumberDetector::isSupported();
3380 }
3381
3382 void Editor::scanSelectionForTelephoneNumbers()
3383 {
3384     if (!shouldDetectTelephoneNumbers() || !client())
3385         return;
3386
3387     m_detectedTelephoneNumberRanges.clear();
3388
3389     Vector<RefPtr<Range>> markedRanges;
3390
3391     FrameSelection& frameSelection = m_frame.selection();
3392     if (!frameSelection.isRange()) {
3393         m_frame.mainFrame().servicesOverlayController().selectedTelephoneNumberRangesChanged();
3394         return;
3395     }
3396     RefPtr<Range> selectedRange = frameSelection.toNormalizedRange();
3397
3398     // Extend the range a few characters in each direction to detect incompletely selected phone numbers.
3399     static const int charactersToExtend = 15;
3400     const VisibleSelection& visibleSelection = frameSelection.selection();
3401     Position start = visibleSelection.start();
3402     Position end = visibleSelection.end();
3403     for (int i = 0; i < charactersToExtend; ++i) {
3404         start = start.previous(Character);
3405         end = end.next(Character);
3406     }
3407
3408     FrameSelection extendedSelection;
3409     extendedSelection.setStart(start);
3410     extendedSelection.setEnd(end);
3411     RefPtr<Range> extendedRange = extendedSelection.toNormalizedRange();
3412
3413     if (!extendedRange) {
3414         m_frame.mainFrame().servicesOverlayController().selectedTelephoneNumberRangesChanged();
3415         return;
3416     }
3417
3418     scanRangeForTelephoneNumbers(*extendedRange, extendedRange->text(), markedRanges);
3419
3420     // Only consider ranges with a detected telephone number if they overlap with the actual selection range.
3421     for (auto& range : markedRanges) {
3422         if (rangesOverlap(range.get(), selectedRange.get()))
3423             m_detectedTelephoneNumberRanges.append(range);
3424     }
3425
3426     m_frame.mainFrame().servicesOverlayController().selectedTelephoneNumberRangesChanged();
3427 }
3428
3429 void Editor::scanRangeForTelephoneNumbers(Range& range, const StringView& stringView, Vector<RefPtr<Range>>& markedRanges)
3430 {
3431     // Don't scan for phone numbers inside editable regions.
3432     Node& startNode = range.startContainer();
3433     if (startNode.hasEditableStyle())
3434         return;
3435
3436     // relativeStartPosition and relativeEndPosition are the endpoints of the phone number range,
3437     // relative to the scannerPosition
3438     unsigned length = stringView.length();
3439     unsigned scannerPosition = 0;
3440     int relativeStartPosition = 0;
3441     int relativeEndPosition = 0;
3442
3443     auto characters = stringView.upconvertedCharacters();
3444
3445     while (scannerPosition < length && TelephoneNumberDetector::find(&characters[scannerPosition], length - scannerPosition, &relativeStartPosition, &relativeEndPosition)) {
3446         // The convention in the Data Detectors framework is that the end position is the first character NOT in the phone number
3447         // (that is, the length of the range is relativeEndPosition - relativeStartPosition). So subtract 1 to get the same
3448         // convention as the old WebCore phone number parser (so that the rest of the code is still valid if we want to go back
3449         // to the old parser).
3450         --relativeEndPosition;
3451
3452         ASSERT(scannerPosition + relativeEndPosition < length);
3453
3454         unsigned subrangeOffset = scannerPosition + relativeStartPosition;
3455         unsigned subrangeLength = relativeEndPosition - relativeStartPosition + 1;
3456
3457         RefPtr<Range> subrange = TextIterator::subrange(range, subrangeOffset, subrangeLength);
3458
3459         markedRanges.append(subrange);
3460         range.ownerDocument().markers().addMarker(subrange.get(), DocumentMarker::TelephoneNumber);
3461
3462         scannerPosition += relativeEndPosition + 1;
3463     }
3464 }
3465
3466 #endif // ENABLE(TELEPHONE_NUMBER_DETECTION) && !PLATFORM(IOS)
3467
3468 void Editor::updateEditorUINowIfScheduled()
3469 {
3470     if (!m_editorUIUpdateTimer.isActive())
3471         return;
3472     m_editorUIUpdateTimer.stop();
3473     editorUIUpdateTimerFired();
3474 }
3475
3476 void Editor::editorUIUpdateTimerFired()
3477 {
3478     VisibleSelection oldSelection = m_oldSelectionForEditorUIUpdate;
3479
3480     m_alternativeTextController->stopPendingCorrection(oldSelection);
3481     
3482     bool isContinuousSpellCheckingEnabled = this->isContinuousSpellCheckingEnabled();
3483     bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && isGrammarCheckingEnabled();
3484     if (isContinuousSpellCheckingEnabled) {
3485         VisibleSelection newAdjacentWords;
3486         VisibleSelection newSelectedSentence;
3487         bool caretBrowsing = m_frame.settings().caretBrowsingEnabled();
3488         if (m_frame.selection().selection().isContentEditable() || caretBrowsing) {
3489             VisiblePosition newStart(m_frame.selection().selection().visibleStart());
3490 #if !PLATFORM(IOS)
3491             newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
3492 #else
3493             // If this bug gets fixed, this PLATFORM(IOS) code could be removed:
3494             // <rdar://problem/7259611> Word boundary code on iPhone gives different results than desktop
3495             EWordSide startWordSide = LeftWordIfOnBoundary;
3496             UChar32 c = newStart.characterBefore();
3497             // FIXME: VisiblePosition::characterAfter() and characterBefore() do not emit newlines the same
3498             // way as TextIterator, so we do an isStartOfParagraph check here.
3499             if (isSpaceOrNewline(c) || c == 0xA0 || isStartOfParagraph(newStart)) {
3500                 startWordSide = RightWordIfOnBoundary;
3501             }
3502             newAdjacentWords = VisibleSelection(startOfWord(newStart, startWordSide), endOfWord(newStart, RightWordIfOnBoundary));
3503 #endif // !PLATFORM(IOS)
3504             if (isContinuousGrammarCheckingEnabled)
3505                 newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
3506         }
3507
3508         // When typing we check spelling elsewhere, so don't redo it here.
3509         // If this is a change in selection resulting from a delete operation,
3510         // oldSelection may no longer be in the document.
3511         if (m_editorUIUpdateTimerShouldCheckSpellingAndGrammar && oldSelection.isContentEditable() && oldSelection.start().deprecatedNode() && oldSelection.start().anchorNode()->isConnected()) {
3512             VisiblePosition oldStart(oldSelection.visibleStart());
3513             VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
3514             if (oldAdjacentWords != newAdjacentWords) {
3515                 if (isContinuousGrammarCheckingEnabled) {
3516                     VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
3517                     markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence);
3518                 } else
3519                     markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
3520             }
3521         }
3522
3523         if (!textChecker() || textChecker()->shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) {
3524             if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
3525                 document().markers().removeMarkers(wordRange.get(), DocumentMarker::Spelling);
3526         }
3527         if (!textChecker() || textChecker()->shouldEraseMarkersAfterChangeSelection(TextCheckingTypeGrammar)) {
3528             if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
3529                 document().markers().removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
3530         }
3531     }
3532
3533     // When continuous spell checking is off, existing markers disappear after the selection changes.
3534     if (!isContinuousSpellCheckingEnabled)
3535         document().markers().removeMarkers(DocumentMarker::Spelling);
3536     if (!isContinuousGrammarCheckingEnabled)
3537         document().markers().removeMarkers(DocumentMarker::Grammar);
3538
3539     if (!m_editorUIUpdateTimerWasTriggeredByDictation)
3540         m_alternativeTextController->respondToChangedSelection(oldSelection);
3541
3542     m_oldSele