UNPKG

@tbela99/css-parser

Version:

CSS parser, minifier and validator for node and the browser

176 lines (173 loc) 4.52 kB
import { memoize } from '../parser/utils/cache.js'; const matchUrl = /^(https?:)?\/\//; /** * return the directory name of a path * @param path * * @private */ function dirname(path) { if (path === "") { return ""; } let i = 0; let parts = [""]; for (; i < path.length; i++) { const chr = path.charAt(i); if (chr == "/") { parts.push(""); } else { parts[parts.length - 1] += chr; } } parts.pop(); return parts.join("/"); } /** * split path * @param result * @private */ function splitPath(result) { if (result.length == 0) { return { parts: [], i: 0 }; } // if (result === "/") { // return { parts: ["/"], i: 0 }; // } const parts = [""]; let i = 0; for (; i < result.length; i++) { const chr = result.charAt(i); if (chr == "/") { parts.push(""); } // else if (chr == "?" || chr == "#") { // break; // } else { parts[parts.length - 1] += chr; } } // let k: number = -1; // while (++k < parts.length) { // if (parts[k] == ".") { // parts.splice(k--, 1); // } else if (parts[k] == "..") { // parts.splice(k - 1, 2); // k -= 2; // } // } return { parts, i }; } /** * Nomalize path */ const normalize = memoize(function (path) { let parts = []; let i = 0; if (path.includes("\\")) { path = path.replace(/(\\)/g, "/"); } for (; i < path.length; i++) { const chr = path.charAt(i); if (chr == "/") { if (parts.length == 0 || parts[parts.length - 1] !== "") { parts.push(""); } } else if (chr == "?" || chr == "#") { break; } else { if (parts.length == 0) { parts.push(""); } parts[parts.length - 1] += chr; } } let k = -1; while (++k < parts.length) { // if (parts[k] == ".") { // parts.splice(k--, 1); // } else if (parts[k] == "..") { parts.splice(k - 1, 2); k -= 2; } } return (path.charAt(0) == "/" ? "/" : "") + parts.join("/"); }); const diff = memoize(function (path1, path2) { let { parts } = splitPath(path1); const { parts: dirs } = splitPath(path2); for (const p of dirs) { if (parts[0] == p) { parts.shift(); } else { parts.unshift(".."); } } return parts.join("/"); }); /** * resolve path * @param url url or path to resolve * @param currentDirectory directory used to resolve the path * @param cwd current working directory * * @private */ const resolve = memoize(function (url, currentDirectory, cwd) { // if (matchUrl.test(url)) { // return { // absolute: url, // relative: url, // }; // } cwd ??= ""; currentDirectory ??= ""; url = normalize(url); if (currentDirectory !== "") { currentDirectory = normalize(currentDirectory); if (url.startsWith(currentDirectory + "/")) { return { absolute: url, relative: url.slice(currentDirectory.length + 1), }; } } if ((currentDirectory === "" || currentDirectory === ".") && cwd !== "") { cwd = normalize(cwd); if (url.startsWith(cwd == "/" ? cwd : cwd + "/")) { const absolute = url; const prefix = cwd == "/" ? cwd : cwd + "/"; return { absolute, relative: absolute.startsWith(prefix) ? absolute.slice(prefix.length) : diff(absolute, cwd), }; } } // if (matchUrl.test(currentDirectory)) { // const path: string = new URL(url, currentDirectory).href; // return { // absolute: path, // relative: path, // }; // } // let result: string = ""; // if (url.charAt(0) == "/") { // result = url; // } // else if (currentDirectory.charAt(0) == "/") { // result = dirname(currentDirectory) + "/" + url; // } // const absolute = url; // normalize(result); return { absolute: url, relative: url === "" ? "" : diff(url, cwd ?? currentDirectory), }; }); export { diff, dirname, matchUrl, normalize, resolve };