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
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">
15 TODO(nevir): Document.
17 TODO(nevir): Support child addition/removal/reorder.
19 <dom-module id=
"more-route-selector">
24 on-more-route-change=
"_onMoreRouteChange">
25 </more-route-selection>
32 is
: 'more-route-selector',
35 MoreRouting
.ContextAware
,
41 * The attribute to read route expressions from (on children).
49 * The routes managed by this element (inferred from the items that are
50 * defined by the selector it targets).
59 * The selected `MoreRouting.Route` object, or `null`.
61 * @type {MoreRouting.Route}
71 * The index of the selected route (relative to `routes`). -1 when there
82 * The _full_ path expression of the selected route, or `null`.
91 * The params of the selected route, or an empty object if no route.
102 * @event more-route-selected fires when a new route is selected.
104 * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route,
105 * newIndex: number, oldIndex: number,
106 * newPath: ?string, oldPath: ?string,
107 * newParams: Object, oldParams: Object,
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.');
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
);
136 _updateRoutes: function() {
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;
149 var index
= this.routes
.indexOf(event
.detail
.newRoute
);
150 var attrForSelected
= this._managedSelector
.attrForSelected
;
151 if (!attrForSelected
) {
154 var item
= this._managedSelector
.items
[index
];
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');
172 var child
= children
[0];
173 if ('selected' in child
&& 'items' in child
) {
176 console
.error(this, 'can only manage children that are selectors');
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');
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
;