Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2010 Igalia S.L | 3 * Copyright (C) 2010 Igalia S.L |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "config.h" | 27 #include "config.h" |
| 28 #include "core/page/ContextMenuController.h" | 28 #include "core/page/ContextMenuController.h" |
| 29 | 29 |
| 30 #include "core/dom/Document.h" | 30 #include "core/dom/Document.h" |
| 31 #include "core/dom/DocumentFragment.h" | |
| 32 #include "core/dom/Event.h" | 31 #include "core/dom/Event.h" |
| 33 #include "core/dom/EventNames.h" | 32 #include "core/dom/EventNames.h" |
| 34 #include "core/dom/ExceptionCodePlaceholder.h" | |
| 35 #include "core/dom/MouseEvent.h" | 33 #include "core/dom/MouseEvent.h" |
| 36 #include "core/dom/Node.h" | 34 #include "core/dom/Node.h" |
| 37 #include "core/dom/UserTypingGestureIndicator.h" | |
| 38 #include "core/editing/Editor.h" | |
| 39 #include "core/editing/FrameSelection.h" | 35 #include "core/editing/FrameSelection.h" |
| 40 #include "core/editing/ReplaceSelectionCommand.h" | |
| 41 #include "core/editing/TextIterator.h" | |
| 42 #include "core/editing/TypingCommand.h" | |
| 43 #include "core/editing/markup.h" | |
| 44 #include "core/history/BackForwardController.h" | |
| 45 #include "core/html/HTMLFormElement.h" | |
| 46 #include "core/inspector/InspectorController.h" | |
| 47 #include "core/loader/DocumentLoader.h" | |
| 48 #include "core/loader/FormState.h" | |
| 49 #include "core/loader/FrameLoadRequest.h" | |
| 50 #include "core/loader/FrameLoader.h" | |
| 51 #include "core/loader/FrameLoaderClient.h" | |
| 52 #include "core/loader/NavigationAction.h" | |
| 53 #include "core/page/Chrome.h" | |
| 54 #include "core/page/ContextMenuClient.h" | 36 #include "core/page/ContextMenuClient.h" |
| 55 #include "core/page/ContextMenuProvider.h" | 37 #include "core/page/ContextMenuProvider.h" |
| 56 #include "core/page/EditorClient.h" | |
| 57 #include "core/page/EventHandler.h" | 38 #include "core/page/EventHandler.h" |
| 58 #include "core/page/Frame.h" | 39 #include "core/page/Frame.h" |
| 59 #include "core/page/Page.h" | 40 #include "core/page/Page.h" |
| 60 #include "core/page/Settings.h" | |
| 61 #include "core/page/WindowFeatures.h" | |
| 62 #include "core/platform/ContextMenu.h" | 41 #include "core/platform/ContextMenu.h" |
| 63 #include "core/platform/ContextMenuItem.h" | 42 #include "core/platform/ContextMenuItem.h" |
| 64 #include "core/platform/LocalizedStrings.h" | |
| 65 #include "core/platform/PlatformEvent.h" | |
| 66 #include "core/platform/network/ResourceRequest.h" | |
| 67 #include "core/rendering/HitTestRequest.h" | |
| 68 #include "core/rendering/HitTestResult.h" | 43 #include "core/rendering/HitTestResult.h" |
| 69 #include "core/rendering/RenderObject.h" | |
| 70 #include <wtf/unicode/CharacterNames.h> | |
| 71 #include <wtf/unicode/Unicode.h> | |
| 72 | |
| 73 using namespace WTF; | |
| 74 using namespace Unicode; | |
| 75 | 44 |
| 76 namespace WebCore { | 45 namespace WebCore { |
| 77 | 46 |
| 78 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie nt) | 47 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie nt) |
| 79 : m_page(page) | 48 : m_page(page) |
| 80 , m_client(client) | 49 , m_client(client) |
| 81 { | 50 { |
| 82 ASSERT_ARG(page, page); | 51 ASSERT_ARG(page, page); |
| 83 ASSERT_ARG(client, client); | 52 ASSERT_ARG(client, client); |
| 84 } | 53 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 99 m_menuProvider->contextMenuCleared(); | 68 m_menuProvider->contextMenuCleared(); |
| 100 m_menuProvider = 0; | 69 m_menuProvider = 0; |
| 101 } | 70 } |
| 102 | 71 |
| 103 void ContextMenuController::handleContextMenuEvent(Event* event) | 72 void ContextMenuController::handleContextMenuEvent(Event* event) |
| 104 { | 73 { |
| 105 m_contextMenu = createContextMenu(event); | 74 m_contextMenu = createContextMenu(event); |
| 106 if (!m_contextMenu) | 75 if (!m_contextMenu) |
| 107 return; | 76 return; |
| 108 | 77 |
| 109 populate(); | |
| 110 | |
| 111 showContextMenu(event); | 78 showContextMenu(event); |
| 112 } | 79 } |
| 113 | 80 |
| 114 static PassOwnPtr<ContextMenuItem> separatorItem() | |
| 115 { | |
| 116 return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoActio n, String())); | |
| 117 } | |
| 118 | |
| 119 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenu Provider> menuProvider) | 81 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenu Provider> menuProvider) |
| 120 { | 82 { |
| 121 m_menuProvider = menuProvider; | 83 m_menuProvider = menuProvider; |
| 122 | 84 |
| 123 m_contextMenu = createContextMenu(event); | 85 m_contextMenu = createContextMenu(event); |
| 124 if (!m_contextMenu) { | 86 if (!m_contextMenu) { |
| 125 clearContextMenu(); | 87 clearContextMenu(); |
| 126 return; | 88 return; |
| 127 } | 89 } |
| 128 | 90 |
| 129 m_menuProvider->populateContextMenu(m_contextMenu.get()); | 91 m_menuProvider->populateContextMenu(m_contextMenu.get()); |
| 130 if (m_hitTestResult.isSelected()) { | |
| 131 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 132 populate(); | |
| 133 } | |
| 134 showContextMenu(event); | 92 showContextMenu(event); |
| 135 } | 93 } |
| 136 | 94 |
| 137 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event) | 95 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event) |
| 138 { | 96 { |
| 139 ASSERT(event); | 97 ASSERT(event); |
| 140 | 98 |
| 141 if (!event->isMouseEvent()) | 99 if (!event->isMouseEvent()) |
| 142 return nullptr; | 100 return nullptr; |
| 143 | 101 |
| 144 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); | 102 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); |
| 145 HitTestResult result(mouseEvent->absoluteLocation()); | 103 HitTestResult result(mouseEvent->absoluteLocation()); |
| 146 | 104 |
| 147 if (Frame* frame = event->target()->toNode()->document()->frame()) | 105 if (Frame* frame = event->target()->toNode()->document()->frame()) |
| 148 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absolut eLocation()); | 106 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absolut eLocation()); |
| 149 | 107 |
| 150 if (!result.innerNonSharedNode()) | 108 if (!result.innerNonSharedNode()) |
| 151 return nullptr; | 109 return nullptr; |
| 152 | 110 |
| 153 m_hitTestResult = result; | 111 m_hitTestResult = result; |
| 154 | 112 |
| 155 return adoptPtr(new ContextMenu); | 113 return adoptPtr(new ContextMenu); |
| 156 } | 114 } |
| 157 | 115 |
| 158 void ContextMenuController::showContextMenu(Event* event) | 116 void ContextMenuController::showContextMenu(Event* event) |
| 159 { | 117 { |
| 160 addInspectElementItem(); | 118 m_client->showContextMenu(m_contextMenu.get()); |
| 161 | |
| 162 m_contextMenu = m_client->customizeMenu(m_contextMenu.release()); | |
| 163 event->setDefaultHandled(); | 119 event->setDefaultHandled(); |
| 164 } | 120 } |
| 165 | 121 |
| 166 static void openNewWindow(const KURL& urlToLoad, Frame* frame) | |
| 167 { | |
| 168 if (Page* oldPage = frame->page()) { | |
| 169 FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRe quest(urlToLoad, frame->loader()->outgoingReferrer())); | |
| 170 Page* newPage = oldPage; | |
| 171 if (!frame->settings() || frame->settings()->supportsMultipleWindows()) { | |
| 172 newPage = oldPage->chrome()->createWindow(frame, request, WindowFeat ures(), NavigationAction(request.resourceRequest())); | |
| 173 if (!newPage) | |
| 174 return; | |
| 175 newPage->chrome()->show(); | |
| 176 } | |
| 177 newPage->mainFrame()->loader()->loadFrameRequest(request, false, 0, 0, M aybeSendReferrer); | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item) | 122 void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item) |
| 182 { | 123 { |
| 183 ASSERT(item->type() == ActionType || item->type() == CheckableActionType); | 124 ASSERT(item->type() == ActionType || item->type() == CheckableActionType); |
| 184 | 125 |
| 185 if (item->action() >= ContextMenuItemBaseApplicationTag) | 126 if (item->action() < ContextMenuItemBaseCustomTag || item->action() > Contex tMenuItemLastCustomTag) |
| 186 return; | 127 return; |
| 187 | 128 |
| 188 if (item->action() >= ContextMenuItemBaseCustomTag) { | 129 ASSERT(m_menuProvider); |
| 189 ASSERT(m_menuProvider); | 130 m_menuProvider->contextMenuItemSelected(item); |
| 190 m_menuProvider->contextMenuItemSelected(item); | |
| 191 return; | |
| 192 } | |
| 193 | |
| 194 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame(); | |
| 195 if (!frame) | |
| 196 return; | |
| 197 | |
| 198 switch (item->action()) { | |
| 199 case ContextMenuItemTagOpenLinkInNewWindow: | |
| 200 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame); | |
| 201 break; | |
| 202 case ContextMenuItemTagDownloadLinkToDisk: | |
| 203 break; | |
| 204 case ContextMenuItemTagCopyLinkToClipboard: | |
| 205 frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestRes ult.textContent()); | |
| 206 break; | |
| 207 case ContextMenuItemTagOpenImageInNewWindow: | |
| 208 openNewWindow(m_hitTestResult.absoluteImageURL(), frame); | |
| 209 break; | |
| 210 case ContextMenuItemTagDownloadImageToDisk: | |
| 211 break; | |
| 212 case ContextMenuItemTagCopyImageToClipboard: | |
| 213 // FIXME: The Pasteboard class is not written yet | |
| 214 // For now, call into the client. This is temporary! | |
| 215 frame->editor()->copyImage(m_hitTestResult); | |
| 216 break; | |
| 217 case ContextMenuItemTagOpenMediaInNewWindow: | |
| 218 openNewWindow(m_hitTestResult.absoluteMediaURL(), frame); | |
| 219 break; | |
| 220 case ContextMenuItemTagCopyMediaLinkToClipboard: | |
| 221 frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestRe sult.textContent()); | |
| 222 break; | |
| 223 case ContextMenuItemTagToggleMediaControls: | |
| 224 m_hitTestResult.toggleMediaControlsDisplay(); | |
| 225 break; | |
| 226 case ContextMenuItemTagToggleMediaLoop: | |
| 227 m_hitTestResult.toggleMediaLoopPlayback(); | |
| 228 break; | |
| 229 case ContextMenuItemTagEnterVideoFullscreen: | |
| 230 m_hitTestResult.enterFullscreenForVideo(); | |
| 231 break; | |
| 232 case ContextMenuItemTagMediaPlayPause: | |
| 233 m_hitTestResult.toggleMediaPlayState(); | |
| 234 break; | |
| 235 case ContextMenuItemTagMediaMute: | |
| 236 m_hitTestResult.toggleMediaMuteState(); | |
| 237 break; | |
| 238 case ContextMenuItemTagOpenFrameInNewWindow: { | |
| 239 DocumentLoader* loader = frame->loader()->documentLoader(); | |
| 240 if (!loader->unreachableURL().isEmpty()) | |
| 241 openNewWindow(loader->unreachableURL(), frame); | |
| 242 else | |
| 243 openNewWindow(loader->url(), frame); | |
| 244 break; | |
| 245 } | |
| 246 case ContextMenuItemTagCopy: | |
| 247 frame->editor()->copy(); | |
| 248 break; | |
| 249 case ContextMenuItemTagGoBack: | |
| 250 if (Page* page = frame->page()) | |
| 251 page->backForward()->goBackOrForward(-1); | |
| 252 break; | |
| 253 case ContextMenuItemTagGoForward: | |
| 254 if (Page* page = frame->page()) | |
| 255 page->backForward()->goBackOrForward(1); | |
| 256 break; | |
| 257 case ContextMenuItemTagStop: | |
| 258 frame->loader()->stop(); | |
| 259 break; | |
| 260 case ContextMenuItemTagReload: | |
| 261 frame->loader()->reload(); | |
| 262 break; | |
| 263 case ContextMenuItemTagCut: | |
| 264 frame->editor()->command("Cut").execute(); | |
| 265 break; | |
| 266 case ContextMenuItemTagPaste: | |
| 267 frame->editor()->command("Paste").execute(); | |
| 268 break; | |
| 269 case ContextMenuItemTagSpellingGuess: { | |
| 270 FrameSelection* frameSelection = frame->selection(); | |
| 271 if (frame->editor()->shouldInsertText(item->title(), frameSelection->toN ormalizedRange().get(), EditorInsertActionPasted)) { | |
| 272 Document* document = frame->document(); | |
| 273 ReplaceSelectionCommand::CommandOptions replaceOptions = ReplaceSele ctionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting | ReplaceSele ctionCommand::SelectReplacement; | |
| 274 ASSERT(frame->editor()->selectedText().length()); | |
| 275 RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::c reate(document, createFragmentFromMarkup(document, item->title(), ""), replaceOp tions); | |
| 276 applyCommand(command); | |
| 277 frameSelection->revealSelection(ScrollAlignment::alignToEdgeIfNeeded ); | |
| 278 } | |
| 279 break; | |
| 280 } | |
| 281 case ContextMenuItemTagIgnoreSpelling: | |
| 282 frame->editor()->ignoreSpelling(); | |
| 283 break; | |
| 284 case ContextMenuItemTagLearnSpelling: | |
| 285 frame->editor()->learnSpelling(); | |
| 286 break; | |
| 287 case ContextMenuItemTagSearchWeb: | |
| 288 break; | |
| 289 case ContextMenuItemTagLookUpInDictionary: | |
| 290 break; | |
| 291 case ContextMenuItemTagOpenLink: | |
| 292 if (Frame* targetFrame = m_hitTestResult.targetFrame()) | |
| 293 targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->docu ment()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), fra me->loader()->outgoingReferrer())), false, 0, 0, MaybeSendReferrer); | |
| 294 else | |
| 295 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame); | |
| 296 break; | |
| 297 case ContextMenuItemTagOpenLinkInThisWindow: | |
| 298 frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->se curityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader ()->outgoingReferrer())), false, 0, 0, MaybeSendReferrer); | |
| 299 break; | |
| 300 case ContextMenuItemTagBold: | |
| 301 frame->editor()->command("ToggleBold").execute(); | |
| 302 break; | |
| 303 case ContextMenuItemTagItalic: | |
| 304 frame->editor()->command("ToggleItalic").execute(); | |
| 305 break; | |
| 306 case ContextMenuItemTagUnderline: | |
| 307 frame->editor()->toggleUnderline(); | |
| 308 break; | |
| 309 case ContextMenuItemTagOutline: | |
| 310 // We actually never enable this because CSS does not have a way to spec ify an outline font, | |
| 311 // which may make this difficult to implement. Maybe a special case of t ext-shadow? | |
| 312 break; | |
| 313 case ContextMenuItemTagStartSpeaking: | |
| 314 break; | |
| 315 case ContextMenuItemTagStopSpeaking: | |
| 316 break; | |
| 317 case ContextMenuItemTagDefaultDirection: | |
| 318 frame->editor()->setBaseWritingDirection(NaturalWritingDirection); | |
| 319 break; | |
| 320 case ContextMenuItemTagLeftToRight: | |
| 321 frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection); | |
| 322 break; | |
| 323 case ContextMenuItemTagRightToLeft: | |
| 324 frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection); | |
| 325 break; | |
| 326 case ContextMenuItemTagTextDirectionDefault: | |
| 327 frame->editor()->command("MakeTextWritingDirectionNatural").execute(); | |
| 328 break; | |
| 329 case ContextMenuItemTagTextDirectionLeftToRight: | |
| 330 frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute( ); | |
| 331 break; | |
| 332 case ContextMenuItemTagTextDirectionRightToLeft: | |
| 333 frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute( ); | |
| 334 break; | |
| 335 case ContextMenuItemTagShowSpellingPanel: | |
| 336 frame->editor()->showSpellingGuessPanel(); | |
| 337 break; | |
| 338 case ContextMenuItemTagCheckSpelling: | |
| 339 frame->editor()->advanceToNextMisspelling(); | |
| 340 break; | |
| 341 case ContextMenuItemTagCheckSpellingWhileTyping: | |
| 342 frame->editor()->toggleContinuousSpellChecking(); | |
| 343 break; | |
| 344 case ContextMenuItemTagCheckGrammarWithSpelling: | |
| 345 break; | |
| 346 case ContextMenuItemTagInspectElement: | |
| 347 if (Page* page = frame->page()) | |
| 348 page->inspectorController()->inspect(m_hitTestResult.innerNonSharedN ode()); | |
| 349 break; | |
| 350 default: | |
| 351 break; | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* p arentMenu) | |
| 356 { | |
| 357 checkOrEnableIfNeeded(menuItem); | |
| 358 if (parentMenu) | |
| 359 parentMenu->appendItem(menuItem); | |
| 360 } | |
| 361 | |
| 362 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenu Item) | |
| 363 { | |
| 364 ContextMenu fontMenu; | |
| 365 | |
| 366 ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMen uItemTagBold()); | |
| 367 ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contex tMenuItemTagItalic()); | |
| 368 ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline()); | |
| 369 ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuIt emTagOutline()); | |
| 370 appendItem(bold, &fontMenu); | |
| 371 appendItem(italic, &fontMenu); | |
| 372 appendItem(underline, &fontMenu); | |
| 373 appendItem(outline, &fontMenu); | |
| 374 | |
| 375 fontMenuItem.setSubMenu(&fontMenu); | |
| 376 } | |
| 377 | |
| 378 | |
| 379 void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenu Item& spellingAndGrammarMenuItem) | |
| 380 { | |
| 381 ContextMenu spellingAndGrammarMenu; | |
| 382 | |
| 383 ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpelling Panel, | |
| 384 contextMenuItemTagShowSpellingPanel(true)); | |
| 385 ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, | |
| 386 contextMenuItemTagCheckSpelling()); | |
| 387 ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckS pellingWhileTyping, | |
| 388 contextMenuItemTagCheckSpellingWhileTyping()); | |
| 389 ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagC heckGrammarWithSpelling, | |
| 390 contextMenuItemTagCheckGrammarWithSpelling()); | |
| 391 | |
| 392 appendItem(showSpellingPanel, &spellingAndGrammarMenu); | |
| 393 appendItem(checkSpelling, &spellingAndGrammarMenu); | |
| 394 appendItem(checkAsYouType, &spellingAndGrammarMenu); | |
| 395 appendItem(grammarWithSpelling, &spellingAndGrammarMenu); | |
| 396 | |
| 397 spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu); | |
| 398 } | |
| 399 | |
| 400 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuIt em& writingDirectionMenuItem) | |
| 401 { | |
| 402 ContextMenu writingDirectionMenu; | |
| 403 | |
| 404 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection, | |
| 405 contextMenuItemTagDefaultDirection()); | |
| 406 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, cont extMenuItemTagLeftToRight()); | |
| 407 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, cont extMenuItemTagRightToLeft()); | |
| 408 | |
| 409 appendItem(defaultItem, &writingDirectionMenu); | |
| 410 appendItem(ltr, &writingDirectionMenu); | |
| 411 appendItem(rtl, &writingDirectionMenu); | |
| 412 | |
| 413 writingDirectionMenuItem.setSubMenu(&writingDirectionMenu); | |
| 414 } | |
| 415 | |
| 416 void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem) | |
| 417 { | |
| 418 ContextMenu textDirectionMenu; | |
| 419 | |
| 420 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefau lt, contextMenuItemTagDefaultDirection()); | |
| 421 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeft ToRight, contextMenuItemTagLeftToRight()); | |
| 422 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRigh tToLeft, contextMenuItemTagRightToLeft()); | |
| 423 | |
| 424 appendItem(defaultItem, &textDirectionMenu); | |
| 425 appendItem(ltr, &textDirectionMenu); | |
| 426 appendItem(rtl, &textDirectionMenu); | |
| 427 | |
| 428 textDirectionMenuItem.setSubMenu(&textDirectionMenu); | |
| 429 } | |
| 430 | |
| 431 static bool selectionContainsPossibleWord(Frame* frame) | |
| 432 { | |
| 433 // Current algorithm: look for a character that's not just a separator. | |
| 434 for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atE nd(); it.advance()) { | |
| 435 int length = it.length(); | |
| 436 for (int i = 0; i < length; ++i) | |
| 437 if (!(category(it.characterAt(i)) & (Separator_Space | Separator_Lin e | Separator_Paragraph))) | |
| 438 return true; | |
| 439 } | |
| 440 return false; | |
| 441 } | |
| 442 | |
| 443 void ContextMenuController::populate() | |
| 444 { | |
| 445 ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, context MenuItemTagOpenLink()); | |
| 446 ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLi nkInNewWindow, | |
| 447 contextMenuItemTagOpenLinkInNewWindow()); | |
| 448 ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkT oDisk, | |
| 449 contextMenuItemTagDownloadLinkToDisk()); | |
| 450 ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboa rd, | |
| 451 contextMenuItemTagCopyLinkToClipboard()); | |
| 452 ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenI mageInNewWindow, | |
| 453 contextMenuItemTagOpenImageInNewWindow()); | |
| 454 ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImag eToDisk, | |
| 455 contextMenuItemTagDownloadImageToDisk()); | |
| 456 ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipb oard, | |
| 457 contextMenuItemTagCopyImageToClipboard()); | |
| 458 ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenM ediaInNewWindow, String()); | |
| 459 ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLin kToClipboard, | |
| 460 String()); | |
| 461 ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause, | |
| 462 contextMenuItemTagMediaPlay()); | |
| 463 ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute, | |
| 464 contextMenuItemTagMediaMute()); | |
| 465 ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagT oggleMediaControls, | |
| 466 contextMenuItemTagToggleMediaControls()); | |
| 467 ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggl eMediaLoop, | |
| 468 contextMenuItemTagToggleMediaLoop()); | |
| 469 ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVide oFullscreen, | |
| 470 contextMenuItemTagEnterVideoFullscreen()); | |
| 471 ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, conte xtMenuItemTagSearchWeb()); | |
| 472 ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItem TagCopy()); | |
| 473 ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuIt emTagGoBack()); | |
| 474 ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contex tMenuItemTagGoForward()); | |
| 475 ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItem TagStop()); | |
| 476 ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenu ItemTagReload()); | |
| 477 ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWi ndow, | |
| 478 contextMenuItemTagOpenFrameInNewWindow()); | |
| 479 ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound, | |
| 480 contextMenuItemTagNoGuessesFound()); | |
| 481 ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpell ing, | |
| 482 contextMenuItemTagIgnoreSpelling()); | |
| 483 ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpellin g, | |
| 484 contextMenuItemTagLearnSpelling()); | |
| 485 ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGramma r, | |
| 486 contextMenuItemTagIgnoreGrammar()); | |
| 487 ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTa gCut()); | |
| 488 ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuIt emTagPaste()); | |
| 489 | |
| 490 Node* node = m_hitTestResult.innerNonSharedNode(); | |
| 491 if (!node) | |
| 492 return; | |
| 493 Frame* frame = node->document()->frame(); | |
| 494 if (!frame) | |
| 495 return; | |
| 496 | |
| 497 if (!m_hitTestResult.isContentEditable()) { | |
| 498 FrameLoader* loader = frame->loader(); | |
| 499 KURL linkURL = m_hitTestResult.absoluteLinkURL(); | |
| 500 if (!linkURL.isEmpty()) { | |
| 501 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) { | |
| 502 appendItem(OpenLinkItem, m_contextMenu.get()); | |
| 503 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get()); | |
| 504 appendItem(DownloadFileItem, m_contextMenu.get()); | |
| 505 } | |
| 506 appendItem(CopyLinkItem, m_contextMenu.get()); | |
| 507 } | |
| 508 | |
| 509 KURL imageURL = m_hitTestResult.absoluteImageURL(); | |
| 510 if (!imageURL.isEmpty()) { | |
| 511 if (!linkURL.isEmpty()) | |
| 512 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 513 | |
| 514 appendItem(OpenImageInNewWindowItem, m_contextMenu.get()); | |
| 515 appendItem(DownloadImageItem, m_contextMenu.get()); | |
| 516 if (imageURL.isLocalFile() || m_hitTestResult.image()) | |
| 517 appendItem(CopyImageItem, m_contextMenu.get()); | |
| 518 } | |
| 519 | |
| 520 KURL mediaURL = m_hitTestResult.absoluteMediaURL(); | |
| 521 if (!mediaURL.isEmpty()) { | |
| 522 if (!linkURL.isEmpty() || !imageURL.isEmpty()) | |
| 523 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 524 | |
| 525 appendItem(MediaPlayPause, m_contextMenu.get()); | |
| 526 appendItem(MediaMute, m_contextMenu.get()); | |
| 527 appendItem(ToggleMediaControls, m_contextMenu.get()); | |
| 528 appendItem(ToggleMediaLoop, m_contextMenu.get()); | |
| 529 appendItem(EnterVideoFullscreen, m_contextMenu.get()); | |
| 530 | |
| 531 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 532 appendItem(CopyMediaLinkItem, m_contextMenu.get()); | |
| 533 appendItem(OpenMediaInNewWindowItem, m_contextMenu.get()); | |
| 534 } | |
| 535 | |
| 536 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) { | |
| 537 if (m_hitTestResult.isSelected()) { | |
| 538 if (selectionContainsPossibleWord(frame)) { | |
| 539 appendItem(SearchWebItem, m_contextMenu.get()); | |
| 540 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 541 } | |
| 542 | |
| 543 appendItem(CopyItem, m_contextMenu.get()); | |
| 544 } else { | |
| 545 if (!(frame->page() && frame->page()->inspectorController()->has InspectorFrontendClient())) { | |
| 546 if (frame->page() && frame->page()->backForward()->canGoBack OrForward(-1)) | |
| 547 appendItem(BackItem, m_contextMenu.get()); | |
| 548 | |
| 549 if (frame->page() && frame->page()->backForward()->canGoBack OrForward(1)) | |
| 550 appendItem(ForwardItem, m_contextMenu.get()); | |
| 551 | |
| 552 // use isLoadingInAPISense rather than isLoading because Sto p/Reload are | |
| 553 // intended to match WebKit's API, not WebCore's internal no tion of loading status | |
| 554 if (loader->documentLoader()->isLoadingInAPISense()) | |
| 555 appendItem(StopItem, m_contextMenu.get()); | |
| 556 else | |
| 557 appendItem(ReloadItem, m_contextMenu.get()); | |
| 558 } | |
| 559 | |
| 560 if (frame->page() && frame != frame->page()->mainFrame()) | |
| 561 appendItem(OpenFrameItem, m_contextMenu.get()); | |
| 562 } | |
| 563 } | |
| 564 } else { // Make an editing context menu | |
| 565 FrameSelection* selection = frame->selection(); | |
| 566 bool inPasswordField = selection->isInPasswordField(); | |
| 567 if (!inPasswordField) { | |
| 568 bool haveContextMenuItemsForMisspellingOrGrammer = false; | |
| 569 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledF or(node); | |
| 570 if (spellCheckingEnabled) { | |
| 571 // Consider adding spelling-related or grammar-related context m enu items (never both, since a single selected range | |
| 572 // is never considered a misspelling and bad grammar at the same time) | |
| 573 bool misspelling; | |
| 574 bool badGrammar; | |
| 575 Vector<String> guesses = frame->editor()->guessesForMisspelledOr Ungrammatical(misspelling, badGrammar); | |
|
adamk
2013/05/14 00:30:52
Just happened to be looking at the code for guesse
groby-ooo-7-16
2013/05/14 00:57:54
I'm not sure what side effects you're seeing there
adamk
2013/05/14 01:05:12
The call sequence I'm worried about is:
Editor::g
| |
| 576 if (misspelling || badGrammar) { | |
| 577 size_t size = guesses.size(); | |
| 578 if (!size) { | |
| 579 // If there's bad grammar but no suggestions (e.g., repe ated word), just leave off the suggestions | |
| 580 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit) | |
| 581 if (misspelling) { | |
| 582 appendItem(NoGuessesItem, m_contextMenu.get()); | |
| 583 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 584 } | |
| 585 } else { | |
| 586 for (unsigned i = 0; i < size; i++) { | |
| 587 const String &guess = guesses[i]; | |
| 588 if (!guess.isEmpty()) { | |
| 589 ContextMenuItem item(ActionType, ContextMenuItem TagSpellingGuess, guess); | |
| 590 appendItem(item, m_contextMenu.get()); | |
| 591 } | |
| 592 } | |
| 593 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 594 } | |
| 595 if (misspelling) { | |
| 596 appendItem(IgnoreSpellingItem, m_contextMenu.get()); | |
| 597 appendItem(LearnSpellingItem, m_contextMenu.get()); | |
| 598 } else | |
| 599 appendItem(IgnoreGrammarItem, m_contextMenu.get()); | |
| 600 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 601 haveContextMenuItemsForMisspellingOrGrammer = true; | |
| 602 } | |
| 603 } | |
| 604 } | |
| 605 | |
| 606 FrameLoader* loader = frame->loader(); | |
| 607 KURL linkURL = m_hitTestResult.absoluteLinkURL(); | |
| 608 if (!linkURL.isEmpty()) { | |
| 609 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) { | |
| 610 appendItem(OpenLinkItem, m_contextMenu.get()); | |
| 611 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get()); | |
| 612 appendItem(DownloadFileItem, m_contextMenu.get()); | |
| 613 } | |
| 614 appendItem(CopyLinkItem, m_contextMenu.get()); | |
| 615 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 616 } | |
| 617 | |
| 618 if (m_hitTestResult.isSelected() && !inPasswordField && selectionContain sPossibleWord(frame)) { | |
| 619 appendItem(SearchWebItem, m_contextMenu.get()); | |
| 620 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 621 } | |
| 622 | |
| 623 appendItem(CutItem, m_contextMenu.get()); | |
| 624 appendItem(CopyItem, m_contextMenu.get()); | |
| 625 appendItem(PasteItem, m_contextMenu.get()); | |
| 626 | |
| 627 if (!inPasswordField) { | |
| 628 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 629 ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuI temTagSpellingMenu, | |
| 630 contextMenuItemTagSpellingMenu()); | |
| 631 createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem) ; | |
| 632 appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get()); | |
| 633 bool shouldShowFontMenu = true; | |
| 634 if (shouldShowFontMenu) { | |
| 635 ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFont Menu, | |
| 636 contextMenuItemTagFontMenu()); | |
| 637 createAndAppendFontSubMenu(FontMenuItem); | |
| 638 appendItem(FontMenuItem, m_contextMenu.get()); | |
| 639 } | |
| 640 ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuIte mTagWritingDirectionMenu, | |
| 641 contextMenuItemTagWritingDirectionMenu()); | |
| 642 createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem); | |
| 643 appendItem(WritingDirectionMenuItem, m_contextMenu.get()); | |
| 644 if (Page* page = frame->page()) { | |
| 645 if (Settings* settings = page->settings()) { | |
| 646 bool includeTextDirectionSubmenu = settings->textDirectionSu bmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded | |
| 647 || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection( )); | |
| 648 if (includeTextDirectionSubmenu) { | |
| 649 ContextMenuItem TextDirectionMenuItem(SubmenuType, Conte xtMenuItemTagTextDirectionMenu, | |
| 650 contextMenuItemTagTextDirectionMenu()); | |
| 651 createAndAppendTextDirectionSubMenu(TextDirectionMenuIte m); | |
| 652 appendItem(TextDirectionMenuItem, m_contextMenu.get()); | |
| 653 } | |
| 654 } | |
| 655 } | |
| 656 } | |
| 657 } | |
| 658 } | |
| 659 | |
| 660 void ContextMenuController::addInspectElementItem() | |
| 661 { | |
| 662 Node* node = m_hitTestResult.innerNonSharedNode(); | |
| 663 if (!node) | |
| 664 return; | |
| 665 | |
| 666 Frame* frame = node->document()->frame(); | |
| 667 if (!frame) | |
| 668 return; | |
| 669 | |
| 670 Page* page = frame->page(); | |
| 671 if (!page) | |
| 672 return; | |
| 673 | |
| 674 if (!page->inspectorController()) | |
| 675 return; | |
| 676 | |
| 677 ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElem ent, contextMenuItemTagInspectElement()); | |
| 678 if (m_contextMenu && !m_contextMenu->items().isEmpty()) | |
| 679 appendItem(*separatorItem(), m_contextMenu.get()); | |
| 680 appendItem(InspectElementItem, m_contextMenu.get()); | |
| 681 } | |
| 682 | |
| 683 void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const | |
| 684 { | |
| 685 if (item.type() == SeparatorType) | |
| 686 return; | |
| 687 | |
| 688 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame(); | |
| 689 if (!frame) | |
| 690 return; | |
| 691 | |
| 692 // Custom items already have proper checked and enabled values. | |
| 693 if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= Contex tMenuItemLastCustomTag) | |
| 694 return; | |
| 695 | |
| 696 bool shouldEnable = true; | |
| 697 bool shouldCheck = false; | |
| 698 | |
| 699 switch (item.action()) { | |
| 700 case ContextMenuItemTagCheckSpelling: | |
| 701 shouldEnable = frame->editor()->canEdit(); | |
| 702 break; | |
| 703 case ContextMenuItemTagDefaultDirection: | |
| 704 shouldCheck = false; | |
| 705 shouldEnable = false; | |
| 706 break; | |
| 707 case ContextMenuItemTagLeftToRight: | |
| 708 case ContextMenuItemTagRightToLeft: { | |
| 709 String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl"; | |
| 710 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirectio n, direction) != FalseTriState; | |
| 711 shouldEnable = true; | |
| 712 break; | |
| 713 } | |
| 714 case ContextMenuItemTagTextDirectionDefault: { | |
| 715 Editor::Command command = frame->editor()->command("MakeTextWritingD irectionNatural"); | |
| 716 shouldCheck = command.state() == TrueTriState; | |
| 717 shouldEnable = command.isEnabled(); | |
| 718 break; | |
| 719 } | |
| 720 case ContextMenuItemTagTextDirectionLeftToRight: { | |
| 721 Editor::Command command = frame->editor()->command("MakeTextWritingD irectionLeftToRight"); | |
| 722 shouldCheck = command.state() == TrueTriState; | |
| 723 shouldEnable = command.isEnabled(); | |
| 724 break; | |
| 725 } | |
| 726 case ContextMenuItemTagTextDirectionRightToLeft: { | |
| 727 Editor::Command command = frame->editor()->command("MakeTextWritingD irectionRightToLeft"); | |
| 728 shouldCheck = command.state() == TrueTriState; | |
| 729 shouldEnable = command.isEnabled(); | |
| 730 break; | |
| 731 } | |
| 732 case ContextMenuItemTagCopy: | |
| 733 shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->c anCopy(); | |
| 734 break; | |
| 735 case ContextMenuItemTagCut: | |
| 736 shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->ca nCut(); | |
| 737 break; | |
| 738 case ContextMenuItemTagIgnoreSpelling: | |
| 739 case ContextMenuItemTagLearnSpelling: | |
| 740 shouldEnable = frame->selection()->isRange(); | |
| 741 break; | |
| 742 case ContextMenuItemTagPaste: | |
| 743 shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()-> canPaste(); | |
| 744 break; | |
| 745 case ContextMenuItemTagUnderline: { | |
| 746 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTe xtDecorationsInEffect, "underline") != FalseTriState; | |
| 747 shouldEnable = frame->editor()->canEditRichly(); | |
| 748 break; | |
| 749 } | |
| 750 case ContextMenuItemTagLookUpInDictionary: | |
| 751 shouldEnable = frame->selection()->isRange(); | |
| 752 break; | |
| 753 case ContextMenuItemTagCheckGrammarWithSpelling: | |
| 754 if (frame->editor()->isGrammarCheckingEnabled()) | |
| 755 shouldCheck = true; | |
| 756 shouldEnable = true; | |
| 757 break; | |
| 758 case ContextMenuItemTagItalic: { | |
| 759 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyl e, "italic") != FalseTriState; | |
| 760 shouldEnable = frame->editor()->canEditRichly(); | |
| 761 break; | |
| 762 } | |
| 763 case ContextMenuItemTagBold: { | |
| 764 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeig ht, "bold") != FalseTriState; | |
| 765 shouldEnable = frame->editor()->canEditRichly(); | |
| 766 break; | |
| 767 } | |
| 768 case ContextMenuItemTagOutline: | |
| 769 shouldEnable = false; | |
| 770 break; | |
| 771 case ContextMenuItemTagShowSpellingPanel: | |
| 772 if (frame->editor()->spellingPanelIsShowing()) | |
| 773 item.setTitle(contextMenuItemTagShowSpellingPanel(false)); | |
| 774 else | |
| 775 item.setTitle(contextMenuItemTagShowSpellingPanel(true)); | |
| 776 shouldEnable = frame->editor()->canEdit(); | |
| 777 break; | |
| 778 case ContextMenuItemTagNoGuessesFound: | |
| 779 shouldEnable = false; | |
| 780 break; | |
| 781 case ContextMenuItemTagCheckSpellingWhileTyping: | |
| 782 shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled(); | |
| 783 break; | |
| 784 case ContextMenuItemTagStopSpeaking: | |
| 785 break; | |
| 786 case ContextMenuItemTagGoBack: | |
| 787 case ContextMenuItemTagGoForward: | |
| 788 case ContextMenuItemTagStop: | |
| 789 case ContextMenuItemTagReload: | |
| 790 case ContextMenuItemTagFontMenu: | |
| 791 case ContextMenuItemTagNoAction: | |
| 792 case ContextMenuItemTagOpenLinkInNewWindow: | |
| 793 case ContextMenuItemTagOpenLinkInThisWindow: | |
| 794 case ContextMenuItemTagDownloadLinkToDisk: | |
| 795 case ContextMenuItemTagCopyLinkToClipboard: | |
| 796 case ContextMenuItemTagOpenImageInNewWindow: | |
| 797 case ContextMenuItemTagDownloadImageToDisk: | |
| 798 case ContextMenuItemTagCopyImageToClipboard: | |
| 799 break; | |
| 800 case ContextMenuItemTagOpenMediaInNewWindow: | |
| 801 if (m_hitTestResult.mediaIsVideo()) | |
| 802 item.setTitle(contextMenuItemTagOpenVideoInNewWindow()); | |
| 803 else | |
| 804 item.setTitle(contextMenuItemTagOpenAudioInNewWindow()); | |
| 805 break; | |
| 806 case ContextMenuItemTagCopyMediaLinkToClipboard: | |
| 807 if (m_hitTestResult.mediaIsVideo()) | |
| 808 item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard()); | |
| 809 else | |
| 810 item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard()); | |
| 811 break; | |
| 812 case ContextMenuItemTagToggleMediaControls: | |
| 813 shouldCheck = m_hitTestResult.mediaControlsEnabled(); | |
| 814 break; | |
| 815 case ContextMenuItemTagToggleMediaLoop: | |
| 816 shouldCheck = m_hitTestResult.mediaLoopEnabled(); | |
| 817 break; | |
| 818 case ContextMenuItemTagEnterVideoFullscreen: | |
| 819 shouldEnable = m_hitTestResult.mediaSupportsFullscreen(); | |
| 820 break; | |
| 821 case ContextMenuItemTagOpenFrameInNewWindow: | |
| 822 case ContextMenuItemTagSpellingGuess: | |
| 823 case ContextMenuItemTagOther: | |
| 824 case ContextMenuItemTagSearchInSpotlight: | |
| 825 case ContextMenuItemTagSearchWeb: | |
| 826 case ContextMenuItemTagOpenWithDefaultApplication: | |
| 827 case ContextMenuItemPDFActualSize: | |
| 828 case ContextMenuItemPDFZoomIn: | |
| 829 case ContextMenuItemPDFZoomOut: | |
| 830 case ContextMenuItemPDFAutoSize: | |
| 831 case ContextMenuItemPDFSinglePage: | |
| 832 case ContextMenuItemPDFFacingPages: | |
| 833 case ContextMenuItemPDFContinuous: | |
| 834 case ContextMenuItemPDFNextPage: | |
| 835 case ContextMenuItemPDFPreviousPage: | |
| 836 case ContextMenuItemTagOpenLink: | |
| 837 case ContextMenuItemTagIgnoreGrammar: | |
| 838 case ContextMenuItemTagSpellingMenu: | |
| 839 case ContextMenuItemTagShowFonts: | |
| 840 case ContextMenuItemTagStyles: | |
| 841 case ContextMenuItemTagShowColors: | |
| 842 case ContextMenuItemTagSpeechMenu: | |
| 843 case ContextMenuItemTagStartSpeaking: | |
| 844 case ContextMenuItemTagWritingDirectionMenu: | |
| 845 case ContextMenuItemTagTextDirectionMenu: | |
| 846 case ContextMenuItemTagPDFSinglePageScrolling: | |
| 847 case ContextMenuItemTagPDFFacingPagesScrolling: | |
| 848 case ContextMenuItemTagInspectElement: | |
| 849 case ContextMenuItemBaseCustomTag: | |
| 850 case ContextMenuItemCustomTagNoAction: | |
| 851 case ContextMenuItemLastCustomTag: | |
| 852 case ContextMenuItemBaseApplicationTag: | |
| 853 break; | |
| 854 case ContextMenuItemTagMediaPlayPause: | |
| 855 if (m_hitTestResult.mediaPlaying()) | |
| 856 item.setTitle(contextMenuItemTagMediaPause()); | |
| 857 else | |
| 858 item.setTitle(contextMenuItemTagMediaPlay()); | |
| 859 break; | |
| 860 case ContextMenuItemTagMediaMute: | |
| 861 shouldEnable = m_hitTestResult.mediaHasAudio(); | |
| 862 shouldCheck = shouldEnable && m_hitTestResult.mediaMuted(); | |
| 863 break; | |
| 864 } | |
| 865 | |
| 866 item.setChecked(shouldCheck); | |
| 867 item.setEnabled(shouldEnable); | |
| 868 } | 131 } |
| 869 | 132 |
| 870 } // namespace WebCore | 133 } // namespace WebCore |
| OLD | NEW |