-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathisw-route-selector.html
125 lines (106 loc) · 3.31 KB
/
isw-route-selector.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-selector/iron-selectable.html">
<!--
### isw-route-selector
Router with app-route like API, wrapped in an iron-selectable element that binds the active route.
<app-location route="{{route}}"></app-location>
<isw-route-selector route="[[route]]" attr-for-selected="route" selected="{{selectedRoute}}" data="{{data}}">
<isw-route route="a" pattern="/route-a"></isw-route>
<isw-route route="b" pattern="/route-a/route-b"></isw-route>
<isw-route route="c" pattern="/route-c/:somedata"></isw-route>
<isw-route route="d" pattern="/route-c/route-d"></isw-route>
</isw-route-selector>
<iron-pages attr-for-selected="route" selected="[[selectedRoute]]">
<div route="a">Route A</div>
<div route="b">Route B</div>
<div route="c">Route C</div>
<div route="d">Route D</div>
</iron-pages>
@demo demo/index.html
-->
<dom-module id="isw-route-selector">
<script>
Polymer({
is: 'isw-route-selector',
behaviors: [ Polymer.IronSelectableBehavior ],
properties: {
/**
* Route from app-location.
*/
route: {
type: String,
notify: true
},
/**
* The parameterized values that are extracted from the route as described by pattern.
*/
data: {
type: Object,
notify: true
}
},
observers: [
'_onRouteChanged(route.path)'
],
listeners: {
'iron-items-changed': '_onRouteChanged'
},
_onRouteChanged: function() {
if( this.items && this.route ) {
// Highest priority match.
var match;
// Split the route.
var routeParts = this.route.path.split( '/' );
// Iterate items from IronSelectableBehavior.
for( var i = 0; i < this.items.length; i++ ) {
// Check that the item has an pattern.
if( this.items[ i ].pattern ) {
// Split the pattern.
var patternParts = this.items[ i ].pattern.split( '/' );
// Data from the placeholders.
var data = {};
// Some improvised priority system.
// Parts in front are more important, placeholder less important.
var priority = 0;
var failed = false;
// Iterate route parts.
for( var j = 0; j < patternParts.length; j++ ) {
// Ignore empty pattern parts.
if( patternParts[ j ] ) {
if( patternParts[ j ] == routeParts[ j ] ) {
// Direct match.
priority += (10 - j) * 2;
} else if( patternParts[ j ].charAt( 0 ) == ':' && routeParts[ j ] ) {
// Placeholder match.
data[ patternParts[ j ].slice( 1 ) ] = routeParts[ j ];
priority += 10 - j;
} else {
// No match.
failed = true;
}
}
}
if( !failed ) {
// If there is no match, or an match with lower priority, replace.
if( !match || match.priority < priority ) {
match = {
index: i,
data: data,
priority: priority
};
}
}
}
}
if( match ) {
this.set( 'data', match.data );
this.set( 'selected', this._indexToValue( match.index ) );
} else {
this.select( this.fallbackSelection );
}
this.dispatchEvent( new CustomEvent( 'isw-route-changed' ) );
}
}
});
</script>
</dom-module>