fix: every leaf's natural top is reconstructed the same way
Only the ordinary-block push site added the space the page-top rule had dropped above it; the index, text box, columns and table-row sites subtracted the spacers alone, so each of those measured too high by whatever the pages above had swallowed and got an equally oversized spacer — a fixture's figure frames landed 16mm down their page. One naturalTopOf() now serves all six.
This commit is contained in:
1 parent
7a4174cd07
commit
0712d44ebf
2 files changed
+17
-7
No files matched your search
@@ -49,6 +49,9 @@ same document opened at 59 or 65 pages from one load to the next. `collectLeaves
|
||||
space back (`spaceAbove`, and a running `cumulativeDropped` for the leaves below), so what it
|
||||
measures is the document; the placement loop then takes the drop off `cumulativeShift` itself. The
|
||||
rule is general — anything the pass decides has to be reconstructed out of the next pass's input.
|
||||
Every leaf is therefore born through `naturalTopOf`: four of the six push sites (index, text box,
|
||||
columns fragment, table row) once subtracted the spacers but not the dropped space, and a figure
|
||||
frame below a chapter heading landed 16mm down its page.
|
||||
|
||||
**A justified line fits more in LibreOffice than in a browser:** LibreOffice compresses the
|
||||
inter-word spaces to squeeze one more word onto a justified line, CSS `text-align: justify` only
|
||||
|
||||
@@ -628,6 +628,13 @@ export const PageBreaks = Extension.create({
|
||||
return top;
|
||||
}
|
||||
|
||||
// A leaf's top in the undecorated document: the rendered top with the spacers
|
||||
// above it taken out and the space they swallowed put back, so a pass never
|
||||
// measures its own previous answer. Every leaf must be born through this.
|
||||
function naturalTopOf(el: HTMLElement): number {
|
||||
return topWithin(el) - cumulativeSpacerHeight + cumulativeDropped;
|
||||
}
|
||||
|
||||
// Emit one atomic leaf per table row so the table breaks between rows across
|
||||
// pages (a whole table is usually taller than a page). TipTap renders tables as
|
||||
// <div class="tableWrapper"><table><colgroup><tbody>…, so walk the tbody rows.
|
||||
@@ -645,7 +652,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: wrapperEl,
|
||||
kind: 'atomic',
|
||||
naturalTop: topWithin(wrapperEl) - cumulativeSpacerHeight,
|
||||
naturalTop: naturalTopOf(wrapperEl),
|
||||
naturalHeight: wrapperEl.offsetHeight,
|
||||
});
|
||||
return;
|
||||
@@ -665,7 +672,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: tr,
|
||||
kind: 'atomic',
|
||||
naturalTop: topWithin(tr) - cumulativeSpacerHeight,
|
||||
naturalTop: naturalTopOf(tr),
|
||||
naturalHeight: rowHeight,
|
||||
tableRow: { columns, wrapperEl, isFirstRow: !seenRealRow },
|
||||
});
|
||||
@@ -732,7 +739,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: child,
|
||||
kind: 'atomic',
|
||||
naturalTop: topWithin(child) - cumulativeSpacerHeight,
|
||||
naturalTop: naturalTopOf(child),
|
||||
naturalHeight: child.offsetHeight,
|
||||
inTableCell,
|
||||
});
|
||||
@@ -744,7 +751,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: child,
|
||||
kind: 'atomic',
|
||||
naturalTop: topWithin(child) - cumulativeSpacerHeight,
|
||||
naturalTop: naturalTopOf(child),
|
||||
naturalHeight: child.offsetHeight,
|
||||
inTableCell,
|
||||
});
|
||||
@@ -764,7 +771,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: child,
|
||||
kind: 'atomic',
|
||||
naturalTop: topWithin(child) - cumulativeSpacerHeight,
|
||||
naturalTop: naturalTopOf(child),
|
||||
naturalHeight: child.offsetHeight,
|
||||
inTableCell,
|
||||
columnsFragment: {
|
||||
@@ -816,7 +823,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: child,
|
||||
kind: isAtomic ? 'atomic' : 'splittable',
|
||||
naturalTop: topWithin(child) - cumulativeSpacerHeight + cumulativeDropped,
|
||||
naturalTop: naturalTopOf(child),
|
||||
naturalHeight: Math.max(child.offsetHeight, floatBottom) - intraSpacerHeight + dropped,
|
||||
spaceAfter: inTableCell ? 0 : parseFloat(cs.marginBottom) || 0,
|
||||
spaceAbove,
|
||||
@@ -847,7 +854,7 @@ export const PageBreaks = Extension.create({
|
||||
leaves.push({
|
||||
el: child,
|
||||
kind: 'splittable',
|
||||
naturalTop: topWithin(child) - cumulativeSpacerHeight,
|
||||
naturalTop: naturalTopOf(child),
|
||||
naturalHeight: child.offsetHeight,
|
||||
inTableCell,
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user