Chromium Code Reviews| 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 | 11 |
| 12 var EXTENSION_OPTIONS_ATTRIBUTE_MAXHEIGHT = 'maxheight'; | |
|
not at google - send to devlin
2014/07/30 17:44:57
just inline each of these?
| |
| 13 var EXTENSION_OPTIONS_ATTRIBUTE_MAXWIDTH = 'maxwidth'; | |
| 14 var EXTENSION_OPTIONS_ATTRIBUTE_MINHEIGHT = 'minheight'; | |
| 15 var EXTENSION_OPTIONS_ATTRIBUTE_MINWIDTH = 'minwidth'; | |
| 16 | |
| 17 var EXTENSION_OPTIONS_ATTRIBUTES = [ | |
| 18 EXTENSION_OPTIONS_ATTRIBUTE_MAXHEIGHT, | |
|
not at google - send to devlin
2014/07/30 17:44:57
can this be a map of name --> default value (poten
ericzeng
2014/07/30 23:29:26
Done.
| |
| 19 EXTENSION_OPTIONS_ATTRIBUTE_MAXWIDTH, | |
| 20 EXTENSION_OPTIONS_ATTRIBUTE_MINHEIGHT, | |
| 21 EXTENSION_OPTIONS_ATTRIBUTE_MINWIDTH | |
| 22 ]; | |
| 23 | |
| 12 function ExtensionOptionsInternal(extensionoptionsNode) { | 24 function ExtensionOptionsInternal(extensionoptionsNode) { |
| 13 privates(extensionoptionsNode).internal = this; | 25 privates(extensionoptionsNode).internal = this; |
| 14 this.extensionoptionsNode = extensionoptionsNode; | 26 this.extensionoptionsNode = extensionoptionsNode; |
| 15 this.viewInstanceId = IdGenerator.GetNextId(); | 27 this.viewInstanceId = IdGenerator.GetNextId(); |
| 16 | 28 |
| 17 // on* Event handlers. | 29 // on* Event handlers. |
| 18 this.eventHandlers = {}; | 30 this.eventHandlers = {}; |
| 19 new ExtensionOptionsEvents(this, this.viewInstanceId); | 31 new ExtensionOptionsEvents(this, this.viewInstanceId); |
| 20 | 32 |
| 21 this.setupNodeProperties(); | 33 this.setupNodeProperties(); |
| 22 | 34 |
| 23 if (this.parseExtensionAttribute()) | 35 if (this.parseExtensionAttribute()) |
| 24 this.init(); | 36 this.init(); |
| 25 }; | 37 }; |
| 26 | 38 |
| 27 ExtensionOptionsInternal.prototype.attachWindow = function(instanceId) { | 39 ExtensionOptionsInternal.prototype.attachWindow = function(instanceId) { |
| 28 this.instanceId = instanceId; | 40 this.instanceId = instanceId; |
| 29 var params = { | 41 var params = { |
| 30 'instanceId': this.viewInstanceId, | 42 'instanceId': this.viewInstanceId, |
| 31 } | 43 } |
| 32 return this.browserPluginNode['-internal-attach'](instanceId, params); | 44 return this.browserPluginNode['-internal-attach'](instanceId, params); |
| 33 }; | 45 }; |
| 34 | 46 |
| 35 ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() { | 47 ExtensionOptionsInternal.prototype.createBrowserPluginNode = function() { |
| 36 var browserPluginNode = new ExtensionOptionsInternal.BrowserPlugin(); | 48 var browserPluginNode = new ExtensionOptionsInternal.BrowserPlugin(); |
| 49 browserPluginNode.setAttribute('autosize', 'on'); | |
| 50 browserPluginNode.setAttribute('minwidth', 80); | |
| 51 browserPluginNode.setAttribute('minheight', 30); | |
| 37 privates(browserPluginNode).internal = this; | 52 privates(browserPluginNode).internal = this; |
| 53 | |
| 54 $Array.forEach(EXTENSION_OPTIONS_ATTRIBUTES, function(attributeName) { | |
| 55 // Only copy attributes that have been assigned values, rather than copying | |
| 56 // a series of undefined attributes to BrowserPlugin. | |
| 57 if (this.extensionoptionsNode.hasAttribute(attributeName)) { | |
| 58 browserPluginNode.setAttribute( | |
| 59 attributeName, this.extensionoptionsNode.getAttribute(attributeName)); | |
|
not at google - send to devlin
2014/07/30 17:44:57
indentation += 2
ericzeng
2014/07/30 23:29:26
Done.
| |
| 60 } | |
| 61 }, this); | |
| 62 | |
| 38 return browserPluginNode; | 63 return browserPluginNode; |
| 39 }; | 64 }; |
| 40 | 65 |
| 41 ExtensionOptionsInternal.prototype.createGuest = function() { | 66 ExtensionOptionsInternal.prototype.createGuest = function() { |
| 42 var params = { | 67 var params = { |
| 43 'extensionId': this.extensionId, | 68 'extensionId': this.extensionId, |
| 44 }; | 69 }; |
| 45 var self = this; | 70 var self = this; |
| 46 GuestViewInternal.createGuest( | 71 GuestViewInternal.createGuest( |
| 47 'extensionoptions', | 72 'extensionoptions', |
| 48 params, | 73 params, |
| 49 function(instanceId) { | 74 function(instanceId) { |
| 50 if (instanceId == 0) { | 75 if (instanceId == 0) { |
| 51 self.initCalled = false; | 76 self.initCalled = false; |
| 52 } else { | 77 } else { |
| 53 self.attachWindow(instanceId); | 78 self.attachWindow(instanceId); |
| 54 } | 79 } |
| 55 }); | 80 }); |
| 56 }; | 81 }; |
| 57 | 82 |
| 58 ExtensionOptionsInternal.prototype.dispatchEvent = | 83 ExtensionOptionsInternal.prototype.dispatchEvent = |
| 59 function(extensionOptionsEvent) { | 84 function(extensionOptionsEvent) { |
| 60 return this.extensionoptionsNode.dispatchEvent(extensionOptionsEvent); | 85 return this.extensionoptionsNode.dispatchEvent(extensionOptionsEvent); |
| 61 }; | 86 }; |
| 62 | 87 |
| 63 ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation = | 88 ExtensionOptionsInternal.prototype.handleExtensionOptionsAttributeMutation = |
| 64 function(name, oldValue, newValue) { | 89 function(name, oldValue, newValue) { |
| 65 if (name != 'extension') | |
| 66 return; | |
| 67 // We treat null attribute (attribute removed) and the empty string as | 90 // We treat null attribute (attribute removed) and the empty string as |
| 68 // one case. | 91 // one case. |
| 69 oldValue = oldValue || ''; | 92 oldValue = oldValue || ''; |
| 70 newValue = newValue || ''; | 93 newValue = newValue || ''; |
| 71 | 94 |
| 72 if (oldValue === newValue) | 95 if (oldValue === newValue) |
| 73 return; | 96 return; |
| 74 this.extensionId = newValue; | |
| 75 | 97 |
| 76 // Create new guest view if one hasn't been created for this element. | 98 if (name == 'extension') { |
| 77 if (!this.instanceId && this.parseExtensionAttribute()) | 99 this.extensionId = newValue; |
| 78 this.init(); | 100 // Create new guest view if one hasn't been created for this element. |
| 79 // TODO(ericzeng): Implement navigation to another guest view if we want | 101 if (!this.instanceId && this.parseExtensionAttribute()) |
| 80 // that functionality. | 102 this.init(); |
| 103 // TODO(ericzeng): Implement navigation to another guest view if we want | |
| 104 // that functionality. | |
| 105 return; | |
| 106 } | |
| 107 | |
| 108 if (this.browserPluginNode.hasOwnProperty(name)) { | |
| 109 this.browserPluginNode[name] = newValue; | |
| 110 } else { | |
| 111 this.browserPluginNode.setAttribute(name, newValue); | |
| 112 } | |
| 81 }; | 113 }; |
| 82 | 114 |
| 83 ExtensionOptionsInternal.prototype.init = function() { | 115 ExtensionOptionsInternal.prototype.init = function() { |
| 84 if (this.initCalled) | 116 if (this.initCalled) |
| 85 return; | 117 return; |
| 86 | 118 |
| 87 this.initCalled = true; | 119 this.initCalled = true; |
| 88 this.browserPluginNode = this.createBrowserPluginNode(); | 120 this.browserPluginNode = this.createBrowserPluginNode(); |
| 89 var shadowRoot = this.extensionoptionsNode.createShadowRoot(); | 121 var shadowRoot = this.extensionoptionsNode.createShadowRoot(); |
| 90 shadowRoot.appendChild(this.browserPluginNode); | 122 shadowRoot.appendChild(this.browserPluginNode); |
| 91 this.createGuest(); | 123 this.createGuest(); |
| 92 }; | 124 }; |
| 93 | 125 |
| 126 ExtensionOptionsInternal.prototype.onSizeChanged = function(width, height) { | |
| 127 this.browserPluginNode.style.width = width + 'px'; | |
| 128 this.browserPluginNode.style.height = height + 'px'; | |
| 129 }; | |
| 130 | |
| 94 ExtensionOptionsInternal.prototype.parseExtensionAttribute = function() { | 131 ExtensionOptionsInternal.prototype.parseExtensionAttribute = function() { |
| 95 if (this.extensionoptionsNode.hasAttribute('extension')) { | 132 if (this.extensionoptionsNode.hasAttribute('extension')) { |
| 96 var extensionId = this.extensionoptionsNode.getAttribute('extension'); | 133 var extensionId = this.extensionoptionsNode.getAttribute('extension'); |
| 97 // Only allow extensions to embed their own options page (if it has one). | 134 // Only allow extensions to embed their own options page (if it has one). |
| 98 if (chrome.runtime.id == extensionId && | 135 if (chrome.runtime.id == extensionId && |
| 99 chrome.runtime.getManifest().hasOwnProperty('options_page')) { | 136 chrome.runtime.getManifest().hasOwnProperty('options_page')) { |
| 100 this.extensionId = extensionId; | 137 this.extensionId = extensionId; |
| 101 return true; | 138 return true; |
| 102 } | 139 } |
| 103 } | 140 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 120 eventName, self.eventHandlers[propertyName]); | 157 eventName, self.eventHandlers[propertyName]); |
| 121 self.eventHandlers[propertyName] = value; | 158 self.eventHandlers[propertyName] = value; |
| 122 if (value) | 159 if (value) |
| 123 extensionoptionsNode.addEventListener(eventName, value); | 160 extensionoptionsNode.addEventListener(eventName, value); |
| 124 }, | 161 }, |
| 125 enumerable: true | 162 enumerable: true |
| 126 }); | 163 }); |
| 127 }; | 164 }; |
| 128 | 165 |
| 129 ExtensionOptionsInternal.prototype.setupNodeProperties = function() { | 166 ExtensionOptionsInternal.prototype.setupNodeProperties = function() { |
| 167 $Array.forEach(EXTENSION_OPTIONS_ATTRIBUTES, function(attributeName) { | |
| 168 Object.defineProperty(this.extensionoptionsNode, attributeName, { | |
| 169 get: function() { | |
| 170 if (this.browserPluginNode.hasOwnProperty(attributeName)) { | |
| 171 return this.browserPluginNode[attributeName]; | |
| 172 } else { | |
|
not at google - send to devlin
2014/07/30 17:44:57
no else after return.
ericzeng
2014/07/30 23:29:26
Done.
| |
| 173 return this.browserPluginNode.getAttribute(attributeName); | |
| 174 } | |
| 175 }, | |
| 176 set: function(value) { | |
| 177 if (this.browserPluginNode.hasOwnProperty(attributeName)) { | |
| 178 // Give the BrowserPlugin first stab at the attribute so that it can | |
| 179 // throw an exception if there is a problem. This attribute will then | |
| 180 // be propagated back to the <extensionoptions>. | |
| 181 this.browserPluginNode[attributeName] = value; | |
| 182 } else { | |
| 183 this.browserPluginNode.setAttribute(attributeName, value); | |
| 184 } | |
| 185 }, | |
| 186 enumerable: true | |
| 187 }); | |
| 188 }, this); | |
| 189 | |
| 130 var self = this; | 190 var self = this; |
| 131 this.extensionId = this.extensionoptionsNode.getAttribute('extension'); | |
| 132 Object.defineProperty(this.extensionoptionsNode, 'extension', { | 191 Object.defineProperty(this.extensionoptionsNode, 'extension', { |
| 133 get: function() { | 192 get: function() { |
| 134 return self.extensionId; | 193 return self.extensionId; |
| 135 }, | 194 }, |
| 136 set: function(value) { | 195 set: function(value) { |
| 137 self.extensionoptionsNode.setAttribute('extension', value); | 196 self.extensionoptionsNode.setAttribute('extension', value); |
|
not at google - send to devlin
2014/07/30 17:44:57
why this second case? seems like if 'extension' we
ericzeng
2014/07/30 23:29:26
If an attribute is in EXTENSION_OPTIONS_ATTRIBUTES
| |
| 138 }, | 197 }, |
| 139 enumerable: true | 198 enumerable: true |
| 140 }); | 199 }); |
| 141 }; | 200 }; |
| 142 | 201 |
| 143 function registerBrowserPluginElement() { | 202 function registerBrowserPluginElement() { |
| 144 var proto = Object.create(HTMLObjectElement.prototype); | 203 var proto = Object.create(HTMLObjectElement.prototype); |
| 145 | 204 |
| 146 proto.createdCallback = function() { | 205 proto.createdCallback = function() { |
| 147 this.setAttribute('type', 'application/browser-plugin'); | 206 this.setAttribute('type', 'application/browser-plugin'); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 | 249 |
| 191 var useCapture = true; | 250 var useCapture = true; |
| 192 window.addEventListener('readystatechange', function listener(event) { | 251 window.addEventListener('readystatechange', function listener(event) { |
| 193 if (document.readyState == 'loading') | 252 if (document.readyState == 'loading') |
| 194 return; | 253 return; |
| 195 | 254 |
| 196 registerBrowserPluginElement(); | 255 registerBrowserPluginElement(); |
| 197 registerExtensionOptionsElement(); | 256 registerExtensionOptionsElement(); |
| 198 window.removeEventListener(event.type, listener, useCapture); | 257 window.removeEventListener(event.type, listener, useCapture); |
| 199 }, useCapture); | 258 }, useCapture); |
| OLD | NEW |