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

Side by Side Diff: chrome/browser/resources/md_extensions/manager.js

Issue 2811993004: [MD Extensions] Add support for URL navigation (Closed)
Patch Set: . Created 3 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 /**
6 * The different pages that can be shown at a time.
7 * Note: This must remain in sync with the order in manager.html!
8 * @enum {string}
9 */
10 var Page = {
11 ITEM_LIST: '0',
12 DETAIL_VIEW: '1',
13 KEYBOARD_SHORTCUTS: '2',
14 ERROR_PAGE: '3',
15 };
16
17 cr.define('extensions', function() { 5 cr.define('extensions', function() {
18 'use strict'; 6 'use strict';
19 7
20 /** 8 /**
21 * Compares two extensions to determine which should come first in the list. 9 * Compares two extensions to determine which should come first in the list.
22 * @param {chrome.developerPrivate.ExtensionInfo} a 10 * @param {chrome.developerPrivate.ExtensionInfo} a
23 * @param {chrome.developerPrivate.ExtensionInfo} b 11 * @param {chrome.developerPrivate.ExtensionInfo} b
24 * @return {number} 12 * @return {number}
25 */ 13 */
26 var compareExtensions = function(a, b) { 14 var compareExtensions = function(a, b) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 */ 64 */
77 errorPageItem_: Object, 65 errorPageItem_: Object,
78 66
79 /** 67 /**
80 * The item currently displayed in the details view subpage. See also 68 * The item currently displayed in the details view subpage. See also
81 * errorPageItem_. 69 * errorPageItem_.
82 * @private {!chrome.developerPrivate.ExtensionInfo|undefined} 70 * @private {!chrome.developerPrivate.ExtensionInfo|undefined}
83 */ 71 */
84 detailViewItem_: Object, 72 detailViewItem_: Object,
85 73
74 /**
75 * The helper object to maintain page state.
76 * @private {!extensions.PageState}
77 */
78 pageState_: Object,
79
80 /**
81 * The current page being shown.
82 * @private {!PageEntry}
83 */
84 currentPage_: Object,
85
86 /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */ 86 /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */
87 extensions: { 87 extensions: {
88 type: Array, 88 type: Array,
89 value: function() { return []; }, 89 value: function() { return []; },
90 }, 90 },
91 91
92 /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */ 92 /** @type {!Array<!chrome.developerPrivate.ExtensionInfo>} */
93 apps: { 93 apps: {
94 type: Array, 94 type: Array,
95 value: function() { return []; }, 95 value: function() { return []; },
(...skipping 11 matching lines...) Expand all
107 107
108 ready: function() { 108 ready: function() {
109 /** @type {extensions.Sidebar} */ 109 /** @type {extensions.Sidebar} */
110 this.sidebar = 110 this.sidebar =
111 /** @type {extensions.Sidebar} */(this.$$('extensions-sidebar')); 111 /** @type {extensions.Sidebar} */(this.$$('extensions-sidebar'));
112 this.toolbar = 112 this.toolbar =
113 /** @type {extensions.Toolbar} */(this.$$('extensions-toolbar')); 113 /** @type {extensions.Toolbar} */(this.$$('extensions-toolbar'));
114 this.listHelper_ = new ListHelper(this); 114 this.listHelper_ = new ListHelper(this);
115 this.sidebar.setListDelegate(this.listHelper_); 115 this.sidebar.setListDelegate(this.listHelper_);
116 this.readyPromiseResolver.resolve(); 116 this.readyPromiseResolver.resolve();
117 this.currentPage_ = {page: Page.LIST};
118 this.pageState_ = new extensions.PageState(function(newPage) {
119 this.changePage(newPage, true);
120 }.bind(this));
121 this.optionsDialog.addEventListener('close', function() {
122 // We update the page when the options dialog closes, but only if we're
123 // still on the details page. We could be on a different page if the
124 // user hit back while the options dialog was visible; in that case, the
125 // new page is already correct.
126 if (this.currentPage_.page == Page.DETAILS)
127 this.changePage({page: Page.DETAILS, id: this.currentPage_.id});
michaelpg 2017/04/14 20:23:53 this seems to contradict the comment: if we're on
Devlin 2017/04/17 23:29:24 Tried to clear it up with some comments.
michaelpg 2017/04/18 22:03:11 Thanks.
128 }.bind(this));
117 }, 129 },
118 130
119 get keyboardShortcuts() { 131 get keyboardShortcuts() {
120 return this.$['keyboard-shortcuts']; 132 return this.$['keyboard-shortcuts'];
121 }, 133 },
122 134
123 get packDialog() { 135 get packDialog() {
124 return this.$['pack-dialog']; 136 return this.$['pack-dialog'];
125 }, 137 },
126 138
127 get loadError() { 139 get loadError() {
128 return this.$['load-error']; 140 return this.$['load-error'];
129 }, 141 },
130 142
131 get optionsDialog() { 143 get optionsDialog() {
132 return this.$['options-dialog']; 144 return this.$['options-dialog'];
133 }, 145 },
134 146
135 get errorPage() { 147 get errorPage() {
136 return this.$['error-page']; 148 return this.$['error-page'];
137 }, 149 },
138 150
139 /** 151 /**
140 * Shows the details view for a given item. 152 * Shows the details view for a given item.
141 * @param {!chrome.developerPrivate.ExtensionInfo} data 153 * @param {!chrome.developerPrivate.ExtensionInfo} data
142 */ 154 */
143 showItemDetails: function(data) { 155 showItemDetails: function(data) {
144 this.$['items-list'].willShowItemSubpage(data.id); 156 this.changePage({page: Page.DETAILS, id: data.id});
145 this.detailViewItem_ = data;
146 this.changePage(Page.DETAIL_VIEW);
147 }, 157 },
148 158
149 /** 159 /**
160 * Initializes the page to reflect what's specified in the url so that if
161 * the user visits chrome://extensions/?id=..., we land on the proper page.
162 */
163 initPage: function() {
164 this.changePage(this.pageState_.getCurrentPage(), true);
165 },
166
167 /**
150 * @param {!CustomEvent} event 168 * @param {!CustomEvent} event
151 * @private 169 * @private
152 */ 170 */
153 onFilterChanged_: function(event) { 171 onFilterChanged_: function(event) {
154 this.filter = /** @type {string} */ (event.detail); 172 this.filter = /** @type {string} */ (event.detail);
155 }, 173 },
156 174
175 /** @private */
157 onMenuButtonTap_: function() { 176 onMenuButtonTap_: function() {
158 this.$.drawer.toggle(); 177 this.$.drawer.toggle();
159 }, 178 },
160 179
161 /** 180 /**
162 * @param {chrome.developerPrivate.ExtensionType} type The type of item. 181 * @param {chrome.developerPrivate.ExtensionType} type The type of item.
163 * @return {string} The ID of the list that the item belongs in. 182 * @return {string} The ID of the list that the item belongs in.
164 * @private 183 * @private
165 */ 184 */
166 getListId_: function(type) { 185 getListId_: function(type) {
(...skipping 24 matching lines...) Expand all
191 * @return {number} The index of the item in the list, or -1 if not found. 210 * @return {number} The index of the item in the list, or -1 if not found.
192 * @private 211 * @private
193 */ 212 */
194 getIndexInList_: function(listId, itemId) { 213 getIndexInList_: function(listId, itemId) {
195 return this[listId].findIndex(function(item) { 214 return this[listId].findIndex(function(item) {
196 return item.id == itemId; 215 return item.id == itemId;
197 }); 216 });
198 }, 217 },
199 218
200 /** 219 /**
220 * @return {?chrome.developerPrivate.ExtensionInfo}
221 * @private
222 */
223 getData_: function(id) {
224 return this.extensions[this.getIndexInList_('extensions', id)] ||
225 this.apps[this.getIndexInList_('apps', id)];
226 },
227
228 /**
201 * @return {boolean} Whether the list should be visible. 229 * @return {boolean} Whether the list should be visible.
202 * @private 230 * @private
203 */ 231 */
204 computeListHidden_: function() { 232 computeListHidden_: function() {
205 return this.$['items-list'].items.length == 0; 233 return this.$['items-list'].items.length == 0;
206 }, 234 },
207 235
208 /** 236 /**
209 * Creates and adds a new extensions-item element to the list, inserting it 237 * Creates and adds a new extensions-item element to the list, inserting it
210 * into its sorted position in the relevant section. 238 * into its sorted position in the relevant section.
(...skipping 22 matching lines...) Expand all
233 // We should never try and update a non-existent item. 261 // We should never try and update a non-existent item.
234 assert(index >= 0); 262 assert(index >= 0);
235 this.set([listId, index], item); 263 this.set([listId, index], item);
236 264
237 // Update the subpage if it is open and displaying the item. If it's not 265 // Update the subpage if it is open and displaying the item. If it's not
238 // open, we don't update the data even if it's displaying that item. We'll 266 // open, we don't update the data even if it's displaying that item. We'll
239 // set the item correctly before opening the page. It's a little weird 267 // set the item correctly before opening the page. It's a little weird
240 // that the DOM will have stale data, but there's no point in causing the 268 // that the DOM will have stale data, but there's no point in causing the
241 // extra work. 269 // extra work.
242 if (this.detailViewItem_ && this.detailViewItem_.id == item.id && 270 if (this.detailViewItem_ && this.detailViewItem_.id == item.id &&
243 this.$.pages.selected == Page.DETAIL_VIEW) { 271 this.$.pages.selected == Page.DETAILS) {
244 this.detailViewItem_ = item; 272 this.detailViewItem_ = item;
245 } else if (this.errorPageItem_ && this.errorPageItem_.id == item.id && 273 } else if (this.errorPageItem_ && this.errorPageItem_.id == item.id &&
246 this.$.pages.selected == Page.ERROR_PAGE) { 274 this.$.pages.selected == Page.ERRORS) {
247 this.errorPageItem_ = item; 275 this.errorPageItem_ = item;
248 } 276 }
249 }, 277 },
250 278
251 /** 279 /**
252 * @param {!chrome.developerPrivate.ExtensionInfo} item The data for the 280 * @param {!chrome.developerPrivate.ExtensionInfo} item The data for the
253 * item to remove. 281 * item to remove.
254 */ 282 */
255 removeItem: function(item) { 283 removeItem: function(item) {
256 var listId = this.getListId_(item.type); 284 var listId = this.getListId_(item.type);
257 var index = this.getIndexInList_(listId, item.id); 285 var index = this.getIndexInList_(listId, item.id);
258 // We should never try and remove a non-existent item. 286 // We should never try and remove a non-existent item.
259 assert(index >= 0); 287 assert(index >= 0);
260 this.splice(listId, index, 1); 288 this.splice(listId, index, 1);
261 }, 289 },
262 290
263 /** 291 /**
264 * @param {Page} page 292 * @param {Page} page
265 * @return {!(extensions.KeyboardShortcuts | 293 * @return {!(extensions.KeyboardShortcuts |
266 * extensions.DetailView | 294 * extensions.DetailView |
267 * extensions.ItemList)} 295 * extensions.ItemList)}
268 * @private 296 * @private
269 */ 297 */
270 getPage_: function(page) { 298 getPage_: function(page) {
271 switch (page) { 299 switch (page) {
272 case Page.ITEM_LIST: 300 case Page.LIST:
273 return this.$['items-list']; 301 return this.$['items-list'];
274 case Page.DETAIL_VIEW: 302 case Page.DETAILS:
275 return this.$['details-view']; 303 return this.$['details-view'];
276 case Page.KEYBOARD_SHORTCUTS: 304 case Page.SHORTCUTS:
277 return this.$['keyboard-shortcuts']; 305 return this.$['keyboard-shortcuts'];
278 case Page.ERROR_PAGE: 306 case Page.ERRORS:
279 return this.$['error-page']; 307 return this.$['error-page'];
280 } 308 }
281 assertNotReached(); 309 assertNotReached();
282 }, 310 },
283 311
284 /** 312 /**
285 * Changes the active page selection. 313 * Changes the active page selection.
286 * @param {Page} toPage 314 * @param {PageEntry} newPage
315 * @param {boolean=} isSilent
michaelpg 2017/04/14 20:23:53 document isSilent
Devlin 2017/04/17 23:29:24 Done.
287 */ 316 */
288 changePage: function(toPage) { 317 changePage: function(newPage, isSilent) {
318 if (this.currentPage_.page == newPage.page &&
319 this.currentPage_.subpage == newPage.subpage &&
320 this.currentPage_.id == newPage.id) {
321 return;
322 }
323
289 this.$.drawer.closeDrawer(); 324 this.$.drawer.closeDrawer();
325 if (this.optionsDialog.open)
326 this.optionsDialog.close();
327
290 var fromPage = this.$.pages.selected; 328 var fromPage = this.$.pages.selected;
291 if (fromPage == toPage) 329 var toPage = newPage.page;
292 return; 330 var data;
293 var entry; 331 if (newPage.id) {
294 var exit; 332 data = this.getData_(newPage.id);
295 if (fromPage == Page.ITEM_LIST && (toPage == Page.DETAIL_VIEW || 333 assert(data, newPage.id);
296 toPage == Page.ERROR_PAGE)) {
297 entry = [extensions.Animation.HERO];
298 // The item grid can be larger than the detail view that we're
299 // hero'ing into, so we want to also fade out to avoid any jarring.
300 exit = [extensions.Animation.HERO, extensions.Animation.FADE_OUT];
301 } else if (toPage == Page.ITEM_LIST) {
302 entry = [extensions.Animation.FADE_IN];
303 exit = [extensions.Animation.SCALE_DOWN];
304 } else {
305 assert(toPage == Page.DETAIL_VIEW ||
306 toPage == Page.KEYBOARD_SHORTCUTS);
307 entry = [extensions.Animation.FADE_IN];
308 exit = [extensions.Animation.FADE_OUT];
309 } 334 }
310 this.getPage_(fromPage).animationHelper.setExitAnimations(exit); 335
311 this.getPage_(toPage).animationHelper.setEntryAnimations(entry); 336 if (toPage == Page.DETAILS) {
312 this.$.pages.selected = toPage; 337 assert(newPage.id);
338 this.detailViewItem_ = data;
339 } else if (toPage == Page.ERRORS) {
340 assert(newPage.id);
341 this.errorPageItem_ = data;
342 }
343
344 if (fromPage != toPage) {
345 var entry;
346 var exit;
347 if (fromPage == Page.LIST && (toPage == Page.DETAILS ||
348 toPage == Page.ERRORS)) {
349 assert(newPage.id);
350 this.$['items-list'].willShowItemSubpage(data.id);
351 entry = [extensions.Animation.HERO];
352 // The item grid can be larger than the detail view that we're
353 // hero'ing into, so we want to also fade out to avoid any jarring.
354 exit = [extensions.Animation.HERO, extensions.Animation.FADE_OUT];
355 } else if (toPage == Page.LIST) {
356 entry = [extensions.Animation.FADE_IN];
357 exit = [extensions.Animation.SCALE_DOWN];
358 } else {
359 assert(toPage == Page.DETAILS ||
360 toPage == Page.SHORTCUTS);
361 entry = [extensions.Animation.FADE_IN];
362 exit = [extensions.Animation.FADE_OUT];
363 }
364
365 this.getPage_(fromPage).animationHelper.setExitAnimations(exit);
366 this.getPage_(toPage).animationHelper.setEntryAnimations(entry);
367 this.$.pages.selected = toPage;
368 }
369
370 if (newPage.subpage) {
371 assert(newPage.subpage == Subpage.OPTIONS);
372 assert(newPage.id);
373 this.optionsDialog.show(data);
374 }
375
376 this.currentPage_ = newPage;
377
378 if (!isSilent)
379 this.pageState_.onPageChange(newPage);
313 }, 380 },
314 381
315 /** 382 /**
316 * Handles the event for the user clicking on a details button. 383 * Handles the event for the user clicking on a details button.
317 * @param {!CustomEvent} e 384 * @param {!CustomEvent} e
318 * @private 385 * @private
319 */ 386 */
320 onShouldShowItemDetails_: function(e) { 387 onShouldShowItemDetails_: function(e) {
321 this.showItemDetails(e.detail.data); 388 this.showItemDetails(e.detail.data);
322 }, 389 },
323 390
324 /** 391 /**
325 * Handles the event for the user clicking on the errors button. 392 * Handles the event for the user clicking on the errors button.
326 * @param {!CustomEvent} e 393 * @param {!CustomEvent} e
327 * @private 394 * @private
328 */ 395 */
329 onShouldShowItemErrors_: function(e) { 396 onShouldShowItemErrors_: function(e) {
330 var data = e.detail.data; 397 this.changePage({page: Page.ERRORS, id: e.detail.data.id});
331 this.$['items-list'].willShowItemSubpage(data.id);
332 this.errorPageItem_ = data;
333 this.changePage(Page.ERROR_PAGE);
334 }, 398 },
335 399
336 /** @private */ 400 /** @private */
337 onDetailsViewClose_: function() { 401 onDetailsViewClose_: function() {
338 // Note: we don't reset detailViewItem_ here because doing so just causes 402 // Note: we don't reset detailViewItem_ here because doing so just causes
339 // extra work for the data-bound details view. 403 // extra work for the data-bound details view.
340 this.changePage(Page.ITEM_LIST); 404 this.changePage({page: Page.LIST});
341 }, 405 },
342 406
343 /** @private */ 407 /** @private */
344 onErrorPageClose_: function() { 408 onErrorPageClose_: function() {
345 // Note: we don't reset errorPageItem_ here because doing so just causes 409 // Note: we don't reset errorPageItem_ here because doing so just causes
346 // extra work for the data-bound error page. 410 // extra work for the data-bound error page.
347 this.changePage(Page.ITEM_LIST); 411 this.changePage({page: Page.LIST});
348 }, 412 },
349 413
350 /** @private */ 414 /** @private */
351 onPackTap_: function() { 415 onPackTap_: function() {
352 this.$['pack-dialog'].show(); 416 this.$['pack-dialog'].show();
353 } 417 }
354 }); 418 });
355 419
356 /** 420 /**
357 * @param {extensions.Manager} manager 421 * @param {extensions.Manager} manager
(...skipping 11 matching lines...) Expand all
369 switch (type) { 433 switch (type) {
370 case extensions.ShowingType.EXTENSIONS: 434 case extensions.ShowingType.EXTENSIONS:
371 items = this.manager_.extensions; 435 items = this.manager_.extensions;
372 break; 436 break;
373 case extensions.ShowingType.APPS: 437 case extensions.ShowingType.APPS:
374 items = this.manager_.apps; 438 items = this.manager_.apps;
375 break; 439 break;
376 } 440 }
377 441
378 this.manager_.$/* hack */ ['items-list'].set('items', assert(items)); 442 this.manager_.$/* hack */ ['items-list'].set('items', assert(items));
379 this.manager_.changePage(Page.ITEM_LIST); 443 this.manager_.changePage({page: Page.LIST});
380 }, 444 },
381 445
382 /** @override */ 446 /** @override */
383 showKeyboardShortcuts: function() { 447 showKeyboardShortcuts: function() {
384 this.manager_.changePage(Page.KEYBOARD_SHORTCUTS); 448 this.manager_.changePage({page: Page.SHORTCUTS});
385 }, 449 },
386 }; 450 };
387 451
388 return {Manager: Manager}; 452 return {Manager: Manager};
389 }); 453 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698