2010-09-08 MORITA Hajime <morrita@google.com>
[WebKit.git] / WebCore / editing / Editor.h
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef Editor_h
27 #define Editor_h
28
29 #include "ClipboardAccessPolicy.h"
30 #include "Color.h"
31 #include "EditAction.h"
32 #include "EditingBehavior.h"
33 #include "EditorDeleteAction.h"
34 #include "EditorInsertAction.h"
35 #include "SelectionController.h"
36
37 namespace WebCore {
38
39 class CSSStyleDeclaration;
40 class Clipboard;
41 class DeleteButtonController;
42 class EditCommand;
43 class EditorClient;
44 class EditorInternalCommand;
45 class Frame;
46 class HTMLElement;
47 class HitTestResult;
48 class KillRing;
49 class Pasteboard;
50 class SimpleFontData;
51 class Text;
52 class TextEvent;
53
54 struct CompositionUnderline {
55     CompositionUnderline() 
56         : startOffset(0), endOffset(0), thick(false) { }
57     CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t) 
58         : startOffset(s), endOffset(e), color(c), thick(t) { }
59     unsigned startOffset;
60     unsigned endOffset;
61     Color color;
62     bool thick;
63 };
64
65 enum TriState { FalseTriState, TrueTriState, MixedTriState };
66 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
67 enum WritingDirection { NaturalWritingDirection, LeftToRightWritingDirection, RightToLeftWritingDirection };
68
69 class Editor {
70 public:
71     Editor(Frame*);
72     ~Editor();
73
74     EditorClient* client() const;
75     Frame* frame() const { return m_frame; }
76     DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); }
77     EditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
78
79     void handleKeyboardEvent(KeyboardEvent*);
80     void handleInputMethodKeydown(KeyboardEvent*);
81     bool handleTextEvent(TextEvent*);
82
83     bool canEdit() const;
84     bool canEditRichly() const;
85
86     bool canDHTMLCut();
87     bool canDHTMLCopy();
88     bool canDHTMLPaste();
89     bool tryDHTMLCopy();
90     bool tryDHTMLCut();
91     bool tryDHTMLPaste();
92
93     bool canCut() const;
94     bool canCopy() const;
95     bool canPaste() const;
96     bool canDelete() const;
97     bool canSmartCopyOrDelete();
98
99     void cut();
100     void copy();
101     void paste();
102     void pasteAsPlainText();
103     void performDelete();
104
105     void copyURL(const KURL&, const String&);
106     void copyImage(const HitTestResult&);
107
108     void indent();
109     void outdent();
110     void transpose();
111
112     bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction);
113     bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
114     bool shouldShowDeleteInterface(HTMLElement*) const;
115     bool shouldDeleteRange(Range*) const;
116     bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
117     
118     void respondToChangedSelection(const VisibleSelection& oldSelection);
119     void respondToChangedContents(const VisibleSelection& endingSelection);
120
121     TriState selectionHasStyle(CSSStyleDeclaration*) const;
122     String selectionStartCSSPropertyValue(int propertyID);
123     const SimpleFontData* fontForSelection(bool&) const;
124     WritingDirection textDirectionForSelection(bool&) const;
125     
126     TriState selectionUnorderedListState() const;
127     TriState selectionOrderedListState() const;
128     PassRefPtr<Node> insertOrderedList();
129     PassRefPtr<Node> insertUnorderedList();
130     bool canIncreaseSelectionListLevel();
131     bool canDecreaseSelectionListLevel();
132     PassRefPtr<Node> increaseSelectionListLevel();
133     PassRefPtr<Node> increaseSelectionListLevelOrdered();
134     PassRefPtr<Node> increaseSelectionListLevelUnordered();
135     void decreaseSelectionListLevel();
136    
137     void removeFormattingAndStyle();
138
139     void clearLastEditCommand();
140
141     bool deleteWithDirection(SelectionController::EDirection, TextGranularity, bool killRing, bool isTypingAction);
142     void deleteSelectionWithSmartDelete(bool smartDelete);
143     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
144     
145     Node* removedAnchor() const { return m_removedAnchor.get(); }
146     void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
147
148     void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
149     void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
150     void applyStyleToSelection(CSSStyleDeclaration*, EditAction);
151     void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction);
152
153     void appliedEditing(PassRefPtr<EditCommand>);
154     void unappliedEditing(PassRefPtr<EditCommand>);
155     void reappliedEditing(PassRefPtr<EditCommand>);
156     
157     bool selectionStartHasStyle(CSSStyleDeclaration*) const;
158
159     bool clientIsEditable() const;
160     
161     void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
162     bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
163
164     class Command {
165     public:
166         Command();
167         Command(PassRefPtr<Frame>, const EditorInternalCommand*, EditorCommandSource);
168
169         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
170         bool execute(Event* triggeringEvent) const;
171
172         bool isSupported() const;
173         bool isEnabled(Event* triggeringEvent = 0) const;
174
175         TriState state(Event* triggeringEvent = 0) const;
176         String value(Event* triggeringEvent = 0) const;
177
178         bool isTextInsertion() const;
179
180     private:
181         RefPtr<Frame> m_frame;
182         const EditorInternalCommand* m_command;
183         EditorCommandSource m_source;
184     };
185     Command command(const String& commandName); // Default is CommandFromMenuOrKeyBinding.
186     Command command(const String& commandName, EditorCommandSource);
187
188     bool insertText(const String&, Event* triggeringEvent);
189     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, Event* triggeringEvent);
190     bool insertLineBreak();
191     bool insertParagraphSeparator();
192     
193     bool isContinuousSpellCheckingEnabled();
194     void toggleContinuousSpellChecking();
195     bool isGrammarCheckingEnabled();
196     void toggleGrammarChecking();
197     void ignoreSpelling();
198     void learnSpelling();
199     int spellCheckerDocumentTag();
200     bool isSelectionUngrammatical();
201     bool isSelectionMisspelled();
202     Vector<String> guessesForMisspelledSelection();
203     Vector<String> guessesForUngrammaticalSelection();
204     Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical);
205     bool spellCheckingEnabledInFocusedNode() const;
206     void markMisspellingsAfterTypingToPosition(const VisiblePosition&);
207     void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
208     void markBadGrammar(const VisibleSelection&);
209     void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
210 #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
211     void uppercaseWord();
212     void lowercaseWord();
213     void capitalizeWord();
214     void showSubstitutionsPanel();
215     bool substitutionsPanelIsShowing();
216     void toggleSmartInsertDelete();
217     bool isAutomaticQuoteSubstitutionEnabled();
218     void toggleAutomaticQuoteSubstitution();
219     bool isAutomaticLinkDetectionEnabled();
220     void toggleAutomaticLinkDetection();
221     bool isAutomaticDashSubstitutionEnabled();
222     void toggleAutomaticDashSubstitution();
223     bool isAutomaticTextReplacementEnabled();
224     void toggleAutomaticTextReplacement();
225     bool isAutomaticSpellingCorrectionEnabled();
226     void toggleAutomaticSpellingCorrection();
227     enum TextCheckingOptionFlags {
228         MarkSpelling = 1 << 0,
229         MarkGrammar = 1 << 1,
230         PerformReplacement = 1 << 2,
231         ShowCorrectionPanel = 1 << 3,
232     };
233     typedef unsigned TextCheckingOptions;
234
235     void markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions, Range* spellingRange, Range* grammarRange);
236     void changeBackToReplacedString(const String& replacedString);
237 #endif
238     void advanceToNextMisspelling(bool startBeforeSelection = false);
239     void showSpellingGuessPanel();
240     bool spellingPanelIsShowing();
241
242     bool shouldBeginEditing(Range*);
243     bool shouldEndEditing(Range*);
244
245     void clearUndoRedoOperations();
246     bool canUndo();
247     void undo();
248     bool canRedo();
249     void redo();
250
251     void didBeginEditing();
252     void didEndEditing();
253     void didWriteSelectionToPasteboard();
254     
255     void showFontPanel();
256     void showStylesPanel();
257     void showColorPanel();
258     void toggleBold();
259     void toggleUnderline();
260     void setBaseWritingDirection(WritingDirection);
261
262     // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are 
263     // mutually exclusive, meaning that enabling one will disable the other.
264     bool smartInsertDeleteEnabled();
265     bool isSelectTrailingWhitespaceEnabled();
266     
267     bool hasBidiSelection() const;
268
269     // international text input composition
270     bool hasComposition() const { return m_compositionNode; }
271     void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
272     void confirmComposition();
273     void confirmComposition(const String&); // if no existing composition, replaces selection
274     void confirmCompositionWithoutDisturbingSelection();
275     PassRefPtr<Range> compositionRange() const;
276     bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
277
278     // getting international text input composition state (for use by InlineTextBox)
279     Text* compositionNode() const { return m_compositionNode.get(); }
280     unsigned compositionStart() const { return m_compositionStart; }
281     unsigned compositionEnd() const { return m_compositionEnd; }
282     bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
283     const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
284
285     bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
286
287     void setStartNewKillRingSequence(bool);
288
289     PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
290
291     void clear();
292
293     VisibleSelection selectionForCommand(Event*);
294
295     KillRing* killRing() const { return m_killRing.get(); }
296
297     EditingBehavior behavior() const;
298
299     PassRefPtr<Range> selectedRange();
300     
301     // We should make these functions private when their callers in Frame are moved over here to Editor
302     bool insideVisibleArea(const IntPoint&) const;
303     bool insideVisibleArea(Range*) const;
304     PassRefPtr<Range> nextVisibleRange(Range*, const String&, bool forward, bool caseFlag, bool wrapFlag);
305
306     void addToKillRing(Range*, bool prepend);
307
308     void handleCancelOperation();
309     void startCorrectionPanelTimer();
310     void handleRejectedCorrection();
311
312     void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
313     void pasteAsPlainText(const String&, bool smartReplace);
314
315     // This is only called on the mac where paste is implemented primarily at the WebKit level.
316     void pasteAsPlainTextBypassingDHTML();
317  
318     void clearMisspellingsAndBadGrammar(const VisibleSelection&);
319     void markMisspellingsAndBadGrammar(const VisibleSelection&);
320
321     Node* findEventTargetFrom(const VisibleSelection& selection) const;
322 private:
323     Frame* m_frame;
324     OwnPtr<DeleteButtonController> m_deleteButtonController;
325     RefPtr<EditCommand> m_lastEditCommand;
326     RefPtr<Node> m_removedAnchor;
327
328     RefPtr<Text> m_compositionNode;
329     unsigned m_compositionStart;
330     unsigned m_compositionEnd;
331     Vector<CompositionUnderline> m_customCompositionUnderlines;
332     bool m_ignoreCompositionSelectionChange;
333     bool m_shouldStartNewKillRingSequence;
334     bool m_shouldStyleWithCSS;
335     OwnPtr<KillRing> m_killRing;
336     RefPtr<Range> m_rangeToBeReplacedByCorrection;
337     String m_stringToBeReplacedByCorrection;
338     Timer<Editor> m_correctionPanelTimer;
339
340     bool canDeleteRange(Range*) const;
341     bool canSmartReplaceWithPasteboard(Pasteboard*);
342     PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy, Frame*);
343     void pasteAsPlainTextWithPasteboard(Pasteboard*);
344     void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
345     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
346     void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
347     void writeSelectionToPasteboard(Pasteboard*);
348     void revealSelectionAfterEditingOperation();
349
350     void selectComposition();
351     void confirmComposition(const String&, bool preserveSelection);
352     void setIgnoreCompositionSelectionChange(bool ignore);
353
354     PassRefPtr<Range> firstVisibleRange(const String&, bool caseFlag);
355     PassRefPtr<Range> lastVisibleRange(const String&, bool caseFlag);
356
357     void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
358     void correctionPanelTimerFired(Timer<Editor>*);
359     Node* findEventTargetFromSelection() const;
360 };
361
362 inline void Editor::setStartNewKillRingSequence(bool flag)
363 {
364     m_shouldStartNewKillRingSequence = flag;
365 }
366
367 } // namespace WebCore
368
369 #endif // Editor_h