Home | History | Annotate | Download | only in editing
      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 "core/dom/ClipboardAccessPolicy.h"
     30 #include "core/dom/DocumentMarker.h"
     31 #include "core/editing/EditAction.h"
     32 #include "core/editing/EditingBehavior.h"
     33 #include "core/editing/EditorInsertAction.h"
     34 #include "core/editing/FindOptions.h"
     35 #include "core/editing/FrameSelection.h"
     36 #include "core/editing/TextIterator.h"
     37 #include "core/editing/VisibleSelection.h"
     38 #include "core/editing/WritingDirection.h"
     39 #include "core/page/FrameDestructionObserver.h"
     40 #include "core/platform/text/TextChecking.h"
     41 
     42 namespace WebCore {
     43 
     44 class Clipboard;
     45 class CompositeEditCommand;
     46 class EditCommand;
     47 class EditCommandComposition;
     48 class EditorClient;
     49 class EditorInternalCommand;
     50 class Frame;
     51 class HTMLElement;
     52 class HitTestResult;
     53 class KillRing;
     54 class Pasteboard;
     55 class SimpleFontData;
     56 class SpellChecker;
     57 class SpellCheckRequest;
     58 class SharedBuffer;
     59 class StylePropertySet;
     60 class Text;
     61 class TextCheckerClient;
     62 class TextEvent;
     63 struct TextCheckingResult;
     64 
     65 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
     66 enum EditorParagraphSeparator { EditorParagraphSeparatorIsDiv, EditorParagraphSeparatorIsP };
     67 
     68 class Editor : public FrameDestructionObserver {
     69 public:
     70     explicit Editor(Frame*);
     71     ~Editor();
     72 
     73     EditorClient* client() const;
     74     TextCheckerClient* textChecker() const;
     75 
     76     Frame* frame() const { return m_frame; }
     77 
     78     CompositeEditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
     79 
     80     void handleKeyboardEvent(KeyboardEvent*);
     81     bool handleTextEvent(TextEvent*);
     82 
     83     bool canEdit() const;
     84     bool canEditRichly() const;
     85 
     86     bool canDHTMLCut();
     87     bool canDHTMLCopy();
     88     bool canDHTMLPaste();
     89     bool tryDHTMLCopy();
     90     bool tryDHTMLCut();
     91     bool tryDHTMLPaste();
     92 
     93     bool canCut() const;
     94     bool canCopy() const;
     95     bool canPaste() const;
     96     bool canDelete() const;
     97     bool canSmartCopyOrDelete();
     98 
     99     void cut();
    100     void copy();
    101     void paste();
    102     void pasteAsPlainText();
    103     void performDelete();
    104 
    105     void copyURL(const KURL&, const String&);
    106     void copyImage(const HitTestResult&);
    107 
    108     void indent();
    109     void outdent();
    110     void transpose();
    111 
    112     bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction);
    113     bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
    114     bool shouldDeleteRange(Range*) const;
    115     bool shouldApplyStyle(StylePropertySet*, Range*);
    116 
    117     void respondToChangedContents(const VisibleSelection& endingSelection);
    118 
    119     bool selectionStartHasStyle(CSSPropertyID, const String& value) const;
    120     TriState selectionHasStyle(CSSPropertyID, const String& value) const;
    121     String selectionStartCSSPropertyValue(CSSPropertyID);
    122 
    123     TriState selectionUnorderedListState() const;
    124     TriState selectionOrderedListState() const;
    125     PassRefPtr<Node> insertOrderedList();
    126     PassRefPtr<Node> insertUnorderedList();
    127     bool canIncreaseSelectionListLevel();
    128     bool canDecreaseSelectionListLevel();
    129     PassRefPtr<Node> increaseSelectionListLevel();
    130     PassRefPtr<Node> increaseSelectionListLevelOrdered();
    131     PassRefPtr<Node> increaseSelectionListLevelUnordered();
    132     void decreaseSelectionListLevel();
    133 
    134     void removeFormattingAndStyle();
    135 
    136     void clearLastEditCommand();
    137 
    138     bool deleteWithDirection(SelectionDirection, TextGranularity, bool killRing, bool isTypingAction);
    139     void deleteSelectionWithSmartDelete(bool smartDelete);
    140     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
    141 
    142     Node* removedAnchor() const { return m_removedAnchor.get(); }
    143     void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
    144 
    145     void applyStyle(StylePropertySet*, EditAction = EditActionUnspecified);
    146     void applyParagraphStyle(StylePropertySet*, EditAction = EditActionUnspecified);
    147     void applyStyleToSelection(StylePropertySet*, EditAction);
    148     void applyParagraphStyleToSelection(StylePropertySet*, EditAction);
    149 
    150     void appliedEditing(PassRefPtr<CompositeEditCommand>);
    151     void unappliedEditing(PassRefPtr<EditCommandComposition>);
    152     void reappliedEditing(PassRefPtr<EditCommandComposition>);
    153 
    154     void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
    155     bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
    156 
    157     class Command {
    158     public:
    159         Command();
    160         Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
    161 
    162         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
    163         bool execute(Event* triggeringEvent) const;
    164 
    165         bool isSupported() const;
    166         bool isEnabled(Event* triggeringEvent = 0) const;
    167 
    168         TriState state(Event* triggeringEvent = 0) const;
    169         String value(Event* triggeringEvent = 0) const;
    170 
    171         bool isTextInsertion() const;
    172 
    173     private:
    174         const EditorInternalCommand* m_command;
    175         EditorCommandSource m_source;
    176         RefPtr<Frame> m_frame;
    177     };
    178     Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
    179     Command command(const String& commandName, EditorCommandSource);
    180     static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
    181 
    182     bool insertText(const String&, Event* triggeringEvent);
    183     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
    184     bool insertLineBreak();
    185     bool insertParagraphSeparator();
    186 
    187     bool isContinuousSpellCheckingEnabled() const;
    188     void toggleContinuousSpellChecking();
    189     bool isGrammarCheckingEnabled();
    190     void ignoreSpelling();
    191     String misspelledWordAtCaretOrRange(Node* clickedNode) const;
    192     bool isSpellCheckingEnabledInFocusedNode() const;
    193     bool isSpellCheckingEnabledFor(Node*) const;
    194     void markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping);
    195     void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
    196     void markBadGrammar(const VisibleSelection&);
    197     void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
    198     void markAndReplaceFor(PassRefPtr<SpellCheckRequest>, const Vector<TextCheckingResult>&);
    199 
    200     bool isOverwriteModeEnabled() const { return m_overwriteModeEnabled; }
    201     void toggleOverwriteModeEnabled();
    202 
    203     void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* grammarRange);
    204 
    205     void advanceToNextMisspelling(bool startBeforeSelection = false);
    206     void showSpellingGuessPanel();
    207 
    208     bool shouldBeginEditing(Range*);
    209     bool shouldEndEditing(Range*);
    210 
    211     void clearUndoRedoOperations();
    212     bool canUndo();
    213     void undo();
    214     bool canRedo();
    215     void redo();
    216 
    217     void didBeginEditing();
    218     void didEndEditing();
    219 
    220     void setBaseWritingDirection(WritingDirection);
    221 
    222     // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are
    223     // mutually exclusive, meaning that enabling one will disable the other.
    224     bool smartInsertDeleteEnabled();
    225     bool isSelectTrailingWhitespaceEnabled();
    226 
    227     bool setSelectionOffsets(int selectionStart, int selectionEnd);
    228 
    229     bool preventRevealSelection() const { return m_preventRevealSelection; }
    230 
    231     void setStartNewKillRingSequence(bool);
    232 
    233     PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
    234 
    235     void clear();
    236 
    237     VisibleSelection selectionForCommand(Event*);
    238 
    239     KillRing* killRing() const { return m_killRing.get(); }
    240     SpellChecker* spellChecker() const { return m_spellChecker.get(); }
    241 
    242     EditingBehavior behavior() const;
    243 
    244     PassRefPtr<Range> selectedRange();
    245 
    246     void addToKillRing(Range*, bool prepend);
    247 
    248     void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
    249     void pasteAsPlainText(const String&, bool smartReplace);
    250 
    251     // This is only called on the mac where paste is implemented primarily at the WebKit level.
    252     void pasteAsPlainTextBypassingDHTML();
    253 
    254     void clearMisspellingsAndBadGrammar(const VisibleSelection&);
    255     void markMisspellingsAndBadGrammar(const VisibleSelection&);
    256 
    257     Node* findEventTargetFrom(const VisibleSelection&) const;
    258 
    259     bool findString(const String&, FindOptions);
    260     // FIXME: Switch callers over to the FindOptions version and retire this one.
    261     bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
    262 
    263     PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
    264     PassRefPtr<Range> findStringAndScrollToVisible(const String&, Range*, FindOptions);
    265 
    266     const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
    267     void setMark(const VisibleSelection&);
    268 
    269     void computeAndSetTypingStyle(StylePropertySet* , EditAction = EditActionUnspecified);
    270     void applyEditingStyleToBodyElement() const;
    271     void applyEditingStyleToElement(Element*) const;
    272 
    273     IntRect firstRectForRange(Range*) const;
    274 
    275     void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
    276     bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
    277 
    278     void spellCheckAfterBlur();
    279     void spellCheckOldSelection(const VisibleSelection& oldSelection, const VisibleSelection& newAdjacentWords, const VisibleSelection& newSelectedSentence);
    280 
    281     bool markedTextMatchesAreHighlighted() const;
    282     void setMarkedTextMatchesAreHighlighted(bool);
    283 
    284     void textFieldDidBeginEditing(Element*);
    285     void textFieldDidEndEditing(Element*);
    286     void textDidChangeInTextField(Element*);
    287     bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
    288     WritingDirection baseWritingDirectionForSelectionStart() const;
    289 
    290     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
    291     void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
    292     bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const;
    293     void updateMarkersForWordsAffectedByEditing(bool onlyHandleWordsContainingSelection);
    294 
    295     void simplifyMarkup(Node* startNode, Node* endNode);
    296 
    297     void deviceScaleFactorChanged();
    298 
    299     EditorParagraphSeparator defaultParagraphSeparator() const { return m_defaultParagraphSeparator; }
    300     void setDefaultParagraphSeparator(EditorParagraphSeparator separator) { m_defaultParagraphSeparator = separator; }
    301 
    302     class RevealSelectionScope {
    303         WTF_MAKE_NONCOPYABLE(RevealSelectionScope);
    304     public:
    305         RevealSelectionScope(Editor*);
    306         ~RevealSelectionScope();
    307     private:
    308         Editor* m_editor;
    309     };
    310     friend class RevealSelectionScope;
    311 
    312 private:
    313     RefPtr<CompositeEditCommand> m_lastEditCommand;
    314     RefPtr<Node> m_removedAnchor;
    315     int m_preventRevealSelection;
    316     bool m_shouldStartNewKillRingSequence;
    317     bool m_shouldStyleWithCSS;
    318     OwnPtr<KillRing> m_killRing;
    319     OwnPtr<SpellChecker> m_spellChecker;
    320     VisibleSelection m_mark;
    321     bool m_areMarkedTextMatchesHighlighted;
    322     EditorParagraphSeparator m_defaultParagraphSeparator;
    323     bool m_overwriteModeEnabled;
    324 
    325     bool canDeleteRange(Range*) const;
    326     bool canSmartReplaceWithPasteboard(Pasteboard*);
    327     PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy, Frame*);
    328     void pasteAsPlainTextWithPasteboard(Pasteboard*);
    329     void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
    330 
    331     void revealSelectionAfterEditingOperation(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
    332     void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
    333     TextCheckingTypeMask resolveTextCheckingTypeMask(TextCheckingTypeMask);
    334 
    335     void changeSelectionAfterCommand(const VisibleSelection& newSelection, FrameSelection::SetSelectionOptions);
    336     void notifyComponentsOnChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
    337 
    338     Node* findEventTargetFromSelection() const;
    339 
    340     bool unifiedTextCheckerEnabled() const;
    341 };
    342 
    343 inline void Editor::setStartNewKillRingSequence(bool flag)
    344 {
    345     m_shouldStartNewKillRingSequence = flag;
    346 }
    347 
    348 inline const VisibleSelection& Editor::mark() const
    349 {
    350     return m_mark;
    351 }
    352 
    353 inline void Editor::setMark(const VisibleSelection& selection)
    354 {
    355     m_mark = selection;
    356 }
    357 
    358 inline bool Editor::markedTextMatchesAreHighlighted() const
    359 {
    360     return m_areMarkedTextMatchesHighlighted;
    361 }
    362 
    363 
    364 } // namespace WebCore
    365 
    366 #endif // Editor_h
    367