forked from akai/readest
Footnotes/endnotes are hidden in the rendered page via `display: none`, but TTS builds its blocks from its own document. For background sections that document is raw XHTML loaded via `section.createDocument()` without the page layout styles, so the footnotes were read aloud. - `createRejectFilter` gains an `attributeTokens` option to match `aside[epub:type~="footnote|endnote|note|rearnote"]` (value-token match, like CSS `[attr~="x"]`), so footnotes are detectable on raw documents that lack the `epubtype-footnote` class. - `TTSController` adds the footnote selectors to its reject filter. - `getBlocks()` (foliate-js) skips the subtree of any block-level element the node filter rejects, ending the preceding block before it so footnote text doesn't leak in. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,11 +2,18 @@ export const createRejectFilter = ({
|
||||
tags = [],
|
||||
classes = [],
|
||||
attributes = [],
|
||||
attributeTokens = [],
|
||||
contents = [],
|
||||
}: {
|
||||
tags?: string[];
|
||||
classes?: string[];
|
||||
attributes?: string[];
|
||||
/**
|
||||
* Reject elements whose space-separated attribute value contains any of the
|
||||
* given tokens, optionally constrained to a tag name. Matches the way CSS
|
||||
* `[attr~="token"]` selectors work — e.g. `aside[epub:type~="footnote"]`.
|
||||
*/
|
||||
attributeTokens?: { tag?: string; attribute: string; tokens: string[] }[];
|
||||
contents?: { tag: string; content: RegExp }[];
|
||||
}) => {
|
||||
return (node: Node): number => {
|
||||
@@ -24,6 +31,17 @@ export const createRejectFilter = ({
|
||||
if (attributes.some((attr) => (node as Element).hasAttribute(attr))) {
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
}
|
||||
if (
|
||||
attributeTokens.some(({ tag, attribute, tokens }) => {
|
||||
if (tag && name !== tag) return false;
|
||||
const value = (node as Element).getAttribute(attribute);
|
||||
if (!value) return false;
|
||||
const valueTokens = value.split(/\s+/);
|
||||
return tokens.some((token) => valueTokens.includes(token));
|
||||
})
|
||||
) {
|
||||
return NodeFilter.FILTER_REJECT;
|
||||
}
|
||||
if (
|
||||
contents.some(({ tag, content }) => {
|
||||
return name === tag && content.test((node as Element).textContent || '');
|
||||
|
||||
Reference in New Issue
Block a user