OLD | NEW |
| (Empty) |
1 | |
2 Polymer({ | |
3 | |
4 is: 'more-route-selector', | |
5 | |
6 behaviors: [ | |
7 MoreRouting.ContextAware, | |
8 ], | |
9 | |
10 properties: { | |
11 | |
12 /** | |
13 * The attribute to read route expressions from (on children). | |
14 */ | |
15 routeAttribute: { | |
16 type: String, | |
17 value: 'route', | |
18 }, | |
19 | |
20 /** | |
21 * The routes managed by this element (inferred from the items that are | |
22 * defined by the selector it targets). | |
23 */ | |
24 routes: { | |
25 type: Array, | |
26 readOnly: true, | |
27 notify: true, | |
28 }, | |
29 | |
30 /** | |
31 * The selected `MoreRouting.Route` object, or `null`. | |
32 * | |
33 * @type {MoreRouting.Route} | |
34 */ | |
35 selectedRoute: { | |
36 type: Object, | |
37 value: null, | |
38 readOnly: true, | |
39 notify: true, | |
40 }, | |
41 | |
42 /** | |
43 * The index of the selected route (relative to `routes`). -1 when there | |
44 * is no active route. | |
45 */ | |
46 selectedIndex: { | |
47 type: Number, | |
48 value: -1, | |
49 readOnly: true, | |
50 notify: true, | |
51 }, | |
52 | |
53 /** | |
54 * The _full_ path expression of the selected route, or `null`. | |
55 */ | |
56 selectedPath: { | |
57 type: String, | |
58 readOnly: true, | |
59 notify: true, | |
60 }, | |
61 | |
62 /** | |
63 * The params of the selected route, or an empty object if no route. | |
64 */ | |
65 selectedParams: { | |
66 type: Object, | |
67 readOnly: true, | |
68 notify: true, | |
69 }, | |
70 | |
71 }, | |
72 | |
73 /** | |
74 * @event more-route-selected fires when a new route is selected. | |
75 * @param {{ | |
76 * newRoute: MoreRouting.Route, oldRoute: MoreRouting.Route, | |
77 * newIndex: number, oldIndex: number, | |
78 * newPath: ?string, oldPath: ?string, | |
79 * newParams: Object, oldParams: Object, | |
80 * }} | |
81 */ | |
82 | |
83 attached: function() { | |
84 this._managedSelector = this._findTargetSelector(); | |
85 if (!this._managedSelector) { | |
86 console.warn(this, 'was built without a selector to manage. It will do not
hing.'); | |
87 return; | |
88 } | |
89 | |
90 this._managedSelector.addEventListener( | |
91 'selected-item-changed', this._onSelectedItemChanged.bind(this)); | |
92 this._updateRoutes(); | |
93 }, | |
94 | |
95 /** | |
96 * Handle a change in selected item, driven by the targeted selector. | |
97 * | |
98 * Note that this will fail if a route is chosen that requires params not | |
99 * defined by the current URL. | |
100 */ | |
101 _onSelectedItemChanged: function(event) { | |
102 if (this._settingSelection) return; | |
103 var route = this._routeForItem(event.detail.value); | |
104 if (!route) return; | |
105 route.navigateTo(); | |
106 }, | |
107 | |
108 _updateRoutes: function() { | |
109 var routes = []; | |
110 if (this._managedSelector) { | |
111 routes = this._managedSelector.items.map(this._routeForItem.bind(this)); | |
112 } | |
113 this._setRoutes(routes); | |
114 }, | |
115 | |
116 _onMoreRouteChange: function(event) { | |
117 if (!this._managedSelector) return; | |
118 | |
119 var selected = ''; | |
120 | |
121 var index = this.routes.indexOf(event.detail.newRoute); | |
122 var attrForSelected = this._managedSelector.attrForSelected; | |
123 if (!attrForSelected) { | |
124 selected = index; | |
125 } else { | |
126 var item = this._managedSelector.items[index]; | |
127 if (item) | |
128 selected = item[attrForSelected] || item.getAttribute(attrForSelected); | |
129 } | |
130 | |
131 // Make sure that we don't turn around and re-navigate | |
132 this._settingSelection = true; | |
133 this._managedSelector.select(selected); | |
134 this._settingSelection = false; | |
135 }, | |
136 | |
137 _findTargetSelector: function() { | |
138 var children = Polymer.dom(this).children; | |
139 if (children.length !== 1) { | |
140 console.error(this, 'expects only a single selector child'); | |
141 return null; | |
142 } | |
143 | |
144 var child = children[0]; | |
145 if ('selected' in child && 'items' in child) { | |
146 return child; | |
147 } else { | |
148 console.error(this, 'can only manage children that are selectors'); | |
149 return null; | |
150 } | |
151 }, | |
152 | |
153 _routeForItem: function(item) { | |
154 if (!item) return null; | |
155 if (item.moreRouteContext && item.moreRouteContext instanceof MoreRouting.Ro
ute) { | |
156 return item.moreRouteContext; | |
157 } | |
158 | |
159 if (!item.hasAttribute(this.routeAttribute)) { | |
160 console.warn(item, 'is missing a context route or "' + this.routeAttribute
+ '" attribute'); | |
161 return null; | |
162 } | |
163 var expression = item.getAttribute(this.routeAttribute); | |
164 var route = MoreRouting.getRoute(expression, this.parentRoute); | |
165 // Associate the route w/ its element while we're here. | |
166 item.moreRouteContext = route; | |
167 | |
168 return route; | |
169 }, | |
170 | |
171 }); | |
OLD | NEW |