Cleanup: Use exceptionless Range::* methods rather than ignoring exceptions.
[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     Node* startContainer = range->startContainer();
258     Node* endContainer = range->endContainer();
259     if (!startContainer || !endContainer)
260         return false;
261     
262     if (!startContainer->rendererIsEditable() || !endContainer->rendererIsEditable())
263         return false;
264
265     ExceptionCode ec;
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     willWriteSelectionToPasteboard(selection);
986     if (shouldDeleteRange(selection.get())) {
987         updateMarkersForWordsAffectedByEditing(true);
988         if (enclosingTextFormControl(m_frame->selection()->start())) {
989             Pasteboard::generalPasteboard()->writePlainText(selectedText(),
990                 canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
991         } else
992             Pasteboard::generalPasteboard()->writeSelection(selection.get(), canSmartCopyOrDelete(), m_frame);
993         didWriteSelectionToPasteboard();
994         deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
995     }
996 }
997
998 void Editor::copy()
999 {
1000     if (tryDHTMLCopy())
1001         return; // DHTML did the whole operation
1002     if (!canCopy()) {
1003         systemBeep();
1004         return;
1005     }
1006
1007     willWriteSelectionToPasteboard(selectedRange());
1008     if (enclosingTextFormControl(m_frame->selection()->start())) {
1009         Pasteboard::generalPasteboard()->writePlainText(selectedText(),
1010             canSmartCopyOrDelete() ? Pasteboard::CanSmartReplace : Pasteboard::CannotSmartReplace);
1011     } else {
1012         Document* document = m_frame->document();
1013         if (HTMLImageElement* imageElement = imageElementFromImageDocument(document))
1014             Pasteboard::generalPasteboard()->writeImage(imageElement, document->url(), document->title());
1015         else
1016             Pasteboard::generalPasteboard()->writeSelection(selectedRange().get(), canSmartCopyOrDelete(), m_frame);
1017     }
1018
1019     didWriteSelectionToPasteboard();
1020 }
1021
1022 void Editor::paste()
1023 {
1024     ASSERT(m_frame->document());
1025     if (tryDHTMLPaste())
1026         return; // DHTML did the whole operation
1027     if (!canPaste())
1028         return;
1029     updateMarkersForWordsAffectedByEditing(false);
1030     CachedResourceLoader* loader = m_frame->document()->cachedResourceLoader();
1031     ResourceCacheValidationSuppressor validationSuppressor(loader);
1032     if (m_frame->selection()->isContentRichlyEditable())
1033         pasteWithPasteboard(Pasteboard::generalPasteboard(), true);
1034     else
1035         pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard());
1036 }
1037
1038 void Editor::pasteAsPlainText()
1039 {
1040     if (tryDHTMLPaste())
1041         return;
1042     if (!canPaste())
1043         return;
1044     updateMarkersForWordsAffectedByEditing(false);
1045     pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard());
1046 }
1047
1048 void Editor::performDelete()
1049 {
1050     if (!canDelete()) {
1051         systemBeep();
1052         return;
1053     }
1054
1055     addToKillRing(selectedRange().get(), false);
1056     deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
1057
1058     // clear the "start new kill ring sequence" setting, because it was set to true
1059     // when the selection was updated by deleting the range
1060     setStartNewKillRingSequence(false);
1061 }
1062
1063 void Editor::simplifyMarkup(Node* startNode, Node* endNode)
1064 {
1065     if (!startNode)
1066         return;
1067     if (endNode) {
1068         if (startNode->document() != endNode->document())
1069             return;
1070         // check if start node is before endNode
1071         Node* node = startNode;
1072         while (node && node != endNode)
1073             node = NodeTraversal::next(node);
1074         if (!node)
1075             return;
1076     }
1077     
1078     applyCommand(SimplifyMarkupCommand::create(m_frame->document(), startNode, (endNode) ? NodeTraversal::next(endNode) : 0));
1079 }
1080
1081 void Editor::copyURL(const KURL& url, const String& title)
1082 {
1083     Pasteboard::generalPasteboard()->writeURL(url, title, m_frame);
1084 }
1085
1086 void Editor::copyImage(const HitTestResult& result)
1087 {
1088     KURL url = result.absoluteLinkURL();
1089     if (url.isEmpty())
1090         url = result.absoluteImageURL();
1091
1092     Pasteboard::generalPasteboard()->writeImage(result.innerNonSharedNode(), url, result.altDisplayString());
1093 }
1094
1095 bool Editor::isContinuousSpellCheckingEnabled() const
1096 {
1097     return client() && client()->isContinuousSpellCheckingEnabled();
1098 }
1099
1100 void Editor::toggleContinuousSpellChecking()
1101 {
1102     if (client())
1103         client()->toggleContinuousSpellChecking();
1104 }
1105
1106 bool Editor::isGrammarCheckingEnabled()
1107 {
1108     return client() && client()->isGrammarCheckingEnabled();
1109 }
1110
1111 void Editor::toggleGrammarChecking()
1112 {
1113     if (client())
1114         client()->toggleGrammarChecking();
1115 }
1116
1117 int Editor::spellCheckerDocumentTag()
1118 {
1119     return client() ? client()->spellCheckerDocumentTag() : 0;
1120 }
1121
1122 #if USE(APPKIT)
1123
1124 void Editor::uppercaseWord()
1125 {
1126     if (client())
1127         client()->uppercaseWord();
1128 }
1129
1130 void Editor::lowercaseWord()
1131 {
1132     if (client())
1133         client()->lowercaseWord();
1134 }
1135
1136 void Editor::capitalizeWord()
1137 {
1138     if (client())
1139         client()->capitalizeWord();
1140 }
1141     
1142 #endif
1143
1144 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1145
1146 void Editor::showSubstitutionsPanel()
1147 {
1148     if (!client()) {
1149         LOG_ERROR("No NSSpellChecker");
1150         return;
1151     }
1152
1153     if (client()->substitutionsPanelIsShowing()) {
1154         client()->showSubstitutionsPanel(false);
1155         return;
1156     }
1157     client()->showSubstitutionsPanel(true);
1158 }
1159
1160 bool Editor::substitutionsPanelIsShowing()
1161 {
1162     if (!client())
1163         return false;
1164     return client()->substitutionsPanelIsShowing();
1165 }
1166
1167 void Editor::toggleSmartInsertDelete()
1168 {
1169     if (client())
1170         client()->toggleSmartInsertDelete();
1171 }
1172
1173 bool Editor::isAutomaticQuoteSubstitutionEnabled()
1174 {
1175     return client() && client()->isAutomaticQuoteSubstitutionEnabled();
1176 }
1177
1178 void Editor::toggleAutomaticQuoteSubstitution()
1179 {
1180     if (client())
1181         client()->toggleAutomaticQuoteSubstitution();
1182 }
1183
1184 bool Editor::isAutomaticLinkDetectionEnabled()
1185 {
1186     return client() && client()->isAutomaticLinkDetectionEnabled();
1187 }
1188
1189 void Editor::toggleAutomaticLinkDetection()
1190 {
1191     if (client())
1192         client()->toggleAutomaticLinkDetection();
1193 }
1194
1195 bool Editor::isAutomaticDashSubstitutionEnabled()
1196 {
1197     return client() && client()->isAutomaticDashSubstitutionEnabled();
1198 }
1199
1200 void Editor::toggleAutomaticDashSubstitution()
1201 {
1202     if (client())
1203         client()->toggleAutomaticDashSubstitution();
1204 }
1205
1206 bool Editor::isAutomaticTextReplacementEnabled()
1207 {
1208     return client() && client()->isAutomaticTextReplacementEnabled();
1209 }
1210
1211 void Editor::toggleAutomaticTextReplacement()
1212 {
1213     if (client())
1214         client()->toggleAutomaticTextReplacement();
1215 }
1216
1217 bool Editor::isAutomaticSpellingCorrectionEnabled()
1218 {
1219     return m_alternativeTextController->isAutomaticSpellingCorrectionEnabled();
1220 }
1221
1222 void Editor::toggleAutomaticSpellingCorrection()
1223 {
1224     if (client())
1225         client()->toggleAutomaticSpellingCorrection();
1226 }
1227
1228 #endif
1229
1230 bool Editor::shouldEndEditing(Range* range)
1231 {
1232     return client() && client()->shouldEndEditing(range);
1233 }
1234
1235 bool Editor::shouldBeginEditing(Range* range)
1236 {
1237     return client() && client()->shouldBeginEditing(range);
1238 }
1239
1240 void Editor::clearUndoRedoOperations()
1241 {
1242     if (client())
1243         client()->clearUndoRedoOperations();
1244 }
1245
1246 bool Editor::canUndo()
1247 {
1248     return client() && client()->canUndo();
1249 }
1250
1251 void Editor::undo()
1252 {
1253     if (client())
1254         client()->undo();
1255 }
1256
1257 bool Editor::canRedo()
1258 {
1259     return client() && client()->canRedo();
1260 }
1261
1262 void Editor::redo()
1263 {
1264     if (client())
1265         client()->redo();
1266 }
1267
1268 void Editor::didBeginEditing()
1269 {
1270     if (client())
1271         client()->didBeginEditing();
1272 }
1273
1274 void Editor::didEndEditing()
1275 {
1276     if (client())
1277         client()->didEndEditing();
1278 }
1279
1280 void Editor::willWriteSelectionToPasteboard(PassRefPtr<Range> range)
1281 {
1282     if (client())
1283         client()->willWriteSelectionToPasteboard(range.get());
1284 }
1285
1286 void Editor::didWriteSelectionToPasteboard()
1287 {
1288     if (client())
1289         client()->didWriteSelectionToPasteboard();
1290 }
1291
1292 void Editor::toggleBold()
1293 {
1294     command("ToggleBold").execute();
1295 }
1296
1297 void Editor::toggleUnderline()
1298 {
1299     command("ToggleUnderline").execute();
1300 }
1301
1302 void Editor::setBaseWritingDirection(WritingDirection direction)
1303 {
1304     Node* focusedNode = frame()->document()->focusedNode();
1305     if (focusedNode && isHTMLTextFormControlElement(focusedNode)) {
1306         if (direction == NaturalWritingDirection)
1307             return;
1308         toHTMLElement(focusedNode)->setAttribute(dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl");
1309         focusedNode->dispatchInputEvent();
1310         frame()->document()->updateStyleIfNeeded();
1311         return;
1312     }
1313
1314     RefPtr<StylePropertySet> style = StylePropertySet::create();
1315     style->setProperty(CSSPropertyDirection, direction == LeftToRightWritingDirection ? "ltr" : direction == RightToLeftWritingDirection ? "rtl" : "inherit", false);
1316     applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection);
1317 }
1318
1319 void Editor::selectComposition()
1320 {
1321     RefPtr<Range> range = compositionRange();
1322     if (!range)
1323         return;
1324     
1325     // The composition can start inside a composed character sequence, so we have to override checks.
1326     // See <http://bugs.webkit.org/show_bug.cgi?id=15781>
1327     VisibleSelection selection;
1328     selection.setWithoutValidation(range->startPosition(), range->endPosition());
1329     m_frame->selection()->setSelection(selection, 0);
1330 }
1331
1332 void Editor::confirmComposition()
1333 {
1334     if (!m_compositionNode)
1335         return;
1336     setComposition(m_compositionNode->data().substring(m_compositionStart, m_compositionEnd - m_compositionStart), ConfirmComposition);
1337 }
1338
1339 void Editor::cancelComposition()
1340 {
1341     if (!m_compositionNode)
1342         return;
1343     setComposition(emptyString(), CancelComposition);
1344 }
1345
1346 bool Editor::cancelCompositionIfSelectionIsInvalid()
1347 {
1348     unsigned start;
1349     unsigned end;
1350     if (!hasComposition() || ignoreCompositionSelectionChange() || getCompositionSelection(start, end))
1351         return false;
1352
1353     cancelComposition();
1354     return true;
1355 }
1356
1357 void Editor::confirmComposition(const String& text)
1358 {
1359     setComposition(text, ConfirmComposition);
1360 }
1361
1362 void Editor::setComposition(const String& text, SetCompositionMode mode)
1363 {
1364     ASSERT(mode == ConfirmComposition || mode == CancelComposition);
1365     UserTypingGestureIndicator typingGestureIndicator(m_frame);
1366
1367     setIgnoreCompositionSelectionChange(true);
1368
1369     if (mode == CancelComposition)
1370         ASSERT(text == emptyString());
1371     else
1372         selectComposition();
1373
1374     if (m_frame->selection()->isNone()) {
1375         setIgnoreCompositionSelectionChange(false);
1376         return;
1377     }
1378     
1379     // Dispatch a compositionend event to the focused node.
1380     // We should send this event before sending a TextEvent as written in Section 6.2.2 and 6.2.3 of
1381     // the DOM Event specification.
1382     Node* target = m_frame->document()->focusedNode();
1383     if (target) {
1384         RefPtr<CompositionEvent> event = CompositionEvent::create(eventNames().compositionendEvent, m_frame->document()->domWindow(), text);
1385         ExceptionCode ec = 0;
1386         target->dispatchEvent(event, ec);
1387     }
1388
1389     // If text is empty, then delete the old composition here.  If text is non-empty, InsertTextCommand::input
1390     // will delete the old composition with an optimized replace operation.
1391     if (text.isEmpty() && mode != CancelComposition)
1392         TypingCommand::deleteSelection(m_frame->document(), 0);
1393
1394     m_compositionNode = 0;
1395     m_customCompositionUnderlines.clear();
1396
1397     insertTextForConfirmedComposition(text);
1398
1399     if (mode == CancelComposition) {
1400         // An open typing command that disagrees about current selection would cause issues with typing later on.
1401         TypingCommand::closeTyping(m_frame);
1402     }
1403
1404     setIgnoreCompositionSelectionChange(false);
1405 }
1406
1407 void Editor::setComposition(const String& text, const Vector<CompositionUnderline>& underlines, unsigned selectionStart, unsigned selectionEnd)
1408 {
1409     UserTypingGestureIndicator typingGestureIndicator(m_frame);
1410
1411     setIgnoreCompositionSelectionChange(true);
1412
1413     // Updates styles before setting selection for composition to prevent
1414     // inserting the previous composition text into text nodes oddly.
1415     // See https://bugs.webkit.org/show_bug.cgi?id=46868
1416     m_frame->document()->updateStyleIfNeeded();
1417
1418     selectComposition();
1419
1420     if (m_frame->selection()->isNone()) {
1421         setIgnoreCompositionSelectionChange(false);
1422         return;
1423     }
1424
1425     Node* target = m_frame->document()->focusedNode();
1426     if (target) {
1427         // Dispatch an appropriate composition event to the focused node.
1428         // We check the composition status and choose an appropriate composition event since this
1429         // function is used for three purposes:
1430         // 1. Starting a new composition.
1431         //    Send a compositionstart and a compositionupdate event when this function creates
1432         //    a new composition node, i.e.
1433         //    m_compositionNode == 0 && !text.isEmpty().
1434         //    Sending a compositionupdate event at this time ensures that at least one
1435         //    compositionupdate event is dispatched.
1436         // 2. Updating the existing composition node.
1437         //    Send a compositionupdate event when this function updates the existing composition
1438         //    node, i.e. m_compositionNode != 0 && !text.isEmpty().
1439         // 3. Canceling the ongoing composition.
1440         //    Send a compositionend event when function deletes the existing composition node, i.e.
1441         //    m_compositionNode != 0 && test.isEmpty().
1442         RefPtr<CompositionEvent> event;
1443         if (!m_compositionNode) {
1444             // We should send a compositionstart event only when the given text is not empty because this
1445             // function doesn't create a composition node when the text is empty.
1446             if (!text.isEmpty()) {
1447                 target->dispatchEvent(CompositionEvent::create(eventNames().compositionstartEvent, m_frame->document()->domWindow(), text));
1448                 event = CompositionEvent::create(eventNames().compositionupdateEvent, m_frame->document()->domWindow(), text);
1449             }
1450         } else {
1451             if (!text.isEmpty())
1452                 event = CompositionEvent::create(eventNames().compositionupdateEvent, m_frame->document()->domWindow(), text);
1453             else
1454               event = CompositionEvent::create(eventNames().compositionendEvent, m_frame->document()->domWindow(), text);
1455         }
1456         ExceptionCode ec = 0;
1457         if (event.get())
1458             target->dispatchEvent(event, ec);
1459     }
1460
1461     // If text is empty, then delete the old composition here.  If text is non-empty, InsertTextCommand::input
1462     // will delete the old composition with an optimized replace operation.
1463     if (text.isEmpty())
1464         TypingCommand::deleteSelection(m_frame->document(), TypingCommand::PreventSpellChecking);
1465
1466     m_compositionNode = 0;
1467     m_customCompositionUnderlines.clear();
1468
1469     if (!text.isEmpty()) {
1470         TypingCommand::insertText(m_frame->document(), text, TypingCommand::SelectInsertedText | TypingCommand::PreventSpellChecking, TypingCommand::TextCompositionUpdate);
1471
1472         // Find out what node has the composition now.
1473         Position base = m_frame->selection()->base().downstream();
1474         Position extent = m_frame->selection()->extent();
1475         Node* baseNode = base.deprecatedNode();
1476         unsigned baseOffset = base.deprecatedEditingOffset();
1477         Node* extentNode = extent.deprecatedNode();
1478         unsigned extentOffset = extent.deprecatedEditingOffset();
1479
1480         if (baseNode && baseNode == extentNode && baseNode->isTextNode() && baseOffset + text.length() == extentOffset) {
1481             m_compositionNode = toText(baseNode);
1482             m_compositionStart = baseOffset;
1483             m_compositionEnd = extentOffset;
1484             m_customCompositionUnderlines = underlines;
1485             size_t numUnderlines = m_customCompositionUnderlines.size();
1486             for (size_t i = 0; i < numUnderlines; ++i) {
1487                 m_customCompositionUnderlines[i].startOffset += baseOffset;
1488                 m_customCompositionUnderlines[i].endOffset += baseOffset;
1489             }
1490             if (baseNode->renderer())
1491                 baseNode->renderer()->repaint();
1492
1493             unsigned start = min(baseOffset + selectionStart, extentOffset);
1494             unsigned end = min(max(start, baseOffset + selectionEnd), extentOffset);
1495             RefPtr<Range> selectedRange = Range::create(baseNode->document(), baseNode, start, baseNode, end);                
1496             m_frame->selection()->setSelectedRange(selectedRange.get(), DOWNSTREAM, false);
1497         }
1498     }
1499
1500     setIgnoreCompositionSelectionChange(false);
1501 }
1502
1503 void Editor::ignoreSpelling()
1504 {
1505     if (!client())
1506         return;
1507         
1508     RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange();
1509     if (selectedRange)
1510         frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
1511
1512     String text = selectedText();
1513     ASSERT(text.length());
1514     textChecker()->ignoreWordInSpellDocument(text);
1515 }
1516
1517 void Editor::learnSpelling()
1518 {
1519     if (!client())
1520         return;
1521         
1522     // 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>.
1523
1524     RefPtr<Range> selectedRange = frame()->selection()->toNormalizedRange();
1525     if (selectedRange)
1526         frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
1527
1528     String text = selectedText();
1529     ASSERT(text.length());
1530     textChecker()->learnWord(text);
1531 }
1532
1533 void Editor::advanceToNextMisspelling(bool startBeforeSelection)
1534 {
1535     ExceptionCode ec = 0;
1536
1537     // The basic approach is to search in two phases - from the selection end to the end of the doc, and
1538     // then we wrap and search from the doc start to (approximately) where we started.
1539     
1540     // Start at the end of the selection, search to edge of document.  Starting at the selection end makes
1541     // repeated "check spelling" commands work.
1542     VisibleSelection selection(frame()->selection()->selection());
1543     RefPtr<Range> spellingSearchRange(rangeOfContents(frame()->document()));
1544
1545     bool startedWithSelection = false;
1546     if (selection.start().deprecatedNode()) {
1547         startedWithSelection = true;
1548         if (startBeforeSelection) {
1549             VisiblePosition start(selection.visibleStart());
1550             // We match AppKit's rule: Start 1 character before the selection.
1551             VisiblePosition oneBeforeStart = start.previous();
1552             setStart(spellingSearchRange.get(), oneBeforeStart.isNotNull() ? oneBeforeStart : start);
1553         } else
1554             setStart(spellingSearchRange.get(), selection.visibleEnd());
1555     }
1556
1557     Position position = spellingSearchRange->startPosition();
1558     if (!isEditablePosition(position)) {
1559         // This shouldn't happen in very often because the Spelling menu items aren't enabled unless the
1560         // selection is editable.
1561         // This can happen in Mail for a mix of non-editable and editable content (like Stationary), 
1562         // when spell checking the whole document before sending the message.
1563         // In that case the document might not be editable, but there are editable pockets that need to be spell checked.
1564
1565         position = firstEditablePositionAfterPositionInRoot(position, frame()->document()->documentElement()).deepEquivalent();
1566         if (position.isNull())
1567             return;
1568         
1569         Position rangeCompliantPosition = position.parentAnchoredEquivalent();
1570         spellingSearchRange->setStart(rangeCompliantPosition.deprecatedNode(), rangeCompliantPosition.deprecatedEditingOffset(), ec);
1571         startedWithSelection = false; // won't need to wrap
1572     }
1573     
1574     // topNode defines the whole range we want to operate on 
1575     Node* topNode = highestEditableRoot(position);
1576     // FIXME: lastOffsetForEditing() is wrong here if editingIgnoresContent(highestEditableRoot()) returns true (e.g. a <table>)
1577     spellingSearchRange->setEnd(topNode, lastOffsetForEditing(topNode), ec);
1578
1579     // If spellingSearchRange starts in the middle of a word, advance to the next word so we start checking
1580     // at a word boundary. Going back by one char and then forward by a word does the trick.
1581     if (startedWithSelection) {
1582         VisiblePosition oneBeforeStart = startVisiblePosition(spellingSearchRange.get(), DOWNSTREAM).previous();
1583         if (oneBeforeStart.isNotNull())
1584             setStart(spellingSearchRange.get(), endOfWord(oneBeforeStart));
1585         // else we were already at the start of the editable node
1586     }
1587
1588     if (spellingSearchRange->collapsed(ec))
1589         return; // nothing to search in
1590     
1591     // Get the spell checker if it is available
1592     if (!client())
1593         return;
1594         
1595     // We go to the end of our first range instead of the start of it, just to be sure
1596     // we don't get foiled by any word boundary problems at the start.  It means we might
1597     // do a tiny bit more searching.
1598     Node* searchEndNodeAfterWrap = spellingSearchRange->endContainer();
1599     int searchEndOffsetAfterWrap = spellingSearchRange->endOffset();
1600     
1601     int misspellingOffset = 0;
1602     GrammarDetail grammarDetail;
1603     int grammarPhraseOffset = 0;
1604     RefPtr<Range> grammarSearchRange;
1605     String badGrammarPhrase;
1606     String misspelledWord;
1607
1608     bool isSpelling = true;
1609     int foundOffset = 0;
1610     String foundItem;
1611     RefPtr<Range> firstMisspellingRange;
1612     if (unifiedTextCheckerEnabled()) {
1613         grammarSearchRange = spellingSearchRange->cloneRange(ec);
1614         foundItem = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
1615         if (isSpelling) {
1616             misspelledWord = foundItem;
1617             misspellingOffset = foundOffset;
1618         } else {
1619             badGrammarPhrase = foundItem;
1620             grammarPhraseOffset = foundOffset;
1621         }
1622     } else {
1623         misspelledWord = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange);
1624
1625 #if USE(GRAMMAR_CHECKING)
1626         grammarSearchRange = spellingSearchRange->cloneRange(ec);
1627         if (!misspelledWord.isEmpty()) {
1628             // Stop looking at start of next misspelled word
1629             CharacterIterator chars(grammarSearchRange.get());
1630             chars.advance(misspellingOffset);
1631             grammarSearchRange->setEnd(chars.range()->startContainer(), chars.range()->startOffset(), ec);
1632         }
1633     
1634         if (isGrammarCheckingEnabled())
1635             badGrammarPhrase = TextCheckingHelper(client(), grammarSearchRange).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false);
1636 #endif
1637     }
1638     
1639     // 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
1640     // block rather than at a selection).
1641     if (startedWithSelection && !misspelledWord && !badGrammarPhrase) {
1642         spellingSearchRange->setStart(topNode, 0, ec);
1643         // going until the end of the very first chunk we tested is far enough
1644         spellingSearchRange->setEnd(searchEndNodeAfterWrap, searchEndOffsetAfterWrap, ec);
1645         
1646         if (unifiedTextCheckerEnabled()) {
1647             grammarSearchRange = spellingSearchRange->cloneRange(ec);
1648             foundItem = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
1649             if (isSpelling) {
1650                 misspelledWord = foundItem;
1651                 misspellingOffset = foundOffset;
1652             } else {
1653                 badGrammarPhrase = foundItem;
1654                 grammarPhraseOffset = foundOffset;
1655             }
1656         } else {
1657             misspelledWord = TextCheckingHelper(client(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange);
1658
1659 #if USE(GRAMMAR_CHECKING)
1660             grammarSearchRange = spellingSearchRange->cloneRange(ec);
1661             if (!misspelledWord.isEmpty()) {
1662                 // Stop looking at start of next misspelled word
1663                 CharacterIterator chars(grammarSearchRange.get());
1664                 chars.advance(misspellingOffset);
1665                 grammarSearchRange->setEnd(chars.range()->startContainer(), chars.range()->startOffset(), ec);
1666             }
1667
1668             if (isGrammarCheckingEnabled())
1669                 badGrammarPhrase = TextCheckingHelper(client(), grammarSearchRange).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false);
1670 #endif
1671         }
1672     }
1673     
1674     if (!badGrammarPhrase.isEmpty()) {
1675         ASSERT(WTF_USE_GRAMMAR_CHECKING);
1676         // We found bad grammar. Since we only searched for bad grammar up to the first misspelled word, the bad grammar
1677         // takes precedence and we ignore any potential misspelled word. Select the grammar detail, update the spelling
1678         // panel, and store a marker so we draw the green squiggle later.
1679         
1680         ASSERT(badGrammarPhrase.length() > 0);
1681         ASSERT(grammarDetail.location != -1 && grammarDetail.length > 0);
1682         
1683         // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
1684         RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
1685         frame()->selection()->setSelection(VisibleSelection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY));
1686         frame()->selection()->revealSelection();
1687         
1688         client()->updateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail);
1689         frame()->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
1690     } else if (!misspelledWord.isEmpty()) {
1691         // We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store
1692         // a marker so we draw the red squiggle later.
1693         
1694         RefPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRange.get(), misspellingOffset, misspelledWord.length());
1695         frame()->selection()->setSelection(VisibleSelection(misspellingRange.get(), DOWNSTREAM));
1696         frame()->selection()->revealSelection();
1697         
1698         client()->updateSpellingUIWithMisspelledWord(misspelledWord);
1699         frame()->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
1700     }
1701 }
1702
1703 String Editor::misspelledWordAtCaretOrRange(Node* clickedNode) const
1704 {
1705     if (!isContinuousSpellCheckingEnabled() || !clickedNode || !isSpellCheckingEnabledFor(clickedNode))
1706         return String();
1707
1708     VisibleSelection selection = m_frame->selection()->selection();
1709     if (!selection.isContentEditable() || selection.isNone())
1710         return String();
1711
1712     VisibleSelection wordSelection(selection.base());
1713     wordSelection.expandUsingGranularity(WordGranularity);
1714     RefPtr<Range> wordRange = wordSelection.toNormalizedRange();
1715
1716     // In compliance with GTK+ applications, additionally allow to provide suggestions when the current
1717     // selection exactly match the word selection.
1718     if (selection.isRange() && !areRangesEqual(wordRange.get(), selection.toNormalizedRange().get()))
1719         return String();
1720
1721     String word = wordRange->text();
1722     if (word.isEmpty() || !client())
1723         return String();
1724
1725     int wordLength = word.length();
1726     int misspellingLocation = -1;
1727     int misspellingLength = 0;
1728     textChecker()->checkSpellingOfString(word.characters(), wordLength, &misspellingLocation, &misspellingLength);
1729
1730     return misspellingLength == wordLength ? word : String();
1731 }
1732
1733 String Editor::misspelledSelectionString() const
1734 {
1735     String selectedString = selectedText();
1736     int length = selectedString.length();
1737     if (!length || !client())
1738         return String();
1739
1740     int misspellingLocation = -1;
1741     int misspellingLength = 0;
1742     textChecker()->checkSpellingOfString(selectedString.characters(), length, &misspellingLocation, &misspellingLength);
1743     
1744     // The selection only counts as misspelled if the selected text is exactly one misspelled word
1745     if (misspellingLength != length)
1746         return String();
1747     
1748     // Update the spelling panel to be displaying this error (whether or not the spelling panel is on screen).
1749     // This is necessary to make a subsequent call to [NSSpellChecker ignoreWord:inSpellDocumentWithTag:] work
1750     // correctly; that call behaves differently based on whether the spelling panel is displaying a misspelling
1751     // or a grammar error.
1752     client()->updateSpellingUIWithMisspelledWord(selectedString);
1753     
1754     return selectedString;
1755 }
1756
1757 bool Editor::isSelectionUngrammatical()
1758 {
1759 #if USE(GRAMMAR_CHECKING)
1760     Vector<String> ignoredGuesses;
1761     RefPtr<Range> range = frame()->selection()->toNormalizedRange();
1762     if (!range)
1763         return false;
1764     return TextCheckingHelper(client(), range).isUngrammatical(ignoredGuesses);
1765 #else
1766     return false;
1767 #endif
1768 }
1769
1770 Vector<String> Editor::guessesForUngrammaticalSelection()
1771 {
1772 #if USE(GRAMMAR_CHECKING)
1773     Vector<String> guesses;
1774     RefPtr<Range> range = frame()->selection()->toNormalizedRange();
1775     if (!range)
1776         return guesses;
1777     // Ignore the result of isUngrammatical; we just want the guesses, whether or not there are any
1778     TextCheckingHelper(client(), range).isUngrammatical(guesses);
1779     return guesses;
1780 #else
1781     return Vector<String>();
1782 #endif
1783 }
1784
1785 Vector<String> Editor::guessesForMisspelledWord(const String& word) const
1786 {
1787     ASSERT(word.length());
1788
1789     Vector<String> guesses;
1790     if (client())
1791         textChecker()->getGuessesForWord(word, String(), guesses);
1792     return guesses;
1793 }
1794
1795 Vector<String> Editor::guessesForMisspelledOrUngrammatical(bool& misspelled, bool& ungrammatical)
1796 {
1797     if (unifiedTextCheckerEnabled()) {
1798         RefPtr<Range> range;
1799         FrameSelection* frameSelection = frame()->selection();
1800         if (frameSelection->isCaret() && behavior().shouldAllowSpellingSuggestionsWithoutSelection()) {
1801             VisibleSelection wordSelection = VisibleSelection(frameSelection->base());
1802             wordSelection.expandUsingGranularity(WordGranularity);
1803             range = wordSelection.toNormalizedRange();
1804         } else
1805             range = frameSelection->toNormalizedRange();
1806         if (!range)
1807             return Vector<String>();
1808         return TextCheckingHelper(client(), range).guessesForMisspelledOrUngrammaticalRange(isGrammarCheckingEnabled(), misspelled, ungrammatical);
1809     }
1810
1811     String misspelledWord = behavior().shouldAllowSpellingSuggestionsWithoutSelection() ? misspelledWordAtCaretOrRange(m_frame->document()->focusedNode()) : misspelledSelectionString();
1812     misspelled = !misspelledWord.isEmpty();
1813
1814     if (misspelled) {
1815         ungrammatical = false;
1816         return guessesForMisspelledWord(misspelledWord);
1817     }
1818     if (isGrammarCheckingEnabled() && isSelectionUngrammatical()) {
1819         ungrammatical = true;
1820         return guessesForUngrammaticalSelection();
1821     }
1822     ungrammatical = false;
1823     return Vector<String>();
1824 }
1825
1826 void Editor::showSpellingGuessPanel()
1827 {
1828     if (!client()) {
1829         LOG_ERROR("No NSSpellChecker");
1830         return;
1831     }
1832
1833     if (client()->spellingUIIsShowing()) {
1834         client()->showSpellingUI(false);
1835         return;
1836     }
1837     
1838     advanceToNextMisspelling(true);
1839     client()->showSpellingUI(true);
1840 }
1841
1842 bool Editor::spellingPanelIsShowing()
1843 {
1844     if (!client())
1845         return false;
1846     return client()->spellingUIIsShowing();
1847 }
1848
1849 void Editor::clearMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
1850 {
1851     RefPtr<Range> selectedRange = movingSelection.toNormalizedRange();
1852     if (selectedRange) {
1853         frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
1854         frame()->document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Grammar);
1855     }
1856 }
1857
1858 void Editor::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
1859 {
1860     markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnabled() && isGrammarCheckingEnabled(), movingSelection);
1861 }
1862
1863 void Editor::markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement)
1864 {
1865 #if !USE(AUTOMATIC_TEXT_REPLACEMENT)
1866     UNUSED_PARAM(doReplacement);
1867 #endif
1868
1869     if (unifiedTextCheckerEnabled()) {
1870         m_alternativeTextController->applyPendingCorrection(selectionAfterTyping);
1871
1872         TextCheckingTypeMask textCheckingOptions = 0;
1873
1874         if (isContinuousSpellCheckingEnabled())
1875             textCheckingOptions |= TextCheckingTypeSpelling;
1876
1877 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1878         if (doReplacement
1879             && (isAutomaticQuoteSubstitutionEnabled()
1880                 || isAutomaticLinkDetectionEnabled()
1881                 || isAutomaticDashSubstitutionEnabled()
1882                 || isAutomaticTextReplacementEnabled()
1883                 || ((textCheckingOptions & TextCheckingTypeSpelling) && isAutomaticSpellingCorrectionEnabled())))
1884             textCheckingOptions |= TextCheckingTypeReplacement;
1885 #endif
1886         if (!(textCheckingOptions & (TextCheckingTypeSpelling | TextCheckingTypeReplacement)))
1887             return;
1888
1889         if (isGrammarCheckingEnabled())
1890             textCheckingOptions |= TextCheckingTypeGrammar;
1891
1892         VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
1893         if (textCheckingOptions & TextCheckingTypeGrammar) {
1894             VisibleSelection selectedSentence = VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart));
1895             markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedRange().get(), selectedSentence.toNormalizedRange().get());
1896         } else
1897             markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedRange().get(), adjacentWords.toNormalizedRange().get());
1898         return;
1899     }
1900
1901     if (!isContinuousSpellCheckingEnabled())
1902         return;
1903
1904     // Check spelling of one word
1905     RefPtr<Range> misspellingRange;
1906     markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange);
1907
1908     // Autocorrect the misspelled word.
1909     if (!misspellingRange)
1910         return;
1911     
1912     // Get the misspelled word.
1913     const String misspelledWord = plainText(misspellingRange.get());
1914     String autocorrectedString = textChecker()->getAutoCorrectSuggestionForMisspelledWord(misspelledWord);
1915
1916     // If autocorrected word is non empty, replace the misspelled word by this word.
1917     if (!autocorrectedString.isEmpty()) {
1918         VisibleSelection newSelection(misspellingRange.get(), DOWNSTREAM);
1919         if (newSelection != frame()->selection()->selection()) {
1920             if (!frame()->selection()->shouldChangeSelection(newSelection))
1921                 return;
1922             frame()->selection()->setSelection(newSelection);
1923         }
1924
1925         if (!frame()->editor()->shouldInsertText(autocorrectedString, misspellingRange.get(), EditorInsertActionTyped))
1926             return;
1927         frame()->editor()->replaceSelectionWithText(autocorrectedString, false, false);
1928
1929         // Reset the charet one character further.
1930         frame()->selection()->moveTo(frame()->selection()->end());
1931         frame()->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
1932     }
1933
1934     if (!isGrammarCheckingEnabled())
1935         return;
1936     
1937     // Check grammar of entire sentence
1938     markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart)));
1939 }
1940     
1941 void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtr<Range>& firstMisspellingRange)
1942 {
1943     // This function is called with a selection already expanded to word boundaries.
1944     // Might be nice to assert that here.
1945     
1946     // This function is used only for as-you-type checking, so if that's off we do nothing. Note that
1947     // grammar checking can only be on if spell checking is also on.
1948     if (!isContinuousSpellCheckingEnabled())
1949         return;
1950     
1951     RefPtr<Range> searchRange(selection.toNormalizedRange());
1952     if (!searchRange)
1953         return;
1954     
1955     // If we're not in an editable node, bail.
1956     Node* editableNode = searchRange->startContainer();
1957     if (!editableNode || !editableNode->rendererIsEditable())
1958         return;
1959
1960     if (!isSpellCheckingEnabledFor(editableNode))
1961         return;
1962
1963     // Get the spell checker if it is available
1964     if (!client())
1965         return;
1966     
1967     TextCheckingHelper checker(client(), searchRange);
1968     if (checkSpelling)
1969         checker.markAllMisspellings(firstMisspellingRange);
1970     else {
1971         ASSERT(WTF_USE_GRAMMAR_CHECKING);
1972         if (isGrammarCheckingEnabled())
1973             checker.markAllBadGrammar();
1974     }    
1975 }
1976
1977 bool Editor::isSpellCheckingEnabledFor(Node* node) const
1978 {
1979     if (!node)
1980         return false;
1981     const Element* focusedElement = node->isElementNode() ? toElement(node) : node->parentElement();
1982     if (!focusedElement)
1983         return false;
1984     return focusedElement->isSpellCheckingEnabled();
1985 }
1986
1987 bool Editor::isSpellCheckingEnabledInFocusedNode() const
1988 {
1989     return isSpellCheckingEnabledFor(m_frame->selection()->start().deprecatedNode());
1990 }
1991
1992 void Editor::markMisspellings(const VisibleSelection& selection, RefPtr<Range>& firstMisspellingRange)
1993 {
1994     markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange);
1995 }
1996     
1997 void Editor::markBadGrammar(const VisibleSelection& selection)
1998 {
1999     ASSERT(WTF_USE_GRAMMAR_CHECKING);
2000     RefPtr<Range> firstMisspellingRange;
2001     markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange);
2002 }
2003
2004 void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, Range* spellingRange, Range* grammarRange)
2005 {
2006     ASSERT(m_frame);
2007     ASSERT(unifiedTextCheckerEnabled());
2008
2009     // There shouldn't be pending autocorrection at this moment.
2010     ASSERT(!m_alternativeTextController->hasPendingCorrection());
2011
2012     bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
2013     bool shouldShowCorrectionPanel = textCheckingOptions & TextCheckingTypeShowCorrectionPanel;
2014
2015     // This function is called with selections already expanded to word boundaries.
2016     if (!client() || !spellingRange || (shouldMarkGrammar && !grammarRange))
2017         return;
2018
2019     // If we're not in an editable node, bail.
2020     Node* editableNode = spellingRange->startContainer();
2021     if (!editableNode || !editableNode->rendererIsEditable())
2022         return;
2023
2024     if (!isSpellCheckingEnabledFor(editableNode))
2025         return;
2026
2027     Range* rangeToCheck = shouldMarkGrammar ? grammarRange : spellingRange;
2028     TextCheckingParagraph paragraphToCheck(rangeToCheck);
2029     if (paragraphToCheck.isRangeEmpty() || paragraphToCheck.isEmpty())
2030         return;
2031     RefPtr<Range> paragraphRange = paragraphToCheck.paragraphRange();
2032
2033     bool asynchronous = m_frame && m_frame->settings() && m_frame->settings()->asynchronousSpellCheckingEnabled() && !shouldShowCorrectionPanel;
2034
2035     // In asynchronous mode, we intentionally check paragraph-wide sentence.
2036     RefPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessIncremental, asynchronous ? paragraphRange : rangeToCheck, paragraphRange);
2037
2038     if (asynchronous) {
2039         m_spellChecker->requestCheckingFor(request);
2040         return;
2041     }
2042
2043     Vector<TextCheckingResult> results;
2044     checkTextOfParagraph(textChecker(), paragraphToCheck.textCharacters(), paragraphToCheck.textLength(),
2045         resolveTextCheckingTypeMask(textCheckingOptions), results);
2046     markAndReplaceFor(request, results);
2047 }
2048
2049 void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vector<TextCheckingResult>& results)
2050 {
2051     ASSERT(request);
2052
2053     TextCheckingTypeMask textCheckingOptions = request->mask();
2054     TextCheckingParagraph paragraph(request->checkingRange(), request->paragraphRange());
2055
2056     bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
2057     bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
2058     bool shouldMarkLink = textCheckingOptions & TextCheckingTypeLink;
2059     bool shouldPerformReplacement = textCheckingOptions & TextCheckingTypeReplacement;
2060     bool shouldShowCorrectionPanel = textCheckingOptions & TextCheckingTypeShowCorrectionPanel;
2061     bool shouldCheckForCorrection = shouldShowCorrectionPanel || (textCheckingOptions & TextCheckingTypeCorrection);
2062
2063     // Expand the range to encompass entire paragraphs, since text checking needs that much context.
2064     int selectionOffset = 0;
2065     int ambiguousBoundaryOffset = -1;
2066     bool selectionChanged = false;
2067     bool restoreSelectionAfterChange = false;
2068     bool adjustSelectionForParagraphBoundaries = false;
2069
2070     if (shouldPerformReplacement || shouldMarkSpelling || shouldCheckForCorrection) {
2071         if (m_frame->selection()->selectionType() == VisibleSelection::CaretSelection) {
2072             // Attempt to save the caret position so we can restore it later if needed
2073             Position caretPosition = m_frame->selection()->end();
2074             selectionOffset = paragraph.offsetTo(caretPosition, ASSERT_NO_EXCEPTION);
2075             restoreSelectionAfterChange = true;
2076             if (selectionOffset > 0 && (selectionOffset > paragraph.textLength() || paragraph.textCharAt(selectionOffset - 1) == newlineCharacter))
2077                 adjustSelectionForParagraphBoundaries = true;
2078             if (selectionOffset > 0 && selectionOffset <= paragraph.textLength() && isAmbiguousBoundaryCharacter(paragraph.textCharAt(selectionOffset - 1)))
2079                 ambiguousBoundaryOffset = selectionOffset - 1;
2080         }
2081     }
2082
2083     // If this checking is only for showing correction panel, we shouldn't bother to mark misspellings.
2084     if (shouldShowCorrectionPanel)
2085         shouldMarkSpelling = false;
2086
2087     int offsetDueToReplacement = 0;
2088
2089     for (unsigned i = 0; i < results.size(); i++) {
2090         int spellingRangeEndOffset = paragraph.checkingEnd() + offsetDueToReplacement;
2091         const TextCheckingResult* result = &results[i];
2092         int resultLocation = result->location + offsetDueToReplacement;
2093         int resultLength = result->length;
2094         bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && resultLocation + resultLength == ambiguousBoundaryOffset;
2095
2096         // Only mark misspelling if:
2097         // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false.
2098         // 2. Result falls within spellingRange.
2099         // 3. The word in question doesn't end at an ambiguous boundary. For instance, we would not mark
2100         //    "wouldn'" as misspelled right after apostrophe is typed.
2101         if (shouldMarkSpelling && result->type == TextCheckingTypeSpelling && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) {
2102             ASSERT(resultLength > 0 && resultLocation >= 0);
2103             RefPtr<Range> misspellingRange = paragraph.subrange(resultLocation, resultLength);
2104             if (!m_alternativeTextController->isSpellingMarkerAllowed(misspellingRange))
2105                 continue;
2106             misspellingRange->startContainer()->document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling, result->replacement);
2107         } else if (shouldMarkGrammar && result->type == TextCheckingTypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) {
2108             ASSERT(resultLength > 0 && resultLocation >= 0);
2109             for (unsigned j = 0; j < result->details.size(); j++) {
2110                 const GrammarDetail* detail = &result->details[j];
2111                 ASSERT(detail->length > 0 && detail->location >= 0);
2112                 if (paragraph.checkingRangeCovers(resultLocation + detail->location, detail->length)) {
2113                     RefPtr<Range> badGrammarRange = paragraph.subrange(resultLocation + detail->location, detail->length);
2114                     badGrammarRange->startContainer()->document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
2115                 }
2116             }
2117         } else if (resultLocation + resultLength <= spellingRangeEndOffset && resultLocation + resultLength >= paragraph.checkingStart()
2118                     && (result->type == TextCheckingTypeLink
2119                     || result->type == TextCheckingTypeQuote
2120                     || result->type == TextCheckingTypeDash
2121                     || result->type == TextCheckingTypeReplacement
2122                     || result->type == TextCheckingTypeCorrection)) {
2123             // In this case the result range just has to touch the spelling range, so we can handle replacing non-word text such as punctuation.
2124             ASSERT(resultLength > 0 && resultLocation >= 0);
2125
2126             if (shouldShowCorrectionPanel && (resultLocation + resultLength < spellingRangeEndOffset || result->type != TextCheckingTypeCorrection))
2127                 continue;
2128
2129             int replacementLength = result->replacement.length();
2130
2131             // Apply replacement if:
2132             // 1. The replacement length is non-zero.
2133             // 2. The result doesn't end at an ambiguous boundary.
2134             //    (FIXME: this is required until 6853027 is fixed and text checking can do this for us
2135             bool doReplacement = replacementLength > 0 && !resultEndsAtAmbiguousBoundary;
2136             RefPtr<Range> rangeToReplace = paragraph.subrange(resultLocation, resultLength);
2137             VisibleSelection selectionToReplace(rangeToReplace.get(), DOWNSTREAM);
2138
2139             // adding links should be done only immediately after they are typed
2140             int resultEnd = resultLocation + resultLength;
2141             if (result->type == TextCheckingTypeLink
2142                 && (selectionOffset > resultEnd + 1 || selectionOffset <= resultLocation))
2143                 continue;
2144
2145             if (!(shouldPerformReplacement || shouldCheckForCorrection || shouldMarkLink) || !doReplacement)
2146                 continue;
2147
2148             String replacedString = plainText(rangeToReplace.get());
2149             bool existingMarkersPermitReplacement = m_alternativeTextController->processMarkersOnTextToBeReplacedByResult(result, rangeToReplace.get(), replacedString);
2150             if (!existingMarkersPermitReplacement)
2151                 continue;
2152
2153             if (shouldShowCorrectionPanel) {
2154 #if !USE(AUTOCORRECTION_PANEL)
2155                 ASSERT_NOT_REACHED();
2156 #endif
2157                 // shouldShowCorrectionPanel can be true only when the panel is available.
2158                 if (resultLocation + resultLength == spellingRangeEndOffset) {
2159                     // We only show the correction panel on the last word.
2160                     m_alternativeTextController->show(rangeToReplace, result->replacement);
2161                     break;
2162                 }
2163                 // If this function is called for showing correction panel, we ignore other correction or replacement.
2164                 continue;
2165             }
2166
2167             if (selectionToReplace != m_frame->selection()->selection()) {
2168                 if (!m_frame->selection()->shouldChangeSelection(selectionToReplace))
2169                     continue;
2170             }
2171
2172             if (result->type == TextCheckingTypeLink) {
2173                 m_frame->selection()->setSelection(selectionToReplace);
2174                 selectionChanged = true;
2175                 restoreSelectionAfterChange = false;
2176                 if (canEditRichly())
2177                     applyCommand(CreateLinkCommand::create(m_frame->document(), result->replacement));
2178             } else if (canEdit() && shouldInsertText(result->replacement, rangeToReplace.get(), EditorInsertActionTyped)) {
2179                 Node* root = paragraph.paragraphRange()->startContainer();
2180                 while (ContainerNode* parent = root->parentNode())
2181                     root = parent;
2182
2183                 int paragraphStartIndex = TextIterator::rangeLength(Range::create(m_frame->document(), root, 0, paragraph.paragraphRange()->startContainer(), paragraph.paragraphRange()->startOffset()).get());
2184                 int paragraphLength = TextIterator::rangeLength(paragraph.paragraphRange().get());
2185                 applyCommand(SpellingCorrectionCommand::create(rangeToReplace, result->replacement));
2186                 // Recalculate newParagraphRange, since SpellingCorrectionCommand modifies the DOM, such that the original paragraph range is no longer valid. Radar: 10305315 Bugzilla: 89526
2187                 RefPtr<Range> newParagraphRange = TextIterator::rangeFromLocationAndLength(toContainerNode(root), paragraphStartIndex, paragraphLength + replacementLength - resultLength);
2188                 paragraph = TextCheckingParagraph(TextIterator::subrange(newParagraphRange.get(), resultLocation, replacementLength), newParagraphRange);
2189                 
2190                 if (AXObjectCache::accessibilityEnabled()) {
2191                     if (Element* root = m_frame->selection()->selection().rootEditableElement())
2192                         m_frame->document()->axObjectCache()->postNotification(root, AXObjectCache::AXAutocorrectionOccured, true);
2193                 }
2194
2195                 selectionChanged = true;
2196                 offsetDueToReplacement += replacementLength - resultLength;
2197                 if (resultLocation < selectionOffset) {
2198                     selectionOffset += replacementLength - resultLength;
2199                     if (ambiguousBoundaryOffset >= 0)
2200                         ambiguousBoundaryOffset = selectionOffset - 1;
2201                 }
2202
2203                 // Add a marker so that corrections can easily be undone and won't be re-corrected.
2204                 if (result->type == TextCheckingTypeCorrection)
2205                     m_alternativeTextController->markCorrection(paragraph.subrange(resultLocation, replacementLength), replacedString);
2206             }
2207         }
2208     }
2209
2210     if (selectionChanged) {
2211         TextCheckingParagraph extendedParagraph(paragraph);
2212         // Restore the caret position if we have made any replacements
2213         extendedParagraph.expandRangeToNextEnd();
2214         if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffset <= extendedParagraph.rangeLength()) {
2215             RefPtr<Range> selectionRange = extendedParagraph.subrange(0, selectionOffset);
2216             m_frame->selection()->moveTo(selectionRange->endPosition(), DOWNSTREAM);
2217             if (adjustSelectionForParagraphBoundaries)
2218                 m_frame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
2219         } else {
2220             // If this fails for any reason, the fallback is to go one position beyond the last replacement
2221             m_frame->selection()->moveTo(m_frame->selection()->end());
2222             m_frame->selection()->modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
2223         }
2224     }
2225 }
2226
2227 void Editor::changeBackToReplacedString(const String& replacedString)
2228 {
2229     ASSERT(unifiedTextCheckerEnabled());
2230
2231     if (replacedString.isEmpty())
2232         return;
2233
2234     RefPtr<Range> selection = selectedRange();
2235     if (!shouldInsertText(replacedString, selection.get(), EditorInsertActionPasted))
2236         return;
2237     
2238     m_alternativeTextController->recordAutocorrectionResponseReversed(replacedString, selection);
2239     TextCheckingParagraph paragraph(selection);
2240     replaceSelectionWithText(replacedString, false, false);
2241     RefPtr<Range> changedRange = paragraph.subrange(paragraph.checkingStart(), replacedString.length());
2242     changedRange->startContainer()->document()->markers()->addMarker(changedRange.get(), DocumentMarker::Replacement, String());
2243     m_alternativeTextController->markReversed(changedRange.get());
2244 }
2245
2246
2247 void Editor::markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection)
2248 {
2249     if (unifiedTextCheckerEnabled()) {
2250         if (!isContinuousSpellCheckingEnabled())
2251             return;
2252
2253         // markMisspellingsAndBadGrammar() is triggered by selection change, in which case we check spelling and grammar, but don't autocorrect misspellings.
2254         TextCheckingTypeMask textCheckingOptions = TextCheckingTypeSpelling;
2255         if (markGrammar && isGrammarCheckingEnabled())
2256             textCheckingOptions |= TextCheckingTypeGrammar;
2257         markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellingSelection.toNormalizedRange().get(), grammarSelection.toNormalizedRange().get());
2258         return;
2259     }
2260
2261     RefPtr<Range> firstMisspellingRange;
2262     markMisspellings(spellingSelection, firstMisspellingRange);
2263     if (markGrammar)
2264         markBadGrammar(grammarSelection);
2265 }
2266
2267 void Editor::unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction)
2268 {
2269     m_alternativeTextController->respondToUnappliedSpellCorrection(selectionOfCorrected, corrected, correction);
2270 }
2271
2272 void Editor::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionAtWordBoundary)
2273 {
2274     if (!m_alternativeTextController->shouldRemoveMarkersUponEditing() && (!textChecker() || textChecker()->shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)))
2275         return;
2276
2277     // We want to remove the markers from a word if an editing command will change the word. This can happen in one of
2278     // several scenarios:
2279     // 1. Insert in the middle of a word.
2280     // 2. Appending non whitespace at the beginning of word.
2281     // 3. Appending non whitespace at the end of word.
2282     // Note that, appending only whitespaces at the beginning or end of word won't change the word, so we don't need to
2283     // remove the markers on that word.
2284     // Of course, if current selection is a range, we potentially will edit two words that fall on the boundaries of
2285     // selection, and remove words between the selection boundaries.
2286     //
2287     VisiblePosition startOfSelection = frame()->selection()->selection().start();
2288     VisiblePosition endOfSelection = frame()->selection()->selection().end();
2289     if (startOfSelection.isNull())
2290         return;
2291     // First word is the word that ends after or on the start of selection.
2292     VisiblePosition startOfFirstWord = startOfWord(startOfSelection, LeftWordIfOnBoundary);
2293     VisiblePosition endOfFirstWord = endOfWord(startOfSelection, LeftWordIfOnBoundary);
2294     // Last word is the word that begins before or on the end of selection
2295     VisiblePosition startOfLastWord = startOfWord(endOfSelection, RightWordIfOnBoundary);
2296     VisiblePosition endOfLastWord = endOfWord(endOfSelection, RightWordIfOnBoundary);
2297
2298     if (startOfFirstWord.isNull()) {
2299         startOfFirstWord = startOfWord(startOfSelection, RightWordIfOnBoundary);
2300         endOfFirstWord = endOfWord(startOfSelection, RightWordIfOnBoundary);
2301     }
2302     
2303     if (endOfLastWord.isNull()) {
2304         startOfLastWord = startOfWord(endOfSelection, LeftWordIfOnBoundary);
2305         endOfLastWord = endOfWord(endOfSelection, LeftWordIfOnBoundary);
2306     }
2307
2308     // If doNotRemoveIfSelectionAtWordBoundary is true, and first word ends at the start of selection,
2309     // we choose next word as the first word.
2310     if (doNotRemoveIfSelectionAtWordBoundary && endOfFirstWord == startOfSelection) {
2311         startOfFirstWord = nextWordPosition(startOfFirstWord);
2312         endOfFirstWord = endOfWord(startOfFirstWord, RightWordIfOnBoundary);
2313         if (startOfFirstWord == endOfSelection)
2314             return;
2315     }
2316
2317     // If doNotRemoveIfSelectionAtWordBoundary is true, and last word begins at the end of selection,
2318     // we choose previous word as the last word.
2319     if (doNotRemoveIfSelectionAtWordBoundary && startOfLastWord == endOfSelection) {
2320         startOfLastWord = previousWordPosition(startOfLastWord);
2321         endOfLastWord = endOfWord(startOfLastWord, RightWordIfOnBoundary);
2322         if (endOfLastWord == startOfSelection)
2323             return;
2324     }
2325
2326     if (startOfFirstWord.isNull() || endOfFirstWord.isNull() || startOfLastWord.isNull() || endOfLastWord.isNull())
2327         return;
2328
2329     // Now we remove markers on everything between startOfFirstWord and endOfLastWord.
2330     // However, if an autocorrection change a single word to multiple words, we want to remove correction mark from all the
2331     // resulted words even we only edit one of them. For example, assuming autocorrection changes "avantgarde" to "avant
2332     // garde", we will have CorrectionIndicator marker on both words and on the whitespace between them. If we then edit garde,
2333     // we would like to remove the marker from word "avant" and whitespace as well. So we need to get the continous range of
2334     // of marker that contains the word in question, and remove marker on that whole range.
2335     Document* document = m_frame->document();
2336     RefPtr<Range> wordRange = Range::create(document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());
2337
2338     Vector<DocumentMarker*> markers = document->markers()->markersInRange(wordRange.get(), DocumentMarker::DictationAlternatives);
2339     for (size_t i = 0; i < markers.size(); ++i)
2340         m_alternativeTextController->removeDictationAlternativesForMarker(markers[i]);
2341
2342     document->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling | DocumentMarker::Grammar | DocumentMarker::CorrectionIndicator | DocumentMarker::SpellCheckingExemption | DocumentMarker::DictationAlternatives, DocumentMarkerController::RemovePartiallyOverlappingMarker);
2343     document->markers()->clearDescriptionOnMarkersIntersectingRange(wordRange.get(), DocumentMarker::Replacement);
2344 }
2345
2346 void Editor::deletedAutocorrectionAtPosition(const Position& position, const String& originalString)
2347 {
2348     m_alternativeTextController->deletedAutocorrectionAtPosition(position, originalString);
2349 }
2350
2351 PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
2352 {
2353     Document* document = m_frame->documentAtPoint(windowPoint);
2354     if (!document)
2355         return 0;
2356     
2357     Frame* frame = document->frame();
2358     ASSERT(frame);
2359     FrameView* frameView = frame->view();
2360     if (!frameView)
2361         return 0;
2362     IntPoint framePoint = frameView->windowToContents(windowPoint);
2363     VisibleSelection selection(frame->visiblePositionForPoint(framePoint));
2364     return avoidIntersectionWithNode(selection.toNormalizedRange().get(), m_deleteButtonController->containerElement());
2365 }
2366
2367 void Editor::revealSelectionAfterEditingOperation(const ScrollAlignment& alignment, RevealExtentOption revealExtentOption)
2368 {
2369     if (m_ignoreCompositionSelectionChange)
2370         return;
2371
2372     m_frame->selection()->revealSelection(alignment, revealExtentOption);
2373 }
2374
2375 void Editor::setIgnoreCompositionSelectionChange(bool ignore)
2376 {
2377     if (m_ignoreCompositionSelectionChange == ignore)
2378         return;
2379
2380     m_ignoreCompositionSelectionChange = ignore;
2381     if (!ignore)
2382         revealSelectionAfterEditingOperation(ScrollAlignment::alignToEdgeIfNeeded, RevealExtent);
2383 }
2384
2385 PassRefPtr<Range> Editor::compositionRange() const
2386 {
2387     if (!m_compositionNode)
2388         return 0;
2389     unsigned length = m_compositionNode->length();
2390     unsigned start = min(m_compositionStart, length);
2391     unsigned end = min(max(start, m_compositionEnd), length);
2392     if (start >= end)
2393         return 0;
2394     return Range::create(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);
2395 }
2396
2397 bool Editor::getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const
2398 {
2399     if (!m_compositionNode)
2400         return false;
2401     Position start = m_frame->selection()->start();
2402     if (start.deprecatedNode() != m_compositionNode)
2403         return false;
2404     Position end = m_frame->selection()->end();
2405     if (end.deprecatedNode() != m_compositionNode)
2406         return false;
2407
2408     if (static_cast<unsigned>(start.deprecatedEditingOffset()) < m_compositionStart)
2409         return false;
2410     if (static_cast<unsigned>(end.deprecatedEditingOffset()) > m_compositionEnd)
2411         return false;
2412
2413     selectionStart = start.deprecatedEditingOffset() - m_compositionStart;
2414     selectionEnd = start.deprecatedEditingOffset() - m_compositionEnd;
2415     return true;
2416 }
2417
2418 bool Editor::setSelectionOffsets(int selectionStart, int selectionEnd)
2419 {
2420     Element* rootEditableElement = m_frame->selection()->rootEditableElement();
2421     if (!rootEditableElement)
2422         return false;
2423
2424     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(rootEditableElement, selectionStart, selectionEnd - selectionStart);
2425     if (!range)
2426         return false;
2427
2428     return m_frame->selection()->setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, false);
2429 }
2430
2431 void Editor::transpose()
2432 {
2433     if (!canEdit())
2434         return;
2435
2436      VisibleSelection selection = m_frame->selection()->selection();
2437      if (!selection.isCaret())
2438          return;
2439
2440     // Make a selection that goes back one character and forward two characters.
2441     VisiblePosition caret = selection.visibleStart();
2442     VisiblePosition next = isEndOfParagraph(caret) ? caret : caret.next();
2443     VisiblePosition previous = next.previous();
2444     if (next == previous)
2445         return;
2446     previous = previous.previous();
2447     if (!inSameParagraph(next, previous))
2448         return;
2449     RefPtr<Range> range = makeRange(previous, next);
2450     if (!range)
2451         return;
2452     VisibleSelection newSelection(range.get(), DOWNSTREAM);
2453
2454     // Transpose the two characters.
2455     String text = plainText(range.get());
2456     if (text.length() != 2)
2457         return;
2458     String transposed = text.right(1) + text.left(1);
2459
2460     // Select the two characters.
2461     if (newSelection != m_frame->selection()->selection()) {
2462         if (!m_frame->selection()->shouldChangeSelection(newSelection))
2463             return;
2464         m_frame->selection()->setSelection(newSelection);
2465     }
2466
2467     // Insert the transposed characters.
2468     if (!shouldInsertText(transposed, range.get(), EditorInsertActionTyped))
2469         return;
2470     replaceSelectionWithText(transposed, false, false);
2471 }
2472
2473 void Editor::addToKillRing(Range* range, bool prepend)
2474 {
2475     if (m_shouldStartNewKillRingSequence)
2476         killRing()->startNewSequence();
2477
2478     String text = plainText(range);
2479     if (prepend)
2480         killRing()->prepend(text);
2481     else
2482         killRing()->append(text);
2483     m_shouldStartNewKillRingSequence = false;
2484 }
2485
2486 void Editor::startAlternativeTextUITimer()
2487 {
2488     m_alternativeTextController->startAlternativeTextUITimer(AlternativeTextTypeCorrection);
2489 }
2490
2491 void Editor::handleAlternativeTextUIResult(const String& correction)
2492 {
2493     m_alternativeTextController->handleAlternativeTextUIResult(correction);
2494 }
2495
2496
2497 void Editor::dismissCorrectionPanelAsIgnored()
2498 {
2499     m_alternativeTextController->dismiss(ReasonForDismissingAlternativeTextIgnored);
2500 }
2501
2502 void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection,  FrameSelection::SetSelectionOptions options)
2503 {
2504     // If the new selection is orphaned, then don't update the selection.
2505     if (newSelection.start().isOrphan() || newSelection.end().isOrphan())
2506         return;
2507
2508     // If there is no selection change, don't bother sending shouldChangeSelection, but still call setSelection,
2509     // because there is work that it must do in this situation.
2510     // The old selection can be invalid here and calling shouldChangeSelection can produce some strange calls.
2511     // See <rdar://problem/5729315> Some shouldChangeSelectedDOMRange contain Ranges for selections that are no longer valid
2512     bool selectionDidNotChangeDOMPosition = newSelection == m_frame->selection()->selection();
2513     if (selectionDidNotChangeDOMPosition || m_frame->selection()->shouldChangeSelection(newSelection))
2514         m_frame->selection()->setSelection(newSelection, options);
2515
2516     // Some editing operations change the selection visually without affecting its position within the DOM.
2517     // For example when you press return in the following (the caret is marked by ^):
2518     // <div contentEditable="true"><div>^Hello</div></div>
2519     // WebCore inserts <div><br></div> *before* the current block, which correctly moves the paragraph down but which doesn't
2520     // change the caret's DOM position (["hello", 0]). In these situations the above FrameSelection::setSelection call
2521     // does not call EditorClient::respondToChangedSelection(), which, on the Mac, sends selection change notifications and
2522     // starts a new kill ring sequence, but we want to do these things (matches AppKit).
2523     if (selectionDidNotChangeDOMPosition && client())
2524         client()->respondToChangedSelection(m_frame);
2525 }
2526
2527 String Editor::selectedText() const
2528 {
2529     // We remove '\0' characters because they are not visibly rendered to the user.
2530     return plainText(m_frame->selection()->toNormalizedRange().get()).replace(0, "");
2531 }
2532
2533 IntRect Editor::firstRectForRange(Range* range) const
2534 {
2535     LayoutUnit extraWidthToEndOfLine = 0;
2536     ASSERT(range->startContainer());
2537     ASSERT(range->endContainer());
2538
2539     IntRect startCaretRect = RenderedPosition(VisiblePosition(range->startPosition()).deepEquivalent(), DOWNSTREAM).absoluteRect(&extraWidthToEndOfLine);
2540     if (startCaretRect == LayoutRect())
2541         return IntRect();
2542
2543     IntRect endCaretRect = RenderedPosition(VisiblePosition(range->endPosition()).deepEquivalent(), UPSTREAM).absoluteRect();
2544     if (endCaretRect == LayoutRect())
2545         return IntRect();
2546
2547     if (startCaretRect.y() == endCaretRect.y()) {
2548         // start and end are on the same line
2549         return IntRect(min(startCaretRect.x(), endCaretRect.x()),
2550             startCaretRect.y(),
2551             abs(endCaretRect.x() - startCaretRect.x()),
2552             max(startCaretRect.height(), endCaretRect.height()));
2553     }
2554
2555     // start and end aren't on the same line, so go from start to the end of its line
2556     return IntRect(startCaretRect.x(),
2557         startCaretRect.y(),
2558         startCaretRect.width() + extraWidthToEndOfLine,
2559         startCaretRect.height());
2560 }
2561
2562 bool Editor::shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity affinity, bool stillSelecting) const
2563 {
2564     return client() && client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange().get(), newSelection.toNormalizedRange().get(), affinity, stillSelecting);
2565 }
2566
2567 void Editor::computeAndSetTypingStyle(StylePropertySet* style, EditAction editingAction)
2568 {
2569     if (!style || style->isEmpty()) {
2570         m_frame->selection()->clearTypingStyle();
2571         return;
2572     }
2573
2574     // Calculate the current typing style.
2575     RefPtr<EditingStyle> typingStyle;
2576     if (m_frame->selection()->typingStyle()) {
2577         typingStyle = m_frame->selection()->typingStyle()->copy();
2578         typingStyle->overrideWithStyle(style);
2579     } else
2580         typingStyle = EditingStyle::create(style);
2581
2582     typingStyle->prepareToApplyAt(m_frame->selection()->selection().visibleStart().deepEquivalent(), EditingStyle::PreserveWritingDirection);
2583
2584     // Handle block styles, substracting these from the typing style.
2585     RefPtr<EditingStyle> blockStyle = typingStyle->extractAndRemoveBlockProperties();
2586     if (!blockStyle->isEmpty())
2587         applyCommand(ApplyStyleCommand::create(m_frame->document(), blockStyle.get(), editingAction));
2588
2589     // Set the remaining style as the typing style.
2590     m_frame->selection()->setTypingStyle(typingStyle);
2591 }
2592
2593 void Editor::textFieldDidBeginEditing(Element* e)
2594 {
2595     if (client())
2596         client()->textFieldDidBeginEditing(e);
2597 }
2598
2599 void Editor::textFieldDidEndEditing(Element* e)
2600 {
2601     dismissCorrectionPanelAsIgnored();
2602     if (client())
2603         client()->textFieldDidEndEditing(e);
2604 }
2605
2606 void Editor::textDidChangeInTextField(Element* e)
2607 {
2608     if (client())
2609         client()->textDidChangeInTextField(e);
2610 }
2611
2612 bool Editor::doTextFieldCommandFromEvent(Element* e, KeyboardEvent* ke)
2613 {
2614     if (client())
2615         return client()->doTextFieldCommandFromEvent(e, ke);
2616
2617     return false;
2618 }
2619
2620 void Editor::textWillBeDeletedInTextField(Element* input)
2621 {
2622     if (client())
2623         client()->textWillBeDeletedInTextField(input);
2624 }
2625
2626 void Editor::textDidChangeInTextArea(Element* e)
2627 {
2628     if (client())
2629         client()->textDidChangeInTextArea(e);
2630 }
2631
2632 void Editor::applyEditingStyleToBodyElement() const
2633 {
2634     RefPtr<NodeList> list = m_frame->document()->getElementsByTagName("body");
2635     unsigned len = list->length();
2636     for (unsigned i = 0; i < len; i++)
2637         applyEditingStyleToElement(static_cast<Element*>(list->item(i)));
2638 }
2639
2640 void Editor::applyEditingStyleToElement(Element* element) const
2641 {
2642     if (!element)
2643         return;
2644     ASSERT(element->isStyledElement());
2645     if (!element->isStyledElement())
2646         return;
2647
2648     // Mutate using the CSSOM wrapper so we get the same event behavior as a script.
2649     CSSStyleDeclaration* style = static_cast<StyledElement*>(element)->style();
2650     ExceptionCode ec;
2651     style->setPropertyInternal(CSSPropertyWordWrap, "break-word", false, ec);
2652     style->setPropertyInternal(CSSPropertyWebkitNbspMode, "space", false, ec);
2653     style->setPropertyInternal(CSSPropertyWebkitLineBreak, "after-white-space", false, ec);
2654 }
2655
2656 // Searches from the beginning of the document if nothing is selected.
2657 bool Editor::findString(const String& target, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection)
2658 {
2659     FindOptions options = (forward ? 0 : Backwards) | (caseFlag ? 0 : CaseInsensitive) | (wrapFlag ? WrapAround : 0) | (startInSelection ? StartInSelection : 0);
2660     return findString(target, options);
2661 }
2662
2663 bool Editor::findString(const String& target, FindOptions options)
2664 {
2665     VisibleSelection selection = m_frame->selection()->selection();
2666
2667     RefPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options);
2668
2669     if (!resultRange)
2670         return false;
2671
2672     m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM));
2673     m_frame->selection()->revealSelection();
2674     return true;
2675 }
2676
2677 PassRefPtr<Range> Editor::findStringAndScrollToVisible(const String& target, Range* previousMatch, FindOptions options)
2678 {
2679     RefPtr<Range> nextMatch = rangeOfString(target, previousMatch, options);
2680     if (!nextMatch)
2681         return 0;
2682
2683     nextMatch->firstNode()->renderer()->scrollRectToVisible(nextMatch->boundingBox(),
2684         ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
2685
2686     return nextMatch.release();
2687 }
2688
2689 PassRefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
2690 {
2691     if (target.isEmpty())
2692         return 0;
2693
2694     // Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge
2695     // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
2696     RefPtr<Range> searchRange(rangeOfContents(m_frame->document()));
2697
2698     bool forward = !(options & Backwards);
2699     bool startInReferenceRange = referenceRange && (options & StartInSelection);
2700     if (referenceRange) {
2701         if (forward)
2702             searchRange->setStart(startInReferenceRange ? referenceRange->startPosition() : referenceRange->endPosition());
2703         else
2704             searchRange->setEnd(startInReferenceRange ? referenceRange->endPosition() : referenceRange->startPosition());
2705     }
2706
2707     RefPtr<Node> shadowTreeRoot = referenceRange && referenceRange->startContainer() ? referenceRange->startContainer()->nonBoundaryShadowTreeRootNode() : 0;
2708     if (shadowTreeRoot) {
2709         if (forward)
2710             searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
2711         else
2712             searchRange->setStart(shadowTreeRoot.get(), 0);
2713     }
2714
2715     RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options));
2716     // If we started in the reference range and the found range exactly matches the reference range, find again.
2717     // Build a selection with the found range to remove collapsed whitespace.
2718     // Compare ranges instead of selection objects to ignore the way that the current selection was made.
2719     if (startInReferenceRange && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), referenceRange)) {
2720         searchRange = rangeOfContents(m_frame->document());
2721         if (forward)
2722             searchRange->setStart(referenceRange->endPosition());
2723         else
2724             searchRange->setEnd(referenceRange->startPosition());
2725
2726         if (shadowTreeRoot) {
2727             if (forward)
2728                 searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
2729             else
2730                 searchRange->setStart(shadowTreeRoot.get(), 0);
2731         }
2732
2733         resultRange = findPlainText(searchRange.get(), target, options);
2734     }
2735
2736     // If nothing was found in the shadow tree, search in main content following the shadow tree.
2737     if (resultRange->collapsed() && shadowTreeRoot) {
2738         searchRange = rangeOfContents(m_frame->document());
2739         if (forward)
2740             searchRange->setStartAfter(shadowTreeRoot->shadowHost());
2741         else
2742             searchRange->setEndBefore(shadowTreeRoot->shadowHost());
2743
2744         resultRange = findPlainText(searchRange.get(), target, options);
2745     }
2746
2747     // If we didn't find anything and we're wrapping, search again in the entire document (this will
2748     // redundantly re-search the area already searched in some cases).
2749     if (resultRange->collapsed() && options & WrapAround) {
2750         searchRange = rangeOfContents(m_frame->document());
2751         resultRange = findPlainText(searchRange.get(), target, options);
2752         // We used to return false here if we ended up with the same range that we started with
2753         // (e.g., the reference range was already the only instance of this text). But we decided that
2754         // this should be a success case instead, so we'll just fall through in that case.
2755     }
2756
2757     return resultRange->collapsed() ? 0 : resultRange.release();
2758 }
2759
2760 static bool isFrameInRange(Frame* frame, Range* range)
2761 {
2762     bool inRange = false;
2763     for (HTMLFrameOwnerElement* ownerElement = frame->ownerElement(); ownerElement; ownerElement = ownerElement->document()->ownerElement()) {
2764         if (ownerElement->document() == range->ownerDocument()) {
2765             ExceptionCode ec = 0;
2766             inRange = range->intersectsNode(ownerElement, ec);
2767             break;
2768         }
2769     }
2770     return inRange;
2771 }
2772
2773 unsigned Editor::countMatchesForText(const String& target, Range* range, FindOptions options, unsigned limit, bool markMatches, Vector<RefPtr<Range> >* matches)
2774 {
2775     if (target.isEmpty())
2776         return 0;
2777
2778     RefPtr<Range> searchRange;
2779     if (range) {
2780         if (range->ownerDocument() == m_frame->document())
2781             searchRange = range;
2782         else if (!isFrameInRange(m_frame, range))
2783             return 0;
2784     }
2785     if (!searchRange)
2786         searchRange = rangeOfContents(m_frame->document());
2787
2788     Node* originalEndContainer = searchRange->endContainer();
2789     int originalEndOffset = searchRange->endOffset();
2790
2791     ExceptionCode exception = 0;
2792     unsigned matchCount = 0;
2793     do {
2794         RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options & ~Backwards));
2795         if (resultRange->collapsed(exception)) {
2796             if (!resultRange->startContainer()->isInShadowTree())
2797                 break;
2798
2799             searchRange->setStartAfter(resultRange->startContainer()->shadowHost(), exception);
2800             searchRange->setEnd(originalEndContainer, originalEndOffset, exception);
2801             continue;
2802         }
2803
2804         ++matchCount;
2805         if (matches)
2806             matches->append(resultRange);
2807         
2808         if (markMatches)
2809             m_frame->document()->markers()->addMarker(resultRange.get(), DocumentMarker::TextMatch);
2810
2811         // Stop looking if we hit the specified limit. A limit of 0 means no limit.
2812         if (limit > 0 && matchCount >= limit)
2813             break;
2814
2815         // Set the new start for the search range to be the end of the previous
2816         // result range. There is no need to use a VisiblePosition here,
2817         // since findPlainText will use a TextIterator to go over the visible
2818         // text nodes. 
2819         searchRange->setStart(resultRange->endContainer(exception), resultRange->endOffset(exception), exception);
2820
2821         Node* shadowTreeRoot = searchRange->shadowRoot();
2822         if (searchRange->collapsed(exception) && shadowTreeRoot)
2823             searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
2824     } while (true);
2825
2826     if (markMatches || matches) {
2827         // Do a "fake" paint in order to execute the code that computes the rendered rect for each text match.
2828         if (m_frame->view() && m_frame->contentRenderer()) {
2829             m_frame->document()->updateLayout(); // Ensure layout is up to date.
2830             LayoutRect visibleRect = m_frame->view()->visibleContentRect();
2831             if (!visibleRect.isEmpty()) {
2832                 GraphicsContext context((PlatformGraphicsContext*)0);
2833                 context.setPaintingDisabled(true);
2834
2835                 PaintBehavior oldBehavior = m_frame->view()->paintBehavior();
2836                 m_frame->view()->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
2837                 m_frame->view()->paintContents(&context, enclosingIntRect(visibleRect));
2838                 m_frame->view()->setPaintBehavior(oldBehavior);
2839             }
2840         }
2841     }
2842
2843     return matchCount;
2844 }
2845
2846 void Editor::setMarkedTextMatchesAreHighlighted(bool flag)
2847 {
2848     if (flag == m_areMarkedTextMatchesHighlighted)
2849         return;
2850
2851     m_areMarkedTextMatchesHighlighted = flag;
2852     m_frame->document()->markers()->repaintMarkers(DocumentMarker::TextMatch);
2853 }
2854
2855 void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
2856 {
2857     m_alternativeTextController->stopPendingCorrection(oldSelection);
2858
2859     bool closeTyping = options & FrameSelection::CloseTyping;
2860     bool isContinuousSpellCheckingEnabled = this->isContinuousSpellCheckingEnabled();
2861     bool isContinuousGrammarCheckingEnabled = isContinuousSpellCheckingEnabled && isGrammarCheckingEnabled();
2862     if (isContinuousSpellCheckingEnabled) {
2863         VisibleSelection newAdjacentWords;
2864         VisibleSelection newSelectedSentence;
2865         bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
2866         if (m_frame->selection()->selection().isContentEditable() || caretBrowsing) {
2867             VisiblePosition newStart(m_frame->selection()->selection().visibleStart());
2868             newAdjacentWords = VisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), endOfWord(newStart, RightWordIfOnBoundary));
2869             if (isContinuousGrammarCheckingEnabled)
2870                 newSelectedSentence = VisibleSelection(startOfSentence(newStart), endOfSentence(newStart));
2871         }
2872
2873         // Don't check spelling and grammar if the change of selection is triggered by spelling correction itself.
2874         bool shouldCheckSpellingAndGrammar = !(options & FrameSelection::SpellCorrectionTriggered);
2875
2876         // When typing we check spelling elsewhere, so don't redo it here.
2877         // If this is a change in selection resulting from a delete operation,
2878         // oldSelection may no longer be in the document.
2879         if (shouldCheckSpellingAndGrammar && closeTyping && oldSelection.isContentEditable() && oldSelection.start().deprecatedNode() && oldSelection.start().anchorNode()->inDocument()) {
2880             VisiblePosition oldStart(oldSelection.visibleStart());
2881             VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
2882             if (oldAdjacentWords != newAdjacentWords) {
2883                 if (isContinuousGrammarCheckingEnabled) {
2884                     VisibleSelection oldSelectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
2885                     markMisspellingsAndBadGrammar(oldAdjacentWords, oldSelectedSentence != newSelectedSentence, oldSelectedSentence);
2886                 } else
2887                     markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
2888             }
2889         }
2890
2891         if (!textChecker() || textChecker()->shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) {
2892             if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
2893                 m_frame->document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
2894         }
2895         if (!textChecker() || textChecker()->shouldEraseMarkersAfterChangeSelection(TextCheckingTypeGrammar)) {
2896             if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
2897                 m_frame->document()->markers()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
2898         }
2899     }
2900
2901     // When continuous spell checking is off, existing markers disappear after the selection changes.
2902     if (!isContinuousSpellCheckingEnabled)
2903         m_frame->document()->markers()->removeMarkers(DocumentMarker::Spelling);
2904     if (!isContinuousGrammarCheckingEnabled)
2905         m_frame->document()->markers()->removeMarkers(DocumentMarker::Grammar);
2906
2907     notifyComponentsOnChangedSelection(oldSelection, options);
2908 }
2909
2910 static Node* findFirstMarkable(Node* node)
2911 {
2912     while (node) {
2913         if (!node->renderer())
2914             return 0;
2915         if (node->renderer()->isText())
2916             return node;
2917         if (node->renderer()->isTextControl())
2918             node = toRenderTextControl(node->renderer())->visiblePositionForIndex(1).deepEquivalent().deprecatedNode();
2919         else if (node->firstChild())
2920             node = node->firstChild();
2921         else
2922             node = node->nextSibling();
2923     }
2924
2925     return 0;
2926 }
2927
2928 bool Editor::selectionStartHasMarkerFor(DocumentMarker::MarkerType markerType, int from, int length) const
2929 {
2930     Node* node = findFirstMarkable(m_frame->selection()->start().deprecatedNode());
2931     if (!node)
2932         return false;
2933
2934     unsigned int startOffset = static_cast<unsigned int>(from);
2935     unsigned int endOffset = static_cast<unsigned int>(from + length);
2936     Vector<DocumentMarker*> markers = m_frame->document()->markers()->markersFor(node);
2937     for (size_t i = 0; i < markers.size(); ++i) {
2938         DocumentMarker* marker = markers[i];
2939         if (marker->startOffset() <= startOffset && endOffset <= marker->endOffset() && marker->type() == markerType)
2940             return true;
2941     }
2942
2943     return false;
2944 }       
2945
2946 TextCheckingTypeMask Editor::resolveTextCheckingTypeMask(TextCheckingTypeMask textCheckingOptions)
2947 {
2948     bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
2949     bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
2950     bool shouldShowCorrectionPanel = textCheckingOptions & TextCheckingTypeShowCorrectionPanel;
2951     bool shouldCheckForCorrection = shouldShowCorrectionPanel || (textCheckingOptions & TextCheckingTypeCorrection);
2952
2953     TextCheckingTypeMask checkingTypes = 0;
2954     if (shouldMarkSpelling)
2955         checkingTypes |= TextCheckingTypeSpelling;
2956     if (shouldMarkGrammar)
2957         checkingTypes |= TextCheckingTypeGrammar;
2958     if (shouldCheckForCorrection)
2959         checkingTypes |= TextCheckingTypeCorrection;
2960     if (shouldShowCorrectionPanel)
2961         checkingTypes |= TextCheckingTypeShowCorrectionPanel;
2962
2963 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
2964     bool shouldPerformReplacement = textCheckingOptions & TextCheckingTypeReplacement;
2965     if (shouldPerformReplacement) {
2966         if (isAutomaticLinkDetectionEnabled())
2967             checkingTypes |= TextCheckingTypeLink;
2968         if (isAutomaticQuoteSubstitutionEnabled())
2969             checkingTypes |= TextCheckingTypeQuote;
2970         if (isAutomaticDashSubstitutionEnabled())
2971             checkingTypes |= TextCheckingTypeDash;
2972         if (isAutomaticTextReplacementEnabled())
2973             checkingTypes |= TextCheckingTypeReplacement;
2974         if (shouldMarkSpelling && isAutomaticSpellingCorrectionEnabled())
2975             checkingTypes |= TextCheckingTypeCorrection;
2976     }
2977 #endif
2978
2979     return checkingTypes;
2980 }
2981
2982 void Editor::deviceScaleFactorChanged()
2983 {
2984     m_deleteButtonController->deviceScaleFactorChanged();
2985 }
2986
2987 bool Editor::unifiedTextCheckerEnabled() const
2988 {
2989     return WebCore::unifiedTextCheckerEnabled(m_frame);
2990 }
2991
2992 void Editor::willDetachPage()
2993 {
2994     if (EditorClient* editorClient = client())
2995         editorClient->frameWillDetachPage(frame());
2996 }
2997
2998 Vector<String> Editor::dictationAlternativesForMarker(const DocumentMarker* marker)
2999 {
3000     return m_alternativeTextController->dictationAlternativesForMarker(marker);
3001 }
3002
3003 void Editor::applyDictationAlternativelternative(const String& alternativeString)
3004 {
3005     m_alternativeTextController->applyDictationAlternative(alternativeString);
3006 }
3007
3008 } // namespace WebCore