diff --git a/src/components/FileExplorer/index.tsx b/src/components/FileExplorer/index.tsx index 86bbf5b..da5e794 100644 --- a/src/components/FileExplorer/index.tsx +++ b/src/components/FileExplorer/index.tsx @@ -179,11 +179,7 @@ function LoadedFileExplorer({ useAfterRedirect(goToCurrentItem) const [currentPath, setCurrentPath] = React.useState(() => getCurrentPath()) - useAfterRedirect( - React.useCallback(() => { - setCurrentPath(getCurrentPath()) - }, [getCurrentPath]), - ) + useAfterRedirect(React.useCallback(() => setCurrentPath(getCurrentPath()), [getCurrentPath])) useInspector('CurrentPath', currentPath) const ref = React.useRef(null) diff --git a/src/content.tsx b/src/content.tsx index a2173ed..90fbd37 100644 --- a/src/content.tsx +++ b/src/content.tsx @@ -1,7 +1,8 @@ import { Gitako } from 'components/Gitako' import * as React from 'react' import { createRoot } from 'react-dom/client' -import { insertSideBarMountPoint } from 'utils/DOMHelper' +import { insertMountPoint, insertSideBarMountPoint } from 'utils/DOMHelper' +import { useAfterRedirect } from 'utils/hooks/useFastRedirect' import './content.scss' if (document.readyState === 'loading') { @@ -12,7 +13,18 @@ if (document.readyState === 'loading') { async function init() { await injectStyles(browser.runtime.getURL('content.css')) - createRoot(insertSideBarMountPoint()).render() + const mountPoint = insertSideBarMountPoint() + const MountPointWatcher = () => { + useAfterRedirect(React.useCallback(() => insertMountPoint(() => mountPoint), [])) + return null + } + + createRoot(mountPoint).render( + <> + + + , + ) } // injects a copy of stylesheets so that other extensions(e.g. dark reader) could read diff --git a/src/platforms/GitHub/DOMHelper.ts b/src/platforms/GitHub/DOMHelper.ts index 9858dc5..ec5a795 100644 --- a/src/platforms/GitHub/DOMHelper.ts +++ b/src/platforms/GitHub/DOMHelper.ts @@ -6,6 +6,13 @@ import { formatClass, parseIntFromElement } from 'utils/DOMHelper' import { renderReact } from 'utils/general' const selectors = { + normal: { + reactApp: `react-app[app-name="react-code-view"] [data-target="react-app.reactRoot"]`, + branchSwitcher: `summary[title="Switch branches or tags"]`, + fileNavigation: `.file-navigation`, + breadcrumbs: `[data-testid="breadcrumbs"]`, + breadcrumbsFilename: `[data-testid="breadcrumbs-filename"]`, + }, globalNavigation: { navbar: { repositoryOwner: [ @@ -93,12 +100,11 @@ export function isInRepoPage() { export function isInCodePage() { const branchListSelector = [ - '#branch-select-menu', - '.branch-select-menu', - selectors.globalNavigation.branchSelector, + selectors.normal.breadcrumbsFilename, + selectors.normal.branchSwitcher, ].join() // The element may still exist in DOM for PR pages, but not visible - return Boolean($(branchListSelector, e => e.offsetWidth > 0 && e.offsetHeight > 0)) + return Boolean($(branchListSelector)) } export function isInPullFilesPage() { @@ -295,6 +301,10 @@ export function getPath() { return [] } +export function isNativeFileTreeShown() { + return Boolean($('#repos-file-tree')) +} + export function isNativePRFileTreeShown() { return $('file-tree[data-target="diff-layout.fileTree"]', ele => { // It would be set `display: hidden;` when collapsed diff --git a/src/platforms/GitHub/index.ts b/src/platforms/GitHub/index.ts index 5f1e2c9..eb84969 100644 --- a/src/platforms/GitHub/index.ts +++ b/src/platforms/GitHub/index.ts @@ -162,7 +162,7 @@ export const GitHub: Platform = { }, shouldExpandSideBar() { return Boolean( - DOMHelper.isInCodePage() || + (DOMHelper.isInCodePage() && !DOMHelper.isNativePRFileTreeShown()) || URLHelper.isInCommitPage() || (URLHelper.isInPullPage() && !DOMHelper.isNativePRFileTreeShown()), ) diff --git a/src/utils/$.ts b/src/utils/$.ts index b5d0241..aee42ef 100644 --- a/src/utils/$.ts +++ b/src/utils/$.ts @@ -1,15 +1,15 @@ -export function $(selector: string): HTMLElement | null -export function $(selector: string, existCallback: (element: HTMLElement) => T1): T1 | null -export function $( +export function $(selector: string): E | null +export function $(selector: string, existCallback: (element: HTMLElement) => R1): R1 | null +export function $( selector: string, - existCallback: (element: HTMLElement) => T1, - otherwise: () => T2, -): T1 | T2 -export function $( + existCallback: (element: HTMLElement) => R1, + otherwise: () => R2, +): R1 | R2 +export function $( selector: string, existCallback: undefined | null, - otherwise: () => T2, -): HTMLElement | T2 + otherwise: () => R2, +): E | R2 // eslint-disable-next-line @typescript-eslint/no-explicit-any export function $(selector: string, existCallback?: any, otherwise?: any) { const element = document.querySelector(selector) diff --git a/src/utils/DOMHelper.ts b/src/utils/DOMHelper.ts index 940a236..1eecfdf 100644 --- a/src/utils/DOMHelper.ts +++ b/src/utils/DOMHelper.ts @@ -104,33 +104,36 @@ export function setBodyIndent(shouldShowGitako: boolean) { */ const mountPointContainer = document.body -export function insertMountPoint() { - return $(formatID(rootElementID), undefined, () => { +export function insertMountPoint( + create = () => { const element = document.createElement('div') element.setAttribute('id', rootElementID) - mountPointContainer.appendChild(element) return element - }) + }, +) { + return $(formatID(rootElementID), undefined, () => mountPointContainer.appendChild(create())) } export function insertSideBarMountPoint() { - const sidebarMountPointID = 'gitako-sidebar-mount-point' - return $(formatID(sidebarMountPointID), undefined, () => { - const sideBarElement = document.createElement('div') - sideBarElement.setAttribute('id', sidebarMountPointID) - insertMountPoint().appendChild(sideBarElement) - return sideBarElement - }) + const id = 'gitako-sidebar-mount-point' + const create = () => { + const element = document.createElement('div') + element.setAttribute('id', id) + return element + } + return $(formatID(id), undefined, () => + insertMountPoint().appendChild(create()), + ) } export function insertLogoMountPoint() { - const logoMountPointID = 'gitako-logo-mount-point' - return $(formatID(logoMountPointID), undefined, () => { - const logoMountElement = document.createElement('div') - logoMountElement.setAttribute('id', logoMountPointID) - insertMountPoint().appendChild(logoMountElement) - return logoMountElement - }) + const id = 'gitako-logo-mount-point' + const create = () => { + const element = document.createElement('div') + element.setAttribute('id', id) + return element + } + return $(formatID(id), undefined, () => insertMountPoint().appendChild(create())) } /**