Compare commits

...

1 Commits

Author SHA1 Message Date
Shoubhit Dash e7f4d851f6 fix(ui): avoid WebKit diff viewer crashes 2026-03-16 16:53:02 +05:30
4 changed files with 9 additions and 66 deletions
+1 -11
View File
@@ -6,13 +6,7 @@ import { useWorkerPool } from "../context/worker-pool"
import { createDefaultOptions, styleVariables } from "../pierre" import { createDefaultOptions, styleVariables } from "../pierre"
import { markCommentedDiffLines } from "../pierre/commented-lines" import { markCommentedDiffLines } from "../pierre/commented-lines"
import { fixDiffSelection } from "../pierre/diff-selection" import { fixDiffSelection } from "../pierre/diff-selection"
import { import { clearReadyWatcher, createReadyWatcher, notifyShadowReady } from "../pierre/file-runtime"
applyViewerScheme,
clearReadyWatcher,
createReadyWatcher,
notifyShadowReady,
observeViewerScheme,
} from "../pierre/file-runtime"
import { acquireVirtualizer, virtualMetrics } from "../pierre/virtualizer" import { acquireVirtualizer, virtualMetrics } from "../pierre/virtualizer"
import { File, type DiffFileProps, type FileProps } from "./file" import { File, type DiffFileProps, type FileProps } from "./file"
@@ -87,8 +81,6 @@ function DiffSSRViewer<T>(props: SSRDiffFileProps<T>) {
onMount(() => { onMount(() => {
if (isServer) return if (isServer) return
onCleanup(observeViewerScheme(() => fileDiffRef))
const virtualizer = getVirtualizer() const virtualizer = getVirtualizer()
fileDiffInstance = virtualizer fileDiffInstance = virtualizer
? new VirtualizedFileDiff<T>( ? new VirtualizedFileDiff<T>(
@@ -110,8 +102,6 @@ function DiffSSRViewer<T>(props: SSRDiffFileProps<T>) {
workerPool, workerPool,
) )
applyViewerScheme(fileDiffRef)
// @ts-expect-error private field required for hydration // @ts-expect-error private field required for hydration
fileDiffInstance.fileContainer = fileDiffRef fileDiffInstance.fileContainer = fileDiffRef
fileDiffInstance.hydrate({ fileDiffInstance.hydrate({
+2 -17
View File
@@ -16,20 +16,12 @@ import {
} from "@pierre/diffs" } from "@pierre/diffs"
import { type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
import { createMediaQuery } from "@solid-primitives/media" import { createMediaQuery } from "@solid-primitives/media"
import { ComponentProps, createEffect, createMemo, createSignal, onCleanup, onMount, Show, splitProps } from "solid-js" import { ComponentProps, createEffect, createMemo, createSignal, onCleanup, Show, splitProps } from "solid-js"
import { createDefaultOptions, styleVariables } from "../pierre" import { createDefaultOptions, styleVariables } from "../pierre"
import { markCommentedDiffLines, markCommentedFileLines } from "../pierre/commented-lines" import { markCommentedDiffLines, markCommentedFileLines } from "../pierre/commented-lines"
import { fixDiffSelection, findDiffSide, type DiffSelectionSide } from "../pierre/diff-selection" import { fixDiffSelection, findDiffSide, type DiffSelectionSide } from "../pierre/diff-selection"
import { createFileFind } from "../pierre/file-find" import { createFileFind } from "../pierre/file-find"
import { import { clearReadyWatcher, createReadyWatcher, getViewerRoot, notifyShadowReady } from "../pierre/file-runtime"
applyViewerScheme,
clearReadyWatcher,
createReadyWatcher,
getViewerHost,
getViewerRoot,
notifyShadowReady,
observeViewerScheme,
} from "../pierre/file-runtime"
import { import {
findCodeSelectionSide, findCodeSelectionSide,
findDiffLineNumber, findDiffLineNumber,
@@ -154,7 +146,6 @@ function useFileViewer(config: ViewerConfig) {
const [rendered, setRendered] = createSignal(0) const [rendered, setRendered] = createSignal(0)
const getRoot = () => getViewerRoot(container) const getRoot = () => getViewerRoot(container)
const getHost = () => getViewerHost(container)
const find = createFileFind({ const find = createFileFind({
wrapper: () => wrapper, wrapper: () => wrapper,
@@ -265,10 +256,6 @@ function useFileViewer(config: ViewerConfig) {
// -- shared effects -- // -- shared effects --
onMount(() => {
onCleanup(observeViewerScheme(getHost))
})
createEffect(() => { createEffect(() => {
rendered() rendered()
const ranges = config.commentedLines() const ranges = config.commentedLines()
@@ -351,7 +338,6 @@ function useFileViewer(config: ViewerConfig) {
rendered, rendered,
setRendered, setRendered,
getRoot, getRoot,
getHost,
find, find,
scheduleSelectionUpdate, scheduleSelectionUpdate,
} }
@@ -486,7 +472,6 @@ function renderViewer<I extends RenderTarget>(opts: {
opts.viewer.container.innerHTML = "" opts.viewer.container.innerHTML = ""
opts.draw(next) opts.draw(next)
applyViewerScheme(opts.viewer.getHost())
opts.viewer.setRendered((value) => value + 1) opts.viewer.setRendered((value) => value + 1)
opts.onReady() opts.onReady()
} }
-25
View File
@@ -23,31 +23,6 @@ export function getViewerRoot(container: HTMLElement | undefined) {
return getViewerHost(container)?.shadowRoot ?? undefined return getViewerHost(container)?.shadowRoot ?? undefined
} }
export function applyViewerScheme(host: HTMLElement | undefined) {
if (!host) return
if (typeof document === "undefined") return
const scheme = document.documentElement.dataset.colorScheme
if (scheme === "dark" || scheme === "light") {
host.dataset.colorScheme = scheme
return
}
host.removeAttribute("data-color-scheme")
}
export function observeViewerScheme(getHost: () => HTMLElement | undefined) {
if (typeof document === "undefined") return () => {}
applyViewerScheme(getHost())
if (typeof MutationObserver === "undefined") return () => {}
const root = document.documentElement
const monitor = new MutationObserver(() => applyViewerScheme(getHost()))
monitor.observe(root, { attributes: true, attributeFilter: ["data-color-scheme"] })
return () => monitor.disconnect()
}
export function notifyShadowReady(opts: { export function notifyShadowReady(opts: {
state: ReadyWatcher state: ReadyWatcher
container: HTMLElement container: HTMLElement
+6 -13
View File
@@ -37,26 +37,19 @@ const unsafeCSS = `
--diffs-bg-addition-emphasis: var(--diffs-bg-addition-emphasis-override, light-dark(rgb(from var(--diffs-addition-base) r g b / 0.07), rgb(from var(--diffs-addition-base) r g b / 0.1))); --diffs-bg-addition-emphasis: var(--diffs-bg-addition-emphasis-override, light-dark(rgb(from var(--diffs-addition-base) r g b / 0.07), rgb(from var(--diffs-addition-base) r g b / 0.1)));
--diffs-selection-base: var(--surface-warning-strong); --diffs-selection-base: var(--surface-warning-strong);
--diffs-selection-border: var(--border-warning-base); --diffs-selection-border: var(--border-warning-base);
--diffs-selection-number-fg: #1c1917; --diffs-selection-number-fg: light-dark(#1c1917, #fdfbfb);
/* Use explicit alpha instead of color-mix(..., transparent) to avoid Safari's non-premultiplied interpolation bugs. */ /* Use explicit alpha instead of color-mix(..., transparent) to avoid Safari's non-premultiplied interpolation bugs. */
--diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--surface-warning-base) r g b / 0.65)); --diffs-bg-selection: var(
--diffs-bg-selection-override,
light-dark(rgb(from var(--surface-warning-base) r g b / 0.65), rgb(from var(--solaris-dark-6) r g b / 0.65))
);
--diffs-bg-selection-number: var( --diffs-bg-selection-number: var(
--diffs-bg-selection-number-override, --diffs-bg-selection-number-override,
rgb(from var(--surface-warning-base) r g b / 0.85) light-dark(rgb(from var(--surface-warning-base) r g b / 0.85), rgb(from var(--solaris-dark-6) r g b / 0.85))
); );
--diffs-bg-selection-text: rgb(from var(--surface-warning-strong) r g b / 0.2); --diffs-bg-selection-text: rgb(from var(--surface-warning-strong) r g b / 0.2);
} }
:host([data-color-scheme='dark']) [data-diff],
:host([data-color-scheme='dark']) [data-file] {
--diffs-selection-number-fg: #fdfbfb;
--diffs-bg-selection: var(--diffs-bg-selection-override, rgb(from var(--solaris-dark-6) r g b / 0.65));
--diffs-bg-selection-number: var(
--diffs-bg-selection-number-override,
rgb(from var(--solaris-dark-6) r g b / 0.85)
);
}
[data-diff] ::selection, [data-diff] ::selection,
[data-file] ::selection { [data-file] ::selection {
background-color: var(--diffs-bg-selection-text); background-color: var(--diffs-bg-selection-text);