OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This module implements experimental API for <webview>. | 5 // This module implements experimental API for <webview>. |
6 // See web_view.js for details. | 6 // See web_view.js for details. |
7 // | 7 // |
8 // <webview> Experimental API is only available on canary and dev channels of | 8 // <webview> Experimental API is only available on canary and dev channels of |
9 // Chrome. | 9 // Chrome. |
10 | 10 |
(...skipping 15 matching lines...) Expand all Loading... |
26 // accessible to <webview> developers. | 26 // accessible to <webview> developers. |
27 // |customHandler| allows a handler function to be called each time an extension | 27 // |customHandler| allows a handler function to be called each time an extension |
28 // event is caught by its event listener. The DOM event should be dispatched | 28 // event is caught by its event listener. The DOM event should be dispatched |
29 // within this handler function. With no handler function, the DOM event | 29 // within this handler function. With no handler function, the DOM event |
30 // will be dispatched by default each time the extension event is caught. | 30 // will be dispatched by default each time the extension event is caught. |
31 // |cancelable| (default: false) specifies whether the event's default | 31 // |cancelable| (default: false) specifies whether the event's default |
32 // behavior can be canceled. If the default action associated with the event | 32 // behavior can be canceled. If the default action associated with the event |
33 // is prevented, then its dispatch function will return false in its event | 33 // is prevented, then its dispatch function will return false in its event |
34 // handler. The event must have a custom handler for this to be meaningful. | 34 // handler. The event must have a custom handler for this to be meaningful. |
35 var WEB_VIEW_EXPERIMENTAL_EVENTS = { | 35 var WEB_VIEW_EXPERIMENTAL_EVENTS = { |
36 'dialog': { | |
37 cancelable: true, | |
38 customHandler: function(webViewInternal, event, webViewEvent) { | |
39 webViewInternal.handleDialogEvent(event, webViewEvent); | |
40 }, | |
41 evt: CreateEvent('webview.onDialog'), | |
42 fields: ['defaultPromptText', 'messageText', 'messageType', 'url'] | |
43 }, | |
44 'findupdate': { | 36 'findupdate': { |
45 evt: CreateEvent('webview.onFindReply'), | 37 evt: CreateEvent('webview.onFindReply'), |
46 fields: [ | 38 fields: [ |
47 'searchText', | 39 'searchText', |
48 'numberOfMatches', | 40 'numberOfMatches', |
49 'activeMatchOrdinal', | 41 'activeMatchOrdinal', |
50 'selectionRect', | 42 'selectionRect', |
51 'canceled', | 43 'canceled', |
52 'finalUpdate' | 44 'finalUpdate' |
53 ] | 45 ] |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 /** | 137 /** |
146 * @private | 138 * @private |
147 */ | 139 */ |
148 WebViewInternal.prototype.setZoom = function(zoomFactor) { | 140 WebViewInternal.prototype.setZoom = function(zoomFactor) { |
149 if (!this.instanceId) { | 141 if (!this.instanceId) { |
150 return; | 142 return; |
151 } | 143 } |
152 WebView.setZoom(this.instanceId, zoomFactor); | 144 WebView.setZoom(this.instanceId, zoomFactor); |
153 }; | 145 }; |
154 | 146 |
155 /** | |
156 * @private | |
157 */ | |
158 WebViewInternal.prototype.handleDialogEvent = | |
159 function(event, webViewEvent) { | |
160 var showWarningMessage = function(dialogType) { | |
161 var VOWELS = ['a', 'e', 'i', 'o', 'u']; | |
162 var WARNING_MSG_DIALOG_BLOCKED = '<webview>: %1 %2 dialog was blocked.'; | |
163 var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A'; | |
164 var output = WARNING_MSG_DIALOG_BLOCKED.replace('%1', article); | |
165 output = output.replace('%2', dialogType); | |
166 window.console.warn(output); | |
167 }; | |
168 | |
169 var self = this; | |
170 var browserPluginNode = this.browserPluginNode; | |
171 var webviewNode = this.webviewNode; | |
172 | |
173 var requestId = event.requestId; | |
174 var actionTaken = false; | |
175 | |
176 var validateCall = function() { | |
177 var ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN = '<webview>: ' + | |
178 'An action has already been taken for this "dialog" event.'; | |
179 | |
180 if (actionTaken) { | |
181 throw new Error(ERROR_MSG_DIALOG_ACTION_ALREADY_TAKEN); | |
182 } | |
183 actionTaken = true; | |
184 }; | |
185 | |
186 var dialog = { | |
187 ok: function(user_input) { | |
188 validateCall(); | |
189 user_input = user_input || ''; | |
190 WebView.setPermission(self.instanceId, requestId, 'allow', user_input); | |
191 }, | |
192 cancel: function() { | |
193 validateCall(); | |
194 WebView.setPermission(self.instanceId, requestId, 'deny'); | |
195 } | |
196 }; | |
197 webViewEvent.dialog = dialog; | |
198 | |
199 var defaultPrevented = !webviewNode.dispatchEvent(webViewEvent); | |
200 if (actionTaken) { | |
201 return; | |
202 } | |
203 | |
204 if (defaultPrevented) { | |
205 // Tell the JavaScript garbage collector to track lifetime of |dialog| and | |
206 // call back when the dialog object has been collected. | |
207 MessagingNatives.BindToGC(dialog, function() { | |
208 // Avoid showing a warning message if the decision has already been made. | |
209 if (actionTaken) { | |
210 return; | |
211 } | |
212 WebView.setPermission( | |
213 self.instanceId, requestId, 'default', '', function(allowed) { | |
214 if (allowed) { | |
215 return; | |
216 } | |
217 showWarningMessage(event.messageType); | |
218 }); | |
219 }); | |
220 } else { | |
221 actionTaken = true; | |
222 // The default action is equivalent to canceling the dialog. | |
223 WebView.setPermission( | |
224 self.instanceId, requestId, 'default', '', function(allowed) { | |
225 if (allowed) { | |
226 return; | |
227 } | |
228 showWarningMessage(event.messageType); | |
229 }); | |
230 } | |
231 }; | |
232 | |
233 WebViewInternal.prototype.maybeGetExperimentalEvents = function() { | 147 WebViewInternal.prototype.maybeGetExperimentalEvents = function() { |
234 return WEB_VIEW_EXPERIMENTAL_EVENTS; | 148 return WEB_VIEW_EXPERIMENTAL_EVENTS; |
235 }; | 149 }; |
236 | 150 |
237 /** @private */ | 151 /** @private */ |
238 WebViewInternal.prototype.maybeGetExperimentalPermissions = function() { | 152 WebViewInternal.prototype.maybeGetExperimentalPermissions = function() { |
239 return []; | 153 return []; |
240 }; | 154 }; |
241 | 155 |
242 /** @private */ | 156 /** @private */ |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 269 |
356 // Expose <webview>.contextMenus object. | 270 // Expose <webview>.contextMenus object. |
357 Object.defineProperty( | 271 Object.defineProperty( |
358 this.webviewNode, | 272 this.webviewNode, |
359 'contextMenus', | 273 'contextMenus', |
360 { | 274 { |
361 get: createContextMenus(), | 275 get: createContextMenus(), |
362 enumerable: true | 276 enumerable: true |
363 }); | 277 }); |
364 }; | 278 }; |
OLD | NEW |