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