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