| 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 | 12 |
| 13 // Mapping of the autosize attribute names to default values | 13 // Mapping of the autosize attribute names to default values |
| 14 var AUTO_SIZE_ATTRIBUTES = { | 14 var AUTO_SIZE_ATTRIBUTES = { |
| 15 'autosize': 'on', | 15 'autosize': 'on', |
| 16 'maxheight': window.innerHeight, | 16 'maxheight': window.innerHeight, |
| 17 'maxwidth': window.innerWidth, | 17 'maxwidth': window.innerWidth, |
| 18 'minheight': 32, | 18 'minheight': 32, |
| 19 'minwidth': 32 | 19 'minwidth': 32 |
| 20 }; | 20 }; |
| 21 | 21 |
| 22 function ExtensionOptionsInternal(extensionoptionsNode) { | 22 function ExtensionOptionsInternal(extensionoptionsNode) { |
| 23 privates(extensionoptionsNode).internal = this; | 23 privates(extensionoptionsNode).internal = this; |
| 24 this.extensionoptionsNode = extensionoptionsNode; | 24 this.extensionoptionsNode = extensionoptionsNode; |
| 25 this.viewInstanceId = IdGenerator.GetNextId(); | 25 this.viewInstanceId = IdGenerator.GetNextId(); |
| 26 | 26 |
| 27 this.autosizeDeferred = false; |
| 28 |
| 27 // on* Event handlers. | 29 // on* Event handlers. |
| 28 this.eventHandlers = {}; | 30 this.eventHandlers = {}; |
| 29 | 31 |
| 30 // setupEventProperty is normally called in extension_options_events.js to | 32 // setupEventProperty is normally called in extension_options_events.js to |
| 31 // register events, but the createfailed event is registered here because | 33 // register events, but the createfailed event is registered here because |
| 32 // the event is fired from here instead of through | 34 // the event is fired from here instead of through |
| 33 // extension_options_events.js. | 35 // extension_options_events.js. |
| 34 this.setupEventProperty('createfailed'); | 36 this.setupEventProperty('createfailed'); |
| 35 | 37 |
| 36 new ExtensionOptionsEvents(this, this.viewInstanceId); | 38 new ExtensionOptionsEvents(this, this.viewInstanceId); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 if (this.initCalled) | 129 if (this.initCalled) |
| 128 return; | 130 return; |
| 129 | 131 |
| 130 this.initCalled = true; | 132 this.initCalled = true; |
| 131 this.browserPluginNode = this.createBrowserPluginNode(); | 133 this.browserPluginNode = this.createBrowserPluginNode(); |
| 132 var shadowRoot = this.extensionoptionsNode.createShadowRoot(); | 134 var shadowRoot = this.extensionoptionsNode.createShadowRoot(); |
| 133 shadowRoot.appendChild(this.browserPluginNode); | 135 shadowRoot.appendChild(this.browserPluginNode); |
| 134 this.createGuest(); | 136 this.createGuest(); |
| 135 }; | 137 }; |
| 136 | 138 |
| 137 ExtensionOptionsInternal.prototype.onSizeChanged = function(width, height) { | 139 ExtensionOptionsInternal.prototype.onSizeChanged = |
| 138 this.browserPluginNode.style.width = width + 'px'; | 140 function(newWidth, newHeight, oldWidth, oldHeight) { |
| 139 this.browserPluginNode.style.height = height + 'px'; | 141 if (this.autosizeDeferred) { |
| 142 this.deferredAutoSizeState = { |
| 143 newWidth: newWidth, |
| 144 newHeight: newHeight, |
| 145 oldWidth: oldWidth, |
| 146 oldHeight: oldHeight |
| 147 }; |
| 148 } else { |
| 149 this.resize(newWidth, newHeight, oldWidth, oldHeight); |
| 150 } |
| 140 }; | 151 }; |
| 141 | 152 |
| 142 ExtensionOptionsInternal.prototype.parseExtensionAttribute = function() { | 153 ExtensionOptionsInternal.prototype.parseExtensionAttribute = function() { |
| 143 if (this.extensionoptionsNode.hasAttribute('extension')) { | 154 if (this.extensionoptionsNode.hasAttribute('extension')) { |
| 144 this.extensionId = this.extensionoptionsNode.getAttribute('extension'); | 155 this.extensionId = this.extensionoptionsNode.getAttribute('extension'); |
| 145 return true; | 156 return true; |
| 146 } | 157 } |
| 147 return false; | 158 return false; |
| 148 }; | 159 }; |
| 149 | 160 |
| 161 ExtensionOptionsInternal.prototype.resize = |
| 162 function(newWidth, newHeight, oldWidth, oldHeight) { |
| 163 this.browserPluginNode.style.width = newWidth + 'px'; |
| 164 this.browserPluginNode.style.height = newHeight + 'px'; |
| 165 |
| 166 // Do not allow the options page's dimensions to shrink so that the options |
| 167 // page has a consistent UI. If the new size is larger than the minimum, |
| 168 // make that the new minimum size. |
| 169 if (newWidth > this.minwidth) |
| 170 this.minwidth = newWidth; |
| 171 if (newHeight > this.minheight) |
| 172 this.minheight = newHeight; |
| 173 |
| 174 GuestViewInternal.setAutoSize(this.instanceId, { |
| 175 'enableAutoSize': this.extensionoptionsNode.hasAttribute('autosize'), |
| 176 'min': { |
| 177 'width': parseInt(this.minwidth || 0), |
| 178 'height': parseInt(this.minheight || 0) |
| 179 }, |
| 180 'max': { |
| 181 'width': parseInt(this.maxwidth || 0), |
| 182 'height': parseInt(this.maxheight || 0) |
| 183 } |
| 184 }); |
| 185 }; |
| 186 |
| 150 // Adds an 'on<event>' property on the view, which can be used to set/unset | 187 // Adds an 'on<event>' property on the view, which can be used to set/unset |
| 151 // an event handler. | 188 // an event handler. |
| 152 ExtensionOptionsInternal.prototype.setupEventProperty = function(eventName) { | 189 ExtensionOptionsInternal.prototype.setupEventProperty = function(eventName) { |
| 153 var propertyName = 'on' + eventName.toLowerCase(); | 190 var propertyName = 'on' + eventName.toLowerCase(); |
| 154 var extensionoptionsNode = this.extensionoptionsNode; | 191 var extensionoptionsNode = this.extensionoptionsNode; |
| 155 Object.defineProperty(extensionoptionsNode, propertyName, { | 192 Object.defineProperty(extensionoptionsNode, propertyName, { |
| 156 get: function() { | 193 get: function() { |
| 157 return this.eventHandlers[propertyName]; | 194 return this.eventHandlers[propertyName]; |
| 158 }.bind(this), | 195 }.bind(this), |
| 159 set: function(value) { | 196 set: function(value) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 | 242 |
| 206 ExtensionOptionsInternal.prototype.resetSizeConstraintsIfInvalid = function () { | 243 ExtensionOptionsInternal.prototype.resetSizeConstraintsIfInvalid = function () { |
| 207 if (this.minheight > this.maxheight || this.minheight < 0) { | 244 if (this.minheight > this.maxheight || this.minheight < 0) { |
| 208 this.minheight = AUTO_SIZE_ATTRIBUTES.minheight; | 245 this.minheight = AUTO_SIZE_ATTRIBUTES.minheight; |
| 209 this.maxheight = AUTO_SIZE_ATTRIBUTES.maxheight; | 246 this.maxheight = AUTO_SIZE_ATTRIBUTES.maxheight; |
| 210 } | 247 } |
| 211 if (this.minwidth > this.maxwidth || this.minwidth < 0) { | 248 if (this.minwidth > this.maxwidth || this.minwidth < 0) { |
| 212 this.minwidth = AUTO_SIZE_ATTRIBUTES.minwidth; | 249 this.minwidth = AUTO_SIZE_ATTRIBUTES.minwidth; |
| 213 this.maxwidth = AUTO_SIZE_ATTRIBUTES.maxwidth; | 250 this.maxwidth = AUTO_SIZE_ATTRIBUTES.maxwidth; |
| 214 } | 251 } |
| 215 } | 252 }; |
| 253 |
| 254 /** |
| 255 * Toggles whether the element should automatically resize to its preferred |
| 256 * size. If set to true, when the element receives new autosize dimensions, |
| 257 * it passes them to the embedder in a sizechanged event, but does not resize |
| 258 * itself to those dimensions until the embedder calls resumeDeferredAutoSize. |
| 259 * This allows the embedder to defer the resizing until it is ready. |
| 260 * When set to false, the element resizes whenever it receives new autosize |
| 261 * dimensions. |
| 262 */ |
| 263 ExtensionOptionsInternal.prototype.setDeferAutoSize = function(value) { |
| 264 if (!value) |
| 265 resumeDeferredAutoSize(); |
| 266 this.autosizeDeferred = value; |
| 267 }; |
| 268 |
| 269 /** |
| 270 * Allows the element to resize to most recent set of autosize dimensions if |
| 271 * autosizing is being deferred. |
| 272 */ |
| 273 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() { |
| 274 if (this.autosizeDeferred) { |
| 275 this.resize(this.deferredAutoSizeState.newWidth, |
| 276 this.deferredAutoSizeState.newHeight, |
| 277 this.deferredAutoSizeState.oldWidth, |
| 278 this.deferredAutoSizeState.oldHeight); |
| 279 } |
| 280 }; |
| 216 | 281 |
| 217 function registerBrowserPluginElement() { | 282 function registerBrowserPluginElement() { |
| 218 var proto = Object.create(HTMLObjectElement.prototype); | 283 var proto = Object.create(HTMLObjectElement.prototype); |
| 219 | 284 |
| 220 proto.createdCallback = function() { | 285 proto.createdCallback = function() { |
| 221 this.setAttribute('type', 'application/browser-plugin'); | 286 this.setAttribute('type', 'application/browser-plugin'); |
| 222 this.style.width = '100%'; | 287 this.style.width = '100%'; |
| 223 this.style.height = '100%'; | 288 this.style.height = '100%'; |
| 224 }; | 289 }; |
| 225 | 290 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 244 new ExtensionOptionsInternal(this); | 309 new ExtensionOptionsInternal(this); |
| 245 }; | 310 }; |
| 246 | 311 |
| 247 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 312 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
| 248 var internal = privates(this).internal; | 313 var internal = privates(this).internal; |
| 249 if (!internal) | 314 if (!internal) |
| 250 return; | 315 return; |
| 251 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); | 316 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); |
| 252 }; | 317 }; |
| 253 | 318 |
| 319 var methods = [ |
| 320 'setDeferAutoSize', |
| 321 'resumeDeferredAutoSize' |
| 322 ]; |
| 323 |
| 324 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*. |
| 325 for (var i = 0; methods[i]; ++i) { |
| 326 var createHandler = function(m) { |
| 327 return function(var_args) { |
| 328 var internal = privates(this).internal; |
| 329 return $Function.apply(internal[m], internal, arguments); |
| 330 }; |
| 331 }; |
| 332 proto[methods[i]] = createHandler(methods[i]); |
| 333 } |
| 334 |
| 254 window.ExtensionOptions = | 335 window.ExtensionOptions = |
| 255 DocumentNatives.RegisterElement('extensionoptions', {prototype: proto}); | 336 DocumentNatives.RegisterElement('extensionoptions', {prototype: proto}); |
| 256 | 337 |
| 257 // Delete the callbacks so developers cannot call them and produce unexpected | 338 // Delete the callbacks so developers cannot call them and produce unexpected |
| 258 // behavior. | 339 // behavior. |
| 259 delete proto.createdCallback; | 340 delete proto.createdCallback; |
| 260 delete proto.attachedCallback; | 341 delete proto.attachedCallback; |
| 261 delete proto.detachedCallback; | 342 delete proto.detachedCallback; |
| 262 delete proto.attributeChangedCallback; | 343 delete proto.attributeChangedCallback; |
| 263 } | 344 } |
| 264 | 345 |
| 265 var useCapture = true; | 346 var useCapture = true; |
| 266 window.addEventListener('readystatechange', function listener(event) { | 347 window.addEventListener('readystatechange', function listener(event) { |
| 267 if (document.readyState == 'loading') | 348 if (document.readyState == 'loading') |
| 268 return; | 349 return; |
| 269 | 350 |
| 270 registerBrowserPluginElement(); | 351 registerBrowserPluginElement(); |
| 271 registerExtensionOptionsElement(); | 352 registerExtensionOptionsElement(); |
| 272 window.removeEventListener(event.type, listener, useCapture); | 353 window.removeEventListener(event.type, listener, useCapture); |
| 273 }, useCapture); | 354 }, useCapture); |
| OLD | NEW |