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

Side by Side Diff: extensions/renderer/resources/guest_view/guest_view_container.js

Issue 972313002: Make <webview> use out-of-process iframe architecture. (Closed) Base URL: ssh://saopaulo.wat/mnt/dev/shared/src@testoopif2z-better-chrome
Patch Set: address all comments from Nasko and Charlie, minus is_loading Created 5 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 the shared functionality for different guestview 5 // This module implements the shared functionality for different guestview
6 // containers, such as web_view, app_view, etc. 6 // containers, such as web_view, app_view, etc.
7 7
8 var DocumentNatives = requireNative('document_natives'); 8 var DocumentNatives = requireNative('document_natives');
9 var GuestView = require('guestView').GuestView; 9 var GuestView = require('guestView').GuestView;
10 var GuestViewInternalNatives = requireNative('guest_view_internal'); 10 var GuestViewInternalNatives = requireNative('guest_view_internal');
11 var IdGenerator = requireNative('id_generator'); 11 var IdGenerator = requireNative('id_generator');
12 12
13 function GuestViewContainer(element, viewType) { 13 function GuestViewContainer(element, viewType) {
14 privates(element).internal = this; 14 privates(element).internal = this;
15 this.attributes = {}; 15 this.attributes = {};
16 this.element = element; 16 this.element = element;
17 this.elementAttached = false; 17 this.elementAttached = false;
18 this.viewInstanceId = IdGenerator.GetNextId(); 18 this.viewInstanceId = IdGenerator.GetNextId();
19 this.viewType = viewType; 19 this.viewType = viewType;
20 20
21 this.setupGuestProperty(); 21 this.setupGuestProperty();
22 this.guest = new GuestView(viewType); 22 this.guest = new GuestView(viewType);
23 this.setupAttributes(); 23 this.setupAttributes();
24 24
25 privates(this).browserPluginElement = this.createBrowserPluginElement(); 25 privates(this).browserPluginElement = this.createBrowserPluginElement();
26 this.guest.setBrowserPluginElement(privates(this).browserPluginElement);
Fady Samuel 2015/05/26 16:42:15 Why is this necessary? Also, guests can change the
26 this.setupFocusPropagation(); 27 this.setupFocusPropagation();
27 var shadowRoot = this.element.createShadowRoot(); 28 var shadowRoot = this.element.createShadowRoot();
28 shadowRoot.appendChild(privates(this).browserPluginElement); 29 shadowRoot.appendChild(privates(this).browserPluginElement);
29 } 30 }
30 31
31 // Forward public API methods from |proto| to their internal implementations. 32 // Forward public API methods from |proto| to their internal implementations.
32 GuestViewContainer.forwardApiMethods = function(proto, apiMethods) { 33 GuestViewContainer.forwardApiMethods = function(proto, apiMethods) {
33 var createProtoHandler = function(m) { 34 var createProtoHandler = function(m) {
34 return function(var_args) { 35 return function(var_args) {
35 var internal = privates(this).internal; 36 var internal = privates(this).internal;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 85
85 GuestViewContainer.prototype.createBrowserPluginElement = function() { 86 GuestViewContainer.prototype.createBrowserPluginElement = function() {
86 // We create BrowserPlugin as a custom element in order to observe changes 87 // We create BrowserPlugin as a custom element in order to observe changes
87 // to attributes synchronously. 88 // to attributes synchronously.
88 var browserPluginElement = 89 var browserPluginElement =
89 new GuestViewContainer[this.viewType + 'BrowserPlugin'](); 90 new GuestViewContainer[this.viewType + 'BrowserPlugin']();
90 privates(browserPluginElement).internal = this; 91 privates(browserPluginElement).internal = this;
91 return browserPluginElement; 92 return browserPluginElement;
92 }; 93 };
93 94
95 GuestViewContainer.prototype.getBrowserPluginElement = function() {
96 return privates(this).browserPluginElement;
97 };
98
94 GuestViewContainer.prototype.setupFocusPropagation = function() { 99 GuestViewContainer.prototype.setupFocusPropagation = function() {
95 if (!this.element.hasAttribute('tabIndex')) { 100 if (!this.element.hasAttribute('tabIndex')) {
96 // GuestViewContainer needs a tabIndex in order to be focusable. 101 // GuestViewContainer needs a tabIndex in order to be focusable.
97 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute 102 // TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
98 // to allow GuestViewContainer to be focusable. 103 // to allow GuestViewContainer to be focusable.
99 // See http://crbug.com/231664. 104 // See http://crbug.com/231664.
100 this.element.setAttribute('tabIndex', -1); 105 this.element.setAttribute('tabIndex', -1);
101 } 106 }
102 this.element.addEventListener('focus', function(e) { 107 this.element.addEventListener('focus', function(e) {
103 // Focus the BrowserPlugin when the GuestViewContainer takes focus. 108 // Focus the BrowserPlugin when the GuestViewContainer takes focus.
104 privates(this).browserPluginElement.focus(); 109 privates(this).browserPluginElement.focus();
105 }.bind(this)); 110 }.bind(this));
106 this.element.addEventListener('blur', function(e) { 111 this.element.addEventListener('blur', function(e) {
107 // Blur the BrowserPlugin when the GuestViewContainer loses focus. 112 // Blur the BrowserPlugin when the GuestViewContainer loses focus.
108 privates(this).browserPluginElement.blur(); 113 privates(this).browserPluginElement.blur();
109 }.bind(this)); 114 }.bind(this));
110 }; 115 };
111 116
112 GuestViewContainer.prototype.attachWindow = function() { 117 GuestViewContainer.prototype.attachWindow = function() {
113 if (!this.internalInstanceId) { 118 if (!this.internalInstanceId) {
114 return true; 119 return true;
115 } 120 }
116 121
117 this.guest.attach(this.internalInstanceId, 122 this.guest.attach(this.internalInstanceId,
118 this.viewInstanceId, 123 this.viewInstanceId,
119 this.buildParams()); 124 this.buildParams());
120 return true; 125 return true;
121 }; 126 };
122 127
128 GuestViewContainer.prototype.onInternalInstanceID = function(
129 internalInstanceId) {
130 window.console.log('onInternalInstanceID: ' + internalInstanceId);
131 this.internalInstanceId = internalInstanceId;
132
133 // Track when the element resizes using the element resize callback.
134 GuestViewInternalNatives.RegisterElementResizeCallback(
135 this.internalInstanceId, this.onElementResize.bind(this));
136
137 window.console.log('this.guest.getId() = ' +
138 this.guest.getId());
139 if (!this.guest.getId()) {
140 return;
141 }
142 this.guest.attach(this.internalInstanceId,
143 this.viewInstanceId,
144 this.buildParams());
145 };
146
123 GuestViewContainer.prototype.handleBrowserPluginAttributeMutation = 147 GuestViewContainer.prototype.handleBrowserPluginAttributeMutation =
124 function(name, oldValue, newValue) { 148 function(name, oldValue, newValue) {
125 if (name == 'internalinstanceid' && !oldValue && !!newValue) { 149 if (name == 'internalinstanceid' && !oldValue && !!newValue) {
126 privates(this).browserPluginElement.removeAttribute('internalinstanceid'); 150 privates(this).browserPluginElement.removeAttribute('internalinstanceid');
127 this.internalInstanceId = parseInt(newValue); 151 this.onInternalInstanceID(parseInt(newValue));
128
129 // Track when the element resizes using the element resize callback.
130 GuestViewInternalNatives.RegisterElementResizeCallback(
131 this.internalInstanceId, this.onElementResize.bind(this));
132
133 if (!this.guest.getId()) {
134 return;
135 }
136 this.guest.attach(this.internalInstanceId,
137 this.viewInstanceId,
138 this.buildParams());
139 } 152 }
140 }; 153 };
141 154
142 GuestViewContainer.prototype.onElementResize = function(oldWidth, oldHeight, 155 GuestViewContainer.prototype.onElementResize = function(oldWidth, oldHeight,
143 newWidth, newHeight) { 156 newWidth, newHeight) {
144 // Dispatch the 'resize' event. 157 // Dispatch the 'resize' event.
145 var resizeEvent = new Event('resize', { bubbles: true }); 158 var resizeEvent = new Event('resize', { bubbles: true });
146 resizeEvent.oldWidth = oldWidth; 159 resizeEvent.oldWidth = oldWidth;
147 resizeEvent.oldHeight = oldHeight; 160 resizeEvent.oldHeight = oldHeight;
148 resizeEvent.newWidth = newWidth; 161 resizeEvent.newWidth = newWidth;
(...skipping 27 matching lines...) Expand all
176 } 189 }
177 190
178 // Implemented by the specific view type, if needed. 191 // Implemented by the specific view type, if needed.
179 GuestViewContainer.prototype.buildContainerParams = function() { return {}; }; 192 GuestViewContainer.prototype.buildContainerParams = function() { return {}; };
180 GuestViewContainer.prototype.onElementAttached = function() {}; 193 GuestViewContainer.prototype.onElementAttached = function() {};
181 GuestViewContainer.prototype.onElementDetached = function() {}; 194 GuestViewContainer.prototype.onElementDetached = function() {};
182 GuestViewContainer.prototype.setupAttributes = function() {}; 195 GuestViewContainer.prototype.setupAttributes = function() {};
183 196
184 // Registers the browser plugin <object> custom element. |viewType| is the 197 // Registers the browser plugin <object> custom element. |viewType| is the
185 // name of the specific guestview container (e.g. 'webview'). 198 // name of the specific guestview container (e.g. 'webview').
186 function registerBrowserPluginElement(viewType) { 199 function registerBrowserPluginElement(viewType) {
Fady Samuel 2015/05/26 16:42:15 Is this at all necessary in sitePerProcess?
lazyboy 2015/05/29 00:02:24 This function would register the custom element in
187 var proto = $Object.create(HTMLElement.prototype); 200 var isSitePerProcess = GuestViewInternalNatives.IsSitePerProcess();
201 var proto = $Object.create(isSitePerProcess ? HTMLIFrameElement.prototype
202 : HTMLElement.prototype);
203
204 window.console.log('isSitePerProcess: ' + isSitePerProcess);
188 205
189 proto.createdCallback = function() { 206 proto.createdCallback = function() {
190 this.setAttribute('type', 'application/browser-plugin'); 207 if (!isSitePerProcess) {
191 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId()); 208 this.setAttribute('type', 'application/browser-plugin');
209 this.setAttribute('id', 'browser-plugin-' + IdGenerator.GetNextId());
210 }
192 this.style.width = '100%'; 211 this.style.width = '100%';
193 this.style.height = '100%'; 212 this.style.height = '100%';
194 }; 213 };
195 214
196 proto.attachedCallback = function() { 215 proto.attachedCallback = function() {
197 // Load the plugin immediately. 216 // Load the plugin immediately.
198 var unused = this.nonExistentAttribute; 217 var unused = this.nonExistentAttribute;
199 }; 218 };
200 219
201 proto.attributeChangedCallback = function(name, oldValue, newValue) { 220 if (!isSitePerProcess) {
202 var internal = privates(this).internal; 221 proto.attributeChangedCallback = function(name, oldValue, newValue) {
203 if (!internal) { 222 var internal = privates(this).internal;
204 return; 223 if (!internal) {
205 } 224 return;
206 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue); 225 }
207 }; 226 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue);
227 };
228 }
208 229
230 var options = {prototype: proto};
231 options.extends = isSitePerProcess ? 'iframe' : 'object';
209 GuestViewContainer[viewType + 'BrowserPlugin'] = 232 GuestViewContainer[viewType + 'BrowserPlugin'] =
210 DocumentNatives.RegisterElement(viewType + 'browserplugin', 233 DocumentNatives.RegisterElement(viewType + 'browserplugin', options);
211 {extends: 'object', prototype: proto});
212 234
213 delete proto.createdCallback; 235 delete proto.createdCallback;
214 delete proto.attachedCallback; 236 delete proto.attachedCallback;
215 delete proto.detachedCallback; 237 delete proto.detachedCallback;
216 delete proto.attributeChangedCallback; 238 delete proto.attributeChangedCallback;
217 }; 239 };
218 240
219 // Registers the guestview container as a custom element. 241 // Registers the guestview container as a custom element.
220 // |guestViewContainerType| is the type of guestview container 242 // |guestViewContainerType| is the type of guestview container
221 // (e.g.WebViewImpl). 243 // (e.g.WebViewImpl).
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 // Delete the callbacks so developers cannot call them and produce unexpected 292 // Delete the callbacks so developers cannot call them and produce unexpected
271 // behavior. 293 // behavior.
272 delete proto.createdCallback; 294 delete proto.createdCallback;
273 delete proto.attachedCallback; 295 delete proto.attachedCallback;
274 delete proto.detachedCallback; 296 delete proto.detachedCallback;
275 delete proto.attributeChangedCallback; 297 delete proto.attributeChangedCallback;
276 } 298 }
277 299
278 // Exports. 300 // Exports.
279 exports.GuestViewContainer = GuestViewContainer; 301 exports.GuestViewContainer = GuestViewContainer;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698