Skip to content

Instantly share code, notes, and snippets.

@jskrzypek
Created August 17, 2017 08:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jskrzypek/4f8955d74e26ca7256e9683c2c099092 to your computer and use it in GitHub Desktop.
Save jskrzypek/4f8955d74e26ca7256e9683c2c099092 to your computer and use it in GitHub Desktop.
getNamespaceRelativeType() - helper function for vuex proposal
// 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