Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / settings / settings_page / settings_router.js
blob3eb5eca9c8fd64f6b405942dbedb3913eb746118
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
3 // found in the LICENSE file.
5 /**
6 * @fileoverview
7 * 'settings-router' is a simple router for settings. Its responsibilites:
8 * - Update the URL when the routing state changes.
9 * - Initialize the routing state with the initial URL.
10 * - Process and validate all routing state changes.
12 * Example:
14 * <settings-router current-route="{{currentRoute}}">
15 * </settings-router>
17 * @group Chrome Settings Elements
18 * @element settings-router
20 Polymer({
21 is: 'settings-router',
23 properties: {
24 /**
25 * The current active route. This is reflected to the URL. Updates to this
26 * property should replace the whole object.
28 * currentRoute.page refers to top-level pages such as Basic and Advanced.
30 * currentRoute.section is only non-empty when the user is on a subpage. If
31 * the user is on Basic, for instance, this is an empty string.
33 * currentRoute.subpage is an Array. The last element is the actual subpage
34 * the user is on. The previous elements are the ancestor subpages. This
35 * enables support for multiple paths to the same subpage. This is used by
36 * both the Back button and the Breadcrumb to determine ancestor subpages.
38 currentRoute: {
39 notify: true,
40 observer: 'currentRouteChanged_',
41 type: Object,
42 value: function() {
43 // Take the current URL, find a matching pre-defined route, and
44 // initialize the currentRoute to that pre-defined route.
45 for (var i = 0; i < this.routes_.length; ++i) {
46 var route = this.routes_[i];
47 if (route.url == window.location.pathname) {
48 return {
49 page: route.page,
50 section: route.section,
51 subpage: route.subpage,
56 // As a fallback return the default route.
57 return this.routes_[0];
61 /**
62 * Page titles for the currently active route. Updated by the currentRoute
63 * property observer.
64 * @type {{pageTitle: string, subpageTitles: Array<string>}}
66 currentRouteTitles: {
67 notify: true,
68 type: Object,
69 value: function() { return {}; },
74 /**
75 * @private
76 * The 'url' property is not accessible to other elements.
78 routes_: [
80 url: '/',
81 page: 'basic',
82 section: '',
83 subpage: [],
84 subpageTitles: [],
87 url: '/advanced',
88 page: 'advanced',
89 section: '',
90 subpage: [],
91 subpageTitles: [],
94 url: '/startup',
95 page: 'basic',
96 section: 'on-startup',
97 subpage: ['startup-urls'],
98 subpageTitles: ['onStartupSetPages'],
101 url: '/searchEngines',
102 page: 'basic',
103 section: 'search',
104 subpage: ['search-engines'],
105 subpageTitles: ['searchEnginesPageTitle'],
108 url: '/searchEngines/advanced',
109 page: 'basic',
110 section: 'search',
111 subpage: ['search-engines', 'search-engines-advanced'],
112 subpageTitles: ['searchEnginesPageTitle', 'advancedPageTitle'],
115 url: '/certificates',
116 page: 'advanced',
117 section: 'privacy',
118 subpage: ['manage-certificates'],
119 subpageTitles: ['manageCertificates'],
122 url: '/content',
123 page: 'advanced',
124 section: 'privacy',
125 subpage: ['site-settings'],
126 subpageTitles: ['siteSettings'],
129 url: '/clearBrowserData',
130 page: 'advanced',
131 section: 'privacy',
132 subpage: ['clear-browsing-data'],
133 subpageTitles: ['clearBrowsingData'],
136 url: '/networkDetail',
137 page: 'basic',
138 section: 'internet',
139 subpage: ['network-detail'],
140 subpageTitles: ['internetDetailPageTitle'],
143 url: '/knownNetworks',
144 page: 'basic',
145 section: 'internet',
146 subpage: ['known-networks'],
147 subpageTitles: ['internetKnownNetworksPageTitle'],
152 * Sets up a history popstate observer.
154 created: function() {
155 window.addEventListener('popstate', function(event) {
156 if (event.state && event.state.page)
157 this.currentRoute = event.state;
158 }.bind(this));
162 * @private
163 * Is called when another element modifies the route. This observer validates
164 * the route change against the pre-defined list of routes, and updates the
165 * URL appropriately.
167 currentRouteChanged_: function(newRoute, oldRoute) {
168 for (var i = 0; i < this.routes_.length; ++i) {
169 var route = this.routes_[i];
170 if (route.page == newRoute.page && route.section == newRoute.section &&
171 route.subpage.length == newRoute.subpage.length &&
172 newRoute.subpage.every(function(value, index) {
173 return value == route.subpage[index];
174 })) {
176 // Update the property containing the titles for the current route.
177 this.currentRouteTitles = {
178 pageTitle: loadTimeData.getString(route.page + 'PageTitle'),
179 subpageTitles: route.subpageTitles.map(function(titleCode) {
180 return loadTimeData.getString(titleCode);
184 // If we are restoring a state from history, don't push it again.
185 if (newRoute.inHistory)
186 return;
188 // Mark routes persisted in history as already stored in history.
189 var historicState = {
190 inHistory: true,
191 page: newRoute.page,
192 section: newRoute.section,
193 subpage: newRoute.subpage,
196 // Push the current route to the history state, so when the user
197 // navigates with the browser back button, we can recall the route.
198 if (oldRoute) {
199 history.pushState(historicState, null, route.url);
200 } else {
201 // For the very first route (oldRoute will be undefined), we replace
202 // the existing state instead of pushing a new one. This is to allow
203 // the user to use the browser back button to exit Settings entirely.
204 history.replaceState(historicState, null);
207 return;
211 assertNotReached('Route not found: ' + JSON.stringify(newRoute));