Also, I normalized them to all be sentences for consistency, and I moved the reentrancy check from `m.mount` to `m.render` to be a little more helpful. The router change during mounting is inconsequential and only to avoid the new modified error, and the change to the update loop is to send the original error if an error occurred while initializing the default route. (This is all around more useful anyways.) And while I was at it, I fixed an obscure bug with sync redraws.
43 lines
1.8 KiB
JavaScript
43 lines
1.8 KiB
JavaScript
"use strict"
|
|
|
|
var buildQueryString = require("../querystring/build")
|
|
var assign = require("./assign")
|
|
|
|
// Returns `path` from `template` + `params`
|
|
module.exports = function(template, params) {
|
|
if ((/:([^\/\.-]+)(\.{3})?:/).test(template)) {
|
|
throw new SyntaxError("Template parameter names must be separated by either a '/', '-', or '.'.")
|
|
}
|
|
if (params == null) return template
|
|
var queryIndex = template.indexOf("?")
|
|
var hashIndex = template.indexOf("#")
|
|
var queryEnd = hashIndex < 0 ? template.length : hashIndex
|
|
var pathEnd = queryIndex < 0 ? queryEnd : queryIndex
|
|
var path = template.slice(0, pathEnd)
|
|
var query = {}
|
|
|
|
assign(query, params)
|
|
|
|
var resolved = path.replace(/:([^\/\.-]+)(\.{3})?/g, function(m, key, variadic) {
|
|
delete query[key]
|
|
// If no such parameter exists, don't interpolate it.
|
|
if (params[key] == null) return m
|
|
// Escape normal parameters, but not variadic ones.
|
|
return variadic ? params[key] : encodeURIComponent(String(params[key]))
|
|
})
|
|
|
|
// In case the template substitution adds new query/hash parameters.
|
|
var newQueryIndex = resolved.indexOf("?")
|
|
var newHashIndex = resolved.indexOf("#")
|
|
var newQueryEnd = newHashIndex < 0 ? resolved.length : newHashIndex
|
|
var newPathEnd = newQueryIndex < 0 ? newQueryEnd : newQueryIndex
|
|
var result = resolved.slice(0, newPathEnd)
|
|
|
|
if (queryIndex >= 0) result += template.slice(queryIndex, queryEnd)
|
|
if (newQueryIndex >= 0) result += (queryIndex < 0 ? "?" : "&") + resolved.slice(newQueryIndex, newQueryEnd)
|
|
var querystring = buildQueryString(query)
|
|
if (querystring) result += (queryIndex < 0 && newQueryIndex < 0 ? "?" : "&") + querystring
|
|
if (hashIndex >= 0) result += template.slice(hashIndex)
|
|
if (newHashIndex >= 0) result += (hashIndex < 0 ? "" : "&") + resolved.slice(newHashIndex)
|
|
return result
|
|
}
|