Skip to content

Commit d49c55c

Browse files
authored
Merge branch 'main' into pathParts
2 parents c2a0098 + 9ebd678 commit d49c55c

File tree

4 files changed

+106
-13
lines changed

4 files changed

+106
-13
lines changed

.github/workflows/demo.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ jobs:
1515
build:
1616
runs-on: ubuntu-latest
1717
steps:
18-
- uses: actions/checkout@v3
18+
- uses: actions/checkout@v4
1919
- run: npm ci
2020
- run: npm run build:demo
2121
- run: npm run test:demo
2222
- run: grep -rq "/fregante/" ./demo/dist
2323
# https://github.com/refined-github/github-url-detection/pull/161
2424
name: Ensure that the demo is built correctly
2525
- name: Upload artifact
26-
uses: actions/upload-pages-artifact@v1
26+
uses: actions/upload-pages-artifact@v3
2727
with:
2828
path: demo/dist/
2929

@@ -42,4 +42,4 @@ jobs:
4242
steps:
4343
- name: Deploy to GitHub Pages
4444
id: deployment
45-
uses: actions/deploy-pages@v1
45+
uses: actions/deploy-pages@v4

index.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,48 @@ test('getRepositoryInfo', () => {
162162
expect(getRepositoryInfoAdapter('https://github.com/refined-github/github-url-detection/tree/master/distribution/')).toMatchSnapshot();
163163
}
164164
});
165+
166+
test('parseRepoExplorerTitle', () => {
167+
const parse = pageDetect.utils.parseRepoExplorerTitle;
168+
169+
assert.deepEqual(
170+
parse('/eslint/js/tree/2.x', 'eslint/js at 2.x'),
171+
{
172+
nameWithOwner: 'eslint/js',
173+
branch: '2.x',
174+
filePath: '',
175+
},
176+
);
177+
assert.deepEqual(
178+
parse('/eslint/js/tree/2.x', 'js/ at 2.x · eslint/js'),
179+
{
180+
nameWithOwner: 'eslint/js',
181+
branch: '2.x',
182+
filePath: '',
183+
},
184+
);
185+
assert.deepEqual(
186+
parse('/eslint/js/tree/2.x/tools', 'js/tools at 2.x · eslint/js'),
187+
{
188+
nameWithOwner: 'eslint/js',
189+
branch: '2.x',
190+
filePath: 'tools',
191+
},
192+
);
193+
assert.deepEqual(
194+
parse('/eslint/js/tree/2.x/docs/ast', 'js/docs/ast at 2.x · eslint/js'),
195+
{
196+
nameWithOwner: 'eslint/js',
197+
branch: '2.x',
198+
filePath: 'docs/ast',
199+
},
200+
);
201+
assert.deepEqual(
202+
parse('https://github.com/eslint/js', 'only /tree/ URLs are supported'),
203+
undefined,
204+
);
205+
assert.deepEqual(
206+
parse('https://github.com/eslint/js/issues', 'irrelephant'),
207+
undefined,
208+
);
209+
});

index.ts

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -449,25 +449,71 @@ TEST: addTests('isRepoHome', [
449449
'https://github.com/sindresorhus/refined-github?files=1',
450450
]);
451451

452+
export type RepoExplorerInfo = {
453+
nameWithOwner: string;
454+
branch: string;
455+
filePath: string;
456+
};
457+
458+
// https://github.com/eslint/js/tree/2.x ->'eslint/js at 2.x'
459+
// https://github.com/eslint/js/tree/2.x ->'js/ at 2.x · eslint/js'
460+
// https://github.com/eslint/js/tree/2.x/tools -> 'js/tools at 2.x · eslint/js'
461+
const titleParseRegex = /^(?:(?<nameWithOwner>[^ ]+) at (?<branch>[^ ]+)|[^/ ]+(?:\/(?<filePath>[^ ]*))? at (?<branch2>[^ ]+)(?: · (?<nameWithOwner2>[^ ]+))?)$/;
462+
// TODO: Reuse regex group names on the next MAJOR version https://github.com/tc39/proposal-duplicate-named-capturing-groups/issues/4
463+
464+
const parseRepoExplorerTitle = (pathname: string, title: string): RepoExplorerInfo | undefined => {
465+
const match = titleParseRegex.exec(title);
466+
if (!match?.groups) {
467+
return;
468+
}
469+
470+
let {nameWithOwner, branch, filePath, nameWithOwner2, branch2} = match.groups;
471+
472+
nameWithOwner ??= nameWithOwner2;
473+
branch ??= branch2;
474+
filePath ??= '';
475+
476+
if (!nameWithOwner || !branch || !pathname.startsWith(`/${nameWithOwner}/tree/`)) {
477+
return;
478+
}
479+
480+
return {nameWithOwner, branch, filePath};
481+
};
482+
452483
const _isRepoRoot = (url?: URL | HTMLAnchorElement | Location): boolean => {
453484
const repository = getRepo(url ?? location);
454485

455486
if (!repository) {
487+
// Not a repo
456488
return false;
457489
}
458490

459-
if (!repository.path) {
460-
// Absolute repo root: `isRepoHome`
461-
return true;
462-
}
491+
const path = repository.path ? repository.path.split('/') : [];
463492

464-
if (url) {
465-
// Root of a branch/commit/tag
466-
return /^tree\/[^/]+$/.test(repository.path);
467-
}
493+
switch (path.length) {
494+
case 0: {
495+
// Absolute repo root: `isRepoHome`
496+
return true;
497+
}
498+
499+
case 2: {
500+
// 100% certainty that it's a root if it's `tree`
501+
return path[0] === 'tree';
502+
}
468503

469-
// If we're checking the current page, add support for branches with slashes // #15 #24
470-
return repository.path.startsWith('tree/') && document.title.startsWith(repository.nameWithOwner) && !document.title.endsWith(repository.nameWithOwner);
504+
default: {
505+
if (url) {
506+
// From the URL we can safely only know it's a root if it's `user/repo/tree/something`
507+
// With `user/repo/tree/something/else` we can't be sure whether `else` is a folder or still the branch name ("something/else")
508+
return false;
509+
}
510+
511+
// If we're checking the current page, add support for branches with slashes
512+
const titleInfo = parseRepoExplorerTitle(location.pathname, document.title);
513+
514+
return titleInfo?.filePath === '';
515+
}
516+
}
471517
};
472518

473519
// `_isRepoRoot` logic depends on whether a URL was passed, so don't use a `url` default parameter
@@ -864,4 +910,5 @@ export const utils = {
864910
getCleanPathname,
865911
getCleanGistPathname,
866912
getRepositoryInfo: getRepo,
913+
parseRepoExplorerTitle,
867914
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"build:esbuild": "esbuild index.ts --bundle --external:github-reserved-names --outdir=distribution --format=esm --drop-labels=TEST",
2929
"build:typescript": "tsc --declaration --emitDeclarationOnly",
3030
"build:demo": "vite build demo",
31+
"try": "esbuild index.ts --bundle --global-name=x --format=iife | pbcopy && echo 'Copied to clipboard'",
3132
"fix": "xo --fix",
3233
"prepack": "npm run build",
3334
"test": "run-p build test:* xo",

0 commit comments

Comments
 (0)