// How a document looks — the typography of the page itself, as opposed to // the editor's furniture around it (that lives in editor.css). // // It is a string rather than a stylesheet because two different documents // need exactly these rules: the editor's own page, and the standalone HTML // handed to Chromium when exporting a PDF. Loading a shared .css file into // the export isn't possible — it is rendered in a throwaway window from a // temp file, with no add-on folder to resolve relative URLs against — and // keeping two copies in step by hand is how a PDF starts quietly disagreeing // with what the user was looking at. // // Defaults follow Word's: an 11pt serif body with a little space after each // paragraph, so an untouched document looks about the same in both places. (function (root, factory) { const api = factory(); if (typeof module === "object" && module.exports) module.exports = api; root.DocxEditor = Object.assign(root.DocxEditor || {}, { docCss: api }); })(typeof globalThis !== "undefined" ? globalThis : this, function () { "use strict"; const DOC_CSS = ` .sheet { font: 11pt/1.5 Georgia, "Times New Roman", serif; color: #14161a; } .sheet p { margin: 0 0 8pt; } .sheet h1, .sheet h2, .sheet h3, .sheet h4, .sheet h5, .sheet h6 { font-family: "Segoe UI Semibold", "Segoe UI", Calibri, system-ui, sans-serif; color: #1f4e79; font-weight: 600; margin: 14pt 0 6pt; line-height: 1.25; } .sheet h1 { font-size: 20pt; } .sheet h2 { font-size: 16pt; } .sheet h3 { font-size: 13pt; } .sheet h4 { font-size: 12pt; } .sheet h5 { font-size: 11pt; } .sheet h6 { font-size: 10.5pt; color: #2e74b5; } .sheet blockquote { margin: 8pt 0 8pt 24pt; padding-left: 10pt; border-left: 3px solid rgba(0,0,0,.15); color: #404040; font-style: italic; } .sheet pre { font: 10pt/1.4 Consolas, "Courier New", monospace; background: rgba(0,0,0,.04); border: 1px solid rgba(0,0,0,.08); border-radius: 3px; padding: 8pt 10pt; margin: 8pt 0; white-space: pre-wrap; } .sheet hr { border: 0; border-top: 1px solid #808080; margin: 10pt 0; } .sheet ul, .sheet ol { margin: 0 0 8pt; padding-left: 28pt; } .sheet li { margin: 0 0 2pt; } .sheet li > p { margin: 0 0 2pt; } .sheet a { color: #0563c1; text-decoration: underline; } .sheet img { max-width: 100%; height: auto; vertical-align: baseline; } .sheet table { border-collapse: collapse; margin: 8pt 0; width: 100%; table-layout: fixed; } .sheet td, .sheet th { border: 1px solid #999; padding: 4pt 6pt; vertical-align: top; position: relative; min-width: 1em; } .sheet th { background: rgba(0,0,0,.04); font-weight: 600; text-align: left; } .sheet td > p:last-child, .sheet th > p:last-child { margin-bottom: 0; } .sheet .docx-note-ref { color: #0563c1; font-size: .7em; padding: 0 1px; border-bottom: 1px dotted #0563c1; } /* A page break is a labelled dashed rule on screen and a real break on paper. printToPDF renders with print media, so this covers the PDF export and Ctrl+P both. */ .sheet .docx-page-break { border-top: 1px dashed #b00; margin: 14pt 0; text-align: center; user-select: none; position: relative; } .sheet .docx-page-break span { font: 9pt/1 system-ui, sans-serif; color: #b00; background: #fff; padding: 0 8px; position: relative; top: -6pt; letter-spacing: .04em; } @media print { .sheet .docx-page-break { border: 0; margin: 0; break-after: page; page-break-after: always; } .sheet .docx-page-break span { display: none; } .sheet table, .sheet tr, .sheet img { break-inside: avoid; } .sheet h1, .sheet h2, .sheet h3, .sheet h4, .sheet h5, .sheet h6 { break-after: avoid; } } `; // Twips are Word's unit (1440 to the inch); CSS wants inches. Rounded to // thousandths, which is finer than any printer cares about and keeps the // @page rule readable. const inches = (twips, fallback) => { const n = Number(twips); return (Number.isFinite(n) && n > 0 ? n / 1440 : fallback).toFixed(3); }; // An @page rule from the document's own section setup, so the PDF comes // out on the paper the author chose instead of Chromium's default Letter. function pageRule(setup) { const page = (setup && setup.page) || {}; const size = page.size || {}; const m = page.margin || {}; const w = inches(size.width, 8.27); // A4 unless the file says otherwise const h = inches(size.height, 11.69); const top = inches(m.top, 1); const right = inches(m.right, 1); const bottom = inches(m.bottom, 1); const left = inches(m.left, 1); return `@page { size: ${w}in ${h}in; margin: ${top}in ${right}in ${bottom}in ${left}in; }`; } /** * A standalone HTML page of the document, ready to be handed to Chromium's * print pipeline. Everything is inline: no stylesheet to resolve, no * scripts, and images are already data URLs by the time they reach here. */ function printableHtml({ title, bodyHtml, setup }) { const esc = (s) => String(s || "").replace(/[&<>]/g, (c) => ({ "&": "&", "<": "<", ">": ">" }[c])); return ` ${esc(title || "Document")}
${bodyHtml}
`; } return { DOC_CSS, printableHtml, pageRule }; });