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