| 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 |