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"
84 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
85 #include "HTMLInputElement.h"
89 using namespace Unicode;
93 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* client)
97 ASSERT_ARG(page, page);
98 ASSERT_ARG(client, client);
101 ContextMenuController::~ContextMenuController()
103 m_client->contextMenuDestroyed();
106 PassOwnPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
108 return adoptPtr(new ContextMenuController(page, client));
111 void ContextMenuController::clearContextMenu()
113 m_contextMenu.clear();
115 m_menuProvider->contextMenuCleared();
119 void ContextMenuController::handleContextMenuEvent(Event* event)
121 m_contextMenu = createContextMenu(event);
127 showContextMenu(event);
130 static PassOwnPtr<ContextMenuItem> separatorItem()
132 return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
135 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
137 m_menuProvider = menuProvider;
139 m_contextMenu = createContextMenu(event);
140 if (!m_contextMenu) {
145 m_menuProvider->populateContextMenu(m_contextMenu.get());
146 if (m_hitTestResult.isSelected()) {
147 appendItem(*separatorItem(), m_contextMenu.get());
150 showContextMenu(event);
153 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
155 if (!event->isMouseEvent())
158 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
159 HitTestResult result(mouseEvent->absoluteLocation());
161 if (Frame* frame = event->target()->toNode()->document()->frame())
162 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
164 if (!result.innerNonSharedNode())
167 m_hitTestResult = result;
169 return adoptPtr(new ContextMenu);
172 void ContextMenuController::showContextMenu(Event* event)
174 #if ENABLE(INSPECTOR)
175 if (m_page->inspectorController()->enabled())
176 addInspectElementItem();
179 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
180 m_contextMenu = m_client->customizeMenu(m_contextMenu.release());
182 PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
183 m_contextMenu->setPlatformDescription(customMenu);
185 event->setDefaultHandled();
188 static void openNewWindow(const KURL& urlToLoad, Frame* frame)
190 if (Page* oldPage = frame->page()) {
191 FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader()->outgoingReferrer()));
192 if (Page* newPage = oldPage->chrome()->createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()))) {
193 newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
194 newPage->chrome()->show();
200 static void insertUnicodeCharacter(UChar character, Frame* frame)
202 String text(&character, 1);
203 if (!frame->editor()->shouldInsertText(text, frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
206 TypingCommand::insertText(frame->document(), text, 0, TypingCommand::TextCompositionNone);
210 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
212 ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
214 if (item->action() >= ContextMenuItemBaseApplicationTag) {
215 m_client->contextMenuItemSelected(item, m_contextMenu.get());
219 if (item->action() >= ContextMenuItemBaseCustomTag) {
220 ASSERT(m_menuProvider);
221 m_menuProvider->contextMenuItemSelected(item);
225 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
229 #if ENABLE(TIZEN_PASTEBOARD)
230 if (Page* page = frame->page()) {
231 if (item->action() == ContextMenuItemTagCopyLinkToClipboard
232 || item->action() == ContextMenuItemTagCopyImageToClipboard
233 || item->action() == ContextMenuItemTagCopyImageUrlToClipboard
234 || item->action() == ContextMenuItemTagCopyMediaLinkToClipboard
235 || item->action() == ContextMenuItemTagCopy
236 || item->action() == ContextMenuItemTagCut)
237 Pasteboard::generalPasteboard()->setPage(page);
241 switch (item->action()) {
242 case ContextMenuItemTagOpenLinkInNewWindow:
243 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
245 case ContextMenuItemTagDownloadLinkToDisk:
246 // FIXME: Some day we should be able to do this from within WebCore.
247 m_client->downloadURL(m_hitTestResult.absoluteLinkURL());
249 case ContextMenuItemTagCopyLinkToClipboard:
250 frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestResult.textContent());
252 case ContextMenuItemTagOpenImageInNewWindow:
253 openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
255 case ContextMenuItemTagDownloadImageToDisk:
256 // FIXME: Some day we should be able to do this from within WebCore.
257 m_client->downloadURL(m_hitTestResult.absoluteImageURL());
259 case ContextMenuItemTagCopyImageToClipboard:
260 // FIXME: The Pasteboard class is not written yet
261 // For now, call into the client. This is temporary!
262 frame->editor()->copyImage(m_hitTestResult);
264 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
265 case ContextMenuItemTagCopyImageUrlToClipboard:
266 frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
269 case ContextMenuItemTagOpenMediaInNewWindow:
270 openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
272 case ContextMenuItemTagCopyMediaLinkToClipboard:
273 frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestResult.textContent());
275 case ContextMenuItemTagToggleMediaControls:
276 m_hitTestResult.toggleMediaControlsDisplay();
278 case ContextMenuItemTagToggleMediaLoop:
279 m_hitTestResult.toggleMediaLoopPlayback();
281 case ContextMenuItemTagEnterVideoFullscreen:
282 m_hitTestResult.enterFullscreenForVideo();
284 case ContextMenuItemTagMediaPlayPause:
285 m_hitTestResult.toggleMediaPlayState();
287 case ContextMenuItemTagMediaMute:
288 m_hitTestResult.toggleMediaMuteState();
290 case ContextMenuItemTagOpenFrameInNewWindow: {
291 DocumentLoader* loader = frame->loader()->documentLoader();
292 if (!loader->unreachableURL().isEmpty())
293 openNewWindow(loader->unreachableURL(), frame);
295 openNewWindow(loader->url(), frame);
298 case ContextMenuItemTagCopy: {
299 frame->editor()->copy();
302 case ContextMenuItemTagGoBack:
303 if (Page* page = frame->page())
304 page->backForward()->goBackOrForward(-1);
306 case ContextMenuItemTagGoForward:
307 if (Page* page = frame->page())
308 page->backForward()->goBackOrForward(1);
310 case ContextMenuItemTagStop:
311 frame->loader()->stop();
313 case ContextMenuItemTagReload:
314 frame->loader()->reload();
316 case ContextMenuItemTagCut:
317 frame->editor()->command("Cut").execute();
319 case ContextMenuItemTagPaste:
320 frame->editor()->command("Paste").execute();
323 case ContextMenuItemTagDelete:
324 frame->editor()->performDelete();
326 case ContextMenuItemTagUnicodeInsertLRMMark:
327 insertUnicodeCharacter(leftToRightMark, frame);
329 case ContextMenuItemTagUnicodeInsertRLMMark:
330 insertUnicodeCharacter(rightToLeftMark, frame);
332 case ContextMenuItemTagUnicodeInsertLREMark:
333 insertUnicodeCharacter(leftToRightEmbed, frame);
335 case ContextMenuItemTagUnicodeInsertRLEMark:
336 insertUnicodeCharacter(rightToLeftEmbed, frame);
338 case ContextMenuItemTagUnicodeInsertLROMark:
339 insertUnicodeCharacter(leftToRightOverride, frame);
341 case ContextMenuItemTagUnicodeInsertRLOMark:
342 insertUnicodeCharacter(rightToLeftOverride, frame);
344 case ContextMenuItemTagUnicodeInsertPDFMark:
345 insertUnicodeCharacter(popDirectionalFormatting, frame);
347 case ContextMenuItemTagUnicodeInsertZWSMark:
348 insertUnicodeCharacter(zeroWidthSpace, frame);
350 case ContextMenuItemTagUnicodeInsertZWJMark:
351 insertUnicodeCharacter(zeroWidthJoiner, frame);
353 case ContextMenuItemTagUnicodeInsertZWNJMark:
354 insertUnicodeCharacter(zeroWidthNonJoiner, frame);
357 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
358 case ContextMenuItemTagSelectAll:
359 frame->editor()->command("SelectAll").execute();
362 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
363 case ContextMenuItemTagSelectWord:
364 frame->editor()->command("SelectWord").execute();
367 case ContextMenuItemTagSpellingGuess:
368 ASSERT(frame->editor()->selectedText().length());
369 if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) {
370 Document* document = frame->document();
371 RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting);
372 applyCommand(command);
373 frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
376 case ContextMenuItemTagIgnoreSpelling:
377 frame->editor()->ignoreSpelling();
379 case ContextMenuItemTagLearnSpelling:
380 frame->editor()->learnSpelling();
382 case ContextMenuItemTagSearchWeb:
383 m_client->searchWithGoogle(frame);
385 case ContextMenuItemTagLookUpInDictionary:
386 // FIXME: Some day we may be able to do this from within WebCore.
387 m_client->lookUpInDictionary(frame);
389 case ContextMenuItemTagOpenLink:
390 if (Frame* targetFrame = m_hitTestResult.targetFrame())
391 targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
393 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
395 case ContextMenuItemTagBold:
396 frame->editor()->command("ToggleBold").execute();
398 case ContextMenuItemTagItalic:
399 frame->editor()->command("ToggleItalic").execute();
401 case ContextMenuItemTagUnderline:
402 frame->editor()->toggleUnderline();
404 case ContextMenuItemTagOutline:
405 // We actually never enable this because CSS does not have a way to specify an outline font,
406 // which may make this difficult to implement. Maybe a special case of text-shadow?
408 case ContextMenuItemTagStartSpeaking: {
410 RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
411 if (!selectedRange || selectedRange->collapsed(ec)) {
412 Document* document = m_hitTestResult.innerNonSharedNode()->document();
413 selectedRange = document->createRange();
414 selectedRange->selectNode(document->documentElement(), ec);
416 m_client->speak(plainText(selectedRange.get()));
419 case ContextMenuItemTagStopSpeaking:
420 m_client->stopSpeaking();
422 case ContextMenuItemTagDefaultDirection:
423 frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
425 case ContextMenuItemTagLeftToRight:
426 frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
428 case ContextMenuItemTagRightToLeft:
429 frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
431 case ContextMenuItemTagTextDirectionDefault:
432 frame->editor()->command("MakeTextWritingDirectionNatural").execute();
434 case ContextMenuItemTagTextDirectionLeftToRight:
435 frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute();
437 case ContextMenuItemTagTextDirectionRightToLeft:
438 frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute();
441 case ContextMenuItemTagSearchInSpotlight:
442 m_client->searchWithSpotlight();
445 case ContextMenuItemTagShowSpellingPanel:
446 frame->editor()->showSpellingGuessPanel();
448 case ContextMenuItemTagCheckSpelling:
449 frame->editor()->advanceToNextMisspelling();
451 case ContextMenuItemTagCheckSpellingWhileTyping:
452 frame->editor()->toggleContinuousSpellChecking();
454 case ContextMenuItemTagCheckGrammarWithSpelling:
455 frame->editor()->toggleGrammarChecking();
458 case ContextMenuItemTagShowFonts:
459 frame->editor()->showFontPanel();
461 case ContextMenuItemTagStyles:
462 frame->editor()->showStylesPanel();
464 case ContextMenuItemTagShowColors:
465 frame->editor()->showColorPanel();
469 case ContextMenuItemTagMakeUpperCase:
470 frame->editor()->uppercaseWord();
472 case ContextMenuItemTagMakeLowerCase:
473 frame->editor()->lowercaseWord();
475 case ContextMenuItemTagCapitalize:
476 frame->editor()->capitalizeWord();
480 case ContextMenuItemTagChangeBack:
481 frame->editor()->changeBackToReplacedString(m_hitTestResult.replacedString());
484 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
485 case ContextMenuItemTagShowSubstitutions:
486 frame->editor()->showSubstitutionsPanel();
488 case ContextMenuItemTagSmartCopyPaste:
489 frame->editor()->toggleSmartInsertDelete();
491 case ContextMenuItemTagSmartQuotes:
492 frame->editor()->toggleAutomaticQuoteSubstitution();
494 case ContextMenuItemTagSmartDashes:
495 frame->editor()->toggleAutomaticDashSubstitution();
497 case ContextMenuItemTagSmartLinks:
498 frame->editor()->toggleAutomaticLinkDetection();
500 case ContextMenuItemTagTextReplacement:
501 frame->editor()->toggleAutomaticTextReplacement();
503 case ContextMenuItemTagCorrectSpellingAutomatically:
504 frame->editor()->toggleAutomaticSpellingCorrection();
507 #if ENABLE(INSPECTOR)
508 case ContextMenuItemTagInspectElement:
509 if (Page* page = frame->page())
510 page->inspectorController()->inspect(m_hitTestResult.innerNonSharedNode());
513 case ContextMenuItemTagDictationAlternative:
514 frame->editor()->applyDictationAlternativelternative(item->title());
516 #if ENABLE(TIZEN_DRAG_SUPPORT)
517 case ContextMenuItemTagDrag:
518 TIZEN_LOGI("ContextMenuItemTagDrag");
519 if (Page* page = frame->page()) {
520 page->dragController()->setDragState(true);
521 frame->eventHandler()->handleMousePressEvent(page->dragController()->dragPositionEvent());
522 page->dragController()->setDragState(false);
531 void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* parentMenu)
533 checkOrEnableIfNeeded(menuItem);
535 parentMenu->appendItem(menuItem);
538 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem)
540 ContextMenu fontMenu;
543 ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
545 ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
546 ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
547 ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
548 ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
550 ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
551 ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
555 appendItem(showFonts, &fontMenu);
557 appendItem(bold, &fontMenu);
558 appendItem(italic, &fontMenu);
559 appendItem(underline, &fontMenu);
560 appendItem(outline, &fontMenu);
562 appendItem(styles, &fontMenu);
563 appendItem(*separatorItem(), &fontMenu);
564 appendItem(showColors, &fontMenu);
567 fontMenuItem.setSubMenu(&fontMenu);
573 void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem)
575 ContextMenu spellingAndGrammarMenu;
577 ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel,
578 contextMenuItemTagShowSpellingPanel(true));
579 ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
580 contextMenuItemTagCheckSpelling());
581 ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping,
582 contextMenuItemTagCheckSpellingWhileTyping());
583 ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling,
584 contextMenuItemTagCheckGrammarWithSpelling());
586 ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically,
587 contextMenuItemTagCorrectSpellingAutomatically());
590 appendItem(showSpellingPanel, &spellingAndGrammarMenu);
591 appendItem(checkSpelling, &spellingAndGrammarMenu);
593 appendItem(*separatorItem(), &spellingAndGrammarMenu);
595 appendItem(checkAsYouType, &spellingAndGrammarMenu);
596 appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
598 appendItem(correctSpelling, &spellingAndGrammarMenu);
601 spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
604 #endif // !PLATFORM(GTK)
609 void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem)
611 ContextMenu speechMenu;
613 ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking());
614 ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking());
616 appendItem(start, &speechMenu);
617 appendItem(stop, &speechMenu);
619 speechMenuItem.setSubMenu(&speechMenu);
626 void ContextMenuController::createAndAppendUnicodeSubMenu(ContextMenuItem& unicodeMenuItem)
628 ContextMenu unicodeMenu;
630 ContextMenuItem leftToRightMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLRMMark, contextMenuItemTagUnicodeInsertLRMMark());
631 ContextMenuItem rightToLeftMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLMMark, contextMenuItemTagUnicodeInsertRLMMark());
632 ContextMenuItem leftToRightEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLREMark, contextMenuItemTagUnicodeInsertLREMark());
633 ContextMenuItem rightToLeftEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLEMark, contextMenuItemTagUnicodeInsertRLEMark());
634 ContextMenuItem leftToRightOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLROMark, contextMenuItemTagUnicodeInsertLROMark());
635 ContextMenuItem rightToLeftOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLOMark, contextMenuItemTagUnicodeInsertRLOMark());
636 ContextMenuItem popDirectionalFormattingMenuItem(ActionType, ContextMenuItemTagUnicodeInsertPDFMark, contextMenuItemTagUnicodeInsertPDFMark());
637 ContextMenuItem zeroWidthSpaceMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWSMark, contextMenuItemTagUnicodeInsertZWSMark());
638 ContextMenuItem zeroWidthJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWJMark, contextMenuItemTagUnicodeInsertZWJMark());
639 ContextMenuItem zeroWidthNonJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWNJMark, contextMenuItemTagUnicodeInsertZWNJMark());
641 appendItem(leftToRightMarkMenuItem, &unicodeMenu);
642 appendItem(rightToLeftMarkMenuItem, &unicodeMenu);
643 appendItem(leftToRightEmbedMenuItem, &unicodeMenu);
644 appendItem(rightToLeftEmbedMenuItem, &unicodeMenu);
645 appendItem(leftToRightOverrideMenuItem, &unicodeMenu);
646 appendItem(rightToLeftOverrideMenuItem, &unicodeMenu);
647 appendItem(popDirectionalFormattingMenuItem, &unicodeMenu);
648 appendItem(zeroWidthSpaceMenuItem, &unicodeMenu);
649 appendItem(zeroWidthJoinerMenuItem, &unicodeMenu);
650 appendItem(zeroWidthNonJoinerMenuItem, &unicodeMenu);
652 unicodeMenuItem.setSubMenu(&unicodeMenu);
657 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem)
659 ContextMenu writingDirectionMenu;
661 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection,
662 contextMenuItemTagDefaultDirection());
663 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight());
664 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft());
666 appendItem(defaultItem, &writingDirectionMenu);
667 appendItem(ltr, &writingDirectionMenu);
668 appendItem(rtl, &writingDirectionMenu);
670 writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
673 void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem)
675 ContextMenu textDirectionMenu;
677 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection());
678 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight());
679 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft());
681 appendItem(defaultItem, &textDirectionMenu);
682 appendItem(ltr, &textDirectionMenu);
683 appendItem(rtl, &textDirectionMenu);
685 textDirectionMenuItem.setSubMenu(&textDirectionMenu);
692 void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem)
694 ContextMenu substitutionsMenu;
696 ContextMenuItem showSubstitutions(ActionType, ContextMenuItemTagShowSubstitutions, contextMenuItemTagShowSubstitutions(true));
697 ContextMenuItem smartCopyPaste(CheckableActionType, ContextMenuItemTagSmartCopyPaste, contextMenuItemTagSmartCopyPaste());
698 ContextMenuItem smartQuotes(CheckableActionType, ContextMenuItemTagSmartQuotes, contextMenuItemTagSmartQuotes());
699 ContextMenuItem smartDashes(CheckableActionType, ContextMenuItemTagSmartDashes, contextMenuItemTagSmartDashes());
700 ContextMenuItem smartLinks(CheckableActionType, ContextMenuItemTagSmartLinks, contextMenuItemTagSmartLinks());
701 ContextMenuItem textReplacement(CheckableActionType, ContextMenuItemTagTextReplacement, contextMenuItemTagTextReplacement());
703 appendItem(showSubstitutions, &substitutionsMenu);
704 appendItem(*separatorItem(), &substitutionsMenu);
705 appendItem(smartCopyPaste, &substitutionsMenu);
706 appendItem(smartQuotes, &substitutionsMenu);
707 appendItem(smartDashes, &substitutionsMenu);
708 appendItem(smartLinks, &substitutionsMenu);
709 appendItem(textReplacement, &substitutionsMenu);
711 substitutionsMenuItem.setSubMenu(&substitutionsMenu);
714 void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuItem& transformationsMenuItem)
716 ContextMenu transformationsMenu;
718 ContextMenuItem makeUpperCase(ActionType, ContextMenuItemTagMakeUpperCase, contextMenuItemTagMakeUpperCase());
719 ContextMenuItem makeLowerCase(ActionType, ContextMenuItemTagMakeLowerCase, contextMenuItemTagMakeLowerCase());
720 ContextMenuItem capitalize(ActionType, ContextMenuItemTagCapitalize, contextMenuItemTagCapitalize());
722 appendItem(makeUpperCase, &transformationsMenu);
723 appendItem(makeLowerCase, &transformationsMenu);
724 appendItem(capitalize, &transformationsMenu);
726 transformationsMenuItem.setSubMenu(&transformationsMenu);
731 static bool selectionContainsPossibleWord(Frame* frame)
733 // Current algorithm: look for a character that's not just a separator.
734 for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atEnd(); it.advance()) {
735 int length = it.length();
736 const UChar* characters = it.characters();
737 for (int i = 0; i < length; ++i)
738 if (!(category(characters[i]) & (Separator_Space | Separator_Line | Separator_Paragraph)))
745 #if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
746 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 1
748 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 0
752 void ContextMenuController::populate()
754 ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink());
755 ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow,
756 contextMenuItemTagOpenLinkInNewWindow());
757 ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk,
758 contextMenuItemTagDownloadLinkToDisk());
759 ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard,
760 contextMenuItemTagCopyLinkToClipboard());
761 ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow,
762 contextMenuItemTagOpenImageInNewWindow());
763 ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk,
764 contextMenuItemTagDownloadImageToDisk());
765 ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard,
766 contextMenuItemTagCopyImageToClipboard());
767 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
768 ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard,
769 contextMenuItemTagCopyImageUrlToClipboard());
771 ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenMediaInNewWindow, String());
772 ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLinkToClipboard,
774 ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause,
775 contextMenuItemTagMediaPlay());
776 ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute,
777 contextMenuItemTagMediaMute());
778 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
779 ContextMenuItem MediaUnMute(ActionType, ContextMenuItemTagMediaMute,
780 contextMenuItemTagMediaUnMute());
782 ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagToggleMediaControls,
783 contextMenuItemTagToggleMediaControls());
784 ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggleMediaLoop,
785 contextMenuItemTagToggleMediaLoop());
786 ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVideoFullscreen,
787 contextMenuItemTagEnterVideoFullscreen());
789 ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight,
790 contextMenuItemTagSearchInSpotlight());
793 ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
795 ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
796 ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
797 ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contextMenuItemTagGoForward());
798 ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop());
799 ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload());
800 ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow,
801 contextMenuItemTagOpenFrameInNewWindow());
802 ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound,
803 contextMenuItemTagNoGuessesFound());
804 ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling,
805 contextMenuItemTagIgnoreSpelling());
806 ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling,
807 contextMenuItemTagLearnSpelling());
808 ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar,
809 contextMenuItemTagIgnoreGrammar());
810 ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
811 ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
812 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
813 ContextMenuItem ClipboardItem(ActionType, ContextMenuItemTagClipboard, contextMenuItemTagClipboard());
816 ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
818 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
819 ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
821 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
822 ContextMenuItem SelectWordItem(ActionType, ContextMenuItemTagSelectWord, contextMenuItemTagSelectWord());
824 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_TEXT_SELECTION_MODE)
825 ContextMenuItem TextSelectionModeItem(ActionType, ContextMenuItemTagTextSelectionMode, contextMenuItemTagTextSelectionMode());
827 #if ENABLE(TIZEN_DRAG_SUPPORT)
828 ContextMenuItem DragItem(ActionType, ContextMenuItemTagDrag, contextMenuItemTagDrag());
831 Node* node = m_hitTestResult.innerNonSharedNode();
835 if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()))
838 Frame* frame = node->document()->frame();
842 if (!m_hitTestResult.isContentEditable()) {
843 FrameLoader* loader = frame->loader();
844 KURL linkURL = m_hitTestResult.absoluteLinkURL();
845 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
846 if (m_hitTestResult.isSelected() || frame->selection()->isRange())
847 appendItem(SelectAllItem, m_contextMenu.get());
849 if (!linkURL.isEmpty()) {
850 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
851 if (m_hitTestResult.isSelected() || frame->selection()->isRange()) {
852 if (selectionContainsPossibleWord(frame)) {
853 appendItem(SearchWebItem, m_contextMenu.get());
855 appendItem(CopyItem, m_contextMenu.get());
859 #if ENABLE(TIZEN_DOWNLOAD_LINK_FILTER)
860 if (loader->client()->canHandleRequest(ResourceRequest(linkURL)) &&
861 (linkURL.protocolIs("http") || linkURL.protocolIs("https") || linkURL.protocolIs("ftp") || linkURL.protocolIs("ftps"))) {
863 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
865 appendItem(OpenLinkItem, m_contextMenu.get());
866 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
867 appendItem(DownloadFileItem, m_contextMenu.get());
870 if (m_hitTestResult.isSelected())
871 appendItem(CopyItem, m_contextMenu.get());
873 appendItem(CopyLinkItem, m_contextMenu.get());
876 KURL imageURL = m_hitTestResult.absoluteImageURL();
877 if (!imageURL.isEmpty()) {
878 if (!linkURL.isEmpty())
879 appendItem(*separatorItem(), m_contextMenu.get());
881 appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
882 appendItem(DownloadImageItem, m_contextMenu.get());
883 if (imageURL.isLocalFile() || m_hitTestResult.image())
884 appendItem(CopyImageItem, m_contextMenu.get());
885 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
886 appendItem(CopyImageUrlItem, m_contextMenu.get());
890 KURL mediaURL = m_hitTestResult.absoluteMediaURL();
891 if (!mediaURL.isEmpty()) {
892 if (!linkURL.isEmpty() || !imageURL.isEmpty())
893 appendItem(*separatorItem(), m_contextMenu.get());
895 appendItem(MediaPlayPause, m_contextMenu.get());
896 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
897 if (m_hitTestResult.mediaMuted())
898 appendItem(MediaUnMute, m_contextMenu.get());
900 appendItem(MediaMute, m_contextMenu.get());
902 appendItem(MediaMute, m_contextMenu.get());
904 appendItem(ToggleMediaControls, m_contextMenu.get());
905 appendItem(ToggleMediaLoop, m_contextMenu.get());
906 appendItem(EnterVideoFullscreen, m_contextMenu.get());
908 appendItem(*separatorItem(), m_contextMenu.get());
909 appendItem(CopyMediaLinkItem, m_contextMenu.get());
910 appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
913 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_TEXT_SELECTION_MODE)
914 if ((!linkURL.isEmpty() || !imageURL.isEmpty()) && mediaURL.isEmpty())
915 appendItem(TextSelectionModeItem, m_contextMenu.get());
918 #if ENABLE(TIZEN_DRAG_SUPPORT)
919 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty() && !m_hitTestResult.isDragSupport()) {
921 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
923 if (m_hitTestResult.isSelected()) {
924 if (selectionContainsPossibleWord(frame)) {
926 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
927 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
929 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
930 appendItem(SearchSpotlightItem, m_contextMenu.get());
932 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
937 appendItem(SearchWebItem, m_contextMenu.get());
938 appendItem(*separatorItem(), m_contextMenu.get());
941 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
942 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
943 appendItem(*separatorItem(), m_contextMenu.get());
947 appendItem(CopyItem, m_contextMenu.get());
949 appendItem(*separatorItem(), m_contextMenu.get());
951 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
952 createAndAppendSpeechSubMenu(SpeechMenuItem);
953 appendItem(SpeechMenuItem, m_contextMenu.get());
956 #if ENABLE(INSPECTOR)
957 if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) {
960 // In GTK+ unavailable items are not hidden but insensitive
962 appendItem(BackItem, m_contextMenu.get());
963 appendItem(ForwardItem, m_contextMenu.get());
964 appendItem(StopItem, m_contextMenu.get());
965 appendItem(ReloadItem, m_contextMenu.get());
967 #if !ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
968 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1))
969 appendItem(BackItem, m_contextMenu.get());
971 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1))
972 appendItem(ForwardItem, m_contextMenu.get());
974 // use isLoadingInAPISense rather than isLoading because Stop/Reload are
975 // intended to match WebKit's API, not WebCore's internal notion of loading status
976 if (loader->documentLoader()->isLoadingInAPISense())
977 appendItem(StopItem, m_contextMenu.get());
979 appendItem(ReloadItem, m_contextMenu.get());
982 #if ENABLE(INSPECTOR)
986 if (frame->page() && frame != frame->page()->mainFrame())
987 appendItem(OpenFrameItem, m_contextMenu.get());
990 #if ENABLE(TIZEN_DRAG_SUPPORT)
991 if (frame->page() && m_hitTestResult.isDragSupport()) {
992 TIZEN_LOGI("appendItem for drag");
993 appendItem(DragItem, m_contextMenu.get());
996 } else { // Make an editing context menu
997 FrameSelection* selection = frame->selection();
998 bool inPasswordField = selection->isInPasswordField();
999 if (!inPasswordField) {
1000 bool haveContextMenuItemsForMisspellingOrGrammer = false;
1001 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node);
1002 if (spellCheckingEnabled) {
1003 // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
1004 // is never considered a misspelling and bad grammar at the same time)
1005 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1006 bool misspelling = false;
1007 bool badGrammar = false;
1012 Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar);
1013 if (misspelling || badGrammar) {
1014 size_t size = guesses.size();
1016 // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
1017 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
1019 appendItem(NoGuessesItem, m_contextMenu.get());
1020 appendItem(*separatorItem(), m_contextMenu.get());
1023 for (unsigned i = 0; i < size; i++) {
1024 const String &guess = guesses[i];
1025 if (!guess.isEmpty()) {
1026 ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
1027 appendItem(item, m_contextMenu.get());
1030 appendItem(*separatorItem(), m_contextMenu.get());
1033 appendItem(IgnoreSpellingItem, m_contextMenu.get());
1034 appendItem(LearnSpellingItem, m_contextMenu.get());
1036 appendItem(IgnoreGrammarItem, m_contextMenu.get());
1037 appendItem(*separatorItem(), m_contextMenu.get());
1038 haveContextMenuItemsForMisspellingOrGrammer = true;
1039 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
1041 // If the string was autocorrected, generate a contextual menu item allowing it to be changed back.
1042 String replacedString = m_hitTestResult.replacedString();
1043 if (!replacedString.isEmpty()) {
1044 ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString));
1045 appendItem(item, m_contextMenu.get());
1046 appendItem(*separatorItem(), m_contextMenu.get());
1047 haveContextMenuItemsForMisspellingOrGrammer = true;
1053 if (!haveContextMenuItemsForMisspellingOrGrammer) {
1054 // Spelling and grammar checking is mutually exclusive with dictation alternatives.
1055 Vector<String> dictationAlternatives = m_hitTestResult.dictationAlternatives();
1056 if (!dictationAlternatives.isEmpty()) {
1057 for (size_t i = 0; i < dictationAlternatives.size(); ++i) {
1058 ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, dictationAlternatives[i]);
1059 appendItem(item, m_contextMenu.get());
1061 appendItem(*separatorItem(), m_contextMenu.get());
1066 FrameLoader* loader = frame->loader();
1067 KURL linkURL = m_hitTestResult.absoluteLinkURL();
1068 if (!linkURL.isEmpty()) {
1069 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
1070 appendItem(OpenLinkItem, m_contextMenu.get());
1071 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
1072 appendItem(DownloadFileItem, m_contextMenu.get());
1074 appendItem(CopyLinkItem, m_contextMenu.get());
1075 appendItem(*separatorItem(), m_contextMenu.get());
1078 if (m_hitTestResult.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
1080 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
1081 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
1083 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
1084 appendItem(SearchSpotlightItem, m_contextMenu.get());
1086 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
1091 appendItem(SearchWebItem, m_contextMenu.get());
1092 appendItem(*separatorItem(), m_contextMenu.get());
1095 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
1096 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
1097 appendItem(*separatorItem(), m_contextMenu.get());
1101 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1102 bool isInputPickerType = false;
1103 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1104 HTMLInputElement* inputElement = node->toInputElement();
1106 (inputElement->isDateField() || inputElement->isDateTimeField() || inputElement->isDateTimeLocalField()
1107 || inputElement->isMonthField() || inputElement->isTimeField() || inputElement->isWeekField()))
1108 isInputPickerType = true;
1110 if (m_hitTestResult.isSelected() && !inPasswordField) {
1111 if (!isInputPickerType)
1112 appendItem(CutItem, m_contextMenu.get());
1113 appendItem(CopyItem, m_contextMenu.get());
1115 if (!isInputPickerType) {
1116 appendItem(PasteItem, m_contextMenu.get());
1117 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
1118 appendItem(ClipboardItem, m_contextMenu.get());
1122 appendItem(CutItem, m_contextMenu.get());
1123 appendItem(CopyItem, m_contextMenu.get());
1124 appendItem(PasteItem, m_contextMenu.get());
1127 appendItem(DeleteItem, m_contextMenu.get());
1128 appendItem(*separatorItem(), m_contextMenu.get());
1130 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1131 if (frame->selection()) {
1132 Node* baseNode = frame->selection()->base().containerNode();
1133 if (baseNode && baseNode->isTextNode() && (!(baseNode->textContent().isEmpty()))) {
1134 if (inPasswordField) {
1135 if (!m_hitTestResult.isSelected())
1136 appendItem(SelectWordItem, m_contextMenu.get());
1139 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
1140 appendItem(SelectAllItem, m_contextMenu.get());
1142 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
1143 appendItem(SelectWordItem, m_contextMenu.get());
1145 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1151 if (!inPasswordField) {
1153 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1154 appendItem(*separatorItem(), m_contextMenu.get());
1155 ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
1156 contextMenuItemTagSpellingMenu());
1157 createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem);
1158 appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
1159 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1162 ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu,
1163 contextMenuItemTagSubstitutionsMenu());
1164 createAndAppendSubstitutionsSubMenu(substitutionsMenuItem);
1165 appendItem(substitutionsMenuItem, m_contextMenu.get());
1166 ContextMenuItem transformationsMenuItem(SubmenuType, ContextMenuItemTagTransformationsMenu,
1167 contextMenuItemTagTransformationsMenu());
1168 createAndAppendTransformationsSubMenu(transformationsMenuItem);
1169 appendItem(transformationsMenuItem, m_contextMenu.get());
1172 bool shouldShowFontMenu = frame->editor()->canEditRichly();
1174 #if ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1175 bool shouldShowFontMenu = false;
1177 bool shouldShowFontMenu = true;
1178 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1180 if (shouldShowFontMenu) {
1181 ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
1182 contextMenuItemTagFontMenu());
1183 createAndAppendFontSubMenu(FontMenuItem);
1184 appendItem(FontMenuItem, m_contextMenu.get());
1187 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
1188 createAndAppendSpeechSubMenu(SpeechMenuItem);
1189 appendItem(SpeechMenuItem, m_contextMenu.get());
1192 EditorClient* client = frame->editor()->client();
1193 if (client && client->shouldShowUnicodeMenu()) {
1194 ContextMenuItem UnicodeMenuItem(SubmenuType, ContextMenuItemTagUnicode, contextMenuItemTagUnicode());
1195 createAndAppendUnicodeSubMenu(UnicodeMenuItem);
1196 appendItem(*separatorItem(), m_contextMenu.get());
1197 appendItem(UnicodeMenuItem, m_contextMenu.get());
1200 ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu,
1201 contextMenuItemTagWritingDirectionMenu());
1202 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1203 createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem);
1204 appendItem(WritingDirectionMenuItem, m_contextMenu.get());
1205 if (Page* page = frame->page()) {
1206 if (Settings* settings = page->settings()) {
1207 bool includeTextDirectionSubmenu = settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
1208 || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection());
1209 if (includeTextDirectionSubmenu) {
1210 ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu,
1211 contextMenuItemTagTextDirectionMenu());
1212 createAndAppendTextDirectionSubMenu(TextDirectionMenuItem);
1213 appendItem(TextDirectionMenuItem, m_contextMenu.get());
1217 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1223 #if ENABLE(INSPECTOR)
1224 void ContextMenuController::addInspectElementItem()
1226 Node* node = m_hitTestResult.innerNonSharedNode();
1230 Frame* frame = node->document()->frame();
1234 Page* page = frame->page();
1238 if (!page->inspectorController())
1241 ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
1242 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
1243 if (!m_contextMenu->items().isEmpty())
1245 if (m_contextMenu->itemCount())
1247 appendItem(*separatorItem(), m_contextMenu.get());
1248 appendItem(InspectElementItem, m_contextMenu.get());
1250 #endif // ENABLE(INSPECTOR)
1252 void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
1254 if (item.type() == SeparatorType)
1257 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
1261 // Custom items already have proper checked and enabled values.
1262 if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag)
1265 bool shouldEnable = true;
1266 bool shouldCheck = false;
1268 switch (item.action()) {
1269 case ContextMenuItemTagCheckSpelling:
1270 shouldEnable = frame->editor()->canEdit();
1272 case ContextMenuItemTagDefaultDirection:
1273 shouldCheck = false;
1274 shouldEnable = false;
1276 case ContextMenuItemTagLeftToRight:
1277 case ContextMenuItemTagRightToLeft: {
1278 String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
1279 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirection, direction) != FalseTriState;
1280 shouldEnable = true;
1283 case ContextMenuItemTagTextDirectionDefault: {
1284 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionNatural");
1285 shouldCheck = command.state() == TrueTriState;
1286 shouldEnable = command.isEnabled();
1289 case ContextMenuItemTagTextDirectionLeftToRight: {
1290 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionLeftToRight");
1291 shouldCheck = command.state() == TrueTriState;
1292 shouldEnable = command.isEnabled();
1295 case ContextMenuItemTagTextDirectionRightToLeft: {
1296 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionRightToLeft");
1297 shouldCheck = command.state() == TrueTriState;
1298 shouldEnable = command.isEnabled();
1301 case ContextMenuItemTagCopy:
1302 shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
1304 case ContextMenuItemTagCut:
1305 shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
1307 case ContextMenuItemTagIgnoreSpelling:
1308 case ContextMenuItemTagLearnSpelling:
1309 shouldEnable = frame->selection()->isRange();
1311 case ContextMenuItemTagPaste:
1312 shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
1314 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
1315 case ContextMenuItemTagSelectWord:
1316 shouldEnable = frame->editor()->canSelectRange();
1320 case ContextMenuItemTagDelete:
1321 shouldEnable = frame->editor()->canDelete();
1323 case ContextMenuItemTagInputMethods:
1324 case ContextMenuItemTagUnicode:
1325 case ContextMenuItemTagUnicodeInsertLRMMark:
1326 case ContextMenuItemTagUnicodeInsertRLMMark:
1327 case ContextMenuItemTagUnicodeInsertLREMark:
1328 case ContextMenuItemTagUnicodeInsertRLEMark:
1329 case ContextMenuItemTagUnicodeInsertLROMark:
1330 case ContextMenuItemTagUnicodeInsertRLOMark:
1331 case ContextMenuItemTagUnicodeInsertPDFMark:
1332 case ContextMenuItemTagUnicodeInsertZWSMark:
1333 case ContextMenuItemTagUnicodeInsertZWJMark:
1334 case ContextMenuItemTagUnicodeInsertZWNJMark:
1335 shouldEnable = true;
1338 #if PLATFORM(GTK) || PLATFORM(EFL)
1339 case ContextMenuItemTagSelectAll:
1340 shouldEnable = true;
1343 case ContextMenuItemTagUnderline: {
1344 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") != FalseTriState;
1345 shouldEnable = frame->editor()->canEditRichly();
1348 case ContextMenuItemTagLookUpInDictionary:
1349 shouldEnable = frame->selection()->isRange();
1351 case ContextMenuItemTagCheckGrammarWithSpelling:
1352 if (frame->editor()->isGrammarCheckingEnabled())
1354 shouldEnable = true;
1356 case ContextMenuItemTagItalic: {
1357 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic") != FalseTriState;
1358 shouldEnable = frame->editor()->canEditRichly();
1361 case ContextMenuItemTagBold: {
1362 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold") != FalseTriState;
1363 shouldEnable = frame->editor()->canEditRichly();
1366 case ContextMenuItemTagOutline:
1367 shouldEnable = false;
1369 case ContextMenuItemTagShowSpellingPanel:
1370 if (frame->editor()->spellingPanelIsShowing())
1371 item.setTitle(contextMenuItemTagShowSpellingPanel(false));
1373 item.setTitle(contextMenuItemTagShowSpellingPanel(true));
1374 shouldEnable = frame->editor()->canEdit();
1376 case ContextMenuItemTagNoGuessesFound:
1377 shouldEnable = false;
1379 case ContextMenuItemTagCheckSpellingWhileTyping:
1380 shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
1383 case ContextMenuItemTagSubstitutionsMenu:
1384 case ContextMenuItemTagTransformationsMenu:
1386 case ContextMenuItemTagShowSubstitutions:
1387 if (frame->editor()->substitutionsPanelIsShowing())
1388 item.setTitle(contextMenuItemTagShowSubstitutions(false));
1390 item.setTitle(contextMenuItemTagShowSubstitutions(true));
1391 shouldEnable = frame->editor()->canEdit();
1393 case ContextMenuItemTagMakeUpperCase:
1394 case ContextMenuItemTagMakeLowerCase:
1395 case ContextMenuItemTagCapitalize:
1396 case ContextMenuItemTagChangeBack:
1397 shouldEnable = frame->editor()->canEdit();
1399 case ContextMenuItemTagCorrectSpellingAutomatically:
1400 shouldCheck = frame->editor()->isAutomaticSpellingCorrectionEnabled();
1402 case ContextMenuItemTagSmartCopyPaste:
1403 shouldCheck = frame->editor()->smartInsertDeleteEnabled();
1405 case ContextMenuItemTagSmartQuotes:
1406 shouldCheck = frame->editor()->isAutomaticQuoteSubstitutionEnabled();
1408 case ContextMenuItemTagSmartDashes:
1409 shouldCheck = frame->editor()->isAutomaticDashSubstitutionEnabled();
1411 case ContextMenuItemTagSmartLinks:
1412 shouldCheck = frame->editor()->isAutomaticLinkDetectionEnabled();
1414 case ContextMenuItemTagTextReplacement:
1415 shouldCheck = frame->editor()->isAutomaticTextReplacementEnabled();
1417 case ContextMenuItemTagStopSpeaking:
1418 shouldEnable = client() && client()->isSpeaking();
1420 #else // PLATFORM(MAC) ends here
1421 case ContextMenuItemTagStopSpeaking:
1425 case ContextMenuItemTagGoBack:
1426 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1);
1428 case ContextMenuItemTagGoForward:
1429 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1);
1431 case ContextMenuItemTagStop:
1432 shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
1434 case ContextMenuItemTagReload:
1435 shouldEnable = !frame->loader()->documentLoader()->isLoadingInAPISense();
1437 case ContextMenuItemTagFontMenu:
1438 shouldEnable = frame->editor()->canEditRichly();
1441 case ContextMenuItemTagGoBack:
1442 case ContextMenuItemTagGoForward:
1443 case ContextMenuItemTagStop:
1444 case ContextMenuItemTagReload:
1445 case ContextMenuItemTagFontMenu:
1447 case ContextMenuItemTagNoAction:
1448 case ContextMenuItemTagOpenLinkInNewWindow:
1449 case ContextMenuItemTagDownloadLinkToDisk:
1450 case ContextMenuItemTagCopyLinkToClipboard:
1451 case ContextMenuItemTagOpenImageInNewWindow:
1452 case ContextMenuItemTagDownloadImageToDisk:
1453 case ContextMenuItemTagCopyImageToClipboard:
1454 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
1455 case ContextMenuItemTagCopyImageUrlToClipboard:
1458 case ContextMenuItemTagOpenMediaInNewWindow:
1459 if (m_hitTestResult.mediaIsVideo())
1460 item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
1462 item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
1464 case ContextMenuItemTagCopyMediaLinkToClipboard:
1465 if (m_hitTestResult.mediaIsVideo())
1466 item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
1468 item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
1470 case ContextMenuItemTagToggleMediaControls:
1471 shouldCheck = m_hitTestResult.mediaControlsEnabled();
1473 case ContextMenuItemTagToggleMediaLoop:
1474 shouldCheck = m_hitTestResult.mediaLoopEnabled();
1476 case ContextMenuItemTagEnterVideoFullscreen:
1477 shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
1479 case ContextMenuItemTagOpenFrameInNewWindow:
1480 case ContextMenuItemTagSpellingGuess:
1481 case ContextMenuItemTagOther:
1482 case ContextMenuItemTagSearchInSpotlight:
1483 case ContextMenuItemTagSearchWeb:
1484 case ContextMenuItemTagOpenWithDefaultApplication:
1485 case ContextMenuItemPDFActualSize:
1486 case ContextMenuItemPDFZoomIn:
1487 case ContextMenuItemPDFZoomOut:
1488 case ContextMenuItemPDFAutoSize:
1489 case ContextMenuItemPDFSinglePage:
1490 case ContextMenuItemPDFFacingPages:
1491 case ContextMenuItemPDFContinuous:
1492 case ContextMenuItemPDFNextPage:
1493 case ContextMenuItemPDFPreviousPage:
1494 case ContextMenuItemTagOpenLink:
1495 case ContextMenuItemTagIgnoreGrammar:
1496 case ContextMenuItemTagSpellingMenu:
1497 case ContextMenuItemTagShowFonts:
1498 case ContextMenuItemTagStyles:
1499 case ContextMenuItemTagShowColors:
1500 case ContextMenuItemTagSpeechMenu:
1501 case ContextMenuItemTagStartSpeaking:
1502 case ContextMenuItemTagWritingDirectionMenu:
1503 case ContextMenuItemTagTextDirectionMenu:
1504 case ContextMenuItemTagPDFSinglePageScrolling:
1505 case ContextMenuItemTagPDFFacingPagesScrolling:
1506 #if ENABLE(INSPECTOR)
1507 case ContextMenuItemTagInspectElement:
1509 #if ENABLE(TIZEN_DRAG_SUPPORT)
1510 case ContextMenuItemTagDrag:
1512 case ContextMenuItemBaseCustomTag:
1513 case ContextMenuItemCustomTagNoAction:
1514 case ContextMenuItemLastCustomTag:
1515 case ContextMenuItemBaseApplicationTag:
1516 case ContextMenuItemTagDictationAlternative:
1518 case ContextMenuItemTagMediaPlayPause:
1519 if (m_hitTestResult.mediaPlaying())
1520 item.setTitle(contextMenuItemTagMediaPause());
1522 item.setTitle(contextMenuItemTagMediaPlay());
1524 case ContextMenuItemTagMediaMute:
1525 shouldEnable = m_hitTestResult.mediaHasAudio();
1526 shouldCheck = shouldEnable && m_hitTestResult.mediaMuted();
1528 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
1534 item.setChecked(shouldCheck);
1535 item.setEnabled(shouldEnable);
1538 #if USE(ACCESSIBILITY_CONTEXT_MENUS)
1539 void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clickPoint)
1541 // Simulate a click in the middle of the accessibility object.
1542 PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
1543 bool handled = frame->eventHandler()->sendContextMenuEvent(mouseEvent);
1544 if (handled && client())
1545 client()->showContextMenu();
1549 } // namespace WebCore
1551 #endif // ENABLE(CONTEXT_MENUS)