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/FindOptions.h"
     34 #include "core/editing/FrameSelection.h"
     35 #include "core/editing/TextIterator.h"
     36 #include "core/editing/VisibleSelection.h"
     37 #include "core/editing/WritingDirection.h"
     38 #include "core/frame/FrameDestructionObserver.h"
     39 #include "platform/PasteMode.h"
     40 
     41 namespace WebCore {
     42 
     43 class Clipboard;
     44 class CompositeEditCommand;
     45 class EditCommand;
     46 class EditCommandComposition;
     47 class EditorClient;
     48 class EditorInternalCommand;
     49 class Frame;
     50 class HTMLElement;
     51 class HitTestResult;
     52 class KillRing;
     53 class Pasteboard;
     54 class SharedBuffer;
     55 class SimpleFontData;
     56 class SpellChecker;
     57 class StylePropertySet;
     58 class Text;
     59 class TextEvent;
     60 class UndoStack;
     61 
     62 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
     63 enum EditorParagraphSeparator { EditorParagraphSeparatorIsDiv, EditorParagraphSeparatorIsP };
     64 
     65 class Editor {
     66     WTF_MAKE_NONCOPYABLE(Editor);
     67 public:
     68     static PassOwnPtr<Editor> create(Frame&);
     69     ~Editor();
     70 
     71     EditorClient& client() const;
     72 
     73     Frame& frame() const { return m_frame; }
     74 
     75     CompositeEditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
     76 
     77     void handleKeyboardEvent(KeyboardEvent*);
     78     bool handleTextEvent(TextEvent*);
     79 
     80     bool canEdit() const;
     81     bool canEditRichly() const;
     82 
     83     bool canDHTMLCut();
     84     bool canDHTMLCopy();
     85     bool canDHTMLPaste();
     86 
     87     bool canCut() const;
     88     bool canCopy() const;
     89     bool canPaste() const;
     90     bool canDelete() const;
     91     bool canSmartCopyOrDelete() const;
     92 
     93     void cut();
     94     void copy();
     95     void paste();
     96     void pasteAsPlainText();
     97     void performDelete();
     98 
     99     void copyImage(const HitTestResult&);
    100 
    101     void indent();
    102     void outdent();
    103     void transpose();
    104 
    105     bool shouldDeleteRange(Range*) const;
    106 
    107     void respondToChangedContents(const VisibleSelection& endingSelection);
    108 
    109     bool selectionStartHasStyle(CSSPropertyID, const String& value) const;
    110     TriState selectionHasStyle(CSSPropertyID, const String& value) const;
    111     String selectionStartCSSPropertyValue(CSSPropertyID);
    112 
    113     TriState selectionUnorderedListState() const;
    114     TriState selectionOrderedListState() const;
    115     PassRefPtr<Node> insertOrderedList();
    116     PassRefPtr<Node> insertUnorderedList();
    117     bool canIncreaseSelectionListLevel();
    118     bool canDecreaseSelectionListLevel();
    119     PassRefPtr<Node> increaseSelectionListLevel();
    120     PassRefPtr<Node> increaseSelectionListLevelOrdered();
    121     PassRefPtr<Node> increaseSelectionListLevelUnordered();
    122     void decreaseSelectionListLevel();
    123 
    124     void removeFormattingAndStyle();
    125 
    126     void clearLastEditCommand();
    127 
    128     bool deleteWithDirection(SelectionDirection, TextGranularity, bool killRing, bool isTypingAction);
    129     void deleteSelectionWithSmartDelete(bool smartDelete);
    130 
    131     void applyStyle(StylePropertySet*, EditAction = EditActionUnspecified);
    132     void applyParagraphStyle(StylePropertySet*, EditAction = EditActionUnspecified);
    133     void applyStyleToSelection(StylePropertySet*, EditAction);
    134     void applyParagraphStyleToSelection(StylePropertySet*, EditAction);
    135 
    136     void appliedEditing(PassRefPtr<CompositeEditCommand>);
    137     void unappliedEditing(PassRefPtr<EditCommandComposition>);
    138     void reappliedEditing(PassRefPtr<EditCommandComposition>);
    139 
    140     void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
    141     bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
    142 
    143     class Command {
    144     public:
    145         Command();
    146         Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
    147 
    148         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
    149         bool execute(Event* triggeringEvent) const;
    150 
    151         bool isSupported() const;
    152         bool isEnabled(Event* triggeringEvent = 0) const;
    153 
    154         TriState state(Event* triggeringEvent = 0) const;
    155         String value(Event* triggeringEvent = 0) const;
    156 
    157         bool isTextInsertion() const;
    158 
    159     private:
    160         const EditorInternalCommand* m_command;
    161         EditorCommandSource m_source;
    162         RefPtr<Frame> m_frame;
    163     };
    164     Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
    165     Command command(const String& commandName, EditorCommandSource);
    166     static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
    167 
    168     bool insertText(const String&, Event* triggeringEvent);
    169     bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
    170     bool insertLineBreak();
    171     bool insertParagraphSeparator();
    172 
    173     bool isOverwriteModeEnabled() const { return m_overwriteModeEnabled; }
    174     void toggleOverwriteModeEnabled();
    175 
    176     bool canUndo();
    177     void undo();
    178     bool canRedo();
    179     void redo();
    180 
    181     void setBaseWritingDirection(WritingDirection);
    182 
    183     // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are
    184     // mutually exclusive, meaning that enabling one will disable the other.
    185     bool smartInsertDeleteEnabled() const;
    186     bool isSelectTrailingWhitespaceEnabled() const;
    187 
    188     bool preventRevealSelection() const { return m_preventRevealSelection; }
    189 
    190     void setStartNewKillRingSequence(bool);
    191 
    192     void clear();
    193 
    194     VisibleSelection selectionForCommand(Event*);
    195 
    196     KillRing& killRing() const { return *m_killRing; }
    197 
    198     EditingBehavior behavior() const;
    199 
    200     PassRefPtr<Range> selectedRange();
    201 
    202     void addToKillRing(Range*, bool prepend);
    203 
    204     void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
    205     void pasteAsPlainText(const String&, bool smartReplace);
    206 
    207     Node* findEventTargetFrom(const VisibleSelection&) const;
    208 
    209     bool findString(const String&, FindOptions);
    210     // FIXME: Switch callers over to the FindOptions version and retire this one.
    211     bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
    212 
    213     PassRefPtr<Range> findStringAndScrollToVisible(const String&, Range*, FindOptions);
    214 
    215     const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
    216     void setMark(const VisibleSelection&);
    217 
    218     void computeAndSetTypingStyle(StylePropertySet* , EditAction = EditActionUnspecified);
    219 
    220     IntRect firstRectForRange(Range*) const;
    221 
    222     void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
    223 
    224     bool markedTextMatchesAreHighlighted() const;
    225     void setMarkedTextMatchesAreHighlighted(bool);
    226 
    227     void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
    228     void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
    229 
    230     EditorParagraphSeparator defaultParagraphSeparator() const { return m_defaultParagraphSeparator; }
    231     void setDefaultParagraphSeparator(EditorParagraphSeparator separator) { m_defaultParagraphSeparator = separator; }
    232 
    233     class RevealSelectionScope {
    234         WTF_MAKE_NONCOPYABLE(RevealSelectionScope);
    235     public:
    236         RevealSelectionScope(Editor*);
    237         ~RevealSelectionScope();
    238     private:
    239         Editor* m_editor;
    240     };
    241     friend class RevealSelectionScope;
    242 
    243     // Export interpretKeyEvent only for testing
    244     static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
    245 
    246 private:
    247     Frame& m_frame;
    248     RefPtr<CompositeEditCommand> m_lastEditCommand;
    249     int m_preventRevealSelection;
    250     bool m_shouldStartNewKillRingSequence;
    251     bool m_shouldStyleWithCSS;
    252     const OwnPtr<KillRing> m_killRing;
    253     VisibleSelection m_mark;
    254     bool m_areMarkedTextMatchesHighlighted;
    255     EditorParagraphSeparator m_defaultParagraphSeparator;
    256     bool m_overwriteModeEnabled;
    257 
    258     explicit Editor(Frame&);
    259 
    260     bool canDeleteRange(Range*) const;
    261 
    262     UndoStack* undoStack() const;
    263 
    264     bool tryDHTMLCopy();
    265     bool tryDHTMLCut();
    266     bool tryDHTMLPaste(PasteMode);
    267 
    268     bool canSmartReplaceWithPasteboard(Pasteboard*);
    269     void pasteAsPlainTextWithPasteboard(Pasteboard*);
    270     void pasteWithPasteboard(Pasteboard*);
    271     void writeSelectionToPasteboard(Pasteboard*, Range*, const String& plainText);
    272     bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy, PasteMode = AllMimeTypes);
    273 
    274     void revealSelectionAfterEditingOperation(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
    275     void changeSelectionAfterCommand(const VisibleSelection& newSelection, FrameSelection::SetSelectionOptions);
    276     void notifyComponentsOnChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
    277 
    278     Node* findEventTargetFromSelection() const;
    279 
    280     PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
    281 
    282     SpellChecker& spellChecker() const;
    283 
    284     bool handleEditingKeyboardEvent(WebCore::KeyboardEvent*);
    285 };
    286 
    287 inline void Editor::setStartNewKillRingSequence(bool flag)
    288 {
    289     m_shouldStartNewKillRingSequence = flag;
    290 }
    291 
    292 inline const VisibleSelection& Editor::mark() const
    293 {
    294     return m_mark;
    295 }
    296 
    297 inline void Editor::setMark(const VisibleSelection& selection)
    298 {
    299     m_mark = selection;
    300 }
    301 
    302 inline bool Editor::markedTextMatchesAreHighlighted() const
    303 {
    304     return m_areMarkedTextMatchesHighlighted;
    305 }
    306 
    307 
    308 } // namespace WebCore
    309 
    310 #endif // Editor_h
    311