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