Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / renderer / resources / extensions / web_view / chrome_web_view.js
blob2d8c445d994c1e3ecd65907c9eee4694d6155e6e
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');
27 // See comment above.
28 var ContextMenusHandlerEvent =
29     CreateEvent('chromeWebViewInternal.onContextMenuShow');
31 // -----------------------------------------------------------------------------
32 // ContextMenusOnClickedEvent object.
34 // This event is exposed as <webview>.contextMenus.onClicked.
35 function ContextMenusOnClickedEvent(webViewInstanceId,
36                                     opt_eventName,
37                                     opt_argSchemas,
38                                     opt_eventOptions) {
39   var subEventName = GetUniqueSubEventName(opt_eventName);
40   EventBindings.Event.call(this,
41                            subEventName,
42                            opt_argSchemas,
43                            opt_eventOptions,
44                            webViewInstanceId);
46   var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
47   if (!view) {
48     return;
49   }
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,
59                                         opt_eventName,
60                                         opt_argSchemas,
61                                         opt_eventOptions) {
62   var subEventName = GetUniqueSubEventName(opt_eventName);
63   EventBindings.Event.call(this,
64                            subEventName,
65                            opt_argSchemas,
66                            opt_eventOptions,
67                            webViewInstanceId);
69   var view = GuestViewInternalNatives.GetViewFromID(webViewInstanceId);
70   if (!view) {
71     return;
72   }
73   view.events.addScopedListener(ContextMenusHandlerEvent, function(e) {
74     var defaultPrevented = false;
75     var event = {
76       'preventDefault': function() { defaultPrevented = true; }
77     };
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
85       // currently.
86       var items = [];
87       var guestInstanceId = GuestViewInternalNatives.
88           GetViewFromID(webViewInstanceId).guest.getId();
89       ChromeWebView.showContextMenu(guestInstanceId, e.requestId, items);
90     }
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';
134     var eventSchema =
135         Utils.lookup(ChromeWebViewSchema.events, 'name', 'onShow');
136     var eventOptions = {supportsListeners: true};
137     this.contextMenusOnContextMenuEvent_ = new ContextMenusOnContextMenuEvent(
138         this.viewInstanceId, eventName, eventSchema, eventOptions);
139   }
141   var createContextMenus = function() {
142     return this.weakWrapper(function() {
143       if (this.contextMenus_) {
144         return this.contextMenus_;
145       }
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';
154             var eventSchema =
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;
161           }
162           return this.contextMenusOnClickedEvent_;
163         });
164       }.bind(this);
165       $Object.defineProperty(
166           this.contextMenus_,
167           'onClicked',
168           {get: getOnClickedEvent(), enumerable: true});
169       $Object.defineProperty(
170           this.contextMenus_,
171           'onShow',
172           {
173             get: this.weakWrapper(function() {
174               return this.contextMenusOnContextMenuEvent_;
175             }),
176             enumerable: true
177           });
178       return this.contextMenus_;
179     });
180   }.bind(this);
182   // Expose <webview>.contextMenus object.
183   // TODO(lazyboy): Add documentation for contextMenus:
184   // http://crbug.com/470979.
185   $Object.defineProperty(
186       this.element,
187       'contextMenus',
188       {
189         get: createContextMenus(),
190         enumerable: true
191       });
194 function GetUniqueSubEventName(eventName) {
195   return eventName + '/' + idGeneratorNatives.GetNextId();