| OLD | NEW |
| 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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 */ | 246 */ |
| 247 var currentRoute_ = Route.BASIC; | 247 var currentRoute_ = Route.BASIC; |
| 248 | 248 |
| 249 /** | 249 /** |
| 250 * The current query parameters. This is updated only by settings.navigateTo | 250 * The current query parameters. This is updated only by settings.navigateTo |
| 251 * or settings.initializeRouteFromUrl. | 251 * or settings.initializeRouteFromUrl. |
| 252 * @private {!URLSearchParams} | 252 * @private {!URLSearchParams} |
| 253 */ | 253 */ |
| 254 var currentQueryParameters_ = new URLSearchParams(); | 254 var currentQueryParameters_ = new URLSearchParams(); |
| 255 | 255 |
| 256 /** @private {boolean} */ |
| 257 var lastRouteChangeWasPopstate_ = false; |
| 258 |
| 256 /** @private */ | 259 /** @private */ |
| 257 var initializeRouteFromUrlCalled_ = false; | 260 var initializeRouteFromUrlCalled_ = false; |
| 258 | 261 |
| 259 /** | 262 /** |
| 260 * Initialize the route and query params from the URL. | 263 * Initialize the route and query params from the URL. |
| 261 */ | 264 */ |
| 262 var initializeRouteFromUrl = function() { | 265 var initializeRouteFromUrl = function() { |
| 263 assert(!initializeRouteFromUrlCalled_); | 266 assert(!initializeRouteFromUrlCalled_); |
| 264 initializeRouteFromUrlCalled_ = true; | 267 initializeRouteFromUrlCalled_ = true; |
| 265 | 268 |
| 266 var route = getRouteForPath(window.location.pathname); | 269 var route = getRouteForPath(window.location.pathname); |
| 267 // Never allow direct navigation to ADVANCED. | 270 // Never allow direct navigation to ADVANCED. |
| 268 if (route && route != Route.ADVANCED) { | 271 if (route && route != Route.ADVANCED) { |
| 269 currentRoute_ = route; | 272 currentRoute_ = route; |
| 270 currentQueryParameters_ = new URLSearchParams(window.location.search); | 273 currentQueryParameters_ = new URLSearchParams(window.location.search); |
| 271 } else { | 274 } else { |
| 272 window.history.replaceState(undefined, '', Route.BASIC.path); | 275 window.history.replaceState(undefined, '', Route.BASIC.path); |
| 273 } | 276 } |
| 274 }; | 277 }; |
| 275 | 278 |
| 276 /** | 279 /** |
| 277 * Helper function to set the current route and notify all observers. | 280 * Helper function to set the current route and notify all observers. |
| 278 * @param {!settings.Route} route | 281 * @param {!settings.Route} route |
| 279 * @param {!URLSearchParams} queryParameters | 282 * @param {!URLSearchParams} queryParameters |
| 283 * @param {boolean} isPopstate |
| 280 */ | 284 */ |
| 281 var setCurrentRoute = function(route, queryParameters) { | 285 var setCurrentRoute = function(route, queryParameters, isPopstate) { |
| 282 var oldRoute = currentRoute_; | 286 var oldRoute = currentRoute_; |
| 283 currentRoute_ = route; | 287 currentRoute_ = route; |
| 284 currentQueryParameters_ = queryParameters; | 288 currentQueryParameters_ = queryParameters; |
| 289 lastRouteChangeWasPopstate_ = isPopstate; |
| 285 for (var observer of routeObservers_) | 290 for (var observer of routeObservers_) |
| 286 observer.currentRouteChanged(currentRoute_, oldRoute); | 291 observer.currentRouteChanged(currentRoute_, oldRoute); |
| 287 }; | 292 }; |
| 288 | 293 |
| 289 /** @return {!settings.Route} */ | 294 /** @return {!settings.Route} */ |
| 290 var getCurrentRoute = function() { return currentRoute_; }; | 295 var getCurrentRoute = function() { return currentRoute_; }; |
| 291 | 296 |
| 292 /** @return {!URLSearchParams} */ | 297 /** @return {!URLSearchParams} */ |
| 293 var getQueryParameters = function() { | 298 var getQueryParameters = function() { |
| 294 return new URLSearchParams(currentQueryParameters_); // Defensive copy. | 299 return new URLSearchParams(currentQueryParameters_); // Defensive copy. |
| 295 }; | 300 }; |
| 296 | 301 |
| 302 /** @return {boolean} */ |
| 303 var lastRouteChangeWasPopstate = function() { |
| 304 return lastRouteChangeWasPopstate_; |
| 305 }; |
| 306 |
| 297 /** | 307 /** |
| 298 * Navigates to a canonical route and pushes a new history entry. | 308 * Navigates to a canonical route and pushes a new history entry. |
| 299 * @param {!settings.Route} route | 309 * @param {!settings.Route} route |
| 300 * @param {URLSearchParams=} opt_dynamicParameters Navigations to the same | 310 * @param {URLSearchParams=} opt_dynamicParameters Navigations to the same |
| 301 * search parameters in a different order will still push to history. | 311 * search parameters in a different order will still push to history. |
| 302 */ | 312 */ |
| 303 var navigateTo = function(route, opt_dynamicParameters) { | 313 var navigateTo = function(route, opt_dynamicParameters) { |
| 304 var params = opt_dynamicParameters || new URLSearchParams(); | 314 var params = opt_dynamicParameters || new URLSearchParams(); |
| 305 | 315 |
| 306 var url = route.path; | 316 var url = route.path; |
| 307 if (opt_dynamicParameters) { | 317 if (opt_dynamicParameters) { |
| 308 var queryString = opt_dynamicParameters.toString(); | 318 var queryString = opt_dynamicParameters.toString(); |
| 309 if (queryString) | 319 if (queryString) |
| 310 url += '?' + queryString; | 320 url += '?' + queryString; |
| 311 } | 321 } |
| 312 | 322 |
| 313 // History serializes the state, so we don't push the actual route object. | 323 // History serializes the state, so we don't push the actual route object. |
| 314 window.history.pushState(currentRoute_.path, '', url); | 324 window.history.pushState(currentRoute_.path, '', url); |
| 315 setCurrentRoute(route, params); | 325 setCurrentRoute(route, params, false); |
| 316 }; | 326 }; |
| 317 | 327 |
| 318 /** | 328 /** |
| 319 * Navigates to the previous route if it has an equal or lesser depth. | 329 * Navigates to the previous route if it has an equal or lesser depth. |
| 320 * If there is no previous route in history meeting those requirements, | 330 * If there is no previous route in history meeting those requirements, |
| 321 * this navigates to the immediate parent. This will never exit Settings. | 331 * this navigates to the immediate parent. This will never exit Settings. |
| 322 */ | 332 */ |
| 323 var navigateToPreviousRoute = function() { | 333 var navigateToPreviousRoute = function() { |
| 324 var previousRoute = | 334 var previousRoute = |
| 325 window.history.state && | 335 window.history.state && |
| 326 assert(getRouteForPath(/** @type {string} */ (window.history.state))); | 336 assert(getRouteForPath(/** @type {string} */ (window.history.state))); |
| 327 | 337 |
| 328 if (previousRoute && previousRoute.depth <= currentRoute_.depth) | 338 if (previousRoute && previousRoute.depth <= currentRoute_.depth) |
| 329 window.history.back(); | 339 window.history.back(); |
| 330 else | 340 else |
| 331 navigateTo(currentRoute_.parent || Route.BASIC); | 341 navigateTo(currentRoute_.parent || Route.BASIC); |
| 332 }; | 342 }; |
| 333 | 343 |
| 334 window.addEventListener('popstate', function(event) { | 344 window.addEventListener('popstate', function(event) { |
| 335 // On pop state, do not push the state onto the window.history again. | 345 // On pop state, do not push the state onto the window.history again. |
| 336 setCurrentRoute(getRouteForPath(window.location.pathname) || Route.BASIC, | 346 setCurrentRoute(getRouteForPath(window.location.pathname) || Route.BASIC, |
| 337 new URLSearchParams(window.location.search)); | 347 new URLSearchParams(window.location.search), true); |
| 338 }); | 348 }); |
| 339 | 349 |
| 340 return { | 350 return { |
| 341 Route: Route, | 351 Route: Route, |
| 342 RouteObserverBehavior: RouteObserverBehavior, | 352 RouteObserverBehavior: RouteObserverBehavior, |
| 343 getRouteForPath: getRouteForPath, | 353 getRouteForPath: getRouteForPath, |
| 344 initializeRouteFromUrl: initializeRouteFromUrl, | 354 initializeRouteFromUrl: initializeRouteFromUrl, |
| 345 getCurrentRoute: getCurrentRoute, | 355 getCurrentRoute: getCurrentRoute, |
| 346 getQueryParameters: getQueryParameters, | 356 getQueryParameters: getQueryParameters, |
| 357 lastRouteChangeWasPopstate: lastRouteChangeWasPopstate, |
| 347 navigateTo: navigateTo, | 358 navigateTo: navigateTo, |
| 348 navigateToPreviousRoute: navigateToPreviousRoute, | 359 navigateToPreviousRoute: navigateToPreviousRoute, |
| 349 }; | 360 }; |
| 350 }); | 361 }); |
| OLD | NEW |