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.
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.
14 * <settings-router current-route="{{currentRoute}}">
17 * @group Chrome Settings Elements
18 * @element settings-router
21 is
: 'settings-router',
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.
40 observer
: 'currentRouteChanged_',
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
) {
50 section
: route
.section
,
51 subpage
: route
.subpage
,
56 // As a fallback return the default route.
57 return this.routes_
[0];
62 * Page titles for the currently active route. Updated by the currentRoute
64 * @type {{pageTitle: string, subpageTitles: Array<string>}}
69 value: function() { return {}; },
76 * The 'url' property is not accessible to other elements.
94 url
: '/searchEngines',
97 subpage
: ['search-engines'],
98 subpageTitles
: ['searchEnginesPageTitle'],
101 url
: '/searchEngines/advanced',
104 subpage
: ['search-engines', 'search-engines-advanced'],
105 subpageTitles
: ['searchEnginesPageTitle', 'advancedPageTitle'],
108 url
: '/certificates',
111 subpage
: ['manage-certificates'],
112 subpageTitles
: ['manageCertificates'],
118 subpage
: ['site-settings'],
119 subpageTitles
: ['siteSettings'],
124 * Sets up a history popstate observer.
126 created: function() {
127 window
.addEventListener('popstate', function(event
) {
128 if (event
.state
&& event
.state
.page
)
129 this.currentRoute
= event
.state
;
135 * Is called when another element modifies the route. This observer validates
136 * the route change against the pre-defined list of routes, and updates the
139 currentRouteChanged_: function(newRoute
, oldRoute
) {
140 for (var i
= 0; i
< this.routes_
.length
; ++i
) {
141 var route
= this.routes_
[i
];
142 if (route
.page
== newRoute
.page
&& route
.section
== newRoute
.section
&&
143 route
.subpage
.length
== newRoute
.subpage
.length
&&
144 newRoute
.subpage
.every(function(value
, index
) {
145 return value
== route
.subpage
[index
];
148 // Update the property containing the titles for the current route.
149 this.currentRouteTitles
= {
150 pageTitle
: loadTimeData
.getString(route
.page
+ 'PageTitle'),
151 subpageTitles
: route
.subpageTitles
.map(function(titleCode
) {
152 return loadTimeData
.getString(titleCode
);
156 // If we are restoring a state from history, don't push it again.
157 if (newRoute
.inHistory
)
160 // Mark routes persisted in history as already stored in history.
161 var historicState
= {
164 section
: newRoute
.section
,
165 subpage
: newRoute
.subpage
,
168 // Push the current route to the history state, so when the user
169 // navigates with the browser back button, we can recall the route.
171 history
.pushState(historicState
, null, route
.url
);
173 // For the very first route (oldRoute will be undefined), we replace
174 // the existing state instead of pushing a new one. This is to allow
175 // the user to use the browser back button to exit Settings entirely.
176 history
.replaceState(historicState
, null);
183 assertNotReached('Route not found: ' + JSON
.stringify(newRoute
));