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