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

Side by Side Diff: chrome/browser/resources/extensions/extension_list.js

Issue 484033003: Open embedded extension options from the extension action context menu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix missed cases in refactor - setting optionsShown_ in onclose, scrolling only in the context menu… 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <include src="extension_error.js"> 5 <include src="extension_error.js">
6 6
7 cr.define('options', function() { 7 cr.define('options', function() {
8 'use strict'; 8 'use strict';
9 9
10 /** 10 /**
(...skipping 15 matching lines...) Expand all
26 * @type {Object.<string, string>} A map from extension id to last reloaded 26 * @type {Object.<string, string>} A map from extension id to last reloaded
27 * timestamp. The timestamp is recorded when the user click the 'Reload' 27 * timestamp. The timestamp is recorded when the user click the 'Reload'
28 * link. It is used to refresh the icon of an unpacked extension. 28 * link. It is used to refresh the icon of an unpacked extension.
29 * This persists between calls to decorate. 29 * This persists between calls to decorate.
30 */ 30 */
31 var extensionReloadedTimestamp = {}; 31 var extensionReloadedTimestamp = {};
32 32
33 ExtensionsList.prototype = { 33 ExtensionsList.prototype = {
34 __proto__: HTMLDivElement.prototype, 34 __proto__: HTMLDivElement.prototype,
35 35
36 /**
37 * Indicates whether an embedded options page that was navigated to through
38 * the '?options=' URL query has been shown to the user. This is necessary
39 * to prevent showExtensionNodes_ from opening the options more than once.
40 * @type {boolean}
41 * @private
42 */
43 optionsShown_: false,
44
36 /** @override */ 45 /** @override */
37 decorate: function() { 46 decorate: function() {
38 this.textContent = ''; 47 this.textContent = '';
39 48
40 this.showExtensionNodes_(); 49 this.showExtensionNodes_();
41 }, 50 },
42 51
43 getIdQueryParam_: function() { 52 getIdQueryParam_: function() {
44 return parseQueryParams(document.location)['id']; 53 return parseQueryParams(document.location)['id'];
45 }, 54 },
46 55
56 getOptionsQueryParam_: function() {
57 return parseQueryParams(document.location)['options'];
58 },
59
47 /** 60 /**
48 * Creates all extension items from scratch. 61 * Creates all extension items from scratch.
49 * @private 62 * @private
50 */ 63 */
51 showExtensionNodes_: function() { 64 showExtensionNodes_: function() {
52 // Iterate over the extension data and add each item to the list. 65 // Iterate over the extension data and add each item to the list.
53 this.data_.extensions.forEach(this.createNode_, this); 66 this.data_.extensions.forEach(this.createNode_, this);
54 67
55 var idToHighlight = this.getIdQueryParam_(); 68 var idToHighlight = this.getIdQueryParam_();
56 if (idToHighlight && $(idToHighlight)) { 69 if (idToHighlight && $(idToHighlight))
57 // Scroll offset should be calculated slightly higher than the actual 70 this.scrollToNode_(idToHighlight);
58 // offset of the element being scrolled to, so that it ends up not all 71
59 // the way at the top. That way it is clear that there are more elements 72 var idToOpenOptions = this.getOptionsQueryParam_();
60 // above the element being scrolled to. 73 if (idToOpenOptions && $(idToOpenOptions))
61 var scrollFudge = 1.2; 74 this.showEmbeddedExtensionOptions_(idToOpenOptions, true);
62 var scrollTop = $(idToHighlight).offsetTop - scrollFudge *
63 $(idToHighlight).clientHeight;
64 setScrollTopForDocument(document, scrollTop);
65 }
66 75
67 if (this.data_.extensions.length == 0) 76 if (this.data_.extensions.length == 0)
68 this.classList.add('empty-extension-list'); 77 this.classList.add('empty-extension-list');
69 else 78 else
70 this.classList.remove('empty-extension-list'); 79 this.classList.remove('empty-extension-list');
71 }, 80 },
72 81
73 /** 82 /**
83 * Scrolls the page down to the extension node with the given id.
84 * @param {string} extensionId The id of the extension to scroll to.
85 * @private
86 */
87 scrollToNode_: function(extensionId) {
88 // Scroll offset should be calculated slightly higher than the actual
89 // offset of the element being scrolled to, so that it ends up not all
90 // the way at the top. That way it is clear that there are more elements
91 // above the element being scrolled to.
92 var scrollFudge = 1.2;
93 var scrollTop = $(extensionId).offsetTop - scrollFudge *
94 $(extensionId).clientHeight;
95 setScrollTopForDocument(document, scrollTop);
96 },
97
98 /**
74 * Synthesizes and initializes an HTML element for the extension metadata 99 * Synthesizes and initializes an HTML element for the extension metadata
75 * given in |extension|. 100 * given in |extension|.
76 * @param {Object} extension A dictionary of extension metadata. 101 * @param {Object} extension A dictionary of extension metadata.
77 * @private 102 * @private
78 */ 103 */
79 createNode_: function(extension) { 104 createNode_: function(extension) {
80 var template = $('template-collection').querySelector( 105 var template = $('template-collection').querySelector(
81 '.extension-list-item-wrapper'); 106 '.extension-list-item-wrapper');
82 var node = template.cloneNode(true); 107 var node = template.cloneNode(true);
83 node.id = extension.id; 108 node.id = extension.id;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 }); 212 });
188 fileAccess.querySelector('input').checked = extension.allowFileAccess; 213 fileAccess.querySelector('input').checked = extension.allowFileAccess;
189 fileAccess.hidden = false; 214 fileAccess.hidden = false;
190 } 215 }
191 216
192 // The 'Options' link. 217 // The 'Options' link.
193 if (extension.enabled && extension.optionsUrl) { 218 if (extension.enabled && extension.optionsUrl) {
194 var options = node.querySelector('.options-link'); 219 var options = node.querySelector('.options-link');
195 options.addEventListener('click', function(e) { 220 options.addEventListener('click', function(e) {
196 if (this.data_.enableEmbeddedExtensionOptions) { 221 if (this.data_.enableEmbeddedExtensionOptions) {
197 extensions.ExtensionOptionsOverlay.getInstance(). 222 this.showEmbeddedExtensionOptions_(extension.id, false);
198 setExtensionAndShowOverlay(extension.id,
199 extension.name,
200 extension.icon);
201 } else { 223 } else {
202 chrome.send('extensionSettingsOptions', [extension.id]); 224 chrome.send('extensionSettingsOptions', [extension.id]);
203 } 225 }
204 e.preventDefault(); 226 e.preventDefault();
205 }.bind(this)); 227 }.bind(this));
206 options.hidden = false; 228 options.hidden = false;
207 } 229 }
208 230
209 // The 'Permissions' link. 231 // The 'Permissions' link.
210 var permissions = node.querySelector('.permissions-link'); 232 var permissions = node.querySelector('.permissions-link');
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 if (location.hash.substr(1) == extension.id) { 432 if (location.hash.substr(1) == extension.id) {
411 // Scroll beneath the fixed header so that the extension is not 433 // Scroll beneath the fixed header so that the extension is not
412 // obscured. 434 // obscured.
413 var topScroll = node.offsetTop - $('page-header').offsetHeight; 435 var topScroll = node.offsetTop - $('page-header').offsetHeight;
414 var pad = parseInt(getComputedStyle(node, null).marginTop, 10); 436 var pad = parseInt(getComputedStyle(node, null).marginTop, 10);
415 if (!isNaN(pad)) 437 if (!isNaN(pad))
416 topScroll -= pad / 2; 438 topScroll -= pad / 2;
417 setScrollTopForDocument(document, topScroll); 439 setScrollTopForDocument(document, topScroll);
418 } 440 }
419 }, 441 },
442
443 /**
444 * Opens the extension options overlay for the extension with the given id.
445 * @param {string} extensionId The id of extension whose options page should
446 * be displayed.
447 * @param {boolean} scroll Whether the page should scroll to the extension
448 * @private
449 */
450 showEmbeddedExtensionOptions_: function(extensionId, scroll) {
451 if (this.optionsShown_)
452 return;
453
454 // Get the extension from the given id.
455 var extension = this.data_.extensions.filter(function(extension) {
456 return extension.id == extensionId;
457 })[0];
458
459 if (!extension)
460 return;
461
462 if (scroll)
463 this.scrollToNode_(extensionId);
464 // Add the options query string. Corner case: the 'options' query string
465 // will clobber the 'id' query string if the options link is clicked when
466 // 'id' is in the URL, or if both query strings are in the URL.
467 uber.replaceState({}, '?options=' + extensionId);
468
469 extensions.ExtensionOptionsOverlay.getInstance().
470 setExtensionAndShowOverlay(extensionId,
471 extension.name,
472 extension.icon);
473
474 this.optionsShown_ = true;
475 $('overlay').addEventListener('cancelOverlay', function() {
476 this.optionsShown_ = false;
477 }.bind(this));
478 },
420 }; 479 };
421 480
422 return { 481 return {
423 ExtensionsList: ExtensionsList 482 ExtensionsList: ExtensionsList
424 }; 483 };
425 }); 484 });
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_tab_util.cc ('k') | chrome/browser/resources/extensions/extension_options_overlay.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698