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