fix: make the reader's typography, width and arrow keys work
Typography was in the stylesheet foliate prepends, which the book overrides; moved to the appended one. The window keydown handler was never bound. Also: wider reading area, page on a card, arrows moved onto it, spread gutter, and the sidebar stays open on chapter clicks.
This commit is contained in:
@@ -12,7 +12,10 @@ export const DEFAULT_READER_SETTINGS: ReaderSettings = {
|
||||
letterSpacing: 0,
|
||||
margin: 48,
|
||||
gap: 6,
|
||||
maxInlineSize: 720,
|
||||
// foliate caps the reading area at this times the column count, so 1000 gives
|
||||
// a 2000px spread — enough to fill a large display rather than leaving the
|
||||
// book as a narrow strip. Its own default of 720 is noticeably tight.
|
||||
maxInlineSize: 1000,
|
||||
maxColumnCount: 2,
|
||||
flow: 'paginated',
|
||||
justify: true,
|
||||
@@ -30,7 +33,7 @@ export const READER_BOUNDS = {
|
||||
letterSpacing: { min: -0.05, max: 0.2, step: 0.01 },
|
||||
margin: { min: 0, max: 120, step: 4 },
|
||||
gap: { min: 0, max: 15, step: 1 },
|
||||
maxInlineSize: { min: 480, max: 1400, step: 20 }
|
||||
maxInlineSize: { min: 400, max: 2400, step: 20 }
|
||||
} as const;
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,43 +35,37 @@ export function readReaderPalette(dark: boolean): ReaderPalette {
|
||||
};
|
||||
}
|
||||
|
||||
/** Body-text containers. Headings are excluded so their scale survives. */
|
||||
const TEXT = 'p, li, dd, dt, blockquote, td, th, div';
|
||||
|
||||
const HEADINGS = 'h1, h2, h3, h4, h5, h6';
|
||||
|
||||
/**
|
||||
* Builds the two stylesheets foliate injects into each section document.
|
||||
*
|
||||
* The paginator creates two <style> elements per document: the first is
|
||||
* head.prepend()ed, so the book's own CSS overrides it; the second is
|
||||
* head.append()ed, so it wins on equal specificity. setStyles accepts the pair
|
||||
* as a tuple and re-applies it on every section load.
|
||||
* head.append()ed, so it wins. setStyles takes the pair as a tuple and
|
||||
* re-applies it on every section load.
|
||||
*
|
||||
* The split is the point. Typography goes in `before` so a book that styles its
|
||||
* own headings still gets to; colour goes in `after` because most EPUBs set a
|
||||
* body background and would otherwise leave the page white against a dark UI.
|
||||
* Nearly everything goes in `after`, with !important. These are the reader's
|
||||
* settings, and EPUBs routinely set their own font-family, font-size and
|
||||
* line-height on body and on paragraphs — put the settings in `before` and the
|
||||
* book simply overrides them, which is what made the typography controls look
|
||||
* like they did nothing.
|
||||
*
|
||||
* `before` is left for the few defaults a book should be free to override.
|
||||
*/
|
||||
export function buildReaderStyles(
|
||||
s: ReaderSettings,
|
||||
p: ReaderPalette
|
||||
): [before: string, after: string] {
|
||||
const hyphens = s.hyphenate ? 'auto' : 'manual';
|
||||
|
||||
const before = `
|
||||
@namespace epub "http://www.idpf.org/2007/ops";
|
||||
|
||||
/* On html, not body, and without !important: the book's rem/em headings
|
||||
then scale with the setting instead of being flattened to one size. */
|
||||
html {
|
||||
font-size: ${s.fontSize}px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: ${s.fontFamily};
|
||||
font-weight: ${s.fontWeight};
|
||||
line-height: ${s.lineHeight};
|
||||
letter-spacing: ${s.letterSpacing}em;
|
||||
}
|
||||
|
||||
p, li, blockquote, dd, div {
|
||||
line-height: ${s.lineHeight};
|
||||
text-align: ${s.justify ? 'justify' : 'start'};
|
||||
-webkit-hyphens: ${s.hyphenate ? 'auto' : 'manual'};
|
||||
hyphens: ${s.hyphenate ? 'auto' : 'manual'};
|
||||
${TEXT} {
|
||||
-webkit-hyphenate-limit-before: 3;
|
||||
-webkit-hyphenate-limit-after: 2;
|
||||
-webkit-hyphenate-limit-lines: 2;
|
||||
@@ -80,18 +74,50 @@ export function buildReaderStyles(
|
||||
orphans: 2;
|
||||
}
|
||||
|
||||
/* Justification must not silently override an explicit align attribute. */
|
||||
[align="left"] { text-align: left; }
|
||||
[align="right"] { text-align: right; }
|
||||
[align="center"] { text-align: center; }
|
||||
[align="justify"] { text-align: justify; }
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
`;
|
||||
|
||||
const after = `
|
||||
/* The rem base. Headings sized in em/rem keep their scale relative to it. */
|
||||
html {
|
||||
font-size: ${s.fontSize}px !important;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 1rem !important;
|
||||
font-weight: ${s.fontWeight} !important;
|
||||
}
|
||||
|
||||
/* inherit rather than a fixed size: books that set an absolute size in pt
|
||||
or px on their paragraphs would otherwise ignore the size setting
|
||||
entirely, while headings keep whatever relative scale they declare. */
|
||||
${TEXT} {
|
||||
font-size: inherit !important;
|
||||
}
|
||||
|
||||
body, ${TEXT}, ${HEADINGS}, figcaption, caption {
|
||||
font-family: ${s.fontFamily} !important;
|
||||
}
|
||||
|
||||
body, ${TEXT} {
|
||||
line-height: ${s.lineHeight} !important;
|
||||
letter-spacing: ${s.letterSpacing}em !important;
|
||||
}
|
||||
|
||||
p, li, dd, blockquote {
|
||||
text-align: ${s.justify ? 'justify' : 'start'} !important;
|
||||
-webkit-hyphens: ${hyphens} !important;
|
||||
hyphens: ${hyphens} !important;
|
||||
}
|
||||
|
||||
/* Justification must not silently override an explicit align attribute. */
|
||||
[align="left"] { text-align: left !important; }
|
||||
[align="right"] { text-align: right !important; }
|
||||
[align="center"] { text-align: center !important; }
|
||||
[align="justify"] { text-align: justify !important; }
|
||||
|
||||
/* Tells the book's own prefers-color-scheme rules which way we are going.
|
||||
Without it the paginator's media query follows the OS, so a book with
|
||||
dark styles can invert against the app. */
|
||||
@@ -99,15 +125,14 @@ export function buildReaderStyles(
|
||||
color-scheme: ${p.dark ? 'dark' : 'light'};
|
||||
}
|
||||
|
||||
/* !important only here. Most EPUBs set their own body background and
|
||||
colour, and an unprioritised override loses to them. */
|
||||
/* Most EPUBs set their own body background and colour, so an
|
||||
unprioritised override loses to them and the page stays white. */
|
||||
html, body {
|
||||
background: ${p.bg} !important;
|
||||
color: ${p.fg} !important;
|
||||
}
|
||||
|
||||
p, div, span, li, td, th, dl, dd, dt,
|
||||
h1, h2, h3, h4, h5, h6, blockquote, figcaption {
|
||||
${TEXT}, ${HEADINGS}, span, dl, figcaption, caption {
|
||||
color: ${p.fg} !important;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user