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 autosizing should be performed immediately or not. | |
256 * If set to true, sizechanged events will provide the preferred dimensions | |
257 * of the element, but will not resize it until resumeDeferredAutoSize is | |
258 * called. If set to false (the default setting), resizing will occur | |
259 * automatically. | |
260 */ | |
261 ExtensionOptionsInternal.prototype.shouldDeferAutoSize = function(value) { | |
262 if (!value) | |
263 resumeDeferredAutoSize(); | |
264 this.autosizeDeferred = value; | |
265 }; | |
266 | |
267 /** | |
268 * If the shouldDeferAutoSize setting is true, resize the element to the most | |
269 * recent preferred dimensions provided by the browser plugin autosize. | |
270 */ | |
271 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() { | |
not at google - send to devlin
2014/08/20 02:07:15
You could combine these into a method like setAuto
ericzeng
2014/08/20 02:23:30
shouldDeferAutoSize(true|false) does what you desc
not at google - send to devlin
2014/08/20 02:29:34
Ah.
In that case, s/shouldDeferAutosize/setDeferA
ericzeng
2014/08/20 18:44:07
Done.
| |
272 if (this.autosizeDeferred) { | |
273 this.resize(this.deferredAutoSizeState.newWidth, | |
274 this.deferredAutoSizeState.newHeight, | |
275 this.deferredAutoSizeState.oldWidth, | |
276 this.deferredAutoSizeState.oldHeight); | |
277 } | |
278 }; | |
216 | 279 |
217 function registerBrowserPluginElement() { | 280 function registerBrowserPluginElement() { |
218 var proto = Object.create(HTMLObjectElement.prototype); | 281 var proto = Object.create(HTMLObjectElement.prototype); |
219 | 282 |
220 proto.createdCallback = function() { | 283 proto.createdCallback = function() { |
221 this.setAttribute('type', 'application/browser-plugin'); | 284 this.setAttribute('type', 'application/browser-plugin'); |
222 this.style.width = '100%'; | 285 this.style.width = '100%'; |
223 this.style.height = '100%'; | 286 this.style.height = '100%'; |
224 }; | 287 }; |
225 | 288 |
(...skipping 18 matching lines...) Expand all Loading... | |
244 new ExtensionOptionsInternal(this); | 307 new ExtensionOptionsInternal(this); |
245 }; | 308 }; |
246 | 309 |
247 proto.attributeChangedCallback = function(name, oldValue, newValue) { | 310 proto.attributeChangedCallback = function(name, oldValue, newValue) { |
248 var internal = privates(this).internal; | 311 var internal = privates(this).internal; |
249 if (!internal) | 312 if (!internal) |
250 return; | 313 return; |
251 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); | 314 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); |
252 }; | 315 }; |
253 | 316 |
317 var methods = [ | |
318 'shouldDeferAutoSize', | |
319 'resumeDeferredAutoSize' | |
320 ]; | |
321 | |
322 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*. | |
323 for (var i = 0; methods[i]; ++i) { | |
324 var createHandler = function(m) { | |
325 return function(var_args) { | |
326 var internal = privates(this).internal; | |
327 return $Function.apply(internal[m], internal, arguments); | |
328 }; | |
329 }; | |
330 proto[methods[i]] = createHandler(methods[i]); | |
331 } | |
332 | |
254 window.ExtensionOptions = | 333 window.ExtensionOptions = |
255 DocumentNatives.RegisterElement('extensionoptions', {prototype: proto}); | 334 DocumentNatives.RegisterElement('extensionoptions', {prototype: proto}); |
256 | 335 |
257 // Delete the callbacks so developers cannot call them and produce unexpected | 336 // Delete the callbacks so developers cannot call them and produce unexpected |
258 // behavior. | 337 // behavior. |
259 delete proto.createdCallback; | 338 delete proto.createdCallback; |
260 delete proto.attachedCallback; | 339 delete proto.attachedCallback; |
261 delete proto.detachedCallback; | 340 delete proto.detachedCallback; |
262 delete proto.attributeChangedCallback; | 341 delete proto.attributeChangedCallback; |
263 } | 342 } |
264 | 343 |
265 var useCapture = true; | 344 var useCapture = true; |
266 window.addEventListener('readystatechange', function listener(event) { | 345 window.addEventListener('readystatechange', function listener(event) { |
267 if (document.readyState == 'loading') | 346 if (document.readyState == 'loading') |
268 return; | 347 return; |
269 | 348 |
270 registerBrowserPluginElement(); | 349 registerBrowserPluginElement(); |
271 registerExtensionOptionsElement(); | 350 registerExtensionOptionsElement(); |
272 window.removeEventListener(event.type, listener, useCapture); | 351 window.removeEventListener(event.type, listener, useCapture); |
273 }, useCapture); | 352 }, useCapture); |
OLD | NEW |