mirror of
https://github.com/EnixCoda/Gitako.git
synced 2026-03-11 08:54:44 +00:00
parent
3a0680b53d
commit
aeb6b6341c
3 changed files with 79 additions and 11 deletions
|
|
@ -183,8 +183,12 @@ function useFocusSidebarOnExpand(shouldExpand: boolean) {
|
|||
|
||||
function useMarkGitakoReadyState() {
|
||||
React.useEffect(() => {
|
||||
const detach = DOMHelper.attachStickyGitakoReadyState()
|
||||
DOMHelper.markGitakoReadyState(true)
|
||||
return () => DOMHelper.markGitakoReadyState(false)
|
||||
return () => {
|
||||
detach()
|
||||
DOMHelper.markGitakoReadyState(false)
|
||||
}
|
||||
}, [])
|
||||
}
|
||||
|
||||
|
|
@ -199,9 +203,13 @@ function useLogoContainerElement() {
|
|||
function useUpdateBodyIndentOnStateUpdate(shouldExpand: boolean) {
|
||||
const { sidebarToggleMode } = useConfigs().value
|
||||
React.useEffect(() => {
|
||||
if (sidebarToggleMode === 'persistent' && shouldExpand) {
|
||||
DOMHelper.setBodyIndent(true)
|
||||
return () => DOMHelper.setBodyIndent(false)
|
||||
if (!(sidebarToggleMode === 'persistent' && shouldExpand)) return
|
||||
|
||||
const detach = DOMHelper.attachStickyBodyIndent()
|
||||
DOMHelper.setBodyIndent(true)
|
||||
return () => {
|
||||
detach()
|
||||
DOMHelper.setBodyIndent(false)
|
||||
}
|
||||
}, [sidebarToggleMode, shouldExpand])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useConfigs } from 'containers/ConfigsContext'
|
||||
import * as React from 'react'
|
||||
import { useDebounce, useWindowSize } from 'react-use'
|
||||
import { useDebounce, useLatest, useWindowSize } from 'react-use'
|
||||
import { getDefaultConfigs } from 'utils/config/helper'
|
||||
import * as DOMHelper from 'utils/DOMHelper'
|
||||
import { useAfterRedirect } from 'utils/hooks/useFastRedirect'
|
||||
|
|
@ -27,6 +27,12 @@ function useSidebarWidth() {
|
|||
|
||||
React.useLayoutEffect(() => DOMHelper.setGitakoWidthCSSVariable(width), [width])
|
||||
|
||||
const widthRef = useLatest(width)
|
||||
React.useEffect(() => {
|
||||
const detach = DOMHelper.attachStickyGitakoWidthCSSVariable(() => widthRef.current)
|
||||
return () => detach()
|
||||
}, [widthRef])
|
||||
|
||||
// Keep variable when directing from PR to repo home via meta bar
|
||||
useAfterRedirect(React.useCallback(() => DOMHelper.setGitakoWidthCSSVariable(width), [width]))
|
||||
|
||||
|
|
|
|||
|
|
@ -7,20 +7,69 @@ import { $ } from './$'
|
|||
export const rootElementID = 'gitako-root'
|
||||
export const gitakoDescriptionTarget = document.documentElement
|
||||
|
||||
// Some custom attributes added to GitHub html would be removed by GitHub when some events happen
|
||||
function attachStickyAttribute(
|
||||
target: Node,
|
||||
shouldAttach: (mutation: MutationRecord) => boolean,
|
||||
attach: (mutation: MutationRecord) => void,
|
||||
mutationOptions?: MutationObserverInit,
|
||||
) {
|
||||
const observer = new MutationObserver(mutations => {
|
||||
for (const mutation of mutations) if (shouldAttach(mutation)) attach(mutation)
|
||||
})
|
||||
|
||||
observer.observe(target, {
|
||||
attributeOldValue: true,
|
||||
attributes: true,
|
||||
...mutationOptions,
|
||||
})
|
||||
|
||||
return () => observer.disconnect()
|
||||
}
|
||||
|
||||
export const attachStickyDataAttribute = (
|
||||
target: HTMLElement,
|
||||
attributeName: string,
|
||||
attach: (mutation: MutationRecord) => void,
|
||||
) =>
|
||||
attachStickyAttribute(target, () => !target.getAttribute(attributeName), attach, {
|
||||
attributeFilter: [attributeName],
|
||||
})
|
||||
|
||||
export const attachStickyStyle = (
|
||||
target: HTMLElement,
|
||||
styleName: string,
|
||||
attach: (mutation: MutationRecord) => void,
|
||||
) =>
|
||||
attachStickyAttribute(
|
||||
target,
|
||||
() => !target.style.getPropertyValue(styleName), // `''` if not exist
|
||||
attach,
|
||||
{ attributeFilter: ['style'] },
|
||||
)
|
||||
|
||||
/**
|
||||
* when gitako is ready, make page's header narrower
|
||||
* or cancel it
|
||||
* when gitako is ready, attach attribute to activate CSS selectors
|
||||
* e.g. make page's header narrower on pin sidebar
|
||||
*/
|
||||
const readyDataAttributeName = 'data-gitako-ready'
|
||||
export const attachStickyGitakoReadyState = () =>
|
||||
attachStickyDataAttribute(gitakoDescriptionTarget, readyDataAttributeName, ({ oldValue }) =>
|
||||
markGitakoReadyState(oldValue === 'true'),
|
||||
)
|
||||
export function markGitakoReadyState(ready: boolean) {
|
||||
const readyAttributeName = 'data-gitako-ready'
|
||||
return gitakoDescriptionTarget.setAttribute(readyAttributeName, `${ready}`)
|
||||
return gitakoDescriptionTarget.setAttribute(readyDataAttributeName, `${ready}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* if should show gitako, then move body right to make space for showing gitako
|
||||
* otherwise, hide the space
|
||||
*/
|
||||
export const spacingAttributeName = 'data-with-gitako-spacing'
|
||||
const spacingAttributeName = 'data-with-gitako-spacing'
|
||||
export const attachStickyBodyIndent = () =>
|
||||
attachStickyDataAttribute(gitakoDescriptionTarget, spacingAttributeName, ({ oldValue }) =>
|
||||
setBodyIndent(oldValue === 'true'),
|
||||
)
|
||||
export function setBodyIndent(shouldShowGitako: boolean) {
|
||||
gitakoDescriptionTarget.setAttribute(spacingAttributeName, `${shouldShowGitako}`)
|
||||
}
|
||||
|
|
@ -122,8 +171,13 @@ export function setCSSVariable(name: string, value: string | undefined, element:
|
|||
else element.style.setProperty(name, value)
|
||||
}
|
||||
|
||||
const gitakoWidthVariable = '--gitako-width'
|
||||
export const attachStickyGitakoWidthCSSVariable = (getLatestSize: () => number) =>
|
||||
attachStickyStyle(gitakoDescriptionTarget, gitakoWidthVariable, () => {
|
||||
setGitakoWidthCSSVariable(getLatestSize())
|
||||
})
|
||||
export const setGitakoWidthCSSVariable = (size: number) => {
|
||||
setCSSVariable('--gitako-width', `${size}px`, gitakoDescriptionTarget)
|
||||
setCSSVariable(gitakoWidthVariable, `${size}px`, gitakoDescriptionTarget)
|
||||
}
|
||||
|
||||
export function formatID(id: string) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue