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 "CorrectionPanelInfo.h"
32 #include "EditAction.h"
33 #include "EditingBehavior.h"
34 #include "EditorDeleteAction.h"
35 #include "EditorInsertAction.h"
36 #include "SelectionController.h"
38 #if PLATFORM(MAC) && !defined(__OBJC__)
40 typedef int NSWritingDirection;
45 class CSSStyleDeclaration;
47 class DeleteButtonController;
50 class EditorInternalCommand;
60 struct CompositionUnderline {
61 CompositionUnderline()
62 : startOffset(0), endOffset(0), thick(false) { }
63 CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t)
64 : startOffset(s), endOffset(e), color(c), thick(t) { }
71 enum TriState { FalseTriState, TrueTriState, MixedTriState };
72 enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
73 enum WritingDirection { NaturalWritingDirection, LeftToRightWritingDirection, RightToLeftWritingDirection };
80 EditorClient* client() const;
81 Frame* frame() const { return m_frame; }
82 DeleteButtonController* deleteButtonController() const { return m_deleteButtonController.get(); }
83 EditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
85 void handleKeyboardEvent(KeyboardEvent*);
86 void handleInputMethodKeydown(KeyboardEvent*);
87 bool handleTextEvent(TextEvent*);
90 bool canEditRichly() const;
100 bool canCopy() const;
101 bool canPaste() const;
102 bool canDelete() const;
103 bool canSmartCopyOrDelete();
108 void pasteAsPlainText();
109 void performDelete();
111 void copyURL(const KURL&, const String&);
112 void copyImage(const HitTestResult&);
118 bool shouldInsertFragment(PassRefPtr<DocumentFragment>, PassRefPtr<Range>, EditorInsertAction);
119 bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
120 bool shouldShowDeleteInterface(HTMLElement*) const;
121 bool shouldDeleteRange(Range*) const;
122 bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
124 void respondToChangedSelection(const VisibleSelection& oldSelection);
125 void respondToChangedContents(const VisibleSelection& endingSelection);
127 TriState selectionHasStyle(CSSStyleDeclaration*) const;
128 String selectionStartCSSPropertyValue(int propertyID);
129 const SimpleFontData* fontForSelection(bool&) const;
130 WritingDirection textDirectionForSelection(bool&) const;
132 TriState selectionUnorderedListState() const;
133 TriState selectionOrderedListState() const;
134 PassRefPtr<Node> insertOrderedList();
135 PassRefPtr<Node> insertUnorderedList();
136 bool canIncreaseSelectionListLevel();
137 bool canDecreaseSelectionListLevel();
138 PassRefPtr<Node> increaseSelectionListLevel();
139 PassRefPtr<Node> increaseSelectionListLevelOrdered();
140 PassRefPtr<Node> increaseSelectionListLevelUnordered();
141 void decreaseSelectionListLevel();
143 void removeFormattingAndStyle();
145 void clearLastEditCommand();
147 bool deleteWithDirection(SelectionController::EDirection, TextGranularity, bool killRing, bool isTypingAction);
148 void deleteSelectionWithSmartDelete(bool smartDelete);
149 bool dispatchCPPEvent(const AtomicString&, ClipboardAccessPolicy);
151 Node* removedAnchor() const { return m_removedAnchor.get(); }
152 void setRemovedAnchor(PassRefPtr<Node> n) { m_removedAnchor = n; }
154 void applyStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
155 void applyParagraphStyle(CSSStyleDeclaration*, EditAction = EditActionUnspecified);
156 void applyStyleToSelection(CSSStyleDeclaration*, EditAction);
157 void applyParagraphStyleToSelection(CSSStyleDeclaration*, EditAction);
159 void appliedEditing(PassRefPtr<EditCommand>);
160 void unappliedEditing(PassRefPtr<EditCommand>);
161 void reappliedEditing(PassRefPtr<EditCommand>);
163 bool selectionStartHasStyle(CSSStyleDeclaration*) const;
165 bool clientIsEditable() const;
167 void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
168 bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
173 Command(PassRefPtr<Frame>, const EditorInternalCommand*, EditorCommandSource);
175 bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
176 bool execute(Event* triggeringEvent) const;
178 bool isSupported() const;
179 bool isEnabled(Event* triggeringEvent = 0) const;
181 TriState state(Event* triggeringEvent = 0) const;
182 String value(Event* triggeringEvent = 0) const;
184 bool isTextInsertion() const;
187 RefPtr<Frame> m_frame;
188 const EditorInternalCommand* m_command;
189 EditorCommandSource m_source;
191 Command command(const String& commandName); // Default is CommandFromMenuOrKeyBinding.
192 Command command(const String& commandName, EditorCommandSource);
194 bool insertText(const String&, Event* triggeringEvent);
195 bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, Event* triggeringEvent);
196 bool insertLineBreak();
197 bool insertParagraphSeparator();
199 bool isContinuousSpellCheckingEnabled();
200 void toggleContinuousSpellChecking();
201 bool isGrammarCheckingEnabled();
202 void toggleGrammarChecking();
203 void ignoreSpelling();
204 void learnSpelling();
205 int spellCheckerDocumentTag();
206 bool isSelectionUngrammatical();
207 bool isSelectionMisspelled();
208 Vector<String> guessesForMisspelledSelection();
209 Vector<String> guessesForUngrammaticalSelection();
210 Vector<String> guessesForMisspelledOrUngrammaticalSelection(bool& misspelled, bool& ungrammatical);
211 bool isSpellCheckingEnabledInFocusedNode() const;
212 bool isSpellCheckingEnabledFor(Node*) const;
213 void markMisspellingsAfterTypingToPosition(const VisiblePosition&);
214 void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
215 void markBadGrammar(const VisibleSelection&);
216 void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
217 #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
218 void uppercaseWord();
219 void lowercaseWord();
220 void capitalizeWord();
221 void showSubstitutionsPanel();
222 bool substitutionsPanelIsShowing();
223 void toggleSmartInsertDelete();
224 bool isAutomaticQuoteSubstitutionEnabled();
225 void toggleAutomaticQuoteSubstitution();
226 bool isAutomaticLinkDetectionEnabled();
227 void toggleAutomaticLinkDetection();
228 bool isAutomaticDashSubstitutionEnabled();
229 void toggleAutomaticDashSubstitution();
230 bool isAutomaticTextReplacementEnabled();
231 void toggleAutomaticTextReplacement();
232 bool isAutomaticSpellingCorrectionEnabled();
233 void toggleAutomaticSpellingCorrection();
234 enum TextCheckingOptionFlags {
235 MarkSpelling = 1 << 0,
236 MarkGrammar = 1 << 1,
237 PerformReplacement = 1 << 2,
238 ShowCorrectionPanel = 1 << 3,
240 typedef unsigned TextCheckingOptions;
242 void markAllMisspellingsAndBadGrammarInRanges(TextCheckingOptions, Range* spellingRange, Range* grammarRange);
243 void changeBackToReplacedString(const String& replacedString);
245 void advanceToNextMisspelling(bool startBeforeSelection = false);
246 void showSpellingGuessPanel();
247 bool spellingPanelIsShowing();
249 bool shouldBeginEditing(Range*);
250 bool shouldEndEditing(Range*);
252 void clearUndoRedoOperations();
258 void didBeginEditing();
259 void didEndEditing();
260 void didWriteSelectionToPasteboard();
262 void showFontPanel();
263 void showStylesPanel();
264 void showColorPanel();
266 void toggleUnderline();
267 void setBaseWritingDirection(WritingDirection);
269 // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are
270 // mutually exclusive, meaning that enabling one will disable the other.
271 bool smartInsertDeleteEnabled();
272 bool isSelectTrailingWhitespaceEnabled();
274 bool hasBidiSelection() const;
276 // international text input composition
277 bool hasComposition() const { return m_compositionNode; }
278 void setComposition(const String&, const Vector<CompositionUnderline>&, unsigned selectionStart, unsigned selectionEnd);
279 void confirmComposition();
280 void confirmComposition(const String&); // if no existing composition, replaces selection
281 void confirmCompositionWithoutDisturbingSelection();
282 PassRefPtr<Range> compositionRange() const;
283 bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
285 // getting international text input composition state (for use by InlineTextBox)
286 Text* compositionNode() const { return m_compositionNode.get(); }
287 unsigned compositionStart() const { return m_compositionStart; }
288 unsigned compositionEnd() const { return m_compositionEnd; }
289 bool compositionUsesCustomUnderlines() const { return !m_customCompositionUnderlines.isEmpty(); }
290 const Vector<CompositionUnderline>& customCompositionUnderlines() const { return m_customCompositionUnderlines; }
292 bool ignoreCompositionSelectionChange() const { return m_ignoreCompositionSelectionChange; }
294 void setStartNewKillRingSequence(bool);
296 PassRefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
300 VisibleSelection selectionForCommand(Event*);
302 KillRing* killRing() const { return m_killRing.get(); }
304 EditingBehavior behavior() const;
306 PassRefPtr<Range> selectedRange();
308 // We should make these functions private when their callers in Frame are moved over here to Editor
309 bool insideVisibleArea(const IntPoint&) const;
310 bool insideVisibleArea(Range*) const;
311 PassRefPtr<Range> nextVisibleRange(Range*, const String&, bool forward, bool caseFlag, bool wrapFlag);
313 void addToKillRing(Range*, bool prepend);
315 void handleCancelOperation();
316 void startCorrectionPanelTimer(CorrectionPanelInfo::PanelType);
317 void handleRejectedCorrection();
318 bool isShowingCorrectionPanel();
320 void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
321 void pasteAsPlainText(const String&, bool smartReplace);
323 // This is only called on the mac where paste is implemented primarily at the WebKit level.
324 void pasteAsPlainTextBypassingDHTML();
326 void clearMisspellingsAndBadGrammar(const VisibleSelection&);
327 void markMisspellingsAndBadGrammar(const VisibleSelection&);
329 Node* findEventTargetFrom(const VisibleSelection& selection) const;
331 String selectedText() const;
332 bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
334 const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
335 void setMark(const VisibleSelection&);
337 void computeAndSetTypingStyle(CSSStyleDeclaration* , EditAction = EditActionUnspecified);
338 void applyEditingStyleToBodyElement() const;
339 void applyEditingStyleToElement(Element*) const;
341 IntRect firstRectForRange(Range*) const;
343 void respondToChangedSelection(const VisibleSelection& oldSelection, bool closeTyping);
344 bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
346 RenderStyle* styleForSelectionStart(Node*& nodeToRemove) const;
348 unsigned countMatchesForText(const String&, bool caseFlag, unsigned limit, bool markMatches);
349 bool markedTextMatchesAreHighlighted() const;
350 void setMarkedTextMatchesAreHighlighted(bool);
352 PassRefPtr<CSSMutableStyleDeclaration> selectionComputedStyle(bool& shouldUseFixedFontDefaultSize) const;
354 void textFieldDidBeginEditing(Element*);
355 void textFieldDidEndEditing(Element*);
356 void textDidChangeInTextField(Element*);
357 bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
358 void textWillBeDeletedInTextField(Element* input);
359 void textDidChangeInTextArea(Element*);
362 NSDictionary* fontAttributesForSelectionStart() const;
363 NSWritingDirection baseWritingDirectionForSelectionStart() const;
366 bool selectionStartHasSpellingMarkerFor(int from, int length) const;
367 void removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemoveIfSelectionAtWordBoundary);
371 OwnPtr<DeleteButtonController> m_deleteButtonController;
372 RefPtr<EditCommand> m_lastEditCommand;
373 RefPtr<Node> m_removedAnchor;
374 RefPtr<Text> m_compositionNode;
375 unsigned m_compositionStart;
376 unsigned m_compositionEnd;
377 Vector<CompositionUnderline> m_customCompositionUnderlines;
378 bool m_ignoreCompositionSelectionChange;
379 bool m_shouldStartNewKillRingSequence;
380 bool m_shouldStyleWithCSS;
381 OwnPtr<KillRing> m_killRing;
382 CorrectionPanelInfo m_correctionPanelInfo;
383 Timer<Editor> m_correctionPanelTimer;
384 VisibleSelection m_mark;
385 bool m_areMarkedTextMatchesHighlighted;
387 bool canDeleteRange(Range*) const;
388 bool canSmartReplaceWithPasteboard(Pasteboard*);
389 PassRefPtr<Clipboard> newGeneralClipboard(ClipboardAccessPolicy, Frame*);
390 void pasteAsPlainTextWithPasteboard(Pasteboard*);
391 void pasteWithPasteboard(Pasteboard*, bool allowPlainText);
392 void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
393 void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
394 void writeSelectionToPasteboard(Pasteboard*);
395 void revealSelectionAfterEditingOperation();
396 void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
398 void selectComposition();
399 void confirmComposition(const String&, bool preserveSelection);
400 void setIgnoreCompositionSelectionChange(bool ignore);
402 PassRefPtr<Range> firstVisibleRange(const String&, bool caseFlag);
403 PassRefPtr<Range> lastVisibleRange(const String&, bool caseFlag);
405 void changeSelectionAfterCommand(const VisibleSelection& newSelection, bool closeTyping, bool clearTypingStyle);
406 void correctionPanelTimerFired(Timer<Editor>*);
407 Node* findEventTargetFromSelection() const;
408 void stopCorrectionPanelTimer();
409 void dismissCorrectionPanel(CorrectionWasRejectedOrNot);
410 void applyCorrectionPanelInfo(bool addCorrectionIndicatorMarker);
413 inline void Editor::setStartNewKillRingSequence(bool flag)
415 m_shouldStartNewKillRingSequence = flag;
418 inline const VisibleSelection& Editor::mark() const
423 inline void Editor::setMark(const VisibleSelection& selection)
428 inline bool Editor::markedTextMatchesAreHighlighted() const
430 return m_areMarkedTextMatchesHighlighted;
434 } // namespace WebCore