ApplicationImpl cleanup, part 1:
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components / more-routing / more-route-selector.html
blobc45a1937b9d72e4dce5a724de95c21c42ef8f3cf
1 <!--
2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8 -->
9 <link rel="import" href="../polymer/polymer.html">
11 <link rel="import" href="more-route-context-aware.html">
12 <link rel="import" href="more-route-selection.html">
14 <!--
15 TODO(nevir): Document.
17 TODO(nevir): Support child addition/removal/reorder.
18 -->
19 <dom-module id="more-route-selector">
20 <template>
21 <more-route-selection
22 id="selection"
23 routes="[[routes]]"
24 on-more-route-change="_onMoreRouteChange">
25 </more-route-selection>
26 <content></content>
27 </template>
28 </dom-module>
29 <script>
30 Polymer({
32 is: 'more-route-selector',
34 behaviors: [
35 MoreRouting.ContextAware,
38 properties: {
40 /**
41 * The attribute to read route expressions from (on children).
43 routeAttribute: {
44 type: String,
45 value: 'route',
48 /**
49 * The routes managed by this element (inferred from the items that are
50 * defined by the selector it targets).
52 routes: {
53 type: Array,
54 readOnly: true,
55 notify: true,
58 /**
59 * The selected `MoreRouting.Route` object, or `null`.
61 * @type {MoreRouting.Route}
63 selectedRoute: {
64 type: Object,
65 value: null,
66 readOnly: true,
67 notify: true,
70 /**
71 * The index of the selected route (relative to `routes`). -1 when there
72 * is no active route.
74 selectedIndex: {
75 type: Number,
76 value: -1,
77 readOnly: true,
78 notify: true,
81 /**
82 * The _full_ path expression of the selected route, or `null`.
84 selectedPath: {
85 type: String,
86 readOnly: true,
87 notify: true,
90 /**
91 * The params of the selected route, or an empty object if no route.
93 selectedParams: {
94 type: Object,
95 readOnly: true,
96 notify: true,
102 * @event more-route-selected fires when a new route is selected.
103 * @param {{
104 * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route,
105 * newIndex: number, oldIndex: number,
106 * newPath: ?string, oldPath: ?string,
107 * newParams: Object, oldParams: Object,
108 * }}
111 attached: function() {
112 this._managedSelector = this._findTargetSelector();
113 if (!this._managedSelector) {
114 console.warn(this, 'was built without a selector to manage. It will do nothing.');
115 return;
118 this._managedSelector.addEventListener(
119 'selected-item-changed', this._onSelectedItemChanged.bind(this));
120 this._updateRoutes();
124 * Handle a change in selected item, driven by the targeted selector.
126 * Note that this will fail if a route is chosen that requires params not
127 * defined by the current URL.
129 _onSelectedItemChanged: function(event) {
130 if (this._settingSelection) return;
131 var route = this._routeForItem(event.detail.value);
132 if (!route) return;
133 route.navigateTo();
136 _updateRoutes: function() {
137 var routes = [];
138 if (this._managedSelector) {
139 routes = this._managedSelector.items.map(this._routeForItem.bind(this));
141 this._setRoutes(routes);
144 _onMoreRouteChange: function(event) {
145 if (!this._managedSelector) return;
147 var selected = '';
149 var index = this.routes.indexOf(event.detail.newRoute);
150 var attrForSelected = this._managedSelector.attrForSelected;
151 if (!attrForSelected) {
152 selected = index;
153 } else {
154 var item = this._managedSelector.items[index];
155 if (item)
156 selected = item[attrForSelected] || item.getAttribute(attrForSelected);
159 // Make sure that we don't turn around and re-navigate
160 this._settingSelection = true;
161 this._managedSelector.select(selected);
162 this._settingSelection = false;
165 _findTargetSelector: function() {
166 var children = Polymer.dom(this).children;
167 if (children.length !== 1) {
168 console.error(this, 'expects only a single selector child');
169 return null;
172 var child = children[0];
173 if ('selected' in child && 'items' in child) {
174 return child;
175 } else {
176 console.error(this, 'can only manage children that are selectors');
177 return null;
181 _routeForItem: function(item) {
182 if (!item) return null;
183 if (item.moreRouteContext && item.moreRouteContext instanceof MoreRouting.Route) {
184 return item.moreRouteContext;
187 if (!item.hasAttribute(this.routeAttribute)) {
188 console.warn(item, 'is missing a context route or "' + this.routeAttribute + '" attribute');
189 return null;
191 var expression = item.getAttribute(this.routeAttribute);
192 var route = MoreRouting.getRoute(expression, this.parentRoute);
193 // Associate the route w/ its element while we're here.
194 item.moreRouteContext = route;
196 return route;
200 </script>