Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp

Issue 2558643003: [InputEvent] Move 'beforeinput' logic into |CompositeEditCommand::willApplyEditing()| (3/3) (Closed)
Patch Set: Rebase on EditCommandSource and willApply() CLs Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 #include "core/html/HTMLQuoteElement.h" 70 #include "core/html/HTMLQuoteElement.h"
71 #include "core/html/HTMLSpanElement.h" 71 #include "core/html/HTMLSpanElement.h"
72 #include "core/layout/LayoutBlock.h" 72 #include "core/layout/LayoutBlock.h"
73 #include "core/layout/LayoutListItem.h" 73 #include "core/layout/LayoutListItem.h"
74 #include "core/layout/LayoutText.h" 74 #include "core/layout/LayoutText.h"
75 #include "core/layout/line/InlineTextBox.h" 75 #include "core/layout/line/InlineTextBox.h"
76 #include <algorithm> 76 #include <algorithm>
77 77
78 namespace blink { 78 namespace blink {
79 79
80 namespace {
81
82 bool dispatchBeforeInputEvent(EditCommandSource source,
83 LocalFrame* frame,
84 Node* target,
85 InputEvent::InputType inputType,
86 const String& data,
87 DataTransfer* dataTransfer,
88 InputEvent::EventCancelable isCancelable,
89 InputEvent::EventIsComposing isComposing,
90 const RangeVector* ranges) {
91 // Don't fire 'beforeinput', return true to continue.
92 if (source != EditCommandSource::kMenuOrKeyBinding ||
93 inputType == InputEvent::InputType::None)
94 return true;
95 if (!RuntimeEnabledFeatures::inputEventEnabled())
96 return true;
97 if (!frame || !target || !target->isConnected())
98 return true;
99
100 if (!hasRichlyEditableStyle(*target)) {
101 // Plain-text only elements (<input>, <textarea>, etc.) don't support
102 // DataTransfer or Range.
103 dataTransfer = nullptr;
104 ranges = nullptr;
105 }
106
107 InputEvent* beforeInputEvent;
108
109 if (dataTransfer) {
110 beforeInputEvent = InputEvent::createBeforeInput(
111 inputType, dataTransfer, isCancelable, isComposing, ranges);
112 } else {
113 beforeInputEvent = InputEvent::createBeforeInput(
114 inputType, data, isCancelable, isComposing, ranges);
115 }
116
117 DispatchEventResult result = target->dispatchEvent(beforeInputEvent);
118 // 'beforeinput' event handler may destroy target frame.
119 if (frame->document()->frame() != frame)
120 return false;
121 return result == DispatchEventResult::NotCanceled;
122 }
123
124 } // anonymous namespace
125
80 using namespace HTMLNames; 126 using namespace HTMLNames;
81 127
82 EditCommandComposition* EditCommandComposition::create( 128 EditCommandComposition* EditCommandComposition::create(
83 Document* document, 129 Document* document,
84 const VisibleSelection& startingSelection, 130 const VisibleSelection& startingSelection,
85 const VisibleSelection& endingSelection, 131 const VisibleSelection& endingSelection) {
86 InputEvent::InputType inputType) {
87 return new EditCommandComposition(document, startingSelection, 132 return new EditCommandComposition(document, startingSelection,
88 endingSelection, inputType); 133 endingSelection);
89 } 134 }
90 135
91 EditCommandComposition::EditCommandComposition( 136 EditCommandComposition::EditCommandComposition(
92 Document* document, 137 Document* document,
93 const VisibleSelection& startingSelection, 138 const VisibleSelection& startingSelection,
94 const VisibleSelection& endingSelection, 139 const VisibleSelection& endingSelection)
95 InputEvent::InputType inputType)
96 : m_document(document), 140 : m_document(document),
97 m_startingSelection(startingSelection), 141 m_startingSelection(startingSelection),
98 m_endingSelection(endingSelection), 142 m_endingSelection(endingSelection),
99 m_startingRootEditableElement(startingSelection.rootEditableElement()), 143 m_startingRootEditableElement(startingSelection.rootEditableElement()),
100 m_endingRootEditableElement(endingSelection.rootEditableElement()), 144 m_endingRootEditableElement(endingSelection.rootEditableElement()) {}
101 m_inputType(inputType) {}
102 145
103 bool EditCommandComposition::belongsTo(const LocalFrame& frame) const { 146 bool EditCommandComposition::belongsTo(const LocalFrame& frame) const {
104 DCHECK(m_document); 147 DCHECK(m_document);
105 return m_document->frame() == &frame; 148 return m_document->frame() == &frame;
106 } 149 }
107 150
108 void EditCommandComposition::unapply(EditCommandSource source) { 151 void EditCommandComposition::unapply(EditCommandSource source) {
109 DCHECK(m_document); 152 DCHECK(m_document);
110 LocalFrame* frame = m_document->frame(); 153 LocalFrame* frame = m_document->frame();
111 DCHECK(frame); 154 DCHECK(frame);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 m_document->updateStyleAndLayoutIgnorePendingStylesheets(); 188 m_document->updateStyleAndLayoutIgnorePendingStylesheets();
146 189
147 { 190 {
148 for (const auto& command : m_commands) 191 for (const auto& command : m_commands)
149 command->doReapply(); 192 command->doReapply();
150 } 193 }
151 194
152 frame->editor().reappliedEditing(this); 195 frame->editor().reappliedEditing(this);
153 } 196 }
154 197
155 bool EditCommandComposition::willUnapply(EditCommandSource) { 198 bool EditCommandComposition::willUnapply(EditCommandSource source) {
156 // TODO(chongz): Fire 'beforeinput' for 'historyUndo'. 199 return dispatchBeforeInputEvent(source, m_document->frame(), m_document,
157 return true; 200 InputEvent::InputType::HistoryUndo, nullAtom,
201 nullptr, InputEvent::IsCancelable,
202 InputEvent::NotComposing, nullptr);
158 } 203 }
159 204
160 bool EditCommandComposition::willReapply(EditCommandSource) { 205 bool EditCommandComposition::willReapply(EditCommandSource source) {
161 // TODO(chongz): Fire 'beforeinput' for 'historyRedo'. 206 return dispatchBeforeInputEvent(source, m_document->frame(), m_document,
162 return true; 207 InputEvent::InputType::HistoryRedo, nullAtom,
163 } 208 nullptr, InputEvent::IsCancelable,
164 209 InputEvent::NotComposing, nullptr);
165 InputEvent::InputType EditCommandComposition::inputType() const {
166 return m_inputType;
167 } 210 }
168 211
169 void EditCommandComposition::append(SimpleEditCommand* command) { 212 void EditCommandComposition::append(SimpleEditCommand* command) {
170 m_commands.push_back(command); 213 m_commands.push_back(command);
171 } 214 }
172 215
173 void EditCommandComposition::append(EditCommandComposition* composition) { 216 void EditCommandComposition::append(EditCommandComposition* composition) {
174 m_commands.appendVector(composition->m_commands); 217 m_commands.appendVector(composition->m_commands);
175 } 218 }
176 219
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 case InputEvent::InputType::DeleteByDrag: 268 case InputEvent::InputType::DeleteByDrag:
226 case InputEvent::InputType::None: 269 case InputEvent::InputType::None:
227 break; 270 break;
228 default: 271 default:
229 NOTREACHED(); 272 NOTREACHED();
230 return false; 273 return false;
231 } 274 }
232 } 275 }
233 ensureComposition(); 276 ensureComposition();
234 277
278 // Covers the initial TypingCommand and other top-level commands.
279 // TypingCommand::willAddTypingToOpenCommand() also calls willApplyEditing().
280 if (!willApplyEditing(source))
281 return false;
282
235 // Changes to the document may have been made since the last editing operation 283 // Changes to the document may have been made since the last editing operation
236 // that require a layout, as in <rdar://problem/5658603>. Low level 284 // that require a layout, as in <rdar://problem/5658603>. Low level
237 // operations, like RemoveNodeCommand, don't require a layout because the high 285 // operations, like RemoveNodeCommand, don't require a layout because the high
238 // level operations that use them perform one if one is necessary (like for 286 // level operations that use them perform one if one is necessary (like for
239 // the creation of VisiblePositions). 287 // the creation of VisiblePositions).
240 document().updateStyleAndLayoutIgnorePendingStylesheets(); 288 document().updateStyleAndLayoutIgnorePendingStylesheets();
241 289
242 if (!willApplyEditing(source))
243 return false;
244
245 LocalFrame* frame = document().frame(); 290 LocalFrame* frame = document().frame();
246 DCHECK(frame); 291 DCHECK(frame);
247 EditingState editingState; 292 EditingState editingState;
248 { 293 {
249 EventQueueScope eventQueueScope; 294 EventQueueScope eventQueueScope;
250 doApply(&editingState); 295 doApply(&editingState);
251 } 296 }
252 297
253 // Only need to call appliedEditing for top-level commands, and TypingCommands 298 // Only need to call appliedEditing for top-level commands, and TypingCommands
254 // do it on their own (see TypingCommand::typingAddedToOpenCommand). 299 // do it on their own (see TypingCommand::typingAddedToOpenCommand).
255 if (!isTypingCommand()) 300 if (!isTypingCommand())
256 frame->editor().appliedEditing(this); 301 frame->editor().appliedEditing(this);
257 setShouldRetainAutocorrectionIndicator(false); 302 setShouldRetainAutocorrectionIndicator(false);
258 return !editingState.isAborted(); 303 return !editingState.isAborted();
259 } 304 }
260 305
261 EditCommandComposition* CompositeEditCommand::ensureComposition() { 306 EditCommandComposition* CompositeEditCommand::ensureComposition() {
262 CompositeEditCommand* command = this; 307 CompositeEditCommand* command = this;
263 while (command && command->parent()) 308 while (command && command->parent())
264 command = command->parent(); 309 command = command->parent();
265 if (!command->m_composition) 310 if (!command->m_composition) {
266 command->m_composition = EditCommandComposition::create( 311 command->m_composition = EditCommandComposition::create(
267 &document(), startingSelection(), endingSelection(), inputType()); 312 &document(), startingSelection(), endingSelection());
313 }
268 return command->m_composition.get(); 314 return command->m_composition.get();
269 } 315 }
270 316
271 bool CompositeEditCommand::willApplyEditing(EditCommandSource) { 317 bool CompositeEditCommand::willApplyEditing(EditCommandSource source) {
272 // TODO(chongz): Move all the 'beforeinput' dispatching logic here. 318 return dispatchBeforeInputEvent(
273 return true; 319 source, document().frame(), eventTargetNodeForDocument(&document()),
320 inputType(), textDataForInputEvent(), dataTransferForInputEvent(),
321 isCancelableFromCommand(this), isComposingFromCommand(this),
322 targetRangesForInputEvent());
323 }
324
325 InputEvent::InputType CompositeEditCommand::inputType() const {
326 return InputEvent::InputType::None;
327 }
328
329 String CompositeEditCommand::textDataForInputEvent() const {
330 return nullAtom;
331 }
332
333 DataTransfer* CompositeEditCommand::dataTransferForInputEvent() const {
334 return nullptr;
335 }
336
337 RangeVector* CompositeEditCommand::targetRangesForInputEvent() const {
338 if (!document().frame()->editor().canEditRichly())
339 return nullptr;
340 return new RangeVector(1, document().frame()->selection().firstRange());
274 } 341 }
275 342
276 bool CompositeEditCommand::preservesTypingStyle() const { 343 bool CompositeEditCommand::preservesTypingStyle() const {
277 return false; 344 return false;
278 } 345 }
279 346
280 bool CompositeEditCommand::isTypingCommand() const { 347 bool CompositeEditCommand::isTypingCommand() const {
281 return false; 348 return false;
282 } 349 }
283 350
(...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 return node; 2120 return node;
2054 } 2121 }
2055 2122
2056 DEFINE_TRACE(CompositeEditCommand) { 2123 DEFINE_TRACE(CompositeEditCommand) {
2057 visitor->trace(m_commands); 2124 visitor->trace(m_commands);
2058 visitor->trace(m_composition); 2125 visitor->trace(m_composition);
2059 EditCommand::trace(visitor); 2126 EditCommand::trace(visitor);
2060 } 2127 }
2061 2128
2062 } // namespace blink 2129 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698