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 "ClipboardAccessPolicy.h" 30 #include "Color.h" 31 #include "EditAction.h" 32 #include "EditorDeleteAction.h" 33 #include "EditorInsertAction.h" 34 #include "SelectionController.h" 35 36 namespace WebCore { 37 38 class CSSStyleDeclaration; 39 class Clipboard; 40 class DeleteButtonController; 41 class EditCommand; 42 class EditorClient; 43 class EditorInternalCommand; 44 class HTMLElement; 45 class HitTestResult; 46 class Pasteboard; 47 class SimpleFontData; 48 class Text; 49 50 struct CompositionUnderline { 51 CompositionUnderline() 52 : startOffset(0), endOffset(0), thick(false) { } 53 CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t) 54 : startOffset(s), endOffset(e), color(c), thick(t) { } 55 unsigned startOffset; 56 unsigned endOffset; 57 Color color; 58 bool thick; 59 }; 60 61 enum TriState { FalseTriState, TrueTriState, MixedTriState }; 62 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface }; 63 enum WritingDirection { NaturalWritingDirection, LeftToRightWritingDirection, RightToLeftWritingDirection }; 64 65 class Editor { 66 public: 67 Editor(Frame*); 68 ~Editor(); 69 70 EditorClient* client() const; 71 Frame* frame() const { return m_frame; } 72 DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); } 73 EditCommand* lastEditCommand() { return m_lastEditCommand.get(); } 74 75 void handleKeyboardEvent(KeyboardEvent*); 76 void handleInputMethodKeydown(KeyboardEvent*); 77 78 bool canEdit() const; 79 bool canEditRichly() const; 80 81 bool canDHTMLCut(); 82 bool canDHTMLCopy(); 83 bool canDHTMLPaste(); 84 bool tryDHTMLCopy(); 85 bool tryDHTMLCut(); 86 bool tryDHTMLPaste(); 87 88 bool canCut() const; 89 bool canCopy() const; 90 bool canPaste() const; 91 bool canDelete() const; 92 bool canSmartCopyOrDelete(); 93 94 void cut(); 95 void copy(); 96 void paste(); 97 void pasteAsPlainText(); 98 void performDelete(); 99 100 void copyURL(const KURL&, const String&); 101 void copyImage(const HitTestResult&); 102 103 void indent(); 104 void outdent(); 105 void transpose(); 106 107 bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction); 108 bool shouldInsertText(const String&, Range*, EditorInsertAction) const; 109 bool shouldShowDeleteInterface(HTMLElement*) const; 110 bool shouldDeleteRange(Range*) const; 111 bool shouldApplyStyle(CSSStyleDeclaration*, Range*); 112 113 void respondToChangedSelection(const VisibleSelection& oldSelection); 114 void respondToChangedContents(const VisibleSelection& endingSelection); 115 116 TriState selectionHasStyle(CSSStyleDeclaration*) const; 117 const SimpleFontData* fontForSelection(bool&) const; 118 WritingDirection textDirectionForSelection(bool&) const; 119 120 TriState selectionUnorderedListState() const; 121 TriState selectionOrderedListState() const; 122 PassRefPtr<Node> insertOrderedList(); 123 PassRefPtr<Node> insertUnorderedList(); 124 bool canIncreaseSelectionListLevel(); 125 bool canDecreaseSelectionListLevel(); 126 PassRefPtr<Node> increaseSelectionListLevel(); 127 PassRefPtr<Node> increaseSelectionListLevelOrdered(); 128 PassRefPtr<Node> increaseSelectionListLevelUnordered(); 129 void decreaseSelectionListLevel(); 130 131 void removeFormattingAndStyle(); 132 133 void clearLastEditCommand(); 134 135 bool deleteWithDirection(SelectionController::EDirection, TextGranularity, bool killRing, bool isTypingAction); 136 void deleteSelectionWithSmartDelete(bool smartDelete); 137 bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy); 138 139 Node* removedAnchor() const { return m_removedAnchor.get(); } 140 void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; } 141 142 void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified); 143 void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified); 144 void applyStyleToSelection(CSSStyleDeclaration*, EditAction); 145 void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction); 146 147 void appliedEditing(PassRefPtr<EditCommand>); 148 void unappliedEditing(PassRefPtr<EditCommand>); 149 void reappliedEditing(PassRefPtr<EditCommand>); 150 151 bool selectionStartHasStyle(CSSStyleDeclaration*) const; 152 153 bool clientIsEditable() const; 154 155 void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; } 156 bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; } 157 158 class Command { 159 public: 160 Command(); 161 Command(PassRefPtr<Frame>, const EditorInternalCommand*, EditorCommandSource); 162 163 bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const; 164 bool execute(Event* triggeringEvent) const; 165 166 bool isSupported() const; 167 bool isEnabled(Event* triggeringEvent = 0) const; 168 169 TriState state(Event* triggeringEvent = 0) const; 170 String value(Event* triggeringEvent = 0) const; 171 172 bool isTextInsertion() const; 173 174 private: 175 RefPtr<Frame> m_frame; 176 const EditorInternalCommand* m_command; 177 EditorCommandSource m_source; 178 }; 179 Command command(const String& commandName); // Default is CommandFromMenuOrKeyBinding. 180 Command command(const String& commandName, EditorCommandSource); 181 182 bool insertText(const String&, Event* triggeringEvent); 183 bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, Event* triggeringEvent); 184 bool insertLineBreak(); 185 bool insertParagraphSeparator(); 186 187 bool isContinuousSpellCheckingEnabled(); 188 void toggleContinuousSpellChecking(); 189 bool isGrammarCheckingEnabled(); 190 void toggleGrammarChecking(); 191 void ignoreSpelling(); 192 void learnSpelling(); 193 int spellCheckerDocumentTag(); 194 bool isSelectionUngrammatical(); 195 bool isSelectionMisspelled(); 196 Vector<String> guessesForMisspelledSelection(); 197 Vector<String> guessesForUngrammaticalSelection(); 198 Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical); 199 bool spellCheckingEnabledInFocusedNode() const; 200 void markMisspellingsAfterTypingToPosition(const VisiblePosition&); 201 void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange); 202 void markBadGrammar(const VisibleSelection&); 203 void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection); 204 #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) 205 void uppercaseWord(); 206 void lowercaseWord(); 207 void capitalizeWord(); 208 void showSubstitutionsPanel(); 209 bool substitutionsPanelIsShowing(); 210 void toggleSmartInsertDelete(); 211 bool isAutomaticQuoteSubstitutionEnabled(); 212 void toggleAutomaticQuoteSubstitution(); 213 bool isAutomaticLinkDetectionEnabled(); 214 void toggleAutomaticLinkDetection(); 215 bool isAutomaticDashSubstitutionEnabled(); 216 void toggleAutomaticDashSubstitution(); 217 bool isAutomaticTextReplacementEnabled(); 218 void toggleAutomaticTextReplacement(); 219 bool isAutomaticSpellingCorrectionEnabled(); 220 void toggleAutomaticSpellingCorrection(); 221 void markAllMisspellingsAndBadGrammarInRanges(bool markSpelling, Range* spellingRange, bool markGrammar, Range* grammarRange, bool performTextCheckingReplacements); 222 void changeBackToReplacedString(const String& replacedString); 223 #endif 224 void advanceToNextMisspelling(bool startBeforeSelection = false); 225 void showSpellingGuessPanel(); 226 bool spellingPanelIsShowing(); 227 228 bool shouldBeginEditing(Range*); 229 bool shouldEndEditing(Range*); 230 231 void clearUndoRedoOperations(); 232 bool canUndo(); 233 void undo(); 234 bool canRedo(); 235 void redo(); 236 237 void didBeginEditing(); 238 void didEndEditing(); 239 void didWriteSelectionToPasteboard(); 240 241 void showFontPanel(); 242 void showStylesPanel(); 243 void showColorPanel(); 244 void toggleBold(); 245 void toggleUnderline(); 246 void setBaseWritingDirection(WritingDirection); 247 248 // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are 249 // mutually exclusive, meaning that enabling one will disable the other. 250 bool smartInsertDeleteEnabled(); 251 bool isSelectTrailingWhitespaceEnabled(); 252 253 bool hasBidiSelection() const; 254 255 // international text input composition 256 bool hasComposition() const { return m_compositionNode; } 257 void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd); 258 void confirmComposition(); 259 void confirmComposition(const String&); // if no existing composition, replaces selection 260 void confirmCompositionWithoutDisturbingSelection(); 261 PassRefPtr<Range> compositionRange() const; 262 bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const; 263 264 // getting international text input composition state (for use by InlineTextBox) 265 Text* compositionNode() const { return m_compositionNode.get(); } 266 unsigned compositionStart() const { return m_compositionStart; } 267 unsigned compositionEnd() const { return m_compositionEnd; } 268 bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); } 269 const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; } 270 271 bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; } 272 273 void setStartNewKillRingSequence(bool); 274 275 PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint); 276 277 void clear(); 278 279 VisibleSelection selectionForCommand(Event*); 280 281 void appendToKillRing(const String&); 282 void prependToKillRing(const String&); 283 String yankFromKillRing(); 284 void startNewKillRingSequence(); 285 void setKillRingToYankedState(); 286 287 PassRefPtr<Range> selectedRange(); 288 289 // We should make these functions private when their callers in Frame are moved over here to Editor 290 bool insideVisibleArea(const IntPoint&) const; 291 bool insideVisibleArea(Range*) const; 292 PassRefPtr<Range> nextVisibleRange(Range*, const String&, bool forward, bool caseFlag, bool wrapFlag); 293 294 void addToKillRing(Range*, bool prepend); 295 private: 296 Frame* m_frame; 297 OwnPtr<DeleteButtonController> m_deleteButtonController; 298 RefPtr<EditCommand> m_lastEditCommand; 299 RefPtr<Node> m_removedAnchor; 300 301 RefPtr<Text> m_compositionNode; 302 unsigned m_compositionStart; 303 unsigned m_compositionEnd; 304 Vector<CompositionUnderline> m_customCompositionUnderlines; 305 bool m_ignoreCompositionSelectionChange; 306 bool m_shouldStartNewKillRingSequence; 307 bool m_shouldStyleWithCSS; 308 309 bool canDeleteRange(Range*) const; 310 bool canSmartReplaceWithPasteboard(Pasteboard*); 311 PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy); 312 void pasteAsPlainTextWithPasteboard(Pasteboard*); 313 void pasteWithPasteboard(Pasteboard*, bool allowPlainText); 314 void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle); 315 void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace); 316 void writeSelectionToPasteboard(Pasteboard*); 317 void revealSelectionAfterEditingOperation(); 318 319 void selectComposition(); 320 void confirmComposition(const String&, bool preserveSelection); 321 void setIgnoreCompositionSelectionChange(bool ignore); 322 323 PassRefPtr<Range> firstVisibleRange(const String&, bool caseFlag); 324 PassRefPtr<Range> lastVisibleRange(const String&, bool caseFlag); 325 326 void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle, EditCommand*); 327 }; 328 329 inline void Editor::setStartNewKillRingSequence(bool flag) 330 { 331 m_shouldStartNewKillRingSequence = flag; 332 } 333 334 } // namespace WebCore 335 336 #endif // Editor_h 337