@rr0/cms
Version:
RR0 Content Management System (CMS)
51 lines (50 loc) • 1.61 kB
JavaScript
export class AnchorReplacer {
constructor(baseUrl, handlers) {
this.handlers = handlers;
this.baseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
}
async replacement(context, a) {
const href = a.href;
const baseUrl = this.baseUrl + context.file.name;
try {
if (href.startsWith("http") && !href.startsWith(this.baseUrl)) {
this.updateLinkExternal(context, a);
}
else {
const url = new URL(href, baseUrl);
await this.updateLinkInternal(context, a, url);
}
}
catch (e) {
throw Error(e + ": " + href);
}
return a;
}
/**
* Update a link to denote it as external.
*
* @param context
* @param a
* @protected
*/
updateLinkExternal(context, a) {
a.target = "_blank";
a.title = new URL(a.href).host;
context.debug("Adding target in", a.outerHTML);
}
async updateLinkInternal(context, a, url) {
if (url.protocol.startsWith("http")) {
const pathname = url.pathname;
const pathToSearch = pathname.substring(1);
if (pathToSearch) {
for (const handler of this.handlers) {
await handler.handle(context, a, pathToSearch);
}
}
if (pathname.indexOf(".") < 0 && !pathname.endsWith("/") && !url.hash) {
a.href += "/";
context.debug("Added trailing slash in", a.outerHTML);
}
}
}
}