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