Skip to content

Commit a13326d

Browse files
committed
Merge remote-tracking branch 'upstream/master' into timestamp
2 parents 21feccd + 6f74e6c commit a13326d

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed
Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import { isExternalLink } from 'hexo-util';
2-
import Hexo from '../../../hexo';
2+
import type Hexo from '../../../hexo';
33

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

10+
const addNoopener = (relStr: string, rel: string) => {
11+
return rel.includes('noopenner') ? relStr : `rel="${rel} noopener"`;
12+
};
13+
1014
function externalLinkFilter(this: Hexo, data: string): string {
1115
if (!EXTERNAL_LINK_SITE_ENABLED) return;
1216

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

20-
return data.replace(rATag, (str, href) => {
21-
if (!isExternalLink(href, url, external_link.exclude as any) || rTargetAttr.test(str)) return str;
24+
let result = '';
25+
let lastIndex = 0;
26+
let match;
27+
28+
while ((match = rATag.exec(data)) !== null) {
29+
result += data.slice(lastIndex, match.index);
2230

23-
if (rRelAttr.test(str)) {
24-
str = str.replace(rRelStrAttr, (relStr, rel) => {
25-
return rel.includes('noopenner') ? relStr : `rel="${rel} noopener"`;
26-
});
27-
return str.replace('href=', 'target="_blank" href=');
31+
const str = match[0];
32+
const href = match[1];
33+
34+
if (!isExternalLink(href, url, external_link.exclude as any) || rTargetAttr.test(str)) {
35+
result += str;
36+
} else {
37+
if (rRelAttr.test(str)) {
38+
result += str.replace(rRelStrAttr, addNoopener).replace('href=', 'target="_blank" href=');
39+
} else {
40+
result += str.replace('href=', 'target="_blank" rel="noopener" href=');
41+
}
2842
}
43+
lastIndex = rATag.lastIndex;
44+
}
45+
result += data.slice(lastIndex);
2946

30-
return str.replace('href=', 'target="_blank" rel="noopener" href=');
31-
});
47+
return result;
3248
}
3349

3450
export = externalLinkFilter;

0 commit comments

Comments
 (0)