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

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: Move <extensionoptions> off screen until overlay is ready 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 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
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
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
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);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698