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