Add ICU message format support
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / more-routing / more-route-selector-extracted.js
blob07d17d1e5764b2390641af7a9a0dec026c9a8566
2 Polymer({
4   is: 'more-route-selector',
6   behaviors: [
7     MoreRouting.ContextAware,
8   ],
10   properties: {
12     /**
13      * The attribute to read route expressions from (on children).
14      */
15     routeAttribute: {
16       type: String,
17       value: 'route',
18     },
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     },
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     },
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     },
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     },
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     },
71   },
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    */
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 nothing.');
87       return;
88     }
90     this._managedSelector.addEventListener(
91         'selected-item-changed', this._onSelectedItemChanged.bind(this));
92     this._updateRoutes();
93   },
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   },
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   },
116   _onMoreRouteChange: function(event) {
117     if (!this._managedSelector) return;
119     var selected = '';
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     }
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   },
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     }
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   },
153   _routeForItem: function(item) {
154     if (!item) return null;
155     if (item.moreRouteContext && item.moreRouteContext instanceof MoreRouting.Route) {
156       return item.moreRouteContext;
157     }
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;
168     return route;
169   },