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