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

Unified Diff: chrome/browser/resources/settings/route.js

Issue 2957153003: MD Settings: remove unsupported routes from guest-mode. (Closed)
Patch Set: merge Created 3 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/settings/route.js
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js
index ed960c672ae377ef30a2f1d1afbd794f174f451c..02add787caae967d8494e4a4c21296a9e1eddfae 100644
--- a/chrome/browser/resources/settings/route.js
+++ b/chrome/browser/resources/settings/route.js
@@ -2,36 +2,124 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+/**
+ * Specifies all possible routes in settings.
+ *
+ * @typedef {{
+ * ABOUT: (undefined|!settings.Route),
+ * ABOUT_ABOUT: (undefined|!settings.Route),
+ * ACCESSIBILITY: (undefined|!settings.Route),
+ * ACCOUNTS: (undefined|!settings.Route),
+ * ADVANCED: (undefined|!settings.Route),
+ * ANDROID_APPS: (undefined|!settings.Route),
+ * ANDROID_APPS_DETAILS: (undefined|!settings.Route),
+ * APPEARANCE: (undefined|!settings.Route),
+ * AUTOFILL: (undefined|!settings.Route),
+ * BASIC: (undefined|!settings.Route),
+ * BLUETOOTH: (undefined|!settings.Route),
+ * BLUETOOTH_DEVICES: (undefined|!settings.Route),
+ * CERTIFICATES: (undefined|!settings.Route),
+ * CHANGE_PICTURE: (undefined|!settings.Route),
+ * CLEAR_BROWSER_DATA: (undefined|!settings.Route),
+ * CLOUD_PRINTERS: (undefined|!settings.Route),
+ * CUPS_PRINTER_DETAIL: (undefined|!settings.Route),
+ * CUPS_PRINTERS: (undefined|!settings.Route),
+ * DATETIME: (undefined|!settings.Route),
+ * DEFAULT_BROWSER: (undefined|!settings.Route),
+ * DETAILED_BUILD_INFO: (undefined|!settings.Route),
+ * DEVICE: (undefined|!settings.Route),
+ * DISPLAY: (undefined|!settings.Route),
+ * DOWNLOADS: (undefined|!settings.Route),
+ * EDIT_DICTIONARY: (undefined|!settings.Route),
+ * FINGERPRINT: (undefined|!settings.Route),
+ * FONTS: (undefined|!settings.Route),
+ * IMPORT_DATA: (undefined|!settings.Route),
+ * INPUT_METHODS: (undefined|!settings.Route),
+ * INTERNET: (undefined|!settings.Route),
+ * INTERNET_NETWORKS: (undefined|!settings.Route),
+ * KEYBOARD: (undefined|!settings.Route),
+ * KNOWN_NETWORKS: (undefined|!settings.Route),
+ * LANGUAGES: (undefined|!settings.Route),
+ * LOCK_SCREEN: (undefined|!settings.Route),
+ * MANAGE_ACCESSIBILITY: (undefined|!settings.Route),
+ * MANAGE_PASSWORDS: (undefined|!settings.Route),
+ * MANAGE_PROFILE: (undefined|!settings.Route),
+ * NETWORK_CONFIG: (undefined|!settings.Route),
+ * NETWORK_DETAIL: (undefined|!settings.Route),
+ * ON_STARTUP: (undefined|!settings.Route),
+ * PASSWORDS: (undefined|!settings.Route),
+ * PEOPLE: (undefined|!settings.Route),
+ * POINTERS: (undefined|!settings.Route),
+ * POWER: (undefined|!settings.Route),
+ * PRINTING: (undefined|!settings.Route),
+ * PRIVACY: (undefined|!settings.Route),
+ * RESET: (undefined|!settings.Route),
+ * RESET_DIALOG: (undefined|!settings.Route),
+ * SEARCH: (undefined|!settings.Route),
+ * SEARCH_ENGINES: (undefined|!settings.Route),
+ * SIGN_OUT: (undefined|!settings.Route),
+ * SITE_SETTINGS: (undefined|!settings.Route),
+ * SITE_SETTINGS_ADS: (undefined|!settings.Route),
+ * SITE_SETTINGS_ALL: (undefined|!settings.Route),
+ * SITE_SETTINGS_AUTOMATIC_DOWNLOADS: (undefined|!settings.Route),
+ * SITE_SETTINGS_BACKGROUND_SYNC: (undefined|!settings.Route),
+ * SITE_SETTINGS_CAMERA: (undefined|!settings.Route),
+ * SITE_SETTINGS_COOKIES: (undefined|!settings.Route),
+ * SITE_SETTINGS_DATA_DETAILS: (undefined|!settings.Route),
+ * SITE_SETTINGS_FLASH: (undefined|!settings.Route),
+ * SITE_SETTINGS_HANDLERS: (undefined|!settings.Route),
+ * SITE_SETTINGS_IMAGES: (undefined|!settings.Route),
+ * SITE_SETTINGS_JAVASCRIPT: (undefined|!settings.Route),
+ * SITE_SETTINGS_LOCATION: (undefined|!settings.Route),
+ * SITE_SETTINGS_MICROPHONE: (undefined|!settings.Route),
+ * SITE_SETTINGS_MIDI_DEVICES: (undefined|!settings.Route),
+ * SITE_SETTINGS_NOTIFICATIONS: (undefined|!settings.Route),
+ * SITE_SETTINGS_PDF_DOCUMENTS: (undefined|!settings.Route),
+ * SITE_SETTINGS_POPUPS: (undefined|!settings.Route),
+ * SITE_SETTINGS_PROTECTED_CONTENT: (undefined|!settings.Route),
+ * SITE_SETTINGS_SITE_DETAILS: (undefined|!settings.Route),
+ * SITE_SETTINGS_UNSANDBOXED_PLUGINS: (undefined|!settings.Route),
+ * SITE_SETTINGS_USB_DEVICES: (undefined|!settings.Route),
+ * SITE_SETTINGS_ZOOM_LEVELS: (undefined|!settings.Route),
+ * STORAGE: (undefined|!settings.Route),
+ * STYLUS: (undefined|!settings.Route),
+ * SYNC: (undefined|!settings.Route),
+ * SYSTEM: (undefined|!settings.Route),
+ * TRIGGERED_RESET_DIALOG: (undefined|!settings.Route),
+ * }}
+ */
+var SettingsRoutes;
+
cr.define('settings', function() {
+
/**
* Class for navigable routes. May only be instantiated within this file.
- * @constructor
- * @param {string} path
- * @private
*/
- var Route = function(path) {
- this.path = path;
+ class Route {
+ /** @param {string} path */
+ constructor(path) {
+ /** @type {string} */
+ this.path = path;
- /** @type {?settings.Route} */
- this.parent = null;
+ /** @type {?settings.Route} */
+ this.parent = null;
- /** @type {number} */
- this.depth = 0;
+ /** @type {number} */
+ this.depth = 0;
- /**
- * @type {boolean} Whether this route corresponds to a navigable
- * dialog. Those routes don't belong to a "section".
- */
- this.isNavigableDialog = false;
+ /**
+ * @type {boolean} Whether this route corresponds to a navigable
+ * dialog. Those routes don't belong to a "section".
+ */
+ this.isNavigableDialog = false;
- // Below are all legacy properties to provide compatibility with the old
- // routing system.
+ // Below are all legacy properties to provide compatibility with the old
+ // routing system.
- /** @type {string} */
- this.section = '';
- };
+ /** @type {string} */
+ this.section = '';
+ }
- Route.prototype = {
/**
* Returns a new Route instance that's a child of this route.
* @param {string} path Extends this route's path if it doesn't contain a
@@ -39,7 +127,7 @@ cr.define('settings', function() {
* @return {!settings.Route}
* @private
*/
- createChild: function(path) {
+ createChild(path) {
assert(path);
// |path| extends this route's path if it doesn't have a leading slash.
@@ -52,7 +140,7 @@ cr.define('settings', function() {
route.depth = this.depth + 1;
return route;
- },
+ }
/**
* Returns a new Route instance that's a child section of this route.
@@ -62,189 +150,398 @@ cr.define('settings', function() {
* @return {!settings.Route}
* @private
*/
- createSection: function(path, section) {
+ createSection(path, section) {
var route = this.createChild(path);
route.section = section;
return route;
- },
+ }
/**
* Returns true if this route matches or is an ancestor of the parameter.
* @param {!settings.Route} route
* @return {boolean}
*/
- contains: function(route) {
+ contains(route) {
for (var r = route; r != null; r = r.parent) {
if (this == r)
return true;
}
return false;
- },
+ }
/**
* Returns true if this route is a subpage of a section.
* @return {boolean}
*/
- isSubpage: function() {
+ isSubpage() {
return !!this.parent && !!this.section &&
this.parent.section == this.section;
- },
+ }
+ }
+
+ /**
+ * Computes and return all available routes based on settings.pageVisibility.
+ * @return {!SettingsRoutes}
+ */
+ var computeAvailableRoutes = function() {
+ var pageVisibility = settings.pageVisibility || {};
+
+ /** @type {!SettingsRoutes} */
+ var r = {};
+
+ // Root pages.
+ r.BASIC = new Route('/');
+ r.ABOUT = new Route('/help');
+
+ // Navigable dialogs. These are the only non-section children of root
+ // pages. These are disfavored. If we add anymore, we should add explicit
+ // support.
+ r.IMPORT_DATA = r.BASIC.createChild('/importData');
+ r.IMPORT_DATA.isNavigableDialog = true;
+ r.SIGN_OUT = r.BASIC.createChild('/signOut');
+ r.SIGN_OUT.isNavigableDialog = true;
+
+ // <if expr="chromeos">
+ r.INTERNET = r.BASIC.createSection('/internet', 'internet');
+ r.INTERNET_NETWORKS = r.INTERNET.createChild('/networks');
+ r.NETWORK_CONFIG = r.INTERNET.createChild('/networkConfig');
+ r.NETWORK_DETAIL = r.INTERNET.createChild('/networkDetail');
+ r.KNOWN_NETWORKS = r.INTERNET.createChild('/knownNetworks');
+ r.BLUETOOTH = r.BASIC.createSection('/bluetooth', 'bluetooth');
+ r.BLUETOOTH_DEVICES = r.BLUETOOTH.createChild('/bluetoothDevices');
+ // </if>
+
+ if (pageVisibility.appearance !== false) {
+ r.APPEARANCE = r.BASIC.createSection('/appearance', 'appearance');
+ r.FONTS = r.APPEARANCE.createChild('/fonts');
+ }
+
+ if (pageVisibility.defaultBrowser !== false) {
+ r.DEFAULT_BROWSER =
+ r.BASIC.createSection('/defaultBrowser', 'defaultBrowser');
+ }
+
+ r.SEARCH = r.BASIC.createSection('/search', 'search');
+ r.SEARCH_ENGINES = r.SEARCH.createChild('/searchEngines');
+
+ // <if expr="chromeos">
+ r.ANDROID_APPS = r.BASIC.createSection('/androidApps', 'androidApps');
+ r.ANDROID_APPS_DETAILS = r.ANDROID_APPS.createChild('/androidApps/details');
+ // </if>
+
+ if (pageVisibility.onStartup !== false) {
+ r.ON_STARTUP = r.BASIC.createSection('/onStartup', 'onStartup');
+ r.STARTUP_URLS = r.ON_STARTUP.createChild('/startupUrls');
+ }
+
+ if (pageVisibility.people !== false) {
+ r.PEOPLE = r.BASIC.createSection('/people', 'people');
+ r.SYNC = r.PEOPLE.createChild('/syncSetup');
+ // <if expr="not chromeos">
+ r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile');
+ // </if>
+ // <if expr="chromeos">
+ r.CHANGE_PICTURE = r.PEOPLE.createChild('/changePicture');
+ r.ACCOUNTS = r.PEOPLE.createChild('/accounts');
+ r.LOCK_SCREEN = r.PEOPLE.createChild('/lockScreen');
+ r.FINGERPRINT = r.LOCK_SCREEN.createChild('/lockScreen/fingerprint');
+ // </if>
+ }
+
+ // <if expr="chromeos">
+ r.DEVICE = r.BASIC.createSection('/device', 'device');
+ r.POINTERS = r.DEVICE.createChild('/pointer-overlay');
+ r.KEYBOARD = r.DEVICE.createChild('/keyboard-overlay');
+ r.STYLUS = r.DEVICE.createChild('/stylus');
+ r.DISPLAY = r.DEVICE.createChild('/display');
+ r.STORAGE = r.DEVICE.createChild('/storage');
+ r.POWER = r.DEVICE.createChild('/power');
+ // </if>
+
+ // Advacned Routes
+ if (pageVisibility.advancedSettings !== false) {
+ r.ADVANCED = new Route('/advanced');
+
+ r.CLEAR_BROWSER_DATA = r.ADVANCED.createChild('/clearBrowserData');
+ r.CLEAR_BROWSER_DATA.isNavigableDialog = true;
+
+ if (pageVisibility.privacy !== false) {
+ r.PRIVACY = r.ADVANCED.createSection('/privacy', 'privacy');
+ r.CERTIFICATES = r.PRIVACY.createChild('/certificates');
+ r.SITE_SETTINGS = r.PRIVACY.createChild('/content');
+ }
+
+ if (loadTimeData.getBoolean('enableSiteSettings')) {
+ r.SITE_SETTINGS_ALL = r.SITE_SETTINGS.createChild('all');
+ r.SITE_SETTINGS_SITE_DETAILS =
+ r.SITE_SETTINGS_ALL.createChild('/content/siteDetails');
+ } else if (loadTimeData.getBoolean('enableSiteDetails')) {
+ // When there is no "All Sites", pressing 'back' from "Site Details"
+ // should return to "Content Settings". This should only occur when
+ // |kSiteSettings| is off and |kSiteDetails| is on.
+ r.SITE_SETTINGS_SITE_DETAILS =
+ r.SITE_SETTINGS.createChild('/content/siteDetails');
+ }
+
+ r.SITE_SETTINGS_HANDLERS = r.SITE_SETTINGS.createChild('/handlers');
+
+ // TODO(tommycli): Find a way to refactor these repetitive category
+ // routes.
+ r.SITE_SETTINGS_ADS = r.SITE_SETTINGS.createChild('ads');
+ r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS =
+ r.SITE_SETTINGS.createChild('automaticDownloads');
+ r.SITE_SETTINGS_BACKGROUND_SYNC =
+ r.SITE_SETTINGS.createChild('backgroundSync');
+ r.SITE_SETTINGS_CAMERA = r.SITE_SETTINGS.createChild('camera');
+ r.SITE_SETTINGS_COOKIES = r.SITE_SETTINGS.createChild('cookies');
+ r.SITE_SETTINGS_DATA_DETAILS =
+ r.SITE_SETTINGS_COOKIES.createChild('/cookies/detail');
+ r.SITE_SETTINGS_IMAGES = r.SITE_SETTINGS.createChild('images');
+ r.SITE_SETTINGS_JAVASCRIPT = r.SITE_SETTINGS.createChild('javascript');
+ r.SITE_SETTINGS_LOCATION = r.SITE_SETTINGS.createChild('location');
+ r.SITE_SETTINGS_MICROPHONE = r.SITE_SETTINGS.createChild('microphone');
+ r.SITE_SETTINGS_NOTIFICATIONS =
+ r.SITE_SETTINGS.createChild('notifications');
+ r.SITE_SETTINGS_FLASH = r.SITE_SETTINGS.createChild('flash');
+ r.SITE_SETTINGS_POPUPS = r.SITE_SETTINGS.createChild('popups');
+ r.SITE_SETTINGS_UNSANDBOXED_PLUGINS =
+ r.SITE_SETTINGS.createChild('unsandboxedPlugins');
+ r.SITE_SETTINGS_MIDI_DEVICES = r.SITE_SETTINGS.createChild('midiDevices');
+ r.SITE_SETTINGS_USB_DEVICES = r.SITE_SETTINGS.createChild('usbDevices');
+ r.SITE_SETTINGS_ZOOM_LEVELS = r.SITE_SETTINGS.createChild('zoomLevels');
+ r.SITE_SETTINGS_PDF_DOCUMENTS =
+ r.SITE_SETTINGS.createChild('pdfDocuments');
+ r.SITE_SETTINGS_PROTECTED_CONTENT =
+ r.SITE_SETTINGS.createChild('protectedContent');
+
+ // <if expr="chromeos">
+ if (pageVisibility.dateTime !== false) {
+ r.DATETIME = r.ADVANCED.createSection('/dateTime', 'dateTime');
+ }
+ // </if>
+
+ if (pageVisibility.passwordsAndForms !== false) {
+ r.PASSWORDS =
+ r.ADVANCED.createSection('/passwordsAndForms', 'passwordsAndForms');
+ r.AUTOFILL = r.PASSWORDS.createChild('/autofill');
+ r.MANAGE_PASSWORDS = r.PASSWORDS.createChild('/passwords');
+ }
+
+ r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages');
+ // <if expr="chromeos">
+ r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods');
+ // </if>
+ // <if expr="not is_macosx">
+ r.EDIT_DICTIONARY = r.LANGUAGES.createChild('/editDictionary');
+ // </if>
+
+ if (pageVisibility.downloads !== false) {
+ r.DOWNLOADS = r.ADVANCED.createSection('/downloads', 'downloads');
+ }
+
+ r.PRINTING = r.ADVANCED.createSection('/printing', 'printing');
+ r.CLOUD_PRINTERS = r.PRINTING.createChild('/cloudPrinters');
+ // <if expr="chromeos">
+ r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters');
+ r.CUPS_PRINTER_DETAIL =
+ r.CUPS_PRINTERS.createChild('/cupsPrinterDetails');
+ // </if>
+
+ r.ACCESSIBILITY = r.ADVANCED.createSection('/accessibility', 'a11y');
+ // <if expr="chromeos">
+ r.MANAGE_ACCESSIBILITY =
+ r.ACCESSIBILITY.createChild('/manageAccessibility');
+ // </if>
+
+ r.SYSTEM = r.ADVANCED.createSection('/system', 'system');
+
+ if (pageVisibility.reset !== false) {
+ r.RESET = r.ADVANCED.createSection('/reset', 'reset');
+ r.RESET_DIALOG = r.ADVANCED.createChild('/resetProfileSettings');
+ r.RESET_DIALOG.isNavigableDialog = true;
+ r.TRIGGERED_RESET_DIALOG =
+ r.ADVANCED.createChild('/triggeredResetProfileSettings');
+ r.TRIGGERED_RESET_DIALOG.isNavigableDialog = true;
+ }
+ }
+
+ // <if expr="chromeos">
+ // "About" is the only section in About, but we still need to create the
+ // route in order to show the subpage on Chrome OS.
+ r.ABOUT_ABOUT = r.ABOUT.createSection('/help/about', 'about');
+ r.DETAILED_BUILD_INFO = r.ABOUT_ABOUT.createChild('/help/details');
+ // </if>
+
+ return r;
};
- // Abbreviated variable for easier definitions.
- var r = Route;
-
- // Root pages.
- r.BASIC = new Route('/');
- r.ADVANCED = new Route('/advanced');
- r.ABOUT = new Route('/help');
-
- // Navigable dialogs. These are the only non-section children of root pages.
- // These are disfavored. If we add anymore, we should add explicit support.
- r.IMPORT_DATA = r.BASIC.createChild('/importData');
- r.IMPORT_DATA.isNavigableDialog = true;
- r.SIGN_OUT = r.BASIC.createChild('/signOut');
- r.SIGN_OUT.isNavigableDialog = true;
- r.CLEAR_BROWSER_DATA = r.ADVANCED.createChild('/clearBrowserData');
- r.CLEAR_BROWSER_DATA.isNavigableDialog = true;
- r.RESET_DIALOG = r.ADVANCED.createChild('/resetProfileSettings');
- r.RESET_DIALOG.isNavigableDialog = true;
- r.TRIGGERED_RESET_DIALOG =
- r.ADVANCED.createChild('/triggeredResetProfileSettings');
- r.TRIGGERED_RESET_DIALOG.isNavigableDialog = true;
-
- // <if expr="chromeos">
- r.INTERNET = r.BASIC.createSection('/internet', 'internet');
- r.INTERNET_NETWORKS = r.INTERNET.createChild('/networks');
- r.NETWORK_CONFIG = r.INTERNET.createChild('/networkConfig');
- r.NETWORK_DETAIL = r.INTERNET.createChild('/networkDetail');
- r.KNOWN_NETWORKS = r.INTERNET.createChild('/knownNetworks');
- r.BLUETOOTH = r.BASIC.createSection('/bluetooth', 'bluetooth');
- r.BLUETOOTH_DEVICES = r.BLUETOOTH.createChild('/bluetoothDevices');
- // </if>
-
- r.APPEARANCE = r.BASIC.createSection('/appearance', 'appearance');
- r.FONTS = r.APPEARANCE.createChild('/fonts');
-
- r.DEFAULT_BROWSER =
- r.BASIC.createSection('/defaultBrowser', 'defaultBrowser');
-
- r.SEARCH = r.BASIC.createSection('/search', 'search');
- r.SEARCH_ENGINES = r.SEARCH.createChild('/searchEngines');
-
- // <if expr="chromeos">
- r.ANDROID_APPS = r.BASIC.createSection('/androidApps', 'androidApps');
- r.ANDROID_APPS_DETAILS = r.ANDROID_APPS.createChild('/androidApps/details');
- // </if>
-
- r.ON_STARTUP = r.BASIC.createSection('/onStartup', 'onStartup');
- r.STARTUP_URLS = r.ON_STARTUP.createChild('/startupUrls');
-
- r.PEOPLE = r.BASIC.createSection('/people', 'people');
- r.SYNC = r.PEOPLE.createChild('/syncSetup');
- // <if expr="not chromeos">
- r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile');
- // </if>
- // <if expr="chromeos">
- r.CHANGE_PICTURE = r.PEOPLE.createChild('/changePicture');
- r.ACCOUNTS = r.PEOPLE.createChild('/accounts');
- r.LOCK_SCREEN = r.PEOPLE.createChild('/lockScreen');
- r.FINGERPRINT = r.LOCK_SCREEN.createChild('/lockScreen/fingerprint');
-
- r.DEVICE = r.BASIC.createSection('/device', 'device');
- r.POINTERS = r.DEVICE.createChild('/pointer-overlay');
- r.KEYBOARD = r.DEVICE.createChild('/keyboard-overlay');
- r.STYLUS = r.DEVICE.createChild('/stylus');
- r.DISPLAY = r.DEVICE.createChild('/display');
- r.STORAGE = r.DEVICE.createChild('/storage');
- r.POWER = r.DEVICE.createChild('/power');
- // </if>
-
- r.PRIVACY = r.ADVANCED.createSection('/privacy', 'privacy');
- r.CERTIFICATES = r.PRIVACY.createChild('/certificates');
-
- r.SITE_SETTINGS = r.PRIVACY.createChild('/content');
-
- if (loadTimeData.getBoolean('enableSiteSettings')) {
- r.SITE_SETTINGS_ALL = r.SITE_SETTINGS.createChild('all');
- r.SITE_SETTINGS_SITE_DETAILS =
- r.SITE_SETTINGS_ALL.createChild('/content/siteDetails');
- } else if (loadTimeData.getBoolean('enableSiteDetails')) {
- // When there is no "All Sites", pressing 'back' from "Site Details" should
- // return to "Content Settings". This should only occur when |kSiteSettings|
- // is off and |kSiteDetails| is on.
- r.SITE_SETTINGS_SITE_DETAILS =
- r.SITE_SETTINGS.createChild('/content/siteDetails');
+ class Router {
+ constructor() {
+ /**
+ * List of available routes. This is populated taking into account current
+ * state (like guest mode).
+ * @private {!SettingsRoutes}
+ */
+ this.routes_ = computeAvailableRoutes();
+
+ /**
+ * The current active route. This updated is only by settings.navigateTo
+ * or settings.initializeRouteFromUrl.
+ * @type {!settings.Route}
+ */
+ this.currentRoute = /** @type {!settings.Route} */ (this.routes_.BASIC);
+
+ /**
+ * The current query parameters. This is updated only by
+ * settings.navigateTo or settings.initializeRouteFromUrl.
+ * @private {!URLSearchParams}
+ */
+ this.currentQueryParameters_ = new URLSearchParams();
+
+ /** @private {boolean} */
+ this.wasLastRouteChangePopstate_ = false;
+
+ /** @private {boolean}*/
+ this.initializeRouteFromUrlCalled_ = false;
+ }
+
+ /** @return {settings.Route} */
+ getRoute(routeName) {
+ return this.routes_[routeName];
+ }
+
+ /** @return {!SettingsRoutes} */
+ getRoutes() {
+ return this.routes_;
+ }
+
+ /**
+ * Helper function to set the current route and notify all observers.
+ * @param {!settings.Route} route
+ * @param {!URLSearchParams} queryParameters
+ * @param {boolean} isPopstate
+ */
+ setCurrentRoute(route, queryParameters, isPopstate) {
+ var oldRoute = this.currentRoute;
+ this.currentRoute = route;
+ this.currentQueryParameters_ = queryParameters;
+ this.wasLastRouteChangePopstate_ = isPopstate;
+ routeObservers.forEach(function(observer) {
+ observer.currentRouteChanged(this.currentRoute, oldRoute);
+ }.bind(this));
+ }
+
+ /** @return {!settings.Route} */
+ getCurrentRoute() {
+ return this.currentRoute;
+ }
+
+ /** @return {!URLSearchParams} */
+ getQueryParameters() {
+ return new URLSearchParams(
+ this.currentQueryParameters_); // Defensive copy.
+ }
+
+ /** @return {boolean} */
+ lastRouteChangeWasPopstate() {
+ return this.wasLastRouteChangePopstate_;
+ }
+
+ /**
+ * @param {string} path
+ * @return {?settings.Route} The matching canonical route, or null if none
+ * matches.
+ */
+ getRouteForPath(path) {
+ // Allow trailing slash in paths.
+ var canonicalPath = path.replace(CANONICAL_PATH_REGEX, '$1$2');
+
+ // TODO(tommycli): Use Object.values once Closure compilation supports it.
+ var matchingKey = Object.keys(this.routes_).find(function(key) {
+ return this.routes_[key].path == canonicalPath;
+ }.bind(this));
+
+ return !!matchingKey ? this.routes_[matchingKey] : null;
+ }
+
+ /**
+ * Navigates to a canonical route and pushes a new history entry.
+ * @param {!settings.Route} route
+ * @param {URLSearchParams=} opt_dynamicParameters Navigations to the same
+ * URL parameters in a different order will still push to history.
+ * @param {boolean=} opt_removeSearch Whether to strip the 'search' URL
+ * parameter during navigation. Defaults to false.
+ */
+ navigateTo(route, opt_dynamicParameters, opt_removeSearch) {
+ // The ADVANCED route only serves as a parent of subpages, and should not
+ // be possible to navigate to it directly.
+ if (route == this.routes_.ADVANCED)
+ route = /** @type {!settings.Route} */ (this.routes_.BASIC);
+
+ var params = opt_dynamicParameters || new URLSearchParams();
+ var removeSearch = !!opt_removeSearch;
+
+ var oldSearchParam = this.getQueryParameters().get('search') || '';
+ var newSearchParam = params.get('search') || '';
+
+ if (!removeSearch && oldSearchParam && !newSearchParam)
+ params.append('search', oldSearchParam);
+
+ var url = route.path;
+ var queryString = params.toString();
+ if (queryString)
+ url += '?' + queryString;
+
+ // History serializes the state, so we don't push the actual route object.
+ window.history.pushState(this.currentRoute.path, '', url);
+ this.setCurrentRoute(route, params, false);
+ }
+
+ /**
+ * Navigates to the previous route if it has an equal or lesser depth.
+ * If there is no previous route in history meeting those requirements,
+ * this navigates to the immediate parent. This will never exit Settings.
+ */
+ navigateToPreviousRoute() {
+ var previousRoute = window.history.state &&
+ assert(this.getRouteForPath(
+ /** @type {string} */ (window.history.state)));
+
+ if (previousRoute && previousRoute.depth <= this.currentRoute.depth)
+ window.history.back();
+ else
+ this.navigateTo(
+ this.currentRoute.parent ||
+ /** @type {!settings.Route} */ (this.routes_.BASIC));
+ }
+
+ /**
+ * Initialize the route and query params from the URL.
+ */
+ initializeRouteFromUrl() {
+ assert(!this.initializeRouteFromUrlCalled_);
+ this.initializeRouteFromUrlCalled_ = true;
+
+ var route = this.getRouteForPath(window.location.pathname);
+ // Never allow direct navigation to ADVANCED.
+ if (route && route != this.routes_.ADVANCED) {
+ this.currentRoute = route;
+ this.currentQueryParameters_ =
+ new URLSearchParams(window.location.search);
+ } else {
+ window.history.replaceState(undefined, '', this.routes_.BASIC.path);
+ }
+ }
+
+ resetRouteForTesting() {
+ this.initializeRouteFromUrlCalled_ = false;
+ this.wasLastRouteChangePopstate_ = false;
+ this.currentRoute = /** @type {!settings.Route} */ (this.routes_.BASIC);
+ this.currentQueryParameters_ = new URLSearchParams();
+ }
}
- r.SITE_SETTINGS_HANDLERS = r.SITE_SETTINGS.createChild('/handlers');
-
- // TODO(tommycli): Find a way to refactor these repetitive category routes.
- r.SITE_SETTINGS_ADS = r.SITE_SETTINGS.createChild('ads');
- r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS =
- r.SITE_SETTINGS.createChild('automaticDownloads');
- r.SITE_SETTINGS_BACKGROUND_SYNC =
- r.SITE_SETTINGS.createChild('backgroundSync');
- r.SITE_SETTINGS_CAMERA = r.SITE_SETTINGS.createChild('camera');
- r.SITE_SETTINGS_COOKIES = r.SITE_SETTINGS.createChild('cookies');
- r.SITE_SETTINGS_DATA_DETAILS =
- r.SITE_SETTINGS_COOKIES.createChild('/cookies/detail');
- r.SITE_SETTINGS_IMAGES = r.SITE_SETTINGS.createChild('images');
- r.SITE_SETTINGS_JAVASCRIPT = r.SITE_SETTINGS.createChild('javascript');
- r.SITE_SETTINGS_LOCATION = r.SITE_SETTINGS.createChild('location');
- r.SITE_SETTINGS_MICROPHONE = r.SITE_SETTINGS.createChild('microphone');
- r.SITE_SETTINGS_NOTIFICATIONS = r.SITE_SETTINGS.createChild('notifications');
- r.SITE_SETTINGS_FLASH = r.SITE_SETTINGS.createChild('flash');
- r.SITE_SETTINGS_POPUPS = r.SITE_SETTINGS.createChild('popups');
- r.SITE_SETTINGS_UNSANDBOXED_PLUGINS =
- r.SITE_SETTINGS.createChild('unsandboxedPlugins');
- r.SITE_SETTINGS_MIDI_DEVICES = r.SITE_SETTINGS.createChild('midiDevices');
- r.SITE_SETTINGS_USB_DEVICES = r.SITE_SETTINGS.createChild('usbDevices');
- r.SITE_SETTINGS_ZOOM_LEVELS = r.SITE_SETTINGS.createChild('zoomLevels');
- r.SITE_SETTINGS_PDF_DOCUMENTS = r.SITE_SETTINGS.createChild('pdfDocuments');
- r.SITE_SETTINGS_PROTECTED_CONTENT =
- r.SITE_SETTINGS.createChild('protectedContent');
-
- // <if expr="chromeos">
- r.DATETIME = r.ADVANCED.createSection('/dateTime', 'dateTime');
- // </if>
-
- r.PASSWORDS =
- r.ADVANCED.createSection('/passwordsAndForms', 'passwordsAndForms');
- r.AUTOFILL = r.PASSWORDS.createChild('/autofill');
- r.MANAGE_PASSWORDS = r.PASSWORDS.createChild('/passwords');
-
- r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages');
- // <if expr="chromeos">
- r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods');
- // </if>
- // <if expr="not is_macosx">
- r.EDIT_DICTIONARY = r.LANGUAGES.createChild('/editDictionary');
- // </if>
-
- r.DOWNLOADS = r.ADVANCED.createSection('/downloads', 'downloads');
-
- r.PRINTING = r.ADVANCED.createSection('/printing', 'printing');
- r.CLOUD_PRINTERS = r.PRINTING.createChild('/cloudPrinters');
- // <if expr="chromeos">
- r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters');
- r.CUPS_PRINTER_DETAIL = r.CUPS_PRINTERS.createChild('/cupsPrinterDetails');
- // </if>
-
- r.ACCESSIBILITY = r.ADVANCED.createSection('/accessibility', 'a11y');
- // <if expr="chromeos">
- r.MANAGE_ACCESSIBILITY = r.ACCESSIBILITY.createChild('/manageAccessibility');
- // </if>
-
- r.SYSTEM = r.ADVANCED.createSection('/system', 'system');
- r.RESET = r.ADVANCED.createSection('/reset', 'reset');
-
- // <if expr="chromeos">
- // "About" is the only section in About, but we still need to create the route
- // in order to show the subpage on Chrome OS.
- r.ABOUT_ABOUT = r.ABOUT.createSection('/help/about', 'about');
- r.DETAILED_BUILD_INFO = r.ABOUT_ABOUT.createChild('/help/details');
- // </if>
+ var routerInstance = new Router();
var routeObservers = new Set();
@@ -257,7 +554,7 @@ cr.define('settings', function() {
// Emulating Polymer data bindings, the observer is called when the
// element starts observing the route.
- this.currentRouteChanged(currentRoute, undefined);
+ this.currentRouteChanged(routerInstance.currentRoute, undefined);
},
/** @override */
@@ -282,155 +579,40 @@ cr.define('settings', function() {
*/
var CANONICAL_PATH_REGEX = /(^\/)([\/-\w]+)(\/$)/;
- /**
- * @param {string} path
- * @return {?settings.Route} The matching canonical route, or null if none
- * matches.
- */
- var getRouteForPath = function(path) {
- // Allow trailing slash in paths.
- var canonicalPath = path.replace(CANONICAL_PATH_REGEX, '$1$2');
-
- // TODO(tommycli): Use Object.values once Closure compilation supports it.
- var matchingKey = Object.keys(Route).find(function(key) {
- return Route[key].path == canonicalPath;
- });
-
- return !!matchingKey ? Route[matchingKey] : null;
- };
-
- /**
- * The current active route. This updated is only by settings.navigateTo or
- * settings.initializeRouteFromUrl.
- * @private {!settings.Route}
- */
- var currentRoute = Route.BASIC;
-
- /**
- * The current query parameters. This is updated only by settings.navigateTo
- * or settings.initializeRouteFromUrl.
- * @private {!URLSearchParams}
- */
- var currentQueryParameters = new URLSearchParams();
-
- /** @private {boolean} */
- var wasLastRouteChangePopstate = false;
-
- /** @private */
- var initializeRouteFromUrlCalled = false;
-
- /**
- * Initialize the route and query params from the URL.
- */
- var initializeRouteFromUrl = function() {
- assert(!initializeRouteFromUrlCalled);
- initializeRouteFromUrlCalled = true;
-
- var route = getRouteForPath(window.location.pathname);
- // Never allow direct navigation to ADVANCED.
- if (route && route != Route.ADVANCED) {
- currentRoute = route;
- currentQueryParameters = new URLSearchParams(window.location.search);
- } else {
- window.history.replaceState(undefined, '', Route.BASIC.path);
- }
- };
-
- function resetRouteForTesting() {
- initializeRouteFromUrlCalled = false;
- wasLastRouteChangePopstate = false;
- currentRoute = Route.BASIC;
- currentQueryParameters = new URLSearchParams();
- }
-
- /**
- * Helper function to set the current route and notify all observers.
- * @param {!settings.Route} route
- * @param {!URLSearchParams} queryParameters
- * @param {boolean} isPopstate
- */
- var setCurrentRoute = function(route, queryParameters, isPopstate) {
- var oldRoute = currentRoute;
- currentRoute = route;
- currentQueryParameters = queryParameters;
- wasLastRouteChangePopstate = isPopstate;
- routeObservers.forEach(function(observer) {
- observer.currentRouteChanged(currentRoute, oldRoute);
- });
- };
-
- /** @return {!settings.Route} */
- var getCurrentRoute = function() {
- return currentRoute;
- };
-
- /** @return {!URLSearchParams} */
- var getQueryParameters = function() {
- return new URLSearchParams(currentQueryParameters); // Defensive copy.
- };
-
- /** @return {boolean} */
- var lastRouteChangeWasPopstate = function() {
- return wasLastRouteChangePopstate;
- };
-
- /**
- * Navigates to a canonical route and pushes a new history entry.
- * @param {!settings.Route} route
- * @param {URLSearchParams=} opt_dynamicParameters Navigations to the same
- * URL parameters in a different order will still push to history.
- * @param {boolean=} opt_removeSearch Whether to strip the 'search' URL
- * parameter during navigation. Defaults to false.
- */
- var navigateTo = function(route, opt_dynamicParameters, opt_removeSearch) {
- // The ADVANCED route only serves as a parent of subpages, and should not
- // be possible to navigate to it directly.
- if (route == settings.Route.ADVANCED)
- route = settings.Route.BASIC;
-
- var params = opt_dynamicParameters || new URLSearchParams();
- var removeSearch = !!opt_removeSearch;
-
- var oldSearchParam = getQueryParameters().get('search') || '';
- var newSearchParam = params.get('search') || '';
-
- if (!removeSearch && oldSearchParam && !newSearchParam)
- params.append('search', oldSearchParam);
-
- var url = route.path;
- var queryString = params.toString();
- if (queryString)
- url += '?' + queryString;
-
- // History serializes the state, so we don't push the actual route object.
- window.history.pushState(currentRoute.path, '', url);
- setCurrentRoute(route, params, false);
- };
-
- /**
- * Navigates to the previous route if it has an equal or lesser depth.
- * If there is no previous route in history meeting those requirements,
- * this navigates to the immediate parent. This will never exit Settings.
- */
- var navigateToPreviousRoute = function() {
- var previousRoute = window.history.state &&
- assert(getRouteForPath(/** @type {string} */ (window.history.state)));
-
- if (previousRoute && previousRoute.depth <= currentRoute.depth)
- window.history.back();
- else
- navigateTo(currentRoute.parent || Route.BASIC);
- };
-
window.addEventListener('popstate', function(event) {
// On pop state, do not push the state onto the window.history again.
- setCurrentRoute(
- getRouteForPath(window.location.pathname) || Route.BASIC,
+ routerInstance.setCurrentRoute(
+ /** @type {!settings.Route} */ (
+ routerInstance.getRouteForPath(window.location.pathname) ||
+ routerInstance.getRoutes().BASIC),
new URLSearchParams(window.location.search), true);
});
+ // TODO(scottchen): Change to 'get routes() {}' in export when we fix a bug in
+ // ChromePass that limits the syntax of what can be returned from cr.define().
+ var routes = routerInstance.getRoutes();
+
+ // TODO(scottchen): Stop exposing all those methods directly on settings.*,
+ // and instead update all clients to use the singleton instance directly
+ var getCurrentRoute = routerInstance.getCurrentRoute.bind(routerInstance);
+ var getRouteForPath = routerInstance.getRouteForPath.bind(routerInstance);
+ var initializeRouteFromUrl =
+ routerInstance.initializeRouteFromUrl.bind(routerInstance);
+ var resetRouteForTesting =
+ routerInstance.resetRouteForTesting.bind(routerInstance);
+ var getQueryParameters =
+ routerInstance.getQueryParameters.bind(routerInstance);
+ var lastRouteChangeWasPopstate =
+ routerInstance.lastRouteChangeWasPopstate.bind(routerInstance);
+ var navigateTo = routerInstance.navigateTo.bind(routerInstance);
+ var navigateToPreviousRoute =
+ routerInstance.navigateToPreviousRoute.bind(routerInstance);
+
return {
- Route: Route,
+ Route: Route, // The Route class definition.
+ Router: Router, // The Router class definition.
+ router: routerInstance, // the singleton.
+ routes: routes,
RouteObserverBehavior: RouteObserverBehavior,
getRouteForPath: getRouteForPath,
initializeRouteFromUrl: initializeRouteFromUrl,

Powered by Google App Engine
This is Rietveld 408576698