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 // Shim extension to provide permission request API (and possibly other future
6 // experimental APIs) for <webview> tag.
7 // See web_view.js for details.
9 // We want to control the permission API feature in <webview> separately from
10 // the <webview> feature itself. <webview> is available in stable channel, but
11 // permission API would only be available for channels CHANNEL_DEV and
14 var WebRequestEvent
= require('webRequestInternal').WebRequestEvent
;
15 var webRequestSchema
=
16 requireNative('schema_registry').GetSchema('webRequest');
17 var WebView
= require('webView').WebView
;
22 WebView
.prototype.maybeSetupExperimentalAPI_ = function() {
23 this.setupWebRequestEvents_();
24 this.setupDialogEvent_();
30 WebView
.prototype.setupWebRequestEvents_ = function() {
33 var createWebRequestEvent = function(webRequestEvent
) {
35 if (!self
[webRequestEvent
.name
+ '_']) {
36 self
[webRequestEvent
.name
+ '_'] =
38 'webview.' + webRequestEvent
.name
,
39 webRequestEvent
.parameters
,
40 webRequestEvent
.extraParameters
, null,
41 self
.viewInstanceId_
);
43 return self
[webRequestEvent
.name
+ '_'];
47 // Populate the WebRequest events from the API definition.
48 for (var i
= 0; i
< webRequestSchema
.events
.length
; ++i
) {
49 var webRequestEvent
= createWebRequestEvent(webRequestSchema
.events
[i
]);
50 Object
.defineProperty(
52 webRequestSchema
.events
[i
].name
,
58 Object
.defineProperty(
60 webRequestSchema
.events
[i
].name
,
67 Object
.defineProperty(
81 WebView
.prototype.setupDialogEvent_ = function() {
82 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN
= '<webview>: ' +
83 'An action has already been taken for this "dialog" event.';
85 var showWarningMessage = function(dialogType
) {
86 var VOWELS
= ['a', 'e', 'i', 'o', 'u'];
87 var WARNING_MSG_DIALOG_BLOCKED
= '<webview>: %1 %2 dialog was blocked.';
88 var article
= (VOWELS
.indexOf(dialogType
.charAt(0)) >= 0) ? 'An' : 'A';
89 var output
= WARNING_MSG_DIALOG_BLOCKED
.replace('%1', article
);
90 output
= output
.replace('%2', dialogType
);
94 var DIALOG_EVENT_ATTRIBUTES
= [
102 var node
= this.webviewNode_
;
103 var browserPluginNode
= this.browserPluginNode_
;
105 var onTrackedObjectGone = function(requestId
, dialogType
, e
) {
106 var detail
= e
.detail
? JSON
.parse(e
.detail
) : {};
107 if (detail
.id
!= requestId
)
109 // If the request was pending then show a warning indiciating that a new
110 // window was blocked.
111 if (browserPluginNode
['-internal-setPermission'](requestId
, false, '')) {
112 showWarningMessage(dialogType
);
116 browserPluginNode
.addEventListener('-internal-dialog', function(e
) {
117 var evt
= new Event('dialog', { bubbles
: true, cancelable
: true });
118 var detail
= e
.detail
? JSON
.parse(e
.detail
) : {};
120 $Array
.forEach(DIALOG_EVENT_ATTRIBUTES
, function(attribName
) {
121 evt
[attribName
] = detail
[attribName
];
123 var requestId
= detail
.requestId
;
124 var actionTaken
= false;
126 var validateCall = function() {
128 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN
);
134 ok: function(user_input
) {
136 browserPluginNode
['-internal-setPermission'](
137 requestId
, true, user_input
);
141 browserPluginNode
['-internal-setPermission'](requestId
, false, '');
146 var defaultPrevented
= !node
.dispatchEvent(evt
);
151 if (defaultPrevented
) {
152 // Tell the JavaScript garbage collector to track lifetime of |dialog| and
153 // call back when the dialog object has been collected.
154 var onTrackedObjectGoneWithRequestId
=
156 onTrackedObjectGone
, self
, requestId
, detail
.messageType
);
157 browserPluginNode
.addEventListener('-internal-trackedobjectgone',
158 onTrackedObjectGoneWithRequestId
);
159 browserPluginNode
['-internal-trackObjectLifetime'](dialog
, requestId
);
162 // The default action is equivalent to canceling the dialog.
163 browserPluginNode
['-internal-setPermission'](requestId
, false, '');
164 showWarningMessage(detail
.messageType
);