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