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