Chromium Code Reviews| 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 = |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 100 // newwindow. | 100 // newwindow. |
| 101 this.deferredAttachState = null; | 101 this.deferredAttachState = null; |
| 102 | 102 |
| 103 // on* Event handlers. | 103 // on* Event handlers. |
| 104 this.on = {}; | 104 this.on = {}; |
| 105 | 105 |
| 106 this.browserPluginNode = this.createBrowserPluginNode(); | 106 this.browserPluginNode = this.createBrowserPluginNode(); |
| 107 var shadowRoot = this.webviewNode.createShadowRoot(); | 107 var shadowRoot = this.webviewNode.createShadowRoot(); |
| 108 this.partition = new Partition(); | 108 this.partition = new Partition(); |
| 109 | 109 |
| 110 this.setupWebviewNodeAttributes(); | 110 this.setupWebViewSrcAttributeMutationObserver(); |
| 111 this.setupFocusPropagation(); | 111 this.setupFocusPropagation(); |
| 112 this.setupWebviewNodeProperties(); | 112 this.setupWebviewNodeProperties(); |
| 113 | 113 |
| 114 this.viewInstanceId = IdGenerator.GetNextId(); | 114 this.viewInstanceId = IdGenerator.GetNextId(); |
| 115 | 115 |
| 116 new WebViewEvents(this, this.viewInstanceId); | 116 new WebViewEvents(this, this.viewInstanceId); |
| 117 | 117 |
| 118 shadowRoot.appendChild(this.browserPluginNode); | 118 shadowRoot.appendChild(this.browserPluginNode); |
| 119 } | 119 } |
| 120 | 120 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 }; | 162 }; |
| 163 | 163 |
| 164 WebViewInternal.prototype.setupFocusPropagation = function() { | 164 WebViewInternal.prototype.setupFocusPropagation = function() { |
| 165 if (!this.webviewNode.hasAttribute('tabIndex')) { | 165 if (!this.webviewNode.hasAttribute('tabIndex')) { |
| 166 // <webview> needs a tabIndex in order to be focusable. | 166 // <webview> needs a tabIndex in order to be focusable. |
| 167 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute | 167 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute |
| 168 // to allow <webview> to be focusable. | 168 // to allow <webview> to be focusable. |
| 169 // See http://crbug.com/231664. | 169 // See http://crbug.com/231664. |
| 170 this.webviewNode.setAttribute('tabIndex', -1); | 170 this.webviewNode.setAttribute('tabIndex', -1); |
| 171 } | 171 } |
| 172 var self = this; | |
| 173 this.webviewNode.addEventListener('focus', function(e) { | 172 this.webviewNode.addEventListener('focus', function(e) { |
| 174 // Focus the BrowserPlugin when the <webview> takes focus. | 173 // Focus the BrowserPlugin when the <webview> takes focus. |
| 175 this.browserPluginNode.focus(); | 174 this.browserPluginNode.focus(); |
| 176 }.bind(this)); | 175 }.bind(this)); |
| 177 this.webviewNode.addEventListener('blur', function(e) { | 176 this.webviewNode.addEventListener('blur', function(e) { |
| 178 // Blur the BrowserPlugin when the <webview> loses focus. | 177 // Blur the BrowserPlugin when the <webview> loses focus. |
| 179 this.browserPluginNode.blur(); | 178 this.browserPluginNode.blur(); |
| 180 }.bind(this)); | 179 }.bind(this)); |
| 181 }; | 180 }; |
| 182 | 181 |
| 183 // Navigates to the previous history entry. | 182 // Validation helper function for executeScript() and insertCSS(). |
| 184 WebViewInternal.prototype.back = function(callback) { | |
| 185 return this.go(-1, callback); | |
| 186 }; | |
| 187 | |
| 188 // Navigates to the subsequent history entry. | |
| 189 WebViewInternal.prototype.forward = function(callback) { | |
| 190 return this.go(1, callback); | |
| 191 }; | |
| 192 | |
| 193 // Returns whether there is a previous history entry to navigate to. | |
| 194 WebViewInternal.prototype.canGoBack = function() { | |
| 195 return this.entryCount > 1 && this.currentEntryIndex > 0; | |
| 196 }; | |
| 197 | |
| 198 // Returns whether there is a subsequent history entry to navigate to. | |
| 199 WebViewInternal.prototype.canGoForward = function() { | |
| 200 return this.currentEntryIndex >= 0 && | |
| 201 this.currentEntryIndex < (this.entryCount - 1); | |
| 202 }; | |
| 203 | |
| 204 // Clears browsing data for the WebView partition. | |
| 205 WebViewInternal.prototype.clearData = function() { | |
| 206 if (!this.guestInstanceId) { | |
| 207 return; | |
| 208 } | |
| 209 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); | |
| 210 $Function.apply(WebView.clearData, null, args); | |
| 211 }; | |
| 212 | |
| 213 // Returns Chrome's internal process ID for the guest web page's current | |
| 214 // process. | |
| 215 WebViewInternal.prototype.getProcessId = function() { | |
| 216 return this.processId; | |
| 217 }; | |
| 218 | |
| 219 // Navigates to a history entry using a history index relative to the current | |
| 220 // navigation. | |
| 221 WebViewInternal.prototype.go = function(relativeIndex, callback) { | |
| 222 if (!this.guestInstanceId) { | |
| 223 return; | |
| 224 } | |
| 225 WebView.go(this.guestInstanceId, relativeIndex, callback); | |
| 226 }; | |
| 227 | |
| 228 // Prints the contents of the webview. | |
| 229 WebViewInternal.prototype.print = function() { | |
| 230 this.executeScript({code: 'window.print();'}); | |
| 231 }; | |
| 232 | |
| 233 // Reloads the current top-level page. | |
| 234 WebViewInternal.prototype.reload = function() { | |
| 235 if (!this.guestInstanceId) { | |
| 236 return; | |
| 237 } | |
| 238 WebView.reload(this.guestInstanceId); | |
| 239 }; | |
| 240 | |
| 241 // Stops loading the current navigation if one is in progress. | |
| 242 WebViewInternal.prototype.stop = function() { | |
| 243 if (!this.guestInstanceId) { | |
| 244 return; | |
| 245 } | |
| 246 WebView.stop(this.guestInstanceId); | |
| 247 }; | |
| 248 | |
| 249 // Forcibly kills the guest web page's renderer process. | |
| 250 WebViewInternal.prototype.terminate = function() { | |
| 251 if (!this.guestInstanceId) { | |
| 252 return; | |
| 253 } | |
| 254 WebView.terminate(this.guestInstanceId); | |
| 255 }; | |
| 256 | |
| 257 WebViewInternal.prototype.validateExecuteCodeCall = function() { | 183 WebViewInternal.prototype.validateExecuteCodeCall = function() { |
| 258 if (!this.guestInstanceId) { | 184 if (!this.guestInstanceId) { |
| 259 throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT); | 185 throw new Error(ERROR_MSG_CANNOT_INJECT_SCRIPT); |
| 260 } | 186 } |
| 261 }; | 187 }; |
| 262 | 188 |
| 263 // Injects JavaScript code into the guest page. | |
| 264 WebViewInternal.prototype.executeScript = function(var_args) { | |
| 265 this.validateExecuteCodeCall(); | |
| 266 var webview_src = this.src; | |
| 267 if (this.baseUrlForDataUrl != '') { | |
| 268 webview_src = this.baseUrlForDataUrl; | |
| 269 } | |
| 270 var args = $Array.concat([this.guestInstanceId, webview_src], | |
| 271 $Array.slice(arguments)); | |
| 272 $Function.apply(WebView.executeScript, null, args); | |
| 273 }; | |
| 274 | |
| 275 // Injects CSS into the guest page. | |
| 276 WebViewInternal.prototype.insertCSS = function(var_args) { | |
| 277 this.validateExecuteCodeCall(); | |
| 278 var webview_src = this.src; | |
| 279 if (this.baseUrlForDataUrl != '') { | |
| 280 webview_src = this.baseUrlForDataUrl; | |
| 281 } | |
| 282 var args = $Array.concat([this.guestInstanceId, webview_src], | |
| 283 $Array.slice(arguments)); | |
| 284 $Function.apply(WebView.insertCSS, null, args); | |
| 285 }; | |
| 286 | |
| 287 WebViewInternal.prototype.setupAutoSizeProperties = function() { | 189 WebViewInternal.prototype.setupAutoSizeProperties = function() { |
| 288 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { | 190 $Array.forEach(AUTO_SIZE_ATTRIBUTES, function(attributeName) { |
| 289 this[attributeName] = this.webviewNode.getAttribute(attributeName); | 191 this[attributeName] = this.webviewNode.getAttribute(attributeName); |
| 290 Object.defineProperty(this.webviewNode, attributeName, { | 192 Object.defineProperty(this.webviewNode, attributeName, { |
| 291 get: function() { | 193 get: function() { |
| 292 return this[attributeName]; | 194 return this[attributeName]; |
| 293 }.bind(this), | 195 }.bind(this), |
| 294 set: function(value) { | 196 set: function(value) { |
| 295 this.webviewNode.setAttribute(attributeName, value); | 197 this.webviewNode.setAttribute(attributeName, value); |
| 296 }.bind(this), | 198 }.bind(this), |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 return this.src; | 259 return this.src; |
| 358 }.bind(this), | 260 }.bind(this), |
| 359 set: function(value) { | 261 set: function(value) { |
| 360 this.webviewNode.setAttribute('src', value); | 262 this.webviewNode.setAttribute('src', value); |
| 361 }.bind(this), | 263 }.bind(this), |
| 362 // No setter. | 264 // No setter. |
| 363 enumerable: true | 265 enumerable: true |
| 364 }); | 266 }); |
| 365 }; | 267 }; |
| 366 | 268 |
| 367 WebViewInternal.prototype.setupWebviewNodeAttributes = function() { | |
| 368 this.setupWebViewSrcAttributeMutationObserver(); | |
| 369 }; | |
| 370 | |
| 371 // The purpose of this mutation observer is to catch assignment to the src | 269 // The purpose of this mutation observer is to catch assignment to the src |
| 372 // attribute without any changes to its value. This is useful in the case | 270 // attribute without any changes to its value. This is useful in the case |
| 373 // where the webview guest has crashed and navigating to the same address | 271 // where the webview guest has crashed and navigating to the same address |
| 374 // spawns off a new process. | 272 // spawns off a new process. |
| 375 WebViewInternal.prototype.setupWebViewSrcAttributeMutationObserver = | 273 WebViewInternal.prototype.setupWebViewSrcAttributeMutationObserver = |
| 376 function() { | 274 function() { |
| 377 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { | 275 this.srcAndPartitionObserver = new MutationObserver(function(mutations) { |
| 378 $Array.forEach(mutations, function(mutation) { | 276 $Array.forEach(mutations, function(mutation) { |
| 379 var oldValue = mutation.oldValue; | 277 var oldValue = mutation.oldValue; |
| 380 var newValue = this.webviewNode.getAttribute(mutation.attributeName); | 278 var newValue = this.webviewNode.getAttribute(mutation.attributeName); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 585 if (!this.partition.validPartitionId) { | 483 if (!this.partition.validPartitionId) { |
| 586 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; | 484 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; |
| 587 return; | 485 return; |
| 588 } | 486 } |
| 589 this.src = this.webviewNode.getAttribute('src'); | 487 this.src = this.webviewNode.getAttribute('src'); |
| 590 | 488 |
| 591 if (!this.src) { | 489 if (!this.src) { |
| 592 return; | 490 return; |
| 593 } | 491 } |
| 594 | 492 |
| 595 if (!this.hasGuestInstanceID()) { | 493 if (this.guestInstanceId == undefined) { |
| 596 if (this.beforeFirstNavigation) { | 494 if (this.beforeFirstNavigation) { |
| 597 this.beforeFirstNavigation = false; | 495 this.beforeFirstNavigation = false; |
| 598 this.createGuest(); | 496 this.createGuest(); |
| 599 } | 497 } |
| 600 return; | 498 return; |
| 601 } | 499 } |
| 602 | 500 |
| 603 // Navigate to |this.src|. | 501 // Navigate to |this.src|. |
| 604 WebView.navigate(this.guestInstanceId, this.src); | 502 WebView.navigate(this.guestInstanceId, this.src); |
| 605 return true; | |
| 606 }; | 503 }; |
| 607 | 504 |
| 608 WebViewInternal.prototype.parseAttributes = function() { | 505 WebViewInternal.prototype.parseAttributes = function() { |
| 609 if (!this.elementAttached) { | 506 if (!this.elementAttached) { |
| 610 return; | 507 return; |
| 611 } | 508 } |
| 612 var hasNavigated = this.hasNavigated(); | 509 var hasNavigated = this.hasNavigated(); |
| 613 var attributeValue = this.webviewNode.getAttribute('partition'); | 510 var attributeValue = this.webviewNode.getAttribute('partition'); |
| 614 var result = this.partition.fromAttribute(attributeValue, hasNavigated); | 511 var result = this.partition.fromAttribute(attributeValue, hasNavigated); |
| 615 this.parseSrcAttribute(result); | 512 this.parseSrcAttribute(result); |
| 616 }; | 513 }; |
| 617 | 514 |
| 618 WebViewInternal.prototype.hasGuestInstanceID = function() { | |
| 619 return this.guestInstanceId != undefined; | |
| 620 }; | |
| 621 | |
| 622 WebViewInternal.prototype.createGuest = function() { | 515 WebViewInternal.prototype.createGuest = function() { |
| 623 if (this.pendingGuestCreation) { | 516 if (this.pendingGuestCreation) { |
| 624 return; | 517 return; |
| 625 } | 518 } |
| 626 var storagePartitionId = | 519 var storagePartitionId = |
| 627 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || | 520 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || |
| 628 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; | 521 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; |
| 629 var params = { | 522 var params = { |
| 630 'storagePartitionId': storagePartitionId | 523 'storagePartitionId': storagePartitionId |
| 631 }; | 524 }; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 693 this.ignoreNextSrcAttributeChange = true; | 586 this.ignoreNextSrcAttributeChange = true; |
| 694 this.webviewNode.setAttribute('src', newValue); | 587 this.webviewNode.setAttribute('src', newValue); |
| 695 } | 588 } |
| 696 }; | 589 }; |
| 697 | 590 |
| 698 WebViewInternal.prototype.onAttach = function(storagePartitionId) { | 591 WebViewInternal.prototype.onAttach = function(storagePartitionId) { |
| 699 this.webviewNode.setAttribute('partition', storagePartitionId); | 592 this.webviewNode.setAttribute('partition', storagePartitionId); |
| 700 this.partition.fromAttribute(storagePartitionId, this.hasNavigated()); | 593 this.partition.fromAttribute(storagePartitionId, this.hasNavigated()); |
| 701 }; | 594 }; |
| 702 | 595 |
| 596 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { | |
| 597 var params = { | |
| 598 'allowtransparency': this.allowtransparency || false, | |
| 599 'autosize': this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE), | |
| 600 'instanceId': this.viewInstanceId, | |
| 601 'maxheight': parseInt(this.maxheight || 0), | |
| 602 'maxwidth': parseInt(this.maxwidth || 0), | |
| 603 'minheight': parseInt(this.minheight || 0), | |
| 604 'minwidth': parseInt(this.minwidth || 0), | |
| 605 'name': this.name, | |
| 606 // We don't need to navigate new window from here. | |
| 607 'src': isNewWindow ? undefined : this.src, | |
| 608 // If we have a partition from the opener, that will also be already | |
| 609 // set via this.onAttach(). | |
| 610 'storagePartitionId': this.partition.toAttribute(), | |
| 611 'userAgentOverride': this.userAgentOverride | |
| 612 }; | |
| 613 return params; | |
| 614 }; | |
| 615 | |
| 616 WebViewInternal.prototype.attachWindow = function(guestInstanceId, | |
| 617 isNewWindow) { | |
| 618 this.guestInstanceId = guestInstanceId; | |
| 619 var params = this.buildAttachParams(isNewWindow); | |
| 620 | |
| 621 if (!this.isPluginInRenderTree()) { | |
| 622 this.deferredAttachState = {isNewWindow: isNewWindow}; | |
| 623 return true; | |
| 624 } | |
| 625 | |
| 626 this.deferredAttachState = null; | |
| 627 return guestViewInternalNatives.AttachGuest( | |
| 628 this.internalInstanceId, | |
| 629 this.guestInstanceId, | |
| 630 params, function(w) { | |
| 631 this.contentWindow = w; | |
| 632 }.bind(this) | |
| 633 ); | |
| 634 }; | |
| 635 | |
| 636 // ----------------------------------------------------------------------------- | |
| 637 // Public-facing API methods. | |
| 638 | |
| 639 | |
| 640 // Navigates to the previous history entry. | |
| 641 WebViewInternal.prototype.back = function(callback) { | |
| 642 return this.go(-1, callback); | |
| 643 }; | |
| 644 | |
| 645 // Returns whether there is a previous history entry to navigate to. | |
| 646 WebViewInternal.prototype.canGoBack = function() { | |
| 647 return this.entryCount > 1 && this.currentEntryIndex > 0; | |
| 648 }; | |
| 649 | |
| 650 // Returns whether there is a subsequent history entry to navigate to. | |
| 651 WebViewInternal.prototype.canGoForward = function() { | |
| 652 return this.currentEntryIndex >= 0 && | |
| 653 this.currentEntryIndex < (this.entryCount - 1); | |
| 654 }; | |
| 655 | |
| 656 // Clears browsing data for the WebView partition. | |
| 657 WebViewInternal.prototype.clearData = function() { | |
| 658 if (!this.guestInstanceId) { | |
| 659 return; | |
| 660 } | |
| 661 var args = $Array.concat([this.guestInstanceId], $Array.slice(arguments)); | |
| 662 $Function.apply(WebView.clearData, null, args); | |
| 663 }; | |
| 664 | |
| 665 // Injects JavaScript code into the guest page. | |
| 666 WebViewInternal.prototype.executeScript = function(var_args) { | |
| 667 this.validateExecuteCodeCall(); | |
| 668 var webview_src = this.src; | |
|
lazyboy
2014/10/09 20:27:20
nit: rename to webviewSrc
| |
| 669 if (this.baseUrlForDataUrl != '') { | |
| 670 webview_src = this.baseUrlForDataUrl; | |
| 671 } | |
| 672 var args = $Array.concat([this.guestInstanceId, webview_src], | |
| 673 $Array.slice(arguments)); | |
| 674 $Function.apply(WebView.executeScript, null, args); | |
| 675 }; | |
| 676 | |
| 677 // Initiates a find-in-page request. | |
| 678 WebViewInternal.prototype.find = function(search_text, options, callback) { | |
| 679 if (!this.guestInstanceId) { | |
| 680 return; | |
| 681 } | |
| 682 WebView.find(this.guestInstanceId, search_text, options, callback); | |
| 683 }; | |
| 684 | |
| 685 // Navigates to the subsequent history entry. | |
| 686 WebViewInternal.prototype.forward = function(callback) { | |
| 687 return this.go(1, callback); | |
| 688 }; | |
| 689 | |
| 690 // Returns Chrome's internal process ID for the guest web page's current | |
| 691 // process. | |
| 692 WebViewInternal.prototype.getProcessId = function() { | |
| 693 return this.processId; | |
| 694 }; | |
| 695 | |
| 703 // Returns the user agent string used by the webview for guest page requests. | 696 // Returns the user agent string used by the webview for guest page requests. |
| 704 WebViewInternal.prototype.getUserAgent = function() { | 697 WebViewInternal.prototype.getUserAgent = function() { |
| 705 return this.userAgentOverride || navigator.userAgent; | 698 return this.userAgentOverride || navigator.userAgent; |
| 706 }; | 699 }; |
| 707 | 700 |
| 701 // Gets the current zoom factor. | |
| 702 WebViewInternal.prototype.getZoom = function(callback) { | |
| 703 if (!this.guestInstanceId) { | |
| 704 return; | |
| 705 } | |
| 706 WebView.getZoom(this.guestInstanceId, callback); | |
| 707 }; | |
| 708 | |
| 709 // Navigates to a history entry using a history index relative to the current | |
| 710 // navigation. | |
| 711 WebViewInternal.prototype.go = function(relativeIndex, callback) { | |
| 712 if (!this.guestInstanceId) { | |
| 713 return; | |
| 714 } | |
| 715 WebView.go(this.guestInstanceId, relativeIndex, callback); | |
| 716 }; | |
| 717 | |
| 718 // Injects CSS into the guest page. | |
| 719 WebViewInternal.prototype.insertCSS = function(var_args) { | |
| 720 this.validateExecuteCodeCall(); | |
| 721 var webview_src = this.src; | |
|
lazyboy
2014/10/09 20:27:20
Same
| |
| 722 if (this.baseUrlForDataUrl != '') { | |
| 723 webview_src = this.baseUrlForDataUrl; | |
| 724 } | |
| 725 var args = $Array.concat([this.guestInstanceId, webview_src], | |
| 726 $Array.slice(arguments)); | |
| 727 $Function.apply(WebView.insertCSS, null, args); | |
| 728 }; | |
| 729 | |
| 708 // Indicates whether or not the webview's user agent string has been overridden. | 730 // Indicates whether or not the webview's user agent string has been overridden. |
| 709 WebViewInternal.prototype.isUserAgentOverridden = function() { | 731 WebViewInternal.prototype.isUserAgentOverridden = function() { |
| 710 return !!this.userAgentOverride && | 732 return !!this.userAgentOverride && |
| 711 this.userAgentOverride != navigator.userAgent; | 733 this.userAgentOverride != navigator.userAgent; |
| 712 }; | 734 }; |
| 713 | 735 |
| 736 // Prints the contents of the webview. | |
| 737 WebViewInternal.prototype.print = function() { | |
| 738 this.executeScript({code: 'window.print();'}); | |
| 739 }; | |
| 740 | |
| 741 // Reloads the current top-level page. | |
| 742 WebViewInternal.prototype.reload = function() { | |
| 743 if (!this.guestInstanceId) { | |
| 744 return; | |
| 745 } | |
| 746 WebView.reload(this.guestInstanceId); | |
| 747 }; | |
| 748 | |
| 714 // Override the user agent string used by the webview for guest page requests. | 749 // Override the user agent string used by the webview for guest page requests. |
| 715 WebViewInternal.prototype.setUserAgentOverride = function(userAgentOverride) { | 750 WebViewInternal.prototype.setUserAgentOverride = function(userAgentOverride) { |
| 716 this.userAgentOverride = userAgentOverride; | 751 this.userAgentOverride = userAgentOverride; |
| 717 if (!this.guestInstanceId) { | 752 if (!this.guestInstanceId) { |
| 718 // If we are not attached yet, then we will pick up the user agent on | 753 // If we are not attached yet, then we will pick up the user agent on |
| 719 // attachment. | 754 // attachment. |
| 720 return; | 755 return; |
| 721 } | 756 } |
| 722 WebView.overrideUserAgent(this.guestInstanceId, userAgentOverride); | 757 WebView.overrideUserAgent(this.guestInstanceId, userAgentOverride); |
| 723 }; | 758 }; |
| 724 | 759 |
| 725 // Initiates a find-in-page request. | 760 // Changes the zoom factor of the page. |
| 726 WebViewInternal.prototype.find = function(search_text, options, callback) { | 761 WebViewInternal.prototype.setZoom = function(zoomFactor, callback) { |
| 727 if (!this.guestInstanceId) { | 762 if (!this.guestInstanceId) { |
| 728 return; | 763 return; |
| 729 } | 764 } |
| 730 WebView.find(this.guestInstanceId, search_text, options, callback); | 765 WebView.setZoom(this.guestInstanceId, zoomFactor, callback); |
| 766 }; | |
| 767 | |
| 768 // Stops loading the current navigation if one is in progress. | |
| 769 WebViewInternal.prototype.stop = function() { | |
| 770 if (!this.guestInstanceId) { | |
| 771 return; | |
| 772 } | |
| 773 WebView.stop(this.guestInstanceId); | |
| 731 }; | 774 }; |
| 732 | 775 |
| 733 // Ends the current find session. | 776 // Ends the current find session. |
| 734 WebViewInternal.prototype.stopFinding = function(action) { | 777 WebViewInternal.prototype.stopFinding = function(action) { |
| 735 if (!this.guestInstanceId) { | 778 if (!this.guestInstanceId) { |
| 736 return; | 779 return; |
| 737 } | 780 } |
| 738 WebView.stopFinding(this.guestInstanceId, action); | 781 WebView.stopFinding(this.guestInstanceId, action); |
| 739 }; | 782 }; |
| 740 | 783 |
| 741 // Changes the zoom factor of the page. | 784 // Forcibly kills the guest web page's renderer process. |
| 742 WebViewInternal.prototype.setZoom = function(zoomFactor, callback) { | 785 WebViewInternal.prototype.terminate = function() { |
| 743 if (!this.guestInstanceId) { | 786 if (!this.guestInstanceId) { |
| 744 return; | 787 return; |
| 745 } | 788 } |
| 746 WebView.setZoom(this.guestInstanceId, zoomFactor, callback); | 789 WebView.terminate(this.guestInstanceId); |
| 747 }; | 790 }; |
| 748 | 791 |
| 749 // Gets the current zoom factor. | 792 // ----------------------------------------------------------------------------- |
| 750 WebViewInternal.prototype.getZoom = function(callback) { | |
| 751 if (!this.guestInstanceId) { | |
| 752 return; | |
| 753 } | |
| 754 WebView.getZoom(this.guestInstanceId, callback); | |
| 755 }; | |
| 756 | |
| 757 WebViewInternal.prototype.buildAttachParams = function(isNewWindow) { | |
| 758 var params = { | |
| 759 'allowtransparency': this.allowtransparency || false, | |
| 760 'autosize': this.webviewNode.hasAttribute(WEB_VIEW_ATTRIBUTE_AUTOSIZE), | |
| 761 'instanceId': this.viewInstanceId, | |
| 762 'maxheight': parseInt(this.maxheight || 0), | |
| 763 'maxwidth': parseInt(this.maxwidth || 0), | |
| 764 'minheight': parseInt(this.minheight || 0), | |
| 765 'minwidth': parseInt(this.minwidth || 0), | |
| 766 'name': this.name, | |
| 767 // We don't need to navigate new window from here. | |
| 768 'src': isNewWindow ? undefined : this.src, | |
| 769 // If we have a partition from the opener, that will also be already | |
| 770 // set via this.onAttach(). | |
| 771 'storagePartitionId': this.partition.toAttribute(), | |
| 772 'userAgentOverride': this.userAgentOverride | |
| 773 }; | |
| 774 return params; | |
| 775 }; | |
| 776 | |
| 777 WebViewInternal.prototype.attachWindow = function(guestInstanceId, | |
| 778 isNewWindow) { | |
| 779 this.guestInstanceId = guestInstanceId; | |
| 780 var params = this.buildAttachParams(isNewWindow); | |
| 781 | |
| 782 if (!this.isPluginInRenderTree()) { | |
| 783 this.deferredAttachState = {isNewWindow: isNewWindow}; | |
| 784 return true; | |
| 785 } | |
| 786 | |
| 787 this.deferredAttachState = null; | |
| 788 return guestViewInternalNatives.AttachGuest( | |
| 789 this.internalInstanceId, | |
| 790 this.guestInstanceId, | |
| 791 params, function(w) { | |
| 792 this.contentWindow = w; | |
| 793 }.bind(this) | |
| 794 ); | |
| 795 }; | |
| 796 | 793 |
| 797 // Registers browser plugin <object> custom element. | 794 // Registers browser plugin <object> custom element. |
| 798 function registerBrowserPluginElement() { | 795 function registerBrowserPluginElement() { |
| 799 var proto = Object.create(HTMLObjectElement.prototype); | 796 var proto = Object.create(HTMLObjectElement.prototype); |
| 800 | 797 |
| 801 proto.createdCallback = function() { | 798 proto.createdCallback = function() { |
| 802 this.setAttribute('type', 'application/browser-plugin'); | 799 this.setAttribute('type', 'application/browser-plugin'); |
| 803 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); | 800 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); |
| 804 // The <object> node fills in the <webview> container. | 801 // The <object> node fills in the <webview> container. |
| 805 this.style.width = '100%'; | 802 this.style.width = '100%'; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 } | 858 } |
| 862 if (!internal.elementAttached) { | 859 if (!internal.elementAttached) { |
| 863 internal.elementAttached = true; | 860 internal.elementAttached = true; |
| 864 internal.parseAttributes(); | 861 internal.parseAttributes(); |
| 865 } | 862 } |
| 866 }; | 863 }; |
| 867 | 864 |
| 868 // Public-facing API methods. | 865 // Public-facing API methods. |
| 869 var methods = [ | 866 var methods = [ |
| 870 'back', | 867 'back', |
| 871 'find', | |
| 872 'forward', | |
| 873 'canGoBack', | 868 'canGoBack', |
| 874 'canGoForward', | 869 'canGoForward', |
| 875 'clearData', | 870 'clearData', |
| 871 'executeScript', | |
| 872 'find', | |
| 873 'forward', | |
| 876 'getProcessId', | 874 'getProcessId', |
| 875 'getUserAgent', | |
| 877 'getZoom', | 876 'getZoom', |
| 878 'go', | 877 'go', |
| 878 'insertCSS', | |
| 879 'isUserAgentOverridden', | |
| 879 'print', | 880 'print', |
| 880 'reload', | 881 'reload', |
| 882 'setUserAgentOverride', | |
| 881 'setZoom', | 883 'setZoom', |
| 882 'stop', | 884 'stop', |
| 883 'stopFinding', | 885 'stopFinding', |
| 884 'terminate', | 886 'terminate' |
| 885 'executeScript', | |
| 886 'insertCSS', | |
| 887 'getUserAgent', | |
| 888 'isUserAgentOverridden', | |
| 889 'setUserAgentOverride' | |
| 890 ]; | 887 ]; |
| 891 | 888 |
| 892 // Add the experimental API methods, if available. | 889 // Add the experimental API methods, if available. |
| 893 var experimentalMethods = | 890 var experimentalMethods = |
| 894 WebViewInternal.maybeGetExperimentalAPIs(); | 891 WebViewInternal.maybeGetExperimentalAPIs(); |
| 895 methods = $Array.concat(methods, experimentalMethods); | 892 methods = $Array.concat(methods, experimentalMethods); |
| 896 | 893 |
| 897 // Forward proto.foo* method calls to WebViewInternal.foo*. | 894 // Forward proto.foo* method calls to WebViewInternal.foo*. |
| 898 var createHandler = function(m) { | 895 var createHandler = function(m) { |
| 899 return function(var_args) { | 896 return function(var_args) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 930 WebViewInternal.prototype.maybeGetChromeWebViewEvents = function() {}; | 927 WebViewInternal.prototype.maybeGetChromeWebViewEvents = function() {}; |
| 931 | 928 |
| 932 // Implemented when the experimental WebView API is available. | 929 // Implemented when the experimental WebView API is available. |
| 933 WebViewInternal.maybeGetExperimentalAPIs = function() {}; | 930 WebViewInternal.maybeGetExperimentalAPIs = function() {}; |
| 934 WebViewInternal.prototype.maybeGetExperimentalEvents = function() {}; | 931 WebViewInternal.prototype.maybeGetExperimentalEvents = function() {}; |
| 935 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; | 932 WebViewInternal.prototype.setupExperimentalContextMenus = function() {}; |
| 936 | 933 |
| 937 // Exports. | 934 // Exports. |
| 938 exports.WebView = WebView; | 935 exports.WebView = WebView; |
| 939 exports.WebViewInternal = WebViewInternal; | 936 exports.WebViewInternal = WebViewInternal; |
| OLD | NEW |