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