diff --git a/mithril.js b/mithril.js index c91bb3cd..8ccfd224 100644 --- a/mithril.js +++ b/mithril.js @@ -354,23 +354,26 @@ Mithril = m = new function app(window) { } return str.join("&") } - var arrayParser = /\[?([^\]\[]+)\]?/g function parseQueryString(str) { + var derefParser = /\[?([^\]\[]+)\]?/g var pairs = str.split("&"), params = {} for (var i = 0; i < pairs.length; i++) { var pair = pairs[i].split("=") - var key = decodeURIComponent(pair[0]), - var value = pair[1] ? decodeURIComponent(pair[1]) : (pair.length === 1 ? true : "") - if (key.indexOf('[') != -1) { + var key = decodeSpace(pair[0]) + var value = pair[1] ? decodeSpace(pair[1]) : (pair.length == 1 ? true : "") + if (key.indexOf('[') > -1) { var subParams = params - while ((match = arrayParser.exec(key)) !== null) { - subParams = subParams[match[1]] = (arrayParser.lastIndex === key.length ? value : subParams[match[1]] || {}) + while ((match = derefParser.exec(key)) !== null) { + subParams = subParams[match[1]] = (derefParser.lastIndex === key.length ? value : subParams[match[1]] || {}) } } else params[key] = value } return params } + function decodeSpace(string) { + return decodeURIComponent(string.replace(/\+/g, " ")) + } //model m.prop = function(store) { diff --git a/tests/mithril-tests.js b/tests/mithril-tests.js index eed776cd..ced6cf2a 100644 --- a/tests/mithril-tests.js +++ b/tests/mithril-tests.js @@ -641,6 +641,42 @@ function testMithril(mock) { mock.performance.$elapse(50) //teardown return true; mock.location.search == path && paramValue.a == "foo" && paramValue.b.c == "1" && paramValue.b.d == "2" && m.route.param("str") == "bar" }) + test(function() { + mock.performance.$elapse(50) //setup + mock.location.pathname = "/" + mock.location.search = "?" + + var root = mock.document.createElement("div") + m.route.mode = "pathname" + m.route(root, "/", { + "/": {controller: function() {}, view: function() { return "bar" }}, + "/test15": {controller: function() {}, view: function() { return "foo" }} + }) + mock.performance.$elapse(50) + var path = "/test15?obj[a]=foo&obj[b][c]=1&obj[b][d]=2&str=bar" + m.route(path) + var paramValue = m.route.param("obj") + mock.performance.$elapse(50) //teardown + return true; mock.location.search == path && paramValue.a == "foo" && paramValue.b.c == "1" && paramValue.b.d == "2" && m.route.param("str") == "bar" + }) + test(function() { + mock.performance.$elapse(50) //setup + mock.location.hash = "#" + mock.location.search = "?" + + var root = mock.document.createElement("div") + m.route.mode = "hash" + m.route(root, "/", { + "/": {controller: function() {}, view: function() { return "bar" }}, + "/test16": {controller: function() {}, view: function() { return "foo" }} + }) + mock.performance.$elapse(50) + var path = "/test16?obj[a]=foo&obj[b][c]=1&obj[b][d]=2&str=bar" + m.route(path) + var paramValue = m.route.param("obj") + mock.performance.$elapse(50) //teardown + return true; mock.location.search == path && paramValue.a == "foo" && paramValue.b.c == "1" && paramValue.b.d == "2" && m.route.param("str") == "bar" + }) //end m.route //m.prop