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