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