OLD | NEW |
---|---|
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 Loading... | |
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.guestInstanceId != 0) { | |
76 this.attachWindow(); | |
77 return; | |
78 } | |
79 if (!this.elementAttached || this.pendingGuestCreation) { | |
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; |
(...skipping 11 matching lines...) Expand all Loading... | |
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) { |
145 this.internalInstanceId = parseInt(newValue); | 162 this.internalInstanceId = parseInt(newValue); |
146 this.browserPluginNode.removeAttribute('internalinstanceid'); | 163 this.browserPluginNode.removeAttribute('internalinstanceid'); |
147 if (this.extensionId) | 164 if (this.extensionId) |
148 this.createGuest(); | 165 this.createGuestIfNecessary(); |
149 | 166 |
150 } | 167 } |
151 }; | 168 }; |
152 | 169 |
153 ExtensionOptionsInternal.prototype.onSizeChanged = | 170 ExtensionOptionsInternal.prototype.onSizeChanged = |
154 function(newWidth, newHeight, oldWidth, oldHeight) { | 171 function(newWidth, newHeight, oldWidth, oldHeight) { |
155 if (this.autosizeDeferred) { | 172 if (this.autosizeDeferred) { |
156 this.deferredAutoSizeState = { | 173 this.deferredAutoSizeState = { |
157 newWidth: newWidth, | 174 newWidth: newWidth, |
158 newHeight: newHeight, | 175 newHeight: newHeight, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 */ | 303 */ |
287 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() { | 304 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() { |
288 if (this.autosizeDeferred) { | 305 if (this.autosizeDeferred) { |
289 this.resize(this.deferredAutoSizeState.newWidth, | 306 this.resize(this.deferredAutoSizeState.newWidth, |
290 this.deferredAutoSizeState.newHeight, | 307 this.deferredAutoSizeState.newHeight, |
291 this.deferredAutoSizeState.oldWidth, | 308 this.deferredAutoSizeState.oldWidth, |
292 this.deferredAutoSizeState.oldHeight); | 309 this.deferredAutoSizeState.oldHeight); |
293 } | 310 } |
294 }; | 311 }; |
295 | 312 |
313 ExtensionOptionsInternal.prototype.reset = function() { | |
314 if (this.guestInstanceId) { | |
315 GuestViewInternal.destroyGuest(this.guestInstanceId); | |
316 this.guestInstanceId = undefined; | |
317 } | |
318 }; | |
319 | |
296 function registerBrowserPluginElement() { | 320 function registerBrowserPluginElement() { |
297 var proto = Object.create(HTMLObjectElement.prototype); | 321 var proto = Object.create(HTMLObjectElement.prototype); |
298 | 322 |
299 proto.createdCallback = function() { | 323 proto.createdCallback = function() { |
300 this.setAttribute('type', 'application/browser-plugin'); | 324 this.setAttribute('type', 'application/browser-plugin'); |
301 this.style.width = '100%'; | 325 this.style.width = '100%'; |
302 this.style.height = '100%'; | 326 this.style.height = '100%'; |
303 }; | 327 }; |
304 | 328 |
305 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 329 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
(...skipping 18 matching lines...) Expand all Loading... | |
324 delete proto.attributeChangedCallback; | 348 delete proto.attributeChangedCallback; |
325 } | 349 } |
326 | 350 |
327 function registerExtensionOptionsElement() { | 351 function registerExtensionOptionsElement() { |
328 var proto = Object.create(HTMLElement.prototype); | 352 var proto = Object.create(HTMLElement.prototype); |
329 | 353 |
330 proto.createdCallback = function() { | 354 proto.createdCallback = function() { |
331 new ExtensionOptionsInternal(this); | 355 new ExtensionOptionsInternal(this); |
332 }; | 356 }; |
333 | 357 |
358 proto.attachedCallback = function() { | |
359 var internal = privates(this).internal; | |
360 if (!internal) { | |
361 return; | |
362 } | |
363 internal.elementAttached = true; | |
364 }; | |
365 | |
366 proto.detachedCallback = function() { | |
367 var internal = privates(this).internal; | |
368 if (!internal) { | |
369 return; | |
370 } | |
371 intenral.elementAttached = false; | |
lfg
2014/09/30 23:29:42
typo.
Fady Samuel
2014/10/01 15:40:16
Done.
| |
372 internal.reset(); | |
373 }; | |
374 | |
334 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 375 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
335 var internal = privates(this).internal; | 376 var internal = privates(this).internal; |
336 if (!internal) | 377 if (!internal) { |
337 return; | 378 return; |
379 } | |
338 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); | 380 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); |
339 }; | 381 }; |
340 | 382 |
341 var methods = [ | 383 var methods = [ |
342 'setDeferAutoSize', | 384 'setDeferAutoSize', |
343 'resumeDeferredAutoSize' | 385 'resumeDeferredAutoSize' |
344 ]; | 386 ]; |
345 | 387 |
346 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*. | 388 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*. |
347 for (var i = 0; methods[i]; ++i) { | 389 for (var i = 0; methods[i]; ++i) { |
(...skipping 19 matching lines...) Expand all Loading... | |
367 | 409 |
368 var useCapture = true; | 410 var useCapture = true; |
369 window.addEventListener('readystatechange', function listener(event) { | 411 window.addEventListener('readystatechange', function listener(event) { |
370 if (document.readyState == 'loading') | 412 if (document.readyState == 'loading') |
371 return; | 413 return; |
372 | 414 |
373 registerBrowserPluginElement(); | 415 registerBrowserPluginElement(); |
374 registerExtensionOptionsElement(); | 416 registerExtensionOptionsElement(); |
375 window.removeEventListener(event.type, listener, useCapture); | 417 window.removeEventListener(event.type, listener, useCapture); |
376 }, useCapture); | 418 }, useCapture); |
OLD | NEW |