OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |