2008-08-08 Beth Dakin <bdakin@apple.com>
[WebKit-https.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 "EditorDeleteAction.h"
33 #include "EditorInsertAction.h"
34 #include "SelectionController.h"
35
36 namespace WebCore {
37
38 class CSSStyleDeclaration;
39 class Clipboard;
40 class DeleteButtonController;
41 class EditCommand;
42 class EditorClient;
43 class EditorInternalCommand;
44 class HTMLElement;
45 class HitTestResult;
46 class Pasteboard;
47 class SimpleFontData;
48 class Text;
49
50 struct CompositionUnderline {
51     CompositionUnderline() 
52         : startOffset(0), endOffset(0), thick(false) { }
53     CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t) 
54         : startOffset(s), endOffset(e), color(c), thick(t) { }
55     unsigned startOffset;
56     unsigned endOffset;
57     Color color;
58     bool thick;
59 };
60
61 enum TriState { FalseTriState, TrueTriState, MixedTriState };
62 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
63 enum WritingDirection { NaturalWritingDirection, LeftToRightWritingDirection, RightToLeftWritingDirection };
64
65 class Editor {
66 public:
67     Editor(Frame*);
68     ~Editor();
69
70     EditorClient* client() const;
71     Frame* frame() const { return m_frame; }
72     DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); }
73     EditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
74
75     void handleKeyboardEvent(KeyboardEvent*);
76     void handleInputMethodKeydown(KeyboardEvent*);
77
78     bool canEdit() const;
79     bool canEditRichly() const;
80
81     bool canDHTMLCut();
82     bool canDHTMLCopy();
83     bool canDHTMLPaste();
84     bool tryDHTMLCopy();
85     bool tryDHTMLCut();
86     bool tryDHTMLPaste();
87
88     bool canCut() const;
89     bool canCopy() const;
90     bool canPaste() const;
91     bool canDelete() const;
92     bool canSmartCopyOrDelete();
93
94     void cut();
95     void copy();
96     void paste();
97     void pasteAsPlainText();
98     void performDelete();
99
100     void copyURL(const KURL&, const String&);
101     void copyImage(const HitTestResult&);
102
103     void indent();
104     void outdent();
105     void transpose();
106
107     bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction);
108     bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
109     bool shouldShowDeleteInterface(HTMLElement*) const;
110     bool shouldDeleteRange(Range*) const;
111     bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
112     
113     void respondToChangedSelection(const Selection& oldSelection);
114     void respondToChangedContents(const Selection& endingSelection);
115
116     TriState selectionHasStyle(CSSStyleDeclaration*) const;
117     const SimpleFontData* fontForSelection(bool&) const;
118     
119     TriState selectionUnorderedListState() const;
120     TriState selectionOrderedListState() const;
121     PassRefPtr<Node> insertOrderedList();
122     PassRefPtr<Node> insertUnorderedList();
123     bool canIncreaseSelectionListLevel();
124     bool canDecreaseSelectionListLevel();
125     PassRefPtr<Node> increaseSelectionListLevel();
126     PassRefPtr<Node> increaseSelectionListLevelOrdered();
127     PassRefPtr<Node> increaseSelectionListLevelUnordered();
128     void decreaseSelectionListLevel();
129    
130     void removeFormattingAndStyle();
131
132     void clearLastEditCommand();
133
134     bool deleteWithDirection(SelectionController::EDirection, TextGranularity, bool killRing, bool isTypingAction);
135     void deleteSelectionWithSmartDelete(bool smartDelete);
136     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
137     
138     Node* removedAnchor() const { return m_removedAnchor.get(); }
139     void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
140
141     void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
142     void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
143     void applyStyleToSelection(CSSStyleDeclaration*, EditAction);
144     void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction);
145
146     void appliedEditing(PassRefPtr<EditCommand>);
147     void unappliedEditing(PassRefPtr<EditCommand>);
148     void reappliedEditing(PassRefPtr<EditCommand>);
149     
150     bool selectionStartHasStyle(CSSStyleDeclaration*) const;
151
152     bool clientIsEditable() const;
153
154     class Command {
155     public:
156         Command();
157         Command(PassRefPtr<Frame>, const EditorInternalCommand*, EditorCommandSource);
158
159         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
160         bool execute(Event* triggeringEvent) const;
161
162         bool isSupported() const;
163         bool isEnabled(Event* triggeringEvent = 0) const;
164
165         TriState state(Event* triggeringEvent = 0) const;
166         String value(Event* triggeringEvent = 0) const;
167
168         bool isTextInsertion() const;
169
170     private:
171         RefPtr<Frame> m_frame;
172         const EditorInternalCommand* m_command;
173         EditorCommandSource m_source;
174     };
175     Command command(const String& commandName); // Default is CommandFromMenuOrKeyBinding.
176     Command command(const String& commandName, EditorCommandSource);
177
178     bool insertText(const String&, Event* triggeringEvent);
179     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, Event* triggeringEvent);
180     bool insertLineBreak();
181     bool insertParagraphSeparator();
182     
183     bool isContinuousSpellCheckingEnabled();
184     void toggleContinuousSpellChecking();
185     bool isGrammarCheckingEnabled();
186     void toggleGrammarChecking();
187     void ignoreSpelling();
188     void learnSpelling();
189     int spellCheckerDocumentTag();
190     bool isSelectionUngrammatical();
191     bool isSelectionMisspelled();
192     Vector<String> guessesForMisspelledSelection();
193     Vector<String> guessesForUngrammaticalSelection();
194     void markMisspellingsAfterTypingToPosition(const VisiblePosition&);
195     void markMisspellings(const Selection&);
196     void markBadGrammar(const Selection&);
197     void advanceToNextMisspelling(bool startBeforeSelection = false);
198     void showSpellingGuessPanel();
199     bool spellingPanelIsShowing();
200
201     bool shouldBeginEditing(Range*);
202     bool shouldEndEditing(Range*);
203
204     void clearUndoRedoOperations();
205     bool canUndo();
206     void undo();
207     bool canRedo();
208     void redo();
209
210     void didBeginEditing();
211     void didEndEditing();
212     void didWriteSelectionToPasteboard();
213     
214     void showFontPanel();
215     void showStylesPanel();
216     void showColorPanel();
217     void toggleBold();
218     void toggleUnderline();
219     void setBaseWritingDirection(WritingDirection);
220
221     bool smartInsertDeleteEnabled();
222     
223     // international text input composition
224     bool hasComposition() const { return m_compositionNode; }
225     void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
226     void confirmComposition();
227     void confirmComposition(const String&); // if no existing composition, replaces selection
228     void confirmCompositionWithoutDisturbingSelection();
229     PassRefPtr<Range> compositionRange() const;
230     bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
231
232     // getting international text input composition state (for use by InlineTextBox)
233     Text* compositionNode() const { return m_compositionNode.get(); }
234     unsigned compositionStart() const { return m_compositionStart; }
235     unsigned compositionEnd() const { return m_compositionEnd; }
236     bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
237     const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
238
239     bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
240
241     void setStartNewKillRingSequence(bool);
242
243     PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
244
245     void clear();
246
247     Selection selectionForCommand(Event*);
248
249     void appendToKillRing(const String&);
250     void prependToKillRing(const String&);
251     String yankFromKillRing();
252     void startNewKillRingSequence();
253     void setKillRingToYankedState();
254
255     PassRefPtr<Range> selectedRange();
256     
257     // We should make these functions private when their callers in Frame are moved over here to Editor
258     enum Visibility { BeforeVisibleArea, InsideVisibleArea, AfterVisibleArea };
259     Visibility rangeVisibility(Range*) const;
260     PassRefPtr<Range> firstVisibleRange(Range*, const String&, bool forward, bool caseFlag);
261     PassRefPtr<Range> lastVisibleRange(Range*, const String&, bool forward, bool caseFlag);
262
263 private:
264     Frame* m_frame;
265     OwnPtr<DeleteButtonController> m_deleteButtonController;
266     RefPtr<EditCommand> m_lastEditCommand;
267     RefPtr<Node> m_removedAnchor;
268
269     RefPtr<Text> m_compositionNode;
270     unsigned m_compositionStart;
271     unsigned m_compositionEnd;
272     Vector<CompositionUnderline> m_customCompositionUnderlines;
273     bool m_ignoreCompositionSelectionChange;
274     bool m_shouldStartNewKillRingSequence;
275
276     bool canDeleteRange(Range*) const;
277     bool canSmartReplaceWithPasteboard(Pasteboard*);
278     PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy);
279     void pasteAsPlainTextWithPasteboard(Pasteboard*);
280     void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
281     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
282     void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
283     void writeSelectionToPasteboard(Pasteboard*);
284     void revealSelectionAfterEditingOperation();
285
286     void selectComposition();
287     void confirmComposition(const String&, bool preserveSelection);
288     void setIgnoreCompositionSelectionChange(bool ignore);
289
290     void addToKillRing(Range*, bool prepend);
291 };
292
293 inline void Editor::setStartNewKillRingSequence(bool flag)
294 {
295     m_shouldStartNewKillRingSequence = flag;
296 }
297
298 } // namespace WebCore
299
300 #endif // Editor_h