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