195 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			HTML
		
	
	
	
<!--
 | 
						|
@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>
 |