Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / chrome / renderer / resources / extensions / chrome_web_view_experimental.js
bloba769ab025e7bb10a34047d6a75f66a64aa077fd6
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This module implements experimental API for <webview>.
6 // See web_view.js for details.
7 //
8 // <webview> Chrome Experimental API is only available on canary and dev
9 // channels of Chrome.
11 var ChromeWebView = require('chromeWebViewInternal').ChromeWebView;
12 var ChromeWebViewSchema =
13 requireNative('schema_registry').GetSchema('chromeWebViewInternal');
14 var ContextMenusSchema =
15 requireNative('schema_registry').GetSchema('contextMenus');
16 var CreateEvent = require('webViewEvents').CreateEvent;
17 var EventBindings = require('event_bindings');
18 var idGeneratorNatives = requireNative('id_generator');
19 var MessagingNatives = requireNative('messaging_natives');
20 var utils = require('utils');
21 var WebViewImpl = require('webView').WebViewImpl;
23 function GetUniqueSubEventName(eventName) {
24 return eventName + '/' + idGeneratorNatives.GetNextId();
27 // This is the only "webViewInternal.onClicked" named event for this renderer.
29 // Since we need an event per <webview>, we define events with suffix
30 // (subEventName) in each of the <webview>. Behind the scenes, this event is
31 // registered as a ContextMenusEvent, with filter set to the webview's
32 // |viewInstanceId|. Any time a ContextMenusEvent is dispatched, we re-dispatch
33 // it to the subEvent's listeners. This way
34 // <webview>.contextMenus.onClicked behave as a regular chrome Event type.
35 var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked');
37 /**
38 * This event is exposed as <webview>.contextMenus.onClicked.
40 * @constructor
42 function ContextMenusOnClickedEvent(opt_eventName,
43 opt_argSchemas,
44 opt_eventOptions,
45 opt_webViewInstanceId) {
46 var subEventName = GetUniqueSubEventName(opt_eventName);
47 EventBindings.Event.call(this,
48 subEventName,
49 opt_argSchemas,
50 opt_eventOptions,
51 opt_webViewInstanceId);
53 // TODO(lazyboy): When do we dispose this listener?
54 ContextMenusEvent.addListener(function() {
55 // Re-dispatch to subEvent's listeners.
56 $Function.apply(this.dispatch, this, $Array.slice(arguments));
57 }.bind(this), {instanceId: opt_webViewInstanceId || 0});
60 ContextMenusOnClickedEvent.prototype = {
61 __proto__: EventBindings.Event.prototype
64 /**
65 * An instance of this class is exposed as <webview>.contextMenus.
66 * @constructor
68 function WebViewContextMenusImpl(viewInstanceId) {
69 this.viewInstanceId_ = viewInstanceId;
72 WebViewContextMenusImpl.prototype.create = function() {
73 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
74 return $Function.apply(ChromeWebView.contextMenusCreate, null, args);
77 WebViewContextMenusImpl.prototype.remove = function() {
78 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
79 return $Function.apply(ChromeWebView.contextMenusRemove, null, args);
82 WebViewContextMenusImpl.prototype.removeAll = function() {
83 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
84 return $Function.apply(ChromeWebView.contextMenusRemoveAll, null, args);
87 WebViewContextMenusImpl.prototype.update = function() {
88 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
89 return $Function.apply(ChromeWebView.contextMenusUpdate, null, args);
92 var WebViewContextMenus = utils.expose(
93 'WebViewContextMenus', WebViewContextMenusImpl,
94 { functions: ['create', 'remove', 'removeAll', 'update'] });
96 /** @private */
97 WebViewImpl.prototype.maybeHandleContextMenu = function(e, webViewEvent) {
98 var requestId = e.requestId;
99 // Construct the event.menu object.
100 var actionTaken = false;
101 var validateCall = function() {
102 var ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN = '<webview>: ' +
103 'An action has already been taken for this "contextmenu" event.';
105 if (actionTaken) {
106 throw new Error(ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN);
108 actionTaken = true;
110 var menu = {
111 show: function(items) {
112 validateCall();
113 // TODO(lazyboy): WebViewShowContextFunction doesn't do anything useful
114 // with |items|, implement.
115 ChromeWebView.showContextMenu(this.guestInstanceId, requestId, items);
116 }.bind(this)
118 webViewEvent.menu = menu;
119 var webviewNode = this.webviewNode;
120 var defaultPrevented = !webviewNode.dispatchEvent(webViewEvent);
121 if (actionTaken) {
122 return;
124 if (!defaultPrevented) {
125 actionTaken = true;
126 // The default action is equivalent to just showing the context menu as is.
127 ChromeWebView.showContextMenu(this.guestInstanceId, requestId, undefined);
129 // TODO(lazyboy): Figure out a way to show warning message only when
130 // listeners are registered for this event.
131 } // else we will ignore showing the context menu completely.
134 /** @private */
135 WebViewImpl.prototype.setupExperimentalContextMenus = function() {
136 var createContextMenus = function() {
137 return function() {
138 if (this.contextMenus_) {
139 return this.contextMenus_;
142 this.contextMenus_ = new WebViewContextMenus(this.viewInstanceId);
144 // Define 'onClicked' event property on |this.contextMenus_|.
145 var getOnClickedEvent = function() {
146 return function() {
147 if (!this.contextMenusOnClickedEvent_) {
148 var eventName = 'chromeWebViewInternal.onClicked';
149 // TODO(lazyboy): Find event by name instead of events[0].
150 var eventSchema = ChromeWebViewSchema.events[0];
151 var eventOptions = {supportsListeners: true};
152 var onClickedEvent = new ContextMenusOnClickedEvent(
153 eventName, eventSchema, eventOptions, this.viewInstanceId);
154 this.contextMenusOnClickedEvent_ = onClickedEvent;
155 return onClickedEvent;
157 return this.contextMenusOnClickedEvent_;
158 }.bind(this);
159 }.bind(this);
160 Object.defineProperty(
161 this.contextMenus_,
162 'onClicked',
163 {get: getOnClickedEvent(), enumerable: true});
165 return this.contextMenus_;
166 }.bind(this);
167 }.bind(this);
169 // Expose <webview>.contextMenus object.
170 Object.defineProperty(
171 this.webviewNode,
172 'contextMenus',
174 get: createContextMenus(),
175 enumerable: true