diff options
author | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-23 23:06:56 +0000 |
---|---|---|
committer | ajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-23 23:06:56 +0000 |
commit | 581b87eb99683237b52cf727178c0492cf273eeb (patch) | |
tree | 516cf6d1b75dc380fa179d72f95579300d9fdfcb /webkit/glue | |
parent | c72d7f9099a607ed546404a04a50402a9c3eeeb6 (diff) | |
download | chromium_src-581b87eb99683237b52cf727178c0492cf273eeb.zip chromium_src-581b87eb99683237b52cf727178c0492cf273eeb.tar.gz chromium_src-581b87eb99683237b52cf727178c0492cf273eeb.tar.bz2 |
Allow the browser to send actions back to the render for media element context menus.
Also renamed ContextNodeType per fishd's suggestion.
BUG=15686
TEST=none
Review URL: http://codereview.chromium.org/155954
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21466 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue')
-rw-r--r-- | webkit/glue/context_menu.h | 50 | ||||
-rw-r--r-- | webkit/glue/context_menu_client_impl.cc | 75 | ||||
-rw-r--r-- | webkit/glue/glue_util.cc | 10 | ||||
-rw-r--r-- | webkit/glue/glue_util.h | 6 | ||||
-rw-r--r-- | webkit/glue/webview.h | 7 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 6 | ||||
-rw-r--r-- | webkit/glue/webview_impl.cc | 36 | ||||
-rw-r--r-- | webkit/glue/webview_impl.h | 4 |
8 files changed, 143 insertions, 51 deletions
diff --git a/webkit/glue/context_menu.h b/webkit/glue/context_menu.h index e6c4660..620338a 100644 --- a/webkit/glue/context_menu.h +++ b/webkit/glue/context_menu.h @@ -12,7 +12,7 @@ // The type of node that the user may perform a contextual action on // in the WebView. -struct ContextNode { +struct ContextNodeType { enum TypeBit { // No node is selected NONE = 0x0, @@ -57,8 +57,8 @@ struct ContextNode { }; int32 type; - ContextNode() : type(NONE) {} - explicit ContextNode(int32 t) : type(t) {} + ContextNodeType() : type(NONE) {} + explicit ContextNodeType(int32 t) : type(t) {} }; // Parameters structure used in ContextMenuParams with attributes needed to @@ -67,15 +67,15 @@ struct ContextNode { // 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 + // 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, + enum PlayerStateBit { + NO_STATE = 0x0, + IN_ERROR = 0x1, + PAUSED = 0x2, + MUTED = 0x4, + LOOP = 0x8, + CAN_SAVE = 0x10, }; // A bitfield representing the current state of the player, such as @@ -86,7 +86,7 @@ struct ContextMenuMediaParams { double playback_rate; ContextMenuMediaParams() - : player_state(PLAYER_NO_STATE), playback_rate(1.0f) { + : player_state(NO_STATE), playback_rate(1.0f) { } }; @@ -98,7 +98,7 @@ struct ContextMenuMediaParams { // could be used for more contextual actions. struct ContextMenuParams { // This is the type of Context Node that the context menu was invoked on. - ContextNode node; + ContextNodeType node_type; // These values represent the coordinates of the mouse when the context menu // was invoked. Coords are relative to the associated RenderView's origin. @@ -157,4 +157,28 @@ struct ContextMenuParams { std::string frame_charset; }; +struct MediaPlayerAction { + enum CommandTypeBit { + NONE = 0x0, + PLAY = 0x1, + PAUSE = 0x2, + MUTE = 0x4, + UNMUTE = 0x8, + LOOP = 0x10, + NO_LOOP = 0x20, + SET_PLAYBACK_RATE = 0x40, + }; + + // A bitfield representing the actions that the context menu should execute + // on the originating node. + int32 command; + + // The new playback rate to set if the action is SET_PLAYBACK_RATE. + double playback_rate; + + MediaPlayerAction() : command(NONE), playback_rate(1.0f) {} + explicit MediaPlayerAction(int c) : command(c), playback_rate(1.0f) {} + MediaPlayerAction(int c, double rate) : command(c), playback_rate(rate) {} +}; + #endif // WEBKIT_GLUE_CONTEXT_NODE_TYPES_H__ diff --git a/webkit/glue/context_menu_client_impl.cc b/webkit/glue/context_menu_client_impl.cc index ec57257..210fb24 100644 --- a/webkit/glue/context_menu_client_impl.cc +++ b/webkit/glue/context_menu_client_impl.cc @@ -124,24 +124,25 @@ void ContextMenuClientImpl::contextMenuDestroyed() { } // Figure out the URL of a page or subframe. Returns |page_type| as the type, -// which indicates page or subframe, or ContextNode::NONE if the URL could not +// which indicates page or subframe, or ContextNodeType::NONE if the URL could not // be determined for some reason. -static ContextNode GetTypeAndURLFromFrame(WebCore::Frame* frame, - GURL* url, - ContextNode page_node) { - ContextNode node; +static ContextNodeType GetTypeAndURLFromFrame( + WebCore::Frame* frame, + GURL* url, + ContextNodeType page_node_type) { + ContextNodeType node_type; if (frame) { WebCore::DocumentLoader* dl = frame->loader()->documentLoader(); if (dl) { WebDataSource* ds = WebDataSourceImpl::FromLoader(dl); if (ds) { - node = page_node; + node_type = page_node_type; *url = ds->hasUnreachableURL() ? ds->unreachableURL() : ds->request().url(); } } } - return node; + return node_type; } WebCore::PlatformMenuDescription @@ -161,13 +162,13 @@ WebCore::PlatformMenuDescription WebCore::IntPoint menu_point = selected_frame->view()->contentsToWindow(r.point()); - ContextNode node; + ContextNodeType node_type; // 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; + node_type.type |= ContextNodeType::LINK; } WebCore::KURL src_url; @@ -176,7 +177,7 @@ WebCore::PlatformMenuDescription if (!r.absoluteImageURL().isEmpty()) { src_url = r.absoluteImageURL(); - node.type |= ContextNode::IMAGE; + node_type.type |= ContextNodeType::IMAGE; } else if (!r.absoluteMediaURL().isEmpty()) { src_url = r.absoluteMediaURL(); @@ -185,25 +186,26 @@ WebCore::PlatformMenuDescription WebCore::HTMLMediaElement* media_element = static_cast<WebCore::HTMLMediaElement*>(r.innerNonSharedNode()); if (media_element->hasTagName(WebCore::HTMLNames::videoTag)) { - node.type |= ContextNode::VIDEO; + node_type.type |= ContextNodeType::VIDEO; } else if (media_element->hasTagName(WebCore::HTMLNames::audioTag)) { - node.type |= ContextNode::AUDIO; + node_type.type |= ContextNodeType::AUDIO; } media_params.playback_rate = media_element->playbackRate(); if (media_element->paused()) { - media_params.player_state |= ContextMenuMediaParams::PLAYER_PAUSED; + media_params.player_state |= ContextMenuMediaParams::PAUSED; } if (media_element->muted()) { - media_params.player_state |= ContextMenuMediaParams::PLAYER_MUTED; + media_params.player_state |= ContextMenuMediaParams::MUTED; } if (media_element->loop()) { - media_params.player_state |= ContextMenuMediaParams::PLAYER_LOOP; + media_params.player_state |= ContextMenuMediaParams::LOOP; } if (media_element->supportsSave()) { - media_params.player_state |= ContextMenuMediaParams::PLAYER_CAN_SAVE; + media_params.player_state |= ContextMenuMediaParams::CAN_SAVE; } + // TODO(ajwong): Report error states in the media player. } // If it's not a link, an image, a media element, or an image/media link, @@ -217,26 +219,27 @@ WebCore::PlatformMenuDescription std::string frame_charset = WideToASCII( webkit_glue::StringToStdWString(selected_frame->loader()->encoding())); // Send the frame and page URLs in any case. - ContextNode frame_node = ContextNode(ContextNode::NONE); - ContextNode page_node = + ContextNodeType frame_node = ContextNodeType(ContextNodeType::NONE); + ContextNodeType page_node = GetTypeAndURLFromFrame(webview_->main_frame()->frame(), &page_url, - ContextNode(ContextNode::PAGE)); + ContextNodeType(ContextNodeType::PAGE)); if (selected_frame != webview_->main_frame()->frame()) { - frame_node = GetTypeAndURLFromFrame(selected_frame, - &frame_url, - ContextNode(ContextNode::FRAME)); + frame_node = + GetTypeAndURLFromFrame(selected_frame, + &frame_url, + ContextNodeType(ContextNodeType::FRAME)); } if (r.isSelected()) { - node.type |= ContextNode::SELECTION; + node_type.type |= ContextNodeType::SELECTION; selection_text_string = CollapseWhitespace( webkit_glue::StringToStdWString(selected_frame->selectedText()), false); } if (r.isContentEditable()) { - node.type |= ContextNode::EDITABLE; + node_type.type |= ContextNodeType::EDITABLE; if (webview_->GetFocusedWebCoreFrame()->editor()-> isContinuousSpellCheckingEnabled()) { misspelled_word_string = GetMisspelledWord(default_menu, @@ -244,11 +247,11 @@ WebCore::PlatformMenuDescription } } - if (node.type == ContextNode::NONE) { + if (node_type.type == ContextNodeType::NONE) { if (selected_frame != webview_->main_frame()->frame()) { - node = frame_node; + node_type = frame_node; } else { - node = page_node; + node_type = page_node; } } @@ -258,26 +261,26 @@ WebCore::PlatformMenuDescription if (ds) security_info = ds->response().securityInfo(); - int edit_flags = ContextNode::CAN_DO_NONE; + int edit_flags = ContextNodeType::CAN_DO_NONE; if (webview_->GetFocusedWebCoreFrame()->editor()->canUndo()) - edit_flags |= ContextNode::CAN_UNDO; + edit_flags |= ContextNodeType::CAN_UNDO; if (webview_->GetFocusedWebCoreFrame()->editor()->canRedo()) - edit_flags |= ContextNode::CAN_REDO; + edit_flags |= ContextNodeType::CAN_REDO; if (webview_->GetFocusedWebCoreFrame()->editor()->canCut()) - edit_flags |= ContextNode::CAN_CUT; + edit_flags |= ContextNodeType::CAN_CUT; if (webview_->GetFocusedWebCoreFrame()->editor()->canCopy()) - edit_flags |= ContextNode::CAN_COPY; + edit_flags |= ContextNodeType::CAN_COPY; if (webview_->GetFocusedWebCoreFrame()->editor()->canPaste()) - edit_flags |= ContextNode::CAN_PASTE; + edit_flags |= ContextNodeType::CAN_PASTE; if (webview_->GetFocusedWebCoreFrame()->editor()->canDelete()) - edit_flags |= ContextNode::CAN_DELETE; + edit_flags |= ContextNodeType::CAN_DELETE; // We can always select all... - edit_flags |= ContextNode::CAN_SELECT_ALL; + edit_flags |= ContextNodeType::CAN_SELECT_ALL; WebViewDelegate* d = webview_->delegate(); if (d) { d->ShowContextMenu(webview_, - node, + node_type, menu_point.x(), menu_point.y(), webkit_glue::KURLToGURL(link_url), diff --git a/webkit/glue/glue_util.cc b/webkit/glue/glue_util.cc index f12be0b..8b9f1fa 100644 --- a/webkit/glue/glue_util.cc +++ b/webkit/glue/glue_util.cc @@ -22,6 +22,7 @@ #include "IntPoint.h" #include "IntRect.h" #include "KURL.h" +#include "Node.h" #include "PlatformString.h" #include "ResourceError.h" @@ -36,6 +37,7 @@ #include "webkit/api/public/WebDragData.h" #include "webkit/api/public/WebForm.h" #include "webkit/api/public/WebHistoryItem.h" +#include "webkit/api/public/WebNode.h" #include "webkit/api/public/WebPoint.h" #include "webkit/api/public/WebRect.h" #include "webkit/api/public/WebSize.h" @@ -261,6 +263,14 @@ WTF::PassRefPtr<WebCore::HTMLFormElement> WebFormToHTMLFormElement( return form; } +// WebNode conversions --------------------------------------------------------- +WebKit::WebNode NodeToWebNode(const WTF::PassRefPtr<WebCore::Node>& node) { + return node; +} +WTF::PassRefPtr<WebCore::Node> WebNodeToNode(const WebKit::WebNode& node) { + return node; +} + // WebHistoryItem conversions -------------------------------------------------- WebKit::WebHistoryItem HistoryItemToWebHistoryItem( diff --git a/webkit/glue/glue_util.h b/webkit/glue/glue_util.h index beafe125..4163f29 100644 --- a/webkit/glue/glue_util.h +++ b/webkit/glue/glue_util.h @@ -20,6 +20,7 @@ class IntPoint; class IntRect; class IntSize; class KURL; +class Node; class ResourceError; class ResourceResponse; class SharedBuffer; @@ -33,6 +34,7 @@ class WebData; class WebDragData; class WebForm; class WebHistoryItem; +class WebNode; class WebString; class WebURL; class WebURLRequest; @@ -120,6 +122,10 @@ WebKit::WebSize IntSizeToWebSize(const WebCore::IntSize&); // WebCursorInfo <- Cursor WebKit::WebCursorInfo CursorToWebCursorInfo(const WebCore::Cursor&); +// WebNode <-> Node +WebKit::WebNode NodeToWebNode(const WTF::PassRefPtr<WebCore::Node>&); +WTF::PassRefPtr<WebCore::Node> WebNodeToNode(const WebKit::WebNode&); + // WebDragData <-> ChromiumDataObject WebKit::WebDragData ChromiumDataObjectToWebDragData( const WTF::PassRefPtr<WebCore::ChromiumDataObject>&); diff --git a/webkit/glue/webview.h b/webkit/glue/webview.h index 565143d..dcc3643 100644 --- a/webkit/glue/webview.h +++ b/webkit/glue/webview.h @@ -16,6 +16,7 @@ class WebDragData; struct WebPoint; } +struct MediaPlayerAction; struct WebPreferences; class GURL; class WebDevToolsAgent; @@ -230,6 +231,12 @@ class WebView : public WebKit::WebWidget { virtual void SetIsTransparent(bool is_transparent) = 0; virtual bool GetIsTransparent() const = 0; + // Performs an action from a context menu for the node at the given + // location. + virtual void MediaPlayerActionAt(int x, + int y, + const MediaPlayerAction& action) = 0; + // Updates the WebView's active state (i.e., control tints). virtual void SetActive(bool active) = 0; diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index 77624b3..8f2371b 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -50,6 +50,7 @@ class WebWorker; class WebWorkerClient; class WebMediaPlayer; class WebMediaPlayerClient; +class WebNode; class WebURLRequest; class WebURLResponse; class WebWidget; @@ -615,7 +616,8 @@ class WebViewDelegate : virtual public WebKit::WebWidgetClient { // @abstract Shows a context menu with commands relevant to a specific // element on the current page. // @param webview The WebView sending the delegate method. - // @param node The node(s) the context menu is being invoked on + // @param node_type The type of the node(s) the context menu is being + // invoked on // @param x The x position of the mouse pointer (relative to the webview) // @param y The y position of the mouse pointer (relative to the webview) // @param link_url The absolute URL of the link that contains the node the @@ -635,7 +637,7 @@ class WebViewDelegate : virtual public WebKit::WebWidgetClient { // @param frame_charset which indicates the character encoding of // the currently focused frame. virtual void ShowContextMenu(WebView* webview, - ContextNode node, + ContextNodeType node_type, int x, int y, const GURL& link_url, diff --git a/webkit/glue/webview_impl.cc b/webkit/glue/webview_impl.cc index 89af941..17ff9eb 100644 --- a/webkit/glue/webview_impl.cc +++ b/webkit/glue/webview_impl.cc @@ -52,6 +52,7 @@ MSVC_PUSH_WARNING_LEVEL(0); #include "GraphicsContext.h" #include "HTMLNames.h" #include "HTMLInputElement.h" +#include "HTMLMediaElement.h" #include "HitTestResult.h" #include "Image.h" #include "InspectorController.h" @@ -1804,6 +1805,41 @@ bool WebViewImpl::GetIsTransparent() const { return is_transparent_; } +void WebViewImpl::MediaPlayerActionAt(int x, + int y, + const MediaPlayerAction& action) { + HitTestResult result = HitTestResultForWindowPos(IntPoint(x, y)); + + WTF::RefPtr<WebCore::Node> node = result.innerNonSharedNode(); + if (node->hasTagName(WebCore::HTMLNames::videoTag) || + node->hasTagName(WebCore::HTMLNames::audioTag)) { + WTF::RefPtr<WebCore::HTMLMediaElement> media_element = + static_pointer_cast<WebCore::HTMLMediaElement>(node); + if (action.command & MediaPlayerAction::PLAY) { + media_element->play(); + } + if (action.command & MediaPlayerAction::PAUSE) { + media_element->pause(); + } + if (action.command & MediaPlayerAction::MUTE) { + media_element->setMuted(true); + } + if (action.command & MediaPlayerAction::UNMUTE) { + media_element->setMuted(false); + } + if (action.command & MediaPlayerAction::LOOP) { + media_element->setLoop(true); + } + if (action.command & MediaPlayerAction::NO_LOOP) { + media_element->setLoop(false); + } + if (action.command & MediaPlayerAction::SET_PLAYBACK_RATE) { + // TODO(ajwong): We should test for overflow. + media_element->setPlaybackRate(static_cast<float>(action.playback_rate)); + } + } +} + void WebViewImpl::SetActive(bool active) { if (page() && page()->focusController()) page()->focusController()->setActive(active); diff --git a/webkit/glue/webview_impl.h b/webkit/glue/webview_impl.h index 92dd080..4ab05dd 100644 --- a/webkit/glue/webview_impl.h +++ b/webkit/glue/webview_impl.h @@ -131,6 +131,10 @@ class WebViewImpl : public WebView, public base::RefCounted<WebViewImpl> { virtual void SetIsTransparent(bool is_transparent); virtual bool GetIsTransparent() const; + virtual void MediaPlayerActionAt(int x, + int y, + const MediaPlayerAction& action); + virtual void SetActive(bool active); virtual bool IsActive(); |