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
|
import select from 'select-dom';
import linkifyUrls from 'linkify-urls';
import linkifyIssues from 'linkify-issues';
import features from '../libs/features';
import getTextNodes from '../libs/get-text-nodes';
import {getOwnerAndRepo} from '../libs/utils';
// 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
}
};
export const editTextNodes = (fn, el) => {
for (const textNode of getTextNodes(el)) {
if (fn === linkifyUrls && textNode.textContent.length < 11) { // Shortest url: http://j.mp
continue;
}
const linkified = fn(textNode.textContent, options);
if (linkified.children.length > 0) { // Children are <a>
if (fn === linkifyIssues) {
// Enable native issue title fetch
for (const link of linkified.children) {
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}`);
}
}
textNode.replaceWith(linkified);
}
}
};
function init() {
const wrappers = select.all(`
.blob-wrapper:not(.${linkifiedURLClass}),
.comment-body:not(.${linkifiedURLClass})
`);
// Don't linkify any already linkified code
if (wrappers.length === 0) {
return false;
}
// Linkify full URLs
// `.blob-code-inner` in diffs
// `pre` in GitHub comments
for (const el of select.all('.blob-code-inner, pre', wrappers)) {
editTextNodes(linkifyUrls, el);
}
// Linkify issue refs in comments
for (const el of select.all('span.pl-c', wrappers)) {
editTextNodes(linkifyIssues, el);
}
// Mark code block as touched
for (const el of wrappers) {
el.classList.add(linkifiedURLClass);
}
}
features.add({
id: 'linkify-urls-in-code',
load: features.onAjaxedPages,
init
});
|