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 "PlatformEvent.h"
62 #include "RenderObject.h"
63 #include "ReplaceSelectionCommand.h"
64 #include "ResourceRequest.h"
66 #include "TextIterator.h"
67 #include "TypingCommand.h"
68 #include "UserTypingGestureIndicator.h"
69 #include "WindowFeatures.h"
71 #include <wtf/unicode/Unicode.h>
72 #if ENABLE(TIZEN_DRAG_SUPPORT)
73 #include "DragController.h"
77 #include <wtf/gobject/GOwnPtr.h>
80 #if ENABLE(TIZEN_PASTEBOARD)
81 #include "Pasteboard.h"
85 using namespace Unicode;
89 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* client)
93 ASSERT_ARG(page, page);
94 ASSERT_ARG(client, client);
97 ContextMenuController::~ContextMenuController()
99 m_client->contextMenuDestroyed();
102 PassOwnPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
104 return adoptPtr(new ContextMenuController(page, client));
107 void ContextMenuController::clearContextMenu()
109 m_contextMenu.clear();
111 m_menuProvider->contextMenuCleared();
115 void ContextMenuController::handleContextMenuEvent(Event* event)
117 m_contextMenu = createContextMenu(event);
123 showContextMenu(event);
126 static PassOwnPtr<ContextMenuItem> separatorItem()
128 return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
131 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
133 m_menuProvider = menuProvider;
135 m_contextMenu = createContextMenu(event);
136 if (!m_contextMenu) {
141 m_menuProvider->populateContextMenu(m_contextMenu.get());
142 if (m_hitTestResult.isSelected()) {
143 appendItem(*separatorItem(), m_contextMenu.get());
146 showContextMenu(event);
149 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
151 if (!event->isMouseEvent())
154 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
155 HitTestResult result(mouseEvent->absoluteLocation());
157 if (Frame* frame = event->target()->toNode()->document()->frame())
158 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
160 if (!result.innerNonSharedNode())
163 m_hitTestResult = result;
165 return adoptPtr(new ContextMenu);
168 void ContextMenuController::showContextMenu(Event* event)
170 #if ENABLE(INSPECTOR)
171 if (m_page->inspectorController()->enabled())
172 addInspectElementItem();
175 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
176 m_contextMenu = m_client->customizeMenu(m_contextMenu.release());
178 PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
179 m_contextMenu->setPlatformDescription(customMenu);
181 event->setDefaultHandled();
184 static void openNewWindow(const KURL& urlToLoad, Frame* frame)
186 if (Page* oldPage = frame->page()) {
187 FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader()->outgoingReferrer()));
188 if (Page* newPage = oldPage->chrome()->createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()))) {
189 newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
190 newPage->chrome()->show();
196 static void insertUnicodeCharacter(UChar character, Frame* frame)
198 String text(&character, 1);
199 if (!frame->editor()->shouldInsertText(text, frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
202 TypingCommand::insertText(frame->document(), text, 0, TypingCommand::TextCompositionNone);
206 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
208 ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
210 if (item->action() >= ContextMenuItemBaseApplicationTag) {
211 m_client->contextMenuItemSelected(item, m_contextMenu.get());
215 if (item->action() >= ContextMenuItemBaseCustomTag) {
216 ASSERT(m_menuProvider);
217 m_menuProvider->contextMenuItemSelected(item);
221 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
225 #if ENABLE(TIZEN_PASTEBOARD)
226 if (Page* page = frame->page()) {
227 if (item->action() == ContextMenuItemTagCopyLinkToClipboard
228 || item->action() == ContextMenuItemTagCopyImageToClipboard
229 || item->action() == ContextMenuItemTagCopyImageUrlToClipboard
230 || item->action() == ContextMenuItemTagCopyMediaLinkToClipboard
231 || item->action() == ContextMenuItemTagCopy
232 || item->action() == ContextMenuItemTagCut)
233 Pasteboard::generalPasteboard()->setPage(page);
237 switch (item->action()) {
238 case ContextMenuItemTagOpenLinkInNewWindow:
239 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
241 case ContextMenuItemTagDownloadLinkToDisk:
242 // FIXME: Some day we should be able to do this from within WebCore.
243 m_client->downloadURL(m_hitTestResult.absoluteLinkURL());
245 case ContextMenuItemTagCopyLinkToClipboard:
246 frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestResult.textContent());
248 case ContextMenuItemTagOpenImageInNewWindow:
249 openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
251 case ContextMenuItemTagDownloadImageToDisk:
252 // FIXME: Some day we should be able to do this from within WebCore.
253 m_client->downloadURL(m_hitTestResult.absoluteImageURL());
255 case ContextMenuItemTagCopyImageToClipboard:
256 // FIXME: The Pasteboard class is not written yet
257 // For now, call into the client. This is temporary!
258 frame->editor()->copyImage(m_hitTestResult);
260 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
261 case ContextMenuItemTagCopyImageUrlToClipboard:
262 frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
265 case ContextMenuItemTagOpenMediaInNewWindow:
266 openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
268 case ContextMenuItemTagCopyMediaLinkToClipboard:
269 frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestResult.textContent());
271 case ContextMenuItemTagToggleMediaControls:
272 m_hitTestResult.toggleMediaControlsDisplay();
274 case ContextMenuItemTagToggleMediaLoop:
275 m_hitTestResult.toggleMediaLoopPlayback();
277 case ContextMenuItemTagEnterVideoFullscreen:
278 m_hitTestResult.enterFullscreenForVideo();
280 case ContextMenuItemTagMediaPlayPause:
281 m_hitTestResult.toggleMediaPlayState();
283 case ContextMenuItemTagMediaMute:
284 m_hitTestResult.toggleMediaMuteState();
286 case ContextMenuItemTagOpenFrameInNewWindow: {
287 DocumentLoader* loader = frame->loader()->documentLoader();
288 if (!loader->unreachableURL().isEmpty())
289 openNewWindow(loader->unreachableURL(), frame);
291 openNewWindow(loader->url(), frame);
294 case ContextMenuItemTagCopy: {
295 frame->editor()->copy();
298 case ContextMenuItemTagGoBack:
299 if (Page* page = frame->page())
300 page->backForward()->goBackOrForward(-1);
302 case ContextMenuItemTagGoForward:
303 if (Page* page = frame->page())
304 page->backForward()->goBackOrForward(1);
306 case ContextMenuItemTagStop:
307 frame->loader()->stop();
309 case ContextMenuItemTagReload:
310 frame->loader()->reload();
312 case ContextMenuItemTagCut:
313 frame->editor()->command("Cut").execute();
315 case ContextMenuItemTagPaste:
316 frame->editor()->command("Paste").execute();
319 case ContextMenuItemTagDelete:
320 frame->editor()->performDelete();
322 case ContextMenuItemTagUnicodeInsertLRMMark:
323 insertUnicodeCharacter(leftToRightMark, frame);
325 case ContextMenuItemTagUnicodeInsertRLMMark:
326 insertUnicodeCharacter(rightToLeftMark, frame);
328 case ContextMenuItemTagUnicodeInsertLREMark:
329 insertUnicodeCharacter(leftToRightEmbed, frame);
331 case ContextMenuItemTagUnicodeInsertRLEMark:
332 insertUnicodeCharacter(rightToLeftEmbed, frame);
334 case ContextMenuItemTagUnicodeInsertLROMark:
335 insertUnicodeCharacter(leftToRightOverride, frame);
337 case ContextMenuItemTagUnicodeInsertRLOMark:
338 insertUnicodeCharacter(rightToLeftOverride, frame);
340 case ContextMenuItemTagUnicodeInsertPDFMark:
341 insertUnicodeCharacter(popDirectionalFormatting, frame);
343 case ContextMenuItemTagUnicodeInsertZWSMark:
344 insertUnicodeCharacter(zeroWidthSpace, frame);
346 case ContextMenuItemTagUnicodeInsertZWJMark:
347 insertUnicodeCharacter(zeroWidthJoiner, frame);
349 case ContextMenuItemTagUnicodeInsertZWNJMark:
350 insertUnicodeCharacter(zeroWidthNonJoiner, frame);
353 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
354 case ContextMenuItemTagSelectAll:
355 frame->editor()->command("SelectAll").execute();
358 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
359 case ContextMenuItemTagSelectWord:
360 frame->editor()->command("SelectWord").execute();
363 case ContextMenuItemTagSpellingGuess:
364 ASSERT(frame->editor()->selectedText().length());
365 if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) {
366 Document* document = frame->document();
367 RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting);
368 applyCommand(command);
369 frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
372 case ContextMenuItemTagIgnoreSpelling:
373 frame->editor()->ignoreSpelling();
375 case ContextMenuItemTagLearnSpelling:
376 frame->editor()->learnSpelling();
378 case ContextMenuItemTagSearchWeb:
379 m_client->searchWithGoogle(frame);
381 case ContextMenuItemTagLookUpInDictionary:
382 // FIXME: Some day we may be able to do this from within WebCore.
383 m_client->lookUpInDictionary(frame);
385 case ContextMenuItemTagOpenLink:
386 if (Frame* targetFrame = m_hitTestResult.targetFrame())
387 targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
389 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
391 case ContextMenuItemTagBold:
392 frame->editor()->command("ToggleBold").execute();
394 case ContextMenuItemTagItalic:
395 frame->editor()->command("ToggleItalic").execute();
397 case ContextMenuItemTagUnderline:
398 frame->editor()->toggleUnderline();
400 case ContextMenuItemTagOutline:
401 // We actually never enable this because CSS does not have a way to specify an outline font,
402 // which may make this difficult to implement. Maybe a special case of text-shadow?
404 case ContextMenuItemTagStartSpeaking: {
406 RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
407 if (!selectedRange || selectedRange->collapsed(ec)) {
408 Document* document = m_hitTestResult.innerNonSharedNode()->document();
409 selectedRange = document->createRange();
410 selectedRange->selectNode(document->documentElement(), ec);
412 m_client->speak(plainText(selectedRange.get()));
415 case ContextMenuItemTagStopSpeaking:
416 m_client->stopSpeaking();
418 case ContextMenuItemTagDefaultDirection:
419 frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
421 case ContextMenuItemTagLeftToRight:
422 frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
424 case ContextMenuItemTagRightToLeft:
425 frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
427 case ContextMenuItemTagTextDirectionDefault:
428 frame->editor()->command("MakeTextWritingDirectionNatural").execute();
430 case ContextMenuItemTagTextDirectionLeftToRight:
431 frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute();
433 case ContextMenuItemTagTextDirectionRightToLeft:
434 frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute();
437 case ContextMenuItemTagSearchInSpotlight:
438 m_client->searchWithSpotlight();
441 case ContextMenuItemTagShowSpellingPanel:
442 frame->editor()->showSpellingGuessPanel();
444 case ContextMenuItemTagCheckSpelling:
445 frame->editor()->advanceToNextMisspelling();
447 case ContextMenuItemTagCheckSpellingWhileTyping:
448 frame->editor()->toggleContinuousSpellChecking();
450 case ContextMenuItemTagCheckGrammarWithSpelling:
451 frame->editor()->toggleGrammarChecking();
454 case ContextMenuItemTagShowFonts:
455 frame->editor()->showFontPanel();
457 case ContextMenuItemTagStyles:
458 frame->editor()->showStylesPanel();
460 case ContextMenuItemTagShowColors:
461 frame->editor()->showColorPanel();
465 case ContextMenuItemTagMakeUpperCase:
466 frame->editor()->uppercaseWord();
468 case ContextMenuItemTagMakeLowerCase:
469 frame->editor()->lowercaseWord();
471 case ContextMenuItemTagCapitalize:
472 frame->editor()->capitalizeWord();
476 case ContextMenuItemTagChangeBack:
477 frame->editor()->changeBackToReplacedString(m_hitTestResult.replacedString());
480 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
481 case ContextMenuItemTagShowSubstitutions:
482 frame->editor()->showSubstitutionsPanel();
484 case ContextMenuItemTagSmartCopyPaste:
485 frame->editor()->toggleSmartInsertDelete();
487 case ContextMenuItemTagSmartQuotes:
488 frame->editor()->toggleAutomaticQuoteSubstitution();
490 case ContextMenuItemTagSmartDashes:
491 frame->editor()->toggleAutomaticDashSubstitution();
493 case ContextMenuItemTagSmartLinks:
494 frame->editor()->toggleAutomaticLinkDetection();
496 case ContextMenuItemTagTextReplacement:
497 frame->editor()->toggleAutomaticTextReplacement();
499 case ContextMenuItemTagCorrectSpellingAutomatically:
500 frame->editor()->toggleAutomaticSpellingCorrection();
503 #if ENABLE(INSPECTOR)
504 case ContextMenuItemTagInspectElement:
505 if (Page* page = frame->page())
506 page->inspectorController()->inspect(m_hitTestResult.innerNonSharedNode());
509 case ContextMenuItemTagDictationAlternative:
510 frame->editor()->applyDictationAlternativelternative(item->title());
512 #if ENABLE(TIZEN_DRAG_SUPPORT)
513 case ContextMenuItemTagDrag:
514 TIZEN_LOGI("ContextMenuItemTagDrag");
515 if (Page* page = frame->page()) {
516 page->dragController()->setDragState(true);
517 frame->eventHandler()->handleMousePressEvent(page->dragController()->dragPositionEvent());
518 page->dragController()->setDragState(false);
527 void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* parentMenu)
529 checkOrEnableIfNeeded(menuItem);
531 parentMenu->appendItem(menuItem);
534 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem)
536 ContextMenu fontMenu;
539 ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
541 ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
542 ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
543 ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
544 ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
546 ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
547 ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
551 appendItem(showFonts, &fontMenu);
553 appendItem(bold, &fontMenu);
554 appendItem(italic, &fontMenu);
555 appendItem(underline, &fontMenu);
556 appendItem(outline, &fontMenu);
558 appendItem(styles, &fontMenu);
559 appendItem(*separatorItem(), &fontMenu);
560 appendItem(showColors, &fontMenu);
563 fontMenuItem.setSubMenu(&fontMenu);
569 void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem)
571 ContextMenu spellingAndGrammarMenu;
573 ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel,
574 contextMenuItemTagShowSpellingPanel(true));
575 ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
576 contextMenuItemTagCheckSpelling());
577 ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping,
578 contextMenuItemTagCheckSpellingWhileTyping());
579 ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling,
580 contextMenuItemTagCheckGrammarWithSpelling());
582 ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically,
583 contextMenuItemTagCorrectSpellingAutomatically());
586 appendItem(showSpellingPanel, &spellingAndGrammarMenu);
587 appendItem(checkSpelling, &spellingAndGrammarMenu);
589 appendItem(*separatorItem(), &spellingAndGrammarMenu);
591 appendItem(checkAsYouType, &spellingAndGrammarMenu);
592 appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
594 appendItem(correctSpelling, &spellingAndGrammarMenu);
597 spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
600 #endif // !PLATFORM(GTK)
605 void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem)
607 ContextMenu speechMenu;
609 ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking());
610 ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking());
612 appendItem(start, &speechMenu);
613 appendItem(stop, &speechMenu);
615 speechMenuItem.setSubMenu(&speechMenu);
622 void ContextMenuController::createAndAppendUnicodeSubMenu(ContextMenuItem& unicodeMenuItem)
624 ContextMenu unicodeMenu;
626 ContextMenuItem leftToRightMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLRMMark, contextMenuItemTagUnicodeInsertLRMMark());
627 ContextMenuItem rightToLeftMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLMMark, contextMenuItemTagUnicodeInsertRLMMark());
628 ContextMenuItem leftToRightEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLREMark, contextMenuItemTagUnicodeInsertLREMark());
629 ContextMenuItem rightToLeftEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLEMark, contextMenuItemTagUnicodeInsertRLEMark());
630 ContextMenuItem leftToRightOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLROMark, contextMenuItemTagUnicodeInsertLROMark());
631 ContextMenuItem rightToLeftOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLOMark, contextMenuItemTagUnicodeInsertRLOMark());
632 ContextMenuItem popDirectionalFormattingMenuItem(ActionType, ContextMenuItemTagUnicodeInsertPDFMark, contextMenuItemTagUnicodeInsertPDFMark());
633 ContextMenuItem zeroWidthSpaceMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWSMark, contextMenuItemTagUnicodeInsertZWSMark());
634 ContextMenuItem zeroWidthJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWJMark, contextMenuItemTagUnicodeInsertZWJMark());
635 ContextMenuItem zeroWidthNonJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWNJMark, contextMenuItemTagUnicodeInsertZWNJMark());
637 appendItem(leftToRightMarkMenuItem, &unicodeMenu);
638 appendItem(rightToLeftMarkMenuItem, &unicodeMenu);
639 appendItem(leftToRightEmbedMenuItem, &unicodeMenu);
640 appendItem(rightToLeftEmbedMenuItem, &unicodeMenu);
641 appendItem(leftToRightOverrideMenuItem, &unicodeMenu);
642 appendItem(rightToLeftOverrideMenuItem, &unicodeMenu);
643 appendItem(popDirectionalFormattingMenuItem, &unicodeMenu);
644 appendItem(zeroWidthSpaceMenuItem, &unicodeMenu);
645 appendItem(zeroWidthJoinerMenuItem, &unicodeMenu);
646 appendItem(zeroWidthNonJoinerMenuItem, &unicodeMenu);
648 unicodeMenuItem.setSubMenu(&unicodeMenu);
653 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem)
655 ContextMenu writingDirectionMenu;
657 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection,
658 contextMenuItemTagDefaultDirection());
659 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight());
660 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft());
662 appendItem(defaultItem, &writingDirectionMenu);
663 appendItem(ltr, &writingDirectionMenu);
664 appendItem(rtl, &writingDirectionMenu);
666 writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
669 void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem)
671 ContextMenu textDirectionMenu;
673 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection());
674 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight());
675 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft());
677 appendItem(defaultItem, &textDirectionMenu);
678 appendItem(ltr, &textDirectionMenu);
679 appendItem(rtl, &textDirectionMenu);
681 textDirectionMenuItem.setSubMenu(&textDirectionMenu);
688 void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem)
690 ContextMenu substitutionsMenu;
692 ContextMenuItem showSubstitutions(ActionType, ContextMenuItemTagShowSubstitutions, contextMenuItemTagShowSubstitutions(true));
693 ContextMenuItem smartCopyPaste(CheckableActionType, ContextMenuItemTagSmartCopyPaste, contextMenuItemTagSmartCopyPaste());
694 ContextMenuItem smartQuotes(CheckableActionType, ContextMenuItemTagSmartQuotes, contextMenuItemTagSmartQuotes());
695 ContextMenuItem smartDashes(CheckableActionType, ContextMenuItemTagSmartDashes, contextMenuItemTagSmartDashes());
696 ContextMenuItem smartLinks(CheckableActionType, ContextMenuItemTagSmartLinks, contextMenuItemTagSmartLinks());
697 ContextMenuItem textReplacement(CheckableActionType, ContextMenuItemTagTextReplacement, contextMenuItemTagTextReplacement());
699 appendItem(showSubstitutions, &substitutionsMenu);
700 appendItem(*separatorItem(), &substitutionsMenu);
701 appendItem(smartCopyPaste, &substitutionsMenu);
702 appendItem(smartQuotes, &substitutionsMenu);
703 appendItem(smartDashes, &substitutionsMenu);
704 appendItem(smartLinks, &substitutionsMenu);
705 appendItem(textReplacement, &substitutionsMenu);
707 substitutionsMenuItem.setSubMenu(&substitutionsMenu);
710 void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuItem& transformationsMenuItem)
712 ContextMenu transformationsMenu;
714 ContextMenuItem makeUpperCase(ActionType, ContextMenuItemTagMakeUpperCase, contextMenuItemTagMakeUpperCase());
715 ContextMenuItem makeLowerCase(ActionType, ContextMenuItemTagMakeLowerCase, contextMenuItemTagMakeLowerCase());
716 ContextMenuItem capitalize(ActionType, ContextMenuItemTagCapitalize, contextMenuItemTagCapitalize());
718 appendItem(makeUpperCase, &transformationsMenu);
719 appendItem(makeLowerCase, &transformationsMenu);
720 appendItem(capitalize, &transformationsMenu);
722 transformationsMenuItem.setSubMenu(&transformationsMenu);
727 static bool selectionContainsPossibleWord(Frame* frame)
729 // Current algorithm: look for a character that's not just a separator.
730 for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atEnd(); it.advance()) {
731 int length = it.length();
732 const UChar* characters = it.characters();
733 for (int i = 0; i < length; ++i)
734 if (!(category(characters[i]) & (Separator_Space | Separator_Line | Separator_Paragraph)))
741 #if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
742 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 1
744 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 0
748 void ContextMenuController::populate()
750 ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink());
751 ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow,
752 contextMenuItemTagOpenLinkInNewWindow());
753 ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk,
754 contextMenuItemTagDownloadLinkToDisk());
755 ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard,
756 contextMenuItemTagCopyLinkToClipboard());
757 ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow,
758 contextMenuItemTagOpenImageInNewWindow());
759 ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk,
760 contextMenuItemTagDownloadImageToDisk());
761 ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard,
762 contextMenuItemTagCopyImageToClipboard());
763 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
764 ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard,
765 contextMenuItemTagCopyImageUrlToClipboard());
767 ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenMediaInNewWindow, String());
768 ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLinkToClipboard,
770 ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause,
771 contextMenuItemTagMediaPlay());
772 ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute,
773 contextMenuItemTagMediaMute());
774 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
775 ContextMenuItem MediaUnMute(ActionType, ContextMenuItemTagMediaMute,
776 contextMenuItemTagMediaUnMute());
778 ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagToggleMediaControls,
779 contextMenuItemTagToggleMediaControls());
780 ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggleMediaLoop,
781 contextMenuItemTagToggleMediaLoop());
782 ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVideoFullscreen,
783 contextMenuItemTagEnterVideoFullscreen());
785 ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight,
786 contextMenuItemTagSearchInSpotlight());
789 ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
791 ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
792 ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
793 ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contextMenuItemTagGoForward());
794 ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop());
795 ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload());
796 ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow,
797 contextMenuItemTagOpenFrameInNewWindow());
798 ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound,
799 contextMenuItemTagNoGuessesFound());
800 ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling,
801 contextMenuItemTagIgnoreSpelling());
802 ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling,
803 contextMenuItemTagLearnSpelling());
804 ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar,
805 contextMenuItemTagIgnoreGrammar());
806 ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
807 ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
808 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
809 ContextMenuItem ClipboardItem(ActionType, ContextMenuItemTagClipboard, contextMenuItemTagClipboard());
812 ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
814 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
815 ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
817 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
818 ContextMenuItem SelectWordItem(ActionType, ContextMenuItemTagSelectWord, contextMenuItemTagSelectWord());
820 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_TEXT_SELECTION_MODE)
821 ContextMenuItem TextSelectionModeItem(ActionType, ContextMenuItemTagTextSelectionMode, contextMenuItemTagTextSelectionMode());
823 #if ENABLE(TIZEN_DRAG_SUPPORT)
824 ContextMenuItem DragItem(ActionType, ContextMenuItemTagDrag, contextMenuItemTagDrag());
827 Node* node = m_hitTestResult.innerNonSharedNode();
831 if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()))
834 Frame* frame = node->document()->frame();
838 if (!m_hitTestResult.isContentEditable()) {
839 FrameLoader* loader = frame->loader();
840 KURL linkURL = m_hitTestResult.absoluteLinkURL();
841 if (!linkURL.isEmpty()) {
842 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
843 if (m_hitTestResult.isSelected()) {
844 if (selectionContainsPossibleWord(frame)) {
845 appendItem(SearchWebItem, m_contextMenu.get());
847 appendItem(CopyItem, m_contextMenu.get());
851 #if ENABLE(TIZEN_DOWNLOAD_LINK_FILTER)
852 if (loader->client()->canHandleRequest(ResourceRequest(linkURL)) &&
853 (linkURL.protocolIs("http") || linkURL.protocolIs("https") || linkURL.protocolIs("ftp") || linkURL.protocolIs("ftps"))) {
855 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
857 appendItem(OpenLinkItem, m_contextMenu.get());
858 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
859 appendItem(DownloadFileItem, m_contextMenu.get());
862 if (m_hitTestResult.isSelected())
863 appendItem(CopyItem, m_contextMenu.get());
865 appendItem(CopyLinkItem, m_contextMenu.get());
868 KURL imageURL = m_hitTestResult.absoluteImageURL();
869 if (!imageURL.isEmpty()) {
870 if (!linkURL.isEmpty())
871 appendItem(*separatorItem(), m_contextMenu.get());
873 appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
874 appendItem(DownloadImageItem, m_contextMenu.get());
875 if (imageURL.isLocalFile() || m_hitTestResult.image())
876 appendItem(CopyImageItem, m_contextMenu.get());
877 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
878 appendItem(CopyImageUrlItem, m_contextMenu.get());
882 KURL mediaURL = m_hitTestResult.absoluteMediaURL();
883 if (!mediaURL.isEmpty()) {
884 if (!linkURL.isEmpty() || !imageURL.isEmpty())
885 appendItem(*separatorItem(), m_contextMenu.get());
887 appendItem(MediaPlayPause, m_contextMenu.get());
888 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
889 if (m_hitTestResult.mediaMuted())
890 appendItem(MediaUnMute, m_contextMenu.get());
892 appendItem(MediaMute, m_contextMenu.get());
894 appendItem(MediaMute, m_contextMenu.get());
896 appendItem(ToggleMediaControls, m_contextMenu.get());
897 appendItem(ToggleMediaLoop, m_contextMenu.get());
898 appendItem(EnterVideoFullscreen, m_contextMenu.get());
900 appendItem(*separatorItem(), m_contextMenu.get());
901 appendItem(CopyMediaLinkItem, m_contextMenu.get());
902 appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
905 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_TEXT_SELECTION_MODE)
906 if ((!linkURL.isEmpty() || !imageURL.isEmpty()) && mediaURL.isEmpty())
907 appendItem(TextSelectionModeItem, m_contextMenu.get());
910 #if ENABLE(TIZEN_DRAG_SUPPORT)
911 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty() && !m_hitTestResult.isDragSupport()) {
913 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
915 if (m_hitTestResult.isSelected()) {
916 if (selectionContainsPossibleWord(frame)) {
918 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
919 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
921 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
922 appendItem(SearchSpotlightItem, m_contextMenu.get());
924 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
929 appendItem(SearchWebItem, m_contextMenu.get());
930 appendItem(*separatorItem(), m_contextMenu.get());
933 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
934 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
935 appendItem(*separatorItem(), m_contextMenu.get());
939 appendItem(CopyItem, m_contextMenu.get());
941 appendItem(*separatorItem(), m_contextMenu.get());
943 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
944 createAndAppendSpeechSubMenu(SpeechMenuItem);
945 appendItem(SpeechMenuItem, m_contextMenu.get());
948 #if ENABLE(INSPECTOR)
949 if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) {
952 // In GTK+ unavailable items are not hidden but insensitive
954 appendItem(BackItem, m_contextMenu.get());
955 appendItem(ForwardItem, m_contextMenu.get());
956 appendItem(StopItem, m_contextMenu.get());
957 appendItem(ReloadItem, m_contextMenu.get());
959 #if !ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
960 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1))
961 appendItem(BackItem, m_contextMenu.get());
963 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1))
964 appendItem(ForwardItem, m_contextMenu.get());
966 // use isLoadingInAPISense rather than isLoading because Stop/Reload are
967 // intended to match WebKit's API, not WebCore's internal notion of loading status
968 if (loader->documentLoader()->isLoadingInAPISense())
969 appendItem(StopItem, m_contextMenu.get());
971 appendItem(ReloadItem, m_contextMenu.get());
974 #if ENABLE(INSPECTOR)
978 if (frame->page() && frame != frame->page()->mainFrame())
979 appendItem(OpenFrameItem, m_contextMenu.get());
982 #if ENABLE(TIZEN_DRAG_SUPPORT)
983 if (frame->page() && m_hitTestResult.isDragSupport()) {
984 TIZEN_LOGI("appendItem for drag");
985 appendItem(DragItem, m_contextMenu.get());
988 } else { // Make an editing context menu
989 FrameSelection* selection = frame->selection();
990 bool inPasswordField = selection->isInPasswordField();
991 if (!inPasswordField) {
992 bool haveContextMenuItemsForMisspellingOrGrammer = false;
993 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node);
994 if (spellCheckingEnabled) {
995 // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
996 // is never considered a misspelling and bad grammar at the same time)
997 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
998 bool misspelling = false;
999 bool badGrammar = false;
1004 Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar);
1005 if (misspelling || badGrammar) {
1006 size_t size = guesses.size();
1008 // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
1009 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
1011 appendItem(NoGuessesItem, m_contextMenu.get());
1012 appendItem(*separatorItem(), m_contextMenu.get());
1015 for (unsigned i = 0; i < size; i++) {
1016 const String &guess = guesses[i];
1017 if (!guess.isEmpty()) {
1018 ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
1019 appendItem(item, m_contextMenu.get());
1022 appendItem(*separatorItem(), m_contextMenu.get());
1025 appendItem(IgnoreSpellingItem, m_contextMenu.get());
1026 appendItem(LearnSpellingItem, m_contextMenu.get());
1028 appendItem(IgnoreGrammarItem, m_contextMenu.get());
1029 appendItem(*separatorItem(), m_contextMenu.get());
1030 haveContextMenuItemsForMisspellingOrGrammer = true;
1031 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
1033 // If the string was autocorrected, generate a contextual menu item allowing it to be changed back.
1034 String replacedString = m_hitTestResult.replacedString();
1035 if (!replacedString.isEmpty()) {
1036 ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString));
1037 appendItem(item, m_contextMenu.get());
1038 appendItem(*separatorItem(), m_contextMenu.get());
1039 haveContextMenuItemsForMisspellingOrGrammer = true;
1045 if (!haveContextMenuItemsForMisspellingOrGrammer) {
1046 // Spelling and grammar checking is mutually exclusive with dictation alternatives.
1047 Vector<String> dictationAlternatives = m_hitTestResult.dictationAlternatives();
1048 if (!dictationAlternatives.isEmpty()) {
1049 for (size_t i = 0; i < dictationAlternatives.size(); ++i) {
1050 ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, dictationAlternatives[i]);
1051 appendItem(item, m_contextMenu.get());
1053 appendItem(*separatorItem(), m_contextMenu.get());
1058 FrameLoader* loader = frame->loader();
1059 KURL linkURL = m_hitTestResult.absoluteLinkURL();
1060 if (!linkURL.isEmpty()) {
1061 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
1062 appendItem(OpenLinkItem, m_contextMenu.get());
1063 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
1064 appendItem(DownloadFileItem, m_contextMenu.get());
1066 appendItem(CopyLinkItem, m_contextMenu.get());
1067 appendItem(*separatorItem(), m_contextMenu.get());
1070 if (m_hitTestResult.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
1072 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
1073 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
1075 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
1076 appendItem(SearchSpotlightItem, m_contextMenu.get());
1078 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
1083 appendItem(SearchWebItem, m_contextMenu.get());
1084 appendItem(*separatorItem(), m_contextMenu.get());
1087 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
1088 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
1089 appendItem(*separatorItem(), m_contextMenu.get());
1093 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1094 if (m_hitTestResult.isSelected() && !inPasswordField) {
1095 appendItem(CutItem, m_contextMenu.get());
1096 appendItem(CopyItem, m_contextMenu.get());
1099 appendItem(CutItem, m_contextMenu.get());
1100 appendItem(CopyItem, m_contextMenu.get());
1102 appendItem(PasteItem, m_contextMenu.get());
1103 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
1104 appendItem(ClipboardItem, m_contextMenu.get());
1107 appendItem(DeleteItem, m_contextMenu.get());
1108 appendItem(*separatorItem(), m_contextMenu.get());
1110 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1111 if (frame->selection()) {
1112 Node* baseNode = frame->selection()->base().containerNode();
1113 if (baseNode && baseNode->isTextNode() && (!(baseNode->textContent().isEmpty()))) {
1114 if (inPasswordField) {
1115 if (!m_hitTestResult.isSelected())
1116 appendItem(SelectWordItem, m_contextMenu.get());
1119 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
1120 appendItem(SelectAllItem, m_contextMenu.get());
1122 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
1123 appendItem(SelectWordItem, m_contextMenu.get());
1125 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1131 if (!inPasswordField) {
1133 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1134 appendItem(*separatorItem(), m_contextMenu.get());
1135 ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
1136 contextMenuItemTagSpellingMenu());
1137 createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem);
1138 appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
1139 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1142 ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu,
1143 contextMenuItemTagSubstitutionsMenu());
1144 createAndAppendSubstitutionsSubMenu(substitutionsMenuItem);
1145 appendItem(substitutionsMenuItem, m_contextMenu.get());
1146 ContextMenuItem transformationsMenuItem(SubmenuType, ContextMenuItemTagTransformationsMenu,
1147 contextMenuItemTagTransformationsMenu());
1148 createAndAppendTransformationsSubMenu(transformationsMenuItem);
1149 appendItem(transformationsMenuItem, m_contextMenu.get());
1152 bool shouldShowFontMenu = frame->editor()->canEditRichly();
1154 #if ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1155 bool shouldShowFontMenu = false;
1157 bool shouldShowFontMenu = true;
1158 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1160 if (shouldShowFontMenu) {
1161 ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
1162 contextMenuItemTagFontMenu());
1163 createAndAppendFontSubMenu(FontMenuItem);
1164 appendItem(FontMenuItem, m_contextMenu.get());
1167 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
1168 createAndAppendSpeechSubMenu(SpeechMenuItem);
1169 appendItem(SpeechMenuItem, m_contextMenu.get());
1172 EditorClient* client = frame->editor()->client();
1173 if (client && client->shouldShowUnicodeMenu()) {
1174 ContextMenuItem UnicodeMenuItem(SubmenuType, ContextMenuItemTagUnicode, contextMenuItemTagUnicode());
1175 createAndAppendUnicodeSubMenu(UnicodeMenuItem);
1176 appendItem(*separatorItem(), m_contextMenu.get());
1177 appendItem(UnicodeMenuItem, m_contextMenu.get());
1180 ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu,
1181 contextMenuItemTagWritingDirectionMenu());
1182 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1183 createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem);
1184 appendItem(WritingDirectionMenuItem, m_contextMenu.get());
1185 if (Page* page = frame->page()) {
1186 if (Settings* settings = page->settings()) {
1187 bool includeTextDirectionSubmenu = settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
1188 || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection());
1189 if (includeTextDirectionSubmenu) {
1190 ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu,
1191 contextMenuItemTagTextDirectionMenu());
1192 createAndAppendTextDirectionSubMenu(TextDirectionMenuItem);
1193 appendItem(TextDirectionMenuItem, m_contextMenu.get());
1197 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1203 #if ENABLE(INSPECTOR)
1204 void ContextMenuController::addInspectElementItem()
1206 Node* node = m_hitTestResult.innerNonSharedNode();
1210 Frame* frame = node->document()->frame();
1214 Page* page = frame->page();
1218 if (!page->inspectorController())
1221 ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
1222 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
1223 if (!m_contextMenu->items().isEmpty())
1225 if (m_contextMenu->itemCount())
1227 appendItem(*separatorItem(), m_contextMenu.get());
1228 appendItem(InspectElementItem, m_contextMenu.get());
1230 #endif // ENABLE(INSPECTOR)
1232 void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
1234 if (item.type() == SeparatorType)
1237 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
1241 // Custom items already have proper checked and enabled values.
1242 if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag)
1245 bool shouldEnable = true;
1246 bool shouldCheck = false;
1248 switch (item.action()) {
1249 case ContextMenuItemTagCheckSpelling:
1250 shouldEnable = frame->editor()->canEdit();
1252 case ContextMenuItemTagDefaultDirection:
1253 shouldCheck = false;
1254 shouldEnable = false;
1256 case ContextMenuItemTagLeftToRight:
1257 case ContextMenuItemTagRightToLeft: {
1258 String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
1259 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirection, direction) != FalseTriState;
1260 shouldEnable = true;
1263 case ContextMenuItemTagTextDirectionDefault: {
1264 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionNatural");
1265 shouldCheck = command.state() == TrueTriState;
1266 shouldEnable = command.isEnabled();
1269 case ContextMenuItemTagTextDirectionLeftToRight: {
1270 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionLeftToRight");
1271 shouldCheck = command.state() == TrueTriState;
1272 shouldEnable = command.isEnabled();
1275 case ContextMenuItemTagTextDirectionRightToLeft: {
1276 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionRightToLeft");
1277 shouldCheck = command.state() == TrueTriState;
1278 shouldEnable = command.isEnabled();
1281 case ContextMenuItemTagCopy:
1282 shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
1284 case ContextMenuItemTagCut:
1285 shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
1287 case ContextMenuItemTagIgnoreSpelling:
1288 case ContextMenuItemTagLearnSpelling:
1289 shouldEnable = frame->selection()->isRange();
1291 case ContextMenuItemTagPaste:
1292 shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
1294 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
1295 case ContextMenuItemTagSelectWord:
1296 shouldEnable = frame->editor()->canSelectRange();
1300 case ContextMenuItemTagDelete:
1301 shouldEnable = frame->editor()->canDelete();
1303 case ContextMenuItemTagInputMethods:
1304 case ContextMenuItemTagUnicode:
1305 case ContextMenuItemTagUnicodeInsertLRMMark:
1306 case ContextMenuItemTagUnicodeInsertRLMMark:
1307 case ContextMenuItemTagUnicodeInsertLREMark:
1308 case ContextMenuItemTagUnicodeInsertRLEMark:
1309 case ContextMenuItemTagUnicodeInsertLROMark:
1310 case ContextMenuItemTagUnicodeInsertRLOMark:
1311 case ContextMenuItemTagUnicodeInsertPDFMark:
1312 case ContextMenuItemTagUnicodeInsertZWSMark:
1313 case ContextMenuItemTagUnicodeInsertZWJMark:
1314 case ContextMenuItemTagUnicodeInsertZWNJMark:
1315 shouldEnable = true;
1318 #if PLATFORM(GTK) || PLATFORM(EFL)
1319 case ContextMenuItemTagSelectAll:
1320 shouldEnable = true;
1323 case ContextMenuItemTagUnderline: {
1324 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") != FalseTriState;
1325 shouldEnable = frame->editor()->canEditRichly();
1328 case ContextMenuItemTagLookUpInDictionary:
1329 shouldEnable = frame->selection()->isRange();
1331 case ContextMenuItemTagCheckGrammarWithSpelling:
1332 if (frame->editor()->isGrammarCheckingEnabled())
1334 shouldEnable = true;
1336 case ContextMenuItemTagItalic: {
1337 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic") != FalseTriState;
1338 shouldEnable = frame->editor()->canEditRichly();
1341 case ContextMenuItemTagBold: {
1342 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold") != FalseTriState;
1343 shouldEnable = frame->editor()->canEditRichly();
1346 case ContextMenuItemTagOutline:
1347 shouldEnable = false;
1349 case ContextMenuItemTagShowSpellingPanel:
1350 if (frame->editor()->spellingPanelIsShowing())
1351 item.setTitle(contextMenuItemTagShowSpellingPanel(false));
1353 item.setTitle(contextMenuItemTagShowSpellingPanel(true));
1354 shouldEnable = frame->editor()->canEdit();
1356 case ContextMenuItemTagNoGuessesFound:
1357 shouldEnable = false;
1359 case ContextMenuItemTagCheckSpellingWhileTyping:
1360 shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
1363 case ContextMenuItemTagSubstitutionsMenu:
1364 case ContextMenuItemTagTransformationsMenu:
1366 case ContextMenuItemTagShowSubstitutions:
1367 if (frame->editor()->substitutionsPanelIsShowing())
1368 item.setTitle(contextMenuItemTagShowSubstitutions(false));
1370 item.setTitle(contextMenuItemTagShowSubstitutions(true));
1371 shouldEnable = frame->editor()->canEdit();
1373 case ContextMenuItemTagMakeUpperCase:
1374 case ContextMenuItemTagMakeLowerCase:
1375 case ContextMenuItemTagCapitalize:
1376 case ContextMenuItemTagChangeBack:
1377 shouldEnable = frame->editor()->canEdit();
1379 case ContextMenuItemTagCorrectSpellingAutomatically:
1380 shouldCheck = frame->editor()->isAutomaticSpellingCorrectionEnabled();
1382 case ContextMenuItemTagSmartCopyPaste:
1383 shouldCheck = frame->editor()->smartInsertDeleteEnabled();
1385 case ContextMenuItemTagSmartQuotes:
1386 shouldCheck = frame->editor()->isAutomaticQuoteSubstitutionEnabled();
1388 case ContextMenuItemTagSmartDashes:
1389 shouldCheck = frame->editor()->isAutomaticDashSubstitutionEnabled();
1391 case ContextMenuItemTagSmartLinks:
1392 shouldCheck = frame->editor()->isAutomaticLinkDetectionEnabled();
1394 case ContextMenuItemTagTextReplacement:
1395 shouldCheck = frame->editor()->isAutomaticTextReplacementEnabled();
1397 case ContextMenuItemTagStopSpeaking:
1398 shouldEnable = client() && client()->isSpeaking();
1400 #else // PLATFORM(MAC) ends here
1401 case ContextMenuItemTagStopSpeaking:
1405 case ContextMenuItemTagGoBack:
1406 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1);
1408 case ContextMenuItemTagGoForward:
1409 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1);
1411 case ContextMenuItemTagStop:
1412 shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
1414 case ContextMenuItemTagReload:
1415 shouldEnable = !frame->loader()->documentLoader()->isLoadingInAPISense();
1417 case ContextMenuItemTagFontMenu:
1418 shouldEnable = frame->editor()->canEditRichly();
1421 case ContextMenuItemTagGoBack:
1422 case ContextMenuItemTagGoForward:
1423 case ContextMenuItemTagStop:
1424 case ContextMenuItemTagReload:
1425 case ContextMenuItemTagFontMenu:
1427 case ContextMenuItemTagNoAction:
1428 case ContextMenuItemTagOpenLinkInNewWindow:
1429 case ContextMenuItemTagDownloadLinkToDisk:
1430 case ContextMenuItemTagCopyLinkToClipboard:
1431 case ContextMenuItemTagOpenImageInNewWindow:
1432 case ContextMenuItemTagDownloadImageToDisk:
1433 case ContextMenuItemTagCopyImageToClipboard:
1434 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
1435 case ContextMenuItemTagCopyImageUrlToClipboard:
1438 case ContextMenuItemTagOpenMediaInNewWindow:
1439 if (m_hitTestResult.mediaIsVideo())
1440 item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
1442 item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
1444 case ContextMenuItemTagCopyMediaLinkToClipboard:
1445 if (m_hitTestResult.mediaIsVideo())
1446 item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
1448 item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
1450 case ContextMenuItemTagToggleMediaControls:
1451 shouldCheck = m_hitTestResult.mediaControlsEnabled();
1453 case ContextMenuItemTagToggleMediaLoop:
1454 shouldCheck = m_hitTestResult.mediaLoopEnabled();
1456 case ContextMenuItemTagEnterVideoFullscreen:
1457 shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
1459 case ContextMenuItemTagOpenFrameInNewWindow:
1460 case ContextMenuItemTagSpellingGuess:
1461 case ContextMenuItemTagOther:
1462 case ContextMenuItemTagSearchInSpotlight:
1463 case ContextMenuItemTagSearchWeb:
1464 case ContextMenuItemTagOpenWithDefaultApplication:
1465 case ContextMenuItemPDFActualSize:
1466 case ContextMenuItemPDFZoomIn:
1467 case ContextMenuItemPDFZoomOut:
1468 case ContextMenuItemPDFAutoSize:
1469 case ContextMenuItemPDFSinglePage:
1470 case ContextMenuItemPDFFacingPages:
1471 case ContextMenuItemPDFContinuous:
1472 case ContextMenuItemPDFNextPage:
1473 case ContextMenuItemPDFPreviousPage:
1474 case ContextMenuItemTagOpenLink:
1475 case ContextMenuItemTagIgnoreGrammar:
1476 case ContextMenuItemTagSpellingMenu:
1477 case ContextMenuItemTagShowFonts:
1478 case ContextMenuItemTagStyles:
1479 case ContextMenuItemTagShowColors:
1480 case ContextMenuItemTagSpeechMenu:
1481 case ContextMenuItemTagStartSpeaking:
1482 case ContextMenuItemTagWritingDirectionMenu:
1483 case ContextMenuItemTagTextDirectionMenu:
1484 case ContextMenuItemTagPDFSinglePageScrolling:
1485 case ContextMenuItemTagPDFFacingPagesScrolling:
1486 #if ENABLE(INSPECTOR)
1487 case ContextMenuItemTagInspectElement:
1489 #if ENABLE(TIZEN_DRAG_SUPPORT)
1490 case ContextMenuItemTagDrag:
1492 case ContextMenuItemBaseCustomTag:
1493 case ContextMenuItemCustomTagNoAction:
1494 case ContextMenuItemLastCustomTag:
1495 case ContextMenuItemBaseApplicationTag:
1496 case ContextMenuItemTagDictationAlternative:
1498 case ContextMenuItemTagMediaPlayPause:
1499 if (m_hitTestResult.mediaPlaying())
1500 item.setTitle(contextMenuItemTagMediaPause());
1502 item.setTitle(contextMenuItemTagMediaPlay());
1504 case ContextMenuItemTagMediaMute:
1505 shouldEnable = m_hitTestResult.mediaHasAudio();
1506 shouldCheck = shouldEnable && m_hitTestResult.mediaMuted();
1508 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
1514 item.setChecked(shouldCheck);
1515 item.setEnabled(shouldEnable);
1518 #if USE(ACCESSIBILITY_CONTEXT_MENUS)
1519 void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clickPoint)
1521 // Simulate a click in the middle of the accessibility object.
1522 PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
1523 bool handled = frame->eventHandler()->sendContextMenuEvent(mouseEvent);
1524 if (handled && client())
1525 client()->showContextMenu();
1529 } // namespace WebCore
1531 #endif // ENABLE(CONTEXT_MENUS)