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"
88 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
89 #include "visible_units.h"
90 #include "htmlediting.h"
94 using namespace Unicode;
98 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* client)
102 ASSERT_ARG(page, page);
103 ASSERT_ARG(client, client);
106 ContextMenuController::~ContextMenuController()
108 m_client->contextMenuDestroyed();
111 PassOwnPtr<ContextMenuController> ContextMenuController::create(Page* page, ContextMenuClient* client)
113 return adoptPtr(new ContextMenuController(page, client));
116 void ContextMenuController::clearContextMenu()
118 m_contextMenu.clear();
120 m_menuProvider->contextMenuCleared();
124 void ContextMenuController::handleContextMenuEvent(Event* event)
126 m_contextMenu = createContextMenu(event);
132 showContextMenu(event);
135 static PassOwnPtr<ContextMenuItem> separatorItem()
137 return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoAction, String()));
140 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
142 m_menuProvider = menuProvider;
144 m_contextMenu = createContextMenu(event);
145 if (!m_contextMenu) {
150 m_menuProvider->populateContextMenu(m_contextMenu.get());
151 if (m_hitTestResult.isSelected()) {
152 appendItem(*separatorItem(), m_contextMenu.get());
155 showContextMenu(event);
158 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
160 if (!event->isMouseEvent())
163 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
164 HitTestResult result(mouseEvent->absoluteLocation());
166 if (Frame* frame = event->target()->toNode()->document()->frame())
167 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
169 if (!result.innerNonSharedNode())
172 m_hitTestResult = result;
174 return adoptPtr(new ContextMenu);
177 void ContextMenuController::showContextMenu(Event* event)
179 #if ENABLE(INSPECTOR)
180 if (m_page->inspectorController()->enabled())
181 addInspectElementItem();
184 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
185 m_contextMenu = m_client->customizeMenu(m_contextMenu.release());
187 PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
188 m_contextMenu->setPlatformDescription(customMenu);
190 event->setDefaultHandled();
193 static void openNewWindow(const KURL& urlToLoad, Frame* frame)
195 if (Page* oldPage = frame->page()) {
196 FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRequest(urlToLoad, frame->loader()->outgoingReferrer()));
197 if (Page* newPage = oldPage->chrome()->createWindow(frame, request, WindowFeatures(), NavigationAction(request.resourceRequest()))) {
198 newPage->mainFrame()->loader()->loadFrameRequest(request, false, false, 0, 0, MaybeSendReferrer);
199 newPage->chrome()->show();
205 static void insertUnicodeCharacter(UChar character, Frame* frame)
207 String text(&character, 1);
208 if (!frame->editor()->shouldInsertText(text, frame->selection()->toNormalizedRange().get(), EditorInsertActionTyped))
211 TypingCommand::insertText(frame->document(), text, 0, TypingCommand::TextCompositionNone);
215 void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
217 ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
219 if (item->action() >= ContextMenuItemBaseApplicationTag) {
220 m_client->contextMenuItemSelected(item, m_contextMenu.get());
224 if (item->action() >= ContextMenuItemBaseCustomTag) {
225 ASSERT(m_menuProvider);
226 m_menuProvider->contextMenuItemSelected(item);
230 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
234 #if ENABLE(TIZEN_PASTEBOARD)
235 if (Page* page = frame->page()) {
236 if (item->action() == ContextMenuItemTagCopyLinkToClipboard
237 || item->action() == ContextMenuItemTagCopyImageToClipboard
238 || item->action() == ContextMenuItemTagCopyImageUrlToClipboard
239 || item->action() == ContextMenuItemTagCopyMediaLinkToClipboard
240 || item->action() == ContextMenuItemTagCopy
241 || item->action() == ContextMenuItemTagCut)
242 Pasteboard::generalPasteboard()->setPage(page);
246 switch (item->action()) {
247 case ContextMenuItemTagOpenLinkInNewWindow:
248 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
250 case ContextMenuItemTagDownloadLinkToDisk:
251 // FIXME: Some day we should be able to do this from within WebCore.
252 m_client->downloadURL(m_hitTestResult.absoluteLinkURL());
254 case ContextMenuItemTagCopyLinkToClipboard:
255 frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestResult.textContent());
257 case ContextMenuItemTagOpenImageInNewWindow:
258 openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
260 case ContextMenuItemTagDownloadImageToDisk:
261 // FIXME: Some day we should be able to do this from within WebCore.
262 m_client->downloadURL(m_hitTestResult.absoluteImageURL());
264 case ContextMenuItemTagCopyImageToClipboard:
265 // FIXME: The Pasteboard class is not written yet
266 // For now, call into the client. This is temporary!
267 frame->editor()->copyImage(m_hitTestResult);
269 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
270 case ContextMenuItemTagCopyImageUrlToClipboard:
271 frame->editor()->copyURL(m_hitTestResult.absoluteImageURL(), m_hitTestResult.textContent());
274 case ContextMenuItemTagOpenMediaInNewWindow:
275 openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
277 case ContextMenuItemTagCopyMediaLinkToClipboard:
278 frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestResult.textContent());
280 case ContextMenuItemTagToggleMediaControls:
281 m_hitTestResult.toggleMediaControlsDisplay();
283 case ContextMenuItemTagToggleMediaLoop:
284 m_hitTestResult.toggleMediaLoopPlayback();
286 case ContextMenuItemTagEnterVideoFullscreen:
287 m_hitTestResult.enterFullscreenForVideo();
289 case ContextMenuItemTagMediaPlayPause:
290 m_hitTestResult.toggleMediaPlayState();
292 case ContextMenuItemTagMediaMute:
293 m_hitTestResult.toggleMediaMuteState();
295 case ContextMenuItemTagOpenFrameInNewWindow: {
296 DocumentLoader* loader = frame->loader()->documentLoader();
297 if (!loader->unreachableURL().isEmpty())
298 openNewWindow(loader->unreachableURL(), frame);
300 openNewWindow(loader->url(), frame);
303 case ContextMenuItemTagCopy: {
304 frame->editor()->copy();
307 case ContextMenuItemTagGoBack:
308 if (Page* page = frame->page())
309 page->backForward()->goBackOrForward(-1);
311 case ContextMenuItemTagGoForward:
312 if (Page* page = frame->page())
313 page->backForward()->goBackOrForward(1);
315 case ContextMenuItemTagStop:
316 frame->loader()->stop();
318 case ContextMenuItemTagReload:
319 frame->loader()->reload();
321 case ContextMenuItemTagCut:
322 frame->editor()->command("Cut").execute();
324 case ContextMenuItemTagPaste:
325 frame->editor()->command("Paste").execute();
328 case ContextMenuItemTagDelete:
329 frame->editor()->performDelete();
331 case ContextMenuItemTagUnicodeInsertLRMMark:
332 insertUnicodeCharacter(leftToRightMark, frame);
334 case ContextMenuItemTagUnicodeInsertRLMMark:
335 insertUnicodeCharacter(rightToLeftMark, frame);
337 case ContextMenuItemTagUnicodeInsertLREMark:
338 insertUnicodeCharacter(leftToRightEmbed, frame);
340 case ContextMenuItemTagUnicodeInsertRLEMark:
341 insertUnicodeCharacter(rightToLeftEmbed, frame);
343 case ContextMenuItemTagUnicodeInsertLROMark:
344 insertUnicodeCharacter(leftToRightOverride, frame);
346 case ContextMenuItemTagUnicodeInsertRLOMark:
347 insertUnicodeCharacter(rightToLeftOverride, frame);
349 case ContextMenuItemTagUnicodeInsertPDFMark:
350 insertUnicodeCharacter(popDirectionalFormatting, frame);
352 case ContextMenuItemTagUnicodeInsertZWSMark:
353 insertUnicodeCharacter(zeroWidthSpace, frame);
355 case ContextMenuItemTagUnicodeInsertZWJMark:
356 insertUnicodeCharacter(zeroWidthJoiner, frame);
358 case ContextMenuItemTagUnicodeInsertZWNJMark:
359 insertUnicodeCharacter(zeroWidthNonJoiner, frame);
362 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
363 case ContextMenuItemTagSelectAll:
364 frame->editor()->command("SelectAll").execute();
367 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
368 case ContextMenuItemTagSelectWord:
369 frame->editor()->command("SelectWord").execute();
372 case ContextMenuItemTagSpellingGuess:
373 ASSERT(frame->editor()->selectedText().length());
374 if (frame->editor()->shouldInsertText(item->title(), frame->selection()->toNormalizedRange().get(), EditorInsertActionPasted)) {
375 Document* document = frame->document();
376 RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(document, createFragmentFromMarkup(document, item->title(), ""), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting);
377 applyCommand(command);
378 frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
381 case ContextMenuItemTagIgnoreSpelling:
382 frame->editor()->ignoreSpelling();
384 case ContextMenuItemTagLearnSpelling:
385 frame->editor()->learnSpelling();
387 case ContextMenuItemTagSearchWeb:
388 m_client->searchWithGoogle(frame);
390 case ContextMenuItemTagLookUpInDictionary:
391 // FIXME: Some day we may be able to do this from within WebCore.
392 m_client->lookUpInDictionary(frame);
394 case ContextMenuItemTagOpenLink:
395 if (Frame* targetFrame = m_hitTestResult.targetFrame())
396 targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, MaybeSendReferrer);
398 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
400 case ContextMenuItemTagBold:
401 frame->editor()->command("ToggleBold").execute();
403 case ContextMenuItemTagItalic:
404 frame->editor()->command("ToggleItalic").execute();
406 case ContextMenuItemTagUnderline:
407 frame->editor()->toggleUnderline();
409 case ContextMenuItemTagOutline:
410 // We actually never enable this because CSS does not have a way to specify an outline font,
411 // which may make this difficult to implement. Maybe a special case of text-shadow?
413 case ContextMenuItemTagStartSpeaking: {
415 RefPtr<Range> selectedRange = frame->selection()->toNormalizedRange();
416 if (!selectedRange || selectedRange->collapsed(ec)) {
417 Document* document = m_hitTestResult.innerNonSharedNode()->document();
418 selectedRange = document->createRange();
419 selectedRange->selectNode(document->documentElement(), ec);
421 m_client->speak(plainText(selectedRange.get()));
424 case ContextMenuItemTagStopSpeaking:
425 m_client->stopSpeaking();
427 case ContextMenuItemTagDefaultDirection:
428 frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
430 case ContextMenuItemTagLeftToRight:
431 frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
433 case ContextMenuItemTagRightToLeft:
434 frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
436 case ContextMenuItemTagTextDirectionDefault:
437 frame->editor()->command("MakeTextWritingDirectionNatural").execute();
439 case ContextMenuItemTagTextDirectionLeftToRight:
440 frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute();
442 case ContextMenuItemTagTextDirectionRightToLeft:
443 frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute();
446 case ContextMenuItemTagSearchInSpotlight:
447 m_client->searchWithSpotlight();
450 case ContextMenuItemTagShowSpellingPanel:
451 frame->editor()->showSpellingGuessPanel();
453 case ContextMenuItemTagCheckSpelling:
454 frame->editor()->advanceToNextMisspelling();
456 case ContextMenuItemTagCheckSpellingWhileTyping:
457 frame->editor()->toggleContinuousSpellChecking();
459 case ContextMenuItemTagCheckGrammarWithSpelling:
460 frame->editor()->toggleGrammarChecking();
463 case ContextMenuItemTagShowFonts:
464 frame->editor()->showFontPanel();
466 case ContextMenuItemTagStyles:
467 frame->editor()->showStylesPanel();
469 case ContextMenuItemTagShowColors:
470 frame->editor()->showColorPanel();
474 case ContextMenuItemTagMakeUpperCase:
475 frame->editor()->uppercaseWord();
477 case ContextMenuItemTagMakeLowerCase:
478 frame->editor()->lowercaseWord();
480 case ContextMenuItemTagCapitalize:
481 frame->editor()->capitalizeWord();
485 case ContextMenuItemTagChangeBack:
486 frame->editor()->changeBackToReplacedString(m_hitTestResult.replacedString());
489 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
490 case ContextMenuItemTagShowSubstitutions:
491 frame->editor()->showSubstitutionsPanel();
493 case ContextMenuItemTagSmartCopyPaste:
494 frame->editor()->toggleSmartInsertDelete();
496 case ContextMenuItemTagSmartQuotes:
497 frame->editor()->toggleAutomaticQuoteSubstitution();
499 case ContextMenuItemTagSmartDashes:
500 frame->editor()->toggleAutomaticDashSubstitution();
502 case ContextMenuItemTagSmartLinks:
503 frame->editor()->toggleAutomaticLinkDetection();
505 case ContextMenuItemTagTextReplacement:
506 frame->editor()->toggleAutomaticTextReplacement();
508 case ContextMenuItemTagCorrectSpellingAutomatically:
509 frame->editor()->toggleAutomaticSpellingCorrection();
512 #if ENABLE(INSPECTOR)
513 case ContextMenuItemTagInspectElement:
514 if (Page* page = frame->page())
515 page->inspectorController()->inspect(m_hitTestResult.innerNonSharedNode());
518 case ContextMenuItemTagDictationAlternative:
519 frame->editor()->applyDictationAlternativelternative(item->title());
521 #if ENABLE(TIZEN_DRAG_SUPPORT)
522 case ContextMenuItemTagDrag:
523 TIZEN_LOGI("ContextMenuItemTagDrag");
524 if (Page* page = frame->page()) {
525 page->dragController()->setDragState(true);
526 frame->eventHandler()->handleMousePressEvent(page->dragController()->dragPositionEvent());
527 page->dragController()->setDragState(false);
536 void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* parentMenu)
538 checkOrEnableIfNeeded(menuItem);
540 parentMenu->appendItem(menuItem);
543 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenuItem)
545 ContextMenu fontMenu;
548 ContextMenuItem showFonts(ActionType, ContextMenuItemTagShowFonts, contextMenuItemTagShowFonts());
550 ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMenuItemTagBold());
551 ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contextMenuItemTagItalic());
552 ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
553 ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuItemTagOutline());
555 ContextMenuItem styles(ActionType, ContextMenuItemTagStyles, contextMenuItemTagStyles());
556 ContextMenuItem showColors(ActionType, ContextMenuItemTagShowColors, contextMenuItemTagShowColors());
560 appendItem(showFonts, &fontMenu);
562 appendItem(bold, &fontMenu);
563 appendItem(italic, &fontMenu);
564 appendItem(underline, &fontMenu);
565 appendItem(outline, &fontMenu);
567 appendItem(styles, &fontMenu);
568 appendItem(*separatorItem(), &fontMenu);
569 appendItem(showColors, &fontMenu);
572 fontMenuItem.setSubMenu(&fontMenu);
578 void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenuItem& spellingAndGrammarMenuItem)
580 ContextMenu spellingAndGrammarMenu;
582 ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpellingPanel,
583 contextMenuItemTagShowSpellingPanel(true));
584 ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
585 contextMenuItemTagCheckSpelling());
586 ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckSpellingWhileTyping,
587 contextMenuItemTagCheckSpellingWhileTyping());
588 ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagCheckGrammarWithSpelling,
589 contextMenuItemTagCheckGrammarWithSpelling());
591 ContextMenuItem correctSpelling(CheckableActionType, ContextMenuItemTagCorrectSpellingAutomatically,
592 contextMenuItemTagCorrectSpellingAutomatically());
595 appendItem(showSpellingPanel, &spellingAndGrammarMenu);
596 appendItem(checkSpelling, &spellingAndGrammarMenu);
598 appendItem(*separatorItem(), &spellingAndGrammarMenu);
600 appendItem(checkAsYouType, &spellingAndGrammarMenu);
601 appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
603 appendItem(correctSpelling, &spellingAndGrammarMenu);
606 spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
609 #endif // !PLATFORM(GTK)
614 void ContextMenuController::createAndAppendSpeechSubMenu(ContextMenuItem& speechMenuItem)
616 ContextMenu speechMenu;
618 ContextMenuItem start(ActionType, ContextMenuItemTagStartSpeaking, contextMenuItemTagStartSpeaking());
619 ContextMenuItem stop(ActionType, ContextMenuItemTagStopSpeaking, contextMenuItemTagStopSpeaking());
621 appendItem(start, &speechMenu);
622 appendItem(stop, &speechMenu);
624 speechMenuItem.setSubMenu(&speechMenu);
631 void ContextMenuController::createAndAppendUnicodeSubMenu(ContextMenuItem& unicodeMenuItem)
633 ContextMenu unicodeMenu;
635 ContextMenuItem leftToRightMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLRMMark, contextMenuItemTagUnicodeInsertLRMMark());
636 ContextMenuItem rightToLeftMarkMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLMMark, contextMenuItemTagUnicodeInsertRLMMark());
637 ContextMenuItem leftToRightEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLREMark, contextMenuItemTagUnicodeInsertLREMark());
638 ContextMenuItem rightToLeftEmbedMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLEMark, contextMenuItemTagUnicodeInsertRLEMark());
639 ContextMenuItem leftToRightOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertLROMark, contextMenuItemTagUnicodeInsertLROMark());
640 ContextMenuItem rightToLeftOverrideMenuItem(ActionType, ContextMenuItemTagUnicodeInsertRLOMark, contextMenuItemTagUnicodeInsertRLOMark());
641 ContextMenuItem popDirectionalFormattingMenuItem(ActionType, ContextMenuItemTagUnicodeInsertPDFMark, contextMenuItemTagUnicodeInsertPDFMark());
642 ContextMenuItem zeroWidthSpaceMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWSMark, contextMenuItemTagUnicodeInsertZWSMark());
643 ContextMenuItem zeroWidthJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWJMark, contextMenuItemTagUnicodeInsertZWJMark());
644 ContextMenuItem zeroWidthNonJoinerMenuItem(ActionType, ContextMenuItemTagUnicodeInsertZWNJMark, contextMenuItemTagUnicodeInsertZWNJMark());
646 appendItem(leftToRightMarkMenuItem, &unicodeMenu);
647 appendItem(rightToLeftMarkMenuItem, &unicodeMenu);
648 appendItem(leftToRightEmbedMenuItem, &unicodeMenu);
649 appendItem(rightToLeftEmbedMenuItem, &unicodeMenu);
650 appendItem(leftToRightOverrideMenuItem, &unicodeMenu);
651 appendItem(rightToLeftOverrideMenuItem, &unicodeMenu);
652 appendItem(popDirectionalFormattingMenuItem, &unicodeMenu);
653 appendItem(zeroWidthSpaceMenuItem, &unicodeMenu);
654 appendItem(zeroWidthJoinerMenuItem, &unicodeMenu);
655 appendItem(zeroWidthNonJoinerMenuItem, &unicodeMenu);
657 unicodeMenuItem.setSubMenu(&unicodeMenu);
662 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuItem& writingDirectionMenuItem)
664 ContextMenu writingDirectionMenu;
666 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection,
667 contextMenuItemTagDefaultDirection());
668 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, contextMenuItemTagLeftToRight());
669 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, contextMenuItemTagRightToLeft());
671 appendItem(defaultItem, &writingDirectionMenu);
672 appendItem(ltr, &writingDirectionMenu);
673 appendItem(rtl, &writingDirectionMenu);
675 writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
678 void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem)
680 ContextMenu textDirectionMenu;
682 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefault, contextMenuItemTagDefaultDirection());
683 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeftToRight, contextMenuItemTagLeftToRight());
684 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRightToLeft, contextMenuItemTagRightToLeft());
686 appendItem(defaultItem, &textDirectionMenu);
687 appendItem(ltr, &textDirectionMenu);
688 appendItem(rtl, &textDirectionMenu);
690 textDirectionMenuItem.setSubMenu(&textDirectionMenu);
697 void ContextMenuController::createAndAppendSubstitutionsSubMenu(ContextMenuItem& substitutionsMenuItem)
699 ContextMenu substitutionsMenu;
701 ContextMenuItem showSubstitutions(ActionType, ContextMenuItemTagShowSubstitutions, contextMenuItemTagShowSubstitutions(true));
702 ContextMenuItem smartCopyPaste(CheckableActionType, ContextMenuItemTagSmartCopyPaste, contextMenuItemTagSmartCopyPaste());
703 ContextMenuItem smartQuotes(CheckableActionType, ContextMenuItemTagSmartQuotes, contextMenuItemTagSmartQuotes());
704 ContextMenuItem smartDashes(CheckableActionType, ContextMenuItemTagSmartDashes, contextMenuItemTagSmartDashes());
705 ContextMenuItem smartLinks(CheckableActionType, ContextMenuItemTagSmartLinks, contextMenuItemTagSmartLinks());
706 ContextMenuItem textReplacement(CheckableActionType, ContextMenuItemTagTextReplacement, contextMenuItemTagTextReplacement());
708 appendItem(showSubstitutions, &substitutionsMenu);
709 appendItem(*separatorItem(), &substitutionsMenu);
710 appendItem(smartCopyPaste, &substitutionsMenu);
711 appendItem(smartQuotes, &substitutionsMenu);
712 appendItem(smartDashes, &substitutionsMenu);
713 appendItem(smartLinks, &substitutionsMenu);
714 appendItem(textReplacement, &substitutionsMenu);
716 substitutionsMenuItem.setSubMenu(&substitutionsMenu);
719 void ContextMenuController::createAndAppendTransformationsSubMenu(ContextMenuItem& transformationsMenuItem)
721 ContextMenu transformationsMenu;
723 ContextMenuItem makeUpperCase(ActionType, ContextMenuItemTagMakeUpperCase, contextMenuItemTagMakeUpperCase());
724 ContextMenuItem makeLowerCase(ActionType, ContextMenuItemTagMakeLowerCase, contextMenuItemTagMakeLowerCase());
725 ContextMenuItem capitalize(ActionType, ContextMenuItemTagCapitalize, contextMenuItemTagCapitalize());
727 appendItem(makeUpperCase, &transformationsMenu);
728 appendItem(makeLowerCase, &transformationsMenu);
729 appendItem(capitalize, &transformationsMenu);
731 transformationsMenuItem.setSubMenu(&transformationsMenu);
736 static bool selectionContainsPossibleWord(Frame* frame)
738 // Current algorithm: look for a character that's not just a separator.
739 for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atEnd(); it.advance()) {
740 int length = it.length();
741 const UChar* characters = it.characters();
742 for (int i = 0; i < length; ++i)
743 if (!(category(characters[i]) & (Separator_Space | Separator_Line | Separator_Paragraph)))
750 #if __MAC_OS_X_VERSION_MIN_REQUIRED == 1060
751 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 1
753 #define INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM 0
757 void ContextMenuController::populate()
759 ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, contextMenuItemTagOpenLink());
760 ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLinkInNewWindow,
761 contextMenuItemTagOpenLinkInNewWindow());
762 ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkToDisk,
763 contextMenuItemTagDownloadLinkToDisk());
764 ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboard,
765 contextMenuItemTagCopyLinkToClipboard());
766 ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenImageInNewWindow,
767 contextMenuItemTagOpenImageInNewWindow());
768 ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImageToDisk,
769 contextMenuItemTagDownloadImageToDisk());
770 ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipboard,
771 contextMenuItemTagCopyImageToClipboard());
772 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
773 ContextMenuItem CopyImageUrlItem(ActionType, ContextMenuItemTagCopyImageUrlToClipboard,
774 contextMenuItemTagCopyImageUrlToClipboard());
776 ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenMediaInNewWindow, String());
777 ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLinkToClipboard,
779 ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause,
780 contextMenuItemTagMediaPlay());
781 ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute,
782 contextMenuItemTagMediaMute());
783 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
784 ContextMenuItem MediaUnMute(ActionType, ContextMenuItemTagMediaMute,
785 contextMenuItemTagMediaUnMute());
787 ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagToggleMediaControls,
788 contextMenuItemTagToggleMediaControls());
789 ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggleMediaLoop,
790 contextMenuItemTagToggleMediaLoop());
791 ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVideoFullscreen,
792 contextMenuItemTagEnterVideoFullscreen());
794 ContextMenuItem SearchSpotlightItem(ActionType, ContextMenuItemTagSearchInSpotlight,
795 contextMenuItemTagSearchInSpotlight());
798 ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, contextMenuItemTagSearchWeb());
800 ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItemTagCopy());
801 ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuItemTagGoBack());
802 ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contextMenuItemTagGoForward());
803 ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItemTagStop());
804 ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenuItemTagReload());
805 ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWindow,
806 contextMenuItemTagOpenFrameInNewWindow());
807 ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound,
808 contextMenuItemTagNoGuessesFound());
809 ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpelling,
810 contextMenuItemTagIgnoreSpelling());
811 ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpelling,
812 contextMenuItemTagLearnSpelling());
813 ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGrammar,
814 contextMenuItemTagIgnoreGrammar());
815 ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTagCut());
816 ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuItemTagPaste());
817 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
818 ContextMenuItem ClipboardItem(ActionType, ContextMenuItemTagClipboard, contextMenuItemTagClipboard());
821 ContextMenuItem DeleteItem(ActionType, ContextMenuItemTagDelete, contextMenuItemTagDelete());
823 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
824 ContextMenuItem SelectAllItem(ActionType, ContextMenuItemTagSelectAll, contextMenuItemTagSelectAll());
826 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
827 ContextMenuItem SelectWordItem(ActionType, ContextMenuItemTagSelectWord, contextMenuItemTagSelectWord());
829 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_TEXT_SELECTION_MODE)
830 ContextMenuItem TextSelectionModeItem(ActionType, ContextMenuItemTagTextSelectionMode, contextMenuItemTagTextSelectionMode());
832 #if ENABLE(TIZEN_DRAG_SUPPORT)
833 ContextMenuItem DragItem(ActionType, ContextMenuItemTagDrag, contextMenuItemTagDrag());
836 Node* node = m_hitTestResult.innerNonSharedNode();
840 if (!m_hitTestResult.isContentEditable() && (node->isElementNode() && static_cast<Element*>(node)->isFormControlElement()))
843 Frame* frame = node->document()->frame();
847 if (!m_hitTestResult.isContentEditable()) {
848 FrameLoader* loader = frame->loader();
849 KURL linkURL = m_hitTestResult.absoluteLinkURL();
850 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
851 if (m_hitTestResult.isSelected() || frame->selection()->isRange())
852 appendItem(SelectAllItem, m_contextMenu.get());
854 if (!linkURL.isEmpty()) {
855 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
856 if (m_hitTestResult.isSelected() || frame->selection()->isRange()) {
857 if (selectionContainsPossibleWord(frame))
858 appendItem(SearchWebItem, m_contextMenu.get());
859 appendItem(CopyItem, m_contextMenu.get());
863 #if ENABLE(TIZEN_DOWNLOAD_LINK_FILTER)
864 if (loader->client()->canHandleRequest(ResourceRequest(linkURL)) &&
865 (linkURL.protocolIs("http") || linkURL.protocolIs("https") || linkURL.protocolIs("ftp") || linkURL.protocolIs("ftps"))) {
867 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
869 appendItem(OpenLinkItem, m_contextMenu.get());
870 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
871 appendItem(DownloadFileItem, m_contextMenu.get());
874 if (m_hitTestResult.isSelected())
875 appendItem(CopyItem, m_contextMenu.get());
877 appendItem(CopyLinkItem, m_contextMenu.get());
880 KURL imageURL = m_hitTestResult.absoluteImageURL();
881 if (!imageURL.isEmpty()) {
882 #if ENABLE(TIZEN_WEBKIT2_TEXT_SELECTION)
883 if (m_hitTestResult.isSelected() || frame->selection()->isRange()) {
884 appendItem(CopyItem, m_contextMenu.get());
888 if (!linkURL.isEmpty())
889 appendItem(*separatorItem(), m_contextMenu.get());
891 appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
892 appendItem(DownloadImageItem, m_contextMenu.get());
893 if (imageURL.isLocalFile() || m_hitTestResult.image())
894 appendItem(CopyImageItem, m_contextMenu.get());
895 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
896 appendItem(CopyImageUrlItem, m_contextMenu.get());
900 KURL mediaURL = m_hitTestResult.absoluteMediaURL();
901 if (!mediaURL.isEmpty()) {
902 if (!linkURL.isEmpty() || !imageURL.isEmpty())
903 appendItem(*separatorItem(), m_contextMenu.get());
905 appendItem(MediaPlayPause, m_contextMenu.get());
906 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
907 if (m_hitTestResult.mediaMuted())
908 appendItem(MediaUnMute, m_contextMenu.get());
910 appendItem(MediaMute, m_contextMenu.get());
912 appendItem(MediaMute, m_contextMenu.get());
914 appendItem(ToggleMediaControls, m_contextMenu.get());
915 appendItem(ToggleMediaLoop, m_contextMenu.get());
916 appendItem(EnterVideoFullscreen, m_contextMenu.get());
918 appendItem(*separatorItem(), m_contextMenu.get());
919 appendItem(CopyMediaLinkItem, m_contextMenu.get());
920 appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
923 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_TEXT_SELECTION_MODE)
924 if ((!linkURL.isEmpty() || !imageURL.isEmpty()) && mediaURL.isEmpty())
925 appendItem(TextSelectionModeItem, m_contextMenu.get());
928 #if ENABLE(TIZEN_DRAG_SUPPORT)
929 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty() && !m_hitTestResult.isDragSupport()) {
931 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
933 if (m_hitTestResult.isSelected()) {
934 if (selectionContainsPossibleWord(frame)) {
936 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
937 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
939 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
940 appendItem(SearchSpotlightItem, m_contextMenu.get());
942 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
947 appendItem(SearchWebItem, m_contextMenu.get());
948 appendItem(*separatorItem(), m_contextMenu.get());
951 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
952 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
953 appendItem(*separatorItem(), m_contextMenu.get());
957 appendItem(CopyItem, m_contextMenu.get());
959 appendItem(*separatorItem(), m_contextMenu.get());
961 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
962 createAndAppendSpeechSubMenu(SpeechMenuItem);
963 appendItem(SpeechMenuItem, m_contextMenu.get());
966 #if ENABLE(INSPECTOR)
967 if (!(frame->page() && frame->page()->inspectorController()->hasInspectorFrontendClient())) {
970 // In GTK+ unavailable items are not hidden but insensitive
972 appendItem(BackItem, m_contextMenu.get());
973 appendItem(ForwardItem, m_contextMenu.get());
974 appendItem(StopItem, m_contextMenu.get());
975 appendItem(ReloadItem, m_contextMenu.get());
977 #if !ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
978 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(-1))
979 appendItem(BackItem, m_contextMenu.get());
981 if (frame->page() && frame->page()->backForward()->canGoBackOrForward(1))
982 appendItem(ForwardItem, m_contextMenu.get());
984 // use isLoadingInAPISense rather than isLoading because Stop/Reload are
985 // intended to match WebKit's API, not WebCore's internal notion of loading status
986 if (loader->documentLoader()->isLoadingInAPISense())
987 appendItem(StopItem, m_contextMenu.get());
989 appendItem(ReloadItem, m_contextMenu.get());
992 #if ENABLE(INSPECTOR)
996 if (frame->page() && frame != frame->page()->mainFrame())
997 appendItem(OpenFrameItem, m_contextMenu.get());
1000 #if ENABLE(TIZEN_DRAG_SUPPORT)
1001 if (frame->page() && m_hitTestResult.isDragSupport()) {
1002 TIZEN_LOGI("appendItem for drag");
1003 appendItem(DragItem, m_contextMenu.get());
1006 } else { // Make an editing context menu
1007 FrameSelection* selection = frame->selection();
1008 bool inPasswordField = selection->isInPasswordField();
1009 if (!inPasswordField) {
1010 bool haveContextMenuItemsForMisspellingOrGrammer = false;
1011 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledFor(node);
1012 if (spellCheckingEnabled) {
1013 // Consider adding spelling-related or grammar-related context menu items (never both, since a single selected range
1014 // is never considered a misspelling and bad grammar at the same time)
1015 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1016 bool misspelling = false;
1017 bool badGrammar = false;
1022 Vector<String> guesses = frame->editor()->guessesForMisspelledOrUngrammaticalSelection(misspelling, badGrammar);
1023 if (misspelling || badGrammar) {
1024 size_t size = guesses.size();
1026 // If there's bad grammar but no suggestions (e.g., repeated word), just leave off the suggestions
1027 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
1029 appendItem(NoGuessesItem, m_contextMenu.get());
1030 appendItem(*separatorItem(), m_contextMenu.get());
1033 for (unsigned i = 0; i < size; i++) {
1034 const String &guess = guesses[i];
1035 if (!guess.isEmpty()) {
1036 ContextMenuItem item(ActionType, ContextMenuItemTagSpellingGuess, guess);
1037 appendItem(item, m_contextMenu.get());
1040 appendItem(*separatorItem(), m_contextMenu.get());
1043 appendItem(IgnoreSpellingItem, m_contextMenu.get());
1044 appendItem(LearnSpellingItem, m_contextMenu.get());
1046 appendItem(IgnoreGrammarItem, m_contextMenu.get());
1047 appendItem(*separatorItem(), m_contextMenu.get());
1048 haveContextMenuItemsForMisspellingOrGrammer = true;
1049 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
1051 // If the string was autocorrected, generate a contextual menu item allowing it to be changed back.
1052 String replacedString = m_hitTestResult.replacedString();
1053 if (!replacedString.isEmpty()) {
1054 ContextMenuItem item(ActionType, ContextMenuItemTagChangeBack, contextMenuItemTagChangeBack(replacedString));
1055 appendItem(item, m_contextMenu.get());
1056 appendItem(*separatorItem(), m_contextMenu.get());
1057 haveContextMenuItemsForMisspellingOrGrammer = true;
1063 if (!haveContextMenuItemsForMisspellingOrGrammer) {
1064 // Spelling and grammar checking is mutually exclusive with dictation alternatives.
1065 Vector<String> dictationAlternatives = m_hitTestResult.dictationAlternatives();
1066 if (!dictationAlternatives.isEmpty()) {
1067 for (size_t i = 0; i < dictationAlternatives.size(); ++i) {
1068 ContextMenuItem item(ActionType, ContextMenuItemTagDictationAlternative, dictationAlternatives[i]);
1069 appendItem(item, m_contextMenu.get());
1071 appendItem(*separatorItem(), m_contextMenu.get());
1076 FrameLoader* loader = frame->loader();
1077 KURL linkURL = m_hitTestResult.absoluteLinkURL();
1078 if (!linkURL.isEmpty()) {
1079 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
1080 appendItem(OpenLinkItem, m_contextMenu.get());
1081 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
1082 appendItem(DownloadFileItem, m_contextMenu.get());
1084 appendItem(CopyLinkItem, m_contextMenu.get());
1085 appendItem(*separatorItem(), m_contextMenu.get());
1088 if (m_hitTestResult.isSelected() && !inPasswordField && selectionContainsPossibleWord(frame)) {
1090 String selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
1091 ContextMenuItem LookUpInDictionaryItem(ActionType, ContextMenuItemTagLookUpInDictionary, contextMenuItemTagLookUpInDictionary(selectedString));
1093 #if INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
1094 appendItem(SearchSpotlightItem, m_contextMenu.get());
1096 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
1101 appendItem(SearchWebItem, m_contextMenu.get());
1102 appendItem(*separatorItem(), m_contextMenu.get());
1105 #if PLATFORM(MAC) && INCLUDE_SPOTLIGHT_CONTEXT_MENU_ITEM
1106 appendItem(LookUpInDictionaryItem, m_contextMenu.get());
1107 appendItem(*separatorItem(), m_contextMenu.get());
1111 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1112 bool isInputPickerType = false;
1113 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
1114 HTMLInputElement* inputElement = node->toInputElement();
1116 (inputElement->isDateField() || inputElement->isDateTimeField() || inputElement->isDateTimeLocalField()
1117 || inputElement->isMonthField() || inputElement->isTimeField() || inputElement->isWeekField()))
1118 isInputPickerType = true;
1120 if (m_hitTestResult.isSelected() && !inPasswordField) {
1121 if (!isInputPickerType)
1122 appendItem(CutItem, m_contextMenu.get());
1123 appendItem(CopyItem, m_contextMenu.get());
1125 if (!isInputPickerType) {
1126 appendItem(PasteItem, m_contextMenu.get());
1127 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
1128 appendItem(ClipboardItem, m_contextMenu.get());
1132 appendItem(CutItem, m_contextMenu.get());
1133 appendItem(CopyItem, m_contextMenu.get());
1134 appendItem(PasteItem, m_contextMenu.get());
1137 appendItem(DeleteItem, m_contextMenu.get());
1138 appendItem(*separatorItem(), m_contextMenu.get());
1140 #if ENABLE(TIZEN_CONTEXT_MENU_WEBKIT_2)
1141 if (frame->selection()) {
1142 Node* baseNode = frame->selection()->base().containerNode();
1143 if (inPasswordField) {
1144 if (baseNode && baseNode->isTextNode() && !(baseNode->textContent().isEmpty()) && !m_hitTestResult.isSelected())
1145 appendItem(SelectWordItem, m_contextMenu.get());
1147 VisiblePosition currentPosition = frame->selection()->selection().visibleStart();
1148 VisiblePosition startPosition = startOfEditableContent(currentPosition);
1149 VisiblePosition endPosition = endOfEditableContent(currentPosition);
1150 if (comparePositions(startPosition, endPosition))
1151 appendItem(SelectAllItem, m_contextMenu.get());
1152 if (baseNode && baseNode->isTextNode() && !(baseNode->textContent().isEmpty()))
1153 appendItem(SelectWordItem, m_contextMenu.get());
1157 #if PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
1158 appendItem(SelectAllItem, m_contextMenu.get());
1162 if (!inPasswordField) {
1164 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1165 appendItem(*separatorItem(), m_contextMenu.get());
1166 ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuItemTagSpellingMenu,
1167 contextMenuItemTagSpellingMenu());
1168 createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem);
1169 appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
1170 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1173 ContextMenuItem substitutionsMenuItem(SubmenuType, ContextMenuItemTagSubstitutionsMenu,
1174 contextMenuItemTagSubstitutionsMenu());
1175 createAndAppendSubstitutionsSubMenu(substitutionsMenuItem);
1176 appendItem(substitutionsMenuItem, m_contextMenu.get());
1177 ContextMenuItem transformationsMenuItem(SubmenuType, ContextMenuItemTagTransformationsMenu,
1178 contextMenuItemTagTransformationsMenu());
1179 createAndAppendTransformationsSubMenu(transformationsMenuItem);
1180 appendItem(transformationsMenuItem, m_contextMenu.get());
1183 bool shouldShowFontMenu = frame->editor()->canEditRichly();
1185 #if ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1186 bool shouldShowFontMenu = false;
1188 bool shouldShowFontMenu = true;
1189 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1191 if (shouldShowFontMenu) {
1192 ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFontMenu,
1193 contextMenuItemTagFontMenu());
1194 createAndAppendFontSubMenu(FontMenuItem);
1195 appendItem(FontMenuItem, m_contextMenu.get());
1198 ContextMenuItem SpeechMenuItem(SubmenuType, ContextMenuItemTagSpeechMenu, contextMenuItemTagSpeechMenu());
1199 createAndAppendSpeechSubMenu(SpeechMenuItem);
1200 appendItem(SpeechMenuItem, m_contextMenu.get());
1203 EditorClient* client = frame->editor()->client();
1204 if (client && client->shouldShowUnicodeMenu()) {
1205 ContextMenuItem UnicodeMenuItem(SubmenuType, ContextMenuItemTagUnicode, contextMenuItemTagUnicode());
1206 createAndAppendUnicodeSubMenu(UnicodeMenuItem);
1207 appendItem(*separatorItem(), m_contextMenu.get());
1208 appendItem(UnicodeMenuItem, m_contextMenu.get());
1211 ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuItemTagWritingDirectionMenu,
1212 contextMenuItemTagWritingDirectionMenu());
1213 #if !ENABLE(TIZEN_CONTEXT_MENU_TEMPORARY_FIX)
1214 createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem);
1215 appendItem(WritingDirectionMenuItem, m_contextMenu.get());
1216 if (Page* page = frame->page()) {
1217 if (Settings* settings = page->settings()) {
1218 bool includeTextDirectionSubmenu = settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
1219 || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection());
1220 if (includeTextDirectionSubmenu) {
1221 ContextMenuItem TextDirectionMenuItem(SubmenuType, ContextMenuItemTagTextDirectionMenu,
1222 contextMenuItemTagTextDirectionMenu());
1223 createAndAppendTextDirectionSubMenu(TextDirectionMenuItem);
1224 appendItem(TextDirectionMenuItem, m_contextMenu.get());
1228 #endif //TIZEN_CONTEXT_MENU_TEMPORARY_FIX
1234 #if ENABLE(INSPECTOR)
1235 void ContextMenuController::addInspectElementItem()
1237 Node* node = m_hitTestResult.innerNonSharedNode();
1241 Frame* frame = node->document()->frame();
1245 Page* page = frame->page();
1249 if (!page->inspectorController())
1252 ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElement, contextMenuItemTagInspectElement());
1253 #if USE(CROSS_PLATFORM_CONTEXT_MENUS)
1254 if (!m_contextMenu->items().isEmpty())
1256 if (m_contextMenu->itemCount())
1258 appendItem(*separatorItem(), m_contextMenu.get());
1259 appendItem(InspectElementItem, m_contextMenu.get());
1261 #endif // ENABLE(INSPECTOR)
1263 void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
1265 if (item.type() == SeparatorType)
1268 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
1272 // Custom items already have proper checked and enabled values.
1273 if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= ContextMenuItemLastCustomTag)
1276 bool shouldEnable = true;
1277 bool shouldCheck = false;
1279 switch (item.action()) {
1280 case ContextMenuItemTagCheckSpelling:
1281 shouldEnable = frame->editor()->canEdit();
1283 case ContextMenuItemTagDefaultDirection:
1284 shouldCheck = false;
1285 shouldEnable = false;
1287 case ContextMenuItemTagLeftToRight:
1288 case ContextMenuItemTagRightToLeft: {
1289 String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
1290 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirection, direction) != FalseTriState;
1291 shouldEnable = true;
1294 case ContextMenuItemTagTextDirectionDefault: {
1295 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionNatural");
1296 shouldCheck = command.state() == TrueTriState;
1297 shouldEnable = command.isEnabled();
1300 case ContextMenuItemTagTextDirectionLeftToRight: {
1301 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionLeftToRight");
1302 shouldCheck = command.state() == TrueTriState;
1303 shouldEnable = command.isEnabled();
1306 case ContextMenuItemTagTextDirectionRightToLeft: {
1307 Editor::Command command = frame->editor()->command("MakeTextWritingDirectionRightToLeft");
1308 shouldCheck = command.state() == TrueTriState;
1309 shouldEnable = command.isEnabled();
1312 case ContextMenuItemTagCopy:
1313 shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->canCopy();
1315 case ContextMenuItemTagCut:
1316 shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->canCut();
1318 case ContextMenuItemTagIgnoreSpelling:
1319 case ContextMenuItemTagLearnSpelling:
1320 shouldEnable = frame->selection()->isRange();
1322 case ContextMenuItemTagPaste:
1323 shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()->canPaste();
1325 #if ENABLE(TIZEN_CONTEXT_MENU_SELECT)
1326 case ContextMenuItemTagSelectWord:
1327 shouldEnable = frame->editor()->canSelectRange();
1331 case ContextMenuItemTagDelete:
1332 shouldEnable = frame->editor()->canDelete();
1334 case ContextMenuItemTagInputMethods:
1335 case ContextMenuItemTagUnicode:
1336 case ContextMenuItemTagUnicodeInsertLRMMark:
1337 case ContextMenuItemTagUnicodeInsertRLMMark:
1338 case ContextMenuItemTagUnicodeInsertLREMark:
1339 case ContextMenuItemTagUnicodeInsertRLEMark:
1340 case ContextMenuItemTagUnicodeInsertLROMark:
1341 case ContextMenuItemTagUnicodeInsertRLOMark:
1342 case ContextMenuItemTagUnicodeInsertPDFMark:
1343 case ContextMenuItemTagUnicodeInsertZWSMark:
1344 case ContextMenuItemTagUnicodeInsertZWJMark:
1345 case ContextMenuItemTagUnicodeInsertZWNJMark:
1346 shouldEnable = true;
1349 #if PLATFORM(GTK) || PLATFORM(EFL)
1350 case ContextMenuItemTagSelectAll:
1351 shouldEnable = true;
1354 case ContextMenuItemTagUnderline: {
1355 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline") != FalseTriState;
1356 shouldEnable = frame->editor()->canEditRichly();
1359 case ContextMenuItemTagLookUpInDictionary:
1360 shouldEnable = frame->selection()->isRange();
1362 case ContextMenuItemTagCheckGrammarWithSpelling:
1363 if (frame->editor()->isGrammarCheckingEnabled())
1365 shouldEnable = true;
1367 case ContextMenuItemTagItalic: {
1368 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyle, "italic") != FalseTriState;
1369 shouldEnable = frame->editor()->canEditRichly();
1372 case ContextMenuItemTagBold: {
1373 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeight, "bold") != FalseTriState;
1374 shouldEnable = frame->editor()->canEditRichly();
1377 case ContextMenuItemTagOutline:
1378 shouldEnable = false;
1380 case ContextMenuItemTagShowSpellingPanel:
1381 if (frame->editor()->spellingPanelIsShowing())
1382 item.setTitle(contextMenuItemTagShowSpellingPanel(false));
1384 item.setTitle(contextMenuItemTagShowSpellingPanel(true));
1385 shouldEnable = frame->editor()->canEdit();
1387 case ContextMenuItemTagNoGuessesFound:
1388 shouldEnable = false;
1390 case ContextMenuItemTagCheckSpellingWhileTyping:
1391 shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
1394 case ContextMenuItemTagSubstitutionsMenu:
1395 case ContextMenuItemTagTransformationsMenu:
1397 case ContextMenuItemTagShowSubstitutions:
1398 if (frame->editor()->substitutionsPanelIsShowing())
1399 item.setTitle(contextMenuItemTagShowSubstitutions(false));
1401 item.setTitle(contextMenuItemTagShowSubstitutions(true));
1402 shouldEnable = frame->editor()->canEdit();
1404 case ContextMenuItemTagMakeUpperCase:
1405 case ContextMenuItemTagMakeLowerCase:
1406 case ContextMenuItemTagCapitalize:
1407 case ContextMenuItemTagChangeBack:
1408 shouldEnable = frame->editor()->canEdit();
1410 case ContextMenuItemTagCorrectSpellingAutomatically:
1411 shouldCheck = frame->editor()->isAutomaticSpellingCorrectionEnabled();
1413 case ContextMenuItemTagSmartCopyPaste:
1414 shouldCheck = frame->editor()->smartInsertDeleteEnabled();
1416 case ContextMenuItemTagSmartQuotes:
1417 shouldCheck = frame->editor()->isAutomaticQuoteSubstitutionEnabled();
1419 case ContextMenuItemTagSmartDashes:
1420 shouldCheck = frame->editor()->isAutomaticDashSubstitutionEnabled();
1422 case ContextMenuItemTagSmartLinks:
1423 shouldCheck = frame->editor()->isAutomaticLinkDetectionEnabled();
1425 case ContextMenuItemTagTextReplacement:
1426 shouldCheck = frame->editor()->isAutomaticTextReplacementEnabled();
1428 case ContextMenuItemTagStopSpeaking:
1429 shouldEnable = client() && client()->isSpeaking();
1431 #else // PLATFORM(MAC) ends here
1432 case ContextMenuItemTagStopSpeaking:
1436 case ContextMenuItemTagGoBack:
1437 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(-1);
1439 case ContextMenuItemTagGoForward:
1440 shouldEnable = frame->page() && frame->page()->backForward()->canGoBackOrForward(1);
1442 case ContextMenuItemTagStop:
1443 shouldEnable = frame->loader()->documentLoader()->isLoadingInAPISense();
1445 case ContextMenuItemTagReload:
1446 shouldEnable = !frame->loader()->documentLoader()->isLoadingInAPISense();
1448 case ContextMenuItemTagFontMenu:
1449 shouldEnable = frame->editor()->canEditRichly();
1452 case ContextMenuItemTagGoBack:
1453 case ContextMenuItemTagGoForward:
1454 case ContextMenuItemTagStop:
1455 case ContextMenuItemTagReload:
1456 case ContextMenuItemTagFontMenu:
1458 case ContextMenuItemTagNoAction:
1459 case ContextMenuItemTagOpenLinkInNewWindow:
1460 case ContextMenuItemTagDownloadLinkToDisk:
1461 case ContextMenuItemTagCopyLinkToClipboard:
1462 case ContextMenuItemTagOpenImageInNewWindow:
1463 case ContextMenuItemTagDownloadImageToDisk:
1464 case ContextMenuItemTagCopyImageToClipboard:
1465 #if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
1466 case ContextMenuItemTagCopyImageUrlToClipboard:
1469 case ContextMenuItemTagOpenMediaInNewWindow:
1470 if (m_hitTestResult.mediaIsVideo())
1471 item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
1473 item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
1475 case ContextMenuItemTagCopyMediaLinkToClipboard:
1476 if (m_hitTestResult.mediaIsVideo())
1477 item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
1479 item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
1481 case ContextMenuItemTagToggleMediaControls:
1482 shouldCheck = m_hitTestResult.mediaControlsEnabled();
1484 case ContextMenuItemTagToggleMediaLoop:
1485 shouldCheck = m_hitTestResult.mediaLoopEnabled();
1487 case ContextMenuItemTagEnterVideoFullscreen:
1488 shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
1490 case ContextMenuItemTagOpenFrameInNewWindow:
1491 case ContextMenuItemTagSpellingGuess:
1492 case ContextMenuItemTagOther:
1493 case ContextMenuItemTagSearchInSpotlight:
1494 case ContextMenuItemTagSearchWeb:
1495 case ContextMenuItemTagOpenWithDefaultApplication:
1496 case ContextMenuItemPDFActualSize:
1497 case ContextMenuItemPDFZoomIn:
1498 case ContextMenuItemPDFZoomOut:
1499 case ContextMenuItemPDFAutoSize:
1500 case ContextMenuItemPDFSinglePage:
1501 case ContextMenuItemPDFFacingPages:
1502 case ContextMenuItemPDFContinuous:
1503 case ContextMenuItemPDFNextPage:
1504 case ContextMenuItemPDFPreviousPage:
1505 case ContextMenuItemTagOpenLink:
1506 case ContextMenuItemTagIgnoreGrammar:
1507 case ContextMenuItemTagSpellingMenu:
1508 case ContextMenuItemTagShowFonts:
1509 case ContextMenuItemTagStyles:
1510 case ContextMenuItemTagShowColors:
1511 case ContextMenuItemTagSpeechMenu:
1512 case ContextMenuItemTagStartSpeaking:
1513 case ContextMenuItemTagWritingDirectionMenu:
1514 case ContextMenuItemTagTextDirectionMenu:
1515 case ContextMenuItemTagPDFSinglePageScrolling:
1516 case ContextMenuItemTagPDFFacingPagesScrolling:
1517 #if ENABLE(INSPECTOR)
1518 case ContextMenuItemTagInspectElement:
1520 #if ENABLE(TIZEN_DRAG_SUPPORT)
1521 case ContextMenuItemTagDrag:
1523 case ContextMenuItemBaseCustomTag:
1524 case ContextMenuItemCustomTagNoAction:
1525 case ContextMenuItemLastCustomTag:
1526 case ContextMenuItemBaseApplicationTag:
1527 case ContextMenuItemTagDictationAlternative:
1529 case ContextMenuItemTagMediaPlayPause:
1530 if (m_hitTestResult.mediaPlaying())
1531 item.setTitle(contextMenuItemTagMediaPause());
1533 item.setTitle(contextMenuItemTagMediaPlay());
1535 case ContextMenuItemTagMediaMute:
1536 shouldEnable = m_hitTestResult.mediaHasAudio();
1537 shouldCheck = shouldEnable && m_hitTestResult.mediaMuted();
1539 #if ENABLE(TIZEN_DAILY_UPVERSIONING)
1545 item.setChecked(shouldCheck);
1546 item.setEnabled(shouldEnable);
1549 #if USE(ACCESSIBILITY_CONTEXT_MENUS)
1550 void ContextMenuController::showContextMenuAt(Frame* frame, const IntPoint& clickPoint)
1552 // Simulate a click in the middle of the accessibility object.
1553 PlatformMouseEvent mouseEvent(clickPoint, clickPoint, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
1554 bool handled = frame->eventHandler()->sendContextMenuEvent(mouseEvent);
1555 if (handled && client())
1556 client()->showContextMenu();
1560 } // namespace WebCore
1562 #endif // ENABLE(CONTEXT_MENUS)