2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Igalia S.L
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
28 #include "ContextMenuController.h"
30 #if ENABLE(CONTEXT_MENUS)
32 #include "BackForwardController.h"
34 #include "ContextMenu.h"
35 #include "ContextMenuClient.h"
36 #include "ContextMenuItem.h"
37 #include "ContextMenuProvider.h"
39 #include "DocumentFragment.h"
40 #include "DocumentLoader.h"
42 #include "EditorClient.h"
44 #include "EventHandler.h"
45 #include "EventNames.h"
46 #include "FormState.h"
48 #include "FrameLoadRequest.h"
49 #include "FrameLoader.h"
50 #include "FrameLoaderClient.h"
51 #include "FrameSelection.h"
52 #include "HTMLFormElement.h"
53 #include "HitTestRequest.h"
54 #include "HitTestResult.h"
55 #include "InspectorController.h"
56 #include "LocalizedStrings.h"
57 #include "MouseEvent.h"
58 #include "NavigationAction.h"
61 #include "RenderLayer.h"
62 #include "RenderObject.h"
63 #include "ReplaceSelectionCommand.h"
64 #include "ResourceRequest.h"
66 #include "TextIterator.h"
67 #include "UserTypingGestureIndicator.h"
68 #include "WindowFeatures.h"
70 #include <wtf/unicode/Unicode.h>
73 using namespace Unicode;
77 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* client)
81 ASSERT_ARG(page, page);
82 ASSERT_ARG(client, client);
85 ContextMenuController::~ContextMenuController()
87 #if ENABLE(TIZEN_CONTEXT_MENU)
88 //this fixes a bug which occured when WebKit was shut down if a context menu was active
89 //then ContextMenuController destructor was calling:
90 //- first m_client->contextMenuDestroyed which destroyed the m_client object explicitly and then
91 //- and then m_contextMenu implicitily
92 //m_contextMenu destructor was then trying to call freePlatformDescription on m_contextMenuClient
93 //which was already destroyed
94 if (contextMenu() && contextMenu()->platformDescription()) {
95 m_client->freePlatformDescription(contextMenu()->platformDescription());
96 contextMenu()->setPlatformDescription(0);
99 m_client->contextMenuDestroyed();
102 void ContextMenuController::clearContextMenu()
104 m_contextMenu.clear();
106 m_menuProvider->contextMenuCleared();
110 void ContextMenuController::handleContextMenuEvent(Event* event)
112 m_contextMenu = createContextMenu(event);
118 showContextMenu(event);
121 static PassOwnPtr<ContextMenuItem> separatorItem()
123 return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
126 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
128 m_menuProvider = menuProvider;
130 m_contextMenu = createContextMenu(event);
131 if (!m_contextMenu) {
136 m_menuProvider->populateContextMenu(m_contextMenu.get());
137 if (m_hitTestResult.isSelected()) {
138 appendItem(*separatorItem(), m_contextMenu.get());
141 showContextMenu(event);
144 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
146 if (!event->isMouseEvent())
149 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
150 HitTestResult result(mouseEvent->absoluteLocation());
152 if (Frame* frame = event->target()->toNode()->document()->frame())
153 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
155 if (!result.innerNonSharedNode())
158 m_hitTestResult = result;
160 #if ENABLE(TIZEN_CONTEXT_MENU)
161 return adoptPtr(new ContextMenu(result));
163 return adoptPtr(new ContextMenu);
167 void ContextMenuController::showContextMenu(Event* event)
169 #if ENABLE(INSPECTOR) && !ENABLE(TIZEN_CONTEXT_MENU)
170 if (m_page->inspectorController()->enabled())
171 addInspectElementItem();
174 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
175 m_contextMenu = m_client->customizeMenu(m_contextMenu.release());
177 PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
178 m_contextMenu->setPlatformDescription(customMenu);
180 event->setDefaultHandled();
183 static void openNewWindow(const KURL& urlToLoad, Frame* frame)
185 if (Page* oldPage = frame->page()) {
186 FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader()->outgoingReferrer()));
187 if (Page* newPage = oldPage->chrome()->createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()))) {
188 newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
189 newPage->chrome()->show();
194 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
196 ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
198 if (item->action() >= ContextMenuItemBaseApplicationTag) {
199 m_client->contextMenuItemSelected(item, m_contextMenu.get());
203 if (item->action() >= ContextMenuItemBaseCustomTag) {
204 ASSERT(m_menuProvider);
205 m_menuProvider->contextMenuItemSelected(item);
209 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
213 switch (item->action()) {
214 case ContextMenuItemTagOpenLinkInNewWindow:
215 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
217 case ContextMenuItemTagDownloadLinkToDisk:
218 // FIXME: Some day we should be able to do this from within WebCore.
219 m_client->downloadURL(m_hitTestResult.absoluteLinkURL());
221 case ContextMenuItemTagCopyLinkToClipboard:
222 frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestResult.textContent());
224 case ContextMenuItemTagOpenImageInNewWindow:
225 openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
227 case ContextMenuItemTagDownloadImageToDisk:
228 // FIXME: Some day we should be able to do this from within WebCore.
229 #if ENABLE(TIZEN_SAVE_IMAGE)
230 m_client->saveAsImage(m_contextMenu.get(), frame, m_hitTestResult.absoluteImageURL());
232 m_client->downloadURL(m_hitTestResult.absoluteImageURL());
235 #if ENABLE(TIZEN_SAVE_IMAGE)
236 case ContextMenuItemTagSendImageViaEmail:
237 m_client->sendImageViaEmail(m_contextMenu.get(), frame, m_hitTestResult.absoluteImageURL());
239 case ContextMenuItemTagSendImageViaMessage:
240 m_client->sendImageViaMessage(m_contextMenu.get(), frame, m_hitTestResult.absoluteImageURL());
243 case ContextMenuItemTagCopyImageToClipboard:
244 // FIXME: The Pasteboard class is not written yet
245 // For now, call into the client. This is temporary!
246 frame->editor()->copyImage(m_hitTestResult);
248 #if PLATFORM(QT) || PLATFORM(GTK)
249 case ContextMenuItemTagCopyImageUrlToClipboard:
250 frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
253 #if ENABLE(TIZEN_COPY_IMAGE_LOCATION)
254 case ContextMenuItemTagCopyImageLocationToClipboard:
255 frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
258 case ContextMenuItemTagOpenMediaInNewWindow:
259 openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
261 case ContextMenuItemTagCopyMediaLinkToClipboard:
262 frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestResult.textContent());
264 case ContextMenuItemTagToggleMediaControls:
265 m_hitTestResult.toggleMediaControlsDisplay();
267 case ContextMenuItemTagToggleMediaLoop:
268 m_hitTestResult.toggleMediaLoopPlayback();
270 case ContextMenuItemTagEnterVideoFullscreen:
271 m_hitTestResult.enterFullscreenForVideo();
273 case ContextMenuItemTagMediaPlayPause:
274 m_hitTestResult.toggleMediaPlayState();
276 case ContextMenuItemTagMediaMute:
277 m_hitTestResult.toggleMediaMuteState();
279 case ContextMenuItemTagOpenFrameInNewWindow: {
280 DocumentLoader* loader = frame->loader()->documentLoader();
281 if (!loader->unreachableURL().isEmpty())
282 openNewWindow(loader->unreachableURL(), frame);
284 openNewWindow(loader->url(), frame);
287 case ContextMenuItemTagCopy:
288 frame->editor()->copy();
290 case ContextMenuItemTagGoBack:
291 if (Page* page = frame->page())
292 page->backForward()->goBackOrForward(-1);
294 case ContextMenuItemTagGoForward:
295 if (Page* page = frame->page())
296 page->backForward()->goBackOrForward(1);
298 case ContextMenuItemTagStop:
299 frame->loader()->stop();
301 case ContextMenuItemTagReload:
302 frame->loader()->reload();
304 case ContextMenuItemTagCut:
305 frame->editor()->command("Cut").execute();
307 case ContextMenuItemTagPaste:
308 frame->editor()->command("Paste").execute();
311 case ContextMenuItemTagDelete:
312 frame->editor()->performDelete();
315 #if PLATFORM(GTK) || PLATFORM(QT)
316 case ContextMenuItemTagSelectAll:
317 frame->editor()->command("SelectAll").execute();
320 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
321 case ContextMenuItemTagSelectAll:
322 frame->editor()->command("SelectAll").execute();
324 case ContextMenuItemTagSelectWord:
325 frame->editor()->command("SelectWord").execute();
328 case ContextMenuItemTagSpellingGuess:
329 ASSERT(frame->editor()->selectedText().length());
330 if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) {
331 Document* document = frame->document();
332 RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting);
333 applyCommand(command);
334 frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
337 case ContextMenuItemTagIgnoreSpelling:
338 frame->editor()->ignoreSpelling();
340 case ContextMenuItemTagLearnSpelling:
341 frame->editor()->learnSpelling();
343 case ContextMenuItemTagSearchWeb:
344 m_client->searchWithGoogle(frame);
346 case ContextMenuItemTagLookUpInDictionary:
347 // FIXME: Some day we may be able to do this from within WebCore.
348 m_client->lookUpInDictionary(frame);
350 case ContextMenuItemTagOpenLink:
351 if (Frame* targetFrame = m_hitTestResult.targetFrame())
352 targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
354 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
356 case ContextMenuItemTagBold:
357 frame->editor()->command("ToggleBold").execute();
359 case ContextMenuItemTagItalic:
360 frame->editor()->command("ToggleItalic").execute();
362 case ContextMenuItemTagUnderline:
363 frame->editor()->toggleUnderline();
365 case ContextMenuItemTagOutline:
366 // We actually never enable this because CSS does not have a way to specify an outline font,
367 // which may make this difficult to implement. Maybe a special case of text-shadow?
369 case ContextMenuItemTagStartSpeaking: {
371 RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
372 if (!selectedRange || selectedRange->collapsed(ec)) {
373 Document* document = m_hitTestResult.innerNonSharedNode()->document();
374 selectedRange = document->createRange();
375 selectedRange->selectNode(document->documentElement(), ec);
377 m_client->speak(plainText(selectedRange.get()));
380 case ContextMenuItemTagStopSpeaking:
381 m_client->stopSpeaking();
383 case ContextMenuItemTagDefaultDirection:
384 frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
386 case ContextMenuItemTagLeftToRight:
387 frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
389 case ContextMenuItemTagRightToLeft:
390 frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
392 case ContextMenuItemTagTextDirectionDefault:
393 frame->editor()->command("MakeTextWritingDirectionNatural").execute();
395 case ContextMenuItemTagTextDirectionLeftToRight:
396 frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute();
398 case ContextMenuItemTagTextDirectionRightToLeft:
399 frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute();
402 case ContextMenuItemTagSearchInSpotlight:
403 m_client->searchWithSpotlight();
406 case ContextMenuItemTagShowSpellingPanel:
407 frame->editor()->showSpellingGuessPanel();
409 case ContextMenuItemTagCheckSpelling:
410 frame->editor()->advanceToNextMisspelling();
412 case ContextMenuItemTagCheckSpellingWhileTyping:
413 frame->editor()->toggleContinuousSpellChecking();
415 case ContextMenuItemTagCheckGrammarWithSpelling:
416 frame->editor()->toggleGrammarChecking();
419 case ContextMenuItemTagShowFonts:
420 frame->editor()->showFontPanel();
422 case ContextMenuItemTagStyles:
423 frame->editor()->showStylesPanel();
425 case ContextMenuItemTagShowColors:
426 frame->editor()->showColorPanel();
429 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
430 case ContextMenuItemTagMakeUpperCase:
431 frame->editor()->uppercaseWord();
433 case ContextMenuItemTagMakeLowerCase:
434 frame->editor()->lowercaseWord();
436 case ContextMenuItemTagCapitalize:
437 frame->editor()->capitalizeWord();
439 case ContextMenuItemTagShowSubstitutions:
440 frame->editor()->showSubstitutionsPanel();
442 case ContextMenuItemTagSmartCopyPaste:
443 frame->editor()->toggleSmartInsertDelete();
445 case ContextMenuItemTagSmartQuotes:
446 frame->editor()->toggleAutomaticQuoteSubstitution();
448 case ContextMenuItemTagSmartDashes:
449 frame->editor()->toggleAutomaticDashSubstitution();
451 case ContextMenuItemTagSmartLinks:
452 frame->editor()->toggleAutomaticLinkDetection();
454 case ContextMenuItemTagTextReplacement:
455 frame->editor()->toggleAutomaticTextReplacement();
457 case ContextMenuItemTagCorrectSpellingAutomatically:
458 frame->editor()->toggleAutomaticSpellingCorrection();
460 case ContextMenuItemTagChangeBack:
461 frame->editor()->changeBackToReplacedString(m_hitTestResult.replacedString());
464 #if ENABLE(INSPECTOR)
465 case ContextMenuItemTagInspectElement:
466 if (Page* page = frame->page())
467 page->inspectorController()->inspect(m_hitTestResult.innerNonSharedNode());
475 void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* parentMenu)
477 checkOrEnableIfNeeded(menuItem);
479 parentMenu->appendItem(menuItem);
482 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem)
484 ContextMenu fontMenu;
487 ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
489 ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
490 ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
491 ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
492 ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
494 ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
495 ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
499 appendItem(showFonts, &fontMenu);
501 appendItem(bold, &fontMenu);
502 appendItem(italic, &fontMenu);
503 appendItem(underline, &fontMenu);
504 appendItem(outline, &fontMenu);
506 appendItem(styles, &fontMenu);
507 appendItem(*separatorItem(), &fontMenu);
508 appendItem(showColors, &fontMenu);
511 fontMenuItem.setSubMenu(&fontMenu);
517 void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem)
519 ContextMenu spellingAndGrammarMenu;
521 ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel,
522 contextMenuItemTagShowSpellingPanel(true));
523 ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
524 contextMenuItemTagCheckSpelling());
525 ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping,
526 contextMenuItemTagCheckSpellingWhileTyping());
527 ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling,
528 contextMenuItemTagCheckGrammarWithSpelling());
529 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
530 ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically,
531 contextMenuItemTagCorrectSpellingAutomatically());
534 appendItem(showSpellingPanel, &spellingAndGrammarMenu);
535 appendItem(checkSpelling, &spellingAndGrammarMenu);
536 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
537 appendItem(*separatorItem(), &spellingAndGrammarMenu);
539 appendItem(checkAsYouType, &spellingAndGrammarMenu);
540 appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
541 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
542 appendItem(correctSpelling, &spellingAndGrammarMenu);
545 spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
548 #endif // !PLATFORM(GTK)
553 void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem)
555 ContextMenu speechMenu;
557 ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking());
558 ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking());
560 appendItem(start, &speechMenu);
561 appendItem(stop, &speechMenu);
563 speechMenuItem.setSubMenu(&speechMenu);
570 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem)
572 ContextMenu writingDirectionMenu;
574 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection,
575 contextMenuItemTagDefaultDirection());
576 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight());
577 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft());
579 appendItem(defaultItem, &writingDirectionMenu);
580 appendItem(ltr, &writingDirectionMenu);
581 appendItem(rtl, &writingDirectionMenu);
583 writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
586 void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem)
588 ContextMenu textDirectionMenu;
590 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection());
591 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight());
592 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft());
594 appendItem(defaultItem, &textDirectionMenu);
595 appendItem(ltr, &textDirectionMenu);
596 appendItem(rtl, &textDirectionMenu);
598 textDirectionMenuItem.setSubMenu(&textDirectionMenu);
603 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
605 void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem)
607 ContextMenu substitutionsMenu;
609 ContextMenuItem showSubstitutions(ActionType, ContextMenuItemTagShowSubstitutions, contextMenuItemTagShowSubstitutions(true));
610 ContextMenuItem smartCopyPaste(CheckableActionType, ContextMenuItemTagSmartCopyPaste, contextMenuItemTagSmartCopyPaste());
611 ContextMenuItem smartQuotes(CheckableActionType, ContextMenuItemTagSmartQuotes, contextMenuItemTagSmartQuotes());
612 ContextMenuItem smartDashes(CheckableActionType, ContextMenuItemTagSmartDashes, contextMenuItemTagSmartDashes());
613 ContextMenuItem smartLinks(CheckableActionType, ContextMenuItemTagSmartLinks, contextMenuItemTagSmartLinks());
614 ContextMenuItem textReplacement(CheckableActionType, ContextMenuItemTagTextReplacement, contextMenuItemTagTextReplacement());
616 appendItem(showSubstitutions, &substitutionsMenu);
617 appendItem(*separatorItem(), &substitutionsMenu);
618 appendItem(smartCopyPaste, &substitutionsMenu);
619 appendItem(smartQuotes, &substitutionsMenu);
620 appendItem(smartDashes, &substitutionsMenu);
621 appendItem(smartLinks, &substitutionsMenu);
622 appendItem(textReplacement, &substitutionsMenu);
624 substitutionsMenuItem.setSubMenu(&substitutionsMenu);
627 void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuItem& transformationsMenuItem)
629 ContextMenu transformationsMenu;
631 ContextMenuItem makeUpperCase(ActionType, ContextMenuItemTagMakeUpperCase, contextMenuItemTagMakeUpperCase());
632 ContextMenuItem makeLowerCase(ActionType, ContextMenuItemTagMakeLowerCase, contextMenuItemTagMakeLowerCase());
633 ContextMenuItem capitalize(ActionType, ContextMenuItemTagCapitalize, contextMenuItemTagCapitalize());
635 appendItem(makeUpperCase, &transformationsMenu);
636 appendItem(makeLowerCase, &transformationsMenu);
637 appendItem(capitalize, &transformationsMenu);
639 transformationsMenuItem.setSubMenu(&transformationsMenu);
644 static bool selectionContainsPossibleWord(Frame* frame)
646 // Current algorithm: look for a character that's not just a separator.
647 for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atEnd(); it.advance()) {
648 int length = it.length();
649 const UChar* characters = it.characters();
650 for (int i = 0; i < length; ++i)
651 if (!(category(characters[i]) & (Separator_Space | Separator_Line | Separator_Paragraph)))
658 #if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
659 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 1
661 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 0
665 void ContextMenuController::populate()
667 ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink());
668 ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow,
669 contextMenuItemTagOpenLinkInNewWindow());
670 ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk,
671 contextMenuItemTagDownloadLinkToDisk());
672 ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard,
673 contextMenuItemTagCopyLinkToClipboard());
674 ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow,
675 contextMenuItemTagOpenImageInNewWindow());
676 ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk,
677 contextMenuItemTagDownloadImageToDisk());
678 ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard,
679 contextMenuItemTagCopyImageToClipboard());
680 #if PLATFORM(QT) || PLATFORM(GTK)
681 ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard,
682 contextMenuItemTagCopyImageUrlToClipboard());
684 ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenMediaInNewWindow, String());
685 ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLinkToClipboard,
687 ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause,
688 contextMenuItemTagMediaPlay());
689 ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute,
690 contextMenuItemTagMediaMute());
691 ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagToggleMediaControls,
692 contextMenuItemTagToggleMediaControls());
693 ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggleMediaLoop,
694 contextMenuItemTagToggleMediaLoop());
695 ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVideoFullscreen,
696 contextMenuItemTagEnterVideoFullscreen());
698 ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight,
699 contextMenuItemTagSearchInSpotlight());
702 ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
704 ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
705 ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
706 ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contextMenuItemTagGoForward());
707 ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop());
708 ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload());
709 ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow,
710 contextMenuItemTagOpenFrameInNewWindow());
711 ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound,
712 contextMenuItemTagNoGuessesFound());
713 ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling,
714 contextMenuItemTagIgnoreSpelling());
715 ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling,
716 contextMenuItemTagLearnSpelling());
717 ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar,
718 contextMenuItemTagIgnoreGrammar());
719 ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
720 ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
722 ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
724 #if PLATFORM(GTK) || PLATFORM(QT)
725 ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
727 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
728 ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
729 ContextMenuItem SelectWordItem(ActionType, ContextMenuItemTagSelectWord, contextMenuItemTagSelectWord());
732 Node* node = m_hitTestResult.innerNonSharedNode();
736 if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()))
739 Frame* frame = node->document()->frame();
743 if (!m_hitTestResult.isContentEditable()) {
744 FrameLoader* loader = frame->loader();
745 KURL linkURL = m_hitTestResult.absoluteLinkURL();
746 if (!linkURL.isEmpty()) {
747 #if ENABLE(TIZEN_DOWNLOAD_LINK_FILTER)
748 if (loader->client()->canHandleRequest(ResourceRequest(linkURL)) &&
749 (linkURL.protocolIs("http") || linkURL.protocolIs("https") || linkURL.protocolIs("ftp") || linkURL.protocolIs("ftps"))) {
751 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
753 appendItem(OpenLinkItem, m_contextMenu.get());
754 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
755 appendItem(DownloadFileItem, m_contextMenu.get());
758 if (m_hitTestResult.isSelected())
759 appendItem(CopyItem, m_contextMenu.get());
761 appendItem(CopyLinkItem, m_contextMenu.get());
764 KURL imageURL = m_hitTestResult.absoluteImageURL();
765 if (!imageURL.isEmpty()) {
766 if (!linkURL.isEmpty())
767 appendItem(*separatorItem(), m_contextMenu.get());
769 appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
770 appendItem(DownloadImageItem, m_contextMenu.get());
771 if (imageURL.isLocalFile() || m_hitTestResult.image())
772 appendItem(CopyImageItem, m_contextMenu.get());
773 #if PLATFORM(QT) || PLATFORM(GTK)
774 appendItem(CopyImageUrlItem, m_contextMenu.get());
778 KURL mediaURL = m_hitTestResult.absoluteMediaURL();
779 if (!mediaURL.isEmpty()) {
780 if (!linkURL.isEmpty() || !imageURL.isEmpty())
781 appendItem(*separatorItem(), m_contextMenu.get());
783 appendItem(MediaPlayPause, m_contextMenu.get());
784 appendItem(MediaMute, m_contextMenu.get());
785 appendItem(ToggleMediaControls, m_contextMenu.get());
786 appendItem(ToggleMediaLoop, m_contextMenu.get());
787 appendItem(EnterVideoFullscreen, m_contextMenu.get());
789 appendItem(*separatorItem(), m_contextMenu.get());
790 appendItem(CopyMediaLinkItem, m_contextMenu.get());
791 appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
794 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
795 if (m_hitTestResult.isSelected()) {
796 if (selectionContainsPossibleWord(frame)) {
798 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
799 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
801 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
802 appendItem(SearchSpotlightItem, m_contextMenu.get());
804 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
809 appendItem(SearchWebItem, m_contextMenu.get());
810 appendItem(*separatorItem(), m_contextMenu.get());
813 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
814 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
815 appendItem(*separatorItem(), m_contextMenu.get());
819 appendItem(CopyItem, m_contextMenu.get());
821 appendItem(*separatorItem(), m_contextMenu.get());
823 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
824 createAndAppendSpeechSubMenu(SpeechMenuItem);
825 appendItem(SpeechMenuItem, m_contextMenu.get());
828 #if ENABLE(INSPECTOR)
829 if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) {
832 // In GTK+ unavailable items are not hidden but insensitive
834 appendItem(BackItem, m_contextMenu.get());
835 appendItem(ForwardItem, m_contextMenu.get());
836 appendItem(StopItem, m_contextMenu.get());
837 appendItem(ReloadItem, m_contextMenu.get());
839 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1))
840 appendItem(BackItem, m_contextMenu.get());
842 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1))
843 appendItem(ForwardItem, m_contextMenu.get());
845 // use isLoadingInAPISense rather than isLoading because Stop/Reload are
846 // intended to match WebKit's API, not WebCore's internal notion of loading status
847 if (loader->documentLoader()->isLoadingInAPISense())
848 appendItem(StopItem, m_contextMenu.get());
850 appendItem(ReloadItem, m_contextMenu.get());
852 #if ENABLE(INSPECTOR)
856 if (frame->page() && frame != frame->page()->mainFrame())
857 appendItem(OpenFrameItem, m_contextMenu.get());
860 } else { // Make an editing context menu
861 FrameSelection* selection = frame->selection();
862 bool inPasswordField = selection->isInPasswordField();
863 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node);
865 if (!inPasswordField && spellCheckingEnabled) {
866 // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
867 // is never considered a misspelling and bad grammar at the same time)
870 Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar);
871 if (misspelling || badGrammar) {
872 size_t size = guesses.size();
874 // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
875 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
877 appendItem(NoGuessesItem, m_contextMenu.get());
878 appendItem(*separatorItem(), m_contextMenu.get());
881 for (unsigned i = 0; i < size; i++) {
882 const String &guess = guesses[i];
883 if (!guess.isEmpty()) {
884 ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
885 appendItem(item, m_contextMenu.get());
888 appendItem(*separatorItem(), m_contextMenu.get());
892 appendItem(IgnoreSpellingItem, m_contextMenu.get());
893 appendItem(LearnSpellingItem, m_contextMenu.get());
895 appendItem(IgnoreGrammarItem, m_contextMenu.get());
896 appendItem(*separatorItem(), m_contextMenu.get());
897 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
899 // If the string was autocorrected, generate a contextual menu item allowing it to be changed back.
900 String replacedString = m_hitTestResult.replacedString();
901 if (!replacedString.isEmpty()) {
902 ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString));
903 appendItem(item, m_contextMenu.get());
904 appendItem(*separatorItem(), m_contextMenu.get());
910 FrameLoader* loader = frame->loader();
911 KURL linkURL = m_hitTestResult.absoluteLinkURL();
912 if (!linkURL.isEmpty()) {
913 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
914 appendItem(OpenLinkItem, m_contextMenu.get());
915 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
916 appendItem(DownloadFileItem, m_contextMenu.get());
918 appendItem(CopyLinkItem, m_contextMenu.get());
919 appendItem(*separatorItem(), m_contextMenu.get());
922 if (m_hitTestResult.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
924 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
925 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
927 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
928 appendItem(SearchSpotlightItem, m_contextMenu.get());
930 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
935 appendItem(SearchWebItem, m_contextMenu.get());
936 appendItem(*separatorItem(), m_contextMenu.get());
939 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
940 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
941 appendItem(*separatorItem(), m_contextMenu.get());
945 appendItem(CutItem, m_contextMenu.get());
946 appendItem(CopyItem, m_contextMenu.get());
947 appendItem(PasteItem, m_contextMenu.get());
949 appendItem(DeleteItem, m_contextMenu.get());
950 appendItem(*separatorItem(), m_contextMenu.get());
952 #if PLATFORM(GTK) || PLATFORM(QT)
953 appendItem(SelectAllItem, m_contextMenu.get());
955 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
956 appendItem(SelectWordItem, m_contextMenu.get());
957 appendItem(SelectAllItem, m_contextMenu.get());
960 if (!inPasswordField) {
962 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
963 appendItem(*separatorItem(), m_contextMenu.get());
964 ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
965 contextMenuItemTagSpellingMenu());
966 createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem);
967 appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
968 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
970 #if PLATFORM(MAC) && !defined(BUILDING_ON_LEOPARD)
971 ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu,
972 contextMenuItemTagSubstitutionsMenu());
973 createAndAppendSubstitutionsSubMenu(substitutionsMenuItem);
974 appendItem(substitutionsMenuItem, m_contextMenu.get());
975 ContextMenuItem transformationsMenuItem(SubmenuType, ContextMenuItemTagTransformationsMenu,
976 contextMenuItemTagTransformationsMenu());
977 createAndAppendTransformationsSubMenu(transformationsMenuItem);
978 appendItem(transformationsMenuItem, m_contextMenu.get());
981 bool shouldShowFontMenu = frame->editor()->canEditRichly();
983 #if ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
984 bool shouldShowFontMenu = false;
986 bool shouldShowFontMenu = true;
987 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
989 if (shouldShowFontMenu) {
990 ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
991 contextMenuItemTagFontMenu());
992 createAndAppendFontSubMenu(FontMenuItem);
993 appendItem(FontMenuItem, m_contextMenu.get());
996 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
997 createAndAppendSpeechSubMenu(SpeechMenuItem);
998 appendItem(SpeechMenuItem, m_contextMenu.get());
1001 ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu,
1002 contextMenuItemTagWritingDirectionMenu());
1003 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1004 createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem);
1005 appendItem(WritingDirectionMenuItem, m_contextMenu.get());
1006 if (Page* page = frame->page()) {
1007 if (Settings* settings = page->settings()) {
1008 bool includeTextDirectionSubmenu = settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
1009 || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection());
1010 if (includeTextDirectionSubmenu) {
1011 ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu,
1012 contextMenuItemTagTextDirectionMenu());
1013 createAndAppendTextDirectionSubMenu(TextDirectionMenuItem);
1014 appendItem(TextDirectionMenuItem, m_contextMenu.get());
1018 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1024 #if ENABLE(INSPECTOR)
1025 void ContextMenuController::addInspectElementItem()
1027 Node* node = m_hitTestResult.innerNonSharedNode();
1031 Frame* frame = node->document()->frame();
1035 Page* page = frame->page();
1039 if (!page->inspectorController())
1042 ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
1043 appendItem(*separatorItem(), m_contextMenu.get());
1044 appendItem(InspectElementItem, m_contextMenu.get());
1046 #endif // ENABLE(INSPECTOR)
1048 void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
1050 if (item.type() == SeparatorType)
1053 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
1057 // Custom items already have proper checked and enabled values.
1058 if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag)
1061 bool shouldEnable = true;
1062 bool shouldCheck = false;
1064 switch (item.action()) {
1065 case ContextMenuItemTagCheckSpelling:
1066 shouldEnable = frame->editor()->canEdit();
1068 case ContextMenuItemTagDefaultDirection:
1069 shouldCheck = false;
1070 shouldEnable = false;
1072 case ContextMenuItemTagLeftToRight:
1073 case ContextMenuItemTagRightToLeft: {
1074 String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
1075 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirection, direction) != FalseTriState;
1076 shouldEnable = true;
1079 case ContextMenuItemTagTextDirectionDefault: {
1080 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionNatural");
1081 shouldCheck = command.state() == TrueTriState;
1082 shouldEnable = command.isEnabled();
1085 case ContextMenuItemTagTextDirectionLeftToRight: {
1086 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionLeftToRight");
1087 shouldCheck = command.state() == TrueTriState;
1088 shouldEnable = command.isEnabled();
1091 case ContextMenuItemTagTextDirectionRightToLeft: {
1092 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionRightToLeft");
1093 shouldCheck = command.state() == TrueTriState;
1094 shouldEnable = command.isEnabled();
1097 case ContextMenuItemTagCopy:
1098 shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
1100 case ContextMenuItemTagCut:
1101 shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
1103 case ContextMenuItemTagIgnoreSpelling:
1104 case ContextMenuItemTagLearnSpelling:
1105 shouldEnable = frame->selection()->isRange();
1107 case ContextMenuItemTagPaste:
1108 shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
1110 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
1111 case ContextMenuItemTagSelectAll:
1112 case ContextMenuItemTagSelectWord:
1113 shouldEnable = frame->editor()->canSelectRange();
1117 case ContextMenuItemTagDelete:
1118 shouldEnable = frame->editor()->canDelete();
1120 case ContextMenuItemTagSelectAll:
1121 case ContextMenuItemTagInputMethods:
1122 case ContextMenuItemTagUnicode:
1123 shouldEnable = true;
1126 case ContextMenuItemTagUnderline: {
1127 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") != FalseTriState;
1128 shouldEnable = frame->editor()->canEditRichly();
1131 case ContextMenuItemTagLookUpInDictionary:
1132 shouldEnable = frame->selection()->isRange();
1134 case ContextMenuItemTagCheckGrammarWithSpelling:
1135 if (frame->editor()->isGrammarCheckingEnabled())
1137 shouldEnable = true;
1139 case ContextMenuItemTagItalic: {
1140 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic") != FalseTriState;
1141 shouldEnable = frame->editor()->canEditRichly();
1144 case ContextMenuItemTagBold: {
1145 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold") != FalseTriState;
1146 shouldEnable = frame->editor()->canEditRichly();
1149 case ContextMenuItemTagOutline:
1150 shouldEnable = false;
1152 case ContextMenuItemTagShowSpellingPanel:
1153 if (frame->editor()->spellingPanelIsShowing())
1154 item.setTitle(contextMenuItemTagShowSpellingPanel(false));
1156 item.setTitle(contextMenuItemTagShowSpellingPanel(true));
1157 shouldEnable = frame->editor()->canEdit();
1159 case ContextMenuItemTagNoGuessesFound:
1160 shouldEnable = false;
1162 case ContextMenuItemTagCheckSpellingWhileTyping:
1163 shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
1166 case ContextMenuItemTagSubstitutionsMenu:
1167 case ContextMenuItemTagTransformationsMenu:
1169 case ContextMenuItemTagShowSubstitutions:
1170 #ifndef BUILDING_ON_LEOPARD
1171 if (frame->editor()->substitutionsPanelIsShowing())
1172 item.setTitle(contextMenuItemTagShowSubstitutions(false));
1174 item.setTitle(contextMenuItemTagShowSubstitutions(true));
1175 shouldEnable = frame->editor()->canEdit();
1178 case ContextMenuItemTagMakeUpperCase:
1179 case ContextMenuItemTagMakeLowerCase:
1180 case ContextMenuItemTagCapitalize:
1181 case ContextMenuItemTagChangeBack:
1182 shouldEnable = frame->editor()->canEdit();
1184 case ContextMenuItemTagCorrectSpellingAutomatically:
1185 #ifndef BUILDING_ON_LEOPARD
1186 shouldCheck = frame->editor()->isAutomaticSpellingCorrectionEnabled();
1189 case ContextMenuItemTagSmartCopyPaste:
1190 #ifndef BUILDING_ON_LEOPARD
1191 shouldCheck = frame->editor()->smartInsertDeleteEnabled();
1194 case ContextMenuItemTagSmartQuotes:
1195 #ifndef BUILDING_ON_LEOPARD
1196 shouldCheck = frame->editor()->isAutomaticQuoteSubstitutionEnabled();
1199 case ContextMenuItemTagSmartDashes:
1200 #ifndef BUILDING_ON_LEOPARD
1201 shouldCheck = frame->editor()->isAutomaticDashSubstitutionEnabled();
1204 case ContextMenuItemTagSmartLinks:
1205 #ifndef BUILDING_ON_LEOPARD
1206 shouldCheck = frame->editor()->isAutomaticLinkDetectionEnabled();
1209 case ContextMenuItemTagTextReplacement:
1210 #ifndef BUILDING_ON_LEOPARD
1211 shouldCheck = frame->editor()->isAutomaticTextReplacementEnabled();
1214 case ContextMenuItemTagStopSpeaking:
1215 shouldEnable = client() && client()->isSpeaking();
1217 #else // PLATFORM(MAC) ends here
1218 case ContextMenuItemTagStopSpeaking:
1222 case ContextMenuItemTagGoBack:
1223 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1);
1225 case ContextMenuItemTagGoForward:
1226 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1);
1228 case ContextMenuItemTagStop:
1229 shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
1231 case ContextMenuItemTagReload:
1232 shouldEnable = !frame->loader()->documentLoader()->isLoadingInAPISense();
1234 case ContextMenuItemTagFontMenu:
1235 shouldEnable = frame->editor()->canEditRichly();
1238 case ContextMenuItemTagGoBack:
1239 case ContextMenuItemTagGoForward:
1240 case ContextMenuItemTagStop:
1241 case ContextMenuItemTagReload:
1242 case ContextMenuItemTagFontMenu:
1244 case ContextMenuItemTagNoAction:
1245 case ContextMenuItemTagOpenLinkInNewWindow:
1246 case ContextMenuItemTagDownloadLinkToDisk:
1247 case ContextMenuItemTagCopyLinkToClipboard:
1248 case ContextMenuItemTagOpenImageInNewWindow:
1249 case ContextMenuItemTagDownloadImageToDisk:
1250 case ContextMenuItemTagCopyImageToClipboard:
1251 #if ENABLE(TIZEN_COPY_IMAGE_LOCATION)
1252 case ContextMenuItemTagCopyImageLocationToClipboard:
1254 #if PLATFORM(QT) || PLATFORM(GTK)
1255 case ContextMenuItemTagCopyImageUrlToClipboard:
1258 case ContextMenuItemTagOpenMediaInNewWindow:
1259 if (m_hitTestResult.mediaIsVideo())
1260 item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
1262 item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
1264 case ContextMenuItemTagCopyMediaLinkToClipboard:
1265 if (m_hitTestResult.mediaIsVideo())
1266 item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
1268 item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
1270 case ContextMenuItemTagToggleMediaControls:
1271 shouldCheck = m_hitTestResult.mediaControlsEnabled();
1273 case ContextMenuItemTagToggleMediaLoop:
1274 shouldCheck = m_hitTestResult.mediaLoopEnabled();
1276 case ContextMenuItemTagEnterVideoFullscreen:
1277 shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
1279 case ContextMenuItemTagOpenFrameInNewWindow:
1280 case ContextMenuItemTagSpellingGuess:
1281 case ContextMenuItemTagOther:
1282 case ContextMenuItemTagSearchInSpotlight:
1283 case ContextMenuItemTagSearchWeb:
1284 case ContextMenuItemTagOpenWithDefaultApplication:
1285 case ContextMenuItemPDFActualSize:
1286 case ContextMenuItemPDFZoomIn:
1287 case ContextMenuItemPDFZoomOut:
1288 case ContextMenuItemPDFAutoSize:
1289 case ContextMenuItemPDFSinglePage:
1290 case ContextMenuItemPDFFacingPages:
1291 case ContextMenuItemPDFContinuous:
1292 case ContextMenuItemPDFNextPage:
1293 case ContextMenuItemPDFPreviousPage:
1294 case ContextMenuItemTagOpenLink:
1295 case ContextMenuItemTagIgnoreGrammar:
1296 case ContextMenuItemTagSpellingMenu:
1297 case ContextMenuItemTagShowFonts:
1298 case ContextMenuItemTagStyles:
1299 case ContextMenuItemTagShowColors:
1300 case ContextMenuItemTagSpeechMenu:
1301 case ContextMenuItemTagStartSpeaking:
1302 case ContextMenuItemTagWritingDirectionMenu:
1303 case ContextMenuItemTagTextDirectionMenu:
1304 case ContextMenuItemTagPDFSinglePageScrolling:
1305 case ContextMenuItemTagPDFFacingPagesScrolling:
1306 #if ENABLE(INSPECTOR)
1307 case ContextMenuItemTagInspectElement:
1309 case ContextMenuItemBaseCustomTag:
1310 case ContextMenuItemCustomTagNoAction:
1311 case ContextMenuItemLastCustomTag:
1312 case ContextMenuItemBaseApplicationTag:
1314 case ContextMenuItemTagMediaPlayPause:
1315 if (m_hitTestResult.mediaPlaying())
1316 item.setTitle(contextMenuItemTagMediaPause());
1318 item.setTitle(contextMenuItemTagMediaPlay());
1320 case ContextMenuItemTagMediaMute:
1321 shouldEnable = m_hitTestResult.mediaHasAudio();
1322 shouldCheck = shouldEnable && m_hitTestResult.mediaMuted();
1326 item.setChecked(shouldCheck);
1327 item.setEnabled(shouldEnable);
1330 } // namespace WebCore
1332 #endif // ENABLE(CONTEXT_MENUS)