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