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

Side by Side Diff: Source/core/editing/EditorCommand.cpp

Issue 1294543005: Move execCommand related files in core/editing/ related files into core/editing/commands/ (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 2015-08-17T17:57:33 Created 5 years, 4 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
(Empty)
1 /*
2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2009 Igalia S.L.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "config.h"
29 #include "core/editing/Editor.h"
30
31 #include "bindings/core/v8/ExceptionState.h"
32 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
33 #include "core/CSSPropertyNames.h"
34 #include "core/CSSValueKeywords.h"
35 #include "core/HTMLNames.h"
36 #include "core/clipboard/Pasteboard.h"
37 #include "core/css/CSSValueList.h"
38 #include "core/css/StylePropertySet.h"
39 #include "core/dom/DocumentFragment.h"
40 #include "core/editing/CreateLinkCommand.h"
41 #include "core/editing/EditingUtilities.h"
42 #include "core/editing/FormatBlockCommand.h"
43 #include "core/editing/FrameSelection.h"
44 #include "core/editing/IndentOutdentCommand.h"
45 #include "core/editing/InsertListCommand.h"
46 #include "core/editing/ReplaceSelectionCommand.h"
47 #include "core/editing/TypingCommand.h"
48 #include "core/editing/UnlinkCommand.h"
49 #include "core/editing/serializers/Serialization.h"
50 #include "core/editing/spellcheck/SpellChecker.h"
51 #include "core/events/Event.h"
52 #include "core/frame/FrameHost.h"
53 #include "core/frame/FrameView.h"
54 #include "core/frame/LocalFrame.h"
55 #include "core/frame/Settings.h"
56 #include "core/html/HTMLFontElement.h"
57 #include "core/html/HTMLHRElement.h"
58 #include "core/html/HTMLImageElement.h"
59 #include "core/input/EventHandler.h"
60 #include "core/layout/LayoutBox.h"
61 #include "core/page/ChromeClient.h"
62 #include "core/page/EditorClient.h"
63 #include "platform/KillRing.h"
64 #include "platform/UserGestureIndicator.h"
65 #include "platform/scroll/Scrollbar.h"
66 #include "public/platform/Platform.h"
67 #include "wtf/text/AtomicString.h"
68
69 namespace blink {
70
71 using namespace HTMLNames;
72
73 class EditorInternalCommand {
74 public:
75 int idForUserMetrics;
76 bool (*execute)(LocalFrame&, Event*, EditorCommandSource, const String&);
77 bool (*isSupportedFromDOM)(LocalFrame*);
78 bool (*isEnabled)(LocalFrame&, Event*, EditorCommandSource);
79 TriState (*state)(LocalFrame&, Event*);
80 String (*value)(LocalFrame&, Event*);
81 bool isTextInsertion;
82 bool allowExecutionWhenDisabled;
83 };
84
85 typedef HashMap<String, const EditorInternalCommand*, CaseFoldingHash> CommandMa p;
86
87 static const bool notTextInsertion = false;
88 static const bool isTextInsertion = true;
89
90 static const bool allowExecutionWhenDisabled = true;
91 static const bool doNotAllowExecutionWhenDisabled = false;
92
93 // Related to Editor::selectionForCommand.
94 // Certain operations continue to use the target control's selection even if the event handler
95 // already moved the selection outside of the text control.
96 static LocalFrame* targetFrame(LocalFrame& frame, Event* event)
97 {
98 if (!event)
99 return &frame;
100 Node* node = event->target()->toNode();
101 if (!node)
102 return &frame;
103 return node->document().frame();
104 }
105
106 static bool applyCommandToFrame(LocalFrame& frame, EditorCommandSource source, E ditAction action, StylePropertySet* style)
107 {
108 // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that?
109 switch (source) {
110 case CommandFromMenuOrKeyBinding:
111 frame.editor().applyStyleToSelection(style, action);
112 return true;
113 case CommandFromDOM:
114 frame.editor().applyStyle(style);
115 return true;
116 }
117 ASSERT_NOT_REACHED();
118 return false;
119 }
120
121 static bool executeApplyStyle(LocalFrame& frame, EditorCommandSource source, Edi tAction action, CSSPropertyID propertyID, const String& propertyValue)
122 {
123 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet: :create();
124 style->setProperty(propertyID, propertyValue);
125 return applyCommandToFrame(frame, source, action, style.get());
126 }
127
128 static bool executeApplyStyle(LocalFrame& frame, EditorCommandSource source, Edi tAction action, CSSPropertyID propertyID, CSSValueID propertyValue)
129 {
130 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet: :create();
131 style->setProperty(propertyID, propertyValue);
132 return applyCommandToFrame(frame, source, action, style.get());
133 }
134
135 // FIXME: executeToggleStyleInList does not handle complicated cases such as <b> <u>hello</u>world</b> properly.
136 // This function must use Editor::selectionHasStyle to determine the curr ent style but we cannot fix this
137 // until https://bugs.webkit.org/show_bug.cgi?id=27818 is resolved.
138 static bool executeToggleStyleInList(LocalFrame& frame, EditorCommandSource sour ce, EditAction action, CSSPropertyID propertyID, CSSValue* value)
139 {
140 RefPtrWillBeRawPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelec tionStart(frame.selection().selection());
141 if (!selectionStyle || !selectionStyle->style())
142 return false;
143
144 RefPtrWillBeRawPtr<CSSValue> selectedCSSValue = selectionStyle->style()->get PropertyCSSValue(propertyID);
145 String newStyle("none");
146 if (selectedCSSValue->isValueList()) {
147 RefPtrWillBeRawPtr<CSSValueList> selectedCSSValueList = toCSSValueList(s electedCSSValue.get());
148 if (!selectedCSSValueList->removeAll(value))
149 selectedCSSValueList->append(value);
150 if (selectedCSSValueList->length())
151 newStyle = selectedCSSValueList->cssText();
152
153 } else if (selectedCSSValue->cssText() == "none")
154 newStyle = value->cssText();
155
156 // FIXME: We shouldn't be having to convert new style into text. We should have setPropertyCSSValue.
157 RefPtrWillBeRawPtr<MutableStylePropertySet> newMutableStyle = MutableStylePr opertySet::create();
158 newMutableStyle->setProperty(propertyID, newStyle);
159 return applyCommandToFrame(frame, source, action, newMutableStyle.get());
160 }
161
162 static bool executeToggleStyle(LocalFrame& frame, EditorCommandSource source, Ed itAction action, CSSPropertyID propertyID, const char* offValue, const char* onV alue)
163 {
164 // Style is considered present when
165 // Mac: present at the beginning of selection
166 // other: present throughout the selection
167
168 bool styleIsPresent;
169 if (frame.editor().behavior().shouldToggleStyleBasedOnStartOfSelection())
170 styleIsPresent = frame.editor().selectionStartHasStyle(propertyID, onVal ue);
171 else
172 styleIsPresent = frame.editor().selectionHasStyle(propertyID, onValue) = = TrueTriState;
173
174 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(propertyID, st yleIsPresent ? offValue : onValue);
175 return applyCommandToFrame(frame, source, action, style->style());
176 }
177
178 static bool executeApplyParagraphStyle(LocalFrame& frame, EditorCommandSource so urce, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
179 {
180 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet: :create();
181 style->setProperty(propertyID, propertyValue);
182 // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that?
183 switch (source) {
184 case CommandFromMenuOrKeyBinding:
185 frame.editor().applyParagraphStyleToSelection(style.get(), action);
186 return true;
187 case CommandFromDOM:
188 frame.editor().applyParagraphStyle(style.get());
189 return true;
190 }
191 ASSERT_NOT_REACHED();
192 return false;
193 }
194
195 static bool executeInsertFragment(LocalFrame& frame, PassRefPtrWillBeRawPtr<Docu mentFragment> fragment)
196 {
197 ASSERT(frame.document());
198 ReplaceSelectionCommand::create(*frame.document(), fragment, ReplaceSelectio nCommand::PreventNesting, EditActionUnspecified)->apply();
199 return true;
200 }
201
202 static bool executeInsertElement(LocalFrame& frame, PassRefPtrWillBeRawPtr<HTMLE lement> content)
203 {
204 ASSERT(frame.document());
205 RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(*fr ame.document());
206 TrackExceptionState exceptionState;
207 fragment->appendChild(content, exceptionState);
208 if (exceptionState.hadException())
209 return false;
210 return executeInsertFragment(frame, fragment.release());
211 }
212
213 static bool expandSelectionToGranularity(LocalFrame& frame, TextGranularity gran ularity)
214 {
215 VisibleSelection selection = frame.selection().selection();
216 selection.expandUsingGranularity(granularity);
217 const EphemeralRange newRange = selection.toNormalizedEphemeralRange();
218 if (newRange.isNull())
219 return false;
220 if (newRange.isCollapsed())
221 return false;
222 EAffinity affinity = frame.selection().affinity();
223 frame.selection().setSelectedRange(newRange, affinity, FrameSelection::NonDi rectional, FrameSelection::CloseTyping);
224 return true;
225 }
226
227 static TriState selectionListState(const FrameSelection& selection, const Qualif iedName& tagName)
228 {
229 if (selection.isCaret()) {
230 if (enclosingElementWithTag(selection.selection().start(), tagName))
231 return TrueTriState;
232 } else if (selection.isRange()) {
233 Element* startElement = enclosingElementWithTag(selection.selection().st art(), tagName);
234 Element* endElement = enclosingElementWithTag(selection.selection().end( ), tagName);
235 if (startElement && endElement && startElement == endElement)
236 return TrueTriState;
237 }
238
239 return FalseTriState;
240 }
241
242 static TriState stateStyle(LocalFrame& frame, CSSPropertyID propertyID, const ch ar* desiredValue)
243 {
244 if (frame.editor().behavior().shouldToggleStyleBasedOnStartOfSelection())
245 return frame.editor().selectionStartHasStyle(propertyID, desiredValue) ? TrueTriState : FalseTriState;
246 return frame.editor().selectionHasStyle(propertyID, desiredValue);
247 }
248
249 static String valueStyle(LocalFrame& frame, CSSPropertyID propertyID)
250 {
251 // FIXME: Rather than retrieving the style at the start of the current selec tion,
252 // we should retrieve the style present throughout the selection for non-Mac platforms.
253 return frame.editor().selectionStartCSSPropertyValue(propertyID);
254 }
255
256 static TriState stateTextWritingDirection(LocalFrame& frame, WritingDirection di rection)
257 {
258 bool hasNestedOrMultipleEmbeddings;
259 WritingDirection selectionDirection = EditingStyle::textDirectionForSelectio n(frame.selection().selection(),
260 frame.selection().typingStyle(), hasNestedOrMultipleEmbeddings);
261 // FXIME: We should be returning MixedTriState when selectionDirection == di rection && hasNestedOrMultipleEmbeddings
262 return (selectionDirection == direction && !hasNestedOrMultipleEmbeddings) ? TrueTriState : FalseTriState;
263 }
264
265 static unsigned verticalScrollDistance(LocalFrame& frame)
266 {
267 Element* focusedElement = frame.document()->focusedElement();
268 if (!focusedElement)
269 return 0;
270 LayoutObject* layoutObject = focusedElement->layoutObject();
271 if (!layoutObject || !layoutObject->isBox())
272 return 0;
273 LayoutBox& layoutBox = toLayoutBox(*layoutObject);
274 const ComputedStyle* style = layoutBox.style();
275 if (!style)
276 return 0;
277 if (!(style->overflowY() == OSCROLL || style->overflowY() == OAUTO || focuse dElement->hasEditableStyle()))
278 return 0;
279 int height = std::min<int>(layoutBox.clientHeight(), frame.view()->visibleHe ight());
280 return static_cast<unsigned>(max(max<int>(height * ScrollableArea::minFracti onToStepWhenPaging(), height - ScrollableArea::maxOverlapBetweenPages()), 1));
281 }
282
283 static EphemeralRange unionEphemeralRanges(const EphemeralRange& range1, const E phemeralRange& range2)
284 {
285 const Position startPosition = range1.startPosition().compareTo(range2.start Position()) <= 0 ? range1.startPosition() : range2.startPosition();
286 const Position endPosition = range1.endPosition().compareTo(range2.endPositi on()) <= 0 ? range1.endPosition() : range2.endPosition();
287 return EphemeralRange(startPosition, endPosition);
288 }
289
290 // Execute command functions
291
292 static bool executeBackColor(LocalFrame& frame, Event*, EditorCommandSource sour ce, const String& value)
293 {
294 return executeApplyStyle(frame, source, EditActionSetBackgroundColor, CSSPro pertyBackgroundColor, value);
295 }
296
297 static bool executeCopy(LocalFrame& frame, Event*, EditorCommandSource, const St ring&)
298 {
299 frame.editor().copy();
300 return true;
301 }
302
303 static bool executeCreateLink(LocalFrame& frame, Event*, EditorCommandSource, co nst String& value)
304 {
305 if (value.isEmpty())
306 return false;
307 ASSERT(frame.document());
308 CreateLinkCommand::create(*frame.document(), value)->apply();
309 return true;
310 }
311
312 static bool executeCut(LocalFrame& frame, Event*, EditorCommandSource, const Str ing&)
313 {
314 frame.editor().cut();
315 return true;
316 }
317
318 static bool executeDefaultParagraphSeparator(LocalFrame& frame, Event*, EditorCo mmandSource, const String& value)
319 {
320 if (equalIgnoringCase(value, "div"))
321 frame.editor().setDefaultParagraphSeparator(EditorParagraphSeparatorIsDi v);
322 else if (equalIgnoringCase(value, "p"))
323 frame.editor().setDefaultParagraphSeparator(EditorParagraphSeparatorIsP) ;
324
325 return true;
326 }
327
328 static bool executeDelete(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
329 {
330 switch (source) {
331 case CommandFromMenuOrKeyBinding: {
332 // Doesn't modify the text if the current selection isn't a range.
333 frame.editor().performDelete();
334 return true;
335 }
336 case CommandFromDOM:
337 // If the current selection is a caret, delete the preceding character. IE performs forwardDelete, but we currently side with Firefox.
338 // Doesn't scroll to make the selection visible, or modify the kill ring (this time, siding with IE, not Firefox).
339 ASSERT(frame.document());
340 TypingCommand::deleteKeyPressed(*frame.document(), frame.selection().gra nularity() == WordGranularity ? TypingCommand::SmartDelete : 0);
341 return true;
342 }
343 ASSERT_NOT_REACHED();
344 return false;
345 }
346
347 static bool executeDeleteBackward(LocalFrame& frame, Event*, EditorCommandSource , const String&)
348 {
349 frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
350 return true;
351 }
352
353 static bool executeDeleteBackwardByDecomposingPreviousCharacter(LocalFrame& fram e, Event*, EditorCommandSource, const String&)
354 {
355 WTF_LOG_ERROR("DeleteBackwardByDecomposingPreviousCharacter is not implement ed, doing DeleteBackward instead");
356 frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
357 return true;
358 }
359
360 static bool executeDeleteForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
361 {
362 frame.editor().deleteWithDirection(DirectionForward, CharacterGranularity, f alse, true);
363 return true;
364 }
365
366 static bool executeDeleteToBeginningOfLine(LocalFrame& frame, Event*, EditorComm andSource, const String&)
367 {
368 frame.editor().deleteWithDirection(DirectionBackward, LineBoundary, true, fa lse);
369 return true;
370 }
371
372 static bool executeDeleteToBeginningOfParagraph(LocalFrame& frame, Event*, Edito rCommandSource, const String&)
373 {
374 frame.editor().deleteWithDirection(DirectionBackward, ParagraphBoundary, tru e, false);
375 return true;
376 }
377
378 static bool executeDeleteToEndOfLine(LocalFrame& frame, Event*, EditorCommandSou rce, const String&)
379 {
380 // Despite its name, this command should delete the newline at the end of
381 // a paragraph if you are at the end of a paragraph (like DeleteToEndOfParag raph).
382 frame.editor().deleteWithDirection(DirectionForward, LineBoundary, true, fal se);
383 return true;
384 }
385
386 static bool executeDeleteToEndOfParagraph(LocalFrame& frame, Event*, EditorComma ndSource, const String&)
387 {
388 // Despite its name, this command should delete the newline at the end of
389 // a paragraph if you are at the end of a paragraph.
390 frame.editor().deleteWithDirection(DirectionForward, ParagraphBoundary, true , false);
391 return true;
392 }
393
394 static bool executeDeleteToMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
395 {
396 // TODO(yosin) We should use |EphemeralRange| version of
397 // |VisibleSelection::toNormalizedRange()|.
398 RefPtrWillBeRawPtr<Range> mark = frame.editor().mark().toNormalizedRange();
399 if (mark) {
400 bool selected = frame.selection().setSelectedRange(unionEphemeralRanges( EphemeralRange(mark.get()), frame.editor().selectedRange()), DOWNSTREAM, FrameSe lection::NonDirectional, FrameSelection::CloseTyping);
401 ASSERT(selected);
402 if (!selected)
403 return false;
404 }
405 frame.editor().performDelete();
406 frame.editor().setMark(frame.selection().selection());
407 return true;
408 }
409
410 static bool executeDeleteWordBackward(LocalFrame& frame, Event*, EditorCommandSo urce, const String&)
411 {
412 frame.editor().deleteWithDirection(DirectionBackward, WordGranularity, true, false);
413 return true;
414 }
415
416 static bool executeDeleteWordForward(LocalFrame& frame, Event*, EditorCommandSou rce, const String&)
417 {
418 frame.editor().deleteWithDirection(DirectionForward, WordGranularity, true, false);
419 return true;
420 }
421
422 static bool executeFindString(LocalFrame& frame, Event*, EditorCommandSource, co nst String& value)
423 {
424 return frame.editor().findString(value, CaseInsensitive | WrapAround);
425 }
426
427 static bool executeFontName(LocalFrame& frame, Event*, EditorCommandSource sourc e, const String& value)
428 {
429 return executeApplyStyle(frame, source, EditActionSetFont, CSSPropertyFontFa mily, value);
430 }
431
432 static bool executeFontSize(LocalFrame& frame, Event*, EditorCommandSource sourc e, const String& value)
433 {
434 CSSValueID size;
435 if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
436 return false;
437 return executeApplyStyle(frame, source, EditActionChangeAttributes, CSSPrope rtyFontSize, size);
438 }
439
440 static bool executeFontSizeDelta(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
441 {
442 return executeApplyStyle(frame, source, EditActionChangeAttributes, CSSPrope rtyWebkitFontSizeDelta, value);
443 }
444
445 static bool executeForeColor(LocalFrame& frame, Event*, EditorCommandSource sour ce, const String& value)
446 {
447 return executeApplyStyle(frame, source, EditActionSetColor, CSSPropertyColor , value);
448 }
449
450 static bool executeFormatBlock(LocalFrame& frame, Event*, EditorCommandSource, c onst String& value)
451 {
452 String tagName = value.lower();
453 if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
454 tagName = tagName.substring(1, tagName.length() - 2);
455
456 AtomicString localName, prefix;
457 if (!Document::parseQualifiedName(AtomicString(tagName), prefix, localName, IGNORE_EXCEPTION))
458 return false;
459 QualifiedName qualifiedTagName(prefix, localName, xhtmlNamespaceURI);
460
461 ASSERT(frame.document());
462 RefPtrWillBeRawPtr<FormatBlockCommand> command = FormatBlockCommand::create( *frame.document(), qualifiedTagName);
463 command->apply();
464 return command->didApply();
465 }
466
467 static bool executeForwardDelete(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
468 {
469 switch (source) {
470 case CommandFromMenuOrKeyBinding:
471 frame.editor().deleteWithDirection(DirectionForward, CharacterGranularit y, false, true);
472 return true;
473 case CommandFromDOM:
474 // Doesn't scroll to make the selection visible, or modify the kill ring .
475 // ForwardDelete is not implemented in IE or Firefox, so this behavior i s only needed for
476 // backward compatibility with ourselves, and for consistency with Delet e.
477 ASSERT(frame.document());
478 TypingCommand::forwardDeleteKeyPressed(*frame.document());
479 return true;
480 }
481 ASSERT_NOT_REACHED();
482 return false;
483 }
484
485 static bool executeIgnoreSpelling(LocalFrame& frame, Event*, EditorCommandSource , const String&)
486 {
487 frame.spellChecker().ignoreSpelling();
488 return true;
489 }
490
491 static bool executeIndent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
492 {
493 ASSERT(frame.document());
494 IndentOutdentCommand::create(*frame.document(), IndentOutdentCommand::Indent )->apply();
495 return true;
496 }
497
498 static bool executeInsertBacktab(LocalFrame& frame, Event* event, EditorCommandS ource, const String&)
499 {
500 return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\t", event, TextEventInputBackTab);
501 }
502
503 static bool executeInsertHorizontalRule(LocalFrame& frame, Event*, EditorCommand Source, const String& value)
504 {
505 ASSERT(frame.document());
506 RefPtrWillBeRawPtr<HTMLHRElement> rule = HTMLHRElement::create(*frame.docume nt());
507 if (!value.isEmpty())
508 rule->setIdAttribute(AtomicString(value));
509 return executeInsertElement(frame, rule.release());
510 }
511
512 static bool executeInsertHTML(LocalFrame& frame, Event*, EditorCommandSource, co nst String& value)
513 {
514 ASSERT(frame.document());
515 return executeInsertFragment(frame, createFragmentFromMarkup(*frame.document (), value, ""));
516 }
517
518 static bool executeInsertImage(LocalFrame& frame, Event*, EditorCommandSource, c onst String& value)
519 {
520 ASSERT(frame.document());
521 RefPtrWillBeRawPtr<HTMLImageElement> image = HTMLImageElement::create(*frame .document());
522 if (!value.isEmpty())
523 image->setSrc(value);
524 return executeInsertElement(frame, image.release());
525 }
526
527 static bool executeInsertLineBreak(LocalFrame& frame, Event* event, EditorComman dSource source, const String&)
528 {
529 switch (source) {
530 case CommandFromMenuOrKeyBinding:
531 return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\ n", event, TextEventInputLineBreak);
532 case CommandFromDOM:
533 // Doesn't scroll to make the selection visible, or modify the kill ring .
534 // InsertLineBreak is not implemented in IE or Firefox, so this behavior is only needed for
535 // backward compatibility with ourselves, and for consistency with other commands.
536 ASSERT(frame.document());
537 TypingCommand::insertLineBreak(*frame.document(), 0);
538 return true;
539 }
540 ASSERT_NOT_REACHED();
541 return false;
542 }
543
544 static bool executeInsertNewline(LocalFrame& frame, Event* event, EditorCommandS ource, const String&)
545 {
546 LocalFrame* targetFrame = blink::targetFrame(frame, event);
547 return targetFrame->eventHandler().handleTextInputEvent("\n", event, targetF rame->editor().canEditRichly() ? TextEventInputKeyboard : TextEventInputLineBrea k);
548 }
549
550 static bool executeInsertNewlineInQuotedContent(LocalFrame& frame, Event*, Edito rCommandSource, const String&)
551 {
552 ASSERT(frame.document());
553 TypingCommand::insertParagraphSeparatorInQuotedContent(*frame.document());
554 return true;
555 }
556
557 static bool executeInsertOrderedList(LocalFrame& frame, Event*, EditorCommandSou rce, const String&)
558 {
559 ASSERT(frame.document());
560 InsertListCommand::create(*frame.document(), InsertListCommand::OrderedList) ->apply();
561 return true;
562 }
563
564 static bool executeInsertParagraph(LocalFrame& frame, Event*, EditorCommandSourc e, const String&)
565 {
566 ASSERT(frame.document());
567 TypingCommand::insertParagraphSeparator(*frame.document(), 0);
568 return true;
569 }
570
571 static bool executeInsertTab(LocalFrame& frame, Event* event, EditorCommandSourc e, const String&)
572 {
573 return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\t", event);
574 }
575
576 static bool executeInsertText(LocalFrame& frame, Event*, EditorCommandSource, co nst String& value)
577 {
578 ASSERT(frame.document());
579 TypingCommand::insertText(*frame.document(), value, 0);
580 return true;
581 }
582
583 static bool executeInsertUnorderedList(LocalFrame& frame, Event*, EditorCommandS ource, const String&)
584 {
585 ASSERT(frame.document());
586 InsertListCommand::create(*frame.document(), InsertListCommand::UnorderedLis t)->apply();
587 return true;
588 }
589
590 static bool executeJustifyCenter(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
591 {
592 return executeApplyParagraphStyle(frame, source, EditActionCenter, CSSProper tyTextAlign, "center");
593 }
594
595 static bool executeJustifyFull(LocalFrame& frame, Event*, EditorCommandSource so urce, const String&)
596 {
597 return executeApplyParagraphStyle(frame, source, EditActionJustify, CSSPrope rtyTextAlign, "justify");
598 }
599
600 static bool executeJustifyLeft(LocalFrame& frame, Event*, EditorCommandSource so urce, const String&)
601 {
602 return executeApplyParagraphStyle(frame, source, EditActionAlignLeft, CSSPro pertyTextAlign, "left");
603 }
604
605 static bool executeJustifyRight(LocalFrame& frame, Event*, EditorCommandSource s ource, const String&)
606 {
607 return executeApplyParagraphStyle(frame, source, EditActionAlignRight, CSSPr opertyTextAlign, "right");
608 }
609
610 static bool executeMakeTextWritingDirectionLeftToRight(LocalFrame& frame, Event* , EditorCommandSource, const String&)
611 {
612 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet: :create();
613 style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
614 style->setProperty(CSSPropertyDirection, CSSValueLtr);
615 frame.editor().applyStyle(style.get(), EditActionSetWritingDirection);
616 return true;
617 }
618
619 static bool executeMakeTextWritingDirectionNatural(LocalFrame& frame, Event*, Ed itorCommandSource, const String&)
620 {
621 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet: :create();
622 style->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal);
623 frame.editor().applyStyle(style.get(), EditActionSetWritingDirection);
624 return true;
625 }
626
627 static bool executeMakeTextWritingDirectionRightToLeft(LocalFrame& frame, Event* , EditorCommandSource, const String&)
628 {
629 RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet: :create();
630 style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
631 style->setProperty(CSSPropertyDirection, CSSValueRtl);
632 frame.editor().applyStyle(style.get(), EditActionSetWritingDirection);
633 return true;
634 }
635
636 static bool executeMoveBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
637 {
638 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
639 return true;
640 }
641
642 static bool executeMoveBackwardAndModifySelection(LocalFrame& frame, Event*, Edi torCommandSource, const String&)
643 {
644 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , CharacterGranularity, UserTriggered);
645 return true;
646 }
647
648 static bool executeMoveDown(LocalFrame& frame, Event*, EditorCommandSource, cons t String&)
649 {
650 return frame.selection().modify(FrameSelection::AlterationMove, DirectionFor ward, LineGranularity, UserTriggered);
651 }
652
653 static bool executeMoveDownAndModifySelection(LocalFrame& frame, Event*, EditorC ommandSource, const String&)
654 {
655 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, LineGranularity, UserTriggered);
656 return true;
657 }
658
659 static bool executeMoveForward(LocalFrame& frame, Event*, EditorCommandSource, c onst String&)
660 {
661 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, C haracterGranularity, UserTriggered);
662 return true;
663 }
664
665 static bool executeMoveForwardAndModifySelection(LocalFrame& frame, Event*, Edit orCommandSource, const String&)
666 {
667 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity, UserTriggered);
668 return true;
669 }
670
671 static bool executeMoveLeft(LocalFrame& frame, Event*, EditorCommandSource, cons t String&)
672 {
673 return frame.selection().modify(FrameSelection::AlterationMove, DirectionLef t, CharacterGranularity, UserTriggered);
674 }
675
676 static bool executeMoveLeftAndModifySelection(LocalFrame& frame, Event*, EditorC ommandSource, const String&)
677 {
678 frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, Ch aracterGranularity, UserTriggered);
679 return true;
680 }
681
682 static bool executeMovePageDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
683 {
684 unsigned distance = verticalScrollDistance(frame);
685 if (!distance)
686 return false;
687 return frame.selection().modify(FrameSelection::AlterationMove, distance, Fr ameSelection::DirectionDown,
688 UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
689 }
690
691 static bool executeMovePageDownAndModifySelection(LocalFrame& frame, Event*, Edi torCommandSource, const String&)
692 {
693 unsigned distance = verticalScrollDistance(frame);
694 if (!distance)
695 return false;
696 return frame.selection().modify(FrameSelection::AlterationExtend, distance, FrameSelection::DirectionDown,
697 UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
698 }
699
700 static bool executeMovePageUp(LocalFrame& frame, Event*, EditorCommandSource, co nst String&)
701 {
702 unsigned distance = verticalScrollDistance(frame);
703 if (!distance)
704 return false;
705 return frame.selection().modify(FrameSelection::AlterationMove, distance, Fr ameSelection::DirectionUp,
706 UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
707 }
708
709 static bool executeMovePageUpAndModifySelection(LocalFrame& frame, Event*, Edito rCommandSource, const String&)
710 {
711 unsigned distance = verticalScrollDistance(frame);
712 if (!distance)
713 return false;
714 return frame.selection().modify(FrameSelection::AlterationExtend, distance, FrameSelection::DirectionUp,
715 UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
716 }
717
718 static bool executeMoveRight(LocalFrame& frame, Event*, EditorCommandSource, con st String&)
719 {
720 return frame.selection().modify(FrameSelection::AlterationMove, DirectionRig ht, CharacterGranularity, UserTriggered);
721 }
722
723 static bool executeMoveRightAndModifySelection(LocalFrame& frame, Event*, Editor CommandSource, const String&)
724 {
725 frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, C haracterGranularity, UserTriggered);
726 return true;
727 }
728
729 static bool executeMoveToBeginningOfDocument(LocalFrame& frame, Event*, EditorCo mmandSource, const String&)
730 {
731 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, DocumentBoundary, UserTriggered);
732 return true;
733 }
734
735 static bool executeMoveToBeginningOfDocumentAndModifySelection(LocalFrame& frame , Event*, EditorCommandSource, const String&)
736 {
737 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , DocumentBoundary, UserTriggered);
738 return true;
739 }
740
741 static bool executeMoveToBeginningOfLine(LocalFrame& frame, Event*, EditorComman dSource, const String&)
742 {
743 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, LineBoundary, UserTriggered);
744 return true;
745 }
746
747 static bool executeMoveToBeginningOfLineAndModifySelection(LocalFrame& frame, Ev ent*, EditorCommandSource, const String&)
748 {
749 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , LineBoundary, UserTriggered);
750 return true;
751 }
752
753 static bool executeMoveToBeginningOfParagraph(LocalFrame& frame, Event*, EditorC ommandSource, const String&)
754 {
755 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, ParagraphBoundary, UserTriggered);
756 return true;
757 }
758
759 static bool executeMoveToBeginningOfParagraphAndModifySelection(LocalFrame& fram e, Event*, EditorCommandSource, const String&)
760 {
761 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , ParagraphBoundary, UserTriggered);
762 return true;
763 }
764
765 static bool executeMoveToBeginningOfSentence(LocalFrame& frame, Event*, EditorCo mmandSource, const String&)
766 {
767 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, SentenceBoundary, UserTriggered);
768 return true;
769 }
770
771 static bool executeMoveToBeginningOfSentenceAndModifySelection(LocalFrame& frame , Event*, EditorCommandSource, const String&)
772 {
773 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , SentenceBoundary, UserTriggered);
774 return true;
775 }
776
777 static bool executeMoveToEndOfDocument(LocalFrame& frame, Event*, EditorCommandS ource, const String&)
778 {
779 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, D ocumentBoundary, UserTriggered);
780 return true;
781 }
782
783 static bool executeMoveToEndOfDocumentAndModifySelection(LocalFrame& frame, Even t*, EditorCommandSource, const String&)
784 {
785 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, DocumentBoundary, UserTriggered);
786 return true;
787 }
788
789 static bool executeMoveToEndOfSentence(LocalFrame& frame, Event*, EditorCommandS ource, const String&)
790 {
791 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, S entenceBoundary, UserTriggered);
792 return true;
793 }
794
795 static bool executeMoveToEndOfSentenceAndModifySelection(LocalFrame& frame, Even t*, EditorCommandSource, const String&)
796 {
797 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, SentenceBoundary, UserTriggered);
798 return true;
799 }
800
801 static bool executeMoveToEndOfLine(LocalFrame& frame, Event*, EditorCommandSourc e, const String&)
802 {
803 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, L ineBoundary, UserTriggered);
804 return true;
805 }
806
807 static bool executeMoveToEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
808 {
809 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, LineBoundary, UserTriggered);
810 return true;
811 }
812
813 static bool executeMoveToEndOfParagraph(LocalFrame& frame, Event*, EditorCommand Source, const String&)
814 {
815 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, P aragraphBoundary, UserTriggered);
816 return true;
817 }
818
819 static bool executeMoveToEndOfParagraphAndModifySelection(LocalFrame& frame, Eve nt*, EditorCommandSource, const String&)
820 {
821 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, ParagraphBoundary, UserTriggered);
822 return true;
823 }
824
825 static bool executeMoveParagraphBackward(LocalFrame& frame, Event*, EditorComman dSource, const String&)
826 {
827 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, ParagraphGranularity, UserTriggered);
828 return true;
829 }
830
831 static bool executeMoveParagraphBackwardAndModifySelection(LocalFrame& frame, Ev ent*, EditorCommandSource, const String&)
832 {
833 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , ParagraphGranularity, UserTriggered);
834 return true;
835 }
836
837 static bool executeMoveParagraphForward(LocalFrame& frame, Event*, EditorCommand Source, const String&)
838 {
839 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, P aragraphGranularity, UserTriggered);
840 return true;
841 }
842
843 static bool executeMoveParagraphForwardAndModifySelection(LocalFrame& frame, Eve nt*, EditorCommandSource, const String&)
844 {
845 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, ParagraphGranularity, UserTriggered);
846 return true;
847 }
848
849 static bool executeMoveUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
850 {
851 return frame.selection().modify(FrameSelection::AlterationMove, DirectionBac kward, LineGranularity, UserTriggered);
852 }
853
854 static bool executeMoveUpAndModifySelection(LocalFrame& frame, Event*, EditorCom mandSource, const String&)
855 {
856 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , LineGranularity, UserTriggered);
857 return true;
858 }
859
860 static bool executeMoveWordBackward(LocalFrame& frame, Event*, EditorCommandSour ce, const String&)
861 {
862 frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, WordGranularity, UserTriggered);
863 return true;
864 }
865
866 static bool executeMoveWordBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
867 {
868 frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward , WordGranularity, UserTriggered);
869 return true;
870 }
871
872 static bool executeMoveWordForward(LocalFrame& frame, Event*, EditorCommandSourc e, const String&)
873 {
874 frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, W ordGranularity, UserTriggered);
875 return true;
876 }
877
878 static bool executeMoveWordForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
879 {
880 frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, WordGranularity, UserTriggered);
881 return true;
882 }
883
884 static bool executeMoveWordLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
885 {
886 frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, Word Granularity, UserTriggered);
887 return true;
888 }
889
890 static bool executeMoveWordLeftAndModifySelection(LocalFrame& frame, Event*, Edi torCommandSource, const String&)
891 {
892 frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, Wo rdGranularity, UserTriggered);
893 return true;
894 }
895
896 static bool executeMoveWordRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
897 {
898 frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, Wor dGranularity, UserTriggered);
899 return true;
900 }
901
902 static bool executeMoveWordRightAndModifySelection(LocalFrame& frame, Event*, Ed itorCommandSource, const String&)
903 {
904 frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, W ordGranularity, UserTriggered);
905 return true;
906 }
907
908 static bool executeMoveToLeftEndOfLine(LocalFrame& frame, Event*, EditorCommandS ource, const String&)
909 {
910 frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, Line Boundary, UserTriggered);
911 return true;
912 }
913
914 static bool executeMoveToLeftEndOfLineAndModifySelection(LocalFrame& frame, Even t*, EditorCommandSource, const String&)
915 {
916 frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, Li neBoundary, UserTriggered);
917 return true;
918 }
919
920 static bool executeMoveToRightEndOfLine(LocalFrame& frame, Event*, EditorCommand Source, const String&)
921 {
922 frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, Lin eBoundary, UserTriggered);
923 return true;
924 }
925
926 static bool executeMoveToRightEndOfLineAndModifySelection(LocalFrame& frame, Eve nt*, EditorCommandSource, const String&)
927 {
928 frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, L ineBoundary, UserTriggered);
929 return true;
930 }
931
932 static bool executeOutdent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
933 {
934 ASSERT(frame.document());
935 IndentOutdentCommand::create(*frame.document(), IndentOutdentCommand::Outden t)->apply();
936 return true;
937 }
938
939 static bool executeToggleOverwrite(LocalFrame& frame, Event*, EditorCommandSourc e, const String&)
940 {
941 frame.editor().toggleOverwriteModeEnabled();
942 return true;
943 }
944
945 static bool executePaste(LocalFrame& frame, Event*, EditorCommandSource, const S tring&)
946 {
947 frame.editor().paste();
948 return true;
949 }
950
951 static bool executePasteGlobalSelection(LocalFrame& frame, Event*, EditorCommand Source source, const String&)
952 {
953 if (!frame.editor().behavior().supportsGlobalSelection())
954 return false;
955 ASSERT_UNUSED(source, source == CommandFromMenuOrKeyBinding);
956
957 bool oldSelectionMode = Pasteboard::generalPasteboard()->isSelectionMode();
958 Pasteboard::generalPasteboard()->setSelectionMode(true);
959 frame.editor().paste();
960 Pasteboard::generalPasteboard()->setSelectionMode(oldSelectionMode);
961 return true;
962 }
963
964 static bool executePasteAndMatchStyle(LocalFrame& frame, Event*, EditorCommandSo urce, const String&)
965 {
966 frame.editor().pasteAsPlainText();
967 return true;
968 }
969
970 static bool executePrint(LocalFrame& frame, Event*, EditorCommandSource, const S tring&)
971 {
972 FrameHost* host = frame.host();
973 if (!host)
974 return false;
975 host->chromeClient().print(&frame);
976 return true;
977 }
978
979 static bool executeRedo(LocalFrame& frame, Event*, EditorCommandSource, const St ring&)
980 {
981 frame.editor().redo();
982 return true;
983 }
984
985 static bool executeRemoveFormat(LocalFrame& frame, Event*, EditorCommandSource, const String&)
986 {
987 frame.editor().removeFormattingAndStyle();
988 return true;
989 }
990
991 static bool executeScrollPageBackward(LocalFrame& frame, Event*, EditorCommandSo urce, const String&)
992 {
993 return frame.eventHandler().bubblingScroll(ScrollBlockDirectionBackward, Scr ollByPage);
994 }
995
996 static bool executeScrollPageForward(LocalFrame& frame, Event*, EditorCommandSou rce, const String&)
997 {
998 return frame.eventHandler().bubblingScroll(ScrollBlockDirectionForward, Scro llByPage);
999 }
1000
1001 static bool executeScrollLineUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
1002 {
1003 return frame.eventHandler().bubblingScroll(ScrollUpIgnoringWritingMode, Scro llByLine);
1004 }
1005
1006 static bool executeScrollLineDown(LocalFrame& frame, Event*, EditorCommandSource , const String&)
1007 {
1008 return frame.eventHandler().bubblingScroll(ScrollDownIgnoringWritingMode, Sc rollByLine);
1009 }
1010
1011 static bool executeScrollToBeginningOfDocument(LocalFrame& frame, Event*, Editor CommandSource, const String&)
1012 {
1013 return frame.eventHandler().bubblingScroll(ScrollBlockDirectionBackward, Scr ollByDocument);
1014 }
1015
1016 static bool executeScrollToEndOfDocument(LocalFrame& frame, Event*, EditorComman dSource, const String&)
1017 {
1018 return frame.eventHandler().bubblingScroll(ScrollBlockDirectionForward, Scro llByDocument);
1019 }
1020
1021 static bool executeSelectAll(LocalFrame& frame, Event*, EditorCommandSource, con st String&)
1022 {
1023 frame.selection().selectAll();
1024 return true;
1025 }
1026
1027 static bool executeSelectLine(LocalFrame& frame, Event*, EditorCommandSource, co nst String&)
1028 {
1029 return expandSelectionToGranularity(frame, LineGranularity);
1030 }
1031
1032 static bool executeSelectParagraph(LocalFrame& frame, Event*, EditorCommandSourc e, const String&)
1033 {
1034 return expandSelectionToGranularity(frame, ParagraphGranularity);
1035 }
1036
1037 static bool executeSelectSentence(LocalFrame& frame, Event*, EditorCommandSource , const String&)
1038 {
1039 return expandSelectionToGranularity(frame, SentenceGranularity);
1040 }
1041
1042 static bool executeSelectToMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
1043 {
1044 // TODO(yosin) We should use |EphemeralRange| version of
1045 // |VisibleSelection::toNormalizedRange()|.
1046 RefPtrWillBeRawPtr<Range> mark = frame.editor().mark().toNormalizedRange();
1047 EphemeralRange selection = frame.editor().selectedRange();
1048 if (!mark || selection.isNull())
1049 return false;
1050 frame.selection().setSelectedRange(unionEphemeralRanges(EphemeralRange(mark. get()), selection), DOWNSTREAM, FrameSelection::NonDirectional, FrameSelection:: CloseTyping);
1051 return true;
1052 }
1053
1054 static bool executeSelectWord(LocalFrame& frame, Event*, EditorCommandSource, co nst String&)
1055 {
1056 return expandSelectionToGranularity(frame, WordGranularity);
1057 }
1058
1059 static bool executeSetMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
1060 {
1061 frame.editor().setMark(frame.selection().selection());
1062 return true;
1063 }
1064
1065 static bool executeStrikethrough(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
1066 {
1067 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineThrough = CSSPrimitiveValue::creat eIdentifier(CSSValueLineThrough);
1068 return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPrope rtyWebkitTextDecorationsInEffect, lineThrough.get());
1069 }
1070
1071 static bool executeStyleWithCSS(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
1072 {
1073 frame.editor().setShouldStyleWithCSS(!equalIgnoringCase(value, "false"));
1074 return true;
1075 }
1076
1077 static bool executeUseCSS(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
1078 {
1079 frame.editor().setShouldStyleWithCSS(equalIgnoringCase(value, "false"));
1080 return true;
1081 }
1082
1083 static bool executeSubscript(LocalFrame& frame, Event*, EditorCommandSource sour ce, const String&)
1084 {
1085 return executeToggleStyle(frame, source, EditActionSubscript, CSSPropertyVer ticalAlign, "baseline", "sub");
1086 }
1087
1088 static bool executeSuperscript(LocalFrame& frame, Event*, EditorCommandSource so urce, const String&)
1089 {
1090 return executeToggleStyle(frame, source, EditActionSuperscript, CSSPropertyV erticalAlign, "baseline", "super");
1091 }
1092
1093 static bool executeSwapWithMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
1094 {
1095 const VisibleSelection& mark = frame.editor().mark();
1096 const VisibleSelection& selection = frame.selection().selection();
1097 if (mark.isNone() || selection.isNone())
1098 return false;
1099 frame.selection().setSelection(mark);
1100 frame.editor().setMark(selection);
1101 return true;
1102 }
1103
1104 static bool executeToggleBold(LocalFrame& frame, Event*, EditorCommandSource sou rce, const String&)
1105 {
1106 return executeToggleStyle(frame, source, EditActionBold, CSSPropertyFontWeig ht, "normal", "bold");
1107 }
1108
1109 static bool executeToggleItalic(LocalFrame& frame, Event*, EditorCommandSource s ource, const String&)
1110 {
1111 return executeToggleStyle(frame, source, EditActionItalics, CSSPropertyFontS tyle, "normal", "italic");
1112 }
1113
1114 static bool executeTranspose(LocalFrame& frame, Event*, EditorCommandSource, con st String&)
1115 {
1116 frame.editor().transpose();
1117 return true;
1118 }
1119
1120 static bool executeUnderline(LocalFrame& frame, Event*, EditorCommandSource sour ce, const String&)
1121 {
1122 RefPtrWillBeRawPtr<CSSPrimitiveValue> underline = CSSPrimitiveValue::createI dentifier(CSSValueUnderline);
1123 return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPrope rtyWebkitTextDecorationsInEffect, underline.get());
1124 }
1125
1126 static bool executeUndo(LocalFrame& frame, Event*, EditorCommandSource, const St ring&)
1127 {
1128 frame.editor().undo();
1129 return true;
1130 }
1131
1132 static bool executeUnlink(LocalFrame& frame, Event*, EditorCommandSource, const String&)
1133 {
1134 ASSERT(frame.document());
1135 UnlinkCommand::create(*frame.document())->apply();
1136 return true;
1137 }
1138
1139 static bool executeUnscript(LocalFrame& frame, Event*, EditorCommandSource sourc e, const String&)
1140 {
1141 return executeApplyStyle(frame, source, EditActionUnscript, CSSPropertyVerti calAlign, "baseline");
1142 }
1143
1144 static bool executeUnselect(LocalFrame& frame, Event*, EditorCommandSource, cons t String&)
1145 {
1146 frame.selection().clear();
1147 return true;
1148 }
1149
1150 static bool executeYank(LocalFrame& frame, Event*, EditorCommandSource, const St ring&)
1151 {
1152 frame.editor().insertTextWithoutSendingTextEvent(frame.editor().killRing().y ank(), false, 0);
1153 frame.editor().killRing().setToYankedState();
1154 return true;
1155 }
1156
1157 static bool executeYankAndSelect(LocalFrame& frame, Event*, EditorCommandSource, const String&)
1158 {
1159 frame.editor().insertTextWithoutSendingTextEvent(frame.editor().killRing().y ank(), true, 0);
1160 frame.editor().killRing().setToYankedState();
1161 return true;
1162 }
1163
1164 // Supported functions
1165
1166 static bool supported(LocalFrame*)
1167 {
1168 return true;
1169 }
1170
1171 static bool supportedFromMenuOrKeyBinding(LocalFrame*)
1172 {
1173 return false;
1174 }
1175
1176 static bool supportedCopyCut(LocalFrame* frame)
1177 {
1178 if (!frame)
1179 return false;
1180
1181 Settings* settings = frame->settings();
1182 bool defaultValue = (settings && settings->javaScriptCanAccessClipboard()) | | UserGestureIndicator::processingUserGesture();
1183 return frame->editor().client().canCopyCut(frame, defaultValue);
1184 }
1185
1186 static bool supportedPaste(LocalFrame* frame)
1187 {
1188 if (!frame)
1189 return false;
1190
1191 Settings* settings = frame->settings();
1192 bool defaultValue = settings && settings->javaScriptCanAccessClipboard() && settings->DOMPasteAllowed();
1193 return frame->editor().client().canPaste(frame, defaultValue);
1194 }
1195
1196 // Enabled functions
1197
1198 static bool enabled(LocalFrame&, Event*, EditorCommandSource)
1199 {
1200 return true;
1201 }
1202
1203 static bool enabledVisibleSelection(LocalFrame& frame, Event* event, EditorComma ndSource)
1204 {
1205 // The term "visible" here includes a caret in editable text or a range in a ny text.
1206 const VisibleSelection& selection = frame.editor().selectionForCommand(event );
1207 return (selection.isCaret() && selection.isContentEditable()) || selection.i sRange();
1208 }
1209
1210 static bool caretBrowsingEnabled(LocalFrame& frame)
1211 {
1212 return frame.settings() && frame.settings()->caretBrowsingEnabled();
1213 }
1214
1215 static EditorCommandSource dummyEditorCommandSource = static_cast<EditorCommandS ource>(0);
1216
1217 static bool enabledVisibleSelectionOrCaretBrowsing(LocalFrame& frame, Event* eve nt, EditorCommandSource)
1218 {
1219 // The EditorCommandSource parameter is unused in enabledVisibleSelection, s o just pass a dummy variable
1220 return caretBrowsingEnabled(frame) || enabledVisibleSelection(frame, event, dummyEditorCommandSource);
1221 }
1222
1223 static bool enabledVisibleSelectionAndMark(LocalFrame& frame, Event* event, Edit orCommandSource)
1224 {
1225 const VisibleSelection& selection = frame.editor().selectionForCommand(event );
1226 return ((selection.isCaret() && selection.isContentEditable()) || selection. isRange())
1227 && frame.editor().mark().isCaretOrRange();
1228 }
1229
1230 static bool enableCaretInEditableText(LocalFrame& frame, Event* event, EditorCom mandSource)
1231 {
1232 const VisibleSelection& selection = frame.editor().selectionForCommand(event );
1233 return selection.isCaret() && selection.isContentEditable();
1234 }
1235
1236 static bool enabledCopy(LocalFrame& frame, Event*, EditorCommandSource)
1237 {
1238 return frame.editor().canDHTMLCopy() || frame.editor().canCopy();
1239 }
1240
1241 static bool enabledCut(LocalFrame& frame, Event*, EditorCommandSource)
1242 {
1243 return frame.editor().canDHTMLCut() || frame.editor().canCut();
1244 }
1245
1246 static bool enabledInEditableText(LocalFrame& frame, Event* event, EditorCommand Source)
1247 {
1248 return frame.editor().selectionForCommand(event).rootEditableElement();
1249 }
1250
1251 static bool enabledDelete(LocalFrame& frame, Event* event, EditorCommandSource s ource)
1252 {
1253 switch (source) {
1254 case CommandFromMenuOrKeyBinding:
1255 return frame.editor().canDelete();
1256 case CommandFromDOM:
1257 // "Delete" from DOM is like delete/backspace keypress, affects selected range if non-empty,
1258 // otherwise removes a character
1259 return enabledInEditableText(frame, event, source);
1260 }
1261 ASSERT_NOT_REACHED();
1262 return false;
1263 }
1264
1265 static bool enabledInEditableTextOrCaretBrowsing(LocalFrame& frame, Event* event , EditorCommandSource)
1266 {
1267 // The EditorCommandSource parameter is unused in enabledInEditableText, so just pass a dummy variable
1268 return caretBrowsingEnabled(frame) || enabledInEditableText(frame, event, du mmyEditorCommandSource);
1269 }
1270
1271 static bool enabledInRichlyEditableText(LocalFrame& frame, Event*, EditorCommand Source)
1272 {
1273 return frame.selection().isCaretOrRange() && frame.selection().isContentRich lyEditable() && frame.selection().rootEditableElement();
1274 }
1275
1276 static bool enabledPaste(LocalFrame& frame, Event*, EditorCommandSource)
1277 {
1278 return frame.editor().canPaste();
1279 }
1280
1281 static bool enabledRangeInEditableText(LocalFrame& frame, Event*, EditorCommandS ource)
1282 {
1283 return frame.selection().isRange() && frame.selection().isContentEditable();
1284 }
1285
1286 static bool enabledRangeInRichlyEditableText(LocalFrame& frame, Event*, EditorCo mmandSource)
1287 {
1288 return frame.selection().isRange() && frame.selection().isContentRichlyEdita ble();
1289 }
1290
1291 static bool enabledRedo(LocalFrame& frame, Event*, EditorCommandSource)
1292 {
1293 return frame.editor().canRedo();
1294 }
1295
1296 static bool enabledUndo(LocalFrame& frame, Event*, EditorCommandSource)
1297 {
1298 return frame.editor().canUndo();
1299 }
1300
1301 // State functions
1302
1303 static TriState stateNone(LocalFrame&, Event*)
1304 {
1305 return FalseTriState;
1306 }
1307
1308 static TriState stateBold(LocalFrame& frame, Event*)
1309 {
1310 return stateStyle(frame, CSSPropertyFontWeight, "bold");
1311 }
1312
1313 static TriState stateItalic(LocalFrame& frame, Event*)
1314 {
1315 return stateStyle(frame, CSSPropertyFontStyle, "italic");
1316 }
1317
1318 static TriState stateOrderedList(LocalFrame& frame, Event*)
1319 {
1320 return selectionListState(frame.selection(), olTag);
1321 }
1322
1323 static TriState stateStrikethrough(LocalFrame& frame, Event*)
1324 {
1325 return stateStyle(frame, CSSPropertyWebkitTextDecorationsInEffect, "line-thr ough");
1326 }
1327
1328 static TriState stateStyleWithCSS(LocalFrame& frame, Event*)
1329 {
1330 return frame.editor().shouldStyleWithCSS() ? TrueTriState : FalseTriState;
1331 }
1332
1333 static TriState stateSubscript(LocalFrame& frame, Event*)
1334 {
1335 return stateStyle(frame, CSSPropertyVerticalAlign, "sub");
1336 }
1337
1338 static TriState stateSuperscript(LocalFrame& frame, Event*)
1339 {
1340 return stateStyle(frame, CSSPropertyVerticalAlign, "super");
1341 }
1342
1343 static TriState stateTextWritingDirectionLeftToRight(LocalFrame& frame, Event*)
1344 {
1345 return stateTextWritingDirection(frame, LeftToRightWritingDirection);
1346 }
1347
1348 static TriState stateTextWritingDirectionNatural(LocalFrame& frame, Event*)
1349 {
1350 return stateTextWritingDirection(frame, NaturalWritingDirection);
1351 }
1352
1353 static TriState stateTextWritingDirectionRightToLeft(LocalFrame& frame, Event*)
1354 {
1355 return stateTextWritingDirection(frame, RightToLeftWritingDirection);
1356 }
1357
1358 static TriState stateUnderline(LocalFrame& frame, Event*)
1359 {
1360 return stateStyle(frame, CSSPropertyWebkitTextDecorationsInEffect, "underlin e");
1361 }
1362
1363 static TriState stateUnorderedList(LocalFrame& frame, Event*)
1364 {
1365 return selectionListState(frame.selection(), ulTag);
1366 }
1367
1368 static TriState stateJustifyCenter(LocalFrame& frame, Event*)
1369 {
1370 return stateStyle(frame, CSSPropertyTextAlign, "center");
1371 }
1372
1373 static TriState stateJustifyFull(LocalFrame& frame, Event*)
1374 {
1375 return stateStyle(frame, CSSPropertyTextAlign, "justify");
1376 }
1377
1378 static TriState stateJustifyLeft(LocalFrame& frame, Event*)
1379 {
1380 return stateStyle(frame, CSSPropertyTextAlign, "left");
1381 }
1382
1383 static TriState stateJustifyRight(LocalFrame& frame, Event*)
1384 {
1385 return stateStyle(frame, CSSPropertyTextAlign, "right");
1386 }
1387
1388 // Value functions
1389
1390 static String valueNull(LocalFrame&, Event*)
1391 {
1392 return String();
1393 }
1394
1395 static String valueBackColor(LocalFrame& frame, Event*)
1396 {
1397 return valueStyle(frame, CSSPropertyBackgroundColor);
1398 }
1399
1400 static String valueDefaultParagraphSeparator(LocalFrame& frame, Event*)
1401 {
1402 switch (frame.editor().defaultParagraphSeparator()) {
1403 case EditorParagraphSeparatorIsDiv:
1404 return divTag.localName();
1405 case EditorParagraphSeparatorIsP:
1406 return pTag.localName();
1407 }
1408
1409 ASSERT_NOT_REACHED();
1410 return String();
1411 }
1412
1413 static String valueFontName(LocalFrame& frame, Event*)
1414 {
1415 return valueStyle(frame, CSSPropertyFontFamily);
1416 }
1417
1418 static String valueFontSize(LocalFrame& frame, Event*)
1419 {
1420 return valueStyle(frame, CSSPropertyFontSize);
1421 }
1422
1423 static String valueFontSizeDelta(LocalFrame& frame, Event*)
1424 {
1425 return valueStyle(frame, CSSPropertyWebkitFontSizeDelta);
1426 }
1427
1428 static String valueForeColor(LocalFrame& frame, Event*)
1429 {
1430 return valueStyle(frame, CSSPropertyColor);
1431 }
1432
1433 static String valueFormatBlock(LocalFrame& frame, Event*)
1434 {
1435 const VisibleSelection& selection = frame.selection().selection();
1436 if (!selection.isNonOrphanedCaretOrRange() || !selection.isContentEditable() )
1437 return "";
1438 Element* formatBlockElement = FormatBlockCommand::elementForFormatBlockComma nd(selection.firstRange().get());
1439 if (!formatBlockElement)
1440 return "";
1441 return formatBlockElement->localName();
1442 }
1443
1444 // Map of functions
1445
1446 struct CommandEntry {
1447 const char* name;
1448 EditorInternalCommand command;
1449 };
1450
1451 static const CommandMap& createCommandMap()
1452 {
1453 // If you add new commands, you should assign new Id to each idForUserMetric s and update MappedEditingCommands
1454 // in chrome/trunk/src/tools/metrics/histograms/histograms.xml.
1455 static const CommandEntry commands[] = {
1456 { "AlignCenter", {139, executeJustifyCenter, supportedFromMenuOrKeyBindi ng, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAl lowExecutionWhenDisabled } },
1457 { "AlignJustified", {1, executeJustifyFull, supportedFromMenuOrKeyBindin g, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAll owExecutionWhenDisabled } },
1458 { "AlignLeft", {2, executeJustifyLeft, supportedFromMenuOrKeyBinding, en abledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExe cutionWhenDisabled } },
1459 { "AlignRight", {3, executeJustifyRight, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowE xecutionWhenDisabled } },
1460 { "BackColor", {4, executeBackColor, supported, enabledInRichlyEditableT ext, stateNone, valueBackColor, notTextInsertion, doNotAllowExecutionWhenDisable d } },
1461 { "BackwardDelete", {5, executeDeleteBackward, supportedFromMenuOrKeyBin ding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowE xecutionWhenDisabled } }, // FIXME: remove BackwardDelete when Safari for Window s stops using it.
1462 { "Bold", {6, executeToggleBold, supported, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1463 { "Copy", {7, executeCopy, supportedCopyCut, enabledCopy, stateNone, val ueNull, notTextInsertion, allowExecutionWhenDisabled } },
1464 { "CreateLink", {8, executeCreateLink, supported, enabledInRichlyEditabl eText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1465 { "Cut", {9, executeCut, supportedCopyCut, enabledCut, stateNone, valueN ull, notTextInsertion, allowExecutionWhenDisabled } },
1466 { "DefaultParagraphSeparator", {10, executeDefaultParagraphSeparator, su pported, enabled, stateNone, valueDefaultParagraphSeparator, notTextInsertion, d oNotAllowExecutionWhenDisabled} },
1467 { "Delete", {11, executeDelete, supported, enabledDelete, stateNone, val ueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1468 { "DeleteBackward", {12, executeDeleteBackward, supportedFromMenuOrKeyBi nding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllow ExecutionWhenDisabled } },
1469 { "DeleteBackwardByDecomposingPreviousCharacter", {13, executeDeleteBack wardByDecomposingPreviousCharacter, supportedFromMenuOrKeyBinding, enabledInEdit ableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisable d } },
1470 { "DeleteForward", {14, executeDeleteForward, supportedFromMenuOrKeyBind ing, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowEx ecutionWhenDisabled } },
1471 { "DeleteToBeginningOfLine", {15, executeDeleteToBeginningOfLine, suppor tedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextIns ertion, doNotAllowExecutionWhenDisabled } },
1472 { "DeleteToBeginningOfParagraph", {16, executeDeleteToBeginningOfParagra ph, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1473 { "DeleteToEndOfLine", {17, executeDeleteToEndOfLine, supportedFromMenuO rKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNo tAllowExecutionWhenDisabled } },
1474 { "DeleteToEndOfParagraph", {18, executeDeleteToEndOfParagraph, supporte dFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInser tion, doNotAllowExecutionWhenDisabled } },
1475 { "DeleteToMark", {19, executeDeleteToMark, supportedFromMenuOrKeyBindin g, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExec utionWhenDisabled } },
1476 { "DeleteWordBackward", {20, executeDeleteWordBackward, supportedFromMen uOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, do NotAllowExecutionWhenDisabled } },
1477 { "DeleteWordForward", {21, executeDeleteWordForward, supportedFromMenuO rKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNo tAllowExecutionWhenDisabled } },
1478 { "FindString", {22, executeFindString, supported, enabled, stateNone, v alueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1479 { "FontName", {23, executeFontName, supported, enabledInEditableText, st ateNone, valueFontName, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1480 { "FontSize", {24, executeFontSize, supported, enabledInEditableText, st ateNone, valueFontSize, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1481 { "FontSizeDelta", {25, executeFontSizeDelta, supported, enabledInEditab leText, stateNone, valueFontSizeDelta, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1482 { "ForeColor", {26, executeForeColor, supported, enabledInRichlyEditable Text, stateNone, valueForeColor, notTextInsertion, doNotAllowExecutionWhenDisabl ed } },
1483 { "FormatBlock", {27, executeFormatBlock, supported, enabledInRichlyEdit ableText, stateNone, valueFormatBlock, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1484 { "ForwardDelete", {28, executeForwardDelete, supported, enabledInEditab leText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1485 { "HiliteColor", {29, executeBackColor, supported, enabledInRichlyEditab leText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1486 { "IgnoreSpelling", {30, executeIgnoreSpelling, supportedFromMenuOrKeyBi nding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllow ExecutionWhenDisabled } },
1487 { "Indent", {31, executeIndent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1488 { "InsertBacktab", {32, executeInsertBacktab, supportedFromMenuOrKeyBind ing, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExe cutionWhenDisabled } },
1489 { "InsertHTML", {33, executeInsertHTML, supported, enabledInEditableText , stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1490 { "InsertHorizontalRule", {34, executeInsertHorizontalRule, supported, e nabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowEx ecutionWhenDisabled } },
1491 { "InsertImage", {35, executeInsertImage, supported, enabledInRichlyEdit ableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisable d } },
1492 { "InsertLineBreak", {36, executeInsertLineBreak, supported, enabledInEd itableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabl ed } },
1493 { "InsertNewline", {37, executeInsertNewline, supportedFromMenuOrKeyBind ing, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExe cutionWhenDisabled } },
1494 { "InsertNewlineInQuotedContent", {38, executeInsertNewlineInQuotedConte nt, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInserti on, doNotAllowExecutionWhenDisabled } },
1495 { "InsertOrderedList", {39, executeInsertOrderedList, supported, enabled InRichlyEditableText, stateOrderedList, valueNull, notTextInsertion, doNotAllowE xecutionWhenDisabled } },
1496 { "InsertParagraph", {40, executeInsertParagraph, supported, enabledInEd itableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisab led } },
1497 { "InsertTab", {41, executeInsertTab, supportedFromMenuOrKeyBinding, ena bledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWh enDisabled } },
1498 { "InsertText", {42, executeInsertText, supported, enabledInEditableText , stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
1499 { "InsertUnorderedList", {43, executeInsertUnorderedList, supported, ena bledInRichlyEditableText, stateUnorderedList, valueNull, notTextInsertion, doNot AllowExecutionWhenDisabled } },
1500 { "Italic", {44, executeToggleItalic, supported, enabledInRichlyEditable Text, stateItalic, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1501 { "JustifyCenter", {45, executeJustifyCenter, supported, enabledInRichly EditableText, stateJustifyCenter, valueNull, notTextInsertion, doNotAllowExecuti onWhenDisabled } },
1502 { "JustifyFull", {46, executeJustifyFull, supported, enabledInRichlyEdit ableText, stateJustifyFull, valueNull, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1503 { "JustifyLeft", {47, executeJustifyLeft, supported, enabledInRichlyEdit ableText, stateJustifyLeft, valueNull, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1504 { "JustifyNone", {48, executeJustifyLeft, supported, enabledInRichlyEdit ableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisable d } },
1505 { "JustifyRight", {49, executeJustifyRight, supported, enabledInRichlyEd itableText, stateJustifyRight, valueNull, notTextInsertion, doNotAllowExecutionW henDisabled } },
1506 { "MakeTextWritingDirectionLeftToRight", {50, executeMakeTextWritingDire ctionLeftToRight, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, st ateTextWritingDirectionLeftToRight, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1507 { "MakeTextWritingDirectionNatural", {51, executeMakeTextWritingDirectio nNatural, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextW ritingDirectionNatural, valueNull, notTextInsertion, doNotAllowExecutionWhenDisa bled } },
1508 { "MakeTextWritingDirectionRightToLeft", {52, executeMakeTextWritingDire ctionRightToLeft, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, st ateTextWritingDirectionRightToLeft, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1509 { "MoveBackward", {53, executeMoveBackward, supportedFromMenuOrKeyBindin g, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1510 { "MoveBackwardAndModifySelection", {54, executeMoveBackwardAndModifySel ection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, s tateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1511 { "MoveDown", {55, executeMoveDown, supportedFromMenuOrKeyBinding, enabl edInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAl lowExecutionWhenDisabled } },
1512 { "MoveDownAndModifySelection", {56, executeMoveDownAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone , valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1513 { "MoveForward", {57, executeMoveForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, d oNotAllowExecutionWhenDisabled } },
1514 { "MoveForwardAndModifySelection", {58, executeMoveForwardAndModifySelec tion, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, sta teNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1515 { "MoveLeft", {59, executeMoveLeft, supportedFromMenuOrKeyBinding, enabl edInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAl lowExecutionWhenDisabled } },
1516 { "MoveLeftAndModifySelection", {60, executeMoveLeftAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone , valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1517 { "MovePageDown", {61, executeMovePageDown, supportedFromMenuOrKeyBindin g, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExec utionWhenDisabled } },
1518 { "MovePageDownAndModifySelection", {62, executeMovePageDownAndModifySel ection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, value Null, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1519 { "MovePageUp", {63, executeMovePageUp, supportedFromMenuOrKeyBinding, e nabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutio nWhenDisabled } },
1520 { "MovePageUpAndModifySelection", {64, executeMovePageUpAndModifySelecti on, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull , notTextInsertion, doNotAllowExecutionWhenDisabled } },
1521 { "MoveParagraphBackward", {65, executeMoveParagraphBackward, supportedF romMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1522 { "MoveParagraphBackwardAndModifySelection", {66, executeMoveParagraphBa ckwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection OrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1523 { "MoveParagraphForward", {67, executeMoveParagraphForward, supportedFro mMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, n otTextInsertion, doNotAllowExecutionWhenDisabled } },
1524 { "MoveParagraphForwardAndModifySelection", {68, executeMoveParagraphFor wardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOr CaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDi sabled } },
1525 { "MoveRight", {69, executeMoveRight, supportedFromMenuOrKeyBinding, ena bledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNot AllowExecutionWhenDisabled } },
1526 { "MoveRightAndModifySelection", {70, executeMoveRightAndModifySelection , supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNo ne, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1527 { "MoveToBeginningOfDocument", {71, executeMoveToBeginningOfDocument, su pportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, va lueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1528 { "MoveToBeginningOfDocumentAndModifySelection", {72, executeMoveToBegin ningOfDocumentAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleS electionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1529 { "MoveToBeginningOfLine", {73, executeMoveToBeginningOfLine, supportedF romMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1530 { "MoveToBeginningOfLineAndModifySelection", {74, executeMoveToBeginning OfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection OrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1531 { "MoveToBeginningOfParagraph", {75, executeMoveToBeginningOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1532 { "MoveToBeginningOfParagraphAndModifySelection", {76, executeMoveToBegi nningOfParagraphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibl eSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExe cutionWhenDisabled } },
1533 { "MoveToBeginningOfSentence", {77, executeMoveToBeginningOfSentence, su pportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, va lueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1534 { "MoveToBeginningOfSentenceAndModifySelection", {78, executeMoveToBegin ningOfSentenceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleS electionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1535 { "MoveToEndOfDocument", {79, executeMoveToEndOfDocument, supportedFromM enuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, not TextInsertion, doNotAllowExecutionWhenDisabled } },
1536 { "MoveToEndOfDocumentAndModifySelection", {80, executeMoveToEndOfDocume ntAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCa retBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisa bled } },
1537 { "MoveToEndOfLine", {81, executeMoveToEndOfLine, supportedFromMenuOrKey Binding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInse rtion, doNotAllowExecutionWhenDisabled } },
1538 { "MoveToEndOfLineAndModifySelection", {82, executeMoveToEndOfLineAndMod ifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrows ing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } } ,
1539 { "MoveToEndOfParagraph", {83, executeMoveToEndOfParagraph, supportedFro mMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, n otTextInsertion, doNotAllowExecutionWhenDisabled } },
1540 { "MoveToEndOfParagraphAndModifySelection", {84, executeMoveToEndOfParag raphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOr CaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDi sabled } },
1541 { "MoveToEndOfSentence", {85, executeMoveToEndOfSentence, supportedFromM enuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, not TextInsertion, doNotAllowExecutionWhenDisabled } },
1542 { "MoveToEndOfSentenceAndModifySelection", {86, executeMoveToEndOfSenten ceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCa retBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisa bled } },
1543 { "MoveToLeftEndOfLine", {87, executeMoveToLeftEndOfLine, supportedFromM enuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1544 { "MoveToLeftEndOfLineAndModifySelection", {88, executeMoveToLeftEndOfLi neAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stat eNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1545 { "MoveToRightEndOfLine", {89, executeMoveToRightEndOfLine, supportedFro mMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion , doNotAllowExecutionWhenDisabled } },
1546 { "MoveToRightEndOfLineAndModifySelection", {90, executeMoveToRightEndOf LineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, st ateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1547 { "MoveUp", {91, executeMoveUp, supportedFromMenuOrKeyBinding, enabledIn EditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowE xecutionWhenDisabled } },
1548 { "MoveUpAndModifySelection", {92, executeMoveUpAndModifySelection, supp ortedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, va lueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1549 { "MoveWordBackward", {93, executeMoveWordBackward, supportedFromMenuOrK eyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextIn sertion, doNotAllowExecutionWhenDisabled } },
1550 { "MoveWordBackwardAndModifySelection", {94, executeMoveWordBackwardAndM odifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBro wsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1551 { "MoveWordForward", {95, executeMoveWordForward, supportedFromMenuOrKey Binding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInse rtion, doNotAllowExecutionWhenDisabled } },
1552 { "MoveWordForwardAndModifySelection", {96, executeMoveWordForwardAndMod ifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrows ing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } } ,
1553 { "MoveWordLeft", {97, executeMoveWordLeft, supportedFromMenuOrKeyBindin g, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1554 { "MoveWordLeftAndModifySelection", {98, executeMoveWordLeftAndModifySel ection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, s tateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1555 { "MoveWordRight", {99, executeMoveWordRight, supportedFromMenuOrKeyBind ing, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertio n, doNotAllowExecutionWhenDisabled } },
1556 { "MoveWordRightAndModifySelection", {100, executeMoveWordRightAndModify Selection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing , stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1557 { "Outdent", {101, executeOutdent, supported, enabledInRichlyEditableTex t, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1558 { "OverWrite", {102, executeToggleOverwrite, supportedFromMenuOrKeyBindi ng, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAl lowExecutionWhenDisabled } },
1559 { "Paste", {103, executePaste, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
1560 { "PasteAndMatchStyle", {104, executePasteAndMatchStyle, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisable d } },
1561 { "PasteGlobalSelection", {105, executePasteGlobalSelection, supportedFr omMenuOrKeyBinding, enabledPaste, stateNone, valueNull, notTextInsertion, allowE xecutionWhenDisabled } },
1562 { "Print", {106, executePrint, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1563 { "Redo", {107, executeRedo, supported, enabledRedo, stateNone, valueNul l, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1564 { "RemoveFormat", {108, executeRemoveFormat, supported, enabledRangeInEd itableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisab led } },
1565 { "ScrollPageBackward", {109, executeScrollPageBackward, supportedFromMe nuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1566 { "ScrollPageForward", {110, executeScrollPageForward, supportedFromMenu OrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecuti onWhenDisabled } },
1567 { "ScrollLineUp", {111, executeScrollLineUp, supportedFromMenuOrKeyBindi ng, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisa bled } },
1568 { "ScrollLineDown", {112, executeScrollLineDown, supportedFromMenuOrKeyB inding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhen Disabled } },
1569 { "ScrollToBeginningOfDocument", {113, executeScrollToBeginningOfDocumen t, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertio n, doNotAllowExecutionWhenDisabled } },
1570 { "ScrollToEndOfDocument", {114, executeScrollToEndOfDocument, supported FromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllo wExecutionWhenDisabled } },
1571 { "SelectAll", {115, executeSelectAll, supported, enabled, stateNone, va lueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1572 { "SelectLine", {116, executeSelectLine, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1573 { "SelectParagraph", {117, executeSelectParagraph, supportedFromMenuOrKe yBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNot AllowExecutionWhenDisabled } },
1574 { "SelectSentence", {118, executeSelectSentence, supportedFromMenuOrKeyB inding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAl lowExecutionWhenDisabled } },
1575 { "SelectToMark", {119, executeSelectToMark, supportedFromMenuOrKeyBindi ng, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNo tAllowExecutionWhenDisabled } },
1576 { "SelectWord", {120, executeSelectWord, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1577 { "SetMark", {121, executeSetMark, supportedFromMenuOrKeyBinding, enable dVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWh enDisabled } },
1578 { "Strikethrough", {122, executeStrikethrough, supported, enabledInRichl yEditableText, stateStrikethrough, valueNull, notTextInsertion, doNotAllowExecut ionWhenDisabled } },
1579 { "StyleWithCSS", {123, executeStyleWithCSS, supported, enabled, stateSt yleWithCSS, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1580 { "Subscript", {124, executeSubscript, supported, enabledInRichlyEditabl eText, stateSubscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisab led } },
1581 { "Superscript", {125, executeSuperscript, supported, enabledInRichlyEdi tableText, stateSuperscript, valueNull, notTextInsertion, doNotAllowExecutionWhe nDisabled } },
1582 { "SwapWithMark", {126, executeSwapWithMark, supportedFromMenuOrKeyBindi ng, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNo tAllowExecutionWhenDisabled } },
1583 { "ToggleBold", {127, executeToggleBold, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion, doNotAllowE xecutionWhenDisabled } },
1584 { "ToggleItalic", {128, executeToggleItalic, supportedFromMenuOrKeyBindi ng, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion, doNot AllowExecutionWhenDisabled } },
1585 { "ToggleUnderline", {129, executeUnderline, supportedFromMenuOrKeyBindi ng, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion, do NotAllowExecutionWhenDisabled } },
1586 { "Transpose", {130, executeTranspose, supported, enableCaretInEditableT ext, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } } ,
1587 { "Underline", {131, executeUnderline, supported, enabledInRichlyEditabl eText, stateUnderline, valueNull, notTextInsertion, doNotAllowExecutionWhenDisab led } },
1588 { "Undo", {132, executeUndo, supported, enabledUndo, stateNone, valueNul l, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1589 { "Unlink", {133, executeUnlink, supported, enabledRangeInRichlyEditable Text, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1590 { "Unscript", {134, executeUnscript, supportedFromMenuOrKeyBinding, enab ledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecu tionWhenDisabled } },
1591 { "Unselect", {135, executeUnselect, supported, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1592 { "UseCSS", {136, executeUseCSS, supported, enabled, stateNone, valueNul l, notTextInsertion, doNotAllowExecutionWhenDisabled } },
1593 { "Yank", {137, executeYank, supportedFromMenuOrKeyBinding, enabledInEdi tableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabl ed } },
1594 { "YankAndSelect", {138, executeYankAndSelect, supportedFromMenuOrKeyBin ding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowE xecutionWhenDisabled } },
1595 };
1596
1597 // These unsupported commands are listed here since they appear in the Micro soft
1598 // documentation used as the starting point for our DOM executeCommand suppo rt.
1599 //
1600 // 2D-Position (not supported)
1601 // AbsolutePosition (not supported)
1602 // BlockDirLTR (not supported)
1603 // BlockDirRTL (not supported)
1604 // BrowseMode (not supported)
1605 // ClearAuthenticationCache (not supported)
1606 // CreateBookmark (not supported)
1607 // DirLTR (not supported)
1608 // DirRTL (not supported)
1609 // EditMode (not supported)
1610 // InlineDirLTR (not supported)
1611 // InlineDirRTL (not supported)
1612 // InsertButton (not supported)
1613 // InsertFieldSet (not supported)
1614 // InsertIFrame (not supported)
1615 // InsertInputButton (not supported)
1616 // InsertInputCheckbox (not supported)
1617 // InsertInputFileUpload (not supported)
1618 // InsertInputHidden (not supported)
1619 // InsertInputImage (not supported)
1620 // InsertInputPassword (not supported)
1621 // InsertInputRadio (not supported)
1622 // InsertInputReset (not supported)
1623 // InsertInputSubmit (not supported)
1624 // InsertInputText (not supported)
1625 // InsertMarquee (not supported)
1626 // InsertSelectDropDown (not supported)
1627 // InsertSelectListBox (not supported)
1628 // InsertTextArea (not supported)
1629 // LiveResize (not supported)
1630 // MultipleSelection (not supported)
1631 // Open (not supported)
1632 // PlayImage (not supported)
1633 // Refresh (not supported)
1634 // RemoveParaFormat (not supported)
1635 // SaveAs (not supported)
1636 // SizeToControl (not supported)
1637 // SizeToControlHeight (not supported)
1638 // SizeToControlWidth (not supported)
1639 // Stop (not supported)
1640 // StopImage (not supported)
1641 // Unbookmark (not supported)
1642
1643 CommandMap& commandMap = *new CommandMap;
1644 #if ENABLE(ASSERT)
1645 HashSet<int> idSet;
1646 #endif
1647 for (size_t i = 0; i < WTF_ARRAY_LENGTH(commands); ++i) {
1648 const CommandEntry& command = commands[i];
1649 ASSERT(!commandMap.get(command.name));
1650 commandMap.set(command.name, &command.command);
1651 #if ENABLE(ASSERT)
1652 ASSERT(!idSet.contains(command.command.idForUserMetrics));
1653 idSet.add(command.command.idForUserMetrics);
1654 #endif
1655 }
1656
1657 return commandMap;
1658 }
1659
1660 static const EditorInternalCommand* internalCommand(const String& commandName)
1661 {
1662 static const CommandMap& commandMap = createCommandMap();
1663 return commandName.isEmpty() ? 0 : commandMap.get(commandName);
1664 }
1665
1666 Editor::Command Editor::command(const String& commandName)
1667 {
1668 return Command(internalCommand(commandName), CommandFromMenuOrKeyBinding, m_ frame);
1669 }
1670
1671 Editor::Command Editor::command(const String& commandName, EditorCommandSource s ource)
1672 {
1673 return Command(internalCommand(commandName), source, m_frame);
1674 }
1675
1676 bool Editor::executeCommand(const String& commandName)
1677 {
1678 // Specially handling commands that Editor::execCommand does not directly
1679 // support.
1680 if (commandName == "DeleteToEndOfParagraph") {
1681 if (!deleteWithDirection(DirectionForward, ParagraphBoundary, true, fals e))
1682 deleteWithDirection(DirectionForward, CharacterGranularity, true, fa lse);
1683 return true;
1684 }
1685 if (commandName == "DeleteBackward")
1686 return command(AtomicString("BackwardDelete")).execute();
1687 if (commandName == "DeleteForward")
1688 return command(AtomicString("ForwardDelete")).execute();
1689 if (commandName == "AdvanceToNextMisspelling") {
1690 // Wee need to pass false here or else the currently selected word will never be skipped.
1691 spellChecker().advanceToNextMisspelling(false);
1692 return true;
1693 }
1694 if (commandName == "ToggleSpellPanel") {
1695 spellChecker().showSpellingGuessPanel();
1696 return true;
1697 }
1698 return command(commandName).execute();
1699 }
1700
1701 bool Editor::executeCommand(const String& commandName, const String& value)
1702 {
1703 // moveToBeginningOfDocument and moveToEndfDocument are only handled by WebK it for editable nodes.
1704 if (!canEdit() && commandName == "moveToBeginningOfDocument")
1705 return frame().eventHandler().bubblingScroll(ScrollUpIgnoringWritingMode , ScrollByDocument);
1706
1707 if (!canEdit() && commandName == "moveToEndOfDocument")
1708 return frame().eventHandler().bubblingScroll(ScrollDownIgnoringWritingMo de, ScrollByDocument);
1709
1710 if (commandName == "showGuessPanel") {
1711 spellChecker().showSpellingGuessPanel();
1712 return true;
1713 }
1714
1715 return command(commandName).execute(value);
1716 }
1717
1718 Editor::Command::Command()
1719 : m_command(0)
1720 {
1721 }
1722
1723 Editor::Command::Command(const EditorInternalCommand* command, EditorCommandSour ce source, PassRefPtrWillBeRawPtr<LocalFrame> frame)
1724 : m_command(command)
1725 , m_source(source)
1726 , m_frame(command ? frame : nullptr)
1727 {
1728 // Use separate assertions so we can tell which bad thing happened.
1729 if (!command)
1730 ASSERT(!m_frame);
1731 else
1732 ASSERT(m_frame);
1733 }
1734
1735 bool Editor::Command::execute(const String& parameter, Event* triggeringEvent) c onst
1736 {
1737 if (!isEnabled(triggeringEvent)) {
1738 // Let certain commands be executed when performed explicitly even if th ey are disabled.
1739 if (!isSupported() || !m_frame || !m_command->allowExecutionWhenDisabled )
1740 return false;
1741 }
1742 frame().document()->updateLayoutIgnorePendingStylesheets();
1743 Platform::current()->histogramSparse("WebCore.Editing.Commands", m_command-> idForUserMetrics);
1744 return m_command->execute(*m_frame, triggeringEvent, m_source, parameter);
1745 }
1746
1747 bool Editor::Command::execute(Event* triggeringEvent) const
1748 {
1749 return execute(String(), triggeringEvent);
1750 }
1751
1752 bool Editor::Command::isSupported() const
1753 {
1754 if (!m_command)
1755 return false;
1756 switch (m_source) {
1757 case CommandFromMenuOrKeyBinding:
1758 return true;
1759 case CommandFromDOM:
1760 return m_command->isSupportedFromDOM(m_frame.get());
1761 }
1762 ASSERT_NOT_REACHED();
1763 return false;
1764 }
1765
1766 bool Editor::Command::isEnabled(Event* triggeringEvent) const
1767 {
1768 if (!isSupported() || !m_frame)
1769 return false;
1770 return m_command->isEnabled(*m_frame, triggeringEvent, m_source);
1771 }
1772
1773 TriState Editor::Command::state(Event* triggeringEvent) const
1774 {
1775 if (!isSupported() || !m_frame)
1776 return FalseTriState;
1777 return m_command->state(*m_frame, triggeringEvent);
1778 }
1779
1780 String Editor::Command::value(Event* triggeringEvent) const
1781 {
1782 if (!isSupported() || !m_frame)
1783 return String();
1784 if (m_command->value == valueNull && m_command->state != stateNone)
1785 return m_command->state(*m_frame, triggeringEvent) == TrueTriState ? "tr ue" : "false";
1786 return m_command->value(*m_frame, triggeringEvent);
1787 }
1788
1789 bool Editor::Command::isTextInsertion() const
1790 {
1791 return m_command && m_command->isTextInsertion;
1792 }
1793
1794 int Editor::Command::idForHistogram() const
1795 {
1796 return isSupported() ? m_command->idForUserMetrics : 0;
1797 }
1798
1799 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698