| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 Copyright 2014 The Chromium Authors. All rights reserved. | |
| 3 Use of this source code is governed by a BSD-style license that can be | |
| 4 found in the LICENSE file. | |
| 5 --> | |
| 6 | |
| 7 <!-- | |
| 8 Handles navigations by showing the appropriate ct-view. Use the "default" attrib
ute on a ct-view to show | |
| 9 that view when no view matches the current path. | |
| 10 pathPrefix: The prefix of the path that is not used for navigation, if any. | |
| 11 defaultPath: If specified, the root URL will be routed using defaultPath, withou
t changing the actual URL. | |
| 12 Gives the app a "landing page." | |
| 13 --> | |
| 14 <polymer-element name="ct-router" attributes="pathPrefix defaultPath"> | |
| 15 <template> | |
| 16 <style> | |
| 17 :host { | |
| 18 display: block; | |
| 19 /* Position the container so it captures its absolutely postioned childr
en. */ | |
| 20 position: relative; | |
| 21 } | |
| 22 </style> | |
| 23 <content select="ct-view"></content> | |
| 24 </template> | |
| 25 <script> | |
| 26 Polymer('ct-router', { | |
| 27 activeView: null, | |
| 28 pathPrefix: '', | |
| 29 currentPath: '', | |
| 30 defaultPath: '/', | |
| 31 | |
| 32 created: function() { | |
| 33 this._routeChanged = this._routeChanged.bind(this); | |
| 34 this._handleNavigate = this._handleNavigate.bind(this); | |
| 35 // This ensures we can run from any subdirectory. | |
| 36 this.pathPrefix = document.location.pathname + '/'; | |
| 37 }, | |
| 38 | |
| 39 attached: function() { | |
| 40 // Use setTimeout instead of this.async since raf won't fire in | |
| 41 // background tabs and we want to bootstrap the inital view even | |
| 42 // for those tabs. | |
| 43 setTimeout(this._replaceInitialUrl.bind(this), 0); | |
| 44 window.addEventListener('popstate', this._routeChanged); | |
| 45 document.addEventListener('navigate', this._handleNavigate); | |
| 46 | |
| 47 this.defaultView = this.querySelector('ct-view[default]'); | |
| 48 if (!this.defaultView) | |
| 49 this.defaultView = this.querySelector('ct-view'); | |
| 50 }, | |
| 51 | |
| 52 detached: function() { | |
| 53 window.removeEventListener('popstate', this._routeChanged); | |
| 54 document.removeEventListener('navigate', this._handleNavigate); | |
| 55 }, | |
| 56 | |
| 57 _replaceInitialUrl: function() { | |
| 58 var url = window.location.pathname + window.location.search + window.loc
ation.hash; | |
| 59 if (url.startsWith(this.pathPrefix)) | |
| 60 url = url.replace(this.pathPrefix, ''); | |
| 61 // Multiple slashes at the beginning of the URL would be interpreted as
another domain. | |
| 62 url = url.replace(/^\/\/+/, '/'); | |
| 63 window.history.replaceState(null, null, url); | |
| 64 this._routeChanged(); | |
| 65 }, | |
| 66 | |
| 67 _handleNavigate: function(event) { | |
| 68 var historyFn = event.detail.replaceState ? window.history.replaceState
: window.history.pushState; | |
| 69 historyFn.call(window.history, null, null, event.detail.url); | |
| 70 this.async(this._routeChanged); | |
| 71 }, | |
| 72 | |
| 73 _routeChanged: function() { | |
| 74 var path = window.location.pathname; | |
| 75 if (path == this.currentPath) | |
| 76 return; | |
| 77 this.currentPath = path; | |
| 78 var views = this.querySelectorAll('ct-view').array(); | |
| 79 for (var i = 0; i < views.length; ++i) { | |
| 80 var nextView = views[i].showView(path); | |
| 81 if (!nextView) | |
| 82 continue; | |
| 83 this._swapViews(nextView); | |
| 84 return; | |
| 85 } | |
| 86 this._swapViews(this.defaultView.showView(this.defaultPath)); | |
| 87 }, | |
| 88 | |
| 89 _swapViews: function(nextView) { | |
| 90 if (this.activeView) | |
| 91 this.activeView.hidden = true; | |
| 92 this.activeView = nextView; | |
| 93 this.activeView.hidden = false; | |
| 94 } | |
| 95 }); | |
| 96 </script> | |
| 97 </polymer-element> | |
| OLD | NEW |