| 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 |