fix: webserver stability, memory leaks, epub underlining, flash screen
Webserver: - Remove MD5 hash computation from file listings (caused EAGAIN errors) - Implement JSON batching (2KB) with pacing for file listings - Simplify sendContentSafe() flow control Memory: - Cache QR codes on server start instead of regenerating per render - Optimize WiFi scan: vector deduplication, 20 network limit, early scanDelete() - Fix 48KB cover buffer leak when navigating Home -> File Transfer EPUB Reader: - Fix errant underlining by flushing partWordBuffer before style changes - Text before styled inline elements (e.g., <a> with CSS underline) no longer incorrectly receives the element's styling Flash Screen: - Fix version string buffer overflow (30 -> 50 char limit) - Use half refresh for cleaner display - Adjust pre_flash.py timing for half refresh completion
This commit is contained in:
@@ -485,6 +485,9 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
||||
}
|
||||
}
|
||||
} else if (matches(name, UNDERLINE_TAGS, NUM_UNDERLINE_TAGS)) {
|
||||
// Flush buffer with CURRENT style before changing effective style
|
||||
self->flushPartWordBuffer();
|
||||
|
||||
self->underlineUntilDepth = std::min(self->underlineUntilDepth, self->depth);
|
||||
// Push inline style entry for underline tag
|
||||
StyleStackEntry entry;
|
||||
@@ -502,6 +505,9 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
||||
self->inlineStyleStack.push_back(entry);
|
||||
self->updateEffectiveInlineStyle();
|
||||
} else if (matches(name, BOLD_TAGS, NUM_BOLD_TAGS)) {
|
||||
// Flush buffer with CURRENT style before changing effective style
|
||||
self->flushPartWordBuffer();
|
||||
|
||||
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
||||
// Push inline style entry for bold tag
|
||||
StyleStackEntry entry;
|
||||
@@ -519,6 +525,9 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
||||
self->inlineStyleStack.push_back(entry);
|
||||
self->updateEffectiveInlineStyle();
|
||||
} else if (matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS)) {
|
||||
// Flush buffer with CURRENT style before changing effective style
|
||||
self->flushPartWordBuffer();
|
||||
|
||||
self->italicUntilDepth = std::min(self->italicUntilDepth, self->depth);
|
||||
// Push inline style entry for italic tag
|
||||
StyleStackEntry entry;
|
||||
@@ -538,6 +547,10 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
||||
} else if (strcmp(name, "span") == 0 || !isBlockElement) {
|
||||
// Handle span and other inline elements for CSS styling
|
||||
if (cssStyle.hasFontWeight() || cssStyle.hasFontStyle() || cssStyle.hasTextDecoration()) {
|
||||
// Flush buffer with CURRENT style before changing effective style
|
||||
// This prevents text accumulated before this element from getting the new style
|
||||
self->flushPartWordBuffer();
|
||||
|
||||
StyleStackEntry entry;
|
||||
entry.depth = self->depth; // Track depth for matching pop
|
||||
if (cssStyle.hasFontWeight()) {
|
||||
@@ -573,6 +586,33 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char
|
||||
self->lastCharDataOffset = XML_GetCurrentByteIndex(self->xmlParser);
|
||||
}
|
||||
|
||||
// If we're inside an <li> but no text block was created yet (direct text without inner <p>),
|
||||
// create a text block and add the list marker now
|
||||
if (self->insideListItem && !self->listItemHasContent) {
|
||||
// Apply left margin for list items
|
||||
CssStyle cssStyle;
|
||||
cssStyle.marginLeft = 24.0f; // Default indent (~1.5em at 16px base)
|
||||
cssStyle.defined.marginLeft = 1;
|
||||
|
||||
BlockStyle blockStyle = createBlockStyleFromCss(cssStyle);
|
||||
self->startNewTextBlock(static_cast<TextBlock::Style>(self->paragraphAlignment), blockStyle);
|
||||
|
||||
// Add the list marker
|
||||
if (!self->listStack.empty()) {
|
||||
const ListContext& ctx = self->listStack.back();
|
||||
if (ctx.isOrdered) {
|
||||
std::string marker = std::to_string(ctx.counter) + ". ";
|
||||
self->currentTextBlock->addWord(marker, EpdFontFamily::REGULAR);
|
||||
} else {
|
||||
self->currentTextBlock->addWord("\xe2\x80\xa2", EpdFontFamily::REGULAR);
|
||||
}
|
||||
} else {
|
||||
// No list context (orphan li), use bullet as fallback
|
||||
self->currentTextBlock->addWord("\xe2\x80\xa2", EpdFontFamily::REGULAR);
|
||||
}
|
||||
self->listItemHasContent = true;
|
||||
}
|
||||
|
||||
// Determine font style from depth-based tracking and CSS effective style
|
||||
const bool isBold = self->boldUntilDepth < self->depth || self->effectiveBold;
|
||||
const bool isItalic = self->italicUntilDepth < self->depth || self->effectiveItalic;
|
||||
|
||||
Reference in New Issue
Block a user