OSDN Git Service

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