Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: Source/core/page/ContextMenuController.cpp

Issue 14795011: Remove dead ContextMenu code from Blink core (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/page/ContextMenuController.h ('k') | Source/core/platform/ContextMenu.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Igalia S.L 3 * Copyright (C) 2010 Igalia S.L
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 10 matching lines...) Expand all
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "config.h" 27 #include "config.h"
28 #include "core/page/ContextMenuController.h" 28 #include "core/page/ContextMenuController.h"
29 29
30 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
31 #include "core/dom/DocumentFragment.h"
32 #include "core/dom/Event.h" 31 #include "core/dom/Event.h"
33 #include "core/dom/EventNames.h" 32 #include "core/dom/EventNames.h"
34 #include "core/dom/ExceptionCodePlaceholder.h"
35 #include "core/dom/MouseEvent.h" 33 #include "core/dom/MouseEvent.h"
36 #include "core/dom/Node.h" 34 #include "core/dom/Node.h"
37 #include "core/dom/UserTypingGestureIndicator.h"
38 #include "core/editing/Editor.h"
39 #include "core/editing/FrameSelection.h" 35 #include "core/editing/FrameSelection.h"
40 #include "core/editing/ReplaceSelectionCommand.h"
41 #include "core/editing/TextIterator.h"
42 #include "core/editing/TypingCommand.h"
43 #include "core/editing/markup.h"
44 #include "core/history/BackForwardController.h"
45 #include "core/html/HTMLFormElement.h"
46 #include "core/inspector/InspectorController.h"
47 #include "core/loader/DocumentLoader.h"
48 #include "core/loader/FormState.h"
49 #include "core/loader/FrameLoadRequest.h"
50 #include "core/loader/FrameLoader.h"
51 #include "core/loader/FrameLoaderClient.h"
52 #include "core/loader/NavigationAction.h"
53 #include "core/page/Chrome.h"
54 #include "core/page/ContextMenuClient.h" 36 #include "core/page/ContextMenuClient.h"
55 #include "core/page/ContextMenuProvider.h" 37 #include "core/page/ContextMenuProvider.h"
56 #include "core/page/EditorClient.h"
57 #include "core/page/EventHandler.h" 38 #include "core/page/EventHandler.h"
58 #include "core/page/Frame.h" 39 #include "core/page/Frame.h"
59 #include "core/page/Page.h" 40 #include "core/page/Page.h"
60 #include "core/page/Settings.h"
61 #include "core/page/WindowFeatures.h"
62 #include "core/platform/ContextMenu.h" 41 #include "core/platform/ContextMenu.h"
63 #include "core/platform/ContextMenuItem.h" 42 #include "core/platform/ContextMenuItem.h"
64 #include "core/platform/LocalizedStrings.h"
65 #include "core/platform/PlatformEvent.h"
66 #include "core/platform/network/ResourceRequest.h"
67 #include "core/rendering/HitTestRequest.h"
68 #include "core/rendering/HitTestResult.h" 43 #include "core/rendering/HitTestResult.h"
69 #include "core/rendering/RenderObject.h"
70 #include <wtf/unicode/CharacterNames.h>
71 #include <wtf/unicode/Unicode.h>
72
73 using namespace WTF;
74 using namespace Unicode;
75 44
76 namespace WebCore { 45 namespace WebCore {
77 46
78 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie nt) 47 ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie nt)
79 : m_page(page) 48 : m_page(page)
80 , m_client(client) 49 , m_client(client)
81 { 50 {
82 ASSERT_ARG(page, page); 51 ASSERT_ARG(page, page);
83 ASSERT_ARG(client, client); 52 ASSERT_ARG(client, client);
84 } 53 }
(...skipping 14 matching lines...) Expand all
99 m_menuProvider->contextMenuCleared(); 68 m_menuProvider->contextMenuCleared();
100 m_menuProvider = 0; 69 m_menuProvider = 0;
101 } 70 }
102 71
103 void ContextMenuController::handleContextMenuEvent(Event* event) 72 void ContextMenuController::handleContextMenuEvent(Event* event)
104 { 73 {
105 m_contextMenu = createContextMenu(event); 74 m_contextMenu = createContextMenu(event);
106 if (!m_contextMenu) 75 if (!m_contextMenu)
107 return; 76 return;
108 77
109 populate();
110
111 showContextMenu(event); 78 showContextMenu(event);
112 } 79 }
113 80
114 static PassOwnPtr<ContextMenuItem> separatorItem()
115 {
116 return adoptPtr(new ContextMenuItem(SeparatorType, ContextMenuItemTagNoActio n, String()));
117 }
118
119 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenu Provider> menuProvider) 81 void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenu Provider> menuProvider)
120 { 82 {
121 m_menuProvider = menuProvider; 83 m_menuProvider = menuProvider;
122 84
123 m_contextMenu = createContextMenu(event); 85 m_contextMenu = createContextMenu(event);
124 if (!m_contextMenu) { 86 if (!m_contextMenu) {
125 clearContextMenu(); 87 clearContextMenu();
126 return; 88 return;
127 } 89 }
128 90
129 m_menuProvider->populateContextMenu(m_contextMenu.get()); 91 m_menuProvider->populateContextMenu(m_contextMenu.get());
130 if (m_hitTestResult.isSelected()) {
131 appendItem(*separatorItem(), m_contextMenu.get());
132 populate();
133 }
134 showContextMenu(event); 92 showContextMenu(event);
135 } 93 }
136 94
137 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event) 95 PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
138 { 96 {
139 ASSERT(event); 97 ASSERT(event);
140 98
141 if (!event->isMouseEvent()) 99 if (!event->isMouseEvent())
142 return nullptr; 100 return nullptr;
143 101
144 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); 102 MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
145 HitTestResult result(mouseEvent->absoluteLocation()); 103 HitTestResult result(mouseEvent->absoluteLocation());
146 104
147 if (Frame* frame = event->target()->toNode()->document()->frame()) 105 if (Frame* frame = event->target()->toNode()->document()->frame())
148 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absolut eLocation()); 106 result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absolut eLocation());
149 107
150 if (!result.innerNonSharedNode()) 108 if (!result.innerNonSharedNode())
151 return nullptr; 109 return nullptr;
152 110
153 m_hitTestResult = result; 111 m_hitTestResult = result;
154 112
155 return adoptPtr(new ContextMenu); 113 return adoptPtr(new ContextMenu);
156 } 114 }
157 115
158 void ContextMenuController::showContextMenu(Event* event) 116 void ContextMenuController::showContextMenu(Event* event)
159 { 117 {
160 addInspectElementItem(); 118 m_client->showContextMenu(m_contextMenu.get());
161
162 m_contextMenu = m_client->customizeMenu(m_contextMenu.release());
163 event->setDefaultHandled(); 119 event->setDefaultHandled();
164 } 120 }
165 121
166 static void openNewWindow(const KURL& urlToLoad, Frame* frame)
167 {
168 if (Page* oldPage = frame->page()) {
169 FrameLoadRequest request(frame->document()->securityOrigin(), ResourceRe quest(urlToLoad, frame->loader()->outgoingReferrer()));
170 Page* newPage = oldPage;
171 if (!frame->settings() || frame->settings()->supportsMultipleWindows()) {
172 newPage = oldPage->chrome()->createWindow(frame, request, WindowFeat ures(), NavigationAction(request.resourceRequest()));
173 if (!newPage)
174 return;
175 newPage->chrome()->show();
176 }
177 newPage->mainFrame()->loader()->loadFrameRequest(request, false, 0, 0, M aybeSendReferrer);
178 }
179 }
180
181 void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item) 122 void ContextMenuController::contextMenuItemSelected(const ContextMenuItem* item)
182 { 123 {
183 ASSERT(item->type() == ActionType || item->type() == CheckableActionType); 124 ASSERT(item->type() == ActionType || item->type() == CheckableActionType);
184 125
185 if (item->action() >= ContextMenuItemBaseApplicationTag) 126 if (item->action() < ContextMenuItemBaseCustomTag || item->action() > Contex tMenuItemLastCustomTag)
186 return; 127 return;
187 128
188 if (item->action() >= ContextMenuItemBaseCustomTag) { 129 ASSERT(m_menuProvider);
189 ASSERT(m_menuProvider); 130 m_menuProvider->contextMenuItemSelected(item);
190 m_menuProvider->contextMenuItemSelected(item);
191 return;
192 }
193
194 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
195 if (!frame)
196 return;
197
198 switch (item->action()) {
199 case ContextMenuItemTagOpenLinkInNewWindow:
200 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
201 break;
202 case ContextMenuItemTagDownloadLinkToDisk:
203 break;
204 case ContextMenuItemTagCopyLinkToClipboard:
205 frame->editor()->copyURL(m_hitTestResult.absoluteLinkURL(), m_hitTestRes ult.textContent());
206 break;
207 case ContextMenuItemTagOpenImageInNewWindow:
208 openNewWindow(m_hitTestResult.absoluteImageURL(), frame);
209 break;
210 case ContextMenuItemTagDownloadImageToDisk:
211 break;
212 case ContextMenuItemTagCopyImageToClipboard:
213 // FIXME: The Pasteboard class is not written yet
214 // For now, call into the client. This is temporary!
215 frame->editor()->copyImage(m_hitTestResult);
216 break;
217 case ContextMenuItemTagOpenMediaInNewWindow:
218 openNewWindow(m_hitTestResult.absoluteMediaURL(), frame);
219 break;
220 case ContextMenuItemTagCopyMediaLinkToClipboard:
221 frame->editor()->copyURL(m_hitTestResult.absoluteMediaURL(), m_hitTestRe sult.textContent());
222 break;
223 case ContextMenuItemTagToggleMediaControls:
224 m_hitTestResult.toggleMediaControlsDisplay();
225 break;
226 case ContextMenuItemTagToggleMediaLoop:
227 m_hitTestResult.toggleMediaLoopPlayback();
228 break;
229 case ContextMenuItemTagEnterVideoFullscreen:
230 m_hitTestResult.enterFullscreenForVideo();
231 break;
232 case ContextMenuItemTagMediaPlayPause:
233 m_hitTestResult.toggleMediaPlayState();
234 break;
235 case ContextMenuItemTagMediaMute:
236 m_hitTestResult.toggleMediaMuteState();
237 break;
238 case ContextMenuItemTagOpenFrameInNewWindow: {
239 DocumentLoader* loader = frame->loader()->documentLoader();
240 if (!loader->unreachableURL().isEmpty())
241 openNewWindow(loader->unreachableURL(), frame);
242 else
243 openNewWindow(loader->url(), frame);
244 break;
245 }
246 case ContextMenuItemTagCopy:
247 frame->editor()->copy();
248 break;
249 case ContextMenuItemTagGoBack:
250 if (Page* page = frame->page())
251 page->backForward()->goBackOrForward(-1);
252 break;
253 case ContextMenuItemTagGoForward:
254 if (Page* page = frame->page())
255 page->backForward()->goBackOrForward(1);
256 break;
257 case ContextMenuItemTagStop:
258 frame->loader()->stop();
259 break;
260 case ContextMenuItemTagReload:
261 frame->loader()->reload();
262 break;
263 case ContextMenuItemTagCut:
264 frame->editor()->command("Cut").execute();
265 break;
266 case ContextMenuItemTagPaste:
267 frame->editor()->command("Paste").execute();
268 break;
269 case ContextMenuItemTagSpellingGuess: {
270 FrameSelection* frameSelection = frame->selection();
271 if (frame->editor()->shouldInsertText(item->title(), frameSelection->toN ormalizedRange().get(), EditorInsertActionPasted)) {
272 Document* document = frame->document();
273 ReplaceSelectionCommand::CommandOptions replaceOptions = ReplaceSele ctionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting | ReplaceSele ctionCommand::SelectReplacement;
274 ASSERT(frame->editor()->selectedText().length());
275 RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::c reate(document, createFragmentFromMarkup(document, item->title(), ""), replaceOp tions);
276 applyCommand(command);
277 frameSelection->revealSelection(ScrollAlignment::alignToEdgeIfNeeded );
278 }
279 break;
280 }
281 case ContextMenuItemTagIgnoreSpelling:
282 frame->editor()->ignoreSpelling();
283 break;
284 case ContextMenuItemTagLearnSpelling:
285 frame->editor()->learnSpelling();
286 break;
287 case ContextMenuItemTagSearchWeb:
288 break;
289 case ContextMenuItemTagLookUpInDictionary:
290 break;
291 case ContextMenuItemTagOpenLink:
292 if (Frame* targetFrame = m_hitTestResult.targetFrame())
293 targetFrame->loader()->loadFrameRequest(FrameLoadRequest(frame->docu ment()->securityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), fra me->loader()->outgoingReferrer())), false, 0, 0, MaybeSendReferrer);
294 else
295 openNewWindow(m_hitTestResult.absoluteLinkURL(), frame);
296 break;
297 case ContextMenuItemTagOpenLinkInThisWindow:
298 frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->se curityOrigin(), ResourceRequest(m_hitTestResult.absoluteLinkURL(), frame->loader ()->outgoingReferrer())), false, 0, 0, MaybeSendReferrer);
299 break;
300 case ContextMenuItemTagBold:
301 frame->editor()->command("ToggleBold").execute();
302 break;
303 case ContextMenuItemTagItalic:
304 frame->editor()->command("ToggleItalic").execute();
305 break;
306 case ContextMenuItemTagUnderline:
307 frame->editor()->toggleUnderline();
308 break;
309 case ContextMenuItemTagOutline:
310 // We actually never enable this because CSS does not have a way to spec ify an outline font,
311 // which may make this difficult to implement. Maybe a special case of t ext-shadow?
312 break;
313 case ContextMenuItemTagStartSpeaking:
314 break;
315 case ContextMenuItemTagStopSpeaking:
316 break;
317 case ContextMenuItemTagDefaultDirection:
318 frame->editor()->setBaseWritingDirection(NaturalWritingDirection);
319 break;
320 case ContextMenuItemTagLeftToRight:
321 frame->editor()->setBaseWritingDirection(LeftToRightWritingDirection);
322 break;
323 case ContextMenuItemTagRightToLeft:
324 frame->editor()->setBaseWritingDirection(RightToLeftWritingDirection);
325 break;
326 case ContextMenuItemTagTextDirectionDefault:
327 frame->editor()->command("MakeTextWritingDirectionNatural").execute();
328 break;
329 case ContextMenuItemTagTextDirectionLeftToRight:
330 frame->editor()->command("MakeTextWritingDirectionLeftToRight").execute( );
331 break;
332 case ContextMenuItemTagTextDirectionRightToLeft:
333 frame->editor()->command("MakeTextWritingDirectionRightToLeft").execute( );
334 break;
335 case ContextMenuItemTagShowSpellingPanel:
336 frame->editor()->showSpellingGuessPanel();
337 break;
338 case ContextMenuItemTagCheckSpelling:
339 frame->editor()->advanceToNextMisspelling();
340 break;
341 case ContextMenuItemTagCheckSpellingWhileTyping:
342 frame->editor()->toggleContinuousSpellChecking();
343 break;
344 case ContextMenuItemTagCheckGrammarWithSpelling:
345 break;
346 case ContextMenuItemTagInspectElement:
347 if (Page* page = frame->page())
348 page->inspectorController()->inspect(m_hitTestResult.innerNonSharedN ode());
349 break;
350 default:
351 break;
352 }
353 }
354
355 void ContextMenuController::appendItem(ContextMenuItem& menuItem, ContextMenu* p arentMenu)
356 {
357 checkOrEnableIfNeeded(menuItem);
358 if (parentMenu)
359 parentMenu->appendItem(menuItem);
360 }
361
362 void ContextMenuController::createAndAppendFontSubMenu(ContextMenuItem& fontMenu Item)
363 {
364 ContextMenu fontMenu;
365
366 ContextMenuItem bold(CheckableActionType, ContextMenuItemTagBold, contextMen uItemTagBold());
367 ContextMenuItem italic(CheckableActionType, ContextMenuItemTagItalic, contex tMenuItemTagItalic());
368 ContextMenuItem underline(CheckableActionType, ContextMenuItemTagUnderline, contextMenuItemTagUnderline());
369 ContextMenuItem outline(ActionType, ContextMenuItemTagOutline, contextMenuIt emTagOutline());
370 appendItem(bold, &fontMenu);
371 appendItem(italic, &fontMenu);
372 appendItem(underline, &fontMenu);
373 appendItem(outline, &fontMenu);
374
375 fontMenuItem.setSubMenu(&fontMenu);
376 }
377
378
379 void ContextMenuController::createAndAppendSpellingAndGrammarSubMenu(ContextMenu Item& spellingAndGrammarMenuItem)
380 {
381 ContextMenu spellingAndGrammarMenu;
382
383 ContextMenuItem showSpellingPanel(ActionType, ContextMenuItemTagShowSpelling Panel,
384 contextMenuItemTagShowSpellingPanel(true));
385 ContextMenuItem checkSpelling(ActionType, ContextMenuItemTagCheckSpelling,
386 contextMenuItemTagCheckSpelling());
387 ContextMenuItem checkAsYouType(CheckableActionType, ContextMenuItemTagCheckS pellingWhileTyping,
388 contextMenuItemTagCheckSpellingWhileTyping());
389 ContextMenuItem grammarWithSpelling(CheckableActionType, ContextMenuItemTagC heckGrammarWithSpelling,
390 contextMenuItemTagCheckGrammarWithSpelling());
391
392 appendItem(showSpellingPanel, &spellingAndGrammarMenu);
393 appendItem(checkSpelling, &spellingAndGrammarMenu);
394 appendItem(checkAsYouType, &spellingAndGrammarMenu);
395 appendItem(grammarWithSpelling, &spellingAndGrammarMenu);
396
397 spellingAndGrammarMenuItem.setSubMenu(&spellingAndGrammarMenu);
398 }
399
400 void ContextMenuController::createAndAppendWritingDirectionSubMenu(ContextMenuIt em& writingDirectionMenuItem)
401 {
402 ContextMenu writingDirectionMenu;
403
404 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagDefaultDirection,
405 contextMenuItemTagDefaultDirection());
406 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagLeftToRight, cont extMenuItemTagLeftToRight());
407 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagRightToLeft, cont extMenuItemTagRightToLeft());
408
409 appendItem(defaultItem, &writingDirectionMenu);
410 appendItem(ltr, &writingDirectionMenu);
411 appendItem(rtl, &writingDirectionMenu);
412
413 writingDirectionMenuItem.setSubMenu(&writingDirectionMenu);
414 }
415
416 void ContextMenuController::createAndAppendTextDirectionSubMenu(ContextMenuItem& textDirectionMenuItem)
417 {
418 ContextMenu textDirectionMenu;
419
420 ContextMenuItem defaultItem(ActionType, ContextMenuItemTagTextDirectionDefau lt, contextMenuItemTagDefaultDirection());
421 ContextMenuItem ltr(CheckableActionType, ContextMenuItemTagTextDirectionLeft ToRight, contextMenuItemTagLeftToRight());
422 ContextMenuItem rtl(CheckableActionType, ContextMenuItemTagTextDirectionRigh tToLeft, contextMenuItemTagRightToLeft());
423
424 appendItem(defaultItem, &textDirectionMenu);
425 appendItem(ltr, &textDirectionMenu);
426 appendItem(rtl, &textDirectionMenu);
427
428 textDirectionMenuItem.setSubMenu(&textDirectionMenu);
429 }
430
431 static bool selectionContainsPossibleWord(Frame* frame)
432 {
433 // Current algorithm: look for a character that's not just a separator.
434 for (TextIterator it(frame->selection()->toNormalizedRange().get()); !it.atE nd(); it.advance()) {
435 int length = it.length();
436 for (int i = 0; i < length; ++i)
437 if (!(category(it.characterAt(i)) & (Separator_Space | Separator_Lin e | Separator_Paragraph)))
438 return true;
439 }
440 return false;
441 }
442
443 void ContextMenuController::populate()
444 {
445 ContextMenuItem OpenLinkItem(ActionType, ContextMenuItemTagOpenLink, context MenuItemTagOpenLink());
446 ContextMenuItem OpenLinkInNewWindowItem(ActionType, ContextMenuItemTagOpenLi nkInNewWindow,
447 contextMenuItemTagOpenLinkInNewWindow());
448 ContextMenuItem DownloadFileItem(ActionType, ContextMenuItemTagDownloadLinkT oDisk,
449 contextMenuItemTagDownloadLinkToDisk());
450 ContextMenuItem CopyLinkItem(ActionType, ContextMenuItemTagCopyLinkToClipboa rd,
451 contextMenuItemTagCopyLinkToClipboard());
452 ContextMenuItem OpenImageInNewWindowItem(ActionType, ContextMenuItemTagOpenI mageInNewWindow,
453 contextMenuItemTagOpenImageInNewWindow());
454 ContextMenuItem DownloadImageItem(ActionType, ContextMenuItemTagDownloadImag eToDisk,
455 contextMenuItemTagDownloadImageToDisk());
456 ContextMenuItem CopyImageItem(ActionType, ContextMenuItemTagCopyImageToClipb oard,
457 contextMenuItemTagCopyImageToClipboard());
458 ContextMenuItem OpenMediaInNewWindowItem(ActionType, ContextMenuItemTagOpenM ediaInNewWindow, String());
459 ContextMenuItem CopyMediaLinkItem(ActionType, ContextMenuItemTagCopyMediaLin kToClipboard,
460 String());
461 ContextMenuItem MediaPlayPause(ActionType, ContextMenuItemTagMediaPlayPause,
462 contextMenuItemTagMediaPlay());
463 ContextMenuItem MediaMute(ActionType, ContextMenuItemTagMediaMute,
464 contextMenuItemTagMediaMute());
465 ContextMenuItem ToggleMediaControls(CheckableActionType, ContextMenuItemTagT oggleMediaControls,
466 contextMenuItemTagToggleMediaControls());
467 ContextMenuItem ToggleMediaLoop(CheckableActionType, ContextMenuItemTagToggl eMediaLoop,
468 contextMenuItemTagToggleMediaLoop());
469 ContextMenuItem EnterVideoFullscreen(ActionType, ContextMenuItemTagEnterVide oFullscreen,
470 contextMenuItemTagEnterVideoFullscreen());
471 ContextMenuItem SearchWebItem(ActionType, ContextMenuItemTagSearchWeb, conte xtMenuItemTagSearchWeb());
472 ContextMenuItem CopyItem(ActionType, ContextMenuItemTagCopy, contextMenuItem TagCopy());
473 ContextMenuItem BackItem(ActionType, ContextMenuItemTagGoBack, contextMenuIt emTagGoBack());
474 ContextMenuItem ForwardItem(ActionType, ContextMenuItemTagGoForward, contex tMenuItemTagGoForward());
475 ContextMenuItem StopItem(ActionType, ContextMenuItemTagStop, contextMenuItem TagStop());
476 ContextMenuItem ReloadItem(ActionType, ContextMenuItemTagReload, contextMenu ItemTagReload());
477 ContextMenuItem OpenFrameItem(ActionType, ContextMenuItemTagOpenFrameInNewWi ndow,
478 contextMenuItemTagOpenFrameInNewWindow());
479 ContextMenuItem NoGuessesItem(ActionType, ContextMenuItemTagNoGuessesFound,
480 contextMenuItemTagNoGuessesFound());
481 ContextMenuItem IgnoreSpellingItem(ActionType, ContextMenuItemTagIgnoreSpell ing,
482 contextMenuItemTagIgnoreSpelling());
483 ContextMenuItem LearnSpellingItem(ActionType, ContextMenuItemTagLearnSpellin g,
484 contextMenuItemTagLearnSpelling());
485 ContextMenuItem IgnoreGrammarItem(ActionType, ContextMenuItemTagIgnoreGramma r,
486 contextMenuItemTagIgnoreGrammar());
487 ContextMenuItem CutItem(ActionType, ContextMenuItemTagCut, contextMenuItemTa gCut());
488 ContextMenuItem PasteItem(ActionType, ContextMenuItemTagPaste, contextMenuIt emTagPaste());
489
490 Node* node = m_hitTestResult.innerNonSharedNode();
491 if (!node)
492 return;
493 Frame* frame = node->document()->frame();
494 if (!frame)
495 return;
496
497 if (!m_hitTestResult.isContentEditable()) {
498 FrameLoader* loader = frame->loader();
499 KURL linkURL = m_hitTestResult.absoluteLinkURL();
500 if (!linkURL.isEmpty()) {
501 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
502 appendItem(OpenLinkItem, m_contextMenu.get());
503 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
504 appendItem(DownloadFileItem, m_contextMenu.get());
505 }
506 appendItem(CopyLinkItem, m_contextMenu.get());
507 }
508
509 KURL imageURL = m_hitTestResult.absoluteImageURL();
510 if (!imageURL.isEmpty()) {
511 if (!linkURL.isEmpty())
512 appendItem(*separatorItem(), m_contextMenu.get());
513
514 appendItem(OpenImageInNewWindowItem, m_contextMenu.get());
515 appendItem(DownloadImageItem, m_contextMenu.get());
516 if (imageURL.isLocalFile() || m_hitTestResult.image())
517 appendItem(CopyImageItem, m_contextMenu.get());
518 }
519
520 KURL mediaURL = m_hitTestResult.absoluteMediaURL();
521 if (!mediaURL.isEmpty()) {
522 if (!linkURL.isEmpty() || !imageURL.isEmpty())
523 appendItem(*separatorItem(), m_contextMenu.get());
524
525 appendItem(MediaPlayPause, m_contextMenu.get());
526 appendItem(MediaMute, m_contextMenu.get());
527 appendItem(ToggleMediaControls, m_contextMenu.get());
528 appendItem(ToggleMediaLoop, m_contextMenu.get());
529 appendItem(EnterVideoFullscreen, m_contextMenu.get());
530
531 appendItem(*separatorItem(), m_contextMenu.get());
532 appendItem(CopyMediaLinkItem, m_contextMenu.get());
533 appendItem(OpenMediaInNewWindowItem, m_contextMenu.get());
534 }
535
536 if (imageURL.isEmpty() && linkURL.isEmpty() && mediaURL.isEmpty()) {
537 if (m_hitTestResult.isSelected()) {
538 if (selectionContainsPossibleWord(frame)) {
539 appendItem(SearchWebItem, m_contextMenu.get());
540 appendItem(*separatorItem(), m_contextMenu.get());
541 }
542
543 appendItem(CopyItem, m_contextMenu.get());
544 } else {
545 if (!(frame->page() && frame->page()->inspectorController()->has InspectorFrontendClient())) {
546 if (frame->page() && frame->page()->backForward()->canGoBack OrForward(-1))
547 appendItem(BackItem, m_contextMenu.get());
548
549 if (frame->page() && frame->page()->backForward()->canGoBack OrForward(1))
550 appendItem(ForwardItem, m_contextMenu.get());
551
552 // use isLoadingInAPISense rather than isLoading because Sto p/Reload are
553 // intended to match WebKit's API, not WebCore's internal no tion of loading status
554 if (loader->documentLoader()->isLoadingInAPISense())
555 appendItem(StopItem, m_contextMenu.get());
556 else
557 appendItem(ReloadItem, m_contextMenu.get());
558 }
559
560 if (frame->page() && frame != frame->page()->mainFrame())
561 appendItem(OpenFrameItem, m_contextMenu.get());
562 }
563 }
564 } else { // Make an editing context menu
565 FrameSelection* selection = frame->selection();
566 bool inPasswordField = selection->isInPasswordField();
567 if (!inPasswordField) {
568 bool haveContextMenuItemsForMisspellingOrGrammer = false;
569 bool spellCheckingEnabled = frame->editor()->isSpellCheckingEnabledF or(node);
570 if (spellCheckingEnabled) {
571 // Consider adding spelling-related or grammar-related context m enu items (never both, since a single selected range
572 // is never considered a misspelling and bad grammar at the same time)
573 bool misspelling;
574 bool badGrammar;
575 Vector<String> guesses = frame->editor()->guessesForMisspelledOr Ungrammatical(misspelling, badGrammar);
adamk 2013/05/14 00:30:52 Just happened to be looking at the code for guesse
groby-ooo-7-16 2013/05/14 00:57:54 I'm not sure what side effects you're seeing there
adamk 2013/05/14 01:05:12 The call sequence I'm worried about is: Editor::g
576 if (misspelling || badGrammar) {
577 size_t size = guesses.size();
578 if (!size) {
579 // If there's bad grammar but no suggestions (e.g., repe ated word), just leave off the suggestions
580 // list and trailing separator rather than adding a "No Guesses Found" item (matches AppKit)
581 if (misspelling) {
582 appendItem(NoGuessesItem, m_contextMenu.get());
583 appendItem(*separatorItem(), m_contextMenu.get());
584 }
585 } else {
586 for (unsigned i = 0; i < size; i++) {
587 const String &guess = guesses[i];
588 if (!guess.isEmpty()) {
589 ContextMenuItem item(ActionType, ContextMenuItem TagSpellingGuess, guess);
590 appendItem(item, m_contextMenu.get());
591 }
592 }
593 appendItem(*separatorItem(), m_contextMenu.get());
594 }
595 if (misspelling) {
596 appendItem(IgnoreSpellingItem, m_contextMenu.get());
597 appendItem(LearnSpellingItem, m_contextMenu.get());
598 } else
599 appendItem(IgnoreGrammarItem, m_contextMenu.get());
600 appendItem(*separatorItem(), m_contextMenu.get());
601 haveContextMenuItemsForMisspellingOrGrammer = true;
602 }
603 }
604 }
605
606 FrameLoader* loader = frame->loader();
607 KURL linkURL = m_hitTestResult.absoluteLinkURL();
608 if (!linkURL.isEmpty()) {
609 if (loader->client()->canHandleRequest(ResourceRequest(linkURL))) {
610 appendItem(OpenLinkItem, m_contextMenu.get());
611 appendItem(OpenLinkInNewWindowItem, m_contextMenu.get());
612 appendItem(DownloadFileItem, m_contextMenu.get());
613 }
614 appendItem(CopyLinkItem, m_contextMenu.get());
615 appendItem(*separatorItem(), m_contextMenu.get());
616 }
617
618 if (m_hitTestResult.isSelected() && !inPasswordField && selectionContain sPossibleWord(frame)) {
619 appendItem(SearchWebItem, m_contextMenu.get());
620 appendItem(*separatorItem(), m_contextMenu.get());
621 }
622
623 appendItem(CutItem, m_contextMenu.get());
624 appendItem(CopyItem, m_contextMenu.get());
625 appendItem(PasteItem, m_contextMenu.get());
626
627 if (!inPasswordField) {
628 appendItem(*separatorItem(), m_contextMenu.get());
629 ContextMenuItem SpellingAndGrammarMenuItem(SubmenuType, ContextMenuI temTagSpellingMenu,
630 contextMenuItemTagSpellingMenu());
631 createAndAppendSpellingAndGrammarSubMenu(SpellingAndGrammarMenuItem) ;
632 appendItem(SpellingAndGrammarMenuItem, m_contextMenu.get());
633 bool shouldShowFontMenu = true;
634 if (shouldShowFontMenu) {
635 ContextMenuItem FontMenuItem(SubmenuType, ContextMenuItemTagFont Menu,
636 contextMenuItemTagFontMenu());
637 createAndAppendFontSubMenu(FontMenuItem);
638 appendItem(FontMenuItem, m_contextMenu.get());
639 }
640 ContextMenuItem WritingDirectionMenuItem(SubmenuType, ContextMenuIte mTagWritingDirectionMenu,
641 contextMenuItemTagWritingDirectionMenu());
642 createAndAppendWritingDirectionSubMenu(WritingDirectionMenuItem);
643 appendItem(WritingDirectionMenuItem, m_contextMenu.get());
644 if (Page* page = frame->page()) {
645 if (Settings* settings = page->settings()) {
646 bool includeTextDirectionSubmenu = settings->textDirectionSu bmenuInclusionBehavior() == TextDirectionSubmenuAlwaysIncluded
647 || (settings->textDirectionSubmenuInclusionBehavior() == TextDirectionSubmenuAutomaticallyIncluded && frame->editor()->hasBidiSelection( ));
648 if (includeTextDirectionSubmenu) {
649 ContextMenuItem TextDirectionMenuItem(SubmenuType, Conte xtMenuItemTagTextDirectionMenu,
650 contextMenuItemTagTextDirectionMenu());
651 createAndAppendTextDirectionSubMenu(TextDirectionMenuIte m);
652 appendItem(TextDirectionMenuItem, m_contextMenu.get());
653 }
654 }
655 }
656 }
657 }
658 }
659
660 void ContextMenuController::addInspectElementItem()
661 {
662 Node* node = m_hitTestResult.innerNonSharedNode();
663 if (!node)
664 return;
665
666 Frame* frame = node->document()->frame();
667 if (!frame)
668 return;
669
670 Page* page = frame->page();
671 if (!page)
672 return;
673
674 if (!page->inspectorController())
675 return;
676
677 ContextMenuItem InspectElementItem(ActionType, ContextMenuItemTagInspectElem ent, contextMenuItemTagInspectElement());
678 if (m_contextMenu && !m_contextMenu->items().isEmpty())
679 appendItem(*separatorItem(), m_contextMenu.get());
680 appendItem(InspectElementItem, m_contextMenu.get());
681 }
682
683 void ContextMenuController::checkOrEnableIfNeeded(ContextMenuItem& item) const
684 {
685 if (item.type() == SeparatorType)
686 return;
687
688 Frame* frame = m_hitTestResult.innerNonSharedNode()->document()->frame();
689 if (!frame)
690 return;
691
692 // Custom items already have proper checked and enabled values.
693 if (ContextMenuItemBaseCustomTag <= item.action() && item.action() <= Contex tMenuItemLastCustomTag)
694 return;
695
696 bool shouldEnable = true;
697 bool shouldCheck = false;
698
699 switch (item.action()) {
700 case ContextMenuItemTagCheckSpelling:
701 shouldEnable = frame->editor()->canEdit();
702 break;
703 case ContextMenuItemTagDefaultDirection:
704 shouldCheck = false;
705 shouldEnable = false;
706 break;
707 case ContextMenuItemTagLeftToRight:
708 case ContextMenuItemTagRightToLeft: {
709 String direction = item.action() == ContextMenuItemTagLeftToRight ? "ltr" : "rtl";
710 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyDirectio n, direction) != FalseTriState;
711 shouldEnable = true;
712 break;
713 }
714 case ContextMenuItemTagTextDirectionDefault: {
715 Editor::Command command = frame->editor()->command("MakeTextWritingD irectionNatural");
716 shouldCheck = command.state() == TrueTriState;
717 shouldEnable = command.isEnabled();
718 break;
719 }
720 case ContextMenuItemTagTextDirectionLeftToRight: {
721 Editor::Command command = frame->editor()->command("MakeTextWritingD irectionLeftToRight");
722 shouldCheck = command.state() == TrueTriState;
723 shouldEnable = command.isEnabled();
724 break;
725 }
726 case ContextMenuItemTagTextDirectionRightToLeft: {
727 Editor::Command command = frame->editor()->command("MakeTextWritingD irectionRightToLeft");
728 shouldCheck = command.state() == TrueTriState;
729 shouldEnable = command.isEnabled();
730 break;
731 }
732 case ContextMenuItemTagCopy:
733 shouldEnable = frame->editor()->canDHTMLCopy() || frame->editor()->c anCopy();
734 break;
735 case ContextMenuItemTagCut:
736 shouldEnable = frame->editor()->canDHTMLCut() || frame->editor()->ca nCut();
737 break;
738 case ContextMenuItemTagIgnoreSpelling:
739 case ContextMenuItemTagLearnSpelling:
740 shouldEnable = frame->selection()->isRange();
741 break;
742 case ContextMenuItemTagPaste:
743 shouldEnable = frame->editor()->canDHTMLPaste() || frame->editor()-> canPaste();
744 break;
745 case ContextMenuItemTagUnderline: {
746 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyWebkitTe xtDecorationsInEffect, "underline") != FalseTriState;
747 shouldEnable = frame->editor()->canEditRichly();
748 break;
749 }
750 case ContextMenuItemTagLookUpInDictionary:
751 shouldEnable = frame->selection()->isRange();
752 break;
753 case ContextMenuItemTagCheckGrammarWithSpelling:
754 if (frame->editor()->isGrammarCheckingEnabled())
755 shouldCheck = true;
756 shouldEnable = true;
757 break;
758 case ContextMenuItemTagItalic: {
759 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontStyl e, "italic") != FalseTriState;
760 shouldEnable = frame->editor()->canEditRichly();
761 break;
762 }
763 case ContextMenuItemTagBold: {
764 shouldCheck = frame->editor()->selectionHasStyle(CSSPropertyFontWeig ht, "bold") != FalseTriState;
765 shouldEnable = frame->editor()->canEditRichly();
766 break;
767 }
768 case ContextMenuItemTagOutline:
769 shouldEnable = false;
770 break;
771 case ContextMenuItemTagShowSpellingPanel:
772 if (frame->editor()->spellingPanelIsShowing())
773 item.setTitle(contextMenuItemTagShowSpellingPanel(false));
774 else
775 item.setTitle(contextMenuItemTagShowSpellingPanel(true));
776 shouldEnable = frame->editor()->canEdit();
777 break;
778 case ContextMenuItemTagNoGuessesFound:
779 shouldEnable = false;
780 break;
781 case ContextMenuItemTagCheckSpellingWhileTyping:
782 shouldCheck = frame->editor()->isContinuousSpellCheckingEnabled();
783 break;
784 case ContextMenuItemTagStopSpeaking:
785 break;
786 case ContextMenuItemTagGoBack:
787 case ContextMenuItemTagGoForward:
788 case ContextMenuItemTagStop:
789 case ContextMenuItemTagReload:
790 case ContextMenuItemTagFontMenu:
791 case ContextMenuItemTagNoAction:
792 case ContextMenuItemTagOpenLinkInNewWindow:
793 case ContextMenuItemTagOpenLinkInThisWindow:
794 case ContextMenuItemTagDownloadLinkToDisk:
795 case ContextMenuItemTagCopyLinkToClipboard:
796 case ContextMenuItemTagOpenImageInNewWindow:
797 case ContextMenuItemTagDownloadImageToDisk:
798 case ContextMenuItemTagCopyImageToClipboard:
799 break;
800 case ContextMenuItemTagOpenMediaInNewWindow:
801 if (m_hitTestResult.mediaIsVideo())
802 item.setTitle(contextMenuItemTagOpenVideoInNewWindow());
803 else
804 item.setTitle(contextMenuItemTagOpenAudioInNewWindow());
805 break;
806 case ContextMenuItemTagCopyMediaLinkToClipboard:
807 if (m_hitTestResult.mediaIsVideo())
808 item.setTitle(contextMenuItemTagCopyVideoLinkToClipboard());
809 else
810 item.setTitle(contextMenuItemTagCopyAudioLinkToClipboard());
811 break;
812 case ContextMenuItemTagToggleMediaControls:
813 shouldCheck = m_hitTestResult.mediaControlsEnabled();
814 break;
815 case ContextMenuItemTagToggleMediaLoop:
816 shouldCheck = m_hitTestResult.mediaLoopEnabled();
817 break;
818 case ContextMenuItemTagEnterVideoFullscreen:
819 shouldEnable = m_hitTestResult.mediaSupportsFullscreen();
820 break;
821 case ContextMenuItemTagOpenFrameInNewWindow:
822 case ContextMenuItemTagSpellingGuess:
823 case ContextMenuItemTagOther:
824 case ContextMenuItemTagSearchInSpotlight:
825 case ContextMenuItemTagSearchWeb:
826 case ContextMenuItemTagOpenWithDefaultApplication:
827 case ContextMenuItemPDFActualSize:
828 case ContextMenuItemPDFZoomIn:
829 case ContextMenuItemPDFZoomOut:
830 case ContextMenuItemPDFAutoSize:
831 case ContextMenuItemPDFSinglePage:
832 case ContextMenuItemPDFFacingPages:
833 case ContextMenuItemPDFContinuous:
834 case ContextMenuItemPDFNextPage:
835 case ContextMenuItemPDFPreviousPage:
836 case ContextMenuItemTagOpenLink:
837 case ContextMenuItemTagIgnoreGrammar:
838 case ContextMenuItemTagSpellingMenu:
839 case ContextMenuItemTagShowFonts:
840 case ContextMenuItemTagStyles:
841 case ContextMenuItemTagShowColors:
842 case ContextMenuItemTagSpeechMenu:
843 case ContextMenuItemTagStartSpeaking:
844 case ContextMenuItemTagWritingDirectionMenu:
845 case ContextMenuItemTagTextDirectionMenu:
846 case ContextMenuItemTagPDFSinglePageScrolling:
847 case ContextMenuItemTagPDFFacingPagesScrolling:
848 case ContextMenuItemTagInspectElement:
849 case ContextMenuItemBaseCustomTag:
850 case ContextMenuItemCustomTagNoAction:
851 case ContextMenuItemLastCustomTag:
852 case ContextMenuItemBaseApplicationTag:
853 break;
854 case ContextMenuItemTagMediaPlayPause:
855 if (m_hitTestResult.mediaPlaying())
856 item.setTitle(contextMenuItemTagMediaPause());
857 else
858 item.setTitle(contextMenuItemTagMediaPlay());
859 break;
860 case ContextMenuItemTagMediaMute:
861 shouldEnable = m_hitTestResult.mediaHasAudio();
862 shouldCheck = shouldEnable && m_hitTestResult.mediaMuted();
863 break;
864 }
865
866 item.setChecked(shouldCheck);
867 item.setEnabled(shouldEnable);
868 } 131 }
869 132
870 } // namespace WebCore 133 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/page/ContextMenuController.h ('k') | Source/core/platform/ContextMenu.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698