Skip to content

Commit

Permalink
fix: stable shadow dom key
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Sep 3, 2024
1 parent 29ab323 commit 06cafb5
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 17 deletions.
58 changes: 48 additions & 10 deletions src/renderer/src/components/common/ShadowDOM.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,68 @@
import { useIsDark } from "@renderer/hooks/common"
import { nanoid } from "nanoid"
import type { FC, PropsWithChildren, ReactNode } from "react"
import {
createContext,
createElement,
memo,
useContext,
useLayoutEffect,
useMemo,
useState,
} from "react"
import root from "react-shadow"

const ShadowDOMContext = createContext(false)

const cloneStylesElement = () => {
const MemoedDangerousHTMLStyle: FC<{ children: string }> = memo(
({ children }) => (
<style
dangerouslySetInnerHTML={useMemo(
() => ({
__html: children,
}),
[children],
)}
/>
),
)

const weakMapElementKey = new WeakMap<
HTMLStyleElement | HTMLLinkElement,
string
>()
const cloneStylesElement = (_mutationRecord?: MutationRecord) => {
const $styles = document.head.querySelectorAll("style").values()
const reactNodes = [] as ReactNode[]
let i = 0
for (const style of $styles) {
const key = `style-${i++}`

for (const $style of $styles) {
let key = weakMapElementKey.get($style)

if (!key) {
key = nanoid(8)

weakMapElementKey.set($style, key)
}

reactNodes.push(
createElement("style", {
createElement(MemoedDangerousHTMLStyle, {
key,
dangerouslySetInnerHTML: { __html: style.innerHTML },
children: $style.innerHTML,
}),
)
}

document.head.querySelectorAll("link[rel=stylesheet]").forEach((link) => {
const key = `link-${i++}`
const $links = document.head.querySelectorAll(
"link[rel=stylesheet]",
) as unknown as HTMLLinkElement[]

$links.forEach((link) => {
let key = weakMapElementKey.get(link)
if (!key) {
key = nanoid(8)
weakMapElementKey.set(link, key)
}

reactNodes.push(
createElement("link", {
key,
Expand All @@ -48,8 +84,10 @@ export const ShadowDOM: FC<PropsWithChildren<React.HTMLProps<HTMLElement>>> & {
useState<ReactNode[]>(cloneStylesElement)

useLayoutEffect(() => {
const mutationObserver = new MutationObserver(() => {
setStylesElements(cloneStylesElement())
const mutationObserver = new MutationObserver((e) => {
const event = e[0]

setStylesElements(cloneStylesElement(event))
})
mutationObserver.observe(document.head, {
childList: true,
Expand Down
12 changes: 8 additions & 4 deletions src/renderer/src/components/ui/markdown/Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { parseHtml } from "@renderer/lib/parse-html"
import type { RemarkOptions } from "@renderer/lib/parse-markdown"
import { parseMarkdown } from "@renderer/lib/parse-markdown"
import { cn } from "@renderer/lib/utils"
import { createElement, Fragment, useMemo, useState } from "react"
import { createElement, Fragment, useEffect, useMemo, useState } from "react"

import { MarkdownRenderContainerRefContext } from "./context"

Expand Down Expand Up @@ -46,17 +46,21 @@ export const HTML = <A extends keyof JSX.IntrinsicElements = "div">(
}>,
) => {
const { children, renderInlineStyle, as = "div", accessory, ...rest } = props
const stableRemarkOptions = useState({ renderInlineStyle })[0]
const [remarkOptions, setRemarkOptions] = useState({ renderInlineStyle })

useEffect(() => {
setRemarkOptions({ renderInlineStyle })
}, [renderInlineStyle])

const [refElement, setRefElement] = useState<HTMLElement | null>(null)

const markdownElement = useMemo(
() =>
children &&
parseHtml(children, {
...stableRemarkOptions,
...remarkOptions,
}).toContent(),
[children, stableRemarkOptions],
[children, remarkOptions],
)

if (!markdownElement) return null
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/src/modules/app/EnvironmentIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
export const EnvironmentIndicator = () => (
<Tooltip>
<TooltipTrigger asChild>
<div className="fixed bottom-0 left-0 rounded-tr bg-accent px-1 py-0.5 text-xs text-white">
<div className="fixed bottom-0 right-0 rounded-tl bg-accent px-1 py-0.5 text-xs text-white">
{import.meta.env.MODE}
</div>
</TooltipTrigger>
Expand Down
7 changes: 5 additions & 2 deletions src/renderer/src/pages/(main)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ export function Component() {
ref={containerRef}
onContextMenu={preventDefault}
>
{!import.meta.env.PROD && <EnvironmentIndicator />}

<FeedResponsiveResizerContainer containerRef={containerRef}>
<FeedColumn>
<CornerPlayer />
Expand All @@ -82,7 +84,6 @@ export function Component() {
{ELECTRON && <AutoUpdater />}

<NetworkStatusIndicator />
{!import.meta.env.PROD && <EnvironmentIndicator />}
</FeedColumn>
</FeedResponsiveResizerContainer>
<main
Expand Down Expand Up @@ -219,7 +220,9 @@ const FeedResponsiveResizerContainer = ({
}}
/>

{delayShowSplitter && <PanelSplitter isDragging={isDragging} {...separatorProps} />}
{delayShowSplitter && (
<PanelSplitter isDragging={isDragging} {...separatorProps} />
)}
</>
)
}

0 comments on commit 06cafb5

Please sign in to comment.