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

Side by Side Diff: chrome/renderer/resources/extensions/extension_options.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 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 var DocumentNatives = requireNative('document_natives'); 5 var DocumentNatives = requireNative('document_natives');
6 var ExtensionOptionsEvents = 6 var ExtensionOptionsEvents =
7 require('extensionOptionsEvents').ExtensionOptionsEvents; 7 require('extensionOptionsEvents').ExtensionOptionsEvents;
8 var GuestViewInternal = 8 var GuestViewInternal =
9 require('binding').Binding.create('guestViewInternal').generate(); 9 require('binding').Binding.create('guestViewInternal').generate();
10 var IdGenerator = requireNative('id_generator'); 10 var IdGenerator = requireNative('id_generator');
11 var utils = require('utils'); 11 var utils = require('utils');
12 var guestViewInternalNatives = requireNative('guest_view_internal'); 12 var guestViewInternalNatives = requireNative('guest_view_internal');
13 13
14 // Mapping of the autosize attribute names to default values 14 // Mapping of the autosize attribute names to default values
15 var AUTO_SIZE_ATTRIBUTES = { 15 var AUTO_SIZE_ATTRIBUTES = {
16 'autosize': 'on', 16 'autosize': 'on',
17 'maxheight': window.innerHeight, 17 'maxheight': window.innerHeight,
18 'maxwidth': window.innerWidth, 18 'maxwidth': window.innerWidth,
19 'minheight': 32, 19 'minheight': 32,
20 'minwidth': 32 20 'minwidth': 32
21 }; 21 };
22 22
23 function ExtensionOptionsInternal(extensionoptionsNode) { 23 function ExtensionOptionsInternal(extensionoptionsNode) {
24 privates(extensionoptionsNode).internal = this; 24 privates(extensionoptionsNode).internal = this;
25 this.extensionoptionsNode = extensionoptionsNode; 25 this.extensionoptionsNode = extensionoptionsNode;
26 this.viewInstanceId = IdGenerator.GetNextId(); 26 this.viewInstanceId = IdGenerator.GetNextId();
27 this.guestInstanceId = 0;
28 this.elementAttached = false;
29 this.pendingGuestCreation = false;
27 30
28 this.autosizeDeferred = false; 31 this.autosizeDeferred = false;
29 32
30 // on* Event handlers. 33 // on* Event handlers.
31 this.eventHandlers = {}; 34 this.eventHandlers = {};
32 35
33 // setupEventProperty is normally called in extension_options_events.js to 36 // setupEventProperty is normally called in extension_options_events.js to
34 // register events, but the createfailed event is registered here because 37 // register events, but the createfailed event is registered here because
35 // the event is fired from here instead of through 38 // the event is fired from here instead of through
36 // extension_options_events.js. 39 // extension_options_events.js.
(...skipping 24 matching lines...) Expand all
61 'minwidth': parseInt(this.minwidth || 0) 64 'minwidth': parseInt(this.minwidth || 0)
62 }); 65 });
63 }; 66 };
64 67
65 ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() { 68 ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() {
66 var browserPluginNode = new ExtensionOptionsInternal.BrowserPlugin(); 69 var browserPluginNode = new ExtensionOptionsInternal.BrowserPlugin();
67 privates(browserPluginNode).internal = this; 70 privates(browserPluginNode).internal = this;
68 return browserPluginNode; 71 return browserPluginNode;
69 }; 72 };
70 73
71 ExtensionOptionsInternal.prototype.createGuest = function() { 74 ExtensionOptionsInternal.prototype.createGuestIfNecessary = function() {
75 if (!this.elementAttached || this.pendingGuestCreation) {
76 return;
77 }
78 if (this.guestInstanceId != 0) {
79 this.attachWindow();
80 return;
81 }
72 var params = { 82 var params = {
73 'extensionId': this.extensionId, 83 'extensionId': this.extensionId,
74 }; 84 };
75 GuestViewInternal.createGuest( 85 GuestViewInternal.createGuest(
76 'extensionoptions', 86 'extensionoptions',
77 params, 87 params,
78 function(guestInstanceId) { 88 function(guestInstanceId) {
89 this.pendingGuestCreation = false;
90 if (guestInstanceId && !this.elementAttached) {
91 GuestViewInternal.destroyGuest(guestInstanceId);
92 guestInstanceId = 0;
93 }
79 if (guestInstanceId == 0) { 94 if (guestInstanceId == 0) {
80 // Fire a createfailed event here rather than in ExtensionOptionsGuest 95 // Fire a createfailed event here rather than in ExtensionOptionsGuest
81 // because the guest will not be created, and cannot fire an event. 96 // because the guest will not be created, and cannot fire an event.
82 this.initCalled = false; 97 this.initCalled = false;
83 var createFailedEvent = new Event('createfailed', { bubbles: true }); 98 var createFailedEvent = new Event('createfailed', { bubbles: true });
84 this.dispatchEvent(createFailedEvent); 99 this.dispatchEvent(createFailedEvent);
85 } else { 100 } else {
86 this.guestInstanceId = guestInstanceId; 101 this.guestInstanceId = guestInstanceId;
87 this.attachWindow(); 102 this.attachWindow();
88 } 103 }
89 }.bind(this)); 104 }.bind(this)
105 );
106 this.pendingGuestCreation = true;
90 }; 107 };
91 108
92 ExtensionOptionsInternal.prototype.dispatchEvent = 109 ExtensionOptionsInternal.prototype.dispatchEvent =
93 function(extensionOptionsEvent) { 110 function(extensionOptionsEvent) {
94 return this.extensionoptionsNode.dispatchEvent(extensionOptionsEvent); 111 return this.extensionoptionsNode.dispatchEvent(extensionOptionsEvent);
95 }; 112 };
96 113
97 ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation = 114 ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation =
98 function(name, oldValue, newValue) { 115 function(name, oldValue, newValue) {
99 // We treat null attribute (attribute removed) and the empty string as 116 // We treat null attribute (attribute removed) and the empty string as
100 // one case. 117 // one case.
101 oldValue = oldValue || ''; 118 oldValue = oldValue || '';
102 newValue = newValue || ''; 119 newValue = newValue || '';
103 120
104 if (oldValue === newValue) 121 if (oldValue === newValue)
105 return; 122 return;
106 123
107 if (name == 'extension' && !oldValue && newValue) { 124 if (name == 'extension' && !oldValue && newValue) {
108 this.extensionId = newValue; 125 this.extensionId = newValue;
109 // If the browser plugin is not ready then don't create the guest until 126 // If the browser plugin is not ready then don't create the guest until
110 // it is ready (in handleBrowserPluginAttributeMutation). 127 // it is ready (in handleBrowserPluginAttributeMutation).
111 if (!this.internalInstanceId) 128 if (!this.internalInstanceId)
112 return; 129 return;
113 130
114 // If a guest view does not exist then create one. 131 // If a guest view does not exist then create one.
115 if (!this.guestInstanceId) { 132 if (!this.guestInstanceId) {
116 this.createGuest(); 133 this.createGuestIfNecessary();
117 return; 134 return;
118 } 135 }
119 // TODO(ericzeng): Implement navigation to another guest view if we want 136 // TODO(ericzeng): Implement navigation to another guest view if we want
120 // that functionality. 137 // that functionality.
121 } else if (AUTO_SIZE_ATTRIBUTES.hasOwnProperty(name) > -1) { 138 } else if (AUTO_SIZE_ATTRIBUTES.hasOwnProperty(name) > -1) {
122 this[name] = newValue; 139 this[name] = newValue;
123 this.resetSizeConstraintsIfInvalid(); 140 this.resetSizeConstraintsIfInvalid();
124 141
125 if (!this.guestInstanceId) 142 if (!this.guestInstanceId)
126 return; 143 return;
127 144
128 GuestViewInternal.setAutoSize(this.guestInstanceId, { 145 GuestViewInternal.setAutoSize(this.guestInstanceId, {
129 'enableAutoSize': this.extensionoptionsNode.hasAttribute('autosize'), 146 'enableAutoSize': this.extensionoptionsNode.hasAttribute('autosize'),
130 'min': { 147 'min': {
131 'width': parseInt(this.minwidth || 0), 148 'width': parseInt(this.minwidth || 0),
132 'height': parseInt(this.minheight || 0) 149 'height': parseInt(this.minheight || 0)
133 }, 150 },
134 'max': { 151 'max': {
135 'width': parseInt(this.maxwidth || 0), 152 'width': parseInt(this.maxwidth || 0),
136 'height': parseInt(this.maxheight || 0) 153 'height': parseInt(this.maxheight || 0)
137 } 154 }
138 }); 155 });
139 } 156 }
140 }; 157 };
141 158
142 ExtensionOptionsInternal.prototype.handleBrowserPluginAttributeMutation = 159 ExtensionOptionsInternal.prototype.handleBrowserPluginAttributeMutation =
143 function(name, oldValue, newValue) { 160 function(name, oldValue, newValue) {
144 if (name == 'internalinstanceid' && !oldValue && !!newValue) { 161 if (name == 'internalinstanceid' && !oldValue && !!newValue) {
162 this.elementAttached = true;
145 this.internalInstanceId = parseInt(newValue); 163 this.internalInstanceId = parseInt(newValue);
146 this.browserPluginNode.removeAttribute('internalinstanceid'); 164 this.browserPluginNode.removeAttribute('internalinstanceid');
147 if (this.extensionId) 165 if (this.extensionId)
148 this.createGuest(); 166 this.createGuestIfNecessary();
149 167
150 } 168 }
151 }; 169 };
152 170
153 ExtensionOptionsInternal.prototype.onSizeChanged = 171 ExtensionOptionsInternal.prototype.onSizeChanged =
154 function(newWidth, newHeight, oldWidth, oldHeight) { 172 function(newWidth, newHeight, oldWidth, oldHeight) {
155 if (this.autosizeDeferred) { 173 if (this.autosizeDeferred) {
156 this.deferredAutoSizeState = { 174 this.deferredAutoSizeState = {
157 newWidth: newWidth, 175 newWidth: newWidth,
158 newHeight: newHeight, 176 newHeight: newHeight,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 */ 304 */
287 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() { 305 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() {
288 if (this.autosizeDeferred) { 306 if (this.autosizeDeferred) {
289 this.resize(this.deferredAutoSizeState.newWidth, 307 this.resize(this.deferredAutoSizeState.newWidth,
290 this.deferredAutoSizeState.newHeight, 308 this.deferredAutoSizeState.newHeight,
291 this.deferredAutoSizeState.oldWidth, 309 this.deferredAutoSizeState.oldWidth,
292 this.deferredAutoSizeState.oldHeight); 310 this.deferredAutoSizeState.oldHeight);
293 } 311 }
294 }; 312 };
295 313
314 ExtensionOptionsInternal.prototype.reset = function() {
315 if (this.guestInstanceId) {
316 GuestViewInternal.destroyGuest(this.guestInstanceId);
317 this.guestInstanceId = undefined;
318 }
319 };
320
296 function registerBrowserPluginElement() { 321 function registerBrowserPluginElement() {
297 var proto = Object.create(HTMLObjectElement.prototype); 322 var proto = Object.create(HTMLObjectElement.prototype);
298 323
299 proto.createdCallback = function() { 324 proto.createdCallback = function() {
300 this.setAttribute('type', 'application/browser-plugin'); 325 this.setAttribute('type', 'application/browser-plugin');
301 this.style.width = '100%'; 326 this.style.width = '100%';
302 this.style.height = '100%'; 327 this.style.height = '100%';
303 }; 328 };
304 329
305 proto.attributeChangedCallback = function(name, oldValue, newValue) { 330 proto.attributeChangedCallback = function(name, oldValue, newValue) {
(...skipping 18 matching lines...) Expand all
324 delete proto.attributeChangedCallback; 349 delete proto.attributeChangedCallback;
325 } 350 }
326 351
327 function registerExtensionOptionsElement() { 352 function registerExtensionOptionsElement() {
328 var proto = Object.create(HTMLElement.prototype); 353 var proto = Object.create(HTMLElement.prototype);
329 354
330 proto.createdCallback = function() { 355 proto.createdCallback = function() {
331 new ExtensionOptionsInternal(this); 356 new ExtensionOptionsInternal(this);
332 }; 357 };
333 358
359 proto.detachedCallback = function() {
360 var internal = privates(this).internal;
361 if (!internal) {
362 return;
363 }
364 internal.elementAttached = false;
365 internal.reset();
366 };
367
334 proto.attributeChangedCallback = function(name, oldValue, newValue) { 368 proto.attributeChangedCallback = function(name, oldValue, newValue) {
335 var internal = privates(this).internal; 369 var internal = privates(this).internal;
336 if (!internal) 370 if (!internal) {
337 return; 371 return;
372 }
338 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); 373 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue);
339 }; 374 };
340 375
341 var methods = [ 376 var methods = [
342 'setDeferAutoSize', 377 'setDeferAutoSize',
343 'resumeDeferredAutoSize' 378 'resumeDeferredAutoSize'
344 ]; 379 ];
345 380
346 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*. 381 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*.
347 for (var i = 0; methods[i]; ++i) { 382 for (var i = 0; methods[i]; ++i) {
(...skipping 19 matching lines...) Expand all
367 402
368 var useCapture = true; 403 var useCapture = true;
369 window.addEventListener('readystatechange', function listener(event) { 404 window.addEventListener('readystatechange', function listener(event) {
370 if (document.readyState == 'loading') 405 if (document.readyState == 'loading')
371 return; 406 return;
372 407
373 registerBrowserPluginElement(); 408 registerBrowserPluginElement();
374 registerExtensionOptionsElement(); 409 registerExtensionOptionsElement();
375 window.removeEventListener(event.type, listener, useCapture); 410 window.removeEventListener(event.type, listener, useCapture);
376 }, useCapture); 411 }, useCapture);
OLDNEW
« no previous file with comments | « chrome/renderer/resources/extensions/app_view.js ('k') | chrome/test/data/extensions/platform_apps/app_view/shim/main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698