2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "ClipboardAccessPolicy.h"
31 #include "DocumentMarker.h"
32 #include "EditAction.h"
33 #include "EditingBehavior.h"
34 #include "EditingStyle.h"
35 #include "EditorInsertAction.h"
36 #include "FindOptions.h"
37 #include "FrameSelection.h"
38 #include "TextChecking.h"
39 #include "VisibleSelection.h"
40 #include "WritingDirection.h"
42 #if PLATFORM(MAC) && !defined(__OBJC__)
44 typedef int NSWritingDirection;
49 class CSSStyleDeclaration;
51 class SpellingCorrectionController;
52 class DeleteButtonController;
55 class EditorInternalCommand;
64 class TextCheckerClient;
67 struct CompositionUnderline {
68 CompositionUnderline()
69 : startOffset(0), endOffset(0), thick(false) { }
70 CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t)
71 : startOffset(s), endOffset(e), color(c), thick(t) { }
78 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
85 EditorClient* client() const;
86 TextCheckerClient* textChecker() const;
88 Frame* frame() const { return m_frame; }
89 DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); }
90 EditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
92 void handleKeyboardEvent(KeyboardEvent*);
93 void handleInputMethodKeydown(KeyboardEvent*);
94 bool handleTextEvent(TextEvent*);
97 bool canEditRichly() const;
101 bool canDHTMLPaste();
104 bool tryDHTMLPaste();
107 bool canCopy() const;
108 bool canPaste() const;
109 bool canDelete() const;
110 bool canSmartCopyOrDelete();
115 void pasteAsPlainText();
116 void performDelete();
118 void copyURL(const KURL&, const String&);
119 void copyImage(const HitTestResult&);
125 bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction);
126 bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
127 bool shouldShowDeleteInterface(HTMLElement*) const;
128 bool shouldDeleteRange(Range*) const;
129 bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
131 void respondToChangedSelection(const VisibleSelection& oldSelection);
132 void respondToChangedContents(const VisibleSelection& endingSelection);
134 bool selectionStartHasStyle(int propertyID, const String& value) const;
135 TriState selectionHasStyle(int propertyID, const String& value) const;
136 String selectionStartCSSPropertyValue(int propertyID);
137 const SimpleFontData* fontForSelection(bool&) const;
138 WritingDirection textDirectionForSelection(bool&) const;
140 TriState selectionUnorderedListState() const;
141 TriState selectionOrderedListState() const;
142 PassRefPtr<Node> insertOrderedList();
143 PassRefPtr<Node> insertUnorderedList();
144 bool canIncreaseSelectionListLevel();
145 bool canDecreaseSelectionListLevel();
146 PassRefPtr<Node> increaseSelectionListLevel();
147 PassRefPtr<Node> increaseSelectionListLevelOrdered();
148 PassRefPtr<Node> increaseSelectionListLevelUnordered();
149 void decreaseSelectionListLevel();
151 void removeFormattingAndStyle();
153 void clearLastEditCommand();
155 bool deleteWithDirection(SelectionDirection, TextGranularity, bool killRing, bool isTypingAction);
156 void deleteSelectionWithSmartDelete(bool smartDelete);
157 bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
159 Node* removedAnchor() const { return m_removedAnchor.get(); }
160 void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
162 void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
163 void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
164 void applyStyleToSelection(CSSStyleDeclaration*, EditAction);
165 void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction);
167 void appliedEditing(PassRefPtr<EditCommand>);
168 void unappliedEditing(PassRefPtr<EditCommand>);
169 void reappliedEditing(PassRefPtr<EditCommand>);
170 void unappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction);
172 void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
173 bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
178 Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
180 bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
181 bool execute(Event* triggeringEvent) const;
183 bool isSupported() const;
184 bool isEnabled(Event* triggeringEvent = 0) const;
186 TriState state(Event* triggeringEvent = 0) const;
187 String value(Event* triggeringEvent = 0) const;
189 bool isTextInsertion() const;
192 const EditorInternalCommand* m_command;
193 EditorCommandSource m_source;
194 RefPtr<Frame> m_frame;
196 Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
197 Command command(const String& commandName, EditorCommandSource);
198 static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
200 bool insertText(const String&, Event* triggeringEvent);
201 bool insertTextForConfirmedComposition(const String& text);
202 bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
203 bool insertLineBreak();
204 bool insertParagraphSeparator();
206 bool isContinuousSpellCheckingEnabled();
207 void toggleContinuousSpellChecking();
208 bool isGrammarCheckingEnabled();
209 void toggleGrammarChecking();
210 void ignoreSpelling();
211 void learnSpelling();
212 int spellCheckerDocumentTag();
213 bool isSelectionUngrammatical();
214 bool isSelectionMisspelled();
215 Vector<String> guessesForMisspelledSelection();
216 Vector<String> guessesForUngrammaticalSelection();
217 Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical);
218 bool isSpellCheckingEnabledInFocusedNode() const;
219 bool isSpellCheckingEnabledFor(Node*) const;
220 void markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement);
221 void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
222 void markBadGrammar(const VisibleSelection&);
223 void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
225 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
226 void uppercaseWord();
227 void lowercaseWord();
228 void capitalizeWord();
229 void showSubstitutionsPanel();
230 bool substitutionsPanelIsShowing();
231 void toggleSmartInsertDelete();
232 bool isAutomaticQuoteSubstitutionEnabled();
233 void toggleAutomaticQuoteSubstitution();
234 bool isAutomaticLinkDetectionEnabled();
235 void toggleAutomaticLinkDetection();
236 bool isAutomaticDashSubstitutionEnabled();
237 void toggleAutomaticDashSubstitution();
238 bool isAutomaticTextReplacementEnabled();
239 void toggleAutomaticTextReplacement();
240 bool isAutomaticSpellingCorrectionEnabled();
241 void toggleAutomaticSpellingCorrection();
244 void markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask, Range* spellingRange, Range* grammarRange);
245 void changeBackToReplacedString(const String& replacedString);
247 void advanceToNextMisspelling(bool startBeforeSelection = false);
248 void showSpellingGuessPanel();
249 bool spellingPanelIsShowing();
251 bool shouldBeginEditing(Range*);
252 bool shouldEndEditing(Range*);
254 void clearUndoRedoOperations();
260 void didBeginEditing();
261 void didEndEditing();
262 void didWriteSelectionToPasteboard();
264 void showFontPanel();
265 void showStylesPanel();
266 void showColorPanel();
268 void toggleUnderline();
269 void setBaseWritingDirection(WritingDirection);
271 // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are
272 // mutually exclusive, meaning that enabling one will disable the other.
273 bool smartInsertDeleteEnabled();
274 bool isSelectTrailingWhitespaceEnabled();
276 bool hasBidiSelection() const;
278 // international text input composition
279 bool hasComposition() const { return m_compositionNode; }
280 void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
281 void confirmComposition();
282 void confirmComposition(const String&); // if no existing composition, replaces selection
283 void cancelComposition();
284 PassRefPtr<Range> compositionRange() const;
285 bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
287 // getting international text input composition state (for use by InlineTextBox)
288 Text* compositionNode() const { return m_compositionNode.get(); }
289 unsigned compositionStart() const { return m_compositionStart; }
290 unsigned compositionEnd() const { return m_compositionEnd; }
291 bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
292 const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
294 bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
296 void setStartNewKillRingSequence(bool);
298 PassRefPtr<Range> rangeForPoint(const LayoutPoint& windowPoint);
302 VisibleSelection selectionForCommand(Event*);
304 KillRing* killRing() const { return m_killRing.get(); }
305 SpellChecker* spellChecker() const { return m_spellChecker.get(); }
307 EditingBehavior behavior() const;
309 PassRefPtr<Range> selectedRange();
311 // We should make these functions private when their callers in Frame are moved over here to Editor
312 bool insideVisibleArea(const LayoutPoint&) const;
313 bool insideVisibleArea(Range*) const;
315 void addToKillRing(Range*, bool prepend);
317 void startCorrectionPanelTimer();
318 // If user confirmed a correction in the correction panel, correction has non-zero length, otherwise it means that user has dismissed the panel.
319 void handleCorrectionPanelResult(const String& correction);
320 void dismissCorrectionPanelAsIgnored();
322 void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
323 void pasteAsPlainText(const String&, bool smartReplace);
325 // This is only called on the mac where paste is implemented primarily at the WebKit level.
326 void pasteAsPlainTextBypassingDHTML();
328 void clearMisspellingsAndBadGrammar(const VisibleSelection&);
329 void markMisspellingsAndBadGrammar(const VisibleSelection&);
331 Node* findEventTargetFrom(const VisibleSelection& selection) const;
333 String selectedText() const;
334 bool findString(const String&, FindOptions);
335 // FIXME: Switch callers over to the FindOptions version and retire this one.
336 bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
338 PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
340 const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
341 void setMark(const VisibleSelection&);
343 void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
344 void applyEditingStyleToBodyElement() const;
345 void applyEditingStyleToElement(Element*) const;
347 IntRect firstRectForRange(Range*) const;
349 void respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions);
350 bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
352 RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
354 unsigned countMatchesForText(const String&, FindOptions, unsigned limit, bool markMatches);
355 unsigned countMatchesForText(const String&, Range*, FindOptions, unsigned limit, bool markMatches);
356 bool markedTextMatchesAreHighlighted() const;
357 void setMarkedTextMatchesAreHighlighted(bool);
359 PassRefPtr<EditingStyle> selectionStartStyle() const;
361 void textFieldDidBeginEditing(Element*);
362 void textFieldDidEndEditing(Element*);
363 void textDidChangeInTextField(Element*);
364 bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
365 void textWillBeDeletedInTextField(Element* input);
366 void textDidChangeInTextArea(Element*);
369 NSDictionary* fontAttributesForSelectionStart() const;
370 NSWritingDirection baseWritingDirectionForSelectionStart() const;
371 bool canCopyExcludingStandaloneImages();
372 void takeFindStringFromSelection();
373 void writeSelectionToPasteboard(const String& pasteboardName, const Vector<String>& pasteboardTypes);
374 void readSelectionFromPasteboard(const String& pasteboardName);
377 bool selectionStartHasMarkerFor(DocumentMarker::MarkerType, int from, int length) const;
378 void updateMarkersForWordsAffectedByEditing(bool onlyHandleWordsContainingSelection);
379 void deletedAutocorrectionAtPosition(const Position&, const String& originalString);
383 OwnPtr<DeleteButtonController> m_deleteButtonController;
384 RefPtr<EditCommand> m_lastEditCommand;
385 RefPtr<Node> m_removedAnchor;
386 RefPtr<Text> m_compositionNode;
387 unsigned m_compositionStart;
388 unsigned m_compositionEnd;
389 Vector<CompositionUnderline> m_customCompositionUnderlines;
390 bool m_ignoreCompositionSelectionChange;
391 bool m_shouldStartNewKillRingSequence;
392 bool m_shouldStyleWithCSS;
393 OwnPtr<KillRing> m_killRing;
394 OwnPtr<SpellChecker> m_spellChecker;
395 OwnPtr<SpellingCorrectionController> m_spellingCorrector;
396 VisibleSelection m_mark;
397 bool m_areMarkedTextMatchesHighlighted;
399 bool canDeleteRange(Range*) const;
400 bool canSmartReplaceWithPasteboard(Pasteboard*);
401 PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy, Frame*);
402 void pasteAsPlainTextWithPasteboard(Pasteboard*);
403 void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
404 void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
405 void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
406 void writeSelectionToPasteboard(Pasteboard*);
407 void revealSelectionAfterEditingOperation();
408 void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
409 TextCheckingTypeMask resolveTextCheckingTypeMask(TextCheckingTypeMask);
411 void selectComposition();
412 enum SetCompositionMode { ConfirmComposition, CancelComposition };
413 void setComposition(const String&, SetCompositionMode);
414 void setIgnoreCompositionSelectionChange(bool ignore);
416 PassRefPtr<Range> firstVisibleRange(const String&, FindOptions);
417 PassRefPtr<Range> lastVisibleRange(const String&, FindOptions);
418 PassRefPtr<Range> nextVisibleRange(Range*, const String&, FindOptions);
420 void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
422 Node* findEventTargetFromSelection() const;
425 inline void Editor::setStartNewKillRingSequence(bool flag)
427 m_shouldStartNewKillRingSequence = flag;
430 inline const VisibleSelection& Editor::mark() const
435 inline void Editor::setMark(const VisibleSelection& selection)
440 inline bool Editor::markedTextMatchesAreHighlighted() const
442 return m_areMarkedTextMatchesHighlighted;
446 } // namespace WebCore