to Ensure HTML Parsing
with Cheerio (#2166)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`$()` only treats the input as HTML when it starts with `<`; otherwise it
parses as a CSS selector. The novelbuddy API returns `initialManga.summary`
as plain text for many novels (e.g. "When I opened my eyes, I was inside
a novel."), and cheerio's selector parser then chokes on the first `.`
in the punctuation with `Expected name, found .` — `parseNovel` throws
and the novel page fails to load entirely.
Wrap the summary in a `
` before passing it to `$()` so cheerio always
takes the HTML branch. Plain text becomes `
plain text
` (parses
fine, `.text()` still returns the original string), HTML stays HTML, and
the existing `.find('br').replaceWith('\n')` / `.find('p').before/after`
behavior is preserved either way.
Bumps version 2.1.0 → 2.1.1.
Repro:
- Open the source, search/browse to "Trash of the Count's Family" (or any
novel where the API returns a plain-text summary)
- Tap the entry; details fail with `QuickJsException: Expected name, found .`
---
plugins/english/novelbuddy.ts | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/plugins/english/novelbuddy.ts b/plugins/english/novelbuddy.ts
index f02735e..b30cf46 100644
--- a/plugins/english/novelbuddy.ts
+++ b/plugins/english/novelbuddy.ts
@@ -9,7 +9,7 @@ class NovelBuddy implements Plugin.PluginBase {
name = 'NovelBuddy';
site = 'https://novelbuddy.com/';
api = 'https://api.novelbuddy.com/';
- version = '2.1.0';
+ version = '2.1.1';
icon = 'src/en/novelbuddy/icon.png';
parseNovels(body: Response): Plugin.NovelItem[] {
@@ -97,7 +97,12 @@ class NovelBuddy implements Plugin.PluginBase {
};
novel.status = map[rawStatus.toLowerCase()] ?? NovelStatus.Unknown;
- const summary = $(initialManga.summary || '');
+ // Wrap in
before passing to $(): when the API returns plain text (no leading
+ // `<` tag) cheerio's $() treats the input as a CSS selector, and any `.` in the text
+ // (e.g. punctuation in "I was inside a novel.") trips the selector parser with
+ // "Expected name, found ." and the entire parseNovel call fails. Wrapping forces the
+ // HTML-parsing branch regardless of whether the summary is plain text or HTML.
+ const summary = $('
' + (initialManga.summary || '') + '
');
summary.find('br').replaceWith('\n');
summary.find('p').before('\n').after('\n\n');