mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
fix: support GitHub turbo
This commit is contained in:
parent
98ee885254
commit
05507abbcb
5 changed files with 79 additions and 7 deletions
|
|
@ -63,7 +63,7 @@ export function SideBar() {
|
|||
: intelligentToggle,
|
||||
)
|
||||
const shouldShow = $shouldShow.value
|
||||
React.useEffect(() => {
|
||||
const toggleBodyIndent = React.useCallback(() => {
|
||||
if (sidebarToggleMode === 'persistent') {
|
||||
DOMHelper.setBodyIndent(shouldShow)
|
||||
} else {
|
||||
|
|
@ -75,6 +75,12 @@ export function SideBar() {
|
|||
}
|
||||
}, [shouldShow, sidebarToggleMode])
|
||||
|
||||
React.useEffect(() => {
|
||||
toggleBodyIndent()
|
||||
}, [toggleBodyIndent])
|
||||
|
||||
useOnPJAXDone(toggleBodyIndent)
|
||||
|
||||
// Save expand state on toggle if auto expand is off
|
||||
React.useEffect(() => {
|
||||
if (intelligentToggle !== null) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,11 @@ import { addMiddleware } from 'driver/connect'
|
|||
import { platform } from 'platforms'
|
||||
import * as React from 'react'
|
||||
import * as ReactDOM from 'react-dom'
|
||||
import {
|
||||
insertLogoMountPoint,
|
||||
insertSideBarMountPoint,
|
||||
persistGitakoElements
|
||||
} from 'utils/DOMHelper'
|
||||
import './content.scss'
|
||||
|
||||
if (platform.resolvePartialMetaData()) {
|
||||
|
|
@ -18,8 +23,9 @@ if (platform.resolvePartialMetaData()) {
|
|||
|
||||
async function init() {
|
||||
await injectStyles(browser.runtime.getURL('content.css'))
|
||||
const SideBarElement = document.createElement('div')
|
||||
document.body.appendChild(SideBarElement)
|
||||
const SideBarElement = insertSideBarMountPoint()
|
||||
const logoElement = insertLogoMountPoint()
|
||||
persistGitakoElements(SideBarElement, logoElement)
|
||||
ReactDOM.render(<Gitako />, SideBarElement)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ const pathSHAMap = new Map<string, string>()
|
|||
const pjaxContainerSelector = ['#repo-content-pjax-container', '#js-repo-pjax-container'].find(
|
||||
selector => document.querySelector(selector),
|
||||
)
|
||||
const turboContainerId = 'repo-content-turbo-frame'
|
||||
|
||||
export const GitHub: Platform = {
|
||||
isEnterprise,
|
||||
|
|
@ -213,6 +214,7 @@ export const GitHub: Platform = {
|
|||
if (configRef.pjaxMode === 'native' && (!options?.node || options.node.type === 'blob'))
|
||||
return {
|
||||
'data-pjax': pjaxContainerSelector,
|
||||
'data-turbo-frame': turboContainerId,
|
||||
onClick() {
|
||||
/* Overwriting default onClick */
|
||||
},
|
||||
|
|
|
|||
|
|
@ -36,17 +36,17 @@ export function setBodyIndent(shouldShowGitako: boolean) {
|
|||
}
|
||||
|
||||
export function $(selector: string): HTMLElement | null
|
||||
export function $<T1>(selector: string, existCallback: (element: HTMLElement) => T1): T1
|
||||
export function $<T1>(selector: string, existCallback: (element: HTMLElement) => T1): T1 | null
|
||||
export function $<T1, T2>(
|
||||
selector: string,
|
||||
existCallback: (element: HTMLElement) => T1,
|
||||
otherwise: () => T2,
|
||||
): T1 | T2
|
||||
): T1 | T2 | null
|
||||
export function $<T2>(
|
||||
selector: string,
|
||||
existCallback: undefined | null,
|
||||
otherwise: () => T2,
|
||||
): HTMLElement | null | T2
|
||||
): HTMLElement | T2
|
||||
export function $(selector: string, existCallback?: any, otherwise?: any) {
|
||||
const element = document.querySelector(selector)
|
||||
if (element) {
|
||||
|
|
@ -55,6 +55,15 @@ export function $(selector: string, existCallback?: any, otherwise?: any) {
|
|||
return otherwise ? otherwise() : null
|
||||
}
|
||||
|
||||
export function insertSideBarMountPoint() {
|
||||
const mountPointID = 'gitako-mount-point-wrapper'
|
||||
const sideBarElement = document.createElement('div')
|
||||
sideBarElement.setAttribute('data-turbo-permanent', '')
|
||||
sideBarElement.setAttribute('id', mountPointID)
|
||||
document.body.appendChild(sideBarElement)
|
||||
return sideBarElement
|
||||
}
|
||||
|
||||
/**
|
||||
* add the logo element into DOM
|
||||
*/
|
||||
|
|
@ -64,6 +73,7 @@ export function insertLogoMountPoint() {
|
|||
return $(logoSelector, undefined, function createLogoMountPoint() {
|
||||
const logoMountElement = document.createElement('div')
|
||||
logoMountElement.setAttribute('id', logoID)
|
||||
logoMountElement.setAttribute('data-turbo-permanent', '')
|
||||
document.body.appendChild(logoMountElement)
|
||||
return logoMountElement
|
||||
})
|
||||
|
|
@ -142,3 +152,46 @@ export function setCSSVariable(name: string, value: string | undefined, element:
|
|||
if (value === undefined) element.style.removeProperty(name)
|
||||
else element.style.setProperty(name, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlike the good-old-PJAX-time, now GitHub replaces whole body element after redirecting using turbo.
|
||||
* If move Gitako mount point from `body` to `html`, Gitako style would break because it inherits style from GitHub body.
|
||||
* The temporary solution is recovery Gitako elements once the body is removed.
|
||||
*/
|
||||
export function persistGitakoElements(SideBarElement: HTMLElement, logoElement: HTMLElement) {
|
||||
const observer = new MutationObserver(mutations => {
|
||||
for (const { addedNodes, removedNodes } of mutations) {
|
||||
const [addedBody, removedBody] = [addedNodes, removedNodes].map(findBodyElement)
|
||||
if (addedBody && removedBody) {
|
||||
// hard-coded list due to limited time
|
||||
// TODO: refactor in a better practice
|
||||
|
||||
// migrate gitako attributes, e.g. class
|
||||
const propertiesNeedToMigrate = ['--gitako-width']
|
||||
for (const property of propertiesNeedToMigrate) {
|
||||
const oldValue = removedBody.style.getPropertyValue(property)
|
||||
if (oldValue) addedBody.style.setProperty(property, oldValue)
|
||||
}
|
||||
const cssClassesNeedToMigrate = ['with-gitako-spacing']
|
||||
for (const cssClass of cssClassesNeedToMigrate) {
|
||||
if (removedBody.classList.contains(cssClass)) addedBody.classList.add(cssClass)
|
||||
}
|
||||
|
||||
// move gitako elements
|
||||
if (!addedBody.contains(SideBarElement)) addedBody.appendChild(SideBarElement)
|
||||
if (removedBody.contains(SideBarElement)) removedBody.removeChild(SideBarElement)
|
||||
if (!addedBody.contains(logoElement)) addedBody.appendChild(logoElement)
|
||||
if (removedBody.contains(logoElement)) removedBody.removeChild(logoElement)
|
||||
}
|
||||
}
|
||||
|
||||
function findBodyElement(addedNodes: NodeList) {
|
||||
return Array.from(addedNodes).find(addedNode => addedNode instanceof HTMLBodyElement) as
|
||||
| HTMLBodyElement
|
||||
| undefined
|
||||
}
|
||||
})
|
||||
observer.observe(document.documentElement, {
|
||||
childList: true,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { platform } from 'platforms'
|
|||
import * as React from 'react'
|
||||
import { useEvent } from 'react-use'
|
||||
|
||||
// TODO: rename PJAX
|
||||
|
||||
const config: Config = {
|
||||
areas: [
|
||||
// github
|
||||
|
|
@ -53,7 +55,10 @@ export const loadWithPJAX = (url: string, element: HTMLElement) => {
|
|||
}
|
||||
|
||||
export function useOnPJAXDone(callback: () => void) {
|
||||
useEvent('pjax:end', callback, document)
|
||||
useEvent('pjax:end', callback, document) // legacy support
|
||||
// 'turbo:render' should be the best timing but GitHub has attached a mutation observer on body to block that
|
||||
// TODO: fire at turbo:render
|
||||
useEvent('turbo:load', callback, document)
|
||||
}
|
||||
|
||||
export function useRedirectedEvents(
|
||||
|
|
|
|||
Loading…
Reference in a new issue