| 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 IdGenerator = requireNative('id_generator'); | 12 var IdGenerator = requireNative('id_generator'); |
| 13 // TODO(lazyboy): Rename this to WebViewInternal and call WebViewInternal | 13 // TODO(lazyboy): Rename this to WebViewInternal and call WebViewInternal |
| 14 // something else. | 14 // something else. |
| 15 var WebView = require('webViewInternal').WebView; | 15 var WebView = require('webViewInternal').WebView; |
| 16 var WebViewEvents = require('webViewEvents').WebViewEvents; | 16 var WebViewEvents = require('webViewEvents').WebViewEvents; |
| 17 var guestViewInternalNatives = requireNative('guest_view_internal'); |
| 17 | 18 |
| 18 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; | 19 var WEB_VIEW_ATTRIBUTE_MAXHEIGHT = 'maxheight'; |
| 19 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; | 20 var WEB_VIEW_ATTRIBUTE_MAXWIDTH = 'maxwidth'; |
| 20 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; | 21 var WEB_VIEW_ATTRIBUTE_MINHEIGHT = 'minheight'; |
| 21 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; | 22 var WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'; |
| 22 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'; | 23 var WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'; |
| 23 | 24 |
| 24 var PLUGIN_METHOD_ATTACH = '-internal-attach'; | |
| 25 | |
| 26 var ERROR_MSG_ALREADY_NAVIGATED = | 25 var ERROR_MSG_ALREADY_NAVIGATED = |
| 27 'The object has already navigated, so its partition cannot be changed.'; | 26 'The object has already navigated, so its partition cannot be changed.'; |
| 28 var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.'; | 27 var ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.'; |
| 29 | 28 |
| 30 /** @type {Array.<string>} */ | 29 /** @type {Array.<string>} */ |
| 31 var WEB_VIEW_ATTRIBUTES = [ | 30 var WEB_VIEW_ATTRIBUTES = [ |
| 32 'allowtransparency', | 31 'allowtransparency', |
| 33 'autosize', | 32 'autosize', |
| 34 WEB_VIEW_ATTRIBUTE_MINHEIGHT, | 33 WEB_VIEW_ATTRIBUTE_MINHEIGHT, |
| 35 WEB_VIEW_ATTRIBUTE_MINWIDTH, | 34 WEB_VIEW_ATTRIBUTE_MINWIDTH, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 // window.DOMContentLoaded event). | 137 // window.DOMContentLoaded event). |
| 139 // So copy from property if copying from attribute fails. | 138 // So copy from property if copying from attribute fails. |
| 140 browserPluginNode.setAttribute( | 139 browserPluginNode.setAttribute( |
| 141 attributeName, this.webviewNode[attributeName]); | 140 attributeName, this.webviewNode[attributeName]); |
| 142 } | 141 } |
| 143 }, this); | 142 }, this); |
| 144 | 143 |
| 145 return browserPluginNode; | 144 return browserPluginNode; |
| 146 }; | 145 }; |
| 147 | 146 |
| 148 WebViewInternal.prototype.getInstanceId = function() { | 147 WebViewInternal.prototype.getGuestInstanceId = function() { |
| 149 return this.instanceId; | 148 return this.guestInstanceId; |
| 150 }; | 149 }; |
| 151 | 150 |
| 152 /** | 151 /** |
| 153 * Resets some state upon reattaching <webview> element to the DOM. | 152 * Resets some state upon reattaching <webview> element to the DOM. |
| 154 */ | 153 */ |
| 155 WebViewInternal.prototype.resetUponReattachment = function() { | 154 WebViewInternal.prototype.reset = function() { |
| 156 this.instanceId = undefined; | 155 this.guestInstanceId = undefined; |
| 156 this.internalInstanceId = 0; |
| 157 this.beforeFirstNavigation = true; | 157 this.beforeFirstNavigation = true; |
| 158 this.validPartitionId = true; | 158 this.validPartitionId = true; |
| 159 this.partition.validPartitionId = true; | 159 this.partition.validPartitionId = true; |
| 160 }; | 160 }; |
| 161 | 161 |
| 162 // Sets <webview>.request property. | 162 // Sets <webview>.request property. |
| 163 WebViewInternal.prototype.setRequestPropertyOnWebViewNode = function(request) { | 163 WebViewInternal.prototype.setRequestPropertyOnWebViewNode = function(request) { |
| 164 Object.defineProperty( | 164 Object.defineProperty( |
| 165 this.webviewNode, | 165 this.webviewNode, |
| 166 'request', | 166 'request', |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 */ | 216 */ |
| 217 WebViewInternal.prototype.canGoForward = function() { | 217 WebViewInternal.prototype.canGoForward = function() { |
| 218 return this.currentEntryIndex >= 0 && | 218 return this.currentEntryIndex >= 0 && |
| 219 this.currentEntryIndex < (this.entryCount - 1); | 219 this.currentEntryIndex < (this.entryCount - 1); |
| 220 }; | 220 }; |
| 221 | 221 |
| 222 /** | 222 /** |
| 223 * @private | 223 * @private |
| 224 */ | 224 */ |
| 225 WebViewInternal.prototype.clearData = function() { | 225 WebViewInternal.prototype.clearData = function() { |
| 226 if (!this.instanceId) { | 226 if (!this.guestInstanceId) { |
| 227 return; | 227 return; |
| 228 } | 228 } |
| 229 var args = $Array.concat([this.instanceId], $Array.slice(arguments)); | 229 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); |
| 230 $Function.apply(WebView.clearData, null, args); | 230 $Function.apply(WebView.clearData, null, args); |
| 231 }; | 231 }; |
| 232 | 232 |
| 233 /** | 233 /** |
| 234 * @private | 234 * @private |
| 235 */ | 235 */ |
| 236 WebViewInternal.prototype.getProcessId = function() { | 236 WebViewInternal.prototype.getProcessId = function() { |
| 237 return this.processId; | 237 return this.processId; |
| 238 }; | 238 }; |
| 239 | 239 |
| 240 /** | 240 /** |
| 241 * @private | 241 * @private |
| 242 */ | 242 */ |
| 243 WebViewInternal.prototype.go = function(relativeIndex) { | 243 WebViewInternal.prototype.go = function(relativeIndex) { |
| 244 if (!this.instanceId) { | 244 if (!this.guestInstanceId) { |
| 245 return; | 245 return; |
| 246 } | 246 } |
| 247 WebView.go(this.instanceId, relativeIndex); | 247 WebView.go(this.guestInstanceId, relativeIndex); |
| 248 }; | 248 }; |
| 249 | 249 |
| 250 /** | 250 /** |
| 251 * @private | 251 * @private |
| 252 */ | 252 */ |
| 253 WebViewInternal.prototype.print = function() { | 253 WebViewInternal.prototype.print = function() { |
| 254 this.executeScript({code: 'window.print();'}); | 254 this.executeScript({code: 'window.print();'}); |
| 255 }; | 255 }; |
| 256 | 256 |
| 257 /** | 257 /** |
| 258 * @private | 258 * @private |
| 259 */ | 259 */ |
| 260 WebViewInternal.prototype.reload = function() { | 260 WebViewInternal.prototype.reload = function() { |
| 261 if (!this.instanceId) { | 261 if (!this.guestInstanceId) { |
| 262 return; | 262 return; |
| 263 } | 263 } |
| 264 WebView.reload(this.instanceId); | 264 WebView.reload(this.guestInstanceId); |
| 265 }; | 265 }; |
| 266 | 266 |
| 267 /** | 267 /** |
| 268 * @private | 268 * @private |
| 269 */ | 269 */ |
| 270 WebViewInternal.prototype.stop = function() { | 270 WebViewInternal.prototype.stop = function() { |
| 271 if (!this.instanceId) { | 271 if (!this.guestInstanceId) { |
| 272 return; | 272 return; |
| 273 } | 273 } |
| 274 WebView.stop(this.instanceId); | 274 WebView.stop(this.guestInstanceId); |
| 275 }; | 275 }; |
| 276 | 276 |
| 277 /** | 277 /** |
| 278 * @private | 278 * @private |
| 279 */ | 279 */ |
| 280 WebViewInternal.prototype.terminate = function() { | 280 WebViewInternal.prototype.terminate = function() { |
| 281 if (!this.instanceId) { | 281 if (!this.guestInstanceId) { |
| 282 return; | 282 return; |
| 283 } | 283 } |
| 284 WebView.terminate(this.instanceId); | 284 WebView.terminate(this.guestInstanceId); |
| 285 }; | 285 }; |
| 286 | 286 |
| 287 /** | 287 /** |
| 288 * @private | 288 * @private |
| 289 */ | 289 */ |
| 290 WebViewInternal.prototype.validateExecuteCodeCall = function() { | 290 WebViewInternal.prototype.validateExecuteCodeCall = function() { |
| 291 var ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview>: ' + | 291 var ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview>: ' + |
| 292 'Script cannot be injected into content until the page has loaded.'; | 292 'Script cannot be injected into content until the page has loaded.'; |
| 293 if (!this.instanceId) { | 293 if (!this.guestInstanceId) { |
| 294 throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT); | 294 throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT); |
| 295 } | 295 } |
| 296 }; | 296 }; |
| 297 | 297 |
| 298 /** | 298 /** |
| 299 * @private | 299 * @private |
| 300 */ | 300 */ |
| 301 WebViewInternal.prototype.executeScript = function(var_args) { | 301 WebViewInternal.prototype.executeScript = function(var_args) { |
| 302 this.validateExecuteCodeCall(); | 302 this.validateExecuteCodeCall(); |
| 303 var args = $Array.concat([this.instanceId, this.src], | 303 var args = $Array.concat([this.guestInstanceId, this.src], |
| 304 $Array.slice(arguments)); | 304 $Array.slice(arguments)); |
| 305 $Function.apply(WebView.executeScript, null, args); | 305 $Function.apply(WebView.executeScript, null, args); |
| 306 }; | 306 }; |
| 307 | 307 |
| 308 /** | 308 /** |
| 309 * @private | 309 * @private |
| 310 */ | 310 */ |
| 311 WebViewInternal.prototype.insertCSS = function(var_args) { | 311 WebViewInternal.prototype.insertCSS = function(var_args) { |
| 312 this.validateExecuteCodeCall(); | 312 this.validateExecuteCodeCall(); |
| 313 var args = $Array.concat([this.instanceId, this.src], | 313 var args = $Array.concat([this.guestInstanceId, this.src], |
| 314 $Array.slice(arguments)); | 314 $Array.slice(arguments)); |
| 315 $Function.apply(WebView.insertCSS, null, args); | 315 $Function.apply(WebView.insertCSS, null, args); |
| 316 }; | 316 }; |
| 317 | 317 |
| 318 /** | 318 /** |
| 319 * @private | 319 * @private |
| 320 */ | 320 */ |
| 321 WebViewInternal.prototype.setupWebviewNodeProperties = function() { | 321 WebViewInternal.prototype.setupWebviewNodeProperties = function() { |
| 322 var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' + | 322 var ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' + |
| 323 'contentWindow is not available at this time. It will become available ' + | 323 'contentWindow is not available at this time. It will become available ' + |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 if (name == 'name') { | 449 if (name == 'name') { |
| 450 // We treat null attribute (attribute removed) and the empty string as | 450 // We treat null attribute (attribute removed) and the empty string as |
| 451 // one case. | 451 // one case. |
| 452 oldValue = oldValue || ''; | 452 oldValue = oldValue || ''; |
| 453 newValue = newValue || ''; | 453 newValue = newValue || ''; |
| 454 | 454 |
| 455 if (oldValue === newValue) { | 455 if (oldValue === newValue) { |
| 456 return; | 456 return; |
| 457 } | 457 } |
| 458 this.name = newValue; | 458 this.name = newValue; |
| 459 if (!this.instanceId) { | 459 if (!this.guestInstanceId) { |
| 460 return; | 460 return; |
| 461 } | 461 } |
| 462 WebView.setName(this.instanceId, newValue); | 462 WebView.setName(this.guestInstanceId, newValue); |
| 463 return; | 463 return; |
| 464 } else if (name == 'src') { | 464 } else if (name == 'src') { |
| 465 // We treat null attribute (attribute removed) and the empty string as | 465 // We treat null attribute (attribute removed) and the empty string as |
| 466 // one case. | 466 // one case. |
| 467 oldValue = oldValue || ''; | 467 oldValue = oldValue || ''; |
| 468 newValue = newValue || ''; | 468 newValue = newValue || ''; |
| 469 // Once we have navigated, we don't allow clearing the src attribute. | 469 // Once we have navigated, we don't allow clearing the src attribute. |
| 470 // Once <webview> enters a navigated state, it cannot be return back to a | 470 // Once <webview> enters a navigated state, it cannot be return back to a |
| 471 // placeholder state. | 471 // placeholder state. |
| 472 if (newValue == '' && oldValue != '') { | 472 if (newValue == '' && oldValue != '') { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 } else { | 505 } else { |
| 506 this.browserPluginNode.setAttribute(name, newValue); | 506 this.browserPluginNode.setAttribute(name, newValue); |
| 507 } | 507 } |
| 508 }; | 508 }; |
| 509 | 509 |
| 510 /** | 510 /** |
| 511 * @private | 511 * @private |
| 512 */ | 512 */ |
| 513 WebViewInternal.prototype.handleBrowserPluginAttributeMutation = | 513 WebViewInternal.prototype.handleBrowserPluginAttributeMutation = |
| 514 function(name, oldValue, newValue) { | 514 function(name, oldValue, newValue) { |
| 515 if (name == 'internalbindings' && !oldValue && newValue) { | 515 if (name == 'internalinstanceid' && !oldValue && !!newValue) { |
| 516 this.browserPluginNode.removeAttribute('internalbindings'); | 516 this.browserPluginNode.removeAttribute('internalinstanceid'); |
| 517 | 517 this.internalInstanceId = 1 * newValue; |
| 518 if (this.deferredAttachState) { | 518 if (this.deferredAttachState && !!this.guestInstanceId && |
| 519 var self = this; | 519 this.guestInstanceId != 0) { |
| 520 // A setTimeout is necessary for the binding to be initialized properly. | |
| 521 window.setTimeout(function() { | 520 window.setTimeout(function() { |
| 522 if (self.hasBindings()) { | 521 var isNewWindow = this.deferredAttachState ? |
| 523 var params = self.buildAttachParams( | 522 this.deferredAttachState.isNewWindow : false; |
| 524 self.deferredAttachState.isNewWindow); | 523 var params = this.buildAttachParams(isNewWindow); |
| 525 self.browserPluginNode[PLUGIN_METHOD_ATTACH](self.instanceId, params); | 524 guestViewInternalNatives.AttachPlugin( |
| 526 self.deferredAttachState = null; | 525 this.guestInstanceId, |
| 527 } | 526 this.internalInstanceId, |
| 528 }, 0); | 527 params, |
| 528 this.browserPluginNode); |
| 529 }.bind(this), 0); |
| 529 } | 530 } |
| 530 return; | 531 return; |
| 531 } | 532 } |
| 532 | 533 |
| 533 // This observer monitors mutations to attributes of the BrowserPlugin and | 534 // This observer monitors mutations to attributes of the BrowserPlugin and |
| 534 // updates the <webview> attributes accordingly. | 535 // updates the <webview> attributes accordingly. |
| 535 // |newValue| is null if the attribute |name| has been removed. | 536 // |newValue| is null if the attribute |name| has been removed. |
| 536 if (newValue != null) { | 537 if (newValue != null) { |
| 537 // Update the <webview> attribute to match the BrowserPlugin attribute. | 538 // Update the <webview> attribute to match the BrowserPlugin attribute. |
| 538 // Note: Calling setAttribute on <webview> will trigger its mutation | 539 // Note: Calling setAttribute on <webview> will trigger its mutation |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 | 599 |
| 599 if (newWidth >= minWidth && | 600 if (newWidth >= minWidth && |
| 600 newWidth <= maxWidth && | 601 newWidth <= maxWidth && |
| 601 newHeight >= minHeight && | 602 newHeight >= minHeight && |
| 602 newHeight <= maxHeight) { | 603 newHeight <= maxHeight) { |
| 603 node.style.width = newWidth + 'px'; | 604 node.style.width = newWidth + 'px'; |
| 604 node.style.height = newHeight + 'px'; | 605 node.style.height = newHeight + 'px'; |
| 605 } | 606 } |
| 606 }; | 607 }; |
| 607 | 608 |
| 608 // Returns true if Browser Plugin bindings is available. | 609 // Returns if <object> is in the render tree. |
| 609 // Bindings are unavailable if <object> is not in the render tree. | 610 WebViewInternal.prototype.isPluginInRenderTree = function() { |
| 610 WebViewInternal.prototype.hasBindings = function() { | 611 return !!this.internalInstanceId && this.internalInstanceId != 0; |
| 611 return 'function' == typeof this.browserPluginNode[PLUGIN_METHOD_ATTACH]; | |
| 612 }; | 612 }; |
| 613 | 613 |
| 614 WebViewInternal.prototype.hasNavigated = function() { | 614 WebViewInternal.prototype.hasNavigated = function() { |
| 615 return !this.beforeFirstNavigation; | 615 return !this.beforeFirstNavigation; |
| 616 }; | 616 }; |
| 617 | 617 |
| 618 /** @return {boolean} */ | 618 /** @return {boolean} */ |
| 619 WebViewInternal.prototype.parseSrcAttribute = function(result) { | 619 WebViewInternal.prototype.parseSrcAttribute = function(result) { |
| 620 if (!this.partition.validPartitionId) { | 620 if (!this.partition.validPartitionId) { |
| 621 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; | 621 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 633 | 633 |
| 634 if (!this.hasGuestInstanceID()) { | 634 if (!this.hasGuestInstanceID()) { |
| 635 if (this.beforeFirstNavigation) { | 635 if (this.beforeFirstNavigation) { |
| 636 this.beforeFirstNavigation = false; | 636 this.beforeFirstNavigation = false; |
| 637 this.allocateInstanceId(); | 637 this.allocateInstanceId(); |
| 638 } | 638 } |
| 639 return true; | 639 return true; |
| 640 } | 640 } |
| 641 | 641 |
| 642 // Navigate to this.src. | 642 // Navigate to this.src. |
| 643 WebView.navigate(this.instanceId, this.src); | 643 WebView.navigate(this.guestInstanceId, this.src); |
| 644 return true; | 644 return true; |
| 645 }; | 645 }; |
| 646 | 646 |
| 647 /** @return {boolean} */ | 647 /** @return {boolean} */ |
| 648 WebViewInternal.prototype.parseAttributes = function() { | 648 WebViewInternal.prototype.parseAttributes = function() { |
| 649 var hasNavigated = this.hasNavigated(); | 649 var hasNavigated = this.hasNavigated(); |
| 650 var attributeValue = this.webviewNode.getAttribute('partition'); | 650 var attributeValue = this.webviewNode.getAttribute('partition'); |
| 651 var result = this.partition.fromAttribute(attributeValue, hasNavigated); | 651 var result = this.partition.fromAttribute(attributeValue, hasNavigated); |
| 652 return this.parseSrcAttribute(result); | 652 return this.parseSrcAttribute(result); |
| 653 }; | 653 }; |
| 654 | 654 |
| 655 WebViewInternal.prototype.hasGuestInstanceID = function() { | 655 WebViewInternal.prototype.hasGuestInstanceID = function() { |
| 656 return this.instanceId != undefined; | 656 return this.guestInstanceId != undefined; |
| 657 }; | 657 }; |
| 658 | 658 |
| 659 WebViewInternal.prototype.allocateInstanceId = function() { | 659 WebViewInternal.prototype.allocateInstanceId = function() { |
| 660 var storagePartitionId = | 660 var storagePartitionId = |
| 661 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || | 661 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || |
| 662 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; | 662 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; |
| 663 var params = { | 663 var params = { |
| 664 'storagePartitionId': storagePartitionId, | 664 'storagePartitionId': storagePartitionId, |
| 665 }; | 665 }; |
| 666 var self = this; | 666 var self = this; |
| 667 GuestViewInternal.createGuest( | 667 GuestViewInternal.createGuest( |
| 668 'webview', | 668 'webview', |
| 669 params, | 669 params, |
| 670 function(instanceId) { | 670 function(guestInstanceId) { |
| 671 // TODO(lazyboy): Make sure this.autoNavigate_ stuff correctly updated | 671 // TODO(lazyboy): Make sure this.autoNavigate_ stuff correctly updated |
| 672 // |self.src| at this point. | 672 // |self.src| at this point. |
| 673 self.attachWindow(instanceId, false); | 673 self.attachWindow(guestInstanceId, false); |
| 674 }); | 674 }); |
| 675 }; | 675 }; |
| 676 | 676 |
| 677 WebViewInternal.prototype.onFrameNameChanged = function(name) { | 677 WebViewInternal.prototype.onFrameNameChanged = function(name) { |
| 678 this.name = name || ''; | 678 this.name = name || ''; |
| 679 if (this.name === '') { | 679 if (this.name === '') { |
| 680 this.webviewNode.removeAttribute('name'); | 680 this.webviewNode.removeAttribute('name'); |
| 681 } else { | 681 } else { |
| 682 this.webviewNode.setAttribute('name', this.name); | 682 this.webviewNode.setAttribute('name', this.name); |
| 683 } | 683 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 | 740 |
| 741 /** @private */ | 741 /** @private */ |
| 742 WebViewInternal.prototype.isUserAgentOverridden = function() { | 742 WebViewInternal.prototype.isUserAgentOverridden = function() { |
| 743 return !!this.userAgentOverride && | 743 return !!this.userAgentOverride && |
| 744 this.userAgentOverride != navigator.userAgent; | 744 this.userAgentOverride != navigator.userAgent; |
| 745 }; | 745 }; |
| 746 | 746 |
| 747 /** @private */ | 747 /** @private */ |
| 748 WebViewInternal.prototype.setUserAgentOverride = function(userAgentOverride) { | 748 WebViewInternal.prototype.setUserAgentOverride = function(userAgentOverride) { |
| 749 this.userAgentOverride = userAgentOverride; | 749 this.userAgentOverride = userAgentOverride; |
| 750 if (!this.instanceId) { | 750 if (!this.guestInstanceId) { |
| 751 // If we are not attached yet, then we will pick up the user agent on | 751 // If we are not attached yet, then we will pick up the user agent on |
| 752 // attachment. | 752 // attachment. |
| 753 return; | 753 return; |
| 754 } | 754 } |
| 755 WebView.overrideUserAgent(this.instanceId, userAgentOverride); | 755 WebView.overrideUserAgent(this.guestInstanceId, userAgentOverride); |
| 756 }; | 756 }; |
| 757 | 757 |
| 758 /** @private */ | 758 /** @private */ |
| 759 WebViewInternal.prototype.find = function(search_text, options, callback) { | 759 WebViewInternal.prototype.find = function(search_text, options, callback) { |
| 760 if (!this.instanceId) { | 760 if (!this.guestInstanceId) { |
| 761 return; | 761 return; |
| 762 } | 762 } |
| 763 WebView.find(this.instanceId, search_text, options, callback); | 763 WebView.find(this.guestInstanceId, search_text, options, callback); |
| 764 }; | 764 }; |
| 765 | 765 |
| 766 /** @private */ | 766 /** @private */ |
| 767 WebViewInternal.prototype.stopFinding = function(action) { | 767 WebViewInternal.prototype.stopFinding = function(action) { |
| 768 if (!this.instanceId) { | 768 if (!this.guestInstanceId) { |
| 769 return; | 769 return; |
| 770 } | 770 } |
| 771 WebView.stopFinding(this.instanceId, action); | 771 WebView.stopFinding(this.guestInstanceId, action); |
| 772 }; | 772 }; |
| 773 | 773 |
| 774 /** @private */ | 774 /** @private */ |
| 775 WebViewInternal.prototype.setZoom = function(zoomFactor, callback) { | 775 WebViewInternal.prototype.setZoom = function(zoomFactor, callback) { |
| 776 if (!this.instanceId) { | 776 if (!this.guestInstanceId) { |
| 777 return; | 777 return; |
| 778 } | 778 } |
| 779 WebView.setZoom(this.instanceId, zoomFactor, callback); | 779 WebView.setZoom(this.guestInstanceId, zoomFactor, callback); |
| 780 }; | 780 }; |
| 781 | 781 |
| 782 WebViewInternal.prototype.getZoom = function(callback) { | 782 WebViewInternal.prototype.getZoom = function(callback) { |
| 783 if (!this.instanceId) { | 783 if (!this.guestInstanceId) { |
| 784 return; | 784 return; |
| 785 } | 785 } |
| 786 WebView.getZoom(this.instanceId, callback); | 786 WebView.getZoom(this.guestInstanceId, callback); |
| 787 }; | 787 }; |
| 788 | 788 |
| 789 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { | 789 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { |
| 790 var params = { | 790 var params = { |
| 791 'api': 'webview', | 791 'api': 'webview', |
| 792 'instanceId': this.viewInstanceId, | 792 'instanceId': this.viewInstanceId, |
| 793 'name': this.name, | 793 'name': this.name, |
| 794 // We don't need to navigate new window from here. | 794 // We don't need to navigate new window from here. |
| 795 'src': isNewWindow ? undefined : this.src, | 795 'src': isNewWindow ? undefined : this.src, |
| 796 // If we have a partition from the opener, that will also be already | 796 // If we have a partition from the opener, that will also be already |
| 797 // set via this.onAttach(). | 797 // set via this.onAttach(). |
| 798 'storagePartitionId': this.partition.toAttribute(), | 798 'storagePartitionId': this.partition.toAttribute(), |
| 799 'userAgentOverride': this.userAgentOverride | 799 'userAgentOverride': this.userAgentOverride |
| 800 }; | 800 }; |
| 801 return params; | 801 return params; |
| 802 }; | 802 }; |
| 803 | 803 |
| 804 WebViewInternal.prototype.attachWindow = function(instanceId, isNewWindow) { | 804 WebViewInternal.prototype.attachWindow = function(guestInstanceId, |
| 805 this.instanceId = instanceId; | 805 isNewWindow) { |
| 806 this.guestInstanceId = guestInstanceId; |
| 806 var params = this.buildAttachParams(isNewWindow); | 807 var params = this.buildAttachParams(isNewWindow); |
| 807 | 808 |
| 808 if (!this.hasBindings()) { | 809 if (!this.isPluginInRenderTree()) { |
| 809 // No bindings means that the plugin isn't there (display: none), we defer | |
| 810 // attachWindow in this case. | |
| 811 this.deferredAttachState = {isNewWindow: isNewWindow}; | 810 this.deferredAttachState = {isNewWindow: isNewWindow}; |
| 812 return false; | 811 return false; |
| 813 } | 812 } |
| 814 | 813 |
| 815 this.deferredAttachState = null; | 814 this.deferredAttachState = null; |
| 816 return this.browserPluginNode[PLUGIN_METHOD_ATTACH](this.instanceId, params); | 815 return guestViewInternalNatives.AttachPlugin( |
| 816 this.guestInstanceId, this.internalInstanceId, params, |
| 817 this.browserPluginNode); |
| 817 }; | 818 }; |
| 818 | 819 |
| 819 // Registers browser plugin <object> custom element. | 820 // Registers browser plugin <object> custom element. |
| 820 function registerBrowserPluginElement() { | 821 function registerBrowserPluginElement() { |
| 821 var proto = Object.create(HTMLObjectElement.prototype); | 822 var proto = Object.create(HTMLObjectElement.prototype); |
| 822 | 823 |
| 823 proto.createdCallback = function() { | 824 proto.createdCallback = function() { |
| 824 this.setAttribute('type', 'application/browser-plugin'); | 825 this.setAttribute('type', 'application/browser-plugin'); |
| 825 // The <object> node fills in the <webview> container. | 826 // The <object> node fills in the <webview> container. |
| 826 this.style.width = '100%'; | 827 this.style.width = '100%'; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 } | 866 } |
| 866 internal.handleWebviewAttributeMutation(name, oldValue, newValue); | 867 internal.handleWebviewAttributeMutation(name, oldValue, newValue); |
| 867 }; | 868 }; |
| 868 | 869 |
| 869 proto.detachedCallback = function() { | 870 proto.detachedCallback = function() { |
| 870 var internal = privates(this).internal; | 871 var internal = privates(this).internal; |
| 871 if (!internal) { | 872 if (!internal) { |
| 872 return; | 873 return; |
| 873 } | 874 } |
| 874 internal.elementAttached = false; | 875 internal.elementAttached = false; |
| 876 internal.reset(); |
| 875 }; | 877 }; |
| 876 | 878 |
| 877 proto.attachedCallback = function() { | 879 proto.attachedCallback = function() { |
| 878 var internal = privates(this).internal; | 880 var internal = privates(this).internal; |
| 879 if (!internal) { | 881 if (!internal) { |
| 880 return; | 882 return; |
| 881 } | 883 } |
| 882 if (!internal.elementAttached) { | 884 if (!internal.elementAttached) { |
| 883 internal.elementAttached = true; | 885 internal.elementAttached = true; |
| 884 internal.resetUponReattachment(); | |
| 885 internal.parseAttributes(); | 886 internal.parseAttributes(); |
| 886 } | 887 } |
| 887 }; | 888 }; |
| 888 | 889 |
| 889 var methods = [ | 890 var methods = [ |
| 890 'back', | 891 'back', |
| 891 'find', | 892 'find', |
| 892 'forward', | 893 'forward', |
| 893 'canGoBack', | 894 'canGoBack', |
| 894 'canGoForward', | 895 'canGoForward', |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 * Calls to show contextmenu right away instead of dispatching a 'contextmenu' | 962 * Calls to show contextmenu right away instead of dispatching a 'contextmenu' |
| 962 * event. | 963 * event. |
| 963 * This will be overridden in web_view_experimental.js to implement contextmenu | 964 * This will be overridden in web_view_experimental.js to implement contextmenu |
| 964 * API. | 965 * API. |
| 965 */ | 966 */ |
| 966 WebViewInternal.prototype.maybeHandleContextMenu = function(e, webViewEvent) { | 967 WebViewInternal.prototype.maybeHandleContextMenu = function(e, webViewEvent) { |
| 967 var requestId = e.requestId; | 968 var requestId = e.requestId; |
| 968 // Setting |params| = undefined will show the context menu unmodified, hence | 969 // Setting |params| = undefined will show the context menu unmodified, hence |
| 969 // the 'contextmenu' API is disabled for stable channel. | 970 // the 'contextmenu' API is disabled for stable channel. |
| 970 var params = undefined; | 971 var params = undefined; |
| 971 WebView.showContextMenu(this.instanceId, requestId, params); | 972 WebView.showContextMenu(this.guestInstanceId, requestId, params); |
| 972 }; | 973 }; |
| 973 | 974 |
| 974 /** | 975 /** |
| 975 * Implemented when the experimental API is available. | 976 * Implemented when the experimental API is available. |
| 976 * @private | 977 * @private |
| 977 */ | 978 */ |
| 978 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; | 979 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; |
| 979 | 980 |
| 980 exports.WebView = WebView; | 981 exports.WebView = WebView; |
| 981 exports.WebViewInternal = WebViewInternal; | 982 exports.WebViewInternal = WebViewInternal; |
| OLD | NEW |