10d70986dc52d5f8cd396e82634d09a44c765f7c
[WebKit-https.git] / 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     WritingDirection textDirectionForSelection(bool&) const;
138     
139     TriState selectionUnorderedListState() const;
140     TriState selectionOrderedListState() const;
141     PassRefPtr<Node> insertOrderedList();
142     PassRefPtr<Node> insertUnorderedList();
143     bool canIncreaseSelectionListLevel();
144     bool canDecreaseSelectionListLevel();
145     PassRefPtr<Node> increaseSelectionListLevel();
146     PassRefPtr<Node> increaseSelectionListLevelOrdered();
147     PassRefPtr<Node> increaseSelectionListLevelUnordered();
148     void decreaseSelectionListLevel();
149    
150     void removeFormattingAndStyle();
151
152     void clearLastEditCommand();
153
154     bool deleteWithDirection(SelectionDirection, TextGranularity, bool killRing, bool isTypingAction);
155     void deleteSelectionWithSmartDelete(bool smartDelete);
156     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
157     
158     Node* removedAnchor() const { return m_removedAnchor.get(); }
159     void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
160
161     void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
162     void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
163     void applyStyleToSelection(CSSStyleDeclaration*, EditAction);
164     void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction);
165
166     void appliedEditing(PassRefPtr<EditCommand>);
167     void unappliedEditing(PassRefPtr<EditCommand>);
168     void reappliedEditing(PassRefPtr<EditCommand>);
169     void unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction);
170
171     void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
172     bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
173
174     class Command {
175     public:
176         Command();
177         Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
178
179         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
180         bool execute(Event* triggeringEvent) const;
181
182         bool isSupported() const;
183         bool isEnabled(Event* triggeringEvent = 0) const;
184
185         TriState state(Event* triggeringEvent = 0) const;
186         String value(Event* triggeringEvent = 0) const;
187
188         bool isTextInsertion() const;
189
190     private:
191         const EditorInternalCommand* m_command;
192         EditorCommandSource m_source;
193         RefPtr<Frame> m_frame;
194     };
195     Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
196     Command command(const String& commandName, EditorCommandSource);
197     static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
198
199     bool insertText(const String&, Event* triggeringEvent);
200     bool insertTextForConfirmedComposition(const String& text);
201     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
202     bool insertLineBreak();
203     bool insertParagraphSeparator();
204     
205     bool isContinuousSpellCheckingEnabled();
206     void toggleContinuousSpellChecking();
207     bool isGrammarCheckingEnabled();
208     void toggleGrammarChecking();
209     void ignoreSpelling();
210     void learnSpelling();
211     int spellCheckerDocumentTag();
212     bool isSelectionUngrammatical();
213     bool isSelectionMisspelled();
214     Vector<String> guessesForMisspelledSelection();
215     Vector<String> guessesForUngrammaticalSelection();
216     Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical);
217     bool isSpellCheckingEnabledInFocusedNode() const;
218     bool isSpellCheckingEnabledFor(Node*) const;
219     void markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement);
220     void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
221     void markBadGrammar(const VisibleSelection&);
222     void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
223
224 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
225     void uppercaseWord();
226     void lowercaseWord();
227     void capitalizeWord();
228     void showSubstitutionsPanel();
229     bool substitutionsPanelIsShowing();
230     void toggleSmartInsertDelete();
231     bool isAutomaticQuoteSubstitutionEnabled();
232     void toggleAutomaticQuoteSubstitution();
233     bool isAutomaticLinkDetectionEnabled();
234     void toggleAutomaticLinkDetection();
235     bool isAutomaticDashSubstitutionEnabled();
236     void toggleAutomaticDashSubstitution();
237     bool isAutomaticTextReplacementEnabled();
238     void toggleAutomaticTextReplacement();
239     bool isAutomaticSpellingCorrectionEnabled();
240     void toggleAutomaticSpellingCorrection();
241 #endif
242
243     void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* grammarRange);
244     void changeBackToReplacedString(const String& replacedString);
245
246     void advanceToNextMisspelling(bool startBeforeSelection = false);
247     void showSpellingGuessPanel();
248     bool spellingPanelIsShowing();
249
250     bool shouldBeginEditing(Range*);
251     bool shouldEndEditing(Range*);
252
253     void clearUndoRedoOperations();
254     bool canUndo();
255     void undo();
256     bool canRedo();
257     void redo();
258
259     void didBeginEditing();
260     void didEndEditing();
261     void didWriteSelectionToPasteboard();
262     
263     void showFontPanel();
264     void showStylesPanel();
265     void showColorPanel();
266     void toggleBold();
267     void toggleUnderline();
268     void setBaseWritingDirection(WritingDirection);
269
270     // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are 
271     // mutually exclusive, meaning that enabling one will disable the other.
272     bool smartInsertDeleteEnabled();
273     bool isSelectTrailingWhitespaceEnabled();
274     
275     bool hasBidiSelection() const;
276
277     // international text input composition
278     bool hasComposition() const { return m_compositionNode; }
279     void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
280     void confirmComposition();
281     void confirmComposition(const String&); // if no existing composition, replaces selection
282     void cancelComposition();
283     PassRefPtr<Range> compositionRange() const;
284     bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
285
286     // getting international text input composition state (for use by InlineTextBox)
287     Text* compositionNode() const { return m_compositionNode.get(); }
288     unsigned compositionStart() const { return m_compositionStart; }
289     unsigned compositionEnd() const { return m_compositionEnd; }
290     bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
291     const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
292
293     bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
294
295     void setStartNewKillRingSequence(bool);
296
297     PassRefPtr<Range> rangeForPoint(const LayoutPoint& windowPoint);
298
299     void clear();
300
301     VisibleSelection selectionForCommand(Event*);
302
303     KillRing* killRing() const { return m_killRing.get(); }
304     SpellChecker* spellChecker() const { return m_spellChecker.get(); }
305
306     EditingBehavior behavior() const;
307
308     PassRefPtr<Range> selectedRange();
309     
310     // We should make these functions private when their callers in Frame are moved over here to Editor
311     bool insideVisibleArea(const LayoutPoint&) const;
312     bool insideVisibleArea(Range*) const;
313
314     void addToKillRing(Range*, bool prepend);
315
316     void startCorrectionPanelTimer();
317     // If user confirmed a correction in the correction panel, correction has non-zero length, otherwise it means that user has dismissed the panel.
318     void handleCorrectionPanelResult(const String& correction);
319     void dismissCorrectionPanelAsIgnored();
320
321     void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
322     void pasteAsPlainText(const String&, bool smartReplace);
323
324     // This is only called on the mac where paste is implemented primarily at the WebKit level.
325     void pasteAsPlainTextBypassingDHTML();
326  
327     void clearMisspellingsAndBadGrammar(const VisibleSelection&);
328     void markMisspellingsAndBadGrammar(const VisibleSelection&);
329
330     Node* findEventTargetFrom(const VisibleSelection& selection) const;
331
332     String selectedText() const;
333     bool findString(const String&, FindOptions);
334     // FIXME: Switch callers over to the FindOptions version and retire this one.
335     bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
336
337     PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
338
339     const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
340     void setMark(const VisibleSelection&);
341
342     void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
343     void applyEditingStyleToBodyElement() const;
344     void applyEditingStyleToElement(Element*) const;
345
346     IntRect firstRectForRange(Range*) const;
347
348     void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
349     bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
350     unsigned countMatchesForText(const String&, FindOptions, unsigned limit, bool markMatches);
351     unsigned countMatchesForText(const String&, Range*, FindOptions, unsigned limit, bool markMatches);
352     bool markedTextMatchesAreHighlighted() const;
353     void setMarkedTextMatchesAreHighlighted(bool);
354
355     void textFieldDidBeginEditing(Element*);
356     void textFieldDidEndEditing(Element*);
357     void textDidChangeInTextField(Element*);
358     bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
359     void textWillBeDeletedInTextField(Element* input);
360     void textDidChangeInTextArea(Element*);
361
362 #if PLATFORM(MAC)
363     const SimpleFontData* fontForSelection(bool&) const;
364     NSDictionary* fontAttributesForSelectionStart() const;
365     NSWritingDirection baseWritingDirectionForSelectionStart() const;
366     bool canCopyExcludingStandaloneImages();
367     void takeFindStringFromSelection();
368     void writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes);
369     void readSelectionFromPasteboard(const String& pasteboardName);
370 #endif
371
372     bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const;
373     void updateMarkersForWordsAffectedByEditing(bool onlyHandleWordsContainingSelection);
374     void deletedAutocorrectionAtPosition(const Position&, const String& originalString);
375
376     void deviceScaleFactorChanged();
377
378 private:
379     Frame* m_frame;
380     OwnPtr<DeleteButtonController> m_deleteButtonController;
381     RefPtr<EditCommand> m_lastEditCommand;
382     RefPtr<Node> m_removedAnchor;
383     RefPtr<Text> m_compositionNode;
384     unsigned m_compositionStart;
385     unsigned m_compositionEnd;
386     Vector<CompositionUnderline> m_customCompositionUnderlines;
387     bool m_ignoreCompositionSelectionChange;
388     bool m_shouldStartNewKillRingSequence;
389     bool m_shouldStyleWithCSS;
390     OwnPtr<KillRing> m_killRing;
391     OwnPtr<SpellChecker> m_spellChecker;
392     OwnPtr<SpellingCorrectionController> m_spellingCorrector;
393     VisibleSelection m_mark;
394     bool m_areMarkedTextMatchesHighlighted;
395
396     bool canDeleteRange(Range*) const;
397     bool canSmartReplaceWithPasteboard(Pasteboard*);
398     PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy, Frame*);
399     void pasteAsPlainTextWithPasteboard(Pasteboard*);
400     void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
401     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
402     void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
403     void writeSelectionToPasteboard(Pasteboard*);
404     void revealSelectionAfterEditingOperation();
405     void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
406     TextCheckingTypeMask resolveTextCheckingTypeMask(TextCheckingTypeMask);
407
408     void selectComposition();
409     enum SetCompositionMode { ConfirmComposition, CancelComposition };
410     void setComposition(const String&, SetCompositionMode);
411     void setIgnoreCompositionSelectionChange(bool ignore);
412
413     PassRefPtr<Range> firstVisibleRange(const String&, FindOptions);
414     PassRefPtr<Range> lastVisibleRange(const String&, FindOptions);
415     PassRefPtr<Range> nextVisibleRange(Range*, const String&, FindOptions);
416
417     void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
418
419     Node* findEventTargetFromSelection() const;
420
421     bool unifiedTextCheckerEnabled() const;
422 };
423
424 inline void Editor::setStartNewKillRingSequence(bool flag)
425 {
426     m_shouldStartNewKillRingSequence = flag;
427 }
428
429 inline const VisibleSelection& Editor::mark() const
430 {
431     return m_mark;
432 }
433
434 inline void Editor::setMark(const VisibleSelection& selection)
435 {
436     m_mark = selection;
437 }
438
439 inline bool Editor::markedTextMatchesAreHighlighted() const
440 {
441     return m_areMarkedTextMatchesHighlighted;
442 }
443
444
445 } // namespace WebCore
446
447 #endif // Editor_h