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