Skip to content

Instantly share code, notes, and snippets.

@tayiorbeii
Created April 14, 2016 15:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tayiorbeii/e9c48e79d87984517ee83fe8bb696bf2 to your computer and use it in GitHub Desktop.
Save tayiorbeii/e9c48e79d87984517ee83fe8bb696bf2 to your computer and use it in GitHub Desktop.
Link.jsx is a wrapper for react-router's Link that adds some helper functionality for things like relative links.
export let clean = (url) => {
// Remove consecutive slashes
// If it starts with a slash, treat as a standalone path. Otherwise
// we expect a protocol to be present
let slashRe = /([^:\s])\/+/g
if (url.charAt(0) === '/') {
slashRe = /([\w\s]|.?)\/\/+/g
}
let cleaned = url.replace(slashRe, '$1/')
// Remove any trailing slash, even if there are parameters.
return cleaned.replace(/\/(\?|&|#[^!]|$)/g, '$1')
}
export let join = (...parts) => {
// Do a simple join, then clean.
return clean(parts.join('/'))
}
export let parts = (url) => {
// Return the RHS of the url split into parts. So no protocol parts.
let protoParts = url.split('://')
let uri = ''
if (protoParts.length === 1) {
uri = protoParts[0]
} else {
uri = protoParts[1]
}
uri = clean(uri)
let uriParts = uri.split('/')
// If the URI/Path started with a '/', the first part will be empty.
// We don't want that.
if (uriParts[0] === '') {
return uriParts.slice(1)
}
return uriParts
}
export let proto = (url) => {
// Return LHS of the url, the protocol part.
// Returns null if none is found
let protoParts = url.split(':')
if (protoParts.length <= 1) {
return null
}
return protoParts[0]
}
export let pop = (url, num = 1) => {
let lhs = proto(url)
let rhs = parts(url)
let uri = ''
if (num < 1) {
return clean(url)
}
if (rhs.length > num) {
rhs = rhs.slice(0, (-1 * num))
uri = join(...rhs)
}
if (lhs) {
return `${lhs}://${uri}`
}
return `/${uri}`
}
export let isRelative = (url) => {
if (url.length === 0) {
return true
}
return url.charAt(0) !== '/'
}
/**
* Removes any redundant parts and will process
* path manipulators `.`, `./` and `..` appropriately
* to create a clean and accurate URI
*/
export let normalize = (url) => {
const uriParts = parts(url)
if (uriParts.length === 0) {
return ''
}
const res = uriParts.reduce((res, val) => {
if (val === '..') {
return pop(res)
}
if (val === '.' || val === '') {
return res
}
return join(res, val)
}, '')
// Due to the join and that we start with an empty
// string, the result will always have a / at it's root.
// But we respect relative input URLs, so remove it if the
// input was relative.
if (isRelative(url)) {
return res.slice(1)
}
return res
}
export let slugify = (unslug) => {
// Convert spaces to hyphens.
// Remove non-alphanumeric.
// Convert to lowercase
let slug = unslug.trim().toLowerCase()
// If it's not space, alpha-num or hyphen
slug = slug.replace(/[^\w\s-]+|[_]/g, '')
// add hyphens as needed.
slug = slug.replace(/[\s-]+/g, '-')
return slug
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment