Fix broken layout when book has !important styles

This commit is contained in:
John Factotum
2023-11-15 04:33:02 +08:00
parent f75fbba096
commit 2ea63929c7
+39 -34
View File
@@ -150,6 +150,11 @@ const makeMarginals = (length, part) => Array.from({ length }, () => {
return div return div
}) })
const setStylesImportant = (el, styles) => {
const { style } = el
for (const [k, v] of Object.entries(styles)) style.setProperty(k, v, 'important')
}
class View { class View {
#observer = new ResizeObserver(() => this.expand()) #observer = new ResizeObserver(() => this.expand())
#element = document.createElement('div') #element = document.createElement('div')
@@ -235,16 +240,16 @@ class View {
scrolled({ gap, columnWidth }) { scrolled({ gap, columnWidth }) {
const vertical = this.#vertical const vertical = this.#vertical
const doc = this.document const doc = this.document
Object.assign(doc.documentElement.style, { setStylesImportant(doc.documentElement, {
boxSizing: 'border-box', 'box-sizing': 'border-box',
padding: vertical ? `${gap}px 0` : `0 ${gap}px`, 'padding': vertical ? `${gap}px 0` : `0 ${gap}px`,
columnWidth: 'auto', 'column-width': 'auto',
height: 'auto', 'height': 'auto',
width: 'auto', 'width': 'auto',
}) })
Object.assign(doc.body.style, { setStylesImportant(doc.body, {
[vertical ? 'maxHeight' : 'maxWidth']: `${columnWidth}px`, [vertical ? 'max-height' : 'max-width']: `${columnWidth}px`,
margin: 'auto', 'margin': 'auto',
}) })
this.setImageSize() this.setImageSize()
this.expand() this.expand()
@@ -254,29 +259,29 @@ class View {
this.#size = vertical ? height : width this.#size = vertical ? height : width
const doc = this.document const doc = this.document
Object.assign(doc.documentElement.style, { setStylesImportant(doc.documentElement, {
boxSizing: 'border-box', 'box-sizing': 'border-box',
columnWidth: `${Math.trunc(columnWidth)}px`, 'column-width': `${Math.trunc(columnWidth)}px`,
columnGap: `${gap}px`, 'column-gap': `${gap}px`,
columnFill: 'auto', 'column-fill': 'auto',
...(vertical ...(vertical
? { width: `${width}px` } ? { 'width': `${width}px` }
: { height: `${height}px` }), : { 'height': `${height}px` }),
padding: vertical ? `${gap / 2}px 0` : `0 ${gap / 2}px`, 'padding': vertical ? `${gap / 2}px 0` : `0 ${gap / 2}px`,
overflow: 'hidden', 'overflow': 'hidden',
// force wrap long words // force wrap long words
overflowWrap: 'anywhere', 'overflow-wrap': 'anywhere',
// reset some potentially problematic props // reset some potentially problematic props
position: 'static', border: '0', margin: '0', 'position': 'static', 'border': '0', 'margin': '0',
maxHeight: 'none', maxWidth: 'none', 'max-height': 'none', 'max-width': 'none',
minHeight: 'none', minWidth: 'none', 'min-height': 'none', 'min-width': 'none',
// fix glyph clipping in WebKit // fix glyph clipping in WebKit
webkitLineBoxContain: 'block glyphs replaced', '-webkit-line-box-contain': 'block glyphs replaced',
}) })
Object.assign(doc.body.style, { setStylesImportant(doc.body, {
maxHeight: 'none', 'max-height': 'none',
maxWidth: 'none', 'max-width': 'none',
margin: '0', 'margin': '0',
}) })
this.setImageSize() this.setImageSize()
this.expand() this.expand()
@@ -288,17 +293,17 @@ class View {
for (const el of doc.body.querySelectorAll('img, svg, video')) { for (const el of doc.body.querySelectorAll('img, svg, video')) {
// preserve max size if they are already set // preserve max size if they are already set
const { maxHeight, maxWidth } = doc.defaultView.getComputedStyle(el) const { maxHeight, maxWidth } = doc.defaultView.getComputedStyle(el)
Object.assign(el.style, { setStylesImportant(el, {
maxHeight: vertical 'max-height': vertical
? (maxHeight !== 'none' && maxHeight !== '0px' ? maxHeight : '100%') ? (maxHeight !== 'none' && maxHeight !== '0px' ? maxHeight : '100%')
: `${height - margin * 2}px`, : `${height - margin * 2}px`,
maxWidth: vertical 'max-width': vertical
? `${width - margin * 2}px` ? `${width - margin * 2}px`
: (maxWidth !== 'none' && maxWidth !== '0px' ? maxWidth : '100%'), : (maxWidth !== 'none' && maxWidth !== '0px' ? maxWidth : '100%'),
objectFit: 'contain', 'object-fit': 'contain',
pageBreakInside: 'avoid', 'page-break-inside': 'avoid',
breakInside: 'avoid', 'break-inside': 'avoid',
boxSizing: 'border-box', 'box-sizing': 'border-box',
}) })
} }
} }