| 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 |