mithril-vndb/pathname/build.js
Isiah Meadows b98ab29efd
Make errors and their messages more accurate and helpful (#2536)
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.
2019-09-30 16:08:04 -04:00

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
}