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

Side by Side Diff: chrome/browser/resources/settings/route.js

Issue 2206613003: Settings Router Refactor: Support dynamic parameters (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@223-settings-router-handle-random-urls-better
Patch Set: fix Created 4 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
« no previous file with comments | « no previous file | chrome/test/data/webui/settings/cr_settings_browsertest.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 cr.define('settings', function() { 5 cr.define('settings', function() {
6 /** 6 /**
7 * Class for navigable routes. May only be instantiated within this file. 7 * Class for navigable routes. May only be instantiated within this file.
8 * @constructor 8 * @constructor
9 * @param {string} path 9 * @param {string} path
10 * @private 10 * @private
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 var getRouteForPath = function(path) { 285 var getRouteForPath = function(path) {
286 // TODO(tommycli): Use Object.values once Closure compilation supports it. 286 // TODO(tommycli): Use Object.values once Closure compilation supports it.
287 var matchingKey = Object.keys(Route).find(function(key) { 287 var matchingKey = Object.keys(Route).find(function(key) {
288 return Route[key].path == path; 288 return Route[key].path == path;
289 }); 289 });
290 290
291 return Route[matchingKey] || null; 291 return Route[matchingKey] || null;
292 }; 292 };
293 293
294 /** 294 /**
295 * The current active route. This may only be updated via the global 295 * The current active route. This updated only by settings.navigateTo.
296 * function settings.navigateTo.
297 * @private {!settings.Route} 296 * @private {!settings.Route}
298 */ 297 */
299 var currentRoute_ = (function() { 298 var currentRoute_ = (function() {
300 var route = getRouteForPath(window.location.pathname); 299 var route = getRouteForPath(window.location.pathname);
301 if (route) 300 if (route)
302 return route; 301 return route;
303 302
304 // Reset the URL path to '/' if the user navigates to a nonexistent URL. 303 // Reset the URL path to '/' if the user navigates to a nonexistent URL.
305 window.history.replaceState(undefined, '', Route.BASIC.path); 304 window.history.replaceState({}, '', Route.BASIC.path);
306 return Route.BASIC; 305 return Route.BASIC;
307 })(); 306 })();
308 307
309 /** 308 /**
309 * The current query parameters. This updated only by settings.navigateTo.
310 * @private {!Object}
stevenjb 2016/08/02 22:17:17 Can/should we type this?
tommycli 2016/08/02 22:46:34 Done. I changed it to use the URLSearchParams type
311 */
312 var currentQueryParameters_ = (function() {
313 if (window.location.search.length < 2)
314 return {};
315
316 var params = {};
317 window.location.search.substring(1).split('&').forEach(function(pair) {
Dan Beam 2016/08/02 21:44:50 OH NO YOU DI'NT https://developer.mozilla.org/en-
tommycli 2016/08/02 22:46:33 Thanks! I ended up using the URLSearchParams type
318 var [key, value] = pair.split('=').map(decodeURIComponent);
319 params[key] = value;
320 });
321 window.history.replaceState(params, '', currentRoute_.path);
322 return params;
323 })();
324
325 /**
310 * Helper function to set the current route and notify all observers. 326 * Helper function to set the current route and notify all observers.
311 * @param {!settings.Route} route 327 * @param {!settings.Route} route
328 * @param {!Object} queryParameters
312 */ 329 */
313 var setCurrentRoute = function(route) { 330 var setCurrentRoute = function(route, queryParameters) {
314 currentRoute_ = route; 331 currentRoute_ = route;
332 currentQueryParameters_ = queryParameters;
315 for (var observer of routeObservers_) 333 for (var observer of routeObservers_)
316 observer.currentRouteChanged(); 334 observer.currentRouteChanged();
317 }; 335 };
318 336
319 /** @return {!settings.Route} */ 337 /** @return {!settings.Route} */
320 var getCurrentRoute = function() { return currentRoute_; }; 338 var getCurrentRoute = function() { return currentRoute_; };
321 339
340 /** @return {!Object} */
341 var getQueryParameters = function() { return currentQueryParameters_; };
342
322 /** 343 /**
323 * Navigates to a canonical route and pushes a new history entry. 344 * Navigates to a canonical route and pushes a new history entry.
324 * @param {!settings.Route} route 345 * @param {!settings.Route} route
346 * @param {Object=} opt_dynamicParameters A new history entry is always pushed
347 * when this parameter is truthy, even when the parameters are unchanged.
325 * @private 348 * @private
326 */ 349 */
327 var navigateTo = function(route) { 350 var navigateTo = function(route, opt_dynamicParameters) {
328 if (assert(route) == currentRoute_) 351 if (assert(route) == currentRoute_ && !opt_dynamicParameters)
329 return; 352 return;
330 353
331 window.history.pushState(undefined, '', route.path); 354 var queryString = '';
332 setCurrentRoute(route); 355 if (opt_dynamicParameters) {
356 queryString = '?' + Object.keys(opt_dynamicParameters).map(function(key) {
357 var value = opt_dynamicParameters[key];
358 assert(typeof value == 'string',
359 'Non-string dynamic parameter values cannot be correctly ' +
360 'serialized and deserialized from the URL query string.');
361
362 return encodeURIComponent(key) + '=' + encodeURIComponent(value);
363 }).join('&');
364 }
365
366 setCurrentRoute(route, opt_dynamicParameters || {});
367 window.history.pushState(
368 currentQueryParameters_, '', route.path + queryString);
333 }; 369 };
334 370
335 window.addEventListener('popstate', function(event) { 371 window.addEventListener('popstate', function(event) {
336 // On pop state, do not push the state onto the window.history again. 372 // On pop state, do not push the state onto the window.history again.
337 setCurrentRoute(getRouteForPath(window.location.pathname) || Route.BASIC); 373 setCurrentRoute(getRouteForPath(window.location.pathname) || Route.BASIC,
374 event.state || {});
338 }); 375 });
339 376
340 return { 377 return {
341 Route: Route, 378 Route: Route,
342 RouteObserverBehavior: RouteObserverBehavior, 379 RouteObserverBehavior: RouteObserverBehavior,
343 getRouteForPath: getRouteForPath, 380 getRouteForPath: getRouteForPath,
344 getCurrentRoute: getCurrentRoute, 381 getCurrentRoute: getCurrentRoute,
382 getQueryParameters: getQueryParameters,
345 navigateTo: navigateTo, 383 navigateTo: navigateTo,
346 }; 384 };
347 }); 385 });
OLDNEW
« no previous file with comments | « no previous file | chrome/test/data/webui/settings/cr_settings_browsertest.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698