8000 jsdom/lib/jsdom/utils.js at 4.x · dominicrico/jsdom · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
237 lines (201 loc) · 7.28 KB

utils.js

File metadata and controls

237 lines (201 loc) · 7.28 KB
}
if (!this._memoizedQueries[type]) {
this._memoizedQueries[type] = Object.create(null);
}
var key;
if (arguments.length === 1 && typeof arguments[0] === "string") {
key = arguments[0];
} else if (arguments.length === 2 && typeof arguments[0] === "string" && typeof arguments[1] === "string") {
key = arguments[0] + "::" + arguments[1];
} else {
return fn.apply(this, arguments);
}
if (!(key in this._memoizedQueries[type])) {
this._memoizedQueries[type][key] = fn.apply(this, arguments);
}
return this._memoizedQueries[type][key];
};
};
/**
* A slightly-more-compliant version of `url.resolve`, taking care of a few Node bugs.
*/
exports.resolveHref = function resolveHref(baseUrl, href) {
var about = "about:blank";
// if we're redirecting to another site on about:blank, just let it through
if (href.substring(0, about.length) === about) {
return href;
}
// if we have to resolve from about:blank we need a bit of special logic
if (baseUrl.substring(0, about.length) === about) {
if (href.search(/^([A-Za-z0-9]+):/) === 0) { // we have an absolute url
baseUrl = href;
href = "";
} else if (href[0] === "#") { // we have a location hash on about:blank
return baseUrl.split(/#/)[0] + href;
} else if (!href) { // we just have some base url
return baseUrl;
} else { // must be a file url
baseUrl = "file://" + href;
href = "";
}
}
if (baseUrl === resolveHref.memoizedUrl && resolveHref.cache && resolveHref.cache[href]) {
return resolveHref.cache[href];
}
// When switching protocols, the path doesn't get canonicalized (i.e. .s and ..s are still left):
// https://github.com/joyent/node/issues/5453
var intermediate = url.resolve(baseUrl, href);
// This canonicalizes the path, at the cost of overwriting the hash.
var nextStep = url.resolve(intermediate, "#");
// But it breaks file URLs by removing their colon O_o, so put that back.
nextStep = nextStep.replace(/^file:\/\/([a-z])\//i, "file:///$1:/");
// So, insert the hash back in, if there was one.
var parsed = url.parse(intermediate);
var fixed = nextStep.slice(0, -1) + (parsed.hash || "");
// Finally, fix file:/// URLs on Windows, where Node removes their drive letters:
// https://github.com/joyent/node/issues/5452
if (/^file\:\/\/\/[a-z]\:\//i.test(baseUrl) && /^file\:\/\/\//.test(fixed) &&
!/^file\:\/\/\/[a-z]\:\//i.test(fixed)) {
fixed = fixed.replace(/^file\:\/\/\//, baseUrl.substring(0, 11));
}
// HORRIBLE HACK: encode \u00E4 correctly just so that we pass
// https://github.com/w3c/web-platform-tests/blob/e75f01a689a3481f5c773315c2c2527712cf8c2c/dom/nodes/DOMImplementation-createHTMLDocument.html#L71-L72
// Eventually we should replace this with a real URL parser based on the URL standard.
fixed = fixed.replace(/\u00E4/, "%C3%A4");
if (baseUrl !== resolveHref.memoizedUrl) {
resolveHref.memoizedUrl = baseUrl;
resolveHref.cache = {};
}
resolveHref.cache[href] = fixed;
return fixed;
};
0