-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
linkify-urls-in-code.tsx
92 lines (79 loc) · 2.71 KB
/
linkify-urls-in-code.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import select from 'select-dom';
import linkifyUrls from 'linkify-urls';
import zipTextNodes from 'zip-text-nodes';
import linkifyIssues from 'linkify-issues';
import features from '../libs/features';
import {getOwnerAndRepo} from '../libs/utils';
export function linkifyIssuesInDom(element: Element): void {
const linkified = linkifyIssues(element.textContent!, options);
if (linkified.children.length === 0) { // Children are <a>
return;
}
// Enable native issue title fetch
for (const link of linkified.children as HTMLCollectionOf<HTMLAnchorElement>) {
const issue = link.href.split('/').pop();
link.setAttribute('class', 'issue-link js-issue-link tooltipped tooltipped-ne');
link.setAttribute('data-error-text', 'Failed to load issue title');
link.setAttribute('data-permission-text', 'Issue title is private');
link.setAttribute('data-url', link.href);
link.setAttribute('data-id', `rgh-issue-${issue}`);
}
zipTextNodes(element, linkified);
}
// Shared class necessary to avoid also shortening the links
export const linkifiedURLClass = 'rgh-linkified-code';
// If we are not in a repo, relative issue references won't make sense
// but `user`/`repo` need to be set to avoid breaking errors in `linkify-issues`
// https://github.com/sindresorhus/refined-github/issues/1305
const currentRepo = getOwnerAndRepo();
const options = {
user: currentRepo.ownerName || '/',
repo: currentRepo.repoName || '/',
type: 'dom',
baseUrl: '',
attributes: {
rel: 'noreferrer noopener',
class: linkifiedURLClass // Necessary to avoid also shortening the links
}
};
function init(): false | void {
const wrappers = select.all(`
.js-blob-wrapper:not(.${linkifiedURLClass}),
.blob-wrapper:not(.${linkifiedURLClass}),
.comment-body:not(.${linkifiedURLClass})
`);
if (wrappers.length === 0) {
return false;
}
// Linkify full URLs
// `.blob-code-inner` in diffs
// `pre` in GitHub comments
for (const element of select.all('.blob-code-inner, pre', wrappers)) {
if (element.textContent!.length < 15) { // Must be long enough for a URL
continue;
}
const linkified = linkifyUrls(element.textContent!, options);
if (linkified.children.length === 0) { // Children are <a>
continue;
}
zipTextNodes(element, linkified);
}
// Linkify issue refs in comments
for (const element of select.all('span.pl-c', wrappers)) {
linkifyIssuesInDom(element);
}
// Mark code block as touched
for (const el of wrappers) {
el.classList.add(linkifiedURLClass);
}
}
features.add({
id: __featureName__,
description: 'Linkifies URLs in code.',
screenshot: 'https://cloud.githubusercontent.com/assets/170270/25370217/61718820-29b3-11e7-89c5-2959eaf8cac8.png',
include: [
features.hasCode
],
load: features.onAjaxedPages,
init
});