diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-17 03:23:46 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-17 03:23:46 +0000 |
commit | 574a1d691c71e833638ccb1ca395dfa20c6835a4 (patch) | |
tree | 1d5f63a520c6b87fd74a19d57e9eaf4737bdd4fc | |
parent | 91cea0e774541297a46197d87e486cf8a4199775 (diff) | |
download | chromium_src-574a1d691c71e833638ccb1ca395dfa20c6835a4.zip chromium_src-574a1d691c71e833638ccb1ca395dfa20c6835a4.tar.gz chromium_src-574a1d691c71e833638ccb1ca395dfa20c6835a4.tar.bz2 |
Begin implementation of the context menu for Video and Audio tags.
This code should enable the creation of a basic context menu for the Video and Audio tags. The actions for fullscreen, save screenshot, loop, and set playback rate are not yet implemented.
BUG=15686
TEST=None
Review URL: http://codereview.chromium.org/149604
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20931 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 61 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 2 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 164 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.h | 7 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 22 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 4 | ||||
-rw-r--r-- | webkit/api/public/WebMediaPlayer.h | 2 | ||||
-rw-r--r-- | webkit/api/src/WebMediaPlayerClientImpl.cpp | 14 | ||||
-rw-r--r-- | webkit/api/src/WebMediaPlayerClientImpl.h | 2 | ||||
-rw-r--r-- | webkit/glue/context_menu.h | 47 | ||||
-rw-r--r-- | webkit/glue/context_menu_client_impl.cc | 50 | ||||
-rw-r--r-- | webkit/glue/webmediaplayer_impl.cc | 10 | ||||
-rw-r--r-- | webkit/glue/webmediaplayer_impl.h | 2 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 7 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate.cc | 28 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate.h | 2 |
17 files changed, 385 insertions, 45 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index e281eaa..0f39ed2 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -392,6 +392,67 @@ each locale. --> Open &image in new tab </message> + <message name="IDS_CONTENT_CONTEXT_PLAYBACKRATE_MENU" desc="The text label of the Playback Rate submenu"> + &Playback Rate + </message> + <message name="IDS_CONTENT_CONTEXT_PLAYBACKRATE_SLOW" desc="The text label of the 0.5x Speed Playback Rate menu item. The slowest of 5 options."> + &Slow (0.5x) + </message> + <message name="IDS_CONTENT_CONTEXT_PLAYBACKRATE_NORMAL" desc="The text label of the Normal Speed Playback Rate menu item. The default rate of 5 options."> + &Normal (1.0x) + </message> + <message name="IDS_CONTENT_CONTEXT_PLAYBACKRATE_FAST" desc="The text label of the 1.25x Sped Up Playback Rate menu item. The 3rd fastest of 5 options."> + &Fast (1.25x) + </message> + <message name="IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER" desc="The text label of the 1.5x Sped Up Playback Rate menu item. The 2nd fastest of 5 options."> + F&aster (1.5x) + </message> + <message name="IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME" desc="The text label of the 2.0x Sped Up Playback Rate menu item. The fastest of 5 options."> + D&ouble Time (2.0x) + </message> + + <message name="IDS_CONTENT_CONTEXT_LOOP" desc="The name of the Loop command for audio and video playback in the content area context menu"> + &Loop + </message> + <message name="IDS_CONTENT_CONTEXT_PLAY" desc="The name of the Play command for audio and video playback in the content area context menu"> + &Play + </message> + <message name="IDS_CONTENT_CONTEXT_PAUSE" desc="The name of the Pause command for audio and video playback in the content area context menu"> + &Pause + </message> + <message name="IDS_CONTENT_CONTEXT_MUTE" desc="The name of the Mute command for audio and video playback in the content area context menu"> + &Mute + </message> + <message name="IDS_CONTENT_CONTEXT_UNMUTE" desc="The name of the Unmute command for audio and video playback in the content area context menu"> + Un&mute + </message> + + <message name="IDS_CONTENT_CONTEXT_FULLSCREEN" desc="The name of the Fullscreen command for the video element in the content area context menu"> + &Fullscreen + </message> + <message name="IDS_CONTENT_CONTEXT_SAVESCREENSHOTAS" desc="The name of the Copy Sceenshot As command the video element in the content area context menu"> + Save &Screenshot... + </message> + <message name="IDS_CONTENT_CONTEXT_SAVEVIDEOAS" desc="The name of the Save Video As command in the content area context menu"> + Sa&ve video as... + </message> + <message name="IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION" desc="The name of the Copy Video Location command in the content area context menu"> + C&opy video URL + </message> + <message name="IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB" desc="The name of the Open Video in New Tab command in the content area context menu"> + &Open video in new tab + </message> + + <message name="IDS_CONTENT_CONTEXT_SAVEAUDIOAS" desc="The name of the Save Audio As command in the content area context menu"> + Sa&ve audio as... + </message> + <message name="IDS_CONTENT_CONTEXT_COPYAUDIOLOCATION" desc="The name of the Copy Audio Location command in the content area context menu"> + C&opy audio URL + </message> + <message name="IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB" desc="The name of the Open Audio in New Tab command in the content area context menu"> + &Open audio in new tab + </message> + <message name="IDS_CONTENT_CONTEXT_UNDO" desc="The name of the Undo command in the content area context menu"> &Undo </message> diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 2f775a5..c788560 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1118,7 +1118,7 @@ void RenderViewHost::OnMsgContextMenu(const ContextMenuParams& params) { // We don't validate |unfiltered_link_url| so that this field can be used // when users want to copy the original link URL. FilterURL(policy, renderer_id, &validated_params.link_url); - FilterURL(policy, renderer_id, &validated_params.image_url); + FilterURL(policy, renderer_id, &validated_params.src_url); FilterURL(policy, renderer_id, &validated_params.page_url); FilterURL(policy, renderer_id, &validated_params.frame_url); diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index a922825..ecc6e5c 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -28,6 +28,15 @@ #include "net/base/escape.h" #include "net/base/net_util.h" +// Constants for the standard playback rates provided by the context +// menu. If another rate is reported, it will be considered unknown and +// no rate will be selected in the submenu. +static const double kSlowPlaybackRate = 0.5f; +static const double kNormalPlaybackRate = 1.0f; +static const double kFastPlaybackRate = 1.25f; +static const double kFasterPlaybackRate = 1.50f; +static const double kDoubleTimePlaybackRate = 2.0f; + RenderViewContextMenu::RenderViewContextMenu( TabContents* tab_contents, const ContextMenuParams& params) @@ -42,11 +51,12 @@ RenderViewContextMenu::~RenderViewContextMenu() { // Menu construction functions ------------------------------------------------- void RenderViewContextMenu::Init() { - InitMenu(params_.node); + InitMenu(params_.node, params_.media_params); DoInit(); } -void RenderViewContextMenu::InitMenu(ContextNode node) { +void RenderViewContextMenu::InitMenu(ContextNode node, + ContextMenuMediaParams media_params) { if (node.type & ContextNode::PAGE) AppendPageItems(); if (node.type & ContextNode::FRAME) @@ -60,6 +70,18 @@ void RenderViewContextMenu::InitMenu(ContextNode node) { AppendImageItems(); } + if (node.type & ContextNode::VIDEO) { + if (node.type & ContextNode::LINK) + AppendSeparator(); + AppendVideoItems(media_params); + } + + if (node.type & ContextNode::AUDIO) { + if (node.type & ContextNode::LINK) + AppendSeparator(); + AppendAudioItems(media_params); + } + if (node.type & ContextNode::EDITABLE) AppendEditableItems(); else if (node.type & ContextNode::SELECTION || @@ -98,6 +120,58 @@ void RenderViewContextMenu::AppendImageItems() { AppendMenuItem(IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB); } +void RenderViewContextMenu::AppendAudioItems( + ContextMenuMediaParams media_params) { + AppendMediaItems(media_params); + AppendSeparator(); + AppendMenuItem(IDS_CONTENT_CONTEXT_SAVEAUDIOAS); + AppendMenuItem(IDS_CONTENT_CONTEXT_COPYAUDIOLOCATION); + AppendMenuItem(IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB); +} + +void RenderViewContextMenu::AppendVideoItems( + ContextMenuMediaParams media_params) { + AppendMediaItems(media_params); + AppendMenuItem(IDS_CONTENT_CONTEXT_FULLSCREEN); + AppendSeparator(); + AppendMenuItem(IDS_CONTENT_CONTEXT_SAVEVIDEOAS); + AppendMenuItem(IDS_CONTENT_CONTEXT_SAVESCREENSHOTAS); + AppendMenuItem(IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION); + AppendMenuItem(IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB); +} + +void RenderViewContextMenu::AppendMediaItems( + ContextMenuMediaParams media_params) { + if (media_params.player_state & ContextMenuMediaParams::PLAYER_PAUSED) { + AppendMenuItem(IDS_CONTENT_CONTEXT_PLAY); + } else { + AppendMenuItem(IDS_CONTENT_CONTEXT_PAUSE); + } + + if (media_params.player_state & ContextMenuMediaParams::PLAYER_MUTED) { + AppendMenuItem(IDS_CONTENT_CONTEXT_UNMUTE); + } else { + AppendMenuItem(IDS_CONTENT_CONTEXT_MUTE); + } + + AppendCheckboxMenuItem(IDS_CONTENT_CONTEXT_LOOP, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_LOOP)); + + StartSubMenu(IDS_CONTENT_CONTEXT_PLAYBACKRATE_MENU, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAYBACKRATE_MENU)); + AppendRadioMenuItem(IDS_CONTENT_CONTEXT_PLAYBACKRATE_SLOW, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAYBACKRATE_SLOW)); + AppendRadioMenuItem(IDS_CONTENT_CONTEXT_PLAYBACKRATE_NORMAL, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAYBACKRATE_NORMAL)); + AppendRadioMenuItem(IDS_CONTENT_CONTEXT_PLAYBACKRATE_FAST, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAYBACKRATE_FAST)); + AppendRadioMenuItem(IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER)); + AppendRadioMenuItem(IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME, + l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME)); + FinishSubMenu(); +} + void RenderViewContextMenu::AppendPageItems() { AppendMenuItem(IDS_CONTENT_CONTEXT_BACK); AppendMenuItem(IDS_CONTENT_CONTEXT_FORWARD); @@ -246,20 +320,58 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const { URLRequest::IsHandledURL(params_.link_url); case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: - return params_.image_url.is_valid() && - URLRequest::IsHandledURL(params_.image_url); + return params_.src_url.is_valid() && + URLRequest::IsHandledURL(params_.src_url); case IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB: // The images shown in the most visited thumbnails do not currently open // in a new tab as they should. Disabling this context menu option for // now, as a quick hack, before we resolve this issue (Issue = 2608). // TODO (sidchat): Enable this option once this issue is resolved. - if (params_.image_url.scheme() == chrome::kChromeUIScheme) + if (params_.src_url.scheme() == chrome::kChromeUIScheme) return false; return true; + case IDS_CONTENT_CONTEXT_FULLSCREEN: + // TODO(ajwong): Enable fullsceren after we actually implement this. + return false; + + // Media control commands should all be disabled if the player is in an + // error state. + case IDS_CONTENT_CONTEXT_PLAY: + case IDS_CONTENT_CONTEXT_PAUSE: + case IDS_CONTENT_CONTEXT_MUTE: + case IDS_CONTENT_CONTEXT_UNMUTE: + case IDS_CONTENT_CONTEXT_LOOP: + case IDS_CONTENT_CONTEXT_PLAYBACKRATE_MENU: + case IDS_CONTENT_CONTEXT_PLAYBACKRATE_SLOW: + case IDS_CONTENT_CONTEXT_PLAYBACKRATE_NORMAL: + case IDS_CONTENT_CONTEXT_PLAYBACKRATE_FAST: + case IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER: + case IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME: + return (params_.media_params.player_state & + ContextMenuMediaParams::PLAYER_ERROR) == 0; + + case IDS_CONTENT_CONTEXT_SAVESCREENSHOTAS: + // TODO(ajwong): Enable save screenshot after we actually implement + // this. + return false; + + case IDS_CONTENT_CONTEXT_COPYAUDIOLOCATION: + case IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION: case IDS_CONTENT_CONTEXT_COPYIMAGELOCATION: - return params_.image_url.is_valid(); + return params_.src_url.is_valid(); + + case IDS_CONTENT_CONTEXT_SAVEAUDIOAS: + case IDS_CONTENT_CONTEXT_SAVEVIDEOAS: + return (params_.media_params.player_state & + ContextMenuMediaParams::PLAYER_CAN_SAVE) && + params_.src_url.is_valid() && + URLRequest::IsHandledURL(params_.src_url); + + case IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB: + case IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB: + return true; case IDS_CONTENT_CONTEXT_SAVEPAGEAS: return SavePackage::IsSavableURL(source_tab_contents_->GetURL()); @@ -324,6 +436,29 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const { } bool RenderViewContextMenu::ItemIsChecked(int id) const { + // Select the correct playback rate. + if (id == IDS_CONTENT_CONTEXT_PLAYBACKRATE_SLOW) { + return params_.media_params.playback_rate == kSlowPlaybackRate; + } + if (id == IDS_CONTENT_CONTEXT_PLAYBACKRATE_NORMAL) { + return params_.media_params.playback_rate == kNormalPlaybackRate; + } + if (id == IDS_CONTENT_CONTEXT_PLAYBACKRATE_FAST) { + return params_.media_params.playback_rate == kFastPlaybackRate; + } + if (id == IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER) { + return params_.media_params.playback_rate == kFasterPlaybackRate; + } + if (id == IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME) { + return params_.media_params.playback_rate == kDoubleTimePlaybackRate; + } + + // See if the video is set to looping. + if (id == IDS_CONTENT_CONTEXT_LOOP) { + return (params_.media_params.player_state & + ContextMenuMediaParams::PLAYER_LOOP) != 0; + } + // Check box for 'Check the Spelling of this field'. if (id == IDC_CHECK_SPELLING_OF_THIS_FIELD) { return (params_.spellcheck_enabled && @@ -371,13 +506,15 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) { OpenURL(params_.link_url, OFF_THE_RECORD, PageTransition::LINK); break; + case IDS_CONTENT_CONTEXT_SAVEAUDIOAS: + case IDS_CONTENT_CONTEXT_SAVEVIDEOAS: case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: case IDS_CONTENT_CONTEXT_SAVELINKAS: { const GURL& referrer = params_.frame_url.is_empty() ? params_.page_url : params_.frame_url; const GURL& url = (id == IDS_CONTENT_CONTEXT_SAVELINKAS ? params_.link_url : - params_.image_url); + params_.src_url); DownloadManager* dlm = profile_->GetDownloadManager(); dlm->DownloadUrl(url, referrer, params_.frame_charset, source_tab_contents_); @@ -388,16 +525,20 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) { WriteURLToClipboard(params_.unfiltered_link_url); break; + case IDS_CONTENT_CONTEXT_COPYAUDIOLOCATION: + case IDS_CONTENT_CONTEXT_COPYVIDEOLOCATION: case IDS_CONTENT_CONTEXT_COPYIMAGELOCATION: - WriteURLToClipboard(params_.image_url); + WriteURLToClipboard(params_.src_url); break; case IDS_CONTENT_CONTEXT_COPYIMAGE: CopyImageAt(params_.x, params_.y); break; + case IDS_CONTENT_CONTEXT_OPENAUDIONEWTAB: + case IDS_CONTENT_CONTEXT_OPENVIDEONEWTAB: case IDS_CONTENT_CONTEXT_OPENIMAGENEWTAB: - OpenURL(params_.image_url, NEW_BACKGROUND_TAB, PageTransition::LINK); + OpenURL(params_.src_url, NEW_BACKGROUND_TAB, PageTransition::LINK); break; case IDS_CONTENT_CONTEXT_BACK: @@ -632,8 +773,7 @@ void RenderViewContextMenu::Inspect(int x, int y) { source_tab_contents_->render_view_host(), x, y); } -void RenderViewContextMenu::WriteTextToClipboard( - const string16& text) { +void RenderViewContextMenu::WriteTextToClipboard(const string16& text) { Clipboard* clipboard = g_browser_process->clipboard(); if (!clipboard) diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h index 95595c1..4fc97f6 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.h +++ b/chrome/browser/tab_contents/render_view_context_menu.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,7 +25,7 @@ class RenderViewContextMenu { void Init(); protected: - void InitMenu(ContextNode node); + void InitMenu(ContextNode node, ContextMenuMediaParams media_params); // Functions to be implemented by platform-specific subclasses --------------- @@ -76,6 +76,9 @@ class RenderViewContextMenu { void AppendDeveloperItems(); void AppendLinkItems(); void AppendImageItems(); + void AppendAudioItems(ContextMenuMediaParams media_params); + void AppendVideoItems(ContextMenuMediaParams media_params); + void AppendMediaItems(ContextMenuMediaParams media_params); void AppendPageItems(); void AppendFrameItems(); void AppendCopyItem(); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index c887d40..41b9466 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -820,6 +820,20 @@ struct ParamTraits<ViewHostMsg_FrameNavigate_Params> { }; template <> +struct ParamTraits<ContextMenuMediaParams> { + typedef ContextMenuMediaParams param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.player_state); + WriteParam(m, p.playback_rate); + } + static bool Read(const Message* m, void** iter, param_type* p) { + return + ReadParam(m, iter, &p->player_state) && + ReadParam(m, iter, &p->playback_rate); + } +}; + +template <> struct ParamTraits<ContextMenuParams> { typedef ContextMenuParams param_type; static void Write(Message* m, const param_type& p) { @@ -828,9 +842,10 @@ struct ParamTraits<ContextMenuParams> { WriteParam(m, p.y); WriteParam(m, p.link_url); WriteParam(m, p.unfiltered_link_url); - WriteParam(m, p.image_url); + WriteParam(m, p.src_url); WriteParam(m, p.page_url); WriteParam(m, p.frame_url); + WriteParam(m, p.media_params); WriteParam(m, p.selection_text); WriteParam(m, p.misspelled_word); WriteParam(m, p.dictionary_suggestions); @@ -846,9 +861,10 @@ struct ParamTraits<ContextMenuParams> { ReadParam(m, iter, &p->y) && ReadParam(m, iter, &p->link_url) && ReadParam(m, iter, &p->unfiltered_link_url) && - ReadParam(m, iter, &p->image_url) && + ReadParam(m, iter, &p->src_url) && ReadParam(m, iter, &p->page_url) && ReadParam(m, iter, &p->frame_url) && + ReadParam(m, iter, &p->media_params) && ReadParam(m, iter, &p->selection_text) && ReadParam(m, iter, &p->misspelled_word) && ReadParam(m, iter, &p->dictionary_suggestions) && diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 9967ca9..a7445c0 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -1977,9 +1977,10 @@ void RenderView::ShowContextMenu(WebView* webview, int x, int y, const GURL& link_url, - const GURL& image_url, + const GURL& src_url, const GURL& page_url, const GURL& frame_url, + const ContextMenuMediaParams& media_params, const std::wstring& selection_text, const std::wstring& misspelled_word, int edit_flags, @@ -1989,11 +1990,12 @@ void RenderView::ShowContextMenu(WebView* webview, params.node = node; params.x = x; params.y = y; - params.image_url = image_url; + params.src_url = src_url; params.link_url = link_url; params.unfiltered_link_url = link_url; params.page_url = page_url; params.frame_url = frame_url; + params.media_params = media_params; params.selection_text = selection_text; params.misspelled_word = misspelled_word; params.spellcheck_enabled = diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 4310d47..7cc65cf 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -53,6 +53,7 @@ class WebFrame; class WebPluginDelegate; class WebPluginDelegateProxy; class WebDevToolsAgentDelegate; +struct ContextMenuMediaParams; struct ThumbnailScore; struct ViewMsg_Navigate_Params; struct ViewMsg_UploadFile_Params; @@ -264,9 +265,10 @@ class RenderView : public RenderWidget, int x, int y, const GURL& link_url, - const GURL& image_url, + const GURL& src_url, const GURL& page_url, const GURL& frame_url, + const ContextMenuMediaParams& media_params, const std::wstring& selection_text, const std::wstring& misspelled_word, int edit_flags, diff --git a/webkit/api/public/WebMediaPlayer.h b/webkit/api/public/WebMediaPlayer.h index 740b894..8b60c77 100644 --- a/webkit/api/public/WebMediaPlayer.h +++ b/webkit/api/public/WebMediaPlayer.h @@ -67,6 +67,8 @@ namespace WebKit { // Playback controls. virtual void play() = 0; virtual void pause() = 0; + virtual bool supportsFullscreen() const = 0; + virtual bool supportsSave() const = 0; virtual void seek(float seconds) = 0; virtual void setEndTime(float seconds) = 0; virtual void setRate(float) = 0; diff --git a/webkit/api/src/WebMediaPlayerClientImpl.cpp b/webkit/api/src/WebMediaPlayerClientImpl.cpp index ca666e9..0451ad8 100644 --- a/webkit/api/src/WebMediaPlayerClientImpl.cpp +++ b/webkit/api/src/WebMediaPlayerClientImpl.cpp @@ -201,6 +201,20 @@ bool WebMediaPlayerClientImpl::paused() const return false; } +bool WebMediaPlayerClientImpl::supportsFullscreen() const +{ + if (m_webMediaPlayer.get()) + return m_webMediaPlayer->supportsFullscreen(); + return false; +} + +bool WebMediaPlayerClientImpl::supportsSave() const +{ + if (m_webMediaPlayer.get()) + return m_webMediaPlayer->supportsSave(); + return false; +} + void WebMediaPlayerClientImpl::setVolume(float volume) { if (m_webMediaPlayer.get()) diff --git a/webkit/api/src/WebMediaPlayerClientImpl.h b/webkit/api/src/WebMediaPlayerClientImpl.h index 9f5cd5d..d758276 100644 --- a/webkit/api/src/WebMediaPlayerClientImpl.h +++ b/webkit/api/src/WebMediaPlayerClientImpl.h @@ -66,6 +66,8 @@ namespace WebKit { virtual void cancelLoad(); virtual void play(); virtual void pause(); + virtual bool supportsFullscreen() const; + virtual bool supportsSave() const; virtual WebCore::IntSize naturalSize() const; virtual bool hasVideo() const; virtual void setVisible(bool); diff --git a/webkit/glue/context_menu.h b/webkit/glue/context_menu.h index 69ea22f..e6c4660 100644 --- a/webkit/glue/context_menu.h +++ b/webkit/glue/context_menu.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -37,6 +37,12 @@ struct ContextNode { // A misspelled word is selected MISSPELLED_WORD = 0x40, + + // A video node is selected + VIDEO = 0x80, + + // A video node is selected + AUDIO = 0x100, }; enum Capability { @@ -55,6 +61,35 @@ struct ContextNode { explicit ContextNode(int32 t) : type(t) {} }; +// Parameters structure used in ContextMenuParams with attributes needed to +// render the context menu for media elements. +// +// TODO(ajwong): Add support for multiple audio tracks and subtitles. +struct ContextMenuMediaParams { + // Values for the bitfield representing the state of the media player. + // If the state is in ERROR, most media controls should disable + // themselves. + enum PlayerState { + PLAYER_NO_STATE = 0x0, + PLAYER_ERROR = 0x1, + PLAYER_PAUSED = 0x2, + PLAYER_MUTED = 0x4, + PLAYER_LOOP = 0x8, + PLAYER_CAN_SAVE = 0x10, + }; + + // A bitfield representing the current state of the player, such as + // playing, muted, etc. + int32 player_state; + + // The current playback rate for this media element. + double playback_rate; + + ContextMenuMediaParams() + : player_state(PLAYER_NO_STATE), playback_rate(1.0f) { + } +}; + // Parameters structure for ViewHostMsg_ContextMenu. // FIXME(beng): This would be more useful in the future and more efficient // if the parameters here weren't so literally mapped to what @@ -78,8 +113,10 @@ struct ContextMenuParams { // this field in the frontend process. GURL unfiltered_link_url; - // This is the URL of the image the context menu was invoked on. - GURL image_url; + // This is the source URL for the element that the context menu was + // invoked on. Example of elements with source URLs are img, audio, and + // video. + GURL src_url; // This is the URL of the top level page that the context menu was invoked // on. @@ -88,6 +125,10 @@ struct ContextMenuParams { // This is the URL of the subframe that the context menu was invoked on. GURL frame_url; + // These are the parameters for the media element that the context menu + // was invoked on. + ContextMenuMediaParams media_params; + // This is the text of the selection that the context menu was invoked on. std::wstring selection_text; diff --git a/webkit/glue/context_menu_client_impl.cc b/webkit/glue/context_menu_client_impl.cc index 35c9b30..ec57257 100644 --- a/webkit/glue/context_menu_client_impl.cc +++ b/webkit/glue/context_menu_client_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -15,6 +15,8 @@ MSVC_PUSH_WARNING_LEVEL(0); #include "FrameLoader.h" #include "FrameView.h" #include "HitTestResult.h" +#include "HTMLMediaElement.h" +#include "HTMLNames.h" #include "KURL.h" #include "Widget.h" MSVC_POP_WARNING(); @@ -161,18 +163,51 @@ WebCore::PlatformMenuDescription ContextNode node; - // Links, Images and Image-Links take preference over all else. + // Links, Images, Media tags, and Image/Media-Links take preference over + // all else. WebCore::KURL link_url = r.absoluteLinkURL(); if (!link_url.isEmpty()) { node.type |= ContextNode::LINK; } - WebCore::KURL image_url = r.absoluteImageURL(); - if (!image_url.isEmpty()) { + + WebCore::KURL src_url; + + ContextMenuMediaParams media_params; + + if (!r.absoluteImageURL().isEmpty()) { + src_url = r.absoluteImageURL(); node.type |= ContextNode::IMAGE; + } else if (!r.absoluteMediaURL().isEmpty()) { + src_url = r.absoluteMediaURL(); + + // We know that if absoluteMediaURL() is not empty, then this is a media + // element. + WebCore::HTMLMediaElement* media_element = + static_cast<WebCore::HTMLMediaElement*>(r.innerNonSharedNode()); + if (media_element->hasTagName(WebCore::HTMLNames::videoTag)) { + node.type |= ContextNode::VIDEO; + } else if (media_element->hasTagName(WebCore::HTMLNames::audioTag)) { + node.type |= ContextNode::AUDIO; + } + + media_params.playback_rate = media_element->playbackRate(); + + if (media_element->paused()) { + media_params.player_state |= ContextMenuMediaParams::PLAYER_PAUSED; + } + if (media_element->muted()) { + media_params.player_state |= ContextMenuMediaParams::PLAYER_MUTED; + } + if (media_element->loop()) { + media_params.player_state |= ContextMenuMediaParams::PLAYER_LOOP; + } + if (media_element->supportsSave()) { + media_params.player_state |= ContextMenuMediaParams::PLAYER_CAN_SAVE; + } } - // If it's not a link, an image or an image link, show a selection menu or a - // more generic page menu. + // If it's not a link, an image, a media element, or an image/media link, + // show a selection menu or a more generic page menu. std::wstring selection_text_string; std::wstring misspelled_word_string; GURL frame_url; @@ -246,9 +281,10 @@ WebCore::PlatformMenuDescription menu_point.x(), menu_point.y(), webkit_glue::KURLToGURL(link_url), - webkit_glue::KURLToGURL(image_url), + webkit_glue::KURLToGURL(src_url), page_url, frame_url, + media_params, selection_text_string, misspelled_word_string, edit_flags, diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index 051e7d4..b817239 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -198,6 +198,16 @@ void WebMediaPlayerImpl::pause() { pipeline_->SetPlaybackRate(0.0f); } +bool WebMediaPlayerImpl::supportsFullscreen() const { + DCHECK(MessageLoop::current() == main_loop_); + return true; +} + +bool WebMediaPlayerImpl::supportsSave() const { + DCHECK(MessageLoop::current() == main_loop_); + return true; +} + void WebMediaPlayerImpl::seek(float seconds) { DCHECK(MessageLoop::current() == main_loop_); diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h index 9e9522e..5904023 100644 --- a/webkit/glue/webmediaplayer_impl.h +++ b/webkit/glue/webmediaplayer_impl.h @@ -156,6 +156,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, // Playback controls. virtual void play(); virtual void pause(); + virtual bool supportsFullscreen() const; + virtual bool supportsSave() const; virtual void seek(float seconds); virtual void setEndTime(float seconds); virtual void setRate(float rate); diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index e41a7bf..640dc53 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -66,6 +66,8 @@ class WebFrame; class WebMediaPlayerDelegate; class WebPluginDelegate; class WebView; +class WebWidget; +struct ContextMenuMediaParams; struct WebPluginGeometry; struct WebPreferences; @@ -623,6 +625,8 @@ class WebViewDelegate : virtual public WebKit::WebWidgetClient { // clicked on // @param page_url The URL of the page the mouse right clicked on // @param frame_url The URL of the subframe the mouse right clicked on + // @param media_params Extra attributed needed by the context menu for + // media elements. // @param selection_text The raw text of the selection that the mouse right // clicked on // @param misspelled_word The editable (possibily) misspelled word @@ -639,6 +643,7 @@ class WebViewDelegate : virtual public WebKit::WebWidgetClient { const GURL& image_url, const GURL& page_url, const GURL& frame_url, + const ContextMenuMediaParams& media_params, const std::wstring& selection_text, const std::wstring& misspelled_word, int edit_flags, diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc index 2fdf392..6fbaa1f 100644 --- a/webkit/tools/test_shell/test_webview_delegate.cc +++ b/webkit/tools/test_shell/test_webview_delegate.cc @@ -570,19 +570,21 @@ void TestWebViewDelegate::StartDragging(WebView* webview, webview->DragSourceSystemDragEnded(); } -void TestWebViewDelegate::ShowContextMenu(WebView* webview, - ContextNode node, - int x, - int y, - const GURL& link_url, - const GURL& image_url, - const GURL& page_url, - const GURL& frame_url, - const std::wstring& selection_text, - const std::wstring& misspelled_word, - int edit_flags, - const std::string& security_info, - const std::string& frame_charset) { +void TestWebViewDelegate::ShowContextMenu( + WebView* webview, + ContextNode node, + int x, + int y, + const GURL& link_url, + const GURL& image_url, + const GURL& page_url, + const GURL& frame_url, + const ContextMenuMediaParams& media_params, + const std::wstring& selection_text, + const std::wstring& misspelled_word, + int edit_flags, + const std::string& security_info, + const std::string& frame_charset) { CapturedContextMenuEvent context(node, x, y); captured_context_menu_events_.push_back(context); } diff --git a/webkit/tools/test_shell/test_webview_delegate.h b/webkit/tools/test_shell/test_webview_delegate.h index e70ede9..f86bc56 100644 --- a/webkit/tools/test_shell/test_webview_delegate.h +++ b/webkit/tools/test_shell/test_webview_delegate.h @@ -35,6 +35,7 @@ #endif #include "webkit/tools/test_shell/test_navigation_controller.h" +struct ContextMenuMediaParams; struct WebPreferences; class GURL; class TestShell; @@ -136,6 +137,7 @@ class TestWebViewDelegate : public base::RefCounted<TestWebViewDelegate>, const GURL& image_url, const GURL& page_url, const GURL& frame_url, + const ContextMenuMediaParams& media_params, const std::wstring& selection_text, const std::wstring& misspelled_word, int edit_flags, |