Created
August 17, 2017 08:04
-
-
Save jskrzypek/4f8955d74e26ca7256e9683c2c099092 to your computer and use it in GitHub Desktop.
getNamespaceRelativeType() - helper function for vuex proposal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// adapted from node's posix path.relative() | |
// https://github.com/nodejs/node/blob/be63c26e8c5d9f337cc7349ea37dc5b312c9631d/lib/path.js#L1252-L1342 | |
function getNamespaceRelativeType(namespace, type) { | |
// Trim any leading backslashes | |
var namespaceStart = 1; | |
for (; namespaceStart < namespace.length; ++namespaceStart) { | |
if (namespace.charCodeAt(namespaceStart) !== 47/*/*/) | |
break; | |
} | |
var namespaceEnd = namespace.length; | |
var namespaceLen = (namespaceEnd - namespaceStart); | |
// Trim any leading backslashes | |
var typeStart = 1; | |
for (; typeStart < type.length; ++typeStart) { | |
if (type.charCodeAt(typeStart) !== 47/*/*/) | |
break; | |
} | |
var typeEnd = type.length; | |
var typeLen = (typeEnd - typeStart); | |
// Compare paths to find the longest common path from root | |
var length = (namespaceLen < typeLen ? namespaceLen : typeLen); | |
var lastCommonSep = -1; | |
var i = 0; | |
for (; i <= length; ++i) { | |
if (i === length) { | |
if (typeLen > length) { | |
if (type.charCodeAt(typeStart + i) === 47/*/*/) { | |
// We get here if `namespace` is the exact base path for `type`. | |
// For example: namespace='foo/bar/'; type='foo/bar/baz' | |
return type.slice(typeStart + i + 1); | |
} else if (i === 0) { | |
// We get here if `namespace` is the root | |
// For example: namespace='/'; type='/foo' | |
return type.slice(typeStart + i); | |
} | |
} else if (namespaceLen > length) { | |
if (namespace.charCodeAt(namespaceStart + i) === 47/*/*/) { | |
// We get here if `type` is the exact base path for `namespace`. | |
// For example: namespace='/foo/bar/baz'; type='/foo/bar' | |
// This should n never happen, | |
lastCommonSep = i; | |
} else if (i === 0) { | |
// We get here if `type` is the root. | |
// For example: namespace='/foo'; type='/' | |
lastCommonSep = 0; | |
} | |
} | |
break; | |
} | |
var namespaceCode = namespace.charCodeAt(namespaceStart + i); | |
var typeCode = type.charCodeAt(typeStart + i); | |
if (namespaceCode !== typeCode) | |
break; | |
else if (namespaceCode === 47/*/*/) | |
lastCommonSep = i; | |
} | |
var out = ''; | |
// Generate the relative path based on the path difference between `type` | |
// and `namespace` | |
for (i = namespaceStart + lastCommonSep + 1; i <= namespaceEnd; ++i) { | |
if (i === namespaceEnd || namespace.charCodeAt(i) === 47/*/*/) { | |
if (out.length === 0) | |
out += '..'; | |
else | |
out += '/..'; | |
} | |
} | |
// Lastly, append the rest of the destination (`type`) path that comes after | |
// the common path parts | |
if (out.length > 0) | |
return out + type.slice(typeStart + lastCommonSep); | |
else { | |
typeStart += lastCommonSep; | |
if (type.charCodeAt(typeStart) === 47/*/*/) | |
++typeStart; | |
return type.slice(typeStart); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment