initial import
[vuplus_webkit] / Source / 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 "DocumentMarker.h"
32 #include "EditAction.h"
33 #include "EditingBehavior.h"
34 #include "EditingStyle.h"
35 #include "EditorInsertAction.h"
36 #include "FindOptions.h"
37 #include "FrameSelection.h"
38 #include "TextChecking.h"
39 #include "VisibleSelection.h"
40 #include "WritingDirection.h"
41
42 #if PLATFORM(MAC) && !defined(__OBJC__)
43 class NSDictionary;
44 typedef int NSWritingDirection;
45 #endif
46
47 namespace WebCore {
48
49 class CSSStyleDeclaration;
50 class Clipboard;
51 class SpellingCorrectionController;
52 class DeleteButtonController;
53 class EditCommand;
54 class EditorClient;
55 class EditorInternalCommand;
56 class Frame;
57 class HTMLElement;
58 class HitTestResult;
59 class KillRing;
60 class Pasteboard;
61 class SimpleFontData;
62 class SpellChecker;
63 class Text;
64 class TextCheckerClient;
65 class TextEvent;
66
67 struct CompositionUnderline {
68     CompositionUnderline() 
69         : startOffset(0), endOffset(0), thick(false) { }
70     CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t) 
71         : startOffset(s), endOffset(e), color(c), thick(t) { }
72     unsigned startOffset;
73     unsigned endOffset;
74     Color color;
75     bool thick;
76 };
77
78 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
79
80 class Editor {
81 public:
82     Editor(Frame*);
83     ~Editor();
84
85     EditorClient* client() const;
86     TextCheckerClient* textChecker() const;
87
88     Frame* frame() const { return m_frame; }
89     DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); }
90     EditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
91
92     void handleKeyboardEvent(KeyboardEvent*);
93     void handleInputMethodKeydown(KeyboardEvent*);
94     bool handleTextEvent(TextEvent*);
95
96     bool canEdit() const;
97     bool canEditRichly() const;
98
99     bool canDHTMLCut();
100     bool canDHTMLCopy();
101     bool canDHTMLPaste();
102     bool tryDHTMLCopy();
103     bool tryDHTMLCut();
104     bool tryDHTMLPaste();
105
106     bool canCut() const;
107     bool canCopy() const;
108     bool canPaste() const;
109     bool canDelete() const;
110     bool canSmartCopyOrDelete();
111
112     void cut();
113     void copy();
114     void paste();
115     void pasteAsPlainText();
116     void performDelete();
117
118     void copyURL(const KURL&, const String&);
119     void copyImage(const HitTestResult&);
120
121     void indent();
122     void outdent();
123     void transpose();
124
125     bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction);
126     bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
127     bool shouldShowDeleteInterface(HTMLElement*) const;
128     bool shouldDeleteRange(Range*) const;
129     bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
130     
131     void respondToChangedSelection(const VisibleSelection& oldSelection);
132     void respondToChangedContents(const VisibleSelection& endingSelection);
133
134     bool selectionStartHasStyle(int propertyID, const String& value) const;
135     TriState selectionHasStyle(int propertyID, const String& value) const;
136     String selectionStartCSSPropertyValue(int propertyID);
137     const SimpleFontData* fontForSelection(bool&) const;
138     WritingDirection textDirectionForSelection(bool&) const;
139     
140     TriState selectionUnorderedListState() const;
141     TriState selectionOrderedListState() const;
142     PassRefPtr<Node> insertOrderedList();
143     PassRefPtr<Node> insertUnorderedList();
144     bool canIncreaseSelectionListLevel();
145     bool canDecreaseSelectionListLevel();
146     PassRefPtr<Node> increaseSelectionListLevel();
147     PassRefPtr<Node> increaseSelectionListLevelOrdered();
148     PassRefPtr<Node> increaseSelectionListLevelUnordered();
149     void decreaseSelectionListLevel();
150    
151     void removeFormattingAndStyle();
152
153     void clearLastEditCommand();
154
155     bool deleteWithDirection(SelectionDirection, TextGranularity, bool killRing, bool isTypingAction);
156     void deleteSelectionWithSmartDelete(bool smartDelete);
157     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
158     
159     Node* removedAnchor() const { return m_removedAnchor.get(); }
160     void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
161
162     void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
163     void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
164     void applyStyleToSelection(CSSStyleDeclaration*, EditAction);
165     void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction);
166
167     void appliedEditing(PassRefPtr<EditCommand>);
168     void unappliedEditing(PassRefPtr<EditCommand>);
169     void reappliedEditing(PassRefPtr<EditCommand>);
170     void unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction);
171
172     void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
173     bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
174
175     class Command {
176     public:
177         Command();
178         Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
179
180         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
181         bool execute(Event* triggeringEvent) const;
182
183         bool isSupported() const;
184         bool isEnabled(Event* triggeringEvent = 0) const;
185
186         TriState state(Event* triggeringEvent = 0) const;
187         String value(Event* triggeringEvent = 0) const;
188
189         bool isTextInsertion() const;
190
191     private:
192         const EditorInternalCommand* m_command;
193         EditorCommandSource m_source;
194         RefPtr<Frame> m_frame;
195     };
196     Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
197     Command command(const String& commandName, EditorCommandSource);
198     static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
199
200     bool insertText(const String&, Event* triggeringEvent);
201     bool insertTextForConfirmedComposition(const String& text);
202     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
203     bool insertLineBreak();
204     bool insertParagraphSeparator();
205     
206     bool isContinuousSpellCheckingEnabled();
207     void toggleContinuousSpellChecking();
208     bool isGrammarCheckingEnabled();
209     void toggleGrammarChecking();
210     void ignoreSpelling();
211     void learnSpelling();
212     int spellCheckerDocumentTag();
213     bool isSelectionUngrammatical();
214     bool isSelectionMisspelled();
215     Vector<String> guessesForMisspelledSelection();
216     Vector<String> guessesForUngrammaticalSelection();
217     Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical);
218     bool isSpellCheckingEnabledInFocusedNode() const;
219     bool isSpellCheckingEnabledFor(Node*) const;
220     void markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement);
221     void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
222     void markBadGrammar(const VisibleSelection&);
223     void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
224
225 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
226     void uppercaseWord();
227     void lowercaseWord();
228     void capitalizeWord();
229     void showSubstitutionsPanel();
230     bool substitutionsPanelIsShowing();
231     void toggleSmartInsertDelete();
232     bool isAutomaticQuoteSubstitutionEnabled();
233     void toggleAutomaticQuoteSubstitution();
234     bool isAutomaticLinkDetectionEnabled();
235     void toggleAutomaticLinkDetection();
236     bool isAutomaticDashSubstitutionEnabled();
237     void toggleAutomaticDashSubstitution();
238     bool isAutomaticTextReplacementEnabled();
239     void toggleAutomaticTextReplacement();
240     bool isAutomaticSpellingCorrectionEnabled();
241     void toggleAutomaticSpellingCorrection();
242 #endif
243
244     void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* grammarRange);
245     void changeBackToReplacedString(const String& replacedString);
246
247     void advanceToNextMisspelling(bool startBeforeSelection = false);
248     void showSpellingGuessPanel();
249     bool spellingPanelIsShowing();
250
251     bool shouldBeginEditing(Range*);
252     bool shouldEndEditing(Range*);
253
254     void clearUndoRedoOperations();
255     bool canUndo();
256     void undo();
257     bool canRedo();
258     void redo();
259
260     void didBeginEditing();
261     void didEndEditing();
262     void didWriteSelectionToPasteboard();
263     
264     void showFontPanel();
265     void showStylesPanel();
266     void showColorPanel();
267     void toggleBold();
268     void toggleUnderline();
269     void setBaseWritingDirection(WritingDirection);
270
271     // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are 
272     // mutually exclusive, meaning that enabling one will disable the other.
273     bool smartInsertDeleteEnabled();
274     bool isSelectTrailingWhitespaceEnabled();
275     
276     bool hasBidiSelection() const;
277
278     // international text input composition
279     bool hasComposition() const { return m_compositionNode; }
280     void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
281     void confirmComposition();
282     void confirmComposition(const String&); // if no existing composition, replaces selection
283     void cancelComposition();
284     PassRefPtr<Range> compositionRange() const;
285     bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
286
287     // getting international text input composition state (for use by InlineTextBox)
288     Text* compositionNode() const { return m_compositionNode.get(); }
289     unsigned compositionStart() const { return m_compositionStart; }
290     unsigned compositionEnd() const { return m_compositionEnd; }
291     bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
292     const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
293
294     bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
295
296     void setStartNewKillRingSequence(bool);
297
298     PassRefPtr<Range> rangeForPoint(const LayoutPoint& windowPoint);
299
300     void clear();
301
302     VisibleSelection selectionForCommand(Event*);
303
304     KillRing* killRing() const { return m_killRing.get(); }
305     SpellChecker* spellChecker() const { return m_spellChecker.get(); }
306
307     EditingBehavior behavior() const;
308
309     PassRefPtr<Range> selectedRange();
310     
311     // We should make these functions private when their callers in Frame are moved over here to Editor
312     bool insideVisibleArea(const LayoutPoint&) const;
313     bool insideVisibleArea(Range*) const;
314
315     void addToKillRing(Range*, bool prepend);
316
317     void startCorrectionPanelTimer();
318     // If user confirmed a correction in the correction panel, correction has non-zero length, otherwise it means that user has dismissed the panel.
319     void handleCorrectionPanelResult(const String& correction);
320     void dismissCorrectionPanelAsIgnored();
321
322     void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
323     void pasteAsPlainText(const String&, bool smartReplace);
324
325     // This is only called on the mac where paste is implemented primarily at the WebKit level.
326     void pasteAsPlainTextBypassingDHTML();
327  
328     void clearMisspellingsAndBadGrammar(const VisibleSelection&);
329     void markMisspellingsAndBadGrammar(const VisibleSelection&);
330
331     Node* findEventTargetFrom(const VisibleSelection& selection) const;
332
333     String selectedText() const;
334     bool findString(const String&, FindOptions);
335     // FIXME: Switch callers over to the FindOptions version and retire this one.
336     bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
337
338     PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
339
340     const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
341     void setMark(const VisibleSelection&);
342
343     void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
344     void applyEditingStyleToBodyElement() const;
345     void applyEditingStyleToElement(Element*) const;
346
347     IntRect firstRectForRange(Range*) const;
348
349     void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
350     bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
351
352     RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
353
354     unsigned countMatchesForText(const String&, FindOptions, unsigned limit, bool markMatches);
355     unsigned countMatchesForText(const String&, Range*, FindOptions, unsigned limit, bool markMatches);
356     bool markedTextMatchesAreHighlighted() const;
357     void setMarkedTextMatchesAreHighlighted(bool);
358
359     PassRefPtr<EditingStyle> selectionStartStyle() const;
360
361     void textFieldDidBeginEditing(Element*);
362     void textFieldDidEndEditing(Element*);
363     void textDidChangeInTextField(Element*);
364     bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
365     void textWillBeDeletedInTextField(Element* input);
366     void textDidChangeInTextArea(Element*);
367
368 #if PLATFORM(MAC)
369     NSDictionary* fontAttributesForSelectionStart() const;
370     NSWritingDirection baseWritingDirectionForSelectionStart() const;
371     bool canCopyExcludingStandaloneImages();
372     void takeFindStringFromSelection();
373     void writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes);
374     void readSelectionFromPasteboard(const String& pasteboardName);
375 #endif
376
377     bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const;
378     void updateMarkersForWordsAffectedByEditing(bool onlyHandleWordsContainingSelection);
379     void deletedAutocorrectionAtPosition(const Position&, const String& originalString);
380
381 private:
382     Frame* m_frame;
383     OwnPtr<DeleteButtonController> m_deleteButtonController;
384     RefPtr<EditCommand> m_lastEditCommand;
385     RefPtr<Node> m_removedAnchor;
386     RefPtr<Text> m_compositionNode;
387     unsigned m_compositionStart;
388     unsigned m_compositionEnd;
389     Vector<CompositionUnderline> m_customCompositionUnderlines;
390     bool m_ignoreCompositionSelectionChange;
391     bool m_shouldStartNewKillRingSequence;
392     bool m_shouldStyleWithCSS;
393     OwnPtr<KillRing> m_killRing;
394     OwnPtr<SpellChecker> m_spellChecker;
395     OwnPtr<SpellingCorrectionController> m_spellingCorrector;
396     VisibleSelection m_mark;
397     bool m_areMarkedTextMatchesHighlighted;
398
399     bool canDeleteRange(Range*) const;
400     bool canSmartReplaceWithPasteboard(Pasteboard*);
401     PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy, Frame*);
402     void pasteAsPlainTextWithPasteboard(Pasteboard*);
403     void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
404     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
405     void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
406     void writeSelectionToPasteboard(Pasteboard*);
407     void revealSelectionAfterEditingOperation();
408     void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
409     TextCheckingTypeMask resolveTextCheckingTypeMask(TextCheckingTypeMask);
410
411     void selectComposition();
412     enum SetCompositionMode { ConfirmComposition, CancelComposition };
413     void setComposition(const String&, SetCompositionMode);
414     void setIgnoreCompositionSelectionChange(bool ignore);
415
416     PassRefPtr<Range> firstVisibleRange(const String&, FindOptions);
417     PassRefPtr<Range> lastVisibleRange(const String&, FindOptions);
418     PassRefPtr<Range> nextVisibleRange(Range*, const String&, FindOptions);
419
420     void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
421
422     Node* findEventTargetFromSelection() const;
423 };
424
425 inline void Editor::setStartNewKillRingSequence(bool flag)
426 {
427     m_shouldStartNewKillRingSequence = flag;
428 }
429
430 inline const VisibleSelection& Editor::mark() const
431 {
432     return m_mark;
433 }
434
435 inline void Editor::setMark(const VisibleSelection& selection)
436 {
437     m_mark = selection;
438 }
439
440 inline bool Editor::markedTextMatchesAreHighlighted() const
441 {
442     return m_areMarkedTextMatchesHighlighted;
443 }
444
445
446 } // namespace WebCore
447
448 #endif // Editor_h