Loading editor/src/htmlimport.cpp +29 −1 Changes for editor/src/htmlimport.cpp: 29 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -758,9 +758,37 @@ std::string blogi::htmlimport::extractCustomCss( if (k == kk) { known = true; break; } } if (!known) { toRemove.push_back(k); // "position: fixed"/"sticky" is meaningless (and actively // harmful) once carried over verbatim: both are defined relative // to the *source* page's own viewport/scroll ancestor, which // import completely discards -- the element gets re-parented into // however many extra Container/Section wrapper widgets this // function's caller needed to reconstruct the layout. Keeping it // makes a source-page sticky nav bar or fixed banner render // pinned to whatever ancestor happens to be scrollable in // blogi's own widget tree instead of the page top, floating over // unrelated content (found via bautenschutz-wetzlar.de's sticky // header, which has this exact rule). Dropping the declaration // leaves position at its default ("static"), which is always a // safer fallback than reproducing the wrong out-of-flow anchor; // any accompanying top/left/right/bottom/z-index becomes inert // on a statically positioned element, so nothing else needs to // be stripped alongside it. if (k == "position") { std::string val = v; stripImportant(val); std::transform(val.begin(), val.end(), val.begin(), [](unsigned char c) { return std::tolower(c); }); size_t s = val.find_first_not_of(" \t\r\n"); size_t e = val.find_last_not_of(" \t\r\n"); val = (s == std::string::npos) ? "" : val.substr(s, e - s + 1); if (val == "fixed" || val == "sticky") continue; } if (!plainDecls.empty()) plainDecls += " "; plainDecls += k + ": " + v + ";"; toRemove.push_back(k); } } for (auto &k : toRemove) props.erase(k); Loading Loading
editor/src/htmlimport.cpp +29 −1 Changes for editor/src/htmlimport.cpp: 29 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -758,9 +758,37 @@ std::string blogi::htmlimport::extractCustomCss( if (k == kk) { known = true; break; } } if (!known) { toRemove.push_back(k); // "position: fixed"/"sticky" is meaningless (and actively // harmful) once carried over verbatim: both are defined relative // to the *source* page's own viewport/scroll ancestor, which // import completely discards -- the element gets re-parented into // however many extra Container/Section wrapper widgets this // function's caller needed to reconstruct the layout. Keeping it // makes a source-page sticky nav bar or fixed banner render // pinned to whatever ancestor happens to be scrollable in // blogi's own widget tree instead of the page top, floating over // unrelated content (found via bautenschutz-wetzlar.de's sticky // header, which has this exact rule). Dropping the declaration // leaves position at its default ("static"), which is always a // safer fallback than reproducing the wrong out-of-flow anchor; // any accompanying top/left/right/bottom/z-index becomes inert // on a statically positioned element, so nothing else needs to // be stripped alongside it. if (k == "position") { std::string val = v; stripImportant(val); std::transform(val.begin(), val.end(), val.begin(), [](unsigned char c) { return std::tolower(c); }); size_t s = val.find_first_not_of(" \t\r\n"); size_t e = val.find_last_not_of(" \t\r\n"); val = (s == std::string::npos) ? "" : val.substr(s, e - s + 1); if (val == "fixed" || val == "sticky") continue; } if (!plainDecls.empty()) plainDecls += " "; plainDecls += k + ": " + v + ";"; toRemove.push_back(k); } } for (auto &k : toRemove) props.erase(k); Loading