Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: extensions/renderer/resources/web_view.js

Issue 618823002: GuestView: Move lifetime management out of content (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added comment Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // Implemented when the experimental API is available. 80 // Implemented when the experimental API is available.
81 WebViewInternal.maybeRegisterExperimentalAPIs = function(proto) {} 81 WebViewInternal.maybeRegisterExperimentalAPIs = function(proto) {}
82 82
83 /** 83 /**
84 * @constructor 84 * @constructor
85 */ 85 */
86 function WebViewInternal(webviewNode) { 86 function WebViewInternal(webviewNode) {
87 privates(webviewNode).internal = this; 87 privates(webviewNode).internal = this;
88 this.webviewNode = webviewNode; 88 this.webviewNode = webviewNode;
89 this.attached = false; 89 this.attached = false;
90 this.pendingGuestCreation = false;
90 this.elementAttached = false; 91 this.elementAttached = false;
91 92
92 this.beforeFirstNavigation = true; 93 this.beforeFirstNavigation = true;
93 this.contentWindow = null; 94 this.contentWindow = null;
94 this.validPartitionId = true; 95 this.validPartitionId = true;
95 // Used to save some state upon deferred attachment. 96 // Used to save some state upon deferred attachment.
96 // If <object> bindings is not available, we defer attachment. 97 // If <object> bindings is not available, we defer attachment.
97 // This state contains whether or not the attachment request was for 98 // This state contains whether or not the attachment request was for
98 // newwindow. 99 // newwindow.
99 this.deferredAttachState = null; 100 this.deferredAttachState = null;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 * Resets some state upon reattaching <webview> element to the DOM. 136 * Resets some state upon reattaching <webview> element to the DOM.
136 */ 137 */
137 WebViewInternal.prototype.reset = function() { 138 WebViewInternal.prototype.reset = function() {
138 // If guestInstanceId is defined then the <webview> has navigated and has 139 // If guestInstanceId is defined then the <webview> has navigated and has
139 // already picked up a partition ID. Thus, we need to reset the initialization 140 // already picked up a partition ID. Thus, we need to reset the initialization
140 // state. However, it may be the case that beforeFirstNavigation is false BUT 141 // state. However, it may be the case that beforeFirstNavigation is false BUT
141 // guestInstanceId has yet to be initialized. This means that we have not 142 // guestInstanceId has yet to be initialized. This means that we have not
142 // heard back from createGuest yet. We will not reset the flag in this case so 143 // heard back from createGuest yet. We will not reset the flag in this case so
143 // that we don't end up allocating a second guest. 144 // that we don't end up allocating a second guest.
144 if (this.guestInstanceId) { 145 if (this.guestInstanceId) {
146 GuestViewInternal.destroyGuest(this.guestInstanceId);
145 this.guestInstanceId = undefined; 147 this.guestInstanceId = undefined;
146 this.beforeFirstNavigation = true; 148 this.beforeFirstNavigation = true;
147 this.validPartitionId = true; 149 this.validPartitionId = true;
148 this.partition.validPartitionId = true; 150 this.partition.validPartitionId = true;
149 this.contentWindow = null; 151 this.contentWindow = null;
150 } 152 }
151 this.internalInstanceId = 0; 153 this.internalInstanceId = 0;
152 }; 154 };
153 155
154 // Sets <webview>.request property. 156 // Sets <webview>.request property.
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 537
536 /** 538 /**
537 * @private 539 * @private
538 */ 540 */
539 WebViewInternal.prototype.handleBrowserPluginAttributeMutation = 541 WebViewInternal.prototype.handleBrowserPluginAttributeMutation =
540 function(name, oldValue, newValue) { 542 function(name, oldValue, newValue) {
541 if (name == 'internalinstanceid' && !oldValue && !!newValue) { 543 if (name == 'internalinstanceid' && !oldValue && !!newValue) {
542 this.browserPluginNode.removeAttribute('internalinstanceid'); 544 this.browserPluginNode.removeAttribute('internalinstanceid');
543 this.internalInstanceId = parseInt(newValue); 545 this.internalInstanceId = parseInt(newValue);
544 546
545 if (!this.deferredAttachState) {
546 this.parseAttributes();
547 return;
548 }
549
550 if (!!this.guestInstanceId && this.guestInstanceId != 0) { 547 if (!!this.guestInstanceId && this.guestInstanceId != 0) {
551 window.setTimeout(function() { 548 var isNewWindow = this.deferredAttachState ?
552 var isNewWindow = this.deferredAttachState ? 549 this.deferredAttachState.isNewWindow : false;
553 this.deferredAttachState.isNewWindow : false; 550 var params = this.buildAttachParams(isNewWindow);
554 var params = this.buildAttachParams(isNewWindow); 551 guestViewInternalNatives.AttachGuest(
555 guestViewInternalNatives.AttachGuest( 552 this.internalInstanceId,
556 this.internalInstanceId, 553 this.guestInstanceId,
557 this.guestInstanceId, 554 params,
558 params, 555 function(w) {
559 function(w) { 556 this.contentWindow = w;
560 this.contentWindow = w; 557 }.bind(this)
561 }.bind(this) 558 );
562 );
563 }.bind(this), 0);
564 } 559 }
565 560
566 return; 561 return;
567 } 562 }
568 }; 563 };
569 564
570 WebViewInternal.prototype.onSizeChanged = function(webViewEvent) { 565 WebViewInternal.prototype.onSizeChanged = function(webViewEvent) {
571 var newWidth = webViewEvent.newWidth; 566 var newWidth = webViewEvent.newWidth;
572 var newHeight = webViewEvent.newHeight; 567 var newHeight = webViewEvent.newHeight;
573 568
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 }; 629 };
635 630
636 WebViewInternal.prototype.hasNavigated = function() { 631 WebViewInternal.prototype.hasNavigated = function() {
637 return !this.beforeFirstNavigation; 632 return !this.beforeFirstNavigation;
638 }; 633 };
639 634
640 /** @return {boolean} */ 635 /** @return {boolean} */
641 WebViewInternal.prototype.parseSrcAttribute = function(result) { 636 WebViewInternal.prototype.parseSrcAttribute = function(result) {
642 if (!this.partition.validPartitionId) { 637 if (!this.partition.validPartitionId) {
643 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE; 638 result.error = ERROR_MSG_INVALID_PARTITION_ATTRIBUTE;
644 return false; 639 return;
645 } 640 }
646 this.src = this.webviewNode.getAttribute('src'); 641 this.src = this.webviewNode.getAttribute('src');
647 642
648 if (!this.src) { 643 if (!this.src) {
649 return true; 644 return;
650 }
651
652 if (!this.elementAttached) {
653 return true;
654 } 645 }
655 646
656 if (!this.hasGuestInstanceID()) { 647 if (!this.hasGuestInstanceID()) {
657 if (this.beforeFirstNavigation) { 648 if (this.beforeFirstNavigation) {
658 this.beforeFirstNavigation = false; 649 this.beforeFirstNavigation = false;
659 this.allocateInstanceId(); 650 this.createGuest();
660 } 651 }
661 return true; 652 return;
662 } 653 }
663 654
664 // Navigate to this.src. 655 // Navigate to this.src.
665 WebView.navigate(this.guestInstanceId, this.src); 656 WebView.navigate(this.guestInstanceId, this.src);
666 return true; 657 return true;
667 }; 658 };
668 659
669 /** @return {boolean} */ 660 /** @return {boolean} */
670 WebViewInternal.prototype.parseAttributes = function() { 661 WebViewInternal.prototype.parseAttributes = function() {
662 if (!this.elementAttached) {
663 return;
664 }
671 var hasNavigated = this.hasNavigated(); 665 var hasNavigated = this.hasNavigated();
672 var attributeValue = this.webviewNode.getAttribute('partition'); 666 var attributeValue = this.webviewNode.getAttribute('partition');
673 var result = this.partition.fromAttribute(attributeValue, hasNavigated); 667 var result = this.partition.fromAttribute(attributeValue, hasNavigated);
674 return this.parseSrcAttribute(result); 668 this.parseSrcAttribute(result);
675 }; 669 };
676 670
677 WebViewInternal.prototype.hasGuestInstanceID = function() { 671 WebViewInternal.prototype.hasGuestInstanceID = function() {
678 return this.guestInstanceId != undefined; 672 return this.guestInstanceId != undefined;
679 }; 673 };
680 674
681 WebViewInternal.prototype.allocateInstanceId = function() { 675 WebViewInternal.prototype.createGuest = function() {
676 if (this.pendingGuestCreation) {
677 return;
678 }
682 var storagePartitionId = 679 var storagePartitionId =
683 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) || 680 this.webviewNode.getAttribute(WEB_VIEW_ATTRIBUTE_PARTITION) ||
684 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION]; 681 this.webviewNode[WEB_VIEW_ATTRIBUTE_PARTITION];
685 var params = { 682 var params = {
686 'storagePartitionId': storagePartitionId, 683 'storagePartitionId': storagePartitionId,
687 }; 684 };
688 GuestViewInternal.createGuest( 685 GuestViewInternal.createGuest(
689 'webview', 686 'webview',
690 params, 687 params,
691 function(guestInstanceId) { 688 function(guestInstanceId) {
689 this.pendingGuestCreation = false;
690 if (!this.elementAttached) {
691 GuestViewInternal.destroyGuest(this.guestInstanceId);
692 return;
693 }
692 this.attachWindow(guestInstanceId, false); 694 this.attachWindow(guestInstanceId, false);
693 }.bind(this) 695 }.bind(this)
694 ); 696 );
697 this.pendingGuestCreation = true;
695 }; 698 };
696 699
697 WebViewInternal.prototype.onFrameNameChanged = function(name) { 700 WebViewInternal.prototype.onFrameNameChanged = function(name) {
698 this.name = name || ''; 701 this.name = name || '';
699 if (this.name === '') { 702 if (this.name === '') {
700 this.webviewNode.removeAttribute('name'); 703 this.webviewNode.removeAttribute('name');
701 } else { 704 } else {
702 this.webviewNode.setAttribute('name', this.name); 705 this.webviewNode.setAttribute('name', this.name);
703 } 706 }
704 }; 707 };
705 708
706 WebViewInternal.prototype.onPluginDestroyed = function() {
707 this.reset();
708 };
709
710 WebViewInternal.prototype.dispatchEvent = function(webViewEvent) { 709 WebViewInternal.prototype.dispatchEvent = function(webViewEvent) {
711 return this.webviewNode.dispatchEvent(webViewEvent); 710 return this.webviewNode.dispatchEvent(webViewEvent);
712 }; 711 };
713 712
714 /** 713 /**
715 * Adds an 'on<event>' property on the webview, which can be used to set/unset 714 * Adds an 'on<event>' property on the webview, which can be used to set/unset
716 * an event handler. 715 * an event handler.
717 */ 716 */
718 WebViewInternal.prototype.setupEventProperty = function(eventName) { 717 WebViewInternal.prototype.setupEventProperty = function(eventName) {
719 var propertyName = 'on' + eventName.toLowerCase(); 718 var propertyName = 'on' + eventName.toLowerCase();
(...skipping 29 matching lines...) Expand all
749 this.ignoreNextSrcAttributeChange = true; 748 this.ignoreNextSrcAttributeChange = true;
750 this.webviewNode.setAttribute('src', newValue); 749 this.webviewNode.setAttribute('src', newValue);
751 } 750 }
752 }; 751 };
753 752
754 WebViewInternal.prototype.onAttach = function(storagePartitionId) { 753 WebViewInternal.prototype.onAttach = function(storagePartitionId) {
755 this.webviewNode.setAttribute('partition', storagePartitionId); 754 this.webviewNode.setAttribute('partition', storagePartitionId);
756 this.partition.fromAttribute(storagePartitionId, this.hasNavigated()); 755 this.partition.fromAttribute(storagePartitionId, this.hasNavigated());
757 }; 756 };
758 757
759
760 /** @private */ 758 /** @private */
761 WebViewInternal.prototype.getUserAgent = function() { 759 WebViewInternal.prototype.getUserAgent = function() {
762 return this.userAgentOverride || navigator.userAgent; 760 return this.userAgentOverride || navigator.userAgent;
763 }; 761 };
764 762
765 /** @private */ 763 /** @private */
766 WebViewInternal.prototype.isUserAgentOverridden = function() { 764 WebViewInternal.prototype.isUserAgentOverridden = function() {
767 return !!this.userAgentOverride && 765 return !!this.userAgentOverride &&
768 this.userAgentOverride != navigator.userAgent; 766 this.userAgentOverride != navigator.userAgent;
769 }; 767 };
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 998
1001 /** 999 /**
1002 * Implemented when the experimental API is available. 1000 * Implemented when the experimental API is available.
1003 * @private 1001 * @private
1004 */ 1002 */
1005 WebViewInternal.prototype.setupExperimentalContextMenus = function() { 1003 WebViewInternal.prototype.setupExperimentalContextMenus = function() {
1006 }; 1004 };
1007 1005
1008 exports.WebView = WebView; 1006 exports.WebView = WebView;
1009 exports.WebViewInternal = WebViewInternal; 1007 exports.WebViewInternal = WebViewInternal;
OLDNEW
« no previous file with comments | « extensions/common/api/guest_view_internal.json ('k') | extensions/renderer/resources/web_view_events.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698