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 // This module implements experimental API for <webview>.
6 // See web_view.js for details.
8 // <webview> Experimental API is only available on canary and dev channels of
11 var CreateEvent
= require('webView').CreateEvent
;
12 var MessagingNatives
= requireNative('messaging_natives');
13 var WebViewInternal
= require('webView').WebViewInternal
;
14 var WebView
= require('webView').WebView
;
16 // WEB_VIEW_EXPERIMENTAL_EVENTS is a map of experimental <webview> DOM event
17 // names to their associated extension event descriptor objects.
18 // An event listener will be attached to the extension event |evt| specified in
20 // |fields| specifies the public-facing fields in the DOM event that are
21 // accessible to <webview> developers.
22 // |customHandler| allows a handler function to be called each time an extension
23 // event is caught by its event listener. The DOM event should be dispatched
24 // within this handler function. With no handler function, the DOM event
25 // will be dispatched by default each time the extension event is caught.
26 // |cancelable| (default: false) specifies whether the event's default
27 // behavior can be canceled. If the default action associated with the event
28 // is prevented, then its dispatch function will return false in its event
29 // handler. The event must have a custom handler for this to be meaningful.
30 var WEB_VIEW_EXPERIMENTAL_EVENTS
= {
33 customHandler: function(webViewInternal
, event
, webViewEvent
) {
34 webViewInternal
.handleDialogEvent(event
, webViewEvent
);
36 evt
: CreateEvent('webview.onDialog'),
37 fields
: ['defaultPromptText', 'messageText', 'messageType', 'url']
40 evt
: CreateEvent('webview.onZoomChange'),
41 fields
: ['oldZoomFactor', 'newZoomFactor']
48 WebViewInternal
.prototype.maybeAttachWebRequestEventToObject
=
49 function(obj
, eventName
, webRequestEvent
) {
50 Object
.defineProperty(
63 WebViewInternal
.prototype.setZoom = function(zoomFactor
) {
64 if (!this.instanceId
) {
67 WebView
.setZoom(this.instanceId
, zoomFactor
);
73 WebViewInternal
.prototype.handleDialogEvent
=
74 function(event
, webViewEvent
) {
75 var showWarningMessage = function(dialogType
) {
76 var VOWELS
= ['a', 'e', 'i', 'o', 'u'];
77 var WARNING_MSG_DIALOG_BLOCKED
= '<webview>: %1 %2 dialog was blocked.';
78 var article
= (VOWELS
.indexOf(dialogType
.charAt(0)) >= 0) ? 'An' : 'A';
79 var output
= WARNING_MSG_DIALOG_BLOCKED
.replace('%1', article
);
80 output
= output
.replace('%2', dialogType
);
81 window
.console
.warn(output
);
85 var browserPluginNode
= this.browserPluginNode
;
86 var webviewNode
= this.webviewNode
;
88 var requestId
= event
.requestId
;
89 var actionTaken
= false;
91 var validateCall = function() {
92 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN
= '<webview>: ' +
93 'An action has already been taken for this "dialog" event.';
96 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN
);
102 ok: function(user_input
) {
104 user_input
= user_input
|| '';
105 WebView
.setPermission(self
.instanceId
, requestId
, 'allow', user_input
);
109 WebView
.setPermission(self
.instanceId
, requestId
, 'deny');
112 webViewEvent
.dialog
= dialog
;
114 var defaultPrevented
= !webviewNode
.dispatchEvent(webViewEvent
);
119 if (defaultPrevented
) {
120 // Tell the JavaScript garbage collector to track lifetime of |dialog| and
121 // call back when the dialog object has been collected.
122 MessagingNatives
.BindToGC(dialog
, function() {
123 // Avoid showing a warning message if the decision has already been made.
127 WebView
.setPermission(
128 self
.instanceId
, requestId
, 'default', '', function(allowed
) {
132 showWarningMessage(event
.messageType
);
137 // The default action is equivalent to canceling the dialog.
138 WebView
.setPermission(
139 self
.instanceId
, requestId
, 'default', '', function(allowed
) {
143 showWarningMessage(event
.messageType
);
148 WebViewInternal
.prototype.maybeGetExperimentalEvents = function() {
149 return WEB_VIEW_EXPERIMENTAL_EVENTS
;
153 WebViewInternal
.prototype.maybeGetExperimentalPermissions = function() {
158 WebViewInternal
.prototype.maybeSetCurrentZoomFactor
=
159 function(zoomFactor
) {
160 this.currentZoomFactor
= zoomFactor
;
164 WebViewInternal
.prototype.clearData = function(var_args
) {
165 if (!this.instanceId
) {
168 var args
= $Array
.concat([this.instanceId
], $Array
.slice(arguments
));
169 $Function
.apply(WebView
.clearData
, null, args
);
173 WebViewInternal
.prototype.setZoom = function(zoomFactor
, callback
) {
174 if (!this.instanceId
) {
177 WebView
.setZoom(this.instanceId
, zoomFactor
, callback
);
180 WebViewInternal
.prototype.getZoom = function(callback
) {
181 if (!this.instanceId
) {
184 WebView
.getZoom(this.instanceId
, callback
);
188 WebViewInternal
.prototype.captureVisibleRegion = function(spec
, callback
) {
189 WebView
.captureVisibleRegion(this.instanceId
, spec
, callback
);
192 WebViewInternal
.maybeRegisterExperimentalAPIs = function(proto
) {
193 proto
.clearData = function(var_args
) {
194 var internal = privates(this).internal;
195 $Function
.apply(internal.clearData
, internal, arguments
);
198 proto
.setZoom = function(zoomFactor
, callback
) {
199 privates(this).internal.setZoom(zoomFactor
, callback
);
202 proto
.getZoom = function(callback
) {
203 return privates(this).internal.getZoom(callback
);
206 proto
.captureVisibleRegion = function(spec
, callback
) {
207 privates(this).internal.captureVisibleRegion(spec
, callback
);