@@ -55,13 +55,13 @@ TEST: addTests('isCompare', [
5555 'isQuickPR' ,
5656] ) ;
5757
58- export const isCompareWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && getCleanPathname ( url ) . split ( '/' ) . slice ( 3 , 5 ) . includes ( '_compare' ) ;
58+ export const isCompareWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && processPathname ( url ) . split ( '/' ) . slice ( 3 , 5 ) . includes ( '_compare' ) ;
5959TEST: addTests ( 'isCompareWikiPage' , [
6060 'https://github.com/brookhong/Surfingkeys/wiki/_compare/8ebb46b1a12d16fc1af442b7df0ca13ca3bb34dc...80e51eeabe69b15a3f23880ecc36f800b71e6c6d' ,
6161 'https://github.com/brookhong/Surfingkeys/wiki/Color-Themes/_compare/8ebb46b1a12d16fc1af442b7df0ca13ca3bb34dc...80e51eeabe69b15a3f23880ecc36f800b71e6c6d' ,
6262] ) ;
6363
64- 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 ) ) ;
64+ 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 ) ) ;
6565TEST: addTests ( 'isDashboard' , [
6666 'https://github.com///' ,
6767 'https://github.com//' ,
@@ -174,12 +174,12 @@ TEST: addTests('isNewRelease', [
174174 'https://github.com/sindresorhus/refined-github/releases/new' ,
175175] ) ;
176176
177- export const isNewWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && getCleanPathname ( url ) . endsWith ( '/_new' ) ;
177+ export const isNewWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && processPathname ( url ) . endsWith ( '/_new' ) ;
178178TEST: addTests ( 'isNewWikiPage' , [
179179 'https://github.com/tooomm/wikitest/wiki/_new' ,
180180] ) ;
181181
182- export const isNotifications = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => getCleanPathname ( url ) === 'notifications' ;
182+ export const isNotifications = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => processPathname ( url ) === 'notifications' ;
183183TEST: addTests ( 'isNotifications' , [
184184 'https://github.com/notifications' ,
185185] ) ;
@@ -199,7 +199,7 @@ TEST: addTests('isTeamDiscussion', [
199199 'https://github.com/orgs/refined-github/teams/core-team' ,
200200] ) ;
201201
202- export const isOwnUserProfile = ( ) : boolean => getCleanPathname ( ) === getLoggedInUser ( ) ;
202+ export const isOwnUserProfile = ( ) : boolean => processPathname ( ) === getLoggedInUser ( ) ;
203203
204204// If there's a Report Abuse link, we're not part of the org
205205export const isOwnOrganizationProfile = ( ) : boolean => isOrganizationProfile ( ) && ! exists ( '[href*="contact/report-abuse?report="]' ) ;
@@ -365,7 +365,7 @@ TEST: addTests('isEditingRelease', [
365365export const hasReleaseEditor = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isEditingRelease ( url ) || isNewRelease ( url ) ;
366366TEST: addTests ( 'hasReleaseEditor' , combinedTestOnly ) ;
367367
368- export const isEditingWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && getCleanPathname ( url ) . endsWith ( '/_edit' ) ;
368+ export const isEditingWikiPage = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => isRepoWiki ( url ) && processPathname ( url ) . endsWith ( '/_edit' ) ;
369369TEST: addTests ( 'isEditingWikiPage' , [
370370 'https://github.com/tooomm/wikitest/wiki/Getting-Started/_edit' ,
371371] ) ;
@@ -374,7 +374,7 @@ export const hasWikiPageEditor = (url: URL | HTMLAnchorElement | Location = loca
374374TEST: addTests ( 'hasWikiPageEditor' , combinedTestOnly ) ;
375375
376376export const isRepo = ( url : URL | HTMLAnchorElement | Location = location ) : boolean => {
377- const [ user , repo , extra ] = getCleanPathname ( url ) . split ( '/' ) ;
377+ const [ user , repo , extra ] = processPathname ( url ) . split ( '/' ) ;
378378 return Boolean ( user
379379 && repo
380380 && ! reservedNames . includes ( user )
@@ -704,7 +704,7 @@ const doesLookLikeAProfile = (string: string | undefined): boolean =>
704704
705705export const isProfile = ( url : URL | HTMLAnchorElement | Location = location ) : boolean =>
706706 ! isGist ( url )
707- && doesLookLikeAProfile ( getCleanPathname ( url ) ) ;
707+ && doesLookLikeAProfile ( processPathname ( url ) ) ;
708708
709709TEST: addTests ( 'isProfile' , [
710710 'https://github.com/fregante' ,
@@ -822,7 +822,7 @@ TEST: addTests('isRepoGitObject', [
822822/** Covers blob, trees and blame pages */
823823export const isRepoGitObject = ( url : URL | HTMLAnchorElement | Location = location ) : boolean =>
824824 isRepo ( url )
825- && [ undefined , 'blob' , 'tree' , 'blame' ] . includes ( getCleanPathname ( url ) . split ( '/' ) [ 2 ] ) ;
825+ && [ undefined , 'blob' , 'tree' , 'blame' ] . includes ( processPathname ( url ) . split ( '/' ) [ 2 ] ) ;
826826
827827TEST: addTests ( 'hasFiles' , combinedTestOnly ) ;
828828/** Has a list of files */
@@ -874,7 +874,7 @@ export const canUserAdminRepo = (): boolean => {
874874 ] . join ( ',' ) } ) a[href="/${ repo . nameWithOwner } /settings"]`) ) ;
875875} ;
876876
877- 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 ) ) ) ;
877+ 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 ) ) ) ;
878878TEST: addTests ( 'isNewRepo' , [
879879 'https://github.com/new' ,
880880 'https://github.com/organizations/npmhub/repositories/new' ,
@@ -889,11 +889,19 @@ TEST: addTests('isNewRepoTemplate', [
889889/** Get the logged-in user’s username */
890890const getLoggedInUser = ( ) : string | undefined => $ ( 'meta[name="user-login"]' ) ?. getAttribute ( 'content' ) ?? undefined ;
891891
892- /** Drop all redundant slashes */
893- const getCleanPathname = ( url : URL | HTMLAnchorElement | Location = location ) : string => url . pathname . replaceAll ( / \/ \/ + / g, '/' ) . replace ( / \/ $ / , '' ) . slice ( 1 ) ;
892+ /** Decode it and drop all redundant slashes */
893+ const processPathname = ( url : URL | HTMLAnchorElement | Location = location ) : string =>
894+ url . pathname
895+ . split ( "/" )
896+ . map ( ( part ) => decodeURIComponent ( part ) )
897+ . join ( '/' )
898+ . replaceAll ( / \/ \/ + / g, "/" )
899+ . replace ( / \/ $ / , "" )
900+ . slice ( 1 ) ;
901+
894902
895903const getCleanGistPathname = ( url : URL | HTMLAnchorElement | Location = location ) : string | undefined => {
896- const pathname = getCleanPathname ( url ) ;
904+ const pathname = processPathname ( url ) ;
897905 if ( url . hostname . startsWith ( 'gist.' ) ) {
898906 return pathname ;
899907 }
@@ -903,7 +911,7 @@ const getCleanGistPathname = (url: URL | HTMLAnchorElement | Location = location
903911} ;
904912
905913const getOrg = ( url : URL | HTMLAnchorElement | Location = location ) : { name : string ; path : string } | undefined => {
906- const [ orgs , name , ...path ] = getCleanPathname ( url ) . split ( '/' ) ;
914+ const [ orgs , name , ...path ] = processPathname ( url ) . split ( '/' ) ;
907915 if ( orgs === 'orgs' && name ) {
908916 return { name, path : path . join ( '/' ) } ;
909917 }
@@ -949,7 +957,7 @@ const getRepo = (url?: URL | HTMLAnchorElement | Location | string): RepositoryI
949957 if ( canonical ) {
950958 const canonicalUrl = new URL ( canonical . content , location . origin ) ;
951959 // Sometimes GitHub sets the canonical to an incomplete URL, so it can't be used
952- if ( getCleanPathname ( canonicalUrl ) . toLowerCase ( ) === getCleanPathname ( location ) . toLowerCase ( ) ) {
960+ if ( processPathname ( canonicalUrl ) . toLowerCase ( ) === processPathname ( location ) . toLowerCase ( ) ) {
953961 url = canonicalUrl ;
954962 }
955963 }
@@ -963,7 +971,7 @@ const getRepo = (url?: URL | HTMLAnchorElement | Location | string): RepositoryI
963971 return ;
964972 }
965973
966- const [ owner , name , ...pathParts ] = getCleanPathname ( url ) . split ( '/' ) as [ string , string , string ] ;
974+ const [ owner , name , ...pathParts ] = processPathname ( decodePathname ( url ) ) . split ( '/' ) as [ string , string , string ] ;
967975 return {
968976 owner,
969977 name,
@@ -976,7 +984,7 @@ const getRepo = (url?: URL | HTMLAnchorElement | Location | string): RepositoryI
976984export const utils = {
977985 getOrg,
978986 getLoggedInUser,
979- getCleanPathname ,
987+ processPathname ,
980988 getCleanGistPathname,
981989 getRepositoryInfo : getRepo ,
982990 parseRepoExplorerTitle,
0 commit comments