1/*
2 * Copyright (C) 2005, 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 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 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#pragma once
27
28#include "TextInsertionBaseCommand.h"
29
30namespace WebCore {
31
32class TypingCommand final : public TextInsertionBaseCommand {
33public:
34 enum ETypingCommand {
35 DeleteSelection,
36 DeleteKey,
37 ForwardDeleteKey,
38 InsertText,
39 InsertLineBreak,
40 InsertParagraphSeparator,
41 InsertParagraphSeparatorInQuotedContent
42 };
43
44 enum TextCompositionType {
45 TextCompositionNone,
46 TextCompositionPending,
47 TextCompositionFinal,
48 };
49
50 enum Option {
51 SelectInsertedText = 1 << 0,
52 AddsToKillRing = 1 << 1,
53 RetainAutocorrectionIndicator = 1 << 2,
54 PreventSpellChecking = 1 << 3,
55 SmartDelete = 1 << 4,
56 IsAutocompletion = 1 << 5,
57 };
58 typedef unsigned Options;
59
60 static void deleteSelection(Document&, Options = 0, TextCompositionType = TextCompositionNone);
61 static void deleteKeyPressed(Document&, Options = 0, TextGranularity = CharacterGranularity);
62 static void forwardDeleteKeyPressed(Document&, Options = 0, TextGranularity = CharacterGranularity);
63 static void insertText(Document&, const String&, Options, TextCompositionType = TextCompositionNone);
64 static void insertText(Document&, const String&, const VisibleSelection&, Options, TextCompositionType = TextCompositionNone);
65 static void insertLineBreak(Document&, Options);
66 static void insertParagraphSeparator(Document&, Options);
67 static void insertParagraphSeparatorInQuotedContent(Document&);
68 static void closeTyping(Frame*);
69#if PLATFORM(IOS_FAMILY)
70 static void ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping(Frame*, const VisibleSelection&);
71#endif
72
73 void insertText(const String &text, bool selectInsertedText);
74 void insertTextRunWithoutNewlines(const String &text, bool selectInsertedText);
75 void insertLineBreak();
76 void insertParagraphSeparatorInQuotedContent();
77 void insertParagraphSeparator();
78 void deleteKeyPressed(TextGranularity, bool shouldAddToKillRing);
79 void forwardDeleteKeyPressed(TextGranularity, bool shouldAddToKillRing);
80 void deleteSelection(bool smartDelete);
81 void setCompositionType(TextCompositionType type) { m_compositionType = type; }
82 void setIsAutocompletion(bool isAutocompletion) { m_isAutocompletion = isAutocompletion; }
83
84#if PLATFORM(IOS_FAMILY)
85 void setEndingSelectionOnLastInsertCommand(const VisibleSelection& selection);
86#endif
87
88private:
89 static Ref<TypingCommand> create(Document& document, ETypingCommand command, const String& text = emptyString(), Options options = 0, TextGranularity granularity = CharacterGranularity, TextCompositionType compositionType = TextCompositionNone)
90 {
91 return adoptRef(*new TypingCommand(document, command, text, options, granularity, compositionType));
92 }
93
94 static Ref<TypingCommand> create(Document& document, ETypingCommand command, const String& text, Options options, TextCompositionType compositionType)
95 {
96 return adoptRef(*new TypingCommand(document, command, text, options, CharacterGranularity, compositionType));
97 }
98
99 TypingCommand(Document&, ETypingCommand, const String& text, Options, TextGranularity, TextCompositionType);
100
101 bool smartDelete() const { return m_smartDelete; }
102 void setSmartDelete(bool smartDelete) { m_smartDelete = smartDelete; }
103 bool isOpenForMoreTyping() const { return m_openForMoreTyping; }
104 void closeTyping() { m_openForMoreTyping = false; }
105
106 static RefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame&);
107
108 void doApply() final;
109 bool isTypingCommand() const final;
110 bool preservesTypingStyle() const final { return m_preservesTypingStyle; }
111 bool shouldRetainAutocorrectionIndicator() const final
112 {
113 ASSERT(isTopLevelCommand());
114 return m_shouldRetainAutocorrectionIndicator;
115 }
116 void setShouldRetainAutocorrectionIndicator(bool retain) final { m_shouldRetainAutocorrectionIndicator = retain; }
117 bool shouldStopCaretBlinking() const final { return true; }
118 void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
119
120 String inputEventTypeName() const final;
121 String inputEventData() const final;
122 RefPtr<DataTransfer> inputEventDataTransfer() const final;
123 bool isBeforeInputEventCancelable() const final;
124
125 static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
126
127 void updatePreservesTypingStyle(ETypingCommand);
128 bool willAddTypingToOpenCommand(ETypingCommand, TextGranularity, const String& = emptyString(), RefPtr<Range>&& = nullptr);
129 void markMisspellingsAfterTyping(ETypingCommand);
130 void typingAddedToOpenCommand(ETypingCommand);
131 bool makeEditableRootEmpty();
132
133 void postTextStateChangeNotificationForDeletion(const VisibleSelection&);
134 void insertTextAndNotifyAccessibility(const String &text, bool selectInsertedText);
135 void insertLineBreakAndNotifyAccessibility();
136 void insertParagraphSeparatorInQuotedContentAndNotifyAccessibility();
137 void insertParagraphSeparatorAndNotifyAccessibility();
138
139 bool willApplyCommand() final;
140 void didApplyCommand() final;
141
142 bool shouldDeferWillApplyCommandUntilAddingTypingCommand() const;
143
144 ETypingCommand m_commandType;
145 EditAction m_currentTypingEditAction;
146 String m_textToInsert;
147 String m_currentTextToInsert;
148 bool m_openForMoreTyping;
149 bool m_selectInsertedText;
150 bool m_smartDelete;
151 bool m_isHandlingInitialTypingCommand { true };
152 TextGranularity m_granularity;
153 TextCompositionType m_compositionType;
154 bool m_shouldAddToKillRing;
155 bool m_preservesTypingStyle;
156 bool m_isAutocompletion;
157
158 // Undoing a series of backward deletes will restore a selection around all of the
159 // characters that were deleted, but only if the typing command being undone
160 // was opened with a backward delete.
161 bool m_openedByBackwardDelete;
162
163 bool m_shouldRetainAutocorrectionIndicator;
164 bool m_shouldPreventSpellChecking;
165};
166
167} // namespace WebCore
168