summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 23:06:56 +0000
committerajwong@chromium.org <ajwong@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 23:06:56 +0000
commit581b87eb99683237b52cf727178c0492cf273eeb (patch)
tree516cf6d1b75dc380fa179d72f95579300d9fdfcb
parentc72d7f9099a607ed546404a04a50402a9c3eeeb6 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc7
-rw-r--r--chrome/browser/renderer_host/render_view_host.h4
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc139
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.h4
-rw-r--r--chrome/browser/views/tab_contents/render_view_context_menu_external_win.h2
-rw-r--r--chrome/browser/views/tab_contents/render_view_context_menu_win.h2
-rw-r--r--chrome/common/render_messages.h64
-rw-r--r--chrome/common/render_messages_internal.h7
-rw-r--r--chrome/renderer/render_view.cc15
-rw-r--r--chrome/renderer/render_view.h5
-rw-r--r--webkit/glue/context_menu.h50
-rw-r--r--webkit/glue/context_menu_client_impl.cc75
-rw-r--r--webkit/glue/glue_util.cc10
-rw-r--r--webkit/glue/glue_util.h6
-rw-r--r--webkit/glue/webview.h7
-rw-r--r--webkit/glue/webview_delegate.h6
-rw-r--r--webkit/glue/webview_impl.cc36
-rw-r--r--webkit/glue/webview_impl.h4
-rw-r--r--webkit/tools/test_shell/test_webview_delegate.cc4
-rw-r--r--webkit/tools/test_shell/test_webview_delegate.h8
20 files changed, 351 insertions, 104 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 75b07da..ff99693 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -1248,6 +1248,13 @@ void RenderViewHost::OnMsgShowModalHTMLDialog(
delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg);
}
+void RenderViewHost::MediaPlayerActionAt(int x,
+ int y,
+ const MediaPlayerAction& action) {
+ // TODO(ajwong): Which thread should run this? Does it matter?
+ Send(new ViewMsg_MediaPlayerActionAt(routing_id(), x, y, action));
+}
+
void RenderViewHost::OnMsgPasswordFormsSeen(
const std::vector<webkit_glue::PasswordForm>& forms) {
delegate_->PasswordFormsSeen(forms);
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 6f68bb0..26612b0 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -25,6 +25,7 @@ class SiteInstance;
class SkBitmap;
class ViewMsg_Navigate;
struct ContextMenuParams;
+struct MediaPlayerAction;
struct ViewHostMsg_DidPrintPage_Params;
struct ViewMsg_Navigate_Params;
struct WebDropData;
@@ -297,6 +298,9 @@ class RenderViewHost : public RenderWidgetHost,
void ModalHTMLDialogClosed(IPC::Message* reply_msg,
const std::string& json_retval);
+ // Send an action to the media player element located at |x|, |y|.
+ void MediaPlayerActionAt(int x, int y, const MediaPlayerAction& action);
+
// Copies the image at the specified point.
void CopyImageAt(int x, int y);
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index e7099ac..1c4959f 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -51,44 +51,44 @@ RenderViewContextMenu::~RenderViewContextMenu() {
// Menu construction functions -------------------------------------------------
void RenderViewContextMenu::Init() {
- InitMenu(params_.node, params_.media_params);
+ InitMenu(params_.node_type, params_.media_params);
DoInit();
}
-void RenderViewContextMenu::InitMenu(ContextNode node,
+void RenderViewContextMenu::InitMenu(ContextNodeType node_type,
ContextMenuMediaParams media_params) {
- if (node.type & ContextNode::PAGE)
+ if (node_type.type & ContextNodeType::PAGE)
AppendPageItems();
- if (node.type & ContextNode::FRAME)
+ if (node_type.type & ContextNodeType::FRAME)
AppendFrameItems();
- if (node.type & ContextNode::LINK)
+ if (node_type.type & ContextNodeType::LINK)
AppendLinkItems();
- if (node.type & ContextNode::IMAGE) {
- if (node.type & ContextNode::LINK)
+ if (node_type.type & ContextNodeType::IMAGE) {
+ if (node_type.type & ContextNodeType::LINK)
AppendSeparator();
AppendImageItems();
}
- if (node.type & ContextNode::VIDEO) {
- if (node.type & ContextNode::LINK)
+ if (node_type.type & ContextNodeType::VIDEO) {
+ if (node_type.type & ContextNodeType::LINK)
AppendSeparator();
AppendVideoItems(media_params);
}
- if (node.type & ContextNode::AUDIO) {
- if (node.type & ContextNode::LINK)
+ if (node_type.type & ContextNodeType::AUDIO) {
+ if (node_type.type & ContextNodeType::LINK)
AppendSeparator();
AppendAudioItems(media_params);
}
- if (node.type & ContextNode::EDITABLE)
+ if (node_type.type & ContextNodeType::EDITABLE)
AppendEditableItems();
- else if (node.type & ContextNode::SELECTION ||
- node.type & ContextNode::LINK)
+ else if (node_type.type & ContextNodeType::SELECTION ||
+ node_type.type & ContextNodeType::LINK)
AppendCopyItem();
- if (node.type & ContextNode::SELECTION)
+ if (node_type.type & ContextNodeType::SELECTION)
AppendSearchProvider();
AppendSeparator();
AppendDeveloperItems();
@@ -132,23 +132,21 @@ void RenderViewContextMenu::AppendAudioItems(
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) {
+ if (media_params.player_state & ContextMenuMediaParams::PAUSED) {
AppendMenuItem(IDS_CONTENT_CONTEXT_PLAY);
} else {
AppendMenuItem(IDS_CONTENT_CONTEXT_PAUSE);
}
- if (media_params.player_state & ContextMenuMediaParams::PLAYER_MUTED) {
+ if (media_params.player_state & ContextMenuMediaParams::MUTED) {
AppendMenuItem(IDS_CONTENT_CONTEXT_UNMUTE);
} else {
AppendMenuItem(IDS_CONTENT_CONTEXT_MUTE);
@@ -350,7 +348,7 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const {
case IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER:
case IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME:
return (params_.media_params.player_state &
- ContextMenuMediaParams::PLAYER_ERROR) == 0;
+ ContextMenuMediaParams::IN_ERROR) == 0;
case IDS_CONTENT_CONTEXT_SAVESCREENSHOTAS:
// TODO(ajwong): Enable save screenshot after we actually implement
@@ -365,7 +363,7 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const {
case IDS_CONTENT_CONTEXT_SAVEAUDIOAS:
case IDS_CONTENT_CONTEXT_SAVEVIDEOAS:
return (params_.media_params.player_state &
- ContextMenuMediaParams::PLAYER_CAN_SAVE) &&
+ ContextMenuMediaParams::CAN_SAVE) &&
params_.src_url.is_valid() &&
URLRequest::IsHandledURL(params_.src_url);
@@ -381,25 +379,25 @@ bool RenderViewContextMenu::IsItemCommandEnabled(int id) const {
return params_.frame_url.is_valid();
case IDS_CONTENT_CONTEXT_UNDO:
- return !!(params_.edit_flags & ContextNode::CAN_UNDO);
+ return !!(params_.edit_flags & ContextNodeType::CAN_UNDO);
case IDS_CONTENT_CONTEXT_REDO:
- return !!(params_.edit_flags & ContextNode::CAN_REDO);
+ return !!(params_.edit_flags & ContextNodeType::CAN_REDO);
case IDS_CONTENT_CONTEXT_CUT:
- return !!(params_.edit_flags & ContextNode::CAN_CUT);
+ return !!(params_.edit_flags & ContextNodeType::CAN_CUT);
case IDS_CONTENT_CONTEXT_COPY:
- return !!(params_.edit_flags & ContextNode::CAN_COPY);
+ return !!(params_.edit_flags & ContextNodeType::CAN_COPY);
case IDS_CONTENT_CONTEXT_PASTE:
- return !!(params_.edit_flags & ContextNode::CAN_PASTE);
+ return !!(params_.edit_flags & ContextNodeType::CAN_PASTE);
case IDS_CONTENT_CONTEXT_DELETE:
- return !!(params_.edit_flags & ContextNode::CAN_DELETE);
+ return !!(params_.edit_flags & ContextNodeType::CAN_DELETE);
case IDS_CONTENT_CONTEXT_SELECTALL:
- return !!(params_.edit_flags & ContextNode::CAN_SELECT_ALL);
+ return !!(params_.edit_flags & ContextNodeType::CAN_SELECT_ALL);
case IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD:
return !profile_->IsOffTheRecord() && params_.link_url.is_valid();
@@ -456,7 +454,7 @@ bool RenderViewContextMenu::ItemIsChecked(int id) const {
// See if the video is set to looping.
if (id == IDS_CONTENT_CONTEXT_LOOP) {
return (params_.media_params.player_state &
- ContextMenuMediaParams::PLAYER_LOOP) != 0;
+ ContextMenuMediaParams::LOOP) != 0;
}
// Check box for 'Check the Spelling of this field'.
@@ -541,6 +539,82 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) {
OpenURL(params_.src_url, NEW_BACKGROUND_TAB, PageTransition::LINK);
break;
+ case IDS_CONTENT_CONTEXT_PLAY:
+ MediaPlayerActionAt(params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::PLAY));
+ break;
+
+ case IDS_CONTENT_CONTEXT_PAUSE:
+ MediaPlayerActionAt(params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::PAUSE));
+ break;
+
+ case IDS_CONTENT_CONTEXT_MUTE:
+ MediaPlayerActionAt(params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::MUTE));
+ break;
+
+ case IDS_CONTENT_CONTEXT_UNMUTE:
+ MediaPlayerActionAt(params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::UNMUTE));
+ break;
+
+ case IDS_CONTENT_CONTEXT_LOOP:
+ if (ItemIsChecked(IDS_CONTENT_CONTEXT_LOOP)) {
+ MediaPlayerActionAt(params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::NO_LOOP));
+ } else {
+ MediaPlayerActionAt(params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::LOOP));
+ }
+ break;
+
+ case IDS_CONTENT_CONTEXT_PLAYBACKRATE_SLOW:
+ MediaPlayerActionAt(
+ params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::SET_PLAYBACK_RATE,
+ kSlowPlaybackRate));
+ break;
+
+ case IDS_CONTENT_CONTEXT_PLAYBACKRATE_NORMAL:
+ MediaPlayerActionAt(
+ params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::SET_PLAYBACK_RATE,
+ kNormalPlaybackRate));
+ break;
+
+ case IDS_CONTENT_CONTEXT_PLAYBACKRATE_FAST:
+ MediaPlayerActionAt(
+ params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::SET_PLAYBACK_RATE,
+ kFastPlaybackRate));
+ break;
+
+ case IDS_CONTENT_CONTEXT_PLAYBACKRATE_FASTER:
+ MediaPlayerActionAt(
+ params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::SET_PLAYBACK_RATE,
+ kFasterPlaybackRate));
+ break;
+
+ case IDS_CONTENT_CONTEXT_PLAYBACKRATE_DOUBLETIME:
+ MediaPlayerActionAt(
+ params_.x,
+ params_.y,
+ MediaPlayerAction(MediaPlayerAction::SET_PLAYBACK_RATE,
+ kDoubleTimePlaybackRate));
+ break;
+
case IDS_CONTENT_CONTEXT_BACK:
source_tab_contents_->controller().GoBack();
break;
@@ -779,3 +853,10 @@ void RenderViewContextMenu::WriteURLToClipboard(const GURL& url) {
WriteTextToClipboard(UTF8ToUTF16(utf8_text));
DidWriteURLToClipboard(utf8_text);
}
+
+void RenderViewContextMenu::MediaPlayerActionAt(
+ int x,
+ int y,
+ const MediaPlayerAction& action) {
+ source_tab_contents_->render_view_host()->MediaPlayerActionAt(x, y, action);
+}
diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h
index afa6861..93c554d 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.h
+++ b/chrome/browser/tab_contents/render_view_context_menu.h
@@ -25,7 +25,7 @@ class RenderViewContextMenu {
void Init();
protected:
- void InitMenu(ContextNode node, ContextMenuMediaParams media_params);
+ void InitMenu(ContextNodeType node, ContextMenuMediaParams media_params);
// Functions to be implemented by platform-specific subclasses ---------------
@@ -101,6 +101,8 @@ class RenderViewContextMenu {
void WriteTextToClipboard(const string16& text);
void WriteURLToClipboard(const GURL& url);
+ void MediaPlayerActionAt(int x, int y, const MediaPlayerAction& action);
+
bool IsDevCommandEnabled(int id) const;
DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu);
diff --git a/chrome/browser/views/tab_contents/render_view_context_menu_external_win.h b/chrome/browser/views/tab_contents/render_view_context_menu_external_win.h
index 852adb4..15baa37 100644
--- a/chrome/browser/views/tab_contents/render_view_context_menu_external_win.h
+++ b/chrome/browser/views/tab_contents/render_view_context_menu_external_win.h
@@ -17,7 +17,7 @@ class RenderViewContextMenuExternalWin : public RenderViewContextMenuWin {
const ContextMenuParams& params,
const std::vector<int> disabled_menu_ids);
- ~RenderViewContextMenuExternalWin() {}
+ virtual ~RenderViewContextMenuExternalWin() {}
protected:
// RenderViewContextMenuWin overrides --------------------------------------
diff --git a/chrome/browser/views/tab_contents/render_view_context_menu_win.h b/chrome/browser/views/tab_contents/render_view_context_menu_win.h
index 4ff68b9..89560e3 100644
--- a/chrome/browser/views/tab_contents/render_view_context_menu_win.h
+++ b/chrome/browser/views/tab_contents/render_view_context_menu_win.h
@@ -17,7 +17,7 @@ class RenderViewContextMenuWin : public RenderViewContextMenu,
RenderViewContextMenuWin(TabContents* tab_contents,
const ContextMenuParams& params);
- ~RenderViewContextMenuWin();
+ virtual ~RenderViewContextMenuWin();
void RunMenuAt(int x, int y);
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index d3faea0..6835b49 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -484,8 +484,8 @@ struct ParamTraits<FilterPolicy::Type> {
};
template <>
-struct ParamTraits<ContextNode> {
- typedef ContextNode param_type;
+struct ParamTraits<ContextNodeType> {
+ typedef ContextNodeType param_type;
static void Write(Message* m, const param_type& p) {
m->WriteInt(p.type);
}
@@ -493,7 +493,7 @@ struct ParamTraits<ContextNode> {
int type;
if (!m->ReadInt(iter, &type))
return false;
- *p = ContextNode(type);
+ *p = ContextNodeType(type);
return true;
}
static void Log(const param_type& p, std::wstring* l) {
@@ -503,19 +503,19 @@ struct ParamTraits<ContextNode> {
event.append(L"NONE");
} else {
event.append(L"(");
- if (p.type & ContextNode::PAGE)
+ if (p.type & ContextNodeType::PAGE)
event.append(L"PAGE|");
- if (p.type & ContextNode::FRAME)
+ if (p.type & ContextNodeType::FRAME)
event.append(L"FRAME|");
- if (p.type & ContextNode::LINK)
+ if (p.type & ContextNodeType::LINK)
event.append(L"LINK|");
- if (p.type & ContextNode::IMAGE)
+ if (p.type & ContextNodeType::IMAGE)
event.append(L"IMAGE|");
- if (p.type & ContextNode::SELECTION)
+ if (p.type & ContextNodeType::SELECTION)
event.append(L"SELECTION|");
- if (p.type & ContextNode::EDITABLE)
+ if (p.type & ContextNodeType::EDITABLE)
event.append(L"EDITABLE|");
- if (p.type & ContextNode::MISSPELLED_WORD)
+ if (p.type & ContextNodeType::MISSPELLED_WORD)
event.append(L"MISSPELLED_WORD|");
event.append(L")");
}
@@ -838,7 +838,7 @@ template <>
struct ParamTraits<ContextMenuParams> {
typedef ContextMenuParams param_type;
static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.node);
+ WriteParam(m, p.node_type);
WriteParam(m, p.x);
WriteParam(m, p.y);
WriteParam(m, p.link_url);
@@ -857,7 +857,7 @@ struct ParamTraits<ContextMenuParams> {
}
static bool Read(const Message* m, void** iter, param_type* p) {
return
- ReadParam(m, iter, &p->node) &&
+ ReadParam(m, iter, &p->node_type) &&
ReadParam(m, iter, &p->x) &&
ReadParam(m, iter, &p->y) &&
ReadParam(m, iter, &p->link_url) &&
@@ -879,6 +879,46 @@ struct ParamTraits<ContextMenuParams> {
}
};
+template <>
+struct ParamTraits<MediaPlayerAction> {
+ typedef MediaPlayerAction param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.command);
+ WriteParam(m, p.playback_rate);
+ }
+ static bool Read(const Message* m, void** iter, param_type* p) {
+ return
+ ReadParam(m, iter, &p->command) &&
+ ReadParam(m, iter, &p->playback_rate);
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ std::wstring event = L"";
+ if (!p.command) {
+ l->append(L"NONE");
+ } else {
+ l->append(L"(");
+ if (p.command & MediaPlayerAction::PLAY)
+ l->append(L"PLAY|");
+ if (p.command & MediaPlayerAction::PAUSE)
+ l->append(L"PAUSE|");
+ if (p.command & MediaPlayerAction::MUTE)
+ l->append(L"MUTE|");
+ if (p.command & MediaPlayerAction::UNMUTE)
+ l->append(L"UNMUTE|");
+ if (p.command & MediaPlayerAction::LOOP)
+ l->append(L"LOOP|");
+ if (p.command & MediaPlayerAction::NO_LOOP)
+ l->append(L"NO_LOOP|");
+ if (p.command & MediaPlayerAction::SET_PLAYBACK_RATE) {
+ l->append(L"SET_PLAYBACK_RATE [");
+ LogParam(p.playback_rate, l);
+ l->append(L"]|");
+ }
+ l->append(L")");
+ }
+ }
+};
+
// Traits for ViewHostMsg_PaintRect_Params structure to pack/unpack.
template <>
struct ParamTraits<ViewHostMsg_PaintRect_Params> {
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 344ebad..f240a34 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -65,6 +65,13 @@ IPC_BEGIN_MESSAGES(View)
IPC_MESSAGE_ROUTED1(ViewMsg_SetRendererPrefs,
RendererPreferences)
+ // Tells the renderer to perform the given action on the media player
+ // located at |x|, |y|.
+ IPC_MESSAGE_ROUTED3(ViewMsg_MediaPlayerActionAt,
+ int32 /* x */,
+ int32 /* y */,
+ MediaPlayerAction)
+
// Tells the render view to close.
IPC_MESSAGE_ROUTED0(ViewMsg_Close)
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index fd8f61a..6af62ef 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -59,6 +59,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/WebScriptSource.h"
@@ -423,6 +424,7 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ViewMsg_EnableIntrinsicWidthChangedMode,
OnEnableIntrinsicWidthChangedMode)
IPC_MESSAGE_HANDLER(ViewMsg_SetRendererPrefs, OnSetRendererPrefs)
+ IPC_MESSAGE_HANDLER(ViewMsg_MediaPlayerActionAt, OnMediaPlayerActionAt)
IPC_MESSAGE_HANDLER(ViewMsg_SetActive, OnSetActive)
// Have the super handle all other messages.
@@ -1977,7 +1979,7 @@ void RenderView::SyncNavigationState() {
}
void RenderView::ShowContextMenu(WebView* webview,
- ContextNode node,
+ ContextNodeType node_type,
int x,
int y,
const GURL& link_url,
@@ -1991,7 +1993,7 @@ void RenderView::ShowContextMenu(WebView* webview,
const std::string& security_info,
const std::string& frame_charset) {
ContextMenuParams params;
- params.node = node;
+ params.node_type = node_type;
params.x = x;
params.y = y;
params.src_url = src_url;
@@ -2635,6 +2637,15 @@ void RenderView::OnSetRendererPrefs(const RendererPreferences& renderer_prefs) {
// and |subpixel_rendering| through to Skia.
}
+void RenderView::OnMediaPlayerActionAt(int x,
+ int y,
+ const MediaPlayerAction& action) {
+ if (!webview())
+ return;
+
+ webview()->MediaPlayerActionAt(x, y, action);
+}
+
void RenderView::OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count) {
history_back_list_count_ = back_list_count;
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index d83bab9..d4214c0 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -262,7 +262,7 @@ class RenderView : public RenderWidget,
ErrorPageType error_type);
virtual void ShowContextMenu(WebView* webview,
- ContextNode node,
+ ContextNodeType node_type,
int x,
int y,
const GURL& link_url,
@@ -531,6 +531,9 @@ class RenderView : public RenderWidget,
void OnEnableViewSourceMode();
void OnEnableIntrinsicWidthChangedMode();
void OnSetRendererPrefs(const RendererPreferences& renderer_prefs);
+ void OnMediaPlayerActionAt(int x,
+ int y,
+ const MediaPlayerAction& action);
void OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count);
void OnGetAccessibilityInfo(
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();
diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc
index 55a2d8b..197cc16 100644
--- a/webkit/tools/test_shell/test_webview_delegate.cc
+++ b/webkit/tools/test_shell/test_webview_delegate.cc
@@ -574,7 +574,7 @@ void TestWebViewDelegate::StartDragging(WebView* webview,
void TestWebViewDelegate::ShowContextMenu(
WebView* webview,
- ContextNode node,
+ ContextNodeType node_type,
int x,
int y,
const GURL& link_url,
@@ -587,7 +587,7 @@ void TestWebViewDelegate::ShowContextMenu(
int edit_flags,
const std::string& security_info,
const std::string& frame_charset) {
- CapturedContextMenuEvent context(node, x, y);
+ CapturedContextMenuEvent context(node_type, 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 f86bc56..4e9de10 100644
--- a/webkit/tools/test_shell/test_webview_delegate.h
+++ b/webkit/tools/test_shell/test_webview_delegate.h
@@ -45,15 +45,15 @@ class TestWebViewDelegate : public base::RefCounted<TestWebViewDelegate>,
public WebViewDelegate {
public:
struct CapturedContextMenuEvent {
- CapturedContextMenuEvent(ContextNode in_node,
+ CapturedContextMenuEvent(ContextNodeType in_node_type,
int in_x,
int in_y)
- : node(in_node),
+ : node_type(in_node_type),
x(in_x),
y(in_y) {
}
- ContextNode node;
+ ContextNodeType node_type;
int x;
int y;
};
@@ -130,7 +130,7 @@ class TestWebViewDelegate : public base::RefCounted<TestWebViewDelegate>,
virtual void StartDragging(WebView* webview,
const WebKit::WebDragData& drag_data);
virtual void ShowContextMenu(WebView* webview,
- ContextNode node,
+ ContextNodeType node_type,
int x,
int y,
const GURL& link_url,