diff --git a/__snapshots__/index.test.js.snap b/__snapshots__/index.test.js.snap
index a18cc02..1833926 100644
--- a/__snapshots__/index.test.js.snap
+++ b/__snapshots__/index.test.js.snap
@@ -40,6 +40,8 @@ exports[`https://github.com/fregante/shorten-repo-url/blame/v0.12/.gitignore 1`]
exports[`https://github.com/fregante/shorten-repo-url/blob/cc8fc46/.gitignore 1`] = `cc8fc46
/.gitignore`;
+exports[`https://github.com/fregante/shorten-repo-url/blob/main/한글.txt 1`] = `main
/한글.txt`;
+
exports[`https://github.com/fregante/shorten-repo-url/blob/master/.gitignore 1`] = `master
/.gitignore`;
exports[`https://github.com/fregante/shorten-repo-url/blob/v0.12/.gitignore 1`] = `v0.12
/.gitignore`;
@@ -202,6 +204,10 @@ exports[`https://github.com/refined-github/refined-github/wiki/%22Can-you-add-th
exports[`https://github.com/refined-github/refined-github/wiki/%22Can-you-add-this-feature%3F%22#3-it-doesnt-require-options 1`] = `Wiki: "Can you add this feature?" (3 it doesnt require options) (refined-github/refined-github)`;
+exports[`https://github.com/scarf005/hangul-test/wiki/한글-위키-페이지 1`] = `Wiki: 한글 위키 페이지 (scarf005/hangul-test)`;
+
+exports[`https://github.com/scarf005/hangul-test/wiki/한글-위키-페이지#한글-헤딩 1`] = `Wiki: 한글 위키 페이지 (한글 헤딩) (scarf005/hangul-test)`;
+
exports[`https://github.com/settings/profile 1`] = `github.com/settings/profile`;
exports[`https://github.com/sindresorhus 1`] = `@sindresorhus`;
@@ -261,3 +267,5 @@ exports[`https://www.npmjs.com/ 1`] = `npmjs.com`;
exports[`https://www.npmjs.com/packaasdge/node 1`] = `npmjs.com/packaasdge/node`;
exports[`https://wwww.google.com/ 1`] = `wwww.google.com`;
+
+exports[`https://한글로-된-경로.com/하위경로#한글-해시 1`] = `한글로-된-경로.com/하위경로#한글-해시`;
diff --git a/index.js b/index.js
index 399efdb..1a1abfe 100644
--- a/index.js
+++ b/index.js
@@ -81,16 +81,15 @@ function shortenRepoUrl(href, currentUrl = 'https://github.com') {
const currentRepo = currentUrl.pathname.slice(1).split('/', 2).join('/');
/**
- * Parse URL
+ * Parse URL manually to avoid URL encoding and punycode
*/
+ const origin = href.split('/', 3).join('/');
+ const pathname = href.slice(origin.length).replace(/[?#].*/, '');
+ const hash = /#.+$/.exec(href)?.[0] ?? '';
+
+ // Use URL exclusively for search parameters because they're too hard to parse
const url = new URL(href);
- const {
- origin,
- pathname,
- search,
- searchParams,
- hash,
- } = url;
+ const {search, searchParams} = url;
const pathnameParts = pathname.slice(1).split('/'); // ['user', 'repo', 'pull', '342']
const repoPath = pathnameParts.slice(2).join('/'); // 'pull/342'
@@ -158,31 +157,24 @@ function shortenRepoUrl(href, currentUrl = 'https://github.com') {
* Shorten URL
*/
if (isReserved || pathname === '/' || (!isLocal && !isRaw && !isRedirection)) {
- const parsedUrl = new URL(href);
const cleanHref = [
- parsedUrl.origin
+ origin
.replace(/^https:[/][/]/, '')
.replace(/^www[.]/, ''),
- parsedUrl.pathname
+ pathname
.replace(/[/]$/, ''),
];
if (['issues', 'pulls'].includes(user) && !repo) {
- const query = pullQueryOut(parsedUrl.searchParams, parsedUrl.pathname);
- cleanHref.push(parsedUrl.search, query);
+ const query = pullQueryOut(url.searchParams, url.pathname);
+ cleanHref.push(url.search, query);
} else {
- cleanHref.push(parsedUrl.search);
+ cleanHref.push(url.search);
}
- cleanHref.push(parsedUrl.hash);
+ cleanHref.push(decodeURI(url.hash));
- // The user prefers seeing the URL as it was typed, so we need to decode it
- try {
- return decodeURI(cleanHref.join(''));
- } catch {
- // Decoding fails if the URL includes '%%'
- return href;
- }
+ return cleanHref.join('');
}
if (user && !repo) {
@@ -290,16 +282,18 @@ function shortenRepoUrl(href, currentUrl = 'https://github.com') {
*/
function safeDecode(url) {
try {
- return decodeURIComponent(url);
+ return new URL(url).href;
} catch {
return url;
}
}
+/** @param a {HTMLAnchorElement} */
function getLinkHref(a) {
return a.dataset.originalHref ?? a.href;
}
+/** @param a {HTMLAnchorElement} */
function isCustomLink(a) {
const url = safeDecode(getLinkHref(a));
const label = safeDecode(a.textContent);
@@ -321,7 +315,7 @@ export function applyToLink(a, currentUrl) {
// And if there are no additional images in the link
&& !a.firstElementChild
) {
- const url = getLinkHref(a);
+ const url = a.textContent;
const shortened = shortenRepoUrl(url, currentUrl);
a.replaceChildren(
...shortened.split(
diff --git a/index.test.js b/index.test.js
index fd8dac0..f7ec7e7 100644
--- a/index.test.js
+++ b/index.test.js
@@ -32,6 +32,7 @@ const urls = [
'https://github.com/fregante/shorten-repo-url/blob/master/.gitignore',
'https://github.com/fregante/shorten-repo-url/blob/v0.12/.gitignore',
'https://github.com/fregante/shorten-repo-url/blob/cc8fc46/.gitignore',
+ 'https://github.com/fregante/shorten-repo-url/blob/main/한글.txt',
'https://github.com/nodejs/node/blob/master/.gitignore',
'https://github.com/nodejs/node/blob/v0.12/.gitignore',
'https://github.com/nodejs/node/blob/cc8fc46/.gitignore',
@@ -138,6 +139,8 @@ const urls = [
'https://github.com/refined-github/refined-github/wiki/%22Can-you-add-this-feature%3F%22#',
'https://github.com/refined-github/refined-github/wiki/%22Can-you-add-this-feature%3F%22',
'https://github.com/fregante/shorten-repo-url/wiki/%22Can-you-add-this-feature%3F%22',
+ 'https://github.com/scarf005/hangul-test/wiki/한글-위키-페이지',
+ 'https://github.com/scarf005/hangul-test/wiki/한글-위키-페이지#한글-헤딩',
'https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement#parameters',
'https://www.google.com/',
'https://wwww.google.com/',
@@ -146,6 +149,7 @@ const urls = [
'https://www.npmjs.com/packaasdge/node',
'https://example.com/nodejs/node/blob/cc8fc46/.gitignore',
'https://example.site/한글로-된-URL',
+ 'https://한글로-된-경로.com/하위경로#한글-해시',
];
test.each(urls)('%s', url => {