@@ -100,7 +100,7 @@ TEST: addTests('isCompare', [
100100 'isQuickPR' ,
101101] ) ;
102102
103- export const isCompareWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && getCleanPathname ( url ) . split ( '/' ) . slice ( 3 , 5 ) . includes ( '_compare' ) ;
103+ export const isCompareWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && processPathname ( url ) . split ( '/' ) . slice ( 3 , 5 ) . includes ( '_compare' ) ;
104104TEST: addTests ( 'isCompareWikiPage' , [
105105 'https://github.com/brookhong/Surfingkeys/wiki/_compare/8ebb46b1a12d16fc1af442b7df0ca13ca3bb34dc...80e51eeabe69b15a3f23880ecc36f800b71e6c6d' ,
106106 'https://github.com/brookhong/Surfingkeys/wiki/Color-Themes/_compare/8ebb46b1a12d16fc1af442b7df0ca13ca3bb34dc...80e51eeabe69b15a3f23880ecc36f800b71e6c6d' ,
@@ -109,7 +109,7 @@ TEST: addTests('isCompareWikiPage', [
109109/**
110110 * @deprecated Use `isHome` and/or `isFeed` instead
111111 */
112- export const isDashboard = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && / ^ $ | ^ ( o r g s \/ [ ^ / ] + \/ ) ? d a s h b o a r d ( - f e e d ) ? ( \/ | $ ) / . test ( getCleanPathname ( url ) ) ;
112+ export const isDashboard = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && / ^ $ | ^ ( o r g s \/ [ ^ / ] + \/ ) ? d a s h b o a r d ( - f e e d ) ? ( \/ | $ ) / . test ( processPathname ( url ) ) ;
113113TEST: addTests ( 'isDashboard' , [
114114 'https://github.com///' ,
115115 'https://github.com//' ,
@@ -131,7 +131,7 @@ TEST: addTests('isDashboard', [
131131 'https://github.com/dashboard-feed' ,
132132] ) ;
133133
134- export const isHome = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && / ^ $ | ^ d a s h b o a r d \/ ? $ / . test ( getCleanPathname ( url ) ) ;
134+ export const isHome = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && / ^ $ | ^ d a s h b o a r d \/ ? $ / . test ( processPathname ( url ) ) ;
135135TEST: addTests ( 'isHome' , [
136136 'https://github.com' ,
137137 'https://github.com//dashboard' ,
@@ -150,7 +150,7 @@ TEST: addTests('isHome', [
150150 'https://github.com?search=1' , // Gotcha for `isRepoTree`
151151] ) ;
152152
153- export const isFeed = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && / ^ ( f e e d | o r g s \/ [ ^ / ] + \/ d a s h b o a r d ) \/ ? $ / . test ( getCleanPathname ( url ) ) ;
153+ export const isFeed = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && / ^ ( f e e d | o r g s \/ [ ^ / ] + \/ d a s h b o a r d ) \/ ? $ / . test ( processPathname ( url ) ) ;
154154TEST: addTests ( 'isFeed' , [
155155 'https://github.com/feed' ,
156156 'https://github.com/orgs/refined-github/dashboard' ,
@@ -246,12 +246,12 @@ TEST: addTests('isNewRelease', [
246246 'https://github.com/sindresorhus/refined-github/releases/new' ,
247247] ) ;
248248
249- export const isNewWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && getCleanPathname ( url ) . endsWith ( '/_new' ) ;
249+ export const isNewWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && processPathname ( url ) . endsWith ( '/_new' ) ;
250250TEST: addTests ( 'isNewWikiPage' , [
251251 'https://github.com/tooomm/wikitest/wiki/_new' ,
252252] ) ;
253253
254- export const isNotifications = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => getCleanPathname ( url ) === 'notifications' ;
254+ export const isNotifications = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => processPathname ( url ) === 'notifications' ;
255255TEST: addTests ( 'isNotifications' , [
256256 'https://github.com/notifications' ,
257257] ) ;
@@ -271,7 +271,7 @@ TEST: addTests('isTeamDiscussion', [
271271 'https://github.com/orgs/refined-github/teams/core-team' ,
272272] ) ;
273273
274- export const isOwnUserProfile = ( ) : boolean => getCleanPathname ( ) === getLoggedInUser ( ) ;
274+ export const isOwnUserProfile = ( ) : boolean => processPathname ( ) === getLoggedInUser ( ) ;
275275
276276// If there's a Report Abuse link, we're not part of the org
277277export const isOwnOrganizationProfile = ( ) : boolean => isOrganizationProfile ( ) && ! exists ( '[href*="contact/report-abuse?report="]' ) ;
@@ -437,7 +437,7 @@ TEST: addTests('isEditingRelease', [
437437export const hasReleaseEditor = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isEditingRelease ( url ) || isNewRelease ( url ) ;
438438TEST: addTests ( 'hasReleaseEditor' , combinedTestOnly ) ;
439439
440- export const isEditingWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && getCleanPathname ( url ) . endsWith ( '/_edit' ) ;
440+ export const isEditingWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && processPathname ( url ) . endsWith ( '/_edit' ) ;
441441TEST: addTests ( 'isEditingWikiPage' , [
442442 'https://github.com/tooomm/wikitest/wiki/Getting-Started/_edit' ,
443443] ) ;
@@ -446,7 +446,7 @@ export const hasWikiPageEditor = (url: URL | HTMLAnchorElement | Location = loca
446446TEST: addTests ( 'hasWikiPageEditor' , combinedTestOnly ) ;
447447
448448export const isRepo = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => {
449- const [ user , repo , extra ] = getCleanPathname ( url ) . split ( '/' ) ;
449+ const [ user , repo , extra ] = processPathname ( url ) . split ( '/' ) ;
450450 return Boolean ( user
451451 && repo
452452 && ! reservedNames . includes ( user )
@@ -776,7 +776,7 @@ const doesLookLikeAProfile = (string: string | undefined): boolean =>
776776
777777export const isProfile = ( url : URL | HTMLAnchorElement | Location = location ) : boolean =>
778778 ! isGist ( url )
779- && doesLookLikeAProfile ( getCleanPathname ( url ) ) ;
779+ && doesLookLikeAProfile ( processPathname ( url ) ) ;
780780
781781TEST: addTests ( 'isProfile' , [
782782 'https://github.com/fregante' ,
@@ -894,7 +894,7 @@ TEST: addTests('isRepoGitObject', [
894894/** Covers blob, trees and blame pages */
895895export const isRepoGitObject = ( url : URL | HTMLAnchorElement | Location = location ) : boolean =>
896896 isRepo ( url )
897- && [ undefined , 'blob' , 'tree' , 'blame' ] . includes ( getCleanPathname ( url ) . split ( '/' ) [ 2 ] ) ;
897+ && [ undefined , 'blob' , 'tree' , 'blame' ] . includes ( processPathname ( url ) . split ( '/' ) [ 2 ] ) ;
898898
899899TEST: addTests ( 'hasFiles' , combinedTestOnly ) ;
900900/** Has a list of files */
@@ -952,7 +952,7 @@ export const canUserAdminRepo = (): boolean => {
952952// eslint-disable-next-line @typescript-eslint/no-deprecated
953953export const canUserAccessRepoSettings = canUserAdminRepo ;
954954
955- export const isNewRepo = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && ( url . pathname === '/new' || / ^ o r g a n i z a t i o n s \/ [ ^ / ] + \/ r e p o s i t o r i e s \/ n e w $ / . test ( getCleanPathname ( url ) ) ) ;
955+ export const isNewRepo = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => ! isGist ( url ) && ( url . pathname === '/new' || / ^ o r g a n i z a t i o n s \/ [ ^ / ] + \/ r e p o s i t o r i e s \/ n e w $ / . test ( processPathname ( url ) ) ) ;
956956TEST: addTests ( 'isNewRepo' , [
957957 'https://github.com/new' ,
958958 'https://github.com/organizations/npmhub/repositories/new' ,
@@ -967,11 +967,18 @@ TEST: addTests('isNewRepoTemplate', [
967967/** Get the logged-in user’s username */
968968const getLoggedInUser = ( ) : string | undefined => $ ( 'meta[name="user-login"]' ) ?. getAttribute ( 'content' ) ?? undefined ;
969969
970- /** Drop all redundant slashes */
971- const getCleanPathname = ( url : URL | HTMLAnchorElement | Location = location ) : string => url . pathname . replaceAll ( / \/ \/ + / g, '/' ) . replace ( / \/ $ / , '' ) . slice ( 1 ) ;
970+ /** Decode it and drop all redundant slashes */
971+ const processPathname = ( url : URL | HTMLAnchorElement | Location = location ) : string =>
972+ url . pathname
973+ . split ( '/' )
974+ . map ( part => decodeURIComponent ( part ) )
975+ . join ( '/' )
976+ . replaceAll ( / \/ \/ + / g, '/' )
977+ . replace ( / \/ $ / , '' )
978+ . slice ( 1 ) ;
972979
973980const getCleanGistPathname = ( url : URL | HTMLAnchorElement | Location = location ) : string | undefined => {
974- const pathname = getCleanPathname ( url ) ;
981+ const pathname = processPathname ( url ) ;
975982 if ( url . hostname . startsWith ( 'gist.' ) ) {
976983 return pathname ;
977984 }
@@ -981,7 +988,7 @@ const getCleanGistPathname = (url: URL | HTMLAnchorElement | Location = location
981988} ;
982989
983990const getOrg = ( url : URL | HTMLAnchorElement | Location = location ) : { name : string ; path : string } | undefined => {
984- const [ orgs , name , ...path ] = getCleanPathname ( url ) . split ( '/' ) ;
991+ const [ orgs , name , ...path ] = processPathname ( url ) . split ( '/' ) ;
985992 if ( orgs === 'orgs' && name ) {
986993 return { name, path : path . join ( '/' ) } ;
987994 }
@@ -1027,7 +1034,7 @@ const getRepo = (url?: URL | HTMLAnchorElement | Location | string): RepositoryI
10271034 if ( canonical ) {
10281035 const canonicalUrl = new URL ( canonical . content , location . origin ) ;
10291036 // Sometimes GitHub sets the canonical to an incomplete URL, so it can't be used
1030- if ( getCleanPathname ( canonicalUrl ) . toLowerCase ( ) === getCleanPathname ( location ) . toLowerCase ( ) ) {
1037+ if ( processPathname ( canonicalUrl ) . toLowerCase ( ) === processPathname ( location ) . toLowerCase ( ) ) {
10311038 url = canonicalUrl ;
10321039 }
10331040 }
@@ -1041,7 +1048,7 @@ const getRepo = (url?: URL | HTMLAnchorElement | Location | string): RepositoryI
10411048 return ;
10421049 }
10431050
1044- const [ owner , name , ...pathParts ] = getCleanPathname ( url ) . split ( '/' ) as [ string , string , string ] ;
1051+ const [ owner , name , ...pathParts ] = processPathname ( url ) . split ( '/' ) as [ string , string , string ] ;
10451052 return {
10461053 owner,
10471054 name,
@@ -1054,7 +1061,7 @@ const getRepo = (url?: URL | HTMLAnchorElement | Location | string): RepositoryI
10541061export const utils = {
10551062 getOrg,
10561063 getLoggedInUser,
1057- getCleanPathname ,
1064+ processPathname ,
10581065 getCleanGistPathname,
10591066 getRepositoryInfo : getRepo ,
10601067 parseRepoExplorerTitle,
0 commit comments