| 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'); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 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 Loading... |
| 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 Loading... |
| 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); |
| OLD | NEW |