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 CreateEvent = require('webView').CreateEvent;
15 var MessagingNatives = requireNative('messaging_natives');
16 var WebRequestEvent = require('webRequestInternal').WebRequestEvent;
17 var WebRequestSchema =
18 requireNative('schema_registry').GetSchema('webRequest');
19 var WebViewInternal = require('webView').WebViewInternal;
20 var WebView = require('webView').WebView;
22 var WEB_VIEW_EXPERIMENTAL_EVENTS = {
25 customHandler: function(webViewInternal, event, webViewEvent) {
26 webViewInternal.handleDialogEvent_(event, webViewEvent);
28 evt: CreateEvent('webview.onDialog'),
29 fields: ['defaultPromptText', 'messageText', 'messageType', 'url']
36 WebViewInternal.prototype.maybeAttachWebRequestEventToWebview_ =
37 function(eventName, webRequestEvent) {
38 Object.defineProperty(
51 WebViewInternal.prototype.handleDialogEvent_ =
52 function(event, webViewEvent) {
53 var showWarningMessage = function(dialogType) {
54 var VOWELS = ['a', 'e', 'i', 'o', 'u'];
55 var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.';
56 var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A';
57 var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article);
58 output = output.replace('%2', dialogType);
59 window.console.warn(output);
63 var browserPluginNode = this.browserPluginNode_;
64 var webviewNode = this.webviewNode_;
66 var requestId = event.requestId;
67 var actionTaken = false;
69 var validateCall = function() {
70 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' +
71 'An action has already been taken for this "dialog" event.';
74 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN);
80 ok: function(user_input) {
82 user_input = user_input || '';
83 WebView.setPermission(self.instanceId_, requestId, 'allow', user_input);
87 WebView.setPermission(self.instanceId_, requestId, 'deny');
90 webViewEvent.dialog = dialog;
92 var defaultPrevented = !webviewNode.dispatchEvent(webViewEvent);
97 if (defaultPrevented) {
98 // Tell the JavaScript garbage collector to track lifetime of |dialog| and
99 // call back when the dialog object has been collected.
100 MessagingNatives.BindToGC(dialog, function() {
101 // Avoid showing a warning message if the decision has already been made.
105 WebView.setPermission(
106 self.instanceId_, requestId, 'default', '', function(allowed) {
110 showWarningMessage(event.messageType);
115 // The default action is equivalent to canceling the dialog.
116 WebView.setPermission(
117 self.instanceId_, requestId, 'default', '', function(allowed) {
121 showWarningMessage(event.messageType);
127 WebViewInternal.prototype.maybeGetExperimentalEvents_ = function() {
128 return WEB_VIEW_EXPERIMENTAL_EVENTS;
131 WebViewInternal.prototype.maybeGetExperimentalPermissions_ = function() {
132 return ['loadplugin'];
136 WebViewInternal.prototype.clearData_ = function(var_args) {
137 if (!this.instanceId_) {
140 var args = $Array.concat([this.instanceId_], $Array.slice(arguments));
141 $Function.apply(WebView.clearData, null, args);
145 WebViewInternal.prototype.getUserAgent_ = function() {
146 return this.userAgentOverride_ || navigator.userAgent;
150 WebViewInternal.prototype.isUserAgentOverridden_ = function() {
151 return !!this.userAgentOverride_ &&
152 this.userAgentOverride_ != navigator.userAgent;
156 WebViewInternal.prototype.setUserAgentOverride_ = function(userAgentOverride) {
157 this.userAgentOverride_ = userAgentOverride;
158 if (!this.instanceId_) {
159 // If we are not attached yet, then we will pick up the user agent on
163 WebView.overrideUserAgent(this.instanceId_, userAgentOverride);
166 WebViewInternal.maybeRegisterExperimentalAPIs = function(proto, secret) {
167 proto.clearData = function(var_args) {
168 var internal = this.internal_(secret);
169 $Function.apply(internal.clearData_, internal, arguments);
172 proto.getUserAgent = function() {
173 return this.internal_(secret).getUserAgent_();
176 proto.isUserAgentOverridden = function() {
177 return this.internal_(secret).isUserAgentOverridden_();
180 proto.setUserAgentOverride = function(userAgentOverride) {
181 this.internal_(secret).setUserAgentOverride_(userAgentOverride);