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

Side by Side Diff: chrome/renderer/resources/extensions/extension_options.js

Issue 457653003: Implement <extensionoptions> deferred attach logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove old tests Created 6 years, 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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');
(...skipping 17 matching lines...) Expand all
28 this.autosizeDeferred = false; 28 this.autosizeDeferred = false;
29 29
30 // on* Event handlers. 30 // on* Event handlers.
31 this.eventHandlers = {}; 31 this.eventHandlers = {};
32 32
33 // setupEventProperty is normally called in extension_options_events.js to 33 // setupEventProperty is normally called in extension_options_events.js to
34 // register events, but the createfailed event is registered here because 34 // register events, but the createfailed event is registered here because
35 // the event is fired from here instead of through 35 // the event is fired from here instead of through
36 // extension_options_events.js. 36 // extension_options_events.js.
37 this.setupEventProperty('createfailed'); 37 this.setupEventProperty('createfailed');
38
39 new ExtensionOptionsEvents(this, this.viewInstanceId); 38 new ExtensionOptionsEvents(this, this.viewInstanceId);
40 39
41 this.setupNodeProperties(); 40 this.setupNodeProperties();
42 41
43 if (this.parseExtensionAttribute()) 42 this.parseExtensionAttribute();
44 this.init(); 43
44 // Once the browser plugin has been created, the guest view will be created
45 // and attached. See handleBrowserPluginAttributeMutation().
46 this.browserPluginNode = this.createBrowserPluginNode();
47 var shadowRoot = this.extensionoptionsNode.createShadowRoot();
48 shadowRoot.appendChild(this.browserPluginNode);
45 }; 49 };
46 50
47 ExtensionOptionsInternal.prototype.attachWindow = function(guestInstanceId) { 51 ExtensionOptionsInternal.prototype.attachWindow = function() {
48 this.guestInstanceId = guestInstanceId;
49 var params = {
50 'autosize': this.autosize,
51 'instanceId': this.viewInstanceId,
52 'maxheight': parseInt(this.maxheight || 0),
53 'maxwidth': parseInt(this.maxwidth || 0),
54 'minheight': parseInt(this.minheight || 0),
55 'minwidth': parseInt(this.minwidth || 0)
56 };
57 return guestViewInternalNatives.AttachGuest( 52 return guestViewInternalNatives.AttachGuest(
58 parseInt(this.browserPluginNode.getAttribute('internalinstanceid')), 53 this.internalInstanceId,
59 guestInstanceId, 54 this.guestInstanceId,
60 params); 55 {
56 'autosize': this.autosize,
57 'instanceId': this.viewInstanceId,
58 'maxheight': parseInt(this.maxheight || 0),
59 'maxwidth': parseInt(this.maxwidth || 0),
60 'minheight': parseInt(this.minheight || 0),
61 'minwidth': parseInt(this.minwidth || 0)
62 });
61 }; 63 };
62 64
63 ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() { 65 ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() {
64 var browserPluginNode = new ExtensionOptionsInternal.BrowserPlugin(); 66 var browserPluginNode = new ExtensionOptionsInternal.BrowserPlugin();
65 privates(browserPluginNode).internal = this; 67 privates(browserPluginNode).internal = this;
66 return browserPluginNode; 68 return browserPluginNode;
67 }; 69 };
68 70
69 ExtensionOptionsInternal.prototype.createGuest = function() { 71 ExtensionOptionsInternal.prototype.createGuest = function() {
70 var params = { 72 var params = {
71 'extensionId': this.extensionId, 73 'extensionId': this.extensionId,
72 }; 74 };
73 GuestViewInternal.createGuest( 75 GuestViewInternal.createGuest(
74 'extensionoptions', 76 'extensionoptions',
75 params, 77 params,
76 function(guestInstanceId) { 78 function(guestInstanceId) {
77 if (guestInstanceId == 0) { 79 if (guestInstanceId == 0) {
78 // Fire a createfailed event here rather than in ExtensionOptionsGuest 80 // Fire a createfailed event here rather than in ExtensionOptionsGuest
79 // because the guest will not be created, and cannot fire an event. 81 // because the guest will not be created, and cannot fire an event.
80 this.initCalled = false; 82 this.initCalled = false;
81 var createFailedEvent = new Event('createfailed', { bubbles: true }); 83 var createFailedEvent = new Event('createfailed', { bubbles: true });
82 this.dispatchEvent(createFailedEvent); 84 this.dispatchEvent(createFailedEvent);
83 } else { 85 } else {
84 this.attachWindow(guestInstanceId); 86 this.guestInstanceId = guestInstanceId;
87 this.attachWindow();
85 } 88 }
86 }.bind(this)); 89 }.bind(this));
87 }; 90 };
88 91
89 ExtensionOptionsInternal.prototype.dispatchEvent = 92 ExtensionOptionsInternal.prototype.dispatchEvent =
90 function(extensionOptionsEvent) { 93 function(extensionOptionsEvent) {
91 return this.extensionoptionsNode.dispatchEvent(extensionOptionsEvent); 94 return this.extensionoptionsNode.dispatchEvent(extensionOptionsEvent);
92 }; 95 };
93 96
94 ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation = 97 ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation =
95 function(name, oldValue, newValue) { 98 function(name, oldValue, newValue) {
96 // We treat null attribute (attribute removed) and the empty string as 99 // We treat null attribute (attribute removed) and the empty string as
97 // one case. 100 // one case.
98 oldValue = oldValue || ''; 101 oldValue = oldValue || '';
99 newValue = newValue || ''; 102 newValue = newValue || '';
100 103
101 if (oldValue === newValue) 104 if (oldValue === newValue)
102 return; 105 return;
103 106
104 if (name == 'extension') { 107 if (name == 'extension' && !oldValue && newValue) {
105 this.extensionId = newValue; 108 this.extensionId = newValue;
106 // Create new guest view if one hasn't been created for this element. 109 // If the browser plugin is not ready then don't create the guest until
107 if (!this.guestInstanceId && this.parseExtensionAttribute()) 110 // it is ready (in handleBrowserPluginAttributeMutation).
108 this.init(); 111 if (!this.internalInstanceId)
112 return;
113
114 // If a guest view does not exist then create one.
115 if (!this.guestInstanceId) {
116 this.createGuest();
117 return;
118 }
109 // TODO(ericzeng): Implement navigation to another guest view if we want 119 // TODO(ericzeng): Implement navigation to another guest view if we want
110 // that functionality. 120 // that functionality.
111 } else if (AUTO_SIZE_ATTRIBUTES.hasOwnProperty(name) > -1) { 121 } else if (AUTO_SIZE_ATTRIBUTES.hasOwnProperty(name) > -1) {
112 this[name] = newValue; 122 this[name] = newValue;
113 this.resetSizeConstraintsIfInvalid(); 123 this.resetSizeConstraintsIfInvalid();
114 124
115 if (!this.guestInstanceId) 125 if (!this.guestInstanceId)
116 return; 126 return;
117 127
118 GuestViewInternal.setAutoSize(this.guestInstanceId, { 128 GuestViewInternal.setAutoSize(this.guestInstanceId, {
119 'enableAutoSize': this.extensionoptionsNode.hasAttribute('autosize'), 129 'enableAutoSize': this.extensionoptionsNode.hasAttribute('autosize'),
120 'min': { 130 'min': {
121 'width': parseInt(this.minwidth || 0), 131 'width': parseInt(this.minwidth || 0),
122 'height': parseInt(this.minheight || 0) 132 'height': parseInt(this.minheight || 0)
123 }, 133 },
124 'max': { 134 'max': {
125 'width': parseInt(this.maxwidth || 0), 135 'width': parseInt(this.maxwidth || 0),
126 'height': parseInt(this.maxheight || 0) 136 'height': parseInt(this.maxheight || 0)
127 } 137 }
128 }); 138 });
129 } 139 }
130 }; 140 };
131 141
132 ExtensionOptionsInternal.prototype.init = function() { 142 ExtensionOptionsInternal.prototype.handleBrowserPluginAttributeMutation =
133 if (this.initCalled) 143 function(name, oldValue, newValue) {
134 return; 144 if (name == 'internalinstanceid' && !oldValue && !!newValue) {
145 this.internalInstanceId = parseInt(newValue);
146 this.browserPluginNode.removeAttribute('internalinstanceid');
147 if (this.extensionId)
148 this.createGuest();
135 149
136 this.initCalled = true; 150 }
137 this.browserPluginNode = this.createBrowserPluginNode();
138 var shadowRoot = this.extensionoptionsNode.createShadowRoot();
139 shadowRoot.appendChild(this.browserPluginNode);
140 this.createGuest();
141 }; 151 };
142 152
143 ExtensionOptionsInternal.prototype.onSizeChanged = 153 ExtensionOptionsInternal.prototype.onSizeChanged =
144 function(newWidth, newHeight, oldWidth, oldHeight) { 154 function(newWidth, newHeight, oldWidth, oldHeight) {
145 if (this.autosizeDeferred) { 155 if (this.autosizeDeferred) {
146 this.deferredAutoSizeState = { 156 this.deferredAutoSizeState = {
147 newWidth: newWidth, 157 newWidth: newWidth,
148 newHeight: newHeight, 158 newHeight: newHeight,
149 oldWidth: oldWidth, 159 oldWidth: oldWidth,
150 oldHeight: oldHeight 160 oldHeight: oldHeight
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 295
286 function registerBrowserPluginElement() { 296 function registerBrowserPluginElement() {
287 var proto = Object.create(HTMLObjectElement.prototype); 297 var proto = Object.create(HTMLObjectElement.prototype);
288 298
289 proto.createdCallback = function() { 299 proto.createdCallback = function() {
290 this.setAttribute('type', 'application/browser-plugin'); 300 this.setAttribute('type', 'application/browser-plugin');
291 this.style.width = '100%'; 301 this.style.width = '100%';
292 this.style.height = '100%'; 302 this.style.height = '100%';
293 }; 303 };
294 304
305 proto.attributeChangedCallback = function(name, oldValue, newValue) {
306 var internal = privates(this).internal;
307 if (!internal) {
308 return;
309 }
310 internal.handleBrowserPluginAttributeMutation(name, oldValue, newValue);
311 };
312
295 proto.attachedCallback = function() { 313 proto.attachedCallback = function() {
296 // Load the plugin immediately. 314 // Load the plugin immediately.
297 var unused = this.nonExistentAttribute; 315 var unused = this.nonExistentAttribute;
298 }; 316 };
299 317
300 ExtensionOptionsInternal.BrowserPlugin = 318 ExtensionOptionsInternal.BrowserPlugin =
301 DocumentNatives.RegisterElement('extensionoptionsplugin', 319 DocumentNatives.RegisterElement('extensionoptionsplugin',
302 {extends: 'object', prototype: proto}); 320 {extends: 'object', prototype: proto});
303 delete proto.createdCallback; 321 delete proto.createdCallback;
304 delete proto.attachedCallback; 322 delete proto.attachedCallback;
305 delete proto.detachedCallback; 323 delete proto.detachedCallback;
306 delete proto.attributeChangedCallback; 324 delete proto.attributeChangedCallback;
307 } 325 }
308 326
309 function registerExtensionOptionsElement() { 327 function registerExtensionOptionsElement() {
310 var proto = Object.create(HTMLElement.prototype); 328 var proto = Object.create(HTMLElement.prototype);
311 329
312 proto.createdCallback = function() { 330 proto.createdCallback = function() {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 367
350 var useCapture = true; 368 var useCapture = true;
351 window.addEventListener('readystatechange', function listener(event) { 369 window.addEventListener('readystatechange', function listener(event) {
352 if (document.readyState == 'loading') 370 if (document.readyState == 'loading')
353 return; 371 return;
354 372
355 registerBrowserPluginElement(); 373 registerBrowserPluginElement();
356 registerExtensionOptionsElement(); 374 registerExtensionOptionsElement();
357 window.removeEventListener(event.type, listener, useCapture); 375 window.removeEventListener(event.type, listener, useCapture);
358 }, useCapture); 376 }, useCapture);
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698