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

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

Powered by Google App Engine
This is Rietveld 408576698