|  | /* | 
|  | * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 
|  | * Copyright (C) 2010 Igalia S.L | 
|  | * | 
|  | * Redistribution and use in source and binary forms, with or without | 
|  | * modification, are permitted provided that the following conditions | 
|  | * are met: | 
|  | * 1. Redistributions of source code must retain the above copyright | 
|  | *    notice, this list of conditions and the following disclaimer. | 
|  | * 2. Redistributions in binary form must reproduce the above copyright | 
|  | *    notice, this list of conditions and the following disclaimer in the | 
|  | *    documentation and/or other materials provided with the distribution. | 
|  | * | 
|  | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | 
|  | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|  | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
|  | * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR | 
|  | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
|  | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
|  | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
|  | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 
|  | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | */ | 
|  |  | 
|  | #include "config.h" | 
|  | #include "ContextMenuController.h" | 
|  |  | 
|  | #if ENABLE(CONTEXT_MENUS) | 
|  |  | 
|  | #include "BackForwardController.h" | 
|  | #include "Chrome.h" | 
|  | #include "ContextMenu.h" | 
|  | #include "ContextMenuClient.h" | 
|  | #include "ContextMenuItem.h" | 
|  | #include "ContextMenuProvider.h" | 
|  | #include "Document.h" | 
|  | #include "DocumentFragment.h" | 
|  | #include "DocumentLoader.h" | 
|  | #include "Editor.h" | 
|  | #include "EditorClient.h" | 
|  | #include "Event.h" | 
|  | #include "EventHandler.h" | 
|  | #include "EventNames.h" | 
|  | #include "ExceptionCodePlaceholder.h" | 
|  | #include "FormState.h" | 
|  | #include "FrameLoadRequest.h" | 
|  | #include "FrameLoader.h" | 
|  | #include "FrameLoaderClient.h" | 
|  | #include "FrameSelection.h" | 
|  | #include "HTMLFormControlElement.h" | 
|  | #include "HTMLFormElement.h" | 
|  | #include "HitTestRequest.h" | 
|  | #include "HitTestResult.h" | 
|  | #include "InspectorController.h" | 
|  | #include "LocalizedStrings.h" | 
|  | #include "MainFrame.h" | 
|  | #include "MouseEvent.h" | 
|  | #include "NavigationAction.h" | 
|  | #include "Node.h" | 
|  | #include "Page.h" | 
|  | #include "PlatformEvent.h" | 
|  | #include "RenderImage.h" | 
|  | #include "ReplaceSelectionCommand.h" | 
|  | #include "ResourceRequest.h" | 
|  | #include "Settings.h" | 
|  | #include "TextIterator.h" | 
|  | #include "TypingCommand.h" | 
|  | #include "UserTypingGestureIndicator.h" | 
|  | #include "WindowFeatures.h" | 
|  | #include "markup.h" | 
|  | #include <wtf/unicode/CharacterNames.h> | 
|  |  | 
|  | using namespace WTF; | 
|  | using namespace Unicode; | 
|  |  | 
|  | namespace WebCore { | 
|  |  | 
|  | ContextMenuController::ContextMenuController(Page& page, ContextMenuClient& client) | 
|  | : m_page(page) | 
|  | , m_client(client) | 
|  | { | 
|  | } | 
|  |  | 
|  | ContextMenuController::~ContextMenuController() | 
|  | { | 
|  | m_client.contextMenuDestroyed(); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::clearContextMenu() | 
|  | { | 
|  | m_contextMenu = nullptr; | 
|  | if (m_menuProvider) | 
|  | m_menuProvider->contextMenuCleared(); | 
|  | m_menuProvider = nullptr; | 
|  | } | 
|  |  | 
|  | void ContextMenuController::handleContextMenuEvent(Event* event) | 
|  | { | 
|  | m_contextMenu = maybeCreateContextMenu(event); | 
|  | if (!m_contextMenu) | 
|  | return; | 
|  |  | 
|  | populate(); | 
|  |  | 
|  | showContextMenu(event); | 
|  | } | 
|  |  | 
|  | static std::unique_ptr<ContextMenuItem> separatorItem() | 
|  | { | 
|  | return std::unique_ptr<ContextMenuItem>(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String())); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider) | 
|  | { | 
|  | m_menuProvider = menuProvider; | 
|  |  | 
|  | m_contextMenu = maybeCreateContextMenu(event); | 
|  | if (!m_contextMenu) { | 
|  | clearContextMenu(); | 
|  | return; | 
|  | } | 
|  |  | 
|  | m_menuProvider->populateContextMenu(m_contextMenu.get()); | 
|  | if (m_context.hitTestResult().isSelected()) { | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | populate(); | 
|  | } | 
|  | showContextMenu(event); | 
|  | } | 
|  |  | 
|  | #if ENABLE(SERVICE_CONTROLS) | 
|  | static Image* imageFromImageElementNode(Node& node) | 
|  | { | 
|  | RenderObject* renderer = node.renderer(); | 
|  | if (!is<RenderImage>(renderer)) | 
|  | return nullptr; | 
|  | CachedImage* image = downcast<RenderImage>(*renderer).cachedImage(); | 
|  | if (!image || image->errorOccurred()) | 
|  | return nullptr; | 
|  |  | 
|  | return image->imageForRenderer(renderer); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | std::unique_ptr<ContextMenu> ContextMenuController::maybeCreateContextMenu(Event* event) | 
|  | { | 
|  | ASSERT(event); | 
|  |  | 
|  | if (!is<MouseEvent>(*event)) | 
|  | return nullptr; | 
|  |  | 
|  | MouseEvent& mouseEvent = downcast<MouseEvent>(*event); | 
|  | HitTestResult result(mouseEvent.absoluteLocation()); | 
|  |  | 
|  | Node* node = event->target()->toNode(); | 
|  | if (Frame* frame = node->document().frame()) | 
|  | result = frame->eventHandler().hitTestResultAtPoint(mouseEvent.absoluteLocation()); | 
|  |  | 
|  | if (!result.innerNonSharedNode()) | 
|  | return nullptr; | 
|  |  | 
|  | m_context = ContextMenuContext(result); | 
|  |  | 
|  | #if ENABLE(SERVICE_CONTROLS) | 
|  | if (node->isImageControlsButtonElement()) { | 
|  | if (Image* image = imageFromImageElementNode(*result.innerNonSharedNode())) | 
|  | m_context.setControlledImage(image); | 
|  |  | 
|  | // FIXME: If we couldn't get the image then we shouldn't try to show the image controls menu for it. | 
|  | return nullptr; | 
|  | } | 
|  | #endif | 
|  |  | 
|  | return std::unique_ptr<ContextMenu>(new ContextMenu); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::showContextMenu(Event* event) | 
|  | { | 
|  | if (m_page.inspectorController().enabled()) | 
|  | addInspectElementItem(); | 
|  |  | 
|  | #if USE(CROSS_PLATFORM_CONTEXT_MENUS) | 
|  | m_contextMenu = m_client.customizeMenu(WTF::move(m_contextMenu)); | 
|  | #else | 
|  | PlatformMenuDescription customMenu = m_client.getCustomMenuFromDefaultItems(m_contextMenu.get()); | 
|  | m_contextMenu->setPlatformDescription(customMenu); | 
|  | #endif | 
|  | event->setDefaultHandled(); | 
|  | } | 
|  |  | 
|  | static void openNewWindow(const URL& urlToLoad, Frame* frame, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) | 
|  | { | 
|  | Page* oldPage = frame->page(); | 
|  | if (!oldPage) | 
|  | return; | 
|  |  | 
|  | FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, shouldOpenExternalURLsPolicy); | 
|  |  | 
|  | Page* newPage = oldPage->chrome().createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest())); | 
|  | if (!newPage) | 
|  | return; | 
|  | newPage->chrome().show(); | 
|  | newPage->mainFrame().loader().loadFrameRequest(request, nullptr, nullptr); | 
|  | } | 
|  |  | 
|  | #if PLATFORM(GTK) | 
|  | static void insertUnicodeCharacter(UChar character, Frame* frame) | 
|  | { | 
|  | String text(&character, 1); | 
|  | if (!frame->editor().shouldInsertText(text, frame->selection().toNormalizedRange().get(), EditorInsertActionTyped)) | 
|  | return; | 
|  |  | 
|  | ASSERT(frame->document()); | 
|  | TypingCommand::insertText(*frame->document(), text, 0, TypingCommand::TextCompositionNone); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) | 
|  | { | 
|  | ASSERT(item->type() == ActionType || item->type() == CheckableActionType); | 
|  |  | 
|  | if (item->action() >= ContextMenuItemBaseApplicationTag) { | 
|  | m_client.contextMenuItemSelected(item, m_contextMenu.get()); | 
|  | return; | 
|  | } | 
|  |  | 
|  | if (item->action() >= ContextMenuItemBaseCustomTag) { | 
|  | ASSERT(m_menuProvider); | 
|  | m_menuProvider->contextMenuItemSelected(item); | 
|  | return; | 
|  | } | 
|  |  | 
|  | Frame* frame = m_context.hitTestResult().innerNonSharedNode()->document().frame(); | 
|  | if (!frame) | 
|  | return; | 
|  |  | 
|  | switch (item->action()) { | 
|  | case ContextMenuItemTagOpenLinkInNewWindow: | 
|  | openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame, ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes); | 
|  | break; | 
|  | case ContextMenuItemTagDownloadLinkToDisk: | 
|  | // FIXME: Some day we should be able to do this from within WebCore. (Bug 117709) | 
|  | m_client.downloadURL(m_context.hitTestResult().absoluteLinkURL()); | 
|  | break; | 
|  | case ContextMenuItemTagCopyLinkToClipboard: | 
|  | frame->editor().copyURL(m_context.hitTestResult().absoluteLinkURL(), m_context.hitTestResult().textContent()); | 
|  | break; | 
|  | case ContextMenuItemTagOpenImageInNewWindow: | 
|  | openNewWindow(m_context.hitTestResult().absoluteImageURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow); | 
|  | break; | 
|  | case ContextMenuItemTagDownloadImageToDisk: | 
|  | // FIXME: Some day we should be able to do this from within WebCore. (Bug 117709) | 
|  | m_client.downloadURL(m_context.hitTestResult().absoluteImageURL()); | 
|  | break; | 
|  | case ContextMenuItemTagCopyImageToClipboard: | 
|  | // FIXME: The Pasteboard class is not written yet | 
|  | // For now, call into the client. This is temporary! | 
|  | frame->editor().copyImage(m_context.hitTestResult()); | 
|  | break; | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | case ContextMenuItemTagCopyImageUrlToClipboard: | 
|  | frame->editor().copyURL(m_context.hitTestResult().absoluteImageURL(), m_context.hitTestResult().textContent()); | 
|  | break; | 
|  | #endif | 
|  | case ContextMenuItemTagOpenMediaInNewWindow: | 
|  | openNewWindow(m_context.hitTestResult().absoluteMediaURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow); | 
|  | break; | 
|  | case ContextMenuItemTagDownloadMediaToDisk: | 
|  | // FIXME: Some day we should be able to do this from within WebCore. (Bug 117709) | 
|  | m_client.downloadURL(m_context.hitTestResult().absoluteMediaURL()); | 
|  | break; | 
|  | case ContextMenuItemTagCopyMediaLinkToClipboard: | 
|  | frame->editor().copyURL(m_context.hitTestResult().absoluteMediaURL(), m_context.hitTestResult().textContent()); | 
|  | break; | 
|  | case ContextMenuItemTagToggleMediaControls: | 
|  | m_context.hitTestResult().toggleMediaControlsDisplay(); | 
|  | break; | 
|  | case ContextMenuItemTagToggleMediaLoop: | 
|  | m_context.hitTestResult().toggleMediaLoopPlayback(); | 
|  | break; | 
|  | case ContextMenuItemTagToggleVideoFullscreen: | 
|  | m_context.hitTestResult().toggleMediaFullscreenState(); | 
|  | break; | 
|  | case ContextMenuItemTagEnterVideoFullscreen: | 
|  | m_context.hitTestResult().enterFullscreenForVideo(); | 
|  | break; | 
|  | case ContextMenuItemTagMediaPlayPause: | 
|  | m_context.hitTestResult().toggleMediaPlayState(); | 
|  | break; | 
|  | case ContextMenuItemTagMediaMute: | 
|  | m_context.hitTestResult().toggleMediaMuteState(); | 
|  | break; | 
|  | case ContextMenuItemTagOpenFrameInNewWindow: { | 
|  | DocumentLoader* loader = frame->loader().documentLoader(); | 
|  | if (!loader->unreachableURL().isEmpty()) | 
|  | openNewWindow(loader->unreachableURL(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow); | 
|  | else | 
|  | openNewWindow(loader->url(), frame, ShouldOpenExternalURLsPolicy::ShouldNotAllow); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagCopy: | 
|  | frame->editor().copy(); | 
|  | break; | 
|  | case ContextMenuItemTagGoBack: | 
|  | if (Page* page = frame->page()) | 
|  | page->backForward().goBackOrForward(-1); | 
|  | break; | 
|  | case ContextMenuItemTagGoForward: | 
|  | if (Page* page = frame->page()) | 
|  | page->backForward().goBackOrForward(1); | 
|  | break; | 
|  | case ContextMenuItemTagStop: | 
|  | frame->loader().stop(); | 
|  | break; | 
|  | case ContextMenuItemTagReload: | 
|  | frame->loader().reload(); | 
|  | break; | 
|  | case ContextMenuItemTagCut: | 
|  | frame->editor().command("Cut").execute(); | 
|  | break; | 
|  | case ContextMenuItemTagPaste: | 
|  | frame->editor().command("Paste").execute(); | 
|  | break; | 
|  | #if PLATFORM(GTK) | 
|  | case ContextMenuItemTagDelete: | 
|  | frame->editor().performDelete(); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertLRMMark: | 
|  | insertUnicodeCharacter(leftToRightMark, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertRLMMark: | 
|  | insertUnicodeCharacter(rightToLeftMark, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertLREMark: | 
|  | insertUnicodeCharacter(leftToRightEmbed, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertRLEMark: | 
|  | insertUnicodeCharacter(rightToLeftEmbed, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertLROMark: | 
|  | insertUnicodeCharacter(leftToRightOverride, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertRLOMark: | 
|  | insertUnicodeCharacter(rightToLeftOverride, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertPDFMark: | 
|  | insertUnicodeCharacter(popDirectionalFormatting, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertZWSMark: | 
|  | insertUnicodeCharacter(zeroWidthSpace, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertZWJMark: | 
|  | insertUnicodeCharacter(zeroWidthJoiner, frame); | 
|  | break; | 
|  | case ContextMenuItemTagUnicodeInsertZWNJMark: | 
|  | insertUnicodeCharacter(zeroWidthNonJoiner, frame); | 
|  | break; | 
|  | #endif | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | case ContextMenuItemTagSelectAll: | 
|  | frame->editor().command("SelectAll").execute(); | 
|  | break; | 
|  | #endif | 
|  | case ContextMenuItemTagSpellingGuess: { | 
|  | VisibleSelection selection = frame->selection().selection(); | 
|  | if (frame->editor().shouldInsertText(item->title(), selection.toNormalizedRange().get(), EditorInsertActionPasted)) { | 
|  | ReplaceSelectionCommand::CommandOptions replaceOptions = ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting; | 
|  |  | 
|  | if (frame->editor().behavior().shouldAllowSpellingSuggestionsWithoutSelection()) { | 
|  | ASSERT(selection.isCaretOrRange()); | 
|  | VisibleSelection wordSelection(selection.base()); | 
|  | wordSelection.expandUsingGranularity(WordGranularity); | 
|  | frame->selection().setSelection(wordSelection); | 
|  | } else { | 
|  | ASSERT(frame->editor().selectedText().length()); | 
|  | replaceOptions |= ReplaceSelectionCommand::SelectReplacement; | 
|  | } | 
|  |  | 
|  | Document* document = frame->document(); | 
|  | ASSERT(document); | 
|  | RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(*document, createFragmentFromMarkup(*document, item->title(), ""), replaceOptions); | 
|  | applyCommand(command); | 
|  | frame->selection().revealSelection(ScrollAlignment::alignToEdgeIfNeeded); | 
|  | } | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagIgnoreSpelling: | 
|  | frame->editor().ignoreSpelling(); | 
|  | break; | 
|  | case ContextMenuItemTagLearnSpelling: | 
|  | frame->editor().learnSpelling(); | 
|  | break; | 
|  | case ContextMenuItemTagSearchWeb: | 
|  | m_client.searchWithGoogle(frame); | 
|  | break; | 
|  | case ContextMenuItemTagLookUpInDictionary: | 
|  | // FIXME: Some day we may be able to do this from within WebCore. | 
|  | m_client.lookUpInDictionary(frame); | 
|  | break; | 
|  | case ContextMenuItemTagOpenLink: | 
|  | if (Frame* targetFrame = m_context.hitTestResult().targetFrame()) | 
|  | targetFrame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, targetFrame->isMainFrame() ? ShouldOpenExternalURLsPolicy::ShouldAllow : ShouldOpenExternalURLsPolicy::ShouldNotAllow), nullptr, nullptr); | 
|  | else | 
|  | openNewWindow(m_context.hitTestResult().absoluteLinkURL(), frame, ShouldOpenExternalURLsPolicy::ShouldAllow); | 
|  | break; | 
|  | case ContextMenuItemTagOpenLinkInThisWindow: | 
|  | frame->loader().loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_context.hitTestResult().absoluteLinkURL(), frame->loader().outgoingReferrer()), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress, ShouldOpenExternalURLsPolicy::ShouldAllowExternalSchemes), nullptr, nullptr); | 
|  | break; | 
|  | case ContextMenuItemTagBold: | 
|  | frame->editor().command("ToggleBold").execute(); | 
|  | break; | 
|  | case ContextMenuItemTagItalic: | 
|  | frame->editor().command("ToggleItalic").execute(); | 
|  | break; | 
|  | case ContextMenuItemTagUnderline: | 
|  | frame->editor().toggleUnderline(); | 
|  | break; | 
|  | case ContextMenuItemTagOutline: | 
|  | // We actually never enable this because CSS does not have a way to specify an outline font, | 
|  | // which may make this difficult to implement. Maybe a special case of text-shadow? | 
|  | break; | 
|  | case ContextMenuItemTagStartSpeaking: { | 
|  | RefPtr<Range> selectedRange = frame->selection().toNormalizedRange(); | 
|  | if (!selectedRange || selectedRange->collapsed(IGNORE_EXCEPTION)) { | 
|  | Document& document = m_context.hitTestResult().innerNonSharedNode()->document(); | 
|  | selectedRange = document.createRange(); | 
|  | selectedRange->selectNode(document.documentElement(), IGNORE_EXCEPTION); | 
|  | } | 
|  | m_client.speak(plainText(selectedRange.get())); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagStopSpeaking: | 
|  | m_client.stopSpeaking(); | 
|  | break; | 
|  | case ContextMenuItemTagDefaultDirection: | 
|  | frame->editor().setBaseWritingDirection(NaturalWritingDirection); | 
|  | break; | 
|  | case ContextMenuItemTagLeftToRight: | 
|  | frame->editor().setBaseWritingDirection(LeftToRightWritingDirection); | 
|  | break; | 
|  | case ContextMenuItemTagRightToLeft: | 
|  | frame->editor().setBaseWritingDirection(RightToLeftWritingDirection); | 
|  | break; | 
|  | case ContextMenuItemTagTextDirectionDefault: | 
|  | frame->editor().command("MakeTextWritingDirectionNatural").execute(); | 
|  | break; | 
|  | case ContextMenuItemTagTextDirectionLeftToRight: | 
|  | frame->editor().command("MakeTextWritingDirectionLeftToRight").execute(); | 
|  | break; | 
|  | case ContextMenuItemTagTextDirectionRightToLeft: | 
|  | frame->editor().command("MakeTextWritingDirectionRightToLeft").execute(); | 
|  | break; | 
|  | #if PLATFORM(COCOA) | 
|  | case ContextMenuItemTagSearchInSpotlight: | 
|  | m_client.searchWithSpotlight(); | 
|  | break; | 
|  | #endif | 
|  | case ContextMenuItemTagShowSpellingPanel: | 
|  | frame->editor().showSpellingGuessPanel(); | 
|  | break; | 
|  | case ContextMenuItemTagCheckSpelling: | 
|  | frame->editor().advanceToNextMisspelling(); | 
|  | break; | 
|  | case ContextMenuItemTagCheckSpellingWhileTyping: | 
|  | frame->editor().toggleContinuousSpellChecking(); | 
|  | break; | 
|  | case ContextMenuItemTagCheckGrammarWithSpelling: | 
|  | frame->editor().toggleGrammarChecking(); | 
|  | break; | 
|  | #if PLATFORM(COCOA) | 
|  | case ContextMenuItemTagShowFonts: | 
|  | frame->editor().showFontPanel(); | 
|  | break; | 
|  | case ContextMenuItemTagStyles: | 
|  | frame->editor().showStylesPanel(); | 
|  | break; | 
|  | case ContextMenuItemTagShowColors: | 
|  | frame->editor().showColorPanel(); | 
|  | break; | 
|  | #endif | 
|  | #if USE(APPKIT) | 
|  | case ContextMenuItemTagMakeUpperCase: | 
|  | frame->editor().uppercaseWord(); | 
|  | break; | 
|  | case ContextMenuItemTagMakeLowerCase: | 
|  | frame->editor().lowercaseWord(); | 
|  | break; | 
|  | case ContextMenuItemTagCapitalize: | 
|  | frame->editor().capitalizeWord(); | 
|  | break; | 
|  | #endif | 
|  | #if PLATFORM(COCOA) | 
|  | case ContextMenuItemTagChangeBack: | 
|  | frame->editor().changeBackToReplacedString(m_context.hitTestResult().replacedString()); | 
|  | break; | 
|  | #endif | 
|  | #if USE(AUTOMATIC_TEXT_REPLACEMENT) | 
|  | case ContextMenuItemTagShowSubstitutions: | 
|  | frame->editor().showSubstitutionsPanel(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartCopyPaste: | 
|  | frame->editor().toggleSmartInsertDelete(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartQuotes: | 
|  | frame->editor().toggleAutomaticQuoteSubstitution(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartDashes: | 
|  | frame->editor().toggleAutomaticDashSubstitution(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartLinks: | 
|  | frame->editor().toggleAutomaticLinkDetection(); | 
|  | break; | 
|  | case ContextMenuItemTagTextReplacement: | 
|  | frame->editor().toggleAutomaticTextReplacement(); | 
|  | break; | 
|  | case ContextMenuItemTagCorrectSpellingAutomatically: | 
|  | frame->editor().toggleAutomaticSpellingCorrection(); | 
|  | break; | 
|  | #endif | 
|  | case ContextMenuItemTagInspectElement: | 
|  | if (Page* page = frame->page()) | 
|  | page->inspectorController().inspect(m_context.hitTestResult().innerNonSharedNode()); | 
|  | break; | 
|  | case ContextMenuItemTagDictationAlternative: | 
|  | frame->editor().applyDictationAlternativelternative(item->title()); | 
|  | break; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* parentMenu) | 
|  | { | 
|  | checkOrEnableIfNeeded(menuItem); | 
|  | if (parentMenu) | 
|  | parentMenu->appendItem(menuItem); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem) | 
|  | { | 
|  | ContextMenu fontMenu; | 
|  |  | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts()); | 
|  | #endif | 
|  | ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold()); | 
|  | ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic()); | 
|  | ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline()); | 
|  | ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline()); | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles()); | 
|  | ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors()); | 
|  | #endif | 
|  |  | 
|  | #if PLATFORM(COCOA) | 
|  | appendItem(showFonts, &fontMenu); | 
|  | #endif | 
|  | appendItem(bold, &fontMenu); | 
|  | appendItem(italic, &fontMenu); | 
|  | appendItem(underline, &fontMenu); | 
|  | appendItem(outline, &fontMenu); | 
|  | #if PLATFORM(COCOA) | 
|  | appendItem(styles, &fontMenu); | 
|  | appendItem(*separatorItem(), &fontMenu); | 
|  | appendItem(showColors, &fontMenu); | 
|  | #endif | 
|  |  | 
|  | fontMenuItem.setSubMenu(&fontMenu); | 
|  | } | 
|  |  | 
|  |  | 
|  | #if !PLATFORM(GTK) | 
|  |  | 
|  | void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem) | 
|  | { | 
|  | ContextMenu spellingAndGrammarMenu; | 
|  |  | 
|  | ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel, | 
|  | contextMenuItemTagShowSpellingPanel(true)); | 
|  | ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling, | 
|  | contextMenuItemTagCheckSpelling()); | 
|  | ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping, | 
|  | contextMenuItemTagCheckSpellingWhileTyping()); | 
|  | ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling, | 
|  | contextMenuItemTagCheckGrammarWithSpelling()); | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically, | 
|  | contextMenuItemTagCorrectSpellingAutomatically()); | 
|  | #endif | 
|  |  | 
|  | appendItem(showSpellingPanel, &spellingAndGrammarMenu); | 
|  | appendItem(checkSpelling, &spellingAndGrammarMenu); | 
|  | #if PLATFORM(COCOA) | 
|  | appendItem(*separatorItem(), &spellingAndGrammarMenu); | 
|  | #endif | 
|  | appendItem(checkAsYouType, &spellingAndGrammarMenu); | 
|  | appendItem(grammarWithSpelling, &spellingAndGrammarMenu); | 
|  | #if PLATFORM(COCOA) | 
|  | appendItem(correctSpelling, &spellingAndGrammarMenu); | 
|  | #endif | 
|  |  | 
|  | spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu); | 
|  | } | 
|  |  | 
|  | #endif // !PLATFORM(GTK) | 
|  |  | 
|  |  | 
|  | #if PLATFORM(COCOA) | 
|  |  | 
|  | void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem) | 
|  | { | 
|  | ContextMenu speechMenu; | 
|  |  | 
|  | ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking()); | 
|  | ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking()); | 
|  |  | 
|  | appendItem(start, &speechMenu); | 
|  | appendItem(stop, &speechMenu); | 
|  |  | 
|  | speechMenuItem.setSubMenu(&speechMenu); | 
|  | } | 
|  |  | 
|  | #endif | 
|  |  | 
|  | #if PLATFORM(GTK) | 
|  |  | 
|  | void ContextMenuController::createAndAppendUnicodeSubMenu(ContextMenuItem& unicodeMenuItem) | 
|  | { | 
|  | ContextMenu unicodeMenu; | 
|  |  | 
|  | ContextMenuItem leftToRightMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLRMMark, contextMenuItemTagUnicodeInsertLRMMark()); | 
|  | ContextMenuItem rightToLeftMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLMMark, contextMenuItemTagUnicodeInsertRLMMark()); | 
|  | ContextMenuItem leftToRightEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLREMark, contextMenuItemTagUnicodeInsertLREMark()); | 
|  | ContextMenuItem rightToLeftEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLEMark, contextMenuItemTagUnicodeInsertRLEMark()); | 
|  | ContextMenuItem leftToRightOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLROMark, contextMenuItemTagUnicodeInsertLROMark()); | 
|  | ContextMenuItem rightToLeftOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLOMark, contextMenuItemTagUnicodeInsertRLOMark()); | 
|  | ContextMenuItem popDirectionalFormattingMenuItem(ActionType, ContextMenuItemTagUnicodeInsertPDFMark, contextMenuItemTagUnicodeInsertPDFMark()); | 
|  | ContextMenuItem zeroWidthSpaceMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWSMark, contextMenuItemTagUnicodeInsertZWSMark()); | 
|  | ContextMenuItem zeroWidthJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWJMark, contextMenuItemTagUnicodeInsertZWJMark()); | 
|  | ContextMenuItem zeroWidthNonJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWNJMark, contextMenuItemTagUnicodeInsertZWNJMark()); | 
|  |  | 
|  | appendItem(leftToRightMarkMenuItem, &unicodeMenu); | 
|  | appendItem(rightToLeftMarkMenuItem, &unicodeMenu); | 
|  | appendItem(leftToRightEmbedMenuItem, &unicodeMenu); | 
|  | appendItem(rightToLeftEmbedMenuItem, &unicodeMenu); | 
|  | appendItem(leftToRightOverrideMenuItem, &unicodeMenu); | 
|  | appendItem(rightToLeftOverrideMenuItem, &unicodeMenu); | 
|  | appendItem(popDirectionalFormattingMenuItem, &unicodeMenu); | 
|  | appendItem(zeroWidthSpaceMenuItem, &unicodeMenu); | 
|  | appendItem(zeroWidthJoinerMenuItem, &unicodeMenu); | 
|  | appendItem(zeroWidthNonJoinerMenuItem, &unicodeMenu); | 
|  |  | 
|  | unicodeMenuItem.setSubMenu(&unicodeMenu); | 
|  | } | 
|  |  | 
|  | #else | 
|  |  | 
|  | void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem) | 
|  | { | 
|  | ContextMenu writingDirectionMenu; | 
|  |  | 
|  | ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection, | 
|  | contextMenuItemTagDefaultDirection()); | 
|  | ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight()); | 
|  | ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft()); | 
|  |  | 
|  | appendItem(defaultItem, &writingDirectionMenu); | 
|  | appendItem(ltr, &writingDirectionMenu); | 
|  | appendItem(rtl, &writingDirectionMenu); | 
|  |  | 
|  | writingDirectionMenuItem.setSubMenu(&writingDirectionMenu); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem) | 
|  | { | 
|  | ContextMenu textDirectionMenu; | 
|  |  | 
|  | ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection()); | 
|  | ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight()); | 
|  | ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft()); | 
|  |  | 
|  | appendItem(defaultItem, &textDirectionMenu); | 
|  | appendItem(ltr, &textDirectionMenu); | 
|  | appendItem(rtl, &textDirectionMenu); | 
|  |  | 
|  | textDirectionMenuItem.setSubMenu(&textDirectionMenu); | 
|  | } | 
|  |  | 
|  | #endif | 
|  |  | 
|  | #if PLATFORM(COCOA) | 
|  |  | 
|  | void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem) | 
|  | { | 
|  | ContextMenu substitutionsMenu; | 
|  |  | 
|  | ContextMenuItem showSubstitutions(ActionType, ContextMenuItemTagShowSubstitutions, contextMenuItemTagShowSubstitutions(true)); | 
|  | ContextMenuItem smartCopyPaste(CheckableActionType, ContextMenuItemTagSmartCopyPaste, contextMenuItemTagSmartCopyPaste()); | 
|  | ContextMenuItem smartQuotes(CheckableActionType, ContextMenuItemTagSmartQuotes, contextMenuItemTagSmartQuotes()); | 
|  | ContextMenuItem smartDashes(CheckableActionType, ContextMenuItemTagSmartDashes, contextMenuItemTagSmartDashes()); | 
|  | ContextMenuItem smartLinks(CheckableActionType, ContextMenuItemTagSmartLinks, contextMenuItemTagSmartLinks()); | 
|  | ContextMenuItem textReplacement(CheckableActionType, ContextMenuItemTagTextReplacement, contextMenuItemTagTextReplacement()); | 
|  |  | 
|  | appendItem(showSubstitutions, &substitutionsMenu); | 
|  | appendItem(*separatorItem(), &substitutionsMenu); | 
|  | appendItem(smartCopyPaste, &substitutionsMenu); | 
|  | appendItem(smartQuotes, &substitutionsMenu); | 
|  | appendItem(smartDashes, &substitutionsMenu); | 
|  | appendItem(smartLinks, &substitutionsMenu); | 
|  | appendItem(textReplacement, &substitutionsMenu); | 
|  |  | 
|  | substitutionsMenuItem.setSubMenu(&substitutionsMenu); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuItem& transformationsMenuItem) | 
|  | { | 
|  | ContextMenu transformationsMenu; | 
|  |  | 
|  | ContextMenuItem makeUpperCase(ActionType, ContextMenuItemTagMakeUpperCase, contextMenuItemTagMakeUpperCase()); | 
|  | ContextMenuItem makeLowerCase(ActionType, ContextMenuItemTagMakeLowerCase, contextMenuItemTagMakeLowerCase()); | 
|  | ContextMenuItem capitalize(ActionType, ContextMenuItemTagCapitalize, contextMenuItemTagCapitalize()); | 
|  |  | 
|  | appendItem(makeUpperCase, &transformationsMenu); | 
|  | appendItem(makeLowerCase, &transformationsMenu); | 
|  | appendItem(capitalize, &transformationsMenu); | 
|  |  | 
|  | transformationsMenuItem.setSubMenu(&transformationsMenu); | 
|  | } | 
|  |  | 
|  | #endif | 
|  |  | 
|  | #if PLATFORM(COCOA) | 
|  | #define SUPPORTS_TOGGLE_VIDEO_FULLSCREEN 1 | 
|  | #else | 
|  | #define SUPPORTS_TOGGLE_VIDEO_FULLSCREEN 0 | 
|  | #endif | 
|  |  | 
|  | #if PLATFORM(COCOA) | 
|  | #define SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS 1 | 
|  | #else | 
|  | #define SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS 0 | 
|  | #endif | 
|  |  | 
|  | void ContextMenuController::populate() | 
|  | { | 
|  | ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink()); | 
|  | ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow, | 
|  | contextMenuItemTagOpenLinkInNewWindow()); | 
|  | ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk, | 
|  | contextMenuItemTagDownloadLinkToDisk()); | 
|  | ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard, | 
|  | contextMenuItemTagCopyLinkToClipboard()); | 
|  | ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow, | 
|  | contextMenuItemTagOpenImageInNewWindow()); | 
|  | ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk, | 
|  | contextMenuItemTagDownloadImageToDisk()); | 
|  | ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard, | 
|  | contextMenuItemTagCopyImageToClipboard()); | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard, | 
|  | contextMenuItemTagCopyImageUrlToClipboard()); | 
|  | #endif | 
|  | ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenMediaInNewWindow, String()); | 
|  | ContextMenuItem DownloadMediaItem(ActionType, ContextMenuItemTagDownloadMediaToDisk, String()); | 
|  | ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLinkToClipboard, String()); | 
|  | ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause, | 
|  | contextMenuItemTagMediaPlay()); | 
|  | ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute, | 
|  | contextMenuItemTagMediaMute()); | 
|  | #if SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS | 
|  | ContextMenuItem ToggleMediaControls(ActionType, ContextMenuItemTagToggleMediaControls, | 
|  | contextMenuItemTagHideMediaControls()); | 
|  | #else | 
|  | ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagToggleMediaControls, | 
|  | contextMenuItemTagToggleMediaControls()); | 
|  | #endif | 
|  | ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggleMediaLoop, | 
|  | contextMenuItemTagToggleMediaLoop()); | 
|  | ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVideoFullscreen, | 
|  | contextMenuItemTagEnterVideoFullscreen()); | 
|  | ContextMenuItem ToggleVideoFullscreen(ActionType, ContextMenuItemTagToggleVideoFullscreen, | 
|  | contextMenuItemTagEnterVideoFullscreen()); | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight, | 
|  | contextMenuItemTagSearchInSpotlight()); | 
|  | #endif | 
|  | #if !PLATFORM(GTK) | 
|  | ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb()); | 
|  | #endif | 
|  | ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy()); | 
|  | ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack()); | 
|  | ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward,  contextMenuItemTagGoForward()); | 
|  | ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop()); | 
|  | ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload()); | 
|  | ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow, | 
|  | contextMenuItemTagOpenFrameInNewWindow()); | 
|  | ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound, | 
|  | contextMenuItemTagNoGuessesFound()); | 
|  | ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling, | 
|  | contextMenuItemTagIgnoreSpelling()); | 
|  | ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling, | 
|  | contextMenuItemTagLearnSpelling()); | 
|  | ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar, | 
|  | contextMenuItemTagIgnoreGrammar()); | 
|  | ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut()); | 
|  | ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste()); | 
|  | #if PLATFORM(GTK) | 
|  | ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete()); | 
|  | #endif | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll()); | 
|  | #endif | 
|  |  | 
|  | ContextMenuItem ShareMenuItem = m_client.shareMenuItem(m_context.hitTestResult()); | 
|  |  | 
|  | Node* node = m_context.hitTestResult().innerNonSharedNode(); | 
|  | if (!node) | 
|  | return; | 
|  | #if PLATFORM(GTK) | 
|  | if (!m_context.hitTestResult().isContentEditable() && is<HTMLFormControlElement>(*node)) | 
|  | return; | 
|  | #endif | 
|  | Frame* frame = node->document().frame(); | 
|  | if (!frame) | 
|  | return; | 
|  |  | 
|  | #if ENABLE(SERVICE_CONTROLS) | 
|  | // The default image control menu gets populated solely by the platform. | 
|  | if (m_context.controlledImage()) | 
|  | return; | 
|  | #endif | 
|  |  | 
|  | if (!m_context.hitTestResult().isContentEditable()) { | 
|  | String selectedString = m_context.hitTestResult().selectedText(); | 
|  | m_context.setSelectedText(selectedString); | 
|  |  | 
|  | FrameLoader& loader = frame->loader(); | 
|  | URL linkURL = m_context.hitTestResult().absoluteLinkURL(); | 
|  | if (!linkURL.isEmpty()) { | 
|  | if (loader.client().canHandleRequest(ResourceRequest(linkURL))) { | 
|  | appendItem(OpenLinkItem, m_contextMenu.get()); | 
|  | appendItem(OpenLinkInNewWindowItem, m_contextMenu.get()); | 
|  | appendItem(DownloadFileItem, m_contextMenu.get()); | 
|  | } | 
|  | appendItem(CopyLinkItem, m_contextMenu.get()); | 
|  | } | 
|  |  | 
|  | URL imageURL = m_context.hitTestResult().absoluteImageURL(); | 
|  | if (!imageURL.isEmpty()) { | 
|  | if (!linkURL.isEmpty()) | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  |  | 
|  | appendItem(OpenImageInNewWindowItem, m_contextMenu.get()); | 
|  | appendItem(DownloadImageItem, m_contextMenu.get()); | 
|  | if (imageURL.isLocalFile() || m_context.hitTestResult().image()) | 
|  | appendItem(CopyImageItem, m_contextMenu.get()); | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | appendItem(CopyImageUrlItem, m_contextMenu.get()); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | URL mediaURL = m_context.hitTestResult().absoluteMediaURL(); | 
|  | if (!mediaURL.isEmpty()) { | 
|  | if (!linkURL.isEmpty() || !imageURL.isEmpty()) | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  |  | 
|  | appendItem(MediaPlayPause, m_contextMenu.get()); | 
|  | appendItem(MediaMute, m_contextMenu.get()); | 
|  | appendItem(ToggleMediaControls, m_contextMenu.get()); | 
|  | appendItem(ToggleMediaLoop, m_contextMenu.get()); | 
|  | #if SUPPORTS_TOGGLE_VIDEO_FULLSCREEN | 
|  | appendItem(ToggleVideoFullscreen, m_contextMenu.get()); | 
|  | #else | 
|  | appendItem(EnterVideoFullscreen, m_contextMenu.get()); | 
|  | #endif | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | appendItem(CopyMediaLinkItem, m_contextMenu.get()); | 
|  | appendItem(OpenMediaInNewWindowItem, m_contextMenu.get()); | 
|  | if (m_context.hitTestResult().isDownloadableMedia() && loader.client().canHandleRequest(ResourceRequest(mediaURL))) | 
|  | appendItem(DownloadMediaItem, m_contextMenu.get()); | 
|  | } | 
|  |  | 
|  | if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) { | 
|  | if (m_context.hitTestResult().isSelected()) { | 
|  | if (!selectedString.isEmpty()) { | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString)); | 
|  |  | 
|  | appendItem(LookUpInDictionaryItem, m_contextMenu.get()); | 
|  | #endif | 
|  |  | 
|  | #if !PLATFORM(GTK) | 
|  | appendItem(SearchWebItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | appendItem(CopyItem, m_contextMenu.get()); | 
|  | #if PLATFORM(COCOA) | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  |  | 
|  | if (!ShareMenuItem.isNull()) { | 
|  | appendItem(ShareMenuItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | } | 
|  |  | 
|  | ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu()); | 
|  | createAndAppendSpeechSubMenu(SpeechMenuItem); | 
|  | appendItem(SpeechMenuItem, m_contextMenu.get()); | 
|  | #endif | 
|  | } else { | 
|  | if (!(frame->page() && (frame->page()->inspectorController().hasInspectorFrontendClient() || frame->page()->inspectorController().hasRemoteFrontend()))) { | 
|  |  | 
|  | // In GTK+ unavailable items are not hidden but insensitive. | 
|  | #if PLATFORM(GTK) | 
|  | appendItem(BackItem, m_contextMenu.get()); | 
|  | appendItem(ForwardItem, m_contextMenu.get()); | 
|  | appendItem(StopItem, m_contextMenu.get()); | 
|  | appendItem(ReloadItem, m_contextMenu.get()); | 
|  | #else | 
|  | if (frame->page() && frame->page()->backForward().canGoBackOrForward(-1)) | 
|  | appendItem(BackItem, m_contextMenu.get()); | 
|  |  | 
|  | if (frame->page() && frame->page()->backForward().canGoBackOrForward(1)) | 
|  | appendItem(ForwardItem, m_contextMenu.get()); | 
|  |  | 
|  | // use isLoadingInAPISense rather than isLoading because Stop/Reload are | 
|  | // intended to match WebKit's API, not WebCore's internal notion of loading status | 
|  | if (loader.documentLoader()->isLoadingInAPISense()) | 
|  | appendItem(StopItem, m_contextMenu.get()); | 
|  | else | 
|  | appendItem(ReloadItem, m_contextMenu.get()); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | if (frame->page() && !frame->isMainFrame()) | 
|  | appendItem(OpenFrameItem, m_contextMenu.get()); | 
|  |  | 
|  | if (!ShareMenuItem.isNull()) { | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | appendItem(ShareMenuItem, m_contextMenu.get()); | 
|  | } | 
|  | } | 
|  | } else if (!ShareMenuItem.isNull()) { | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | appendItem(ShareMenuItem, m_contextMenu.get()); | 
|  | } | 
|  | } else { // Make an editing context menu | 
|  | bool inPasswordField = frame->selection().selection().isInPasswordField(); | 
|  | if (!inPasswordField) { | 
|  | bool haveContextMenuItemsForMisspellingOrGrammer = false; | 
|  | bool spellCheckingEnabled = frame->editor().isSpellCheckingEnabledFor(node); | 
|  | if (spellCheckingEnabled) { | 
|  | // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range | 
|  | // is never considered a misspelling and bad grammar at the same time) | 
|  | bool misspelling; | 
|  | bool badGrammar; | 
|  | Vector<String> guesses = frame->editor().guessesForMisspelledOrUngrammatical(misspelling, badGrammar); | 
|  | if (misspelling || badGrammar) { | 
|  | if (guesses.isEmpty()) { | 
|  | // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions | 
|  | // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit) | 
|  | if (misspelling) { | 
|  | appendItem(NoGuessesItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | } | 
|  | } else { | 
|  | for (const auto& guess : guesses) { | 
|  | if (!guess.isEmpty()) { | 
|  | ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess); | 
|  | appendItem(item, m_contextMenu.get()); | 
|  | } | 
|  | } | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | } | 
|  | if (misspelling) { | 
|  | appendItem(IgnoreSpellingItem, m_contextMenu.get()); | 
|  | appendItem(LearnSpellingItem, m_contextMenu.get()); | 
|  | } else | 
|  | appendItem(IgnoreGrammarItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | haveContextMenuItemsForMisspellingOrGrammer = true; | 
|  | #if PLATFORM(COCOA) | 
|  | } else { | 
|  | // If the string was autocorrected, generate a contextual menu item allowing it to be changed back. | 
|  | String replacedString = m_context.hitTestResult().replacedString(); | 
|  | if (!replacedString.isEmpty()) { | 
|  | ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString)); | 
|  | appendItem(item, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | haveContextMenuItemsForMisspellingOrGrammer = true; | 
|  | } | 
|  | #endif | 
|  | } | 
|  | } | 
|  |  | 
|  | if (!haveContextMenuItemsForMisspellingOrGrammer) { | 
|  | // Spelling and grammar checking is mutually exclusive with dictation alternatives. | 
|  | Vector<String> dictationAlternatives = m_context.hitTestResult().dictationAlternatives(); | 
|  | if (!dictationAlternatives.isEmpty()) { | 
|  | for (auto& alternative : dictationAlternatives) { | 
|  | ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, alternative); | 
|  | appendItem(item, m_contextMenu.get()); | 
|  | } | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | FrameLoader& loader = frame->loader(); | 
|  | URL linkURL = m_context.hitTestResult().absoluteLinkURL(); | 
|  | if (!linkURL.isEmpty()) { | 
|  | if (loader.client().canHandleRequest(ResourceRequest(linkURL))) { | 
|  | appendItem(OpenLinkItem, m_contextMenu.get()); | 
|  | appendItem(OpenLinkInNewWindowItem, m_contextMenu.get()); | 
|  | appendItem(DownloadFileItem, m_contextMenu.get()); | 
|  | } | 
|  | appendItem(CopyLinkItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | } | 
|  |  | 
|  | String selectedText = m_context.hitTestResult().selectedText(); | 
|  | if (m_context.hitTestResult().isSelected() && !inPasswordField && !selectedText.isEmpty()) { | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedText)); | 
|  |  | 
|  | appendItem(LookUpInDictionaryItem, m_contextMenu.get()); | 
|  | #endif | 
|  |  | 
|  | #if !PLATFORM(GTK) | 
|  | appendItem(SearchWebItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | appendItem(CutItem, m_contextMenu.get()); | 
|  | appendItem(CopyItem, m_contextMenu.get()); | 
|  | appendItem(PasteItem, m_contextMenu.get()); | 
|  | #if PLATFORM(GTK) | 
|  | appendItem(DeleteItem, m_contextMenu.get()); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | #endif | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | appendItem(SelectAllItem, m_contextMenu.get()); | 
|  | #endif | 
|  |  | 
|  | if (!inPasswordField) { | 
|  | #if !PLATFORM(GTK) | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu, | 
|  | contextMenuItemTagSpellingMenu()); | 
|  | createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem); | 
|  | appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get()); | 
|  | #endif | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu, | 
|  | contextMenuItemTagSubstitutionsMenu()); | 
|  | createAndAppendSubstitutionsSubMenu(substitutionsMenuItem); | 
|  | appendItem(substitutionsMenuItem, m_contextMenu.get()); | 
|  | ContextMenuItem transformationsMenuItem(SubmenuType, ContextMenuItemTagTransformationsMenu, | 
|  | contextMenuItemTagTransformationsMenu()); | 
|  | createAndAppendTransformationsSubMenu(transformationsMenuItem); | 
|  | appendItem(transformationsMenuItem, m_contextMenu.get()); | 
|  | #endif | 
|  | #if PLATFORM(GTK) | 
|  | bool shouldShowFontMenu = frame->editor().canEditRichly(); | 
|  | #else | 
|  | bool shouldShowFontMenu = true; | 
|  | #endif | 
|  | if (shouldShowFontMenu) { | 
|  | ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu, | 
|  | contextMenuItemTagFontMenu()); | 
|  | createAndAppendFontSubMenu(FontMenuItem); | 
|  | appendItem(FontMenuItem, m_contextMenu.get()); | 
|  | } | 
|  | #if PLATFORM(COCOA) | 
|  | ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu()); | 
|  | createAndAppendSpeechSubMenu(SpeechMenuItem); | 
|  | appendItem(SpeechMenuItem, m_contextMenu.get()); | 
|  | #endif | 
|  | #if PLATFORM(GTK) | 
|  | EditorClient* client = frame->editor().client(); | 
|  | if (client && client->shouldShowUnicodeMenu()) { | 
|  | ContextMenuItem UnicodeMenuItem(SubmenuType, ContextMenuItemTagUnicode, contextMenuItemTagUnicode()); | 
|  | createAndAppendUnicodeSubMenu(UnicodeMenuItem); | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | appendItem(UnicodeMenuItem, m_contextMenu.get()); | 
|  | } | 
|  | #else | 
|  | ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu, | 
|  | contextMenuItemTagWritingDirectionMenu()); | 
|  | createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem); | 
|  | appendItem(WritingDirectionMenuItem, m_contextMenu.get()); | 
|  | if (Page* page = frame->page()) { | 
|  | bool includeTextDirectionSubmenu = page->settings().textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded | 
|  | || (page->settings().textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor().hasBidiSelection()); | 
|  | if (includeTextDirectionSubmenu) { | 
|  | ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu, contextMenuItemTagTextDirectionMenu()); | 
|  | createAndAppendTextDirectionSubMenu(TextDirectionMenuItem); | 
|  | appendItem(TextDirectionMenuItem, m_contextMenu.get()); | 
|  | } | 
|  | } | 
|  | #endif | 
|  | } | 
|  |  | 
|  | if (!ShareMenuItem.isNull()) { | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | appendItem(ShareMenuItem, m_contextMenu.get()); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void ContextMenuController::addInspectElementItem() | 
|  | { | 
|  | Node* node = m_context.hitTestResult().innerNonSharedNode(); | 
|  | if (!node) | 
|  | return; | 
|  |  | 
|  | Frame* frame = node->document().frame(); | 
|  | if (!frame) | 
|  | return; | 
|  |  | 
|  | Page* page = frame->page(); | 
|  | if (!page) | 
|  | return; | 
|  |  | 
|  | ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement()); | 
|  | #if USE(CROSS_PLATFORM_CONTEXT_MENUS) | 
|  | if (m_contextMenu && !m_contextMenu->items().isEmpty()) | 
|  | #else | 
|  | if (m_contextMenu && m_contextMenu->itemCount()) | 
|  | #endif | 
|  | appendItem(*separatorItem(), m_contextMenu.get()); | 
|  | appendItem(InspectElementItem, m_contextMenu.get()); | 
|  | } | 
|  |  | 
|  | void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const | 
|  | { | 
|  | if (item.type() == SeparatorType) | 
|  | return; | 
|  |  | 
|  | Frame* frame = m_context.hitTestResult().innerNonSharedNode()->document().frame(); | 
|  | if (!frame) | 
|  | return; | 
|  |  | 
|  | // Custom items already have proper checked and enabled values. | 
|  | if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag) | 
|  | return; | 
|  |  | 
|  | bool shouldEnable = true; | 
|  | bool shouldCheck = false; | 
|  |  | 
|  | switch (item.action()) { | 
|  | case ContextMenuItemTagCheckSpelling: | 
|  | shouldEnable = frame->editor().canEdit(); | 
|  | break; | 
|  | case ContextMenuItemTagDefaultDirection: | 
|  | shouldCheck = false; | 
|  | shouldEnable = false; | 
|  | break; | 
|  | case ContextMenuItemTagLeftToRight: | 
|  | case ContextMenuItemTagRightToLeft: { | 
|  | String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl"; | 
|  | shouldCheck = frame->editor().selectionHasStyle(CSSPropertyDirection, direction) != FalseTriState; | 
|  | shouldEnable = true; | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagTextDirectionDefault: { | 
|  | Editor::Command command = frame->editor().command("MakeTextWritingDirectionNatural"); | 
|  | shouldCheck = command.state() == TrueTriState; | 
|  | shouldEnable = command.isEnabled(); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagTextDirectionLeftToRight: { | 
|  | Editor::Command command = frame->editor().command("MakeTextWritingDirectionLeftToRight"); | 
|  | shouldCheck = command.state() == TrueTriState; | 
|  | shouldEnable = command.isEnabled(); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagTextDirectionRightToLeft: { | 
|  | Editor::Command command = frame->editor().command("MakeTextWritingDirectionRightToLeft"); | 
|  | shouldCheck = command.state() == TrueTriState; | 
|  | shouldEnable = command.isEnabled(); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagCopy: | 
|  | shouldEnable = frame->editor().canDHTMLCopy() || frame->editor().canCopy(); | 
|  | break; | 
|  | case ContextMenuItemTagCut: | 
|  | shouldEnable = frame->editor().canDHTMLCut() || frame->editor().canCut(); | 
|  | break; | 
|  | case ContextMenuItemTagIgnoreSpelling: | 
|  | case ContextMenuItemTagLearnSpelling: | 
|  | shouldEnable = frame->selection().isRange(); | 
|  | break; | 
|  | case ContextMenuItemTagPaste: | 
|  | shouldEnable = frame->editor().canDHTMLPaste() || frame->editor().canPaste(); | 
|  | break; | 
|  | #if PLATFORM(GTK) | 
|  | case ContextMenuItemTagDelete: | 
|  | shouldEnable = frame->editor().canDelete(); | 
|  | break; | 
|  | case ContextMenuItemTagInputMethods: | 
|  | case ContextMenuItemTagUnicode: | 
|  | case ContextMenuItemTagUnicodeInsertLRMMark: | 
|  | case ContextMenuItemTagUnicodeInsertRLMMark: | 
|  | case ContextMenuItemTagUnicodeInsertLREMark: | 
|  | case ContextMenuItemTagUnicodeInsertRLEMark: | 
|  | case ContextMenuItemTagUnicodeInsertLROMark: | 
|  | case ContextMenuItemTagUnicodeInsertRLOMark: | 
|  | case ContextMenuItemTagUnicodeInsertPDFMark: | 
|  | case ContextMenuItemTagUnicodeInsertZWSMark: | 
|  | case ContextMenuItemTagUnicodeInsertZWJMark: | 
|  | case ContextMenuItemTagUnicodeInsertZWNJMark: | 
|  | shouldEnable = true; | 
|  | break; | 
|  | #endif | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | case ContextMenuItemTagSelectAll: | 
|  | shouldEnable = true; | 
|  | break; | 
|  | #endif | 
|  | case ContextMenuItemTagUnderline: { | 
|  | shouldCheck = frame->editor().selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") != FalseTriState; | 
|  | shouldEnable = frame->editor().canEditRichly(); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagLookUpInDictionary: | 
|  | shouldEnable = frame->selection().isRange(); | 
|  | break; | 
|  | case ContextMenuItemTagCheckGrammarWithSpelling: | 
|  | if (frame->editor().isGrammarCheckingEnabled()) | 
|  | shouldCheck = true; | 
|  | shouldEnable = true; | 
|  | break; | 
|  | case ContextMenuItemTagItalic: { | 
|  | shouldCheck = frame->editor().selectionHasStyle(CSSPropertyFontStyle, "italic") != FalseTriState; | 
|  | shouldEnable = frame->editor().canEditRichly(); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagBold: { | 
|  | shouldCheck = frame->editor().selectionHasStyle(CSSPropertyFontWeight, "bold") != FalseTriState; | 
|  | shouldEnable = frame->editor().canEditRichly(); | 
|  | break; | 
|  | } | 
|  | case ContextMenuItemTagOutline: | 
|  | shouldEnable = false; | 
|  | break; | 
|  | case ContextMenuItemTagShowSpellingPanel: | 
|  | if (frame->editor().spellingPanelIsShowing()) | 
|  | item.setTitle(contextMenuItemTagShowSpellingPanel(false)); | 
|  | else | 
|  | item.setTitle(contextMenuItemTagShowSpellingPanel(true)); | 
|  | shouldEnable = frame->editor().canEdit(); | 
|  | break; | 
|  | case ContextMenuItemTagNoGuessesFound: | 
|  | shouldEnable = false; | 
|  | break; | 
|  | case ContextMenuItemTagCheckSpellingWhileTyping: | 
|  | shouldCheck = frame->editor().isContinuousSpellCheckingEnabled(); | 
|  | break; | 
|  | #if PLATFORM(COCOA) | 
|  | case ContextMenuItemTagSubstitutionsMenu: | 
|  | case ContextMenuItemTagTransformationsMenu: | 
|  | break; | 
|  | case ContextMenuItemTagShowSubstitutions: | 
|  | if (frame->editor().substitutionsPanelIsShowing()) | 
|  | item.setTitle(contextMenuItemTagShowSubstitutions(false)); | 
|  | else | 
|  | item.setTitle(contextMenuItemTagShowSubstitutions(true)); | 
|  | shouldEnable = frame->editor().canEdit(); | 
|  | break; | 
|  | case ContextMenuItemTagMakeUpperCase: | 
|  | case ContextMenuItemTagMakeLowerCase: | 
|  | case ContextMenuItemTagCapitalize: | 
|  | case ContextMenuItemTagChangeBack: | 
|  | shouldEnable = frame->editor().canEdit(); | 
|  | break; | 
|  | case ContextMenuItemTagCorrectSpellingAutomatically: | 
|  | shouldCheck = frame->editor().isAutomaticSpellingCorrectionEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartCopyPaste: | 
|  | shouldCheck = frame->editor().smartInsertDeleteEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartQuotes: | 
|  | shouldCheck = frame->editor().isAutomaticQuoteSubstitutionEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartDashes: | 
|  | shouldCheck = frame->editor().isAutomaticDashSubstitutionEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagSmartLinks: | 
|  | shouldCheck = frame->editor().isAutomaticLinkDetectionEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagTextReplacement: | 
|  | shouldCheck = frame->editor().isAutomaticTextReplacementEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagStopSpeaking: | 
|  | shouldEnable = m_client.isSpeaking(); | 
|  | break; | 
|  | #else // PLATFORM(COCOA) ends here | 
|  | case ContextMenuItemTagStopSpeaking: | 
|  | break; | 
|  | #endif | 
|  | #if PLATFORM(GTK) | 
|  | case ContextMenuItemTagGoBack: | 
|  | shouldEnable = frame->page() && frame->page()->backForward().canGoBackOrForward(-1); | 
|  | break; | 
|  | case ContextMenuItemTagGoForward: | 
|  | shouldEnable = frame->page() && frame->page()->backForward().canGoBackOrForward(1); | 
|  | break; | 
|  | case ContextMenuItemTagStop: | 
|  | shouldEnable = frame->loader().documentLoader()->isLoadingInAPISense(); | 
|  | break; | 
|  | case ContextMenuItemTagReload: | 
|  | shouldEnable = !frame->loader().documentLoader()->isLoadingInAPISense(); | 
|  | break; | 
|  | case ContextMenuItemTagFontMenu: | 
|  | shouldEnable = frame->editor().canEditRichly(); | 
|  | break; | 
|  | #else | 
|  | case ContextMenuItemTagGoBack: | 
|  | case ContextMenuItemTagGoForward: | 
|  | case ContextMenuItemTagStop: | 
|  | case ContextMenuItemTagReload: | 
|  | case ContextMenuItemTagFontMenu: | 
|  | #endif | 
|  | case ContextMenuItemTagNoAction: | 
|  | case ContextMenuItemTagOpenLinkInNewWindow: | 
|  | case ContextMenuItemTagOpenLinkInThisWindow: | 
|  | case ContextMenuItemTagDownloadLinkToDisk: | 
|  | case ContextMenuItemTagCopyLinkToClipboard: | 
|  | case ContextMenuItemTagOpenImageInNewWindow: | 
|  | case ContextMenuItemTagCopyImageToClipboard: | 
|  | #if PLATFORM(GTK) || PLATFORM(EFL) | 
|  | case ContextMenuItemTagCopyImageUrlToClipboard: | 
|  | #endif | 
|  | break; | 
|  | case ContextMenuItemTagDownloadImageToDisk: | 
|  | #if PLATFORM(MAC) | 
|  | if (WebCore::protocolIs(m_context.hitTestResult().absoluteImageURL(), "file")) | 
|  | shouldEnable = false; | 
|  | #endif | 
|  | break; | 
|  | case ContextMenuItemTagOpenMediaInNewWindow: | 
|  | if (m_context.hitTestResult().mediaIsVideo()) | 
|  | item.setTitle(contextMenuItemTagOpenVideoInNewWindow()); | 
|  | else | 
|  | item.setTitle(contextMenuItemTagOpenAudioInNewWindow()); | 
|  | break; | 
|  | case ContextMenuItemTagDownloadMediaToDisk: | 
|  | if (m_context.hitTestResult().mediaIsVideo()) | 
|  | item.setTitle(contextMenuItemTagDownloadVideoToDisk()); | 
|  | else | 
|  | item.setTitle(contextMenuItemTagDownloadAudioToDisk()); | 
|  | if (WebCore::protocolIs(m_context.hitTestResult().absoluteImageURL(), "file")) | 
|  | shouldEnable = false; | 
|  | break; | 
|  | case ContextMenuItemTagCopyMediaLinkToClipboard: | 
|  | if (m_context.hitTestResult().mediaIsVideo()) | 
|  | item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard()); | 
|  | else | 
|  | item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard()); | 
|  | break; | 
|  | case ContextMenuItemTagToggleMediaControls: | 
|  | #if SUPPORTS_TOGGLE_SHOW_HIDE_MEDIA_CONTROLS | 
|  | item.setTitle(m_context.hitTestResult().mediaControlsEnabled() ? contextMenuItemTagHideMediaControls() : contextMenuItemTagShowMediaControls()); | 
|  | #else | 
|  | shouldCheck = m_context.hitTestResult().mediaControlsEnabled(); | 
|  | #endif | 
|  | break; | 
|  | case ContextMenuItemTagToggleMediaLoop: | 
|  | shouldCheck = m_context.hitTestResult().mediaLoopEnabled(); | 
|  | break; | 
|  | case ContextMenuItemTagToggleVideoFullscreen: | 
|  | #if SUPPORTS_TOGGLE_VIDEO_FULLSCREEN | 
|  | item.setTitle(m_context.hitTestResult().mediaIsInFullscreen() ? contextMenuItemTagExitVideoFullscreen() : contextMenuItemTagEnterVideoFullscreen()); | 
|  | break; | 
|  | #endif | 
|  | case ContextMenuItemTagEnterVideoFullscreen: | 
|  | shouldEnable = m_context.hitTestResult().mediaSupportsFullscreen(); | 
|  | break; | 
|  | case ContextMenuItemTagOpenFrameInNewWindow: | 
|  | case ContextMenuItemTagSpellingGuess: | 
|  | case ContextMenuItemTagOther: | 
|  | case ContextMenuItemTagSearchInSpotlight: | 
|  | case ContextMenuItemTagSearchWeb: | 
|  | case ContextMenuItemTagOpenWithDefaultApplication: | 
|  | case ContextMenuItemPDFActualSize: | 
|  | case ContextMenuItemPDFZoomIn: | 
|  | case ContextMenuItemPDFZoomOut: | 
|  | case ContextMenuItemPDFAutoSize: | 
|  | case ContextMenuItemPDFSinglePage: | 
|  | case ContextMenuItemPDFFacingPages: | 
|  | case ContextMenuItemPDFContinuous: | 
|  | case ContextMenuItemPDFNextPage: | 
|  | case ContextMenuItemPDFPreviousPage: | 
|  | case ContextMenuItemTagOpenLink: | 
|  | case ContextMenuItemTagIgnoreGrammar: | 
|  | case ContextMenuItemTagSpellingMenu: | 
|  | case ContextMenuItemTagShowFonts: | 
|  | case ContextMenuItemTagStyles: | 
|  | case ContextMenuItemTagShowColors: | 
|  | case ContextMenuItemTagSpeechMenu: | 
|  | case ContextMenuItemTagStartSpeaking: | 
|  | case ContextMenuItemTagWritingDirectionMenu: | 
|  | case ContextMenuItemTagTextDirectionMenu: | 
|  | case ContextMenuItemTagPDFSinglePageScrolling: | 
|  | case ContextMenuItemTagPDFFacingPagesScrolling: | 
|  | case ContextMenuItemTagInspectElement: | 
|  | case ContextMenuItemBaseCustomTag: | 
|  | case ContextMenuItemCustomTagNoAction: | 
|  | case ContextMenuItemLastCustomTag: | 
|  | case ContextMenuItemBaseApplicationTag: | 
|  | case ContextMenuItemTagDictationAlternative: | 
|  | case ContextMenuItemTagShareMenu: | 
|  | break; | 
|  | case ContextMenuItemTagMediaPlayPause: | 
|  | if (m_context.hitTestResult().mediaPlaying()) | 
|  | item.setTitle(contextMenuItemTagMediaPause()); | 
|  | else | 
|  | item.setTitle(contextMenuItemTagMediaPlay()); | 
|  | break; | 
|  | case ContextMenuItemTagMediaMute: | 
|  | shouldEnable = m_context.hitTestResult().mediaHasAudio(); | 
|  | shouldCheck = shouldEnable &&  m_context.hitTestResult().mediaMuted(); | 
|  | break; | 
|  | } | 
|  |  | 
|  | item.setChecked(shouldCheck); | 
|  | item.setEnabled(shouldEnable); | 
|  | } | 
|  |  | 
|  | #if USE(ACCESSIBILITY_CONTEXT_MENUS) | 
|  | void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clickPoint) | 
|  | { | 
|  | clearContextMenu(); | 
|  |  | 
|  | // Simulate a click in the middle of the accessibility object. | 
|  | PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime(), ForceAtClick); | 
|  | frame->eventHandler().handleMousePressEvent(mouseEvent); | 
|  | bool handled = frame->eventHandler().sendContextMenuEvent(mouseEvent); | 
|  | if (handled) | 
|  | m_client.showContextMenu(); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if ENABLE(SERVICE_CONTROLS) | 
|  | void ContextMenuController::showImageControlsMenu(Event* event) | 
|  | { | 
|  | clearContextMenu(); | 
|  | handleContextMenuEvent(event); | 
|  | m_client.showContextMenu(); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | } // namespace WebCore | 
|  |  | 
|  | #endif // ENABLE(CONTEXT_MENUS) |