github-url-detection 7.1.2 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,6 +31,7 @@ export declare const isOwnOrganizationProfile: () => boolean;
31
31
  export declare const isProject: (url?: URL | HTMLAnchorElement | Location) => boolean;
32
32
  export declare const isProjects: (url?: URL | HTMLAnchorElement | Location) => boolean;
33
33
  export declare const isDiscussion: (url?: URL | HTMLAnchorElement | Location) => boolean;
34
+ export declare const isNewDiscussion: (url?: URL | HTMLAnchorElement | Location) => boolean;
34
35
  export declare const isDiscussionList: (url?: URL | HTMLAnchorElement | Location) => boolean;
35
36
  export declare const isPR: (url?: URL | HTMLAnchorElement | Location) => boolean;
36
37
  export declare const isPRConflicts: (url?: URL | HTMLAnchorElement | Location) => boolean;
@@ -50,7 +51,7 @@ export declare const isClosedPR: () => boolean;
50
51
  export declare const isClosedIssue: () => boolean;
51
52
  export declare const isReleases: (url?: URL | HTMLAnchorElement | Location) => boolean;
52
53
  export declare const isTags: (url?: URL | HTMLAnchorElement | Location) => boolean;
53
- export declare const isSingleTag: (url?: URL | HTMLAnchorElement | Location) => boolean;
54
+ export declare const isSingleReleaseOrTag: (url?: URL | HTMLAnchorElement | Location) => boolean;
54
55
  export declare const isReleasesOrTags: (url?: URL | HTMLAnchorElement | Location) => boolean;
55
56
  export declare const isDeletingFile: (url?: URL | HTMLAnchorElement | Location) => boolean;
56
57
  export declare const isEditingFile: (url?: URL | HTMLAnchorElement | Location) => boolean;
@@ -82,6 +83,11 @@ export declare const isRepoWiki: (url?: URL | HTMLAnchorElement | Location) => b
82
83
  export declare const isSingleCommit: (url?: URL | HTMLAnchorElement | Location) => boolean;
83
84
  export declare const isSingleFile: (url?: URL | HTMLAnchorElement | Location) => boolean;
84
85
  export declare const isFileFinder: (url?: URL | HTMLAnchorElement | Location) => boolean;
86
+ /**
87
+ * @example https://github.com/fregante/GhostText/tree/3cacd7df71b097dc525d99c7aa2f54d31b02fcc8/chrome/scripts/InputArea
88
+ * @example https://github.com/refined-github/refined-github/blob/some-non-existent-ref/source/features/bugs-tab.tsx
89
+ */
90
+ export declare const isRepoFile404: (url?: URL | HTMLAnchorElement | Location) => boolean;
85
91
  export declare const isRepoForksList: (url?: URL | HTMLAnchorElement | Location) => boolean;
86
92
  export declare const isRepoNetworkGraph: (url?: URL | HTMLAnchorElement | Location) => boolean;
87
93
  export declare const isForkedRepo: () => boolean;
@@ -98,6 +104,7 @@ export declare const isUserProfileRepoTab: (url?: URL | HTMLAnchorElement | Loca
98
104
  export declare const isUserProfileStarsTab: (url?: URL | HTMLAnchorElement | Location) => boolean;
99
105
  export declare const isUserProfileFollowersTab: (url?: URL | HTMLAnchorElement | Location) => boolean;
100
106
  export declare const isUserProfileFollowingTab: (url?: URL | HTMLAnchorElement | Location) => boolean;
107
+ export declare const isProfileRepoList: (url?: URL | HTMLAnchorElement | Location) => boolean;
101
108
  export declare const hasComments: (url?: URL | HTMLAnchorElement | Location) => boolean;
102
109
  export declare const hasRichTextEditor: (url?: URL | HTMLAnchorElement | Location) => boolean;
103
110
  /** Static code, not the code editor */
@@ -278,7 +278,7 @@ const reservedNames = [
278
278
  ];
279
279
  const $ = (selector) => document.querySelector(selector);
280
280
  const exists = (selector) => Boolean($(selector));
281
- const is404 = () => document.title.startsWith("Page not found · GitHub");
281
+ const is404 = () => /^(Page|File) not found · GitHub/.test(document.title);
282
282
  const is500 = () => document.title === "Server Error · GitHub" || document.title === "Unicorn! · GitHub" || document.title === "504 Gateway Time-out";
283
283
  const isPasswordConfirmation = () => document.title === "Confirm password" || document.title === "Confirm access";
284
284
  const isBlame = (url = location) => Boolean(getRepo(url)?.path.startsWith("blame/"));
@@ -304,13 +304,14 @@ const isNewRelease = (url = location) => getRepo(url)?.path === "releases/new";
304
304
  const isNewWikiPage = (url = location) => isRepoWiki(url) && getCleanPathname(url).endsWith("/_new");
305
305
  const isNotifications = (url = location) => getCleanPathname(url) === "notifications";
306
306
  const isOrganizationProfile = () => exists('meta[name="hovercard-subject-tag"][content^="organization"]');
307
- const isOrganizationRepo = () => Boolean(document.querySelector("[data-owner-scoped-search-url]")?.dataset["ownerScopedSearchUrl"].startsWith("/org"));
307
+ const isOrganizationRepo = () => exists('.AppHeader-context-full [data-hovercard-type="organization"]');
308
308
  const isTeamDiscussion = (url = location) => Boolean(getOrg(url)?.path.startsWith("teams"));
309
309
  const isOwnUserProfile = () => getCleanPathname() === getUsername();
310
310
  const isOwnOrganizationProfile = () => isOrganizationProfile() && !exists('[href*="contact/report-abuse?report="]');
311
311
  const isProject = (url = location) => /^projects\/\d+/.test(getRepo(url)?.path);
312
312
  const isProjects = (url = location) => getRepo(url)?.path === "projects";
313
313
  const isDiscussion = (url = location) => /^discussions\/\d+/.test(getRepo(url)?.path ?? getOrg(url)?.path);
314
+ const isNewDiscussion = (url = location) => getRepo(url)?.path === "discussions/new" || getOrg(url)?.path === "discussions/new";
314
315
  const isDiscussionList = (url = location) => getRepo(url)?.path === "discussions" || getOrg(url)?.path === "discussions";
315
316
  const isPR = (url = location) => /^pull\/\d+/.test(getRepo(url)?.path) && !isPRConflicts(url);
316
317
  const isPRConflicts = (url = location) => /^pull\/\d+\/conflicts/.test(getRepo(url)?.path);
@@ -320,7 +321,7 @@ const isPRCommit404 = () => isPRCommit() && document.title.startsWith("Commit ra
320
321
  const isPRFile404 = () => isPRFiles() && document.title.startsWith("Commit range not found · Pull Request");
321
322
  const isPRConversation = (url = location) => /^pull\/\d+$/.test(getRepo(url)?.path);
322
323
  const isPRCommitList = (url = location) => /^pull\/\d+\/commits$/.test(getRepo(url)?.path);
323
- const isPRFiles = (url = location) => /^pull\/\d+\/files/.test(getRepo(url)?.path);
324
+ const isPRFiles = (url = location) => /^pull\/\d+\/files/.test(getRepo(url)?.path) || isPRCommit(url);
324
325
  const isQuickPR = (url = location) => isCompare(url) && /[?&]quick_pull=1(&|$)/.test(url.search);
325
326
  const isDraftPR = () => exists("#partial-discussion-header .octicon-git-pull-request-draft");
326
327
  const isOpenPR = () => exists("#partial-discussion-header :is(.octicon-git-pull-request, .octicon-git-pull-request-draft)");
@@ -329,8 +330,8 @@ const isClosedPR = () => exists("#partial-discussion-header :is(.octicon-git-pul
329
330
  const isClosedIssue = () => exists("#partial-discussion-header :is(.octicon-issue-closed, .octicon-skip)");
330
331
  const isReleases = (url = location) => getRepo(url)?.path === "releases";
331
332
  const isTags = (url = location) => getRepo(url)?.path === "tags";
332
- const isSingleTag = (url = location) => /^(releases\/tag)/.test(getRepo(url)?.path);
333
- const isReleasesOrTags = (url = location) => isReleases(url) || isTags(url) || isSingleTag(url);
333
+ const isSingleReleaseOrTag = (url = location) => Boolean(getRepo(url)?.path.startsWith("releases/tag"));
334
+ const isReleasesOrTags = (url = location) => isReleases(url) || isTags(url);
334
335
  const isDeletingFile = (url = location) => Boolean(getRepo(url)?.path.startsWith("delete"));
335
336
  const isEditingFile = (url = location) => Boolean(getRepo(url)?.path.startsWith("edit"));
336
337
  const hasFileEditor = (url = location) => isEditingFile(url) || isNewFile(url) || isDeletingFile(url);
@@ -352,8 +353,9 @@ const isRepoIssueList = (url = location) => (
352
353
  // `issues/fregante` is a list but `issues/1`, `issues/new`, `issues/new/choose`, `issues/templates/edit` aren’t
353
354
  /^labels\/|^issues(?!\/(\d+|new|templates)($|\/))/.test(getRepo(url)?.path)
354
355
  );
355
- const isRepoHome = (url = location) => getRepo(url)?.path === "";
356
- const isRepoRoot = (url) => {
356
+ const hasSearchParameter = (url) => new URLSearchParams(url.search).get("search") === "1";
357
+ const isRepoHome = (url = location) => getRepo(url)?.path === "" && !hasSearchParameter(url);
358
+ const _isRepoRoot = (url) => {
357
359
  const repository = getRepo(url ?? location);
358
360
  if (!repository) {
359
361
  return false;
@@ -366,16 +368,18 @@ const isRepoRoot = (url) => {
366
368
  }
367
369
  return repository.path.startsWith("tree/") && document.title.startsWith(repository.nameWithOwner) && !document.title.endsWith(repository.nameWithOwner);
368
370
  };
371
+ const isRepoRoot = (url) => !hasSearchParameter(url ?? location) && _isRepoRoot(url);
369
372
  const isRepoSearch = (url = location) => getRepo(url)?.path === "search";
370
373
  const isRepoSettings = (url = location) => Boolean(getRepo(url)?.path.startsWith("settings"));
371
374
  const isRepoMainSettings = (url = location) => getRepo(url)?.path === "settings";
372
375
  const isRepliesSettings = (url = location) => url.pathname.startsWith("/settings/replies");
373
376
  const isUserSettings = (url = location) => url.pathname.startsWith("/settings/");
374
- const isRepoTree = (url = location) => isRepoRoot(url) || Boolean(getRepo(url)?.path.startsWith("tree/"));
377
+ const isRepoTree = (url = location) => _isRepoRoot(url) || Boolean(getRepo(url)?.path.startsWith("tree/"));
375
378
  const isRepoWiki = (url = location) => Boolean(getRepo(url)?.path.startsWith("wiki"));
376
379
  const isSingleCommit = (url = location) => /^commit\/[\da-f]{5,40}$/.test(getRepo(url)?.path);
377
380
  const isSingleFile = (url = location) => Boolean(getRepo(url)?.path.startsWith("blob/"));
378
381
  const isFileFinder = (url = location) => Boolean(getRepo(url)?.path.startsWith("find/"));
382
+ const isRepoFile404 = (url = location) => (isSingleFile(url) || isRepoTree(url)) && document.title.startsWith("File not found");
379
383
  const isRepoForksList = (url = location) => getRepo(url)?.path === "network/members";
380
384
  const isRepoNetworkGraph = (url = location) => getRepo(url)?.path === "network";
381
385
  const isForkedRepo = () => exists('meta[name="octolytics-dimension-repository_is_fork"][content="true"]');
@@ -393,8 +397,9 @@ const isUserProfileRepoTab = (url = location) => isProfile(url) && new URLSearch
393
397
  const isUserProfileStarsTab = (url = location) => isProfile(url) && new URLSearchParams(url.search).get("tab") === "stars";
394
398
  const isUserProfileFollowersTab = (url = location) => isProfile(url) && new URLSearchParams(url.search).get("tab") === "followers";
395
399
  const isUserProfileFollowingTab = (url = location) => isProfile(url) && new URLSearchParams(url.search).get("tab") === "following";
400
+ const isProfileRepoList = (url = location) => isUserProfileRepoTab(url) || getOrg(url)?.path === "repositories";
396
401
  const hasComments = (url = location) => isPR(url) || isIssue(url) || isCommit(url) || isTeamDiscussion(url) || isSingleGist(url);
397
- const hasRichTextEditor = (url = location) => hasComments(url) || isNewIssue(url) || isCompare(url) || isRepliesSettings(url) || hasReleaseEditor(url) || isDiscussion(url);
402
+ const hasRichTextEditor = (url = location) => hasComments(url) || isNewIssue(url) || isCompare(url) || isRepliesSettings(url) || hasReleaseEditor(url) || isDiscussion(url) || isNewDiscussion(url);
398
403
  const hasCode = (url = location) => hasComments(url) || isRepoTree(url) || isRepoSearch(url) || isGlobalSearchResults(url) || isSingleFile(url) || isGist(url) || isCompare(url) || isCompareWikiPage(url) || isBlame(url);
399
404
  const hasFiles = (url = location) => isCommit(url) || isCompare(url) || isPRFiles(url);
400
405
  const isMarketplaceAction = (url = location) => url.pathname.startsWith("/marketplace/actions/");
@@ -406,8 +411,8 @@ const isUserTheOrganizationOwner = () => isOrganizationProfile() && exists('[ari
406
411
  const canUserEditRepo = () => isRepo() && exists('.reponav-item[href$="/settings"], [data-tab-item$="settings-tab"]');
407
412
  const isNewRepo = (url = location) => url.pathname === "/new" || /^organizations\/[^/]+\/repositories\/new$/.test(getCleanPathname(url));
408
413
  const isNewRepoTemplate = (url = location) => Boolean(url.pathname.split("/")[3] === "generate");
409
- const getUsername = () => document.querySelector('meta[name="user-login"]')?.getAttribute("content");
410
- const getCleanPathname = (url = location) => url.pathname.replace(/\/+/g, "/").slice(1, url.pathname.endsWith("/") ? -1 : void 0);
414
+ const getUsername = () => $('meta[name="user-login"]')?.getAttribute("content");
415
+ const getCleanPathname = (url = location) => url.pathname.replaceAll(/\/+/g, "/").slice(1, url.pathname.endsWith("/") ? -1 : void 0);
411
416
  const getCleanGistPathname = (url = location) => {
412
417
  const pathname = getCleanPathname(url);
413
418
  if (url.hostname.startsWith("gist.")) {
@@ -425,7 +430,7 @@ const getOrg = (url = location) => {
425
430
  };
426
431
  const getRepo = (url) => {
427
432
  if (!url) {
428
- const canonical = document.querySelector('[property="og:url"]');
433
+ const canonical = $('[property="og:url"]');
429
434
  if (canonical) {
430
435
  const canonicalUrl = new URL(canonical.content, location.origin);
431
436
  if (getCleanPathname(canonicalUrl).toLowerCase() === getCleanPathname(location).toLowerCase()) {
@@ -505,6 +510,7 @@ export {
505
510
  isMilestone,
506
511
  isMilestoneList,
507
512
  isNewAction,
513
+ isNewDiscussion,
508
514
  isNewFile,
509
515
  isNewIssue,
510
516
  isNewRelease,
@@ -529,6 +535,7 @@ export {
529
535
  isPasswordConfirmation,
530
536
  isPrivateUserProfile,
531
537
  isProfile,
538
+ isProfileRepoList,
532
539
  isProject,
533
540
  isProjects,
534
541
  isPublicRepo,
@@ -538,6 +545,7 @@ export {
538
545
  isRepliesSettings,
539
546
  isRepo,
540
547
  isRepoCommitList,
548
+ isRepoFile404,
541
549
  isRepoForksList,
542
550
  isRepoHome,
543
551
  isRepoIssueList,
@@ -555,7 +563,7 @@ export {
555
563
  isSingleCommit,
556
564
  isSingleFile,
557
565
  isSingleGist,
558
- isSingleTag,
566
+ isSingleReleaseOrTag,
559
567
  isTags,
560
568
  isTeamDiscussion,
561
569
  isTrending,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-url-detection",
3
- "version": "7.1.2",
3
+ "version": "8.1.0",
4
4
  "description": "Which GitHub page are you on? Is it an issue? Is it a list? Perfect for your WebExtension or userscript.",
5
5
  "keywords": [
6
6
  "github",
@@ -73,21 +73,18 @@
73
73
  "devDependencies": {
74
74
  "@esbuild-kit/esm-loader": "^2.5.5",
75
75
  "@sindresorhus/tsconfig": "^3.0.1",
76
- "@sveltejs/vite-plugin-svelte": "^2.0.4",
77
- "ava": "^5.2.0",
76
+ "@sveltejs/vite-plugin-svelte": "^2.4.3",
77
+ "ava": "^5.3.1",
78
78
  "github-reserved-names": "^2.0.4",
79
79
  "npm-run-all": "^4.1.5",
80
80
  "strip-indent": "^4.0.0",
81
- "svelte": "^3.58.0",
82
- "svelte-check": "^3.2.0",
83
- "typescript": "^5.0.4",
84
- "vite": "^4.3.0-beta.4",
85
- "xo": "^0.54.0"
81
+ "svelte": "^4.1.2",
82
+ "svelte-check": "^3.4.6",
83
+ "typescript": "^5.1.6",
84
+ "vite": "^4.4.7",
85
+ "xo": "^0.55.0"
86
86
  },
87
87
  "engines": {
88
88
  "node": ">=18"
89
- },
90
- "overrides": {
91
- "vite": "^4.3.0-beta.4"
92
89
  }
93
90
  }