Skip to content

Commit

Permalink
perf(external_link): optimize external link filter (#5598)
Browse files Browse the repository at this point in the history
  • Loading branch information
D-Sketon authored Jan 9, 2025
1 parent 5db029a commit 6f74e6c
Showing 1 changed file with 26 additions and 10 deletions.
36 changes: 26 additions & 10 deletions lib/plugins/filter/after_render/external_link.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { isExternalLink } from 'hexo-util';
import Hexo from '../../../hexo';
import type Hexo from '../../../hexo';

let EXTERNAL_LINK_SITE_ENABLED = true;
const rATag = /<a(?:\s+?|\s+?[^<>]+?\s+?)href=["']((?:https?:|\/\/)[^<>"']+)["'][^<>]*>/gi;
const rTargetAttr = /target=/i;
const rRelAttr = /rel=/i;
const rRelStrAttr = /rel=["']([^<>"']*)["']/i;

const addNoopener = (relStr: string, rel: string) => {
return rel.includes('noopenner') ? relStr : `rel="${rel} noopener"`;
};

function externalLinkFilter(this: Hexo, data: string): string {
if (!EXTERNAL_LINK_SITE_ENABLED) return;

Expand All @@ -17,18 +21,30 @@ function externalLinkFilter(this: Hexo, data: string): string {
return;
}

return data.replace(rATag, (str, href) => {
if (!isExternalLink(href, url, external_link.exclude as any) || rTargetAttr.test(str)) return str;
let result = '';
let lastIndex = 0;
let match;

while ((match = rATag.exec(data)) !== null) {
result += data.slice(lastIndex, match.index);

if (rRelAttr.test(str)) {
str = str.replace(rRelStrAttr, (relStr, rel) => {
return rel.includes('noopenner') ? relStr : `rel="${rel} noopener"`;
});
return str.replace('href=', 'target="_blank" href=');
const str = match[0];
const href = match[1];

if (!isExternalLink(href, url, external_link.exclude as any) || rTargetAttr.test(str)) {
result += str;
} else {
if (rRelAttr.test(str)) {
result += str.replace(rRelStrAttr, addNoopener).replace('href=', 'target="_blank" href=');
} else {
result += str.replace('href=', 'target="_blank" rel="noopener" href=');
}
}
lastIndex = rATag.lastIndex;
}
result += data.slice(lastIndex);

return str.replace('href=', 'target="_blank" rel="noopener" href=');
});
return result;
}

export = externalLinkFilter;

0 comments on commit 6f74e6c

Please sign in to comment.