diff options
author | 2019-01-17 19:57:53 +0700 | |
---|---|---|
committer | 2019-01-17 19:57:53 +0700 | |
commit | 11b927189bab258a226e251c1bd87504feee51f4 (patch) | |
tree | 89b3cf4ba9e6b49afd65b8f9a59a7ca33e46efe3 /source/features/linkify-urls-in-code.tsx | |
parent | f25483fa128d9dcc8e1e74fcf2d2751d604fe11f (diff) | |
download | refined-github-11b927189bab258a226e251c1bd87504feee51f4.tar.gz refined-github-11b927189bab258a226e251c1bd87504feee51f4.tar.zst refined-github-11b927189bab258a226e251c1bd87504feee51f4.zip |
Drop Babel in favor of esm and TypeScript (#1726)
To get some meaningful errors during feature development, I thought it'd be useful to use TypeScript on `features.js` only, hoping to keep it contained to that file.
@sindresorhus suggested we just extend it the whole extension and maybe that can be done incrementally, without having to necessarily use types on everything.
Diffstat (limited to 'source/features/linkify-urls-in-code.tsx')
-rw-r--r-- | source/features/linkify-urls-in-code.tsx | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/source/features/linkify-urls-in-code.tsx b/source/features/linkify-urls-in-code.tsx new file mode 100644 index 00000000..d41178ae --- /dev/null +++ b/source/features/linkify-urls-in-code.tsx @@ -0,0 +1,82 @@ +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/page-detect'; + +// 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 +}); |