diff --git a/api/router.js b/api/router.js index 66c7fc792..be8894396 100644 --- a/api/router.js +++ b/api/router.js @@ -52,7 +52,12 @@ module.exports = function($window, mountRedraw) { if (prefix[0] !== "/") prefix = "/" + prefix } } - var path = decodeURIComponentSafe(prefix).slice(route.prefix.length) + // This seemingly useless `.concat()` speeds up the tests quite a bit, + // since the representation is consistently a relatively poorly + // optimized cons string. + var path = prefix.concat() + .replace(/(?:%[a-f89][a-f0-9])+/gim, decodeURIComponentSafe) + .slice(route.prefix.length) var data = parsePathname(path) Object.assign(data.params, $window.history.state) diff --git a/api/tests/test-routerGetSet.js b/api/tests/test-routerGetSet.js index 9846ae052..51752c80b 100644 --- a/api/tests/test-routerGetSet.js +++ b/api/tests/test-routerGetSet.js @@ -220,7 +220,7 @@ o.spec("route.get/route.set", function() { route.set("/other/:a/:b", {a: "x", b: "y/z", c: "d", e: "f"}) setTimeout(function() { // Yep, before even the throttle mechanism takes hold. - o(route.get()).equals("/other/x/y/z?c=d&e=f") + o(route.get()).equals("/other/x/y%2Fz?c=d&e=f") throttleMock.fire() done() }) diff --git a/pathname/compileTemplate.js b/pathname/compileTemplate.js index 7a5950305..51bbee404 100644 --- a/pathname/compileTemplate.js +++ b/pathname/compileTemplate.js @@ -1,6 +1,7 @@ "use strict" var parsePathname = require("./parse") +var decodeURIComponentSafe = require("../util/decodeURIComponentSafe") // Compiles a template into a function that takes a resolved path (without query // strings) and returns an object containing the template parameters with their @@ -36,7 +37,7 @@ module.exports = function(template) { var values = regexp.exec(data.path) if (values == null) return false for (var i = 0; i < keys.length; i++) { - data.params[keys[i].k] = keys[i].r ? values[i + 1] : decodeURIComponent(values[i + 1]) + data.params[keys[i].k] = keys[i].r ? values[i + 1] : decodeURIComponentSafe(values[i + 1]) } return true }