fix(novelbuddy): Wrap Summary in <div> to Ensure HTML Parsing with Cheerio (#2166)

`$()` 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 `<div>` before passing it to `$()` so cheerio always
takes the HTML branch. Plain text becomes `<div>plain text</div>` (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 .`
This commit is contained in:
Ahmed Mohamed
2026-05-04 12:13:41 +03:00
committed by GitHub
parent b23a4a9a92
commit 0b1c2c2404
+7 -2
View File
@@ -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 <div> 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 = $('<div>' + (initialManga.summary || '') + '</div>');
summary.find('br').replaceWith('\n');
summary.find('p').before('\n').after('\n\n');