fix(reader): guard foliate paginator null-document crashes (#5020)

Bumps foliate-js to readest/foliate-js#53:
- setStyles no longer destructures `style` from a null doc.documentElement during
  columnize/render, which crashed while a view's document was blank/detached
  (READEST-1H, 11 users).
- getDirection / getBackground no longer call getComputedStyle on a null body
  during iframe load (READEST-2X).

Adds a getDirection regression test.

Fixes READEST-1H
Fixes READEST-2X

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Huang Xin 2026-07-09 16:00:46 +09:00 committed by GitHub
parent f4b572e2c7
commit a9fb86ddc5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 40 additions and 1 deletions

View file

@ -0,0 +1,39 @@
import { describe, expect, it, vi } from 'vitest';
import { getDirection } from 'foliate-js/paginator.js';
// A view's iframe document is blank/detached while a section loads or the view
// is torn down: body is null, and getComputedStyle(null) throws
// "parameter 1 is not of type 'Element'" (READEST-2X).
describe('getDirection null-document guard (READEST-2X)', () => {
it('falls back to horizontal-ltr instead of calling getComputedStyle(null)', () => {
const getComputedStyle = vi.fn((el: Element | null) => {
if (!el) {
throw new TypeError(
"Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.",
);
}
return { writingMode: 'horizontal-tb', direction: 'ltr' } as CSSStyleDeclaration;
});
const doc = {
defaultView: { getComputedStyle },
body: null,
documentElement: { dir: '' },
} as unknown as Document;
expect(() => getDirection(doc)).not.toThrow();
expect(getDirection(doc)).toEqual({ vertical: false, rtl: false });
expect(getComputedStyle).not.toHaveBeenCalled();
});
it('still reads the writing mode from a present body', () => {
const getComputedStyle = vi.fn(() => ({ writingMode: 'vertical-rl', direction: 'ltr' }));
const doc = {
defaultView: { getComputedStyle },
body: { dir: '', querySelector: () => null },
documentElement: { dir: '' },
} as unknown as Document;
expect(getDirection(doc)).toEqual({ vertical: true, rtl: true });
});
});

@ -1 +1 @@
Subproject commit c1b1bbf6b74a9d83f6acbefe3320529b13ea512b
Subproject commit 03cfb6c9328e3d5705dd928debe4693effa5fbfc