docs: clean up comments
This commit is contained in:
1 parent
15f7e50976
commit
d11fc065f8
5 files changed
+33
-57
No files matched your search
@@ -3,10 +3,9 @@ import type { Node as PMNode } from '@tiptap/pm/model';
|
||||
import { TextSelection } from '@tiptap/pm/state';
|
||||
import type { EditorState, Transaction } from '@tiptap/pm/state';
|
||||
|
||||
// A multi-column (newspaper) section: a block region whose content flows through
|
||||
// balanced CSS columns. The document may hold it as several adjacent fragments with
|
||||
// equal attrs — a "chain" — so the flow can continue across page breaks
|
||||
// (columnsFlow.ts splits/joins fragments); export merges a chain into one section.
|
||||
// A multi-column (newspaper) section: content flows through balanced CSS columns.
|
||||
// The doc may hold it as adjacent equal-attr fragments (a "chain") so columnsFlow.ts
|
||||
// can split/join across page breaks; export merges a chain into one section.
|
||||
|
||||
export const DEFAULT_COLUMN_GAP_CM = 0.5;
|
||||
export const MAX_COLUMN_GAP_CM = 5;
|
||||
@@ -26,11 +25,9 @@ declare module '@tiptap/core' {
|
||||
}
|
||||
}
|
||||
|
||||
// Shared fit margin for the "does the first block fit the remaining page space"
|
||||
// test: the balanced-height estimate (block height / count) undershoots the real
|
||||
// fragment height by margins + line quantization. pageBreaks.ts (push vs. wait for
|
||||
// the flow) and columnsFlow.ts (split vs. leave) MUST use the same margin, or the
|
||||
// two disagree at the boundary and split/push/join cycle forever.
|
||||
// Fit margin for "does the first block fit the remaining page space": the
|
||||
// balanced-height estimate undershoots real height by margins + line quantization.
|
||||
// pageBreaks.ts and columnsFlow.ts MUST share this or split/push/join cycles forever.
|
||||
export const COLUMNS_FIT_MARGIN_PX = 32;
|
||||
|
||||
export function clampColumnCount(n: number): number {
|
||||
|
||||
@@ -7,20 +7,9 @@ import type { Node as PMNode } from '@tiptap/pm/model';
|
||||
import { readVerticalMargins, FORCE_PAGE_RECALC } from './pageBreaks';
|
||||
import { sameColumnsAttrs, COLUMNS_FIT_MARGIN_PX } from './columns';
|
||||
|
||||
// Cross-page column flow: the document holds a columns section as adjacent
|
||||
// equal-attr fragments ("chain"). This layout pass keeps the fragmentation in sync
|
||||
// with the page grid — an overflowing fragment is split at a block boundary (or,
|
||||
// for a paragraph taller than the page slot, at a LINE boundary: the second part
|
||||
// carries the layout-internal joinPrev attr and is re-merged by joins/export), and
|
||||
// a fragment with room pulls the continuation back. Splits/joins are pure layout:
|
||||
// they never enter the undo history, and export merges a chain into one section.
|
||||
//
|
||||
// Fill order is sequential like Word (column 1 fills to the page bottom, then
|
||||
// column 2, then the next page): fragments get a node decoration with an explicit
|
||||
// height + column-fill:auto — full page slot for fragments with a continuation,
|
||||
// content height for the open last fragment of a document-final chain (so typing
|
||||
// grows column 1 first). A chain followed by real content keeps CSS balance on its
|
||||
// last fragment (Word balances the end of a continuous section).
|
||||
// Cross-page column flow: keeps a columns chain's fragmentation in sync with the
|
||||
// page grid (split an overflowing fragment at a block or line boundary, pull a
|
||||
// fragment with room back) via layout-only transactions that never enter undo history.
|
||||
|
||||
const flowKey = new PluginKey<number>('columnsFlow');
|
||||
const FLOW_TX = 'columnsFlowTx';
|
||||
@@ -208,11 +197,9 @@ export const ColumnsFlow = Extension.create({
|
||||
return open;
|
||||
}
|
||||
|
||||
// Split the paragraph at child `blockIndex` at the line whose prefix
|
||||
// consumes `budgetPx` of content flow (Word's mid-paragraph page break);
|
||||
// the second part is marked joinPrev so joins/export restore the original.
|
||||
// `force` takes at least one line even when the budget is tiny (progress
|
||||
// guard for a paragraph taller than the whole page slot).
|
||||
// Split the paragraph at `blockIndex` at the line consuming `budgetPx` (Word's
|
||||
// mid-paragraph page break); the second part is marked joinPrev so joins/export
|
||||
// restore the original. `force` takes at least one line for an over-tall paragraph.
|
||||
function splitParagraphInBlock(
|
||||
frag: Fragment, children: Element[], blockIndex: number, budgetPx: number,
|
||||
scale: number, force: boolean,
|
||||
@@ -346,10 +333,9 @@ export const ColumnsFlow = Extension.create({
|
||||
const headIsJoinPrev =
|
||||
headBlock.type.name === 'paragraph' && headBlock.attrs.joinPrev &&
|
||||
node.child(node.childCount - 1).type.name === 'paragraph';
|
||||
// A joinPrev head needs only one more line row to make progress; a
|
||||
// multi-line paragraph head can be pulled PARTIALLY (the overflow
|
||||
// split hands the excess back via a line split), so ~two line rows
|
||||
// of room justify the pull; any other block needs its full share.
|
||||
// A joinPrev head needs only one more line row; a multi-line head can be
|
||||
// pulled PARTIALLY (the overflow split hands the excess back), so ~two
|
||||
// line rows justify the pull — any other block needs its full share.
|
||||
const headLines = headBlock.type.name === 'paragraph' ? lineRects(nextFirst) : [];
|
||||
const headAdvance = (lineAdvance(headLines) || DEFAULT_LINE_PX * scale) / scale;
|
||||
const need = headIsJoinPrev
|
||||
@@ -373,10 +359,9 @@ export const ColumnsFlow = Extension.create({
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sequential-fill heights: a fragment with a continuation spans its page
|
||||
// slot; the open last fragment of a document-final chain hugs its content
|
||||
// (plus slack) so typing fills column 1 first. A chain followed by real
|
||||
// content keeps its last fragment undecorated (CSS balance).
|
||||
// Sequential-fill heights: a fragment with a continuation spans its page slot;
|
||||
// an open last fragment hugs its content (plus slack) so typing fills column 1
|
||||
// first. Otherwise the last fragment stays undecorated (CSS balance).
|
||||
function updateDecorations(): void {
|
||||
const frags = fragments();
|
||||
const vm = readVerticalMargins(editorView.dom);
|
||||
|
||||
@@ -130,9 +130,8 @@ export type VMargins = {
|
||||
};
|
||||
|
||||
// Reads vertical page margins + page height (px) from the --user-* props the Layout
|
||||
// panel writes. Document-px values, so they pair directly with offsetTop below. Side
|
||||
// margins don't affect pagination (only line wrapping), so they're ignored.
|
||||
// Exported for columnsFlow.ts, which shares this geometry.
|
||||
// panel writes (document-px, pairing directly with offsetTop below); side margins
|
||||
// are ignored (they affect line wrapping, not pagination). Shared with columnsFlow.ts.
|
||||
export function readVerticalMargins(dom: HTMLElement): VMargins {
|
||||
const cs = getComputedStyle(dom);
|
||||
const top = parseFloat(cs.getPropertyValue('--user-margin-top'));
|
||||
@@ -190,10 +189,9 @@ type Leaf = {
|
||||
cellStart?: boolean;
|
||||
rowStart?: boolean;
|
||||
rowEnd?: boolean;
|
||||
// A multi-column section fragment (columns.ts). columnsFlow.ts splits an
|
||||
// overflowing fragment at a block boundary, so pagination must NOT push it when
|
||||
// the flow can act: it only pushes when the first block alone can't fit the
|
||||
// remaining page space (then the flow splits it at the next page top).
|
||||
// A multi-column section fragment (columns.ts): pagination only pushes it when
|
||||
// the first block alone can't fit the remaining space (else columnsFlow.ts splits
|
||||
// the overflow at a block boundary).
|
||||
columnsFragment?: { blockCount: number; firstBlockNeededPx: number };
|
||||
};
|
||||
|
||||
@@ -817,10 +815,9 @@ export const PageBreaks = Extension.create({
|
||||
// Set when a leaf overflows but no spacer can bridge it (block > one page).
|
||||
let noPushReason: string | null = null;
|
||||
|
||||
// The empty trailing paragraph after a document-final columns chain: its
|
||||
// fragment box may run to the page bottom (sequential fill), which would
|
||||
// shove this invisible paragraph onto a phantom extra page. Leave it in
|
||||
// place and keep it out of the page count; typed text re-enables it.
|
||||
// A sequential-fill chain's fragment box may run to the page bottom, which
|
||||
// would shove this trailing empty paragraph onto a phantom extra page —
|
||||
// leave it in place and out of the page count; typed text re-enables it.
|
||||
if (
|
||||
i === leaves.length - 1 &&
|
||||
leaf.el.tagName === 'P' &&
|
||||
|
||||
@@ -83,10 +83,9 @@ const TOC_SENT = '';
|
||||
// <draw:frame>/<draw:text-box> or <draw:custom-shape>. U+E008.
|
||||
const TBX = '';
|
||||
|
||||
// Sentinel bracketing a hoisted multi-column section's blocks (marker paragraphs
|
||||
// COL S{i} COL … COL E{i} COL): replaceColumns hoists like replaceTextBoxes;
|
||||
// applyColumns wraps the region into a <text:section> with a minted section style
|
||||
// carrying <style:columns>. U+E009.
|
||||
// Sentinel bracketing a hoisted multi-column section's blocks, same mechanism as
|
||||
// TBX above; applyColumns wraps the region into a <text:section> with a minted
|
||||
// section style carrying <style:columns>. U+E009.
|
||||
const COL = '';
|
||||
|
||||
const EXT_BY_MIME: Record<string, string> = {
|
||||
@@ -346,10 +345,9 @@ export function mergeJoinedParagraphsJson(blocks: TiptapNode[]): TiptapNode[] {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Swap each top-level columns section for marker paragraphs bracketing its hoisted
|
||||
// child blocks (same mechanism as replaceTextBoxes); applyColumns re-wraps the
|
||||
// serialized region into a <text:section>. Adjacent equal-attr fragments are a
|
||||
// columnsFlow.ts page-split chain — one section, so they coalesce here.
|
||||
// Swap each top-level columns section for marker paragraphs (same mechanism as
|
||||
// replaceTextBoxes). Adjacent equal-attr fragments are a columnsFlow.ts page-split
|
||||
// chain — one section, so they coalesce here.
|
||||
function replaceColumns(doc: TiptapNode, cols: ColumnsExport[]): TiptapNode {
|
||||
if (!doc.content?.length) return doc;
|
||||
const content: TiptapNode[] = [];
|
||||
|
||||
@@ -859,8 +859,7 @@ function flattenTable(tbl: Element, ctx: Ctx): Node[] {
|
||||
|
||||
// ---- section: page geometry + headers/footers ------------------------------
|
||||
// Split body children into sections: a <w:p> whose pPr carries a sectPr ends the
|
||||
// group before it (a continuous section break). The marker paragraph is dropped
|
||||
// unless it has run content (ours and Word's are empty). The trailing group has
|
||||
// group before it (dropped unless it has run content). The trailing group has
|
||||
// sectPr null — the caller pairs it with the body-final <w:sectPr>.
|
||||
function splitBodySections(children: Element[]): {
|
||||
groups: { els: Element[]; sectPr: Element | null }[];
|
||||
|
||||
Reference in new issue
Block a user