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

Unified Diff: chrome/renderer/resources/extensions/web_view/chrome_web_view.js

Issue 1026383003: <webview>: make context menus cancellable using JS API (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address comments from yoz@ Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/resources/extensions/web_view/chrome_web_view.js
diff --git a/chrome/renderer/resources/extensions/web_view/chrome_web_view.js b/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
index a91a239c79133d234774fe7759f4cc421a044458..a2ae068705488e1518ff5bb10b11a6381832ad72 100644
--- a/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
+++ b/chrome/renderer/resources/extensions/web_view/chrome_web_view.js
@@ -12,18 +12,8 @@ var CreateEvent = require('guestViewEvents').CreateEvent;
var EventBindings = require('event_bindings');
var idGeneratorNatives = requireNative('id_generator');
var Utils = require('utils');
-var WebViewEvents = require('webViewEvents').WebViewEvents;
var WebViewImpl = require('webView').WebViewImpl;
-var CHROME_WEB_VIEW_EVENTS = {
- 'contextmenushown': {
- evt: CreateEvent('chromeWebViewInternal.contextmenu'),
- cancelable: true,
- fields: ['items'],
- handler: 'handleContextMenu'
- }
-};
-
// This is the only "webViewInternal.onClicked" named event for this renderer.
//
// Since we need an event per <webview>, we define events with suffix
@@ -33,6 +23,9 @@ var CHROME_WEB_VIEW_EVENTS = {
// it to the subEvent's listeners. This way
// <webview>.contextMenus.onClicked behave as a regular chrome Event type.
var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked');
+// See comment above.
+var ContextMenusHandlerEvent =
+ CreateEvent('chromeWebViewInternal.onContextMenuShow');
// -----------------------------------------------------------------------------
// ContextMenusOnClickedEvent object.
@@ -58,6 +51,41 @@ function ContextMenusOnClickedEvent(opt_eventName,
ContextMenusOnClickedEvent.prototype.__proto__ = EventBindings.Event.prototype;
+function ContextMenusOnContextMenuEvent(webViewImpl,
+ opt_eventName,
+ opt_argSchemas,
+ opt_eventOptions,
+ opt_webViewInstanceId) {
+ var subEventName = GetUniqueSubEventName(opt_eventName);
+ EventBindings.Event.call(this,
+ subEventName,
+ opt_argSchemas,
+ opt_eventOptions,
+ opt_webViewInstanceId);
+ var defaultPrevented = false;
+ ContextMenusHandlerEvent.addListener(function(e) {
+ var defaultPrevented = false;
+ var event = {
+ 'preventDefault': function() { defaultPrevented = true; }
+ };
+
+ // Re-dispatch to subEvent's listeners.
+ $Function.apply(this.dispatch, this, [event]);
+
+ if (!defaultPrevented) {
+ // TODO(lazyboy): Remove |items| parameter completely from
+ // ChromeWebView.showContextMenu as we don't do anything useful with it
+ // currently.
+ var items = [];
+ ChromeWebView.showContextMenu(
+ webViewImpl.guest.getId(), e.requestId, items);
+ }
+ }.bind(this), {instanceId: opt_webViewInstanceId || 0});
+}
+
+ContextMenusOnContextMenuEvent.prototype.__proto__ =
+ EventBindings.Event.prototype;
+
// -----------------------------------------------------------------------------
// WebViewContextMenusImpl object.
@@ -93,6 +121,15 @@ var WebViewContextMenus = Utils.expose(
// -----------------------------------------------------------------------------
WebViewImpl.prototype.maybeSetupContextMenus = function() {
+ if (!this.contextMenusOnContextMenuEvent_) {
+ var eventName = 'chromeWebViewInternal.onContextMenuShow';
+ // TODO(lazyboy): Find event by name instead of events[1].
+ var eventSchema = ChromeWebViewSchema.events[1];
+ var eventOptions = {supportsListeners: true};
+ this.contextMenusOnContextMenuEvent_ = new ContextMenusOnContextMenuEvent(
+ this, eventName, eventSchema, eventOptions, this.viewInstanceId);
+ }
+
var createContextMenus = function() {
return function() {
if (this.contextMenus_) {
@@ -117,17 +154,27 @@ WebViewImpl.prototype.maybeSetupContextMenus = function() {
return this.contextMenusOnClickedEvent_;
}.bind(this);
}.bind(this);
- Object.defineProperty(
+ $Object.defineProperty(
this.contextMenus_,
'onClicked',
{get: getOnClickedEvent(), enumerable: true});
-
+ $Object.defineProperty(
+ this.contextMenus_,
+ 'onShow',
+ {
+ get: function() {
+ return this.contextMenusOnContextMenuEvent_;
+ }.bind(this),
+ enumerable: true
+ });
return this.contextMenus_;
}.bind(this);
}.bind(this);
// Expose <webview>.contextMenus object.
- Object.defineProperty(
+ // TODO(lazyboy): Add documentation for contextMenus:
+ // http://crbug.com/470979.
+ $Object.defineProperty(
this.element,
'contextMenus',
{
@@ -136,52 +183,6 @@ WebViewImpl.prototype.maybeSetupContextMenus = function() {
});
};
-WebViewEvents.prototype.handleContextMenu = function(event, eventName) {
- var webViewEvent = this.makeDomEvent(event, eventName);
- var requestId = event.requestId;
- // Construct the event.menu object.
- var actionTaken = false;
- var validateCall = function() {
- var ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN = '<webview>: ' +
- 'An action has already been taken for this "contextmenu" event.';
-
- if (actionTaken) {
- throw new Error(ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN);
- }
- actionTaken = true;
- };
- var menu = {
- show: function(items) {
- validateCall();
- // TODO(lazyboy): WebViewShowContextFunction doesn't do anything useful
- // with |items|, implement.
- ChromeWebView.showContextMenu(this.view.guest.getId(), requestId, items);
- }.bind(this)
- };
- webViewEvent.menu = menu;
- var element = this.view.element;
- var defaultPrevented = !element.dispatchEvent(webViewEvent);
- if (actionTaken) {
- return;
- }
- if (!defaultPrevented) {
- actionTaken = true;
- // The default action is equivalent to just showing the context menu as is.
- ChromeWebView.showContextMenu(
- this.view.guest.getId(), requestId, undefined);
-
- // TODO(lazyboy): Figure out a way to show warning message only when
- // listeners are registered for this event.
- } // else we will ignore showing the context menu completely.
-};
-
function GetUniqueSubEventName(eventName) {
return eventName + '/' + idGeneratorNatives.GetNextId();
}
-
-// Exposes |CHROME_WEB_VIEW_EVENTS| when the ChromeWebView API is available.
-(function() {
- for (var eventName in CHROME_WEB_VIEW_EVENTS) {
- WebViewEvents.EVENTS[eventName] = CHROME_WEB_VIEW_EVENTS[eventName];
- }
-})();

Powered by Google App Engine
This is Rietveld 408576698