1 // Copyright 2014 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 chrome-specific <webview> API.
6 // See web_view_api_methods.js for details.
8 var ChromeWebView = require('chromeWebViewInternal').ChromeWebView;
9 var ChromeWebViewSchema =
10 requireNative('schema_registry').GetSchema('chromeWebViewInternal');
11 var CreateEvent = require('guestViewEvents').CreateEvent;
12 var EventBindings = require('event_bindings');
13 var GuestViewInternalNatives = requireNative('guest_view_internal');
14 var idGeneratorNatives = requireNative('id_generator');
15 var Utils = require('utils');
16 var WebViewImpl = require('webView').WebViewImpl;
18 // This is the only "webViewInternal.onClicked" named event for this renderer.
20 // Since we need an event per <webview>, we define events with suffix
21 // (subEventName) in each of the <webview>. Behind the scenes, this event is
22 // registered as a ContextMenusEvent, with filter set to the webview's
23 // |viewInstanceId|. Any time a ContextMenusEvent is dispatched, we re-dispatch
24 // it to the subEvent's listeners. This way
25 // <webview>.contextMenus.onClicked behave as a regular chrome Event type.
26 var ContextMenusEvent = CreateEvent('chromeWebViewInternal.onClicked');
28 var ContextMenusHandlerEvent =
29 CreateEvent('chromeWebViewInternal.onContextMenuShow');
31 // -----------------------------------------------------------------------------
32 // ContextMenusOnClickedEvent object.
34 // This event is exposed as <webview>.contextMenus.onClicked.
35 function ContextMenusOnClickedEvent(webViewInstanceId,
39 var subEventName = GetUniqueSubEventName(opt_eventName);
40 EventBindings.Event.call(this,
46 var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
50 view.events.addScopedListener(ContextMenusEvent, function() {
51 // Re-dispatch to subEvent's listeners.
52 $Function.apply(this.dispatch, this, $Array.slice(arguments));
53 }.bind(this), {instanceId: webViewInstanceId});
56 ContextMenusOnClickedEvent.prototype.__proto__ = EventBindings.Event.prototype;
58 function ContextMenusOnContextMenuEvent(webViewInstanceId,
62 var subEventName = GetUniqueSubEventName(opt_eventName);
63 EventBindings.Event.call(this,
69 var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
73 view.events.addScopedListener(ContextMenusHandlerEvent, function(e) {
74 var defaultPrevented = false;
76 'preventDefault': function() { defaultPrevented = true; }
79 // Re-dispatch to subEvent's listeners.
80 $Function.apply(this.dispatch, this, [event]);
82 if (!defaultPrevented) {
83 // TODO(lazyboy): Remove |items| parameter completely from
84 // ChromeWebView.showContextMenu as we don't do anything useful with it
87 var guestInstanceId = GuestViewInternalNatives.
88 GetViewFromID(webViewInstanceId).guest.getId();
89 ChromeWebView.showContextMenu(guestInstanceId, e.requestId, items);
91 }.bind(this), {instanceId: webViewInstanceId});
94 ContextMenusOnContextMenuEvent.prototype.__proto__ =
95 EventBindings.Event.prototype;
97 // -----------------------------------------------------------------------------
98 // WebViewContextMenusImpl object.
100 // An instance of this class is exposed as <webview>.contextMenus.
101 function WebViewContextMenusImpl(viewInstanceId) {
102 this.viewInstanceId_ = viewInstanceId;
105 WebViewContextMenusImpl.prototype.create = function() {
106 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
107 return $Function.apply(ChromeWebView.contextMenusCreate, null, args);
110 WebViewContextMenusImpl.prototype.remove = function() {
111 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
112 return $Function.apply(ChromeWebView.contextMenusRemove, null, args);
115 WebViewContextMenusImpl.prototype.removeAll = function() {
116 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
117 return $Function.apply(ChromeWebView.contextMenusRemoveAll, null, args);
120 WebViewContextMenusImpl.prototype.update = function() {
121 var args = $Array.concat([this.viewInstanceId_], $Array.slice(arguments));
122 return $Function.apply(ChromeWebView.contextMenusUpdate, null, args);
125 var WebViewContextMenus = Utils.expose(
126 'WebViewContextMenus', WebViewContextMenusImpl,
127 { functions: ['create', 'remove', 'removeAll', 'update'] });
129 // -----------------------------------------------------------------------------
131 WebViewImpl.prototype.maybeSetupContextMenus = function() {
132 if (!this.contextMenusOnContextMenuEvent_) {
133 var eventName = 'chromeWebViewInternal.onContextMenuShow';
135 Utils.lookup(ChromeWebViewSchema.events, 'name', 'onShow');
136 var eventOptions = {supportsListeners: true};
137 this.contextMenusOnContextMenuEvent_ = new ContextMenusOnContextMenuEvent(
138 this.viewInstanceId, eventName, eventSchema, eventOptions);
141 var createContextMenus = function() {
142 return this.weakWrapper(function() {
143 if (this.contextMenus_) {
144 return this.contextMenus_;
147 this.contextMenus_ = new WebViewContextMenus(this.viewInstanceId);
149 // Define 'onClicked' event property on |this.contextMenus_|.
150 var getOnClickedEvent = function() {
151 return this.weakWrapper(function() {
152 if (!this.contextMenusOnClickedEvent_) {
153 var eventName = 'chromeWebViewInternal.onClicked';
155 Utils.lookup(ChromeWebViewSchema.events, 'name', 'onClicked');
156 var eventOptions = {supportsListeners: true};
157 var onClickedEvent = new ContextMenusOnClickedEvent(
158 this.viewInstanceId, eventName, eventSchema, eventOptions);
159 this.contextMenusOnClickedEvent_ = onClickedEvent;
160 return onClickedEvent;
162 return this.contextMenusOnClickedEvent_;
165 $Object.defineProperty(
168 {get: getOnClickedEvent(), enumerable: true});
169 $Object.defineProperty(
173 get: this.weakWrapper(function() {
174 return this.contextMenusOnContextMenuEvent_;
178 return this.contextMenus_;
182 // Expose <webview>.contextMenus object.
183 // TODO(lazyboy): Add documentation for contextMenus:
184 // http://crbug.com/470979.
185 $Object.defineProperty(
189 get: createContextMenus(),
194 function GetUniqueSubEventName(eventName) {
195 return eventName + '/' + idGeneratorNatives.GetNextId();