Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(891)

Side by Side Diff: chrome/renderer/resources/extensions/extension_options.js

Issue 480243003: Implement smoother autosizing of the extension options overlay (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 27
28 this.autosizeDeferred = false;
29
28 // on* Event handlers. 30 // on* Event handlers.
29 this.eventHandlers = {}; 31 this.eventHandlers = {};
30 32
31 // setupEventProperty is normally called in extension_options_events.js to 33 // setupEventProperty is normally called in extension_options_events.js to
32 // register events, but the createfailed event is registered here because 34 // register events, but the createfailed event is registered here because
33 // the event is fired from here instead of through 35 // the event is fired from here instead of through
34 // extension_options_events.js. 36 // extension_options_events.js.
35 this.setupEventProperty('createfailed'); 37 this.setupEventProperty('createfailed');
36 38
37 new ExtensionOptionsEvents(this, this.viewInstanceId); 39 new ExtensionOptionsEvents(this, this.viewInstanceId);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 if (this.initCalled) 133 if (this.initCalled)
132 return; 134 return;
133 135
134 this.initCalled = true; 136 this.initCalled = true;
135 this.browserPluginNode = this.createBrowserPluginNode(); 137 this.browserPluginNode = this.createBrowserPluginNode();
136 var shadowRoot = this.extensionoptionsNode.createShadowRoot(); 138 var shadowRoot = this.extensionoptionsNode.createShadowRoot();
137 shadowRoot.appendChild(this.browserPluginNode); 139 shadowRoot.appendChild(this.browserPluginNode);
138 this.createGuest(); 140 this.createGuest();
139 }; 141 };
140 142
141 ExtensionOptionsInternal.prototype.onSizeChanged = function(width, height) { 143 ExtensionOptionsInternal.prototype.onSizeChanged =
142 this.browserPluginNode.style.width = width + 'px'; 144 function(newWidth, newHeight, oldWidth, oldHeight) {
143 this.browserPluginNode.style.height = height + 'px'; 145 if (this.autosizeDeferred) {
146 this.deferredAutoSizeState = {
147 newWidth: newWidth,
148 newHeight: newHeight,
149 oldWidth: oldWidth,
150 oldHeight: oldHeight
151 };
152 } else {
153 this.resize(newWidth, newHeight, oldWidth, oldHeight);
154 }
144 }; 155 };
145 156
146 ExtensionOptionsInternal.prototype.parseExtensionAttribute = function() { 157 ExtensionOptionsInternal.prototype.parseExtensionAttribute = function() {
147 if (this.extensionoptionsNode.hasAttribute('extension')) { 158 if (this.extensionoptionsNode.hasAttribute('extension')) {
148 this.extensionId = this.extensionoptionsNode.getAttribute('extension'); 159 this.extensionId = this.extensionoptionsNode.getAttribute('extension');
149 return true; 160 return true;
150 } 161 }
151 return false; 162 return false;
152 }; 163 };
153 164
165 ExtensionOptionsInternal.prototype.resize =
166 function(newWidth, newHeight, oldWidth, oldHeight) {
167 this.browserPluginNode.style.width = newWidth + 'px';
168 this.browserPluginNode.style.height = newHeight + 'px';
169
170 // Do not allow the options page's dimensions to shrink so that the options
171 // page has a consistent UI. If the new size is larger than the minimum,
172 // make that the new minimum size.
173 if (newWidth > this.minwidth)
174 this.minwidth = newWidth;
175 if (newHeight > this.minheight)
176 this.minheight = newHeight;
177
178 GuestViewInternal.setAutoSize(this.guestInstanceId, {
179 'enableAutoSize': this.extensionoptionsNode.hasAttribute('autosize'),
180 'min': {
181 'width': parseInt(this.minwidth || 0),
182 'height': parseInt(this.minheight || 0)
183 },
184 'max': {
185 'width': parseInt(this.maxwidth || 0),
186 'height': parseInt(this.maxheight || 0)
187 }
188 });
189 };
190
154 // Adds an 'on<event>' property on the view, which can be used to set/unset 191 // Adds an 'on<event>' property on the view, which can be used to set/unset
155 // an event handler. 192 // an event handler.
156 ExtensionOptionsInternal.prototype.setupEventProperty = function(eventName) { 193 ExtensionOptionsInternal.prototype.setupEventProperty = function(eventName) {
157 var propertyName = 'on' + eventName.toLowerCase(); 194 var propertyName = 'on' + eventName.toLowerCase();
158 var extensionoptionsNode = this.extensionoptionsNode; 195 var extensionoptionsNode = this.extensionoptionsNode;
159 Object.defineProperty(extensionoptionsNode, propertyName, { 196 Object.defineProperty(extensionoptionsNode, propertyName, {
160 get: function() { 197 get: function() {
161 return this.eventHandlers[propertyName]; 198 return this.eventHandlers[propertyName];
162 }.bind(this), 199 }.bind(this),
163 set: function(value) { 200 set: function(value) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 246
210 ExtensionOptionsInternal.prototype.resetSizeConstraintsIfInvalid = function () { 247 ExtensionOptionsInternal.prototype.resetSizeConstraintsIfInvalid = function () {
211 if (this.minheight > this.maxheight || this.minheight < 0) { 248 if (this.minheight > this.maxheight || this.minheight < 0) {
212 this.minheight = AUTO_SIZE_ATTRIBUTES.minheight; 249 this.minheight = AUTO_SIZE_ATTRIBUTES.minheight;
213 this.maxheight = AUTO_SIZE_ATTRIBUTES.maxheight; 250 this.maxheight = AUTO_SIZE_ATTRIBUTES.maxheight;
214 } 251 }
215 if (this.minwidth > this.maxwidth || this.minwidth < 0) { 252 if (this.minwidth > this.maxwidth || this.minwidth < 0) {
216 this.minwidth = AUTO_SIZE_ATTRIBUTES.minwidth; 253 this.minwidth = AUTO_SIZE_ATTRIBUTES.minwidth;
217 this.maxwidth = AUTO_SIZE_ATTRIBUTES.maxwidth; 254 this.maxwidth = AUTO_SIZE_ATTRIBUTES.maxwidth;
218 } 255 }
219 } 256 };
257
258 /**
259 * Toggles whether the element should automatically resize to its preferred
260 * size. If set to true, when the element receives new autosize dimensions,
261 * it passes them to the embedder in a sizechanged event, but does not resize
262 * itself to those dimensions until the embedder calls resumeDeferredAutoSize.
263 * This allows the embedder to defer the resizing until it is ready.
264 * When set to false, the element resizes whenever it receives new autosize
265 * dimensions.
266 */
267 ExtensionOptionsInternal.prototype.setDeferAutoSize = function(value) {
268 if (!value)
269 resumeDeferredAutoSize();
270 this.autosizeDeferred = value;
271 };
272
273 /**
274 * Allows the element to resize to most recent set of autosize dimensions if
275 * autosizing is being deferred.
276 */
277 ExtensionOptionsInternal.prototype.resumeDeferredAutoSize = function() {
278 if (this.autosizeDeferred) {
279 this.resize(this.deferredAutoSizeState.newWidth,
280 this.deferredAutoSizeState.newHeight,
281 this.deferredAutoSizeState.oldWidth,
282 this.deferredAutoSizeState.oldHeight);
283 }
284 };
220 285
221 function registerBrowserPluginElement() { 286 function registerBrowserPluginElement() {
222 var proto = Object.create(HTMLObjectElement.prototype); 287 var proto = Object.create(HTMLObjectElement.prototype);
223 288
224 proto.createdCallback = function() { 289 proto.createdCallback = function() {
225 this.setAttribute('type', 'application/browser-plugin'); 290 this.setAttribute('type', 'application/browser-plugin');
226 this.style.width = '100%'; 291 this.style.width = '100%';
227 this.style.height = '100%'; 292 this.style.height = '100%';
228 }; 293 };
229 294
(...skipping 18 matching lines...) Expand all
248 new ExtensionOptionsInternal(this); 313 new ExtensionOptionsInternal(this);
249 }; 314 };
250 315
251 proto.attributeChangedCallback = function(name, oldValue, newValue) { 316 proto.attributeChangedCallback = function(name, oldValue, newValue) {
252 var internal = privates(this).internal; 317 var internal = privates(this).internal;
253 if (!internal) 318 if (!internal)
254 return; 319 return;
255 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue); 320 internal.handleExtensionOptionsAttributeMutation(name, oldValue, newValue);
256 }; 321 };
257 322
323 var methods = [
324 'setDeferAutoSize',
325 'resumeDeferredAutoSize'
326 ];
327
328 // Forward proto.foo* method calls to ExtensionOptionsInternal.foo*.
329 for (var i = 0; methods[i]; ++i) {
330 var createHandler = function(m) {
331 return function(var_args) {
332 var internal = privates(this).internal;
333 return $Function.apply(internal[m], internal, arguments);
334 };
335 };
336 proto[methods[i]] = createHandler(methods[i]);
337 }
338
258 window.ExtensionOptions = 339 window.ExtensionOptions =
259 DocumentNatives.RegisterElement('extensionoptions', {prototype: proto}); 340 DocumentNatives.RegisterElement('extensionoptions', {prototype: proto});
260 341
261 // Delete the callbacks so developers cannot call them and produce unexpected 342 // Delete the callbacks so developers cannot call them and produce unexpected
262 // behavior. 343 // behavior.
263 delete proto.createdCallback; 344 delete proto.createdCallback;
264 delete proto.attachedCallback; 345 delete proto.attachedCallback;
265 delete proto.detachedCallback; 346 delete proto.detachedCallback;
266 delete proto.attributeChangedCallback; 347 delete proto.attributeChangedCallback;
267 } 348 }
268 349
269 var useCapture = true; 350 var useCapture = true;
270 window.addEventListener('readystatechange', function listener(event) { 351 window.addEventListener('readystatechange', function listener(event) {
271 if (document.readyState == 'loading') 352 if (document.readyState == 'loading')
272 return; 353 return;
273 354
274 registerBrowserPluginElement(); 355 registerBrowserPluginElement();
275 registerExtensionOptionsElement(); 356 registerExtensionOptionsElement();
276 window.removeEventListener(event.type, listener, useCapture); 357 window.removeEventListener(event.type, listener, useCapture);
277 }, useCapture); 358 }, useCapture);
OLDNEW
« no previous file with comments | « chrome/browser/resources/extensions/extensions.html ('k') | chrome/renderer/resources/extensions/extension_options_events.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698