| OLD | NEW |
| 1 'use strict'; | 1 'use strict'; |
| 2 | 2 |
| 3 Polymer({ | 3 Polymer({ |
| 4 is: 'iron-location', | 4 is: 'iron-location', |
| 5 properties: { | 5 properties: { |
| 6 /** | 6 /** |
| 7 * The pathname component of the URL. | 7 * The pathname component of the URL. |
| 8 */ | 8 */ |
| 9 path: { | 9 path: { |
| 10 type: String, | 10 type: String, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 | 66 |
| 67 /** | 67 /** |
| 68 * urlSpaceRegex, but coerced into a regexp. | 68 * urlSpaceRegex, but coerced into a regexp. |
| 69 * | 69 * |
| 70 * @type {RegExp} | 70 * @type {RegExp} |
| 71 */ | 71 */ |
| 72 _urlSpaceRegExp: { | 72 _urlSpaceRegExp: { |
| 73 computed: '_makeRegExp(urlSpaceRegex)' | 73 computed: '_makeRegExp(urlSpaceRegex)' |
| 74 }, | 74 }, |
| 75 | 75 |
| 76 _lastChangedAtAt: { | 76 _lastChangedAt: { |
| 77 type: Number, | 77 type: Number |
| 78 value: -Infinity | |
| 79 }, | 78 }, |
| 80 | 79 |
| 81 _initialized: { | 80 _initialized: { |
| 82 type: Boolean, | 81 type: Boolean, |
| 83 value: false | 82 value: false |
| 84 } | 83 } |
| 85 }, | 84 }, |
| 86 hostAttributes: { | 85 hostAttributes: { |
| 87 hidden: true | 86 hidden: true |
| 88 }, | 87 }, |
| 89 observers: [ | 88 observers: [ |
| 90 '_updateUrl(path, query, hash)' | 89 '_updateUrl(path, query, hash)' |
| 91 ], | 90 ], |
| 92 attached: function() { | 91 attached: function() { |
| 93 this.listen(window, 'hashchange', '_hashChanged'); | 92 this.listen(window, 'hashchange', '_hashChanged'); |
| 94 this.listen(window, 'location-changed', '_urlChanged'); | 93 this.listen(window, 'location-changed', '_urlChanged'); |
| 95 this.listen(window, 'popstate', '_urlChanged'); | 94 this.listen(window, 'popstate', '_urlChanged'); |
| 96 this.listen(/** @type {!HTMLBodyElement} */(document.body), 'click', '_glo
balOnClick'); | 95 this.listen(/** @type {!HTMLBodyElement} */(document.body), 'click', '_glo
balOnClick'); |
| 96 // Give a 200ms grace period to make initial redirects without any |
| 97 // additions to the user's history. |
| 98 this._lastChangedAt = window.performance.now() - (this.dwellTime - 200); |
| 97 | 99 |
| 98 this._initialized = true; | 100 this._initialized = true; |
| 99 this._urlChanged(); | 101 this._urlChanged(); |
| 100 }, | 102 }, |
| 101 detached: function() { | 103 detached: function() { |
| 102 this.unlisten(window, 'hashchange', '_hashChanged'); | 104 this.unlisten(window, 'hashchange', '_hashChanged'); |
| 103 this.unlisten(window, 'location-changed', '_urlChanged'); | 105 this.unlisten(window, 'location-changed', '_urlChanged'); |
| 104 this.unlisten(window, 'popstate', '_urlChanged'); | 106 this.unlisten(window, 'popstate', '_urlChanged'); |
| 105 this.unlisten(/** @type {!HTMLBodyElement} */(document.body), 'click', '_g
lobalOnClick'); | 107 this.unlisten(/** @type {!HTMLBodyElement} */(document.body), 'click', '_g
lobalOnClick'); |
| 106 this._initialized = false; | 108 this._initialized = false; |
| 107 }, | 109 }, |
| 108 /** | |
| 109 * @return {number} the number of milliseconds since some point in the | |
| 110 * past. Only useful for comparing against other results from this | |
| 111 * function. | |
| 112 */ | |
| 113 _now: function() { | |
| 114 if (window.performance && window.performance.now) { | |
| 115 return window.performance.now(); | |
| 116 } | |
| 117 return new Date().getTime(); | |
| 118 }, | |
| 119 _hashChanged: function() { | 110 _hashChanged: function() { |
| 120 this.hash = window.location.hash.substring(1); | 111 this.hash = window.location.hash.substring(1); |
| 121 }, | 112 }, |
| 122 _urlChanged: function() { | 113 _urlChanged: function() { |
| 123 // We want to extract all info out of the updated URL before we | 114 // We want to extract all info out of the updated URL before we |
| 124 // try to write anything back into it. | 115 // try to write anything back into it. |
| 125 // | 116 // |
| 126 // i.e. without _dontUpdateUrl we'd overwrite the new path with the old | 117 // i.e. without _dontUpdateUrl we'd overwrite the new path with the old |
| 127 // one when we set this.hash. Likewise for query. | 118 // one when we set this.hash. Likewise for query. |
| 128 this._dontUpdateUrl = true; | 119 this._dontUpdateUrl = true; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 153 window.location.search + | 144 window.location.search + |
| 154 window.location.hash | 145 window.location.hash |
| 155 ); | 146 ); |
| 156 if (newUrl == currentUrl) { | 147 if (newUrl == currentUrl) { |
| 157 // nothing to do, the URL didn't change | 148 // nothing to do, the URL didn't change |
| 158 return; | 149 return; |
| 159 } | 150 } |
| 160 // Need to use a full URL in case the containing page has a base URI. | 151 // Need to use a full URL in case the containing page has a base URI. |
| 161 var fullNewUrl = new URL( | 152 var fullNewUrl = new URL( |
| 162 newUrl, window.location.protocol + '//' + window.location.host).href; | 153 newUrl, window.location.protocol + '//' + window.location.host).href; |
| 163 var now = this._now(); | 154 var now = window.performance.now(); |
| 164 var shouldReplace = | 155 var shouldReplace = |
| 165 this._lastChangedAt + this.dwellTime > now; | 156 this._lastChangedAt + this.dwellTime > now; |
| 166 this._lastChangedAt = now; | 157 this._lastChangedAt = now; |
| 167 if (shouldReplace) { | 158 if (shouldReplace) { |
| 168 window.history.replaceState({}, '', fullNewUrl); | 159 window.history.replaceState({}, '', fullNewUrl); |
| 169 } else { | 160 } else { |
| 170 window.history.pushState({}, '', fullNewUrl); | 161 window.history.pushState({}, '', fullNewUrl); |
| 171 } | 162 } |
| 172 this.fire('location-changed', {}, {node: window}); | 163 this.fire('location-changed', {}, {node: window}); |
| 173 }, | 164 }, |
| 174 /** | 165 /** |
| 175 * A necessary evil so that links work as expected. Does its best to | 166 * A necessary evil so that links work as expected. Does its best to |
| 176 * bail out early if possible. | 167 * bail out early if possible. |
| 177 * | 168 * |
| 178 * @param {MouseEvent} event . | 169 * @param {MouseEvent} event . |
| 179 */ | 170 */ |
| 180 _globalOnClick: function(event) { | 171 _globalOnClick: function(event) { |
| 172 // If another event handler has stopped this event then there's nothing |
| 173 // for us to do. This can happen e.g. when there are multiple |
| 174 // iron-location elements in a page. |
| 175 if (event.defaultPrevented) { |
| 176 return; |
| 177 } |
| 181 var href = this._getSameOriginLinkHref(event); | 178 var href = this._getSameOriginLinkHref(event); |
| 182 if (!href) { | 179 if (!href) { |
| 183 return; | 180 return; |
| 184 } | 181 } |
| 185 window.history.pushState({}, '', href); | 182 window.history.pushState({}, '', href); |
| 186 this.fire('location-changed', {}, {node: window}); | 183 this.fire('location-changed', {}, {node: window}); |
| 187 event.preventDefault(); | 184 event.preventDefault(); |
| 188 }, | 185 }, |
| 189 /** | 186 /** |
| 190 * Returns the absolute URL of the link (if any) that this click event | 187 * Returns the absolute URL of the link (if any) that this click event |
| (...skipping 18 matching lines...) Expand all Loading... |
| 209 for (var i = 0; i < eventPath.length; i++) { | 206 for (var i = 0; i < eventPath.length; i++) { |
| 210 var element = eventPath[i]; | 207 var element = eventPath[i]; |
| 211 if (element.tagName === 'A' && element.href) { | 208 if (element.tagName === 'A' && element.href) { |
| 212 anchor = element; | 209 anchor = element; |
| 213 break; | 210 break; |
| 214 } | 211 } |
| 215 } | 212 } |
| 216 | 213 |
| 217 // If there's no link there's nothing to do. | 214 // If there's no link there's nothing to do. |
| 218 if (!anchor) { | 215 if (!anchor) { |
| 219 return; | 216 return null; |
| 220 } | 217 } |
| 221 | 218 |
| 222 // Target blank is a new tab, don't intercept. | 219 // Target blank is a new tab, don't intercept. |
| 223 if (anchor.target === '_blank') { | 220 if (anchor.target === '_blank') { |
| 224 return; | 221 return null; |
| 225 } | 222 } |
| 226 // If the link is for an existing parent frame, don't intercept. | 223 // If the link is for an existing parent frame, don't intercept. |
| 227 if ((anchor.target === '_top' || | 224 if ((anchor.target === '_top' || |
| 228 anchor.target === '_parent') && | 225 anchor.target === '_parent') && |
| 229 window.top !== window) { | 226 window.top !== window) { |
| 230 return; | 227 return null; |
| 231 } | 228 } |
| 232 | 229 |
| 233 var href = anchor.href; | 230 var href = anchor.href; |
| 234 | 231 |
| 235 // It only makes sense for us to intercept same-origin navigations. | 232 // It only makes sense for us to intercept same-origin navigations. |
| 236 // pushState/replaceState don't work with cross-origin links. | 233 // pushState/replaceState don't work with cross-origin links. |
| 237 var url; | 234 var url; |
| 238 if (document.baseURI != null) { | 235 if (document.baseURI != null) { |
| 239 url = new URL(href, /** @type {string} */(document.baseURI)); | 236 url = new URL(href, /** @type {string} */(document.baseURI)); |
| 240 } else { | 237 } else { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 260 var normalizedHref = url.pathname + url.search + url.hash; | 257 var normalizedHref = url.pathname + url.search + url.hash; |
| 261 | 258 |
| 262 // If we've been configured not to handle this url... don't handle it! | 259 // If we've been configured not to handle this url... don't handle it! |
| 263 if (this._urlSpaceRegExp && | 260 if (this._urlSpaceRegExp && |
| 264 !this._urlSpaceRegExp.test(normalizedHref)) { | 261 !this._urlSpaceRegExp.test(normalizedHref)) { |
| 265 return null; | 262 return null; |
| 266 } | 263 } |
| 267 // Need to use a full URL in case the containing page has a base URI. | 264 // Need to use a full URL in case the containing page has a base URI. |
| 268 var fullNormalizedHref = new URL( | 265 var fullNormalizedHref = new URL( |
| 269 normalizedHref, window.location.href).href; | 266 normalizedHref, window.location.href).href; |
| 267 // If the navigation is to the current page we shouldn't add a history |
| 268 // entry. |
| 269 if (fullNormalizedHref === window.location.href) { |
| 270 return null; |
| 271 } |
| 270 return fullNormalizedHref; | 272 return fullNormalizedHref; |
| 271 }, | 273 }, |
| 272 _makeRegExp: function(urlSpaceRegex) { | 274 _makeRegExp: function(urlSpaceRegex) { |
| 273 return RegExp(urlSpaceRegex); | 275 return RegExp(urlSpaceRegex); |
| 274 } | 276 } |
| 275 }); | 277 }); |
| OLD | NEW |