OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 WebView (<webview>) as a custom element that wraps a | 5 // This module implements WebView (<webview>) as a custom element that wraps a |
6 // BrowserPlugin object element. The object element is hidden within | 6 // BrowserPlugin object element. The object element is hidden within |
7 // the shadow DOM of the WebView element. | 7 // the shadow DOM of the WebView element. |
8 | 8 |
9 var DocumentNatives = requireNative('document_natives'); | 9 var DocumentNatives = requireNative('document_natives'); |
10 var GuestViewInternal = | 10 var GuestViewInternal = |
11 require('binding').Binding.create('guestViewInternal').generate(); | 11 require('binding').Binding.create('guestViewInternal').generate(); |
| 12 var guestViewInternalNatives = requireNative('guest_view_internal'); |
12 var IdGenerator = requireNative('id_generator'); | 13 var IdGenerator = requireNative('id_generator'); |
13 // TODO(lazyboy): Rename this to WebViewInternal and call WebViewInternal | |
14 // something else. | |
15 var WebView = require('webViewInternal').WebView; | |
16 var WebViewEvents = require('webViewEvents').WebViewEvents; | 14 var WebViewEvents = require('webViewEvents').WebViewEvents; |
17 var guestViewInternalNatives = requireNative('guest_view_internal'); | 15 var WebViewInternal = require('webViewInternal').WebViewInternal; |
18 | 16 |
19 // Attributes. | 17 // Attributes. |
20 var WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY = 'allowtransparency'; | 18 var WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY = 'allowtransparency'; |
21 var WEB_VIEW_ATTRIBUTE_AUTOSIZE = 'autosize'; | 19 var WEB_VIEW_ATTRIBUTE_AUTOSIZE = 'autosize'; |
22 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; | 20 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; |
23 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; | 21 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; |
24 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; | 22 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; |
25 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; | 23 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; |
26 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'; | 24 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'; |
27 var AUTO_SIZE_ATTRIBUTES = [ | 25 var AUTO_SIZE_ATTRIBUTES = [ |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 this.persistStorage = true; | 75 this.persistStorage = true; |
78 } else { | 76 } else { |
79 this.persistStorage = false; | 77 this.persistStorage = false; |
80 } | 78 } |
81 | 79 |
82 this.storagePartitionId = value; | 80 this.storagePartitionId = value; |
83 return result; | 81 return result; |
84 }; | 82 }; |
85 | 83 |
86 // Represents the internal state of the WebView node. | 84 // Represents the internal state of the WebView node. |
87 function WebViewInternal(webviewNode) { | 85 function WebView(webviewNode) { |
88 privates(webviewNode).internal = this; | 86 privates(webviewNode).internal = this; |
89 this.webviewNode = webviewNode; | 87 this.webviewNode = webviewNode; |
90 this.attached = false; | 88 this.attached = false; |
91 this.pendingGuestCreation = false; | 89 this.pendingGuestCreation = false; |
92 this.elementAttached = false; | 90 this.elementAttached = false; |
93 | 91 |
94 this.beforeFirstNavigation = true; | 92 this.beforeFirstNavigation = true; |
95 this.contentWindow = null; | 93 this.contentWindow = null; |
96 this.validPartitionId = true; | 94 this.validPartitionId = true; |
97 // Used to save some state upon deferred attachment. | 95 // Used to save some state upon deferred attachment. |
(...skipping 13 matching lines...) Expand all Loading... |
111 this.setupFocusPropagation(); | 109 this.setupFocusPropagation(); |
112 this.setupWebviewNodeProperties(); | 110 this.setupWebviewNodeProperties(); |
113 | 111 |
114 this.viewInstanceId = IdGenerator.GetNextId(); | 112 this.viewInstanceId = IdGenerator.GetNextId(); |
115 | 113 |
116 new WebViewEvents(this, this.viewInstanceId); | 114 new WebViewEvents(this, this.viewInstanceId); |
117 | 115 |
118 shadowRoot.appendChild(this.browserPluginNode); | 116 shadowRoot.appendChild(this.browserPluginNode); |
119 } | 117 } |
120 | 118 |
121 WebViewInternal.prototype.createBrowserPluginNode = function() { | 119 WebView.prototype.createBrowserPluginNode = function() { |
122 // We create BrowserPlugin as a custom element in order to observe changes | 120 // We create BrowserPlugin as a custom element in order to observe changes |
123 // to attributes synchronously. | 121 // to attributes synchronously. |
124 var browserPluginNode = new WebViewInternal.BrowserPlugin(); | 122 var browserPluginNode = new WebView.BrowserPlugin(); |
125 privates(browserPluginNode).internal = this; | 123 privates(browserPluginNode).internal = this; |
126 return browserPluginNode; | 124 return browserPluginNode; |
127 }; | 125 }; |
128 | 126 |
129 WebViewInternal.prototype.getGuestInstanceId = function() { | 127 WebView.prototype.getGuestInstanceId = function() { |
130 return this.guestInstanceId; | 128 return this.guestInstanceId; |
131 }; | 129 }; |
132 | 130 |
133 // Resets some state upon reattaching <webview> element to the DOM. | 131 // Resets some state upon reattaching <webview> element to the DOM. |
134 WebViewInternal.prototype.reset = function() { | 132 WebView.prototype.reset = function() { |
135 // If guestInstanceId is defined then the <webview> has navigated and has | 133 // If guestInstanceId is defined then the <webview> has navigated and has |
136 // already picked up a partition ID. Thus, we need to reset the initialization | 134 // already picked up a partition ID. Thus, we need to reset the initialization |
137 // state. However, it may be the case that beforeFirstNavigation is false BUT | 135 // state. However, it may be the case that beforeFirstNavigation is false BUT |
138 // guestInstanceId has yet to be initialized. This means that we have not | 136 // guestInstanceId has yet to be initialized. This means that we have not |
139 // heard back from createGuest yet. We will not reset the flag in this case so | 137 // heard back from createGuest yet. We will not reset the flag in this case so |
140 // that we don't end up allocating a second guest. | 138 // that we don't end up allocating a second guest. |
141 if (this.guestInstanceId) { | 139 if (this.guestInstanceId) { |
142 GuestViewInternal.destroyGuest(this.guestInstanceId); | 140 GuestViewInternal.destroyGuest(this.guestInstanceId); |
143 this.guestInstanceId = undefined; | 141 this.guestInstanceId = undefined; |
144 this.beforeFirstNavigation = true; | 142 this.beforeFirstNavigation = true; |
145 this.validPartitionId = true; | 143 this.validPartitionId = true; |
146 this.partition.validPartitionId = true; | 144 this.partition.validPartitionId = true; |
147 this.contentWindow = null; | 145 this.contentWindow = null; |
148 } | 146 } |
149 this.internalInstanceId = 0; | 147 this.internalInstanceId = 0; |
150 }; | 148 }; |
151 | 149 |
152 // Sets the <webview>.request property. | 150 // Sets the <webview>.request property. |
153 WebViewInternal.prototype.setRequestPropertyOnWebViewNode = function(request) { | 151 WebView.prototype.setRequestPropertyOnWebViewNode = function(request) { |
154 Object.defineProperty( | 152 Object.defineProperty( |
155 this.webviewNode, | 153 this.webviewNode, |
156 'request', | 154 'request', |
157 { | 155 { |
158 value: request, | 156 value: request, |
159 enumerable: true | 157 enumerable: true |
160 } | 158 } |
161 ); | 159 ); |
162 }; | 160 }; |
163 | 161 |
164 WebViewInternal.prototype.setupFocusPropagation = function() { | 162 WebView.prototype.setupFocusPropagation = function() { |
165 if (!this.webviewNode.hasAttribute('tabIndex')) { | 163 if (!this.webviewNode.hasAttribute('tabIndex')) { |
166 // <webview> needs a tabIndex in order to be focusable. | 164 // <webview> needs a tabIndex in order to be focusable. |
167 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute | 165 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute |
168 // to allow <webview> to be focusable. | 166 // to allow <webview> to be focusable. |
169 // See http://crbug.com/231664. | 167 // See http://crbug.com/231664. |
170 this.webviewNode.setAttribute('tabIndex', -1); | 168 this.webviewNode.setAttribute('tabIndex', -1); |
171 } | 169 } |
172 this.webviewNode.addEventListener('focus', function(e) { | 170 this.webviewNode.addEventListener('focus', function(e) { |
173 // Focus the BrowserPlugin when the <webview> takes focus. | 171 // Focus the BrowserPlugin when the <webview> takes focus. |
174 this.browserPluginNode.focus(); | 172 this.browserPluginNode.focus(); |
175 }.bind(this)); | 173 }.bind(this)); |
176 this.webviewNode.addEventListener('blur', function(e) { | 174 this.webviewNode.addEventListener('blur', function(e) { |
177 // Blur the BrowserPlugin when the <webview> loses focus. | 175 // Blur the BrowserPlugin when the <webview> loses focus. |
178 this.browserPluginNode.blur(); | 176 this.browserPluginNode.blur(); |
179 }.bind(this)); | 177 }.bind(this)); |
180 }; | 178 }; |
181 | 179 |
182 // Validation helper function for executeScript() and insertCSS(). | 180 // Validation helper function for executeScript() and insertCSS(). |
183 WebViewInternal.prototype.validateExecuteCodeCall = function() { | 181 WebView.prototype.validateExecuteCodeCall = function() { |
184 if (!this.guestInstanceId) { | 182 if (!this.guestInstanceId) { |
185 throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT); | 183 throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT); |
186 } | 184 } |
187 }; | 185 }; |
188 | 186 |
189 WebViewInternal.prototype.setupAutoSizeProperties = function() { | 187 WebView.prototype.setupAutoSizeProperties = function() { |
190 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { | 188 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { |
191 this[attributeName] = this.webviewNode.getAttribute(attributeName); | 189 this[attributeName] = this.webviewNode.getAttribute(attributeName); |
192 Object.defineProperty(this.webviewNode, attributeName, { | 190 Object.defineProperty(this.webviewNode, attributeName, { |
193 get: function() { | 191 get: function() { |
194 return this[attributeName]; | 192 return this[attributeName]; |
195 }.bind(this), | 193 }.bind(this), |
196 set: function(value) { | 194 set: function(value) { |
197 this.webviewNode.setAttribute(attributeName, value); | 195 this.webviewNode.setAttribute(attributeName, value); |
198 }.bind(this), | 196 }.bind(this), |
199 enumerable: true | 197 enumerable: true |
200 }); | 198 }); |
201 }.bind(this), this); | 199 }.bind(this), this); |
202 }; | 200 }; |
203 | 201 |
204 WebViewInternal.prototype.setupWebviewNodeProperties = function() { | 202 WebView.prototype.setupWebviewNodeProperties = function() { |
205 this.setupAutoSizeProperties(); | 203 this.setupAutoSizeProperties(); |
206 | 204 |
207 Object.defineProperty(this.webviewNode, | 205 Object.defineProperty(this.webviewNode, |
208 WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY, { | 206 WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY, { |
209 get: function() { | 207 get: function() { |
210 return this.allowtransparency; | 208 return this.allowtransparency; |
211 }.bind(this), | 209 }.bind(this), |
212 set: function(value) { | 210 set: function(value) { |
213 this.webviewNode.setAttribute(WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY, | 211 this.webviewNode.setAttribute(WEB_VIEW_ATTRIBUTE_ALLOWTRANSPARENCY, |
214 value); | 212 value); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 }.bind(this), | 261 }.bind(this), |
264 // No setter. | 262 // No setter. |
265 enumerable: true | 263 enumerable: true |
266 }); | 264 }); |
267 }; | 265 }; |
268 | 266 |
269 // The purpose of this mutation observer is to catch assignment to the src | 267 // The purpose of this mutation observer is to catch assignment to the src |
270 // attribute without any changes to its value. This is useful in the case | 268 // attribute without any changes to its value. This is useful in the case |
271 // where the webview guest has crashed and navigating to the same address | 269 // where the webview guest has crashed and navigating to the same address |
272 // spawns off a new process. | 270 // spawns off a new process. |
273 WebViewInternal.prototype.setupWebViewSrcAttributeMutationObserver = | 271 WebView.prototype.setupWebViewSrcAttributeMutationObserver = |
274 function() { | 272 function() { |
275 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { | 273 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { |
276 $Array.forEach(mutations, function(mutation) { | 274 $Array.forEach(mutations, function(mutation) { |
277 var oldValue = mutation.oldValue; | 275 var oldValue = mutation.oldValue; |
278 var newValue = this.webviewNode.getAttribute(mutation.attributeName); | 276 var newValue = this.webviewNode.getAttribute(mutation.attributeName); |
279 if (oldValue != newValue) { | 277 if (oldValue != newValue) { |
280 return; | 278 return; |
281 } | 279 } |
282 this.handleWebviewAttributeMutation( | 280 this.handleWebviewAttributeMutation( |
283 mutation.attributeName, oldValue, newValue); | 281 mutation.attributeName, oldValue, newValue); |
284 }.bind(this)); | 282 }.bind(this)); |
285 }.bind(this)); | 283 }.bind(this)); |
286 var params = { | 284 var params = { |
287 attributes: true, | 285 attributes: true, |
288 attributeOldValue: true, | 286 attributeOldValue: true, |
289 attributeFilter: ['src', 'partition'] | 287 attributeFilter: ['src', 'partition'] |
290 }; | 288 }; |
291 this.srcAndPartitionObserver.observe(this.webviewNode, params); | 289 this.srcAndPartitionObserver.observe(this.webviewNode, params); |
292 }; | 290 }; |
293 | 291 |
294 // This observer monitors mutations to attributes of the <webview> and | 292 // This observer monitors mutations to attributes of the <webview> and |
295 // updates the BrowserPlugin properties accordingly. In turn, updating | 293 // updates the BrowserPlugin properties accordingly. In turn, updating |
296 // a BrowserPlugin property will update the corresponding BrowserPlugin | 294 // a BrowserPlugin property will update the corresponding BrowserPlugin |
297 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more | 295 // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more |
298 // details. | 296 // details. |
299 WebViewInternal.prototype.handleWebviewAttributeMutation = | 297 WebView.prototype.handleWebviewAttributeMutation = |
300 function(name, oldValue, newValue) { | 298 function(name, oldValue, newValue) { |
301 if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) { | 299 if (AUTO_SIZE_ATTRIBUTES.indexOf(name) > -1) { |
302 this[name] = newValue; | 300 this[name] = newValue; |
303 if (!this.guestInstanceId) { | 301 if (!this.guestInstanceId) { |
304 return; | 302 return; |
305 } | 303 } |
306 // Convert autosize attribute to boolean. | 304 // Convert autosize attribute to boolean. |
307 var autosize = this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE); | 305 var autosize = this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE); |
308 GuestViewInternal.setAutoSize(this.guestInstanceId, { | 306 GuestViewInternal.setAutoSize(this.guestInstanceId, { |
309 'enableAutoSize': autosize, | 307 'enableAutoSize': autosize, |
(...skipping 15 matching lines...) Expand all Loading... |
325 | 323 |
326 if (oldValue === newValue) { | 324 if (oldValue === newValue) { |
327 return; | 325 return; |
328 } | 326 } |
329 this.allowtransparency = newValue != ''; | 327 this.allowtransparency = newValue != ''; |
330 | 328 |
331 if (!this.guestInstanceId) { | 329 if (!this.guestInstanceId) { |
332 return; | 330 return; |
333 } | 331 } |
334 | 332 |
335 WebView.setAllowTransparency(this.guestInstanceId, this.allowtransparency); | 333 WebViewInternal.setAllowTransparency(this.guestInstanceId, |
| 334 this.allowtransparency); |
336 return; | 335 return; |
337 } else if (name == 'name') { | 336 } else if (name == 'name') { |
338 // We treat null attribute (attribute removed) and the empty string as | 337 // We treat null attribute (attribute removed) and the empty string as |
339 // one case. | 338 // one case. |
340 oldValue = oldValue || ''; | 339 oldValue = oldValue || ''; |
341 newValue = newValue || ''; | 340 newValue = newValue || ''; |
342 | 341 |
343 if (oldValue === newValue) { | 342 if (oldValue === newValue) { |
344 return; | 343 return; |
345 } | 344 } |
346 this.name = newValue; | 345 this.name = newValue; |
347 if (!this.guestInstanceId) { | 346 if (!this.guestInstanceId) { |
348 return; | 347 return; |
349 } | 348 } |
350 WebView.setName(this.guestInstanceId, newValue); | 349 WebViewInternal.setName(this.guestInstanceId, newValue); |
351 return; | 350 return; |
352 } else if (name == 'src') { | 351 } else if (name == 'src') { |
353 // We treat null attribute (attribute removed) and the empty string as | 352 // We treat null attribute (attribute removed) and the empty string as |
354 // one case. | 353 // one case. |
355 oldValue = oldValue || ''; | 354 oldValue = oldValue || ''; |
356 newValue = newValue || ''; | 355 newValue = newValue || ''; |
357 // Once we have navigated, we don't allow clearing the src attribute. | 356 // Once we have navigated, we don't allow clearing the src attribute. |
358 // Once <webview> enters a navigated state, it cannot be return back to a | 357 // Once <webview> enters a navigated state, it cannot be return back to a |
359 // placeholder state. | 358 // placeholder state. |
360 if (newValue == '' && oldValue != '') { | 359 if (newValue == '' && oldValue != '') { |
(...skipping 16 matching lines...) Expand all Loading... |
377 | 376 |
378 if (result.error) { | 377 if (result.error) { |
379 throw result.error; | 378 throw result.error; |
380 } | 379 } |
381 } else if (name == 'partition') { | 380 } else if (name == 'partition') { |
382 // Note that throwing error here won't synchronously propagate. | 381 // Note that throwing error here won't synchronously propagate. |
383 this.partition.fromAttribute(newValue, this.hasNavigated()); | 382 this.partition.fromAttribute(newValue, this.hasNavigated()); |
384 } | 383 } |
385 }; | 384 }; |
386 | 385 |
387 WebViewInternal.prototype.handleBrowserPluginAttributeMutation = | 386 WebView.prototype.handleBrowserPluginAttributeMutation = |
388 function(name, oldValue, newValue) { | 387 function(name, oldValue, newValue) { |
389 if (name == 'internalinstanceid' && !oldValue && !!newValue) { | 388 if (name == 'internalinstanceid' && !oldValue && !!newValue) { |
390 this.browserPluginNode.removeAttribute('internalinstanceid'); | 389 this.browserPluginNode.removeAttribute('internalinstanceid'); |
391 this.internalInstanceId = parseInt(newValue); | 390 this.internalInstanceId = parseInt(newValue); |
392 | 391 |
393 if (!!this.guestInstanceId && this.guestInstanceId != 0) { | 392 if (!!this.guestInstanceId && this.guestInstanceId != 0) { |
394 var isNewWindow = this.deferredAttachState ? | 393 var isNewWindow = this.deferredAttachState ? |
395 this.deferredAttachState.isNewWindow : false; | 394 this.deferredAttachState.isNewWindow : false; |
396 var params = this.buildAttachParams(isNewWindow); | 395 var params = this.buildAttachParams(isNewWindow); |
397 guestViewInternalNatives.AttachGuest( | 396 guestViewInternalNatives.AttachGuest( |
398 this.internalInstanceId, | 397 this.internalInstanceId, |
399 this.guestInstanceId, | 398 this.guestInstanceId, |
400 params, | 399 params, |
401 function(w) { | 400 function(w) { |
402 this.contentWindow = w; | 401 this.contentWindow = w; |
403 }.bind(this) | 402 }.bind(this) |
404 ); | 403 ); |
405 } | 404 } |
406 | 405 |
407 return; | 406 return; |
408 } | 407 } |
409 }; | 408 }; |
410 | 409 |
411 WebViewInternal.prototype.onSizeChanged = function(webViewEvent) { | 410 WebView.prototype.onSizeChanged = function(webViewEvent) { |
412 var newWidth = webViewEvent.newWidth; | 411 var newWidth = webViewEvent.newWidth; |
413 var newHeight = webViewEvent.newHeight; | 412 var newHeight = webViewEvent.newHeight; |
414 | 413 |
415 var node = this.webviewNode; | 414 var node = this.webviewNode; |
416 | 415 |
417 var width = node.offsetWidth; | 416 var width = node.offsetWidth; |
418 var height = node.offsetHeight; | 417 var height = node.offsetHeight; |
419 | 418 |
420 // Check the current bounds to make sure we do not resize <webview> | 419 // Check the current bounds to make sure we do not resize <webview> |
421 // outside of current constraints. | 420 // outside of current constraints. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 newHeight <= maxHeight)) { | 463 newHeight <= maxHeight)) { |
465 node.style.width = newWidth + 'px'; | 464 node.style.width = newWidth + 'px'; |
466 node.style.height = newHeight + 'px'; | 465 node.style.height = newHeight + 'px'; |
467 // Only fire the DOM event if the size of the <webview> has actually | 466 // Only fire the DOM event if the size of the <webview> has actually |
468 // changed. | 467 // changed. |
469 this.dispatchEvent(webViewEvent); | 468 this.dispatchEvent(webViewEvent); |
470 } | 469 } |
471 }; | 470 }; |
472 | 471 |
473 // Returns if <object> is in the render tree. | 472 // Returns if <object> is in the render tree. |
474 WebViewInternal.prototype.isPluginInRenderTree = function() { | 473 WebView.prototype.isPluginInRenderTree = function() { |
475 return !!this.internalInstanceId && this.internalInstanceId != 0; | 474 return !!this.internalInstanceId && this.internalInstanceId != 0; |
476 }; | 475 }; |
477 | 476 |
478 WebViewInternal.prototype.hasNavigated = function() { | 477 WebView.prototype.hasNavigated = function() { |
479 return !this.beforeFirstNavigation; | 478 return !this.beforeFirstNavigation; |
480 }; | 479 }; |
481 | 480 |
482 WebViewInternal.prototype.parseSrcAttribute = function(result) { | 481 WebView.prototype.parseSrcAttribute = function(result) { |
483 if (!this.partition.validPartitionId) { | 482 if (!this.partition.validPartitionId) { |
484 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; | 483 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; |
485 return; | 484 return; |
486 } | 485 } |
487 this.src = this.webviewNode.getAttribute('src'); | 486 this.src = this.webviewNode.getAttribute('src'); |
488 | 487 |
489 if (!this.src) { | 488 if (!this.src) { |
490 return; | 489 return; |
491 } | 490 } |
492 | 491 |
493 if (this.guestInstanceId == undefined) { | 492 if (this.guestInstanceId == undefined) { |
494 if (this.beforeFirstNavigation) { | 493 if (this.beforeFirstNavigation) { |
495 this.beforeFirstNavigation = false; | 494 this.beforeFirstNavigation = false; |
496 this.createGuest(); | 495 this.createGuest(); |
497 } | 496 } |
498 return; | 497 return; |
499 } | 498 } |
500 | 499 |
501 // Navigate to |this.src|. | 500 // Navigate to |this.src|. |
502 WebView.navigate(this.guestInstanceId, this.src); | 501 WebViewInternal.navigate(this.guestInstanceId, this.src); |
503 }; | 502 }; |
504 | 503 |
505 WebViewInternal.prototype.parseAttributes = function() { | 504 WebView.prototype.parseAttributes = function() { |
506 if (!this.elementAttached) { | 505 if (!this.elementAttached) { |
507 return; | 506 return; |
508 } | 507 } |
509 var hasNavigated = this.hasNavigated(); | 508 var hasNavigated = this.hasNavigated(); |
510 var attributeValue = this.webviewNode.getAttribute('partition'); | 509 var attributeValue = this.webviewNode.getAttribute('partition'); |
511 var result = this.partition.fromAttribute(attributeValue, hasNavigated); | 510 var result = this.partition.fromAttribute(attributeValue, hasNavigated); |
512 this.parseSrcAttribute(result); | 511 this.parseSrcAttribute(result); |
513 }; | 512 }; |
514 | 513 |
515 WebViewInternal.prototype.createGuest = function() { | 514 WebView.prototype.createGuest = function() { |
516 if (this.pendingGuestCreation) { | 515 if (this.pendingGuestCreation) { |
517 return; | 516 return; |
518 } | 517 } |
519 var storagePartitionId = | 518 var storagePartitionId = |
520 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || | 519 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || |
521 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; | 520 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; |
522 var params = { | 521 var params = { |
523 'storagePartitionId': storagePartitionId | 522 'storagePartitionId': storagePartitionId |
524 }; | 523 }; |
525 GuestViewInternal.createGuest( | 524 GuestViewInternal.createGuest( |
526 'webview', | 525 'webview', |
527 params, | 526 params, |
528 function(guestInstanceId) { | 527 function(guestInstanceId) { |
529 this.pendingGuestCreation = false; | 528 this.pendingGuestCreation = false; |
530 if (!this.elementAttached) { | 529 if (!this.elementAttached) { |
531 GuestViewInternal.destroyGuest(guestInstanceId); | 530 GuestViewInternal.destroyGuest(guestInstanceId); |
532 return; | 531 return; |
533 } | 532 } |
534 this.attachWindow(guestInstanceId, false); | 533 this.attachWindow(guestInstanceId, false); |
535 }.bind(this) | 534 }.bind(this) |
536 ); | 535 ); |
537 this.pendingGuestCreation = true; | 536 this.pendingGuestCreation = true; |
538 }; | 537 }; |
539 | 538 |
540 WebViewInternal.prototype.onFrameNameChanged = function(name) { | 539 WebView.prototype.onFrameNameChanged = function(name) { |
541 this.name = name || ''; | 540 this.name = name || ''; |
542 if (this.name === '') { | 541 if (this.name === '') { |
543 this.webviewNode.removeAttribute('name'); | 542 this.webviewNode.removeAttribute('name'); |
544 } else { | 543 } else { |
545 this.webviewNode.setAttribute('name', this.name); | 544 this.webviewNode.setAttribute('name', this.name); |
546 } | 545 } |
547 }; | 546 }; |
548 | 547 |
549 WebViewInternal.prototype.dispatchEvent = function(webViewEvent) { | 548 WebView.prototype.dispatchEvent = function(webViewEvent) { |
550 return this.webviewNode.dispatchEvent(webViewEvent); | 549 return this.webviewNode.dispatchEvent(webViewEvent); |
551 }; | 550 }; |
552 | 551 |
553 // Adds an 'on<event>' property on the webview, which can be used to set/unset | 552 // Adds an 'on<event>' property on the webview, which can be used to set/unset |
554 // an event handler. | 553 // an event handler. |
555 WebViewInternal.prototype.setupEventProperty = function(eventName) { | 554 WebView.prototype.setupEventProperty = function(eventName) { |
556 var propertyName = 'on' + eventName.toLowerCase(); | 555 var propertyName = 'on' + eventName.toLowerCase(); |
557 Object.defineProperty(this.webviewNode, propertyName, { | 556 Object.defineProperty(this.webviewNode, propertyName, { |
558 get: function() { | 557 get: function() { |
559 return this.on[propertyName]; | 558 return this.on[propertyName]; |
560 }.bind(this), | 559 }.bind(this), |
561 set: function(value) { | 560 set: function(value) { |
562 if (this.on[propertyName]) | 561 if (this.on[propertyName]) |
563 this.webviewNode.removeEventListener(eventName, this.on[propertyName]); | 562 this.webviewNode.removeEventListener(eventName, this.on[propertyName]); |
564 this.on[propertyName] = value; | 563 this.on[propertyName] = value; |
565 if (value) | 564 if (value) |
566 this.webviewNode.addEventListener(eventName, value); | 565 this.webviewNode.addEventListener(eventName, value); |
567 }.bind(this), | 566 }.bind(this), |
568 enumerable: true | 567 enumerable: true |
569 }); | 568 }); |
570 }; | 569 }; |
571 | 570 |
572 // Updates state upon loadcommit. | 571 // Updates state upon loadcommit. |
573 WebViewInternal.prototype.onLoadCommit = function( | 572 WebView.prototype.onLoadCommit = function( |
574 baseUrlForDataUrl, currentEntryIndex, entryCount, | 573 baseUrlForDataUrl, currentEntryIndex, entryCount, |
575 processId, url, isTopLevel) { | 574 processId, url, isTopLevel) { |
576 this.baseUrlForDataUrl = baseUrlForDataUrl; | 575 this.baseUrlForDataUrl = baseUrlForDataUrl; |
577 this.currentEntryIndex = currentEntryIndex; | 576 this.currentEntryIndex = currentEntryIndex; |
578 this.entryCount = entryCount; | 577 this.entryCount = entryCount; |
579 this.processId = processId; | 578 this.processId = processId; |
580 var oldValue = this.webviewNode.getAttribute('src'); | 579 var oldValue = this.webviewNode.getAttribute('src'); |
581 var newValue = url; | 580 var newValue = url; |
582 if (isTopLevel && (oldValue != newValue)) { | 581 if (isTopLevel && (oldValue != newValue)) { |
583 // Touching the src attribute triggers a navigation. To avoid | 582 // Touching the src attribute triggers a navigation. To avoid |
584 // triggering a page reload on every guest-initiated navigation, | 583 // triggering a page reload on every guest-initiated navigation, |
585 // we use the flag ignoreNextSrcAttributeChange here. | 584 // we use the flag ignoreNextSrcAttributeChange here. |
586 this.ignoreNextSrcAttributeChange = true; | 585 this.ignoreNextSrcAttributeChange = true; |
587 this.webviewNode.setAttribute('src', newValue); | 586 this.webviewNode.setAttribute('src', newValue); |
588 } | 587 } |
589 }; | 588 }; |
590 | 589 |
591 WebViewInternal.prototype.onAttach = function(storagePartitionId) { | 590 WebView.prototype.onAttach = function(storagePartitionId) { |
592 this.webviewNode.setAttribute('partition', storagePartitionId); | 591 this.webviewNode.setAttribute('partition', storagePartitionId); |
593 this.partition.fromAttribute(storagePartitionId, this.hasNavigated()); | 592 this.partition.fromAttribute(storagePartitionId, this.hasNavigated()); |
594 }; | 593 }; |
595 | 594 |
596 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { | 595 WebView.prototype.buildAttachParams = function(isNewWindow) { |
597 var params = { | 596 var params = { |
598 'allowtransparency': this.allowtransparency || false, | 597 'allowtransparency': this.allowtransparency || false, |
599 'autosize': this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE), | 598 'autosize': this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE), |
600 'instanceId': this.viewInstanceId, | 599 'instanceId': this.viewInstanceId, |
601 'maxheight': parseInt(this.maxheight || 0), | 600 'maxheight': parseInt(this.maxheight || 0), |
602 'maxwidth': parseInt(this.maxwidth || 0), | 601 'maxwidth': parseInt(this.maxwidth || 0), |
603 'minheight': parseInt(this.minheight || 0), | 602 'minheight': parseInt(this.minheight || 0), |
604 'minwidth': parseInt(this.minwidth || 0), | 603 'minwidth': parseInt(this.minwidth || 0), |
605 'name': this.name, | 604 'name': this.name, |
606 // We don't need to navigate new window from here. | 605 // We don't need to navigate new window from here. |
607 'src': isNewWindow ? undefined : this.src, | 606 'src': isNewWindow ? undefined : this.src, |
608 // If we have a partition from the opener, that will also be already | 607 // If we have a partition from the opener, that will also be already |
609 // set via this.onAttach(). | 608 // set via this.onAttach(). |
610 'storagePartitionId': this.partition.toAttribute(), | 609 'storagePartitionId': this.partition.toAttribute(), |
611 'userAgentOverride': this.userAgentOverride | 610 'userAgentOverride': this.userAgentOverride |
612 }; | 611 }; |
613 return params; | 612 return params; |
614 }; | 613 }; |
615 | 614 |
616 WebViewInternal.prototype.attachWindow = function(guestInstanceId, | 615 WebView.prototype.attachWindow = function(guestInstanceId, |
617 isNewWindow) { | 616 isNewWindow) { |
618 this.guestInstanceId = guestInstanceId; | 617 this.guestInstanceId = guestInstanceId; |
619 var params = this.buildAttachParams(isNewWindow); | 618 var params = this.buildAttachParams(isNewWindow); |
620 | 619 |
621 if (!this.isPluginInRenderTree()) { | 620 if (!this.isPluginInRenderTree()) { |
622 this.deferredAttachState = {isNewWindow: isNewWindow}; | 621 this.deferredAttachState = {isNewWindow: isNewWindow}; |
623 return true; | 622 return true; |
624 } | 623 } |
625 | 624 |
626 this.deferredAttachState = null; | 625 this.deferredAttachState = null; |
627 return guestViewInternalNatives.AttachGuest( | 626 return guestViewInternalNatives.AttachGuest( |
628 this.internalInstanceId, | 627 this.internalInstanceId, |
629 this.guestInstanceId, | 628 this.guestInstanceId, |
630 params, function(w) { | 629 params, function(w) { |
631 this.contentWindow = w; | 630 this.contentWindow = w; |
632 }.bind(this) | 631 }.bind(this) |
633 ); | 632 ); |
634 }; | 633 }; |
635 | 634 |
636 // ----------------------------------------------------------------------------- | 635 // ----------------------------------------------------------------------------- |
637 // Public-facing API methods. | 636 // Public-facing API methods. |
638 | 637 |
639 | 638 |
640 // Navigates to the previous history entry. | 639 // Navigates to the previous history entry. |
641 WebViewInternal.prototype.back = function(callback) { | 640 WebView.prototype.back = function(callback) { |
642 return this.go(-1, callback); | 641 return this.go(-1, callback); |
643 }; | 642 }; |
644 | 643 |
645 // Returns whether there is a previous history entry to navigate to. | 644 // Returns whether there is a previous history entry to navigate to. |
646 WebViewInternal.prototype.canGoBack = function() { | 645 WebView.prototype.canGoBack = function() { |
647 return this.entryCount > 1 && this.currentEntryIndex > 0; | 646 return this.entryCount > 1 && this.currentEntryIndex > 0; |
648 }; | 647 }; |
649 | 648 |
650 // Returns whether there is a subsequent history entry to navigate to. | 649 // Returns whether there is a subsequent history entry to navigate to. |
651 WebViewInternal.prototype.canGoForward = function() { | 650 WebView.prototype.canGoForward = function() { |
652 return this.currentEntryIndex >= 0 && | 651 return this.currentEntryIndex >= 0 && |
653 this.currentEntryIndex < (this.entryCount - 1); | 652 this.currentEntryIndex < (this.entryCount - 1); |
654 }; | 653 }; |
655 | 654 |
656 // Clears browsing data for the WebView partition. | 655 // Clears browsing data for the WebView partition. |
657 WebViewInternal.prototype.clearData = function() { | 656 WebView.prototype.clearData = function() { |
658 if (!this.guestInstanceId) { | 657 if (!this.guestInstanceId) { |
659 return; | 658 return; |
660 } | 659 } |
661 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); | 660 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); |
662 $Function.apply(WebView.clearData, null, args); | 661 $Function.apply(WebViewInternal.clearData, null, args); |
663 }; | 662 }; |
664 | 663 |
665 // Injects JavaScript code into the guest page. | 664 // Injects JavaScript code into the guest page. |
666 WebViewInternal.prototype.executeScript = function(var_args) { | 665 WebView.prototype.executeScript = function(var_args) { |
667 this.validateExecuteCodeCall(); | 666 this.validateExecuteCodeCall(); |
668 var webviewSrc = this.src; | 667 var webviewSrc = this.src; |
669 if (this.baseUrlForDataUrl != '') { | 668 if (this.baseUrlForDataUrl != '') { |
670 webviewSrc = this.baseUrlForDataUrl; | 669 webviewSrc = this.baseUrlForDataUrl; |
671 } | 670 } |
672 var args = $Array.concat([this.guestInstanceId, webviewSrc], | 671 var args = $Array.concat([this.guestInstanceId, webviewSrc], |
673 $Array.slice(arguments)); | 672 $Array.slice(arguments)); |
674 $Function.apply(WebView.executeScript, null, args); | 673 $Function.apply(WebViewInternal.executeScript, null, args); |
675 }; | 674 }; |
676 | 675 |
677 // Initiates a find-in-page request. | 676 // Initiates a find-in-page request. |
678 WebViewInternal.prototype.find = function(search_text, options, callback) { | 677 WebView.prototype.find = function(search_text, options, callback) { |
679 if (!this.guestInstanceId) { | 678 if (!this.guestInstanceId) { |
680 return; | 679 return; |
681 } | 680 } |
682 WebView.find(this.guestInstanceId, search_text, options, callback); | 681 WebViewInternal.find(this.guestInstanceId, search_text, options, callback); |
683 }; | 682 }; |
684 | 683 |
685 // Navigates to the subsequent history entry. | 684 // Navigates to the subsequent history entry. |
686 WebViewInternal.prototype.forward = function(callback) { | 685 WebView.prototype.forward = function(callback) { |
687 return this.go(1, callback); | 686 return this.go(1, callback); |
688 }; | 687 }; |
689 | 688 |
690 // Returns Chrome's internal process ID for the guest web page's current | 689 // Returns Chrome's internal process ID for the guest web page's current |
691 // process. | 690 // process. |
692 WebViewInternal.prototype.getProcessId = function() { | 691 WebView.prototype.getProcessId = function() { |
693 return this.processId; | 692 return this.processId; |
694 }; | 693 }; |
695 | 694 |
696 // Returns the user agent string used by the webview for guest page requests. | 695 // Returns the user agent string used by the webview for guest page requests. |
697 WebViewInternal.prototype.getUserAgent = function() { | 696 WebView.prototype.getUserAgent = function() { |
698 return this.userAgentOverride || navigator.userAgent; | 697 return this.userAgentOverride || navigator.userAgent; |
699 }; | 698 }; |
700 | 699 |
701 // Gets the current zoom factor. | 700 // Gets the current zoom factor. |
702 WebViewInternal.prototype.getZoom = function(callback) { | 701 WebView.prototype.getZoom = function(callback) { |
703 if (!this.guestInstanceId) { | 702 if (!this.guestInstanceId) { |
704 return; | 703 return; |
705 } | 704 } |
706 WebView.getZoom(this.guestInstanceId, callback); | 705 WebViewInternal.getZoom(this.guestInstanceId, callback); |
707 }; | 706 }; |
708 | 707 |
709 // Navigates to a history entry using a history index relative to the current | 708 // Navigates to a history entry using a history index relative to the current |
710 // navigation. | 709 // navigation. |
711 WebViewInternal.prototype.go = function(relativeIndex, callback) { | 710 WebView.prototype.go = function(relativeIndex, callback) { |
712 if (!this.guestInstanceId) { | 711 if (!this.guestInstanceId) { |
713 return; | 712 return; |
714 } | 713 } |
715 WebView.go(this.guestInstanceId, relativeIndex, callback); | 714 WebViewInternal.go(this.guestInstanceId, relativeIndex, callback); |
716 }; | 715 }; |
717 | 716 |
718 // Injects CSS into the guest page. | 717 // Injects CSS into the guest page. |
719 WebViewInternal.prototype.insertCSS = function(var_args) { | 718 WebView.prototype.insertCSS = function(var_args) { |
720 this.validateExecuteCodeCall(); | 719 this.validateExecuteCodeCall(); |
721 var webviewSrc = this.src; | 720 var webviewSrc = this.src; |
722 if (this.baseUrlForDataUrl != '') { | 721 if (this.baseUrlForDataUrl != '') { |
723 webviewSrc = this.baseUrlForDataUrl; | 722 webviewSrc = this.baseUrlForDataUrl; |
724 } | 723 } |
725 var args = $Array.concat([this.guestInstanceId, webviewSrc], | 724 var args = $Array.concat([this.guestInstanceId, webviewSrc], |
726 $Array.slice(arguments)); | 725 $Array.slice(arguments)); |
727 $Function.apply(WebView.insertCSS, null, args); | 726 $Function.apply(WebViewInternal.insertCSS, null, args); |
728 }; | 727 }; |
729 | 728 |
730 // Indicates whether or not the webview's user agent string has been overridden. | 729 // Indicates whether or not the webview's user agent string has been overridden. |
731 WebViewInternal.prototype.isUserAgentOverridden = function() { | 730 WebView.prototype.isUserAgentOverridden = function() { |
732 return !!this.userAgentOverride && | 731 return !!this.userAgentOverride && |
733 this.userAgentOverride != navigator.userAgent; | 732 this.userAgentOverride != navigator.userAgent; |
734 }; | 733 }; |
735 | 734 |
736 // Prints the contents of the webview. | 735 // Prints the contents of the webview. |
737 WebViewInternal.prototype.print = function() { | 736 WebView.prototype.print = function() { |
738 this.executeScript({code: 'window.print();'}); | 737 this.executeScript({code: 'window.print();'}); |
739 }; | 738 }; |
740 | 739 |
741 // Reloads the current top-level page. | 740 // Reloads the current top-level page. |
742 WebViewInternal.prototype.reload = function() { | 741 WebView.prototype.reload = function() { |
743 if (!this.guestInstanceId) { | 742 if (!this.guestInstanceId) { |
744 return; | 743 return; |
745 } | 744 } |
746 WebView.reload(this.guestInstanceId); | 745 WebViewInternal.reload(this.guestInstanceId); |
747 }; | 746 }; |
748 | 747 |
749 // Override the user agent string used by the webview for guest page requests. | 748 // Override the user agent string used by the webview for guest page requests. |
750 WebViewInternal.prototype.setUserAgentOverride = function(userAgentOverride) { | 749 WebView.prototype.setUserAgentOverride = function(userAgentOverride) { |
751 this.userAgentOverride = userAgentOverride; | 750 this.userAgentOverride = userAgentOverride; |
752 if (!this.guestInstanceId) { | 751 if (!this.guestInstanceId) { |
753 // If we are not attached yet, then we will pick up the user agent on | 752 // If we are not attached yet, then we will pick up the user agent on |
754 // attachment. | 753 // attachment. |
755 return; | 754 return; |
756 } | 755 } |
757 WebView.overrideUserAgent(this.guestInstanceId, userAgentOverride); | 756 WebViewInternal.overrideUserAgent(this.guestInstanceId, userAgentOverride); |
758 }; | 757 }; |
759 | 758 |
760 // Changes the zoom factor of the page. | 759 // Changes the zoom factor of the page. |
761 WebViewInternal.prototype.setZoom = function(zoomFactor, callback) { | 760 WebView.prototype.setZoom = function(zoomFactor, callback) { |
762 if (!this.guestInstanceId) { | 761 if (!this.guestInstanceId) { |
763 return; | 762 return; |
764 } | 763 } |
765 WebView.setZoom(this.guestInstanceId, zoomFactor, callback); | 764 WebViewInternal.setZoom(this.guestInstanceId, zoomFactor, callback); |
766 }; | 765 }; |
767 | 766 |
768 // Stops loading the current navigation if one is in progress. | 767 // Stops loading the current navigation if one is in progress. |
769 WebViewInternal.prototype.stop = function() { | 768 WebView.prototype.stop = function() { |
770 if (!this.guestInstanceId) { | 769 if (!this.guestInstanceId) { |
771 return; | 770 return; |
772 } | 771 } |
773 WebView.stop(this.guestInstanceId); | 772 WebViewInternal.stop(this.guestInstanceId); |
774 }; | 773 }; |
775 | 774 |
776 // Ends the current find session. | 775 // Ends the current find session. |
777 WebViewInternal.prototype.stopFinding = function(action) { | 776 WebView.prototype.stopFinding = function(action) { |
778 if (!this.guestInstanceId) { | 777 if (!this.guestInstanceId) { |
779 return; | 778 return; |
780 } | 779 } |
781 WebView.stopFinding(this.guestInstanceId, action); | 780 WebViewInternal.stopFinding(this.guestInstanceId, action); |
782 }; | 781 }; |
783 | 782 |
784 // Forcibly kills the guest web page's renderer process. | 783 // Forcibly kills the guest web page's renderer process. |
785 WebViewInternal.prototype.terminate = function() { | 784 WebView.prototype.terminate = function() { |
786 if (!this.guestInstanceId) { | 785 if (!this.guestInstanceId) { |
787 return; | 786 return; |
788 } | 787 } |
789 WebView.terminate(this.guestInstanceId); | 788 WebViewInternal.terminate(this.guestInstanceId); |
790 }; | 789 }; |
791 | 790 |
792 // ----------------------------------------------------------------------------- | 791 // ----------------------------------------------------------------------------- |
793 | 792 |
794 // Registers browser plugin <object> custom element. | 793 // Registers browser plugin <object> custom element. |
795 function registerBrowserPluginElement() { | 794 function registerBrowserPluginElement() { |
796 var proto = Object.create(HTMLObjectElement.prototype); | 795 var proto = Object.create(HTMLObjectElement.prototype); |
797 | 796 |
798 proto.createdCallback = function() { | 797 proto.createdCallback = function() { |
799 this.setAttribute('type', 'application/browser-plugin'); | 798 this.setAttribute('type', 'application/browser-plugin'); |
800 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); | 799 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); |
801 // The <object> node fills in the <webview> container. | 800 // The <object> node fills in the <webview> container. |
802 this.style.width = '100%'; | 801 this.style.width = '100%'; |
803 this.style.height = '100%'; | 802 this.style.height = '100%'; |
804 }; | 803 }; |
805 | 804 |
806 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 805 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
807 var internal = privates(this).internal; | 806 var internal = privates(this).internal; |
808 if (!internal) { | 807 if (!internal) { |
809 return; | 808 return; |
810 } | 809 } |
811 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue); | 810 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue); |
812 }; | 811 }; |
813 | 812 |
814 proto.attachedCallback = function() { | 813 proto.attachedCallback = function() { |
815 // Load the plugin immediately. | 814 // Load the plugin immediately. |
816 var unused = this.nonExistentAttribute; | 815 var unused = this.nonExistentAttribute; |
817 }; | 816 }; |
818 | 817 |
819 WebViewInternal.BrowserPlugin = | 818 WebView.BrowserPlugin = |
820 DocumentNatives.RegisterElement('browserplugin', {extends: 'object', | 819 DocumentNatives.RegisterElement('browserplugin', {extends: 'object', |
821 prototype: proto}); | 820 prototype: proto}); |
822 | 821 |
823 delete proto.createdCallback; | 822 delete proto.createdCallback; |
824 delete proto.attachedCallback; | 823 delete proto.attachedCallback; |
825 delete proto.detachedCallback; | 824 delete proto.detachedCallback; |
826 delete proto.attributeChangedCallback; | 825 delete proto.attributeChangedCallback; |
827 } | 826 } |
828 | 827 |
829 // Registers <webview> custom element. | 828 // Registers <webview> custom element. |
830 function registerWebViewElement() { | 829 function registerWebViewElement() { |
831 var proto = Object.create(HTMLElement.prototype); | 830 var proto = Object.create(HTMLElement.prototype); |
832 | 831 |
833 proto.createdCallback = function() { | 832 proto.createdCallback = function() { |
834 new WebViewInternal(this); | 833 new WebView(this); |
835 }; | 834 }; |
836 | 835 |
837 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 836 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
838 var internal = privates(this).internal; | 837 var internal = privates(this).internal; |
839 if (!internal) { | 838 if (!internal) { |
840 return; | 839 return; |
841 } | 840 } |
842 internal.handleWebviewAttributeMutation(name, oldValue, newValue); | 841 internal.handleWebviewAttributeMutation(name, oldValue, newValue); |
843 }; | 842 }; |
844 | 843 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 'reload', | 880 'reload', |
882 'setUserAgentOverride', | 881 'setUserAgentOverride', |
883 'setZoom', | 882 'setZoom', |
884 'stop', | 883 'stop', |
885 'stopFinding', | 884 'stopFinding', |
886 'terminate' | 885 'terminate' |
887 ]; | 886 ]; |
888 | 887 |
889 // Add the experimental API methods, if available. | 888 // Add the experimental API methods, if available. |
890 var experimentalMethods = | 889 var experimentalMethods = |
891 WebViewInternal.maybeGetExperimentalAPIs(); | 890 WebView.maybeGetExperimentalAPIs(); |
892 methods = $Array.concat(methods, experimentalMethods); | 891 methods = $Array.concat(methods, experimentalMethods); |
893 | 892 |
894 // Forward proto.foo* method calls to WebViewInternal.foo*. | 893 // Forward proto.foo* method calls to WebView.foo*. |
895 var createHandler = function(m) { | 894 var createHandler = function(m) { |
896 return function(var_args) { | 895 return function(var_args) { |
897 var internal = privates(this).internal; | 896 var internal = privates(this).internal; |
898 return $Function.apply(internal[m], internal, arguments); | 897 return $Function.apply(internal[m], internal, arguments); |
899 }; | 898 }; |
900 }; | 899 }; |
901 for (var i = 0; methods[i]; ++i) { | 900 for (var i = 0; methods[i]; ++i) { |
902 proto[methods[i]] = createHandler(methods[i]); | 901 proto[methods[i]] = createHandler(methods[i]); |
903 } | 902 } |
904 | 903 |
(...skipping 12 matching lines...) Expand all Loading... |
917 window.addEventListener('readystatechange', function listener(event) { | 916 window.addEventListener('readystatechange', function listener(event) { |
918 if (document.readyState == 'loading') | 917 if (document.readyState == 'loading') |
919 return; | 918 return; |
920 | 919 |
921 registerBrowserPluginElement(); | 920 registerBrowserPluginElement(); |
922 registerWebViewElement(); | 921 registerWebViewElement(); |
923 window.removeEventListener(event.type, listener, useCapture); | 922 window.removeEventListener(event.type, listener, useCapture); |
924 }, useCapture); | 923 }, useCapture); |
925 | 924 |
926 // Implemented when the ChromeWebView API is available. | 925 // Implemented when the ChromeWebView API is available. |
927 WebViewInternal.prototype.maybeGetChromeWebViewEvents = function() {}; | 926 WebView.prototype.maybeGetChromeWebViewEvents = function() {}; |
928 | 927 |
929 // Implemented when the experimental WebView API is available. | 928 // Implemented when the experimental WebView API is available. |
930 WebViewInternal.maybeGetExperimentalAPIs = function() {}; | 929 WebView.maybeGetExperimentalAPIs = function() {}; |
931 WebViewInternal.prototype.maybeGetExperimentalEvents = function() {}; | 930 WebView.prototype.maybeGetExperimentalEvents = function() {}; |
932 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; | 931 WebView.prototype.setupExperimentalContextMenus = function() {}; |
933 | 932 |
934 // Exports. | 933 // Exports. |
935 exports.WebView = WebView; | 934 exports.WebView = WebView; |
936 exports.WebViewInternal = WebViewInternal; | 935 exports.WebViewInternal = WebViewInternal; |
OLD | NEW |