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