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

Side by Side Diff: chrome/renderer/resources/extensions/web_view/chrome_web_view_experimental.js

Issue 1004233002: Moved the contextmenu webview API to stable, and removed the experimental API infrastructure. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. 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 unified diff | Download patch
OLDNEW
(Empty)
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.
4
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.
10
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('guestViewEvents').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 WebViewEvents = require('webViewEvents').WebViewEvents;
22 var WebViewImpl = require('webView').WebViewImpl;
23
24 function GetUniqueSubEventName(eventName) {
25 return eventName + '/' + idGeneratorNatives.GetNextId();
26 }
27
28 // This is the only "webViewInternal.onClicked" named event for this renderer.
29 //
30 // Since we need an event per <webview>, we define events with suffix
31 // (subEventName) in each of the <webview>. Behind the scenes, this event is
32 // registered as a ContextMenusEvent, with filter set to the webview's
33 // |viewInstanceId|. Any time a ContextMenusEvent is dispatched, we re-dispatch
34 // it to the subEvent's listeners. This way
35 // <webview>.contextMenus.onClicked behave as a regular chrome Event type.
36 var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked');
37
38 /**
39 * This event is exposed as <webview>.contextMenus.onClicked.
40 *
41 * @constructor
42 */
43 function ContextMenusOnClickedEvent(opt_eventName,
44 opt_argSchemas,
45 opt_eventOptions,
46 opt_webViewInstanceId) {
47 var subEventName = GetUniqueSubEventName(opt_eventName);
48 EventBindings.Event.call(this,
49 subEventName,
50 opt_argSchemas,
51 opt_eventOptions,
52 opt_webViewInstanceId);
53
54 // TODO(lazyboy): When do we dispose this listener?
55 ContextMenusEvent.addListener(function() {
56 // Re-dispatch to subEvent's listeners.
57 $Function.apply(this.dispatch, this, $Array.slice(arguments));
58 }.bind(this), {instanceId: opt_webViewInstanceId || 0});
59 }
60
61 ContextMenusOnClickedEvent.prototype = {
62 __proto__: EventBindings.Event.prototype
63 };
64
65 /**
66 * An instance of this class is exposed as <webview>.contextMenus.
67 * @constructor
68 */
69 function WebViewContextMenusImpl(viewInstanceId) {
70 this.viewInstanceId_ = viewInstanceId;
71 }
72
73 WebViewContextMenusImpl.prototype.create = function() {
74 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
75 return $Function.apply(ChromeWebView.contextMenusCreate, null, args);
76 };
77
78 WebViewContextMenusImpl.prototype.remove = function() {
79 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
80 return $Function.apply(ChromeWebView.contextMenusRemove, null, args);
81 };
82
83 WebViewContextMenusImpl.prototype.removeAll = function() {
84 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
85 return $Function.apply(ChromeWebView.contextMenusRemoveAll, null, args);
86 };
87
88 WebViewContextMenusImpl.prototype.update = function() {
89 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
90 return $Function.apply(ChromeWebView.contextMenusUpdate, null, args);
91 };
92
93 var WebViewContextMenus = utils.expose(
94 'WebViewContextMenus', WebViewContextMenusImpl,
95 { functions: ['create', 'remove', 'removeAll', 'update'] });
96
97 /** @private */
98 WebViewEvents.prototype.handleContextMenu = function(event, eventName) {
99 var webViewEvent = this.makeDomEvent(event, eventName);
100 var requestId = event.requestId;
101 // Construct the event.menu object.
102 var actionTaken = false;
103 var validateCall = function() {
104 var ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN = '<webview>: ' +
105 'An action has already been taken for this "contextmenu" event.';
106
107 if (actionTaken) {
108 throw new Error(ERROR_MSG_CONTEXT_MENU_ACTION_ALREADY_TAKEN);
109 }
110 actionTaken = true;
111 };
112 var menu = {
113 show: function(items) {
114 validateCall();
115 // TODO(lazyboy): WebViewShowContextFunction doesn't do anything useful
116 // with |items|, implement.
117 ChromeWebView.showContextMenu(this.view.guest.getId(), requestId, items);
118 }.bind(this)
119 };
120 webViewEvent.menu = menu;
121 var element = this.view.element;
122 var defaultPrevented = !element.dispatchEvent(webViewEvent);
123 if (actionTaken) {
124 return;
125 }
126 if (!defaultPrevented) {
127 actionTaken = true;
128 // The default action is equivalent to just showing the context menu as is.
129 ChromeWebView.showContextMenu(
130 this.view.guest.getId(), requestId, undefined);
131
132 // TODO(lazyboy): Figure out a way to show warning message only when
133 // listeners are registered for this event.
134 } // else we will ignore showing the context menu completely.
135 };
136
137 /** @private */
138 WebViewImpl.prototype.setupExperimentalContextMenus = function() {
139 var createContextMenus = function() {
140 return function() {
141 if (this.contextMenus_) {
142 return this.contextMenus_;
143 }
144
145 this.contextMenus_ = new WebViewContextMenus(this.viewInstanceId);
146
147 // Define 'onClicked' event property on |this.contextMenus_|.
148 var getOnClickedEvent = function() {
149 return function() {
150 if (!this.contextMenusOnClickedEvent_) {
151 var eventName = 'chromeWebViewInternal.onClicked';
152 // TODO(lazyboy): Find event by name instead of events[0].
153 var eventSchema = ChromeWebViewSchema.events[0];
154 var eventOptions = {supportsListeners: true};
155 var onClickedEvent = new ContextMenusOnClickedEvent(
156 eventName, eventSchema, eventOptions, this.viewInstanceId);
157 this.contextMenusOnClickedEvent_ = onClickedEvent;
158 return onClickedEvent;
159 }
160 return this.contextMenusOnClickedEvent_;
161 }.bind(this);
162 }.bind(this);
163 Object.defineProperty(
164 this.contextMenus_,
165 'onClicked',
166 {get: getOnClickedEvent(), enumerable: true});
167
168 return this.contextMenus_;
169 }.bind(this);
170 }.bind(this);
171
172 // Expose <webview>.contextMenus object.
173 Object.defineProperty(
174 this.element,
175 'contextMenus',
176 {
177 get: createContextMenus(),
178 enumerable: true
179 });
180 };
OLDNEW
« no previous file with comments | « chrome/renderer/resources/extensions/web_view/chrome_web_view.js ('k') | chrome/renderer/resources/renderer_resources.grd » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698