aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/app-route/app-location.html
blob: 3e001ae1e319ee6449a7c4499b489d0c7b541904 (plain)
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
<!--
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-location/iron-location.html">
<link rel="import" href="../iron-location/iron-query-params.html">
<link rel="import" href="app-route-converter-behavior.html">

<!--
`app-location` is an element that provides synchronization between the
browser location bar and the state of an app. When created, `app-location`
elements will automatically watch the global location for changes. As changes
occur, `app-location` produces and updates an object called `route`. This
`route` object is suitable for passing into a `app-route`, and other similar
elements.

An example of the public API of a route object that describes the URL
`https://elements.polymer-project.org/elements/app-location`:

    {
      prefix: '',
      path: '/elements/app-location'
    }

Example Usage:

    <app-location route="{{route}}"></app-location>
    <app-route route="{{route}}" pattern="/:page" data="{{data}}"></app-route>

As you can see above, the `app-location` element produces a `route` and that
property is then bound into the `app-route` element. The bindings are two-
directional, so when changes to the `route` object occur within `app-route`,
they automatically reflect back to the global location.

### Hashes vs Paths

By default `app-location` routes using the pathname portion of the URL. This has
broad browser support but it does require cooperation of the backend server. An
`app-location` can be configured to use the hash part of a URL instead using
the `use-hash-as-path` attribute, like so:

    <app-location route="{{route}}" use-hash-as-path></app-location>

### Integrating with other routing code

There is no standard event that is fired when window.location is modified.
`app-location` fires a `location-changed` event on `window` when it updates the
location. It also listens for that same event, and re-reads the URL when it's
fired. This makes it very easy to interop with other routing code.

So for example if you want to navigate to `/new_path` imperatively you could
call `window.location.pushState` or `window.location.replaceState` followed by
firing a `location-changed` event on `window`. i.e.

    window.history.pushState({}, null, '/new_path');
    window.dispatchEvent(new CustomEvent('location-changed'));

@element app-location
@demo demo/index.html
-->
<dom-module id="app-location">
  <template>
    <iron-location
        path="{{__path}}"
        query="{{__query}}"
        hash="{{__hash}}"
        url-space-regex={{urlSpaceRegex}}>
    </iron-location>
    <iron-query-params
        params-string="{{__query}}"
        params-object="{{queryParams}}">
    </iron-query-params>
  </template>
  <script>
    (function() {
      'use strict';

      Polymer({
        is: 'app-location',

        properties: {
          /**
           * A model representing the deserialized path through the route tree, as
           * well as the current queryParams.
           */
          route: {
            type: Object,
            notify: true
          },

          /**
           * In many scenarios, it is convenient to treat the `hash` as a stand-in
           * alternative to the `path`. For example, if deploying an app to a static
           * web server (e.g., Github Pages) - where one does not have control over
           * server-side routing - it is usually a better experience to use the hash
           * to represent paths through one's app.
           *
           * When this property is set to true, the `hash` will be used in place of

           * the `path` for generating a `route`.
           */
          useHashAsPath: {
            type: Boolean,
            value: false
          },

          /**
           * A regexp that defines the set of URLs that should be considered part
           * of this web app.
           *
           * Clicking on a link that matches this regex won't result in a full page
           * navigation, but will instead just update the URL state in place.
           *
           * This regexp is given everything after the origin in an absolute
           * URL. So to match just URLs that start with /search/ do:
           *     url-space-regex="^/search/"
           *
           * @type {string|RegExp}
           */
          urlSpaceRegex: {
            type: String,
            notify: true
          },

          /**
           * A set of key/value pairs that are universally accessible to branches
           * of the route tree.
           */
          __queryParams: {
            type: Object
          },

          /**
           * The pathname component of the current URL.
           */
          __path: {
            type: String
          },

          /**
           * The query string portion of the current URL.
           */
          __query: {
            type: String
          },

          /**
           * The hash portion of the current URL.
           */
          __hash: {
            type: String
          },

          /**
           * The route path, which will be either the hash or the path, depending
           * on useHashAsPath.
           */
          path: {
            type: String,
            observer: '__onPathChanged'
          }
        },

        behaviors: [Polymer.AppRouteConverterBehavior],

        observers: [
          '__computeRoutePath(useHashAsPath, __hash, __path)'
        ],

        __computeRoutePath: function() {
          this.path = this.useHashAsPath ? this.__hash : this.__path;
        },

        __onPathChanged: function() {
          if (!this._readied) {
            return;
          }

          if (this.useHashAsPath) {
            this.__hash = this.path;
          } else {
            this.__path = this.path;
          }
        }
      });
    })();
  </script>
</dom-module>