OLD | NEW |
| (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 | |
OLD | NEW |