feat(docx-editor): the page fills the window, and two fonts ship with it
The page sat marooned in the middle of a wide window with dark space either side of it. It is now drawn at the size the document actually claims — A4 stays A4, margins come from its own sectPr — and CSS `zoom` scales that to fit, defaulting to Fit width with a control in the footer and Ctrl +/-/0. Scaling rather than widening is deliberate. A page stretched to the window would break every line somewhere different from where the printed page breaks it, and an editor whose whole claim is that it shows you the document should not lie about where the lines end. `zoom` also beats a transform here: it affects layout, so the board scrolls correctly and ProseMirror's coordinate maths keeps working. Ubuntu and Fraunces now ship in fonts/, because Windows has neither and a font offered in the ribbon that the machine lacks is a font the user picks and then cannot see. Fetched once by `npm run fonts` and committed, never at runtime: an extension in a browser built around not phoning home should not ask a font CDN what a document looks like every time one is opened. Two things had to be worked around. On file:// Chromium registers @font-face rules and then refuses to fetch the files — the family appears in document.fonts and every glyph still renders in the fallback — so the add-on reads the woff2 and hands the page a stylesheet with them inlined as data URLs. The PDF export needed the same treatment for a different reason: its print window runs from a temp folder, where a relative url() resolves to nothing, which would have quietly undone the one-stylesheet-for-both promise that lib/doc-css.js exists to keep. If either path fails, the ribbon labels those families "(not available)" rather than implying otherwise. About 700 KB, most of it Ubuntu's Cyrillic and Greek — kept because the documents this is used on are not all English. Licences ship alongside.
This commit is contained in:
parent
f189b48102
commit
2f8eaa62ff
29 changed files with 679 additions and 6 deletions
85
addon-build/docx-editor/fetch-fonts.mjs
Normal file
85
addon-build/docx-editor/fetch-fonts.mjs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
// Vendor the editor's bundled webfonts.
|
||||
//
|
||||
// npm run fonts (from addon-build/docx-editor/)
|
||||
//
|
||||
// The editor offers fonts in its ribbon, and a font the machine doesn't have
|
||||
// is a font the user picks and then cannot see. Ubuntu and Fraunces are not
|
||||
// on Windows, so they ship with the add-on.
|
||||
//
|
||||
// Fetched from Google Fonts once, here, and committed — never at runtime. An
|
||||
// extension in a browser built around not phoning home should not ask
|
||||
// fonts.gstatic.com what a document looks like every time one is opened.
|
||||
//
|
||||
// Subsets: Latin plus Cyrillic and Greek where the family has them, because
|
||||
// the documents this editor is actually used on are not all English.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
const OUT = path.resolve(here, "../../bundled-addons/docx-editor/fonts");
|
||||
|
||||
// A browser UA, or Google serves ttf instead of woff2.
|
||||
const UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
|
||||
"(KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
||||
|
||||
const FAMILIES = [
|
||||
{
|
||||
name: "Ubuntu",
|
||||
css: "https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,400;0,700;1,400;1,700&display=block",
|
||||
// No cyrillic-ext or greek-ext: 148 KB for historic and liturgical
|
||||
// ranges that a word processor's font menu will not miss.
|
||||
keep: ["latin", "latin-ext", "cyrillic", "greek"],
|
||||
},
|
||||
{
|
||||
// The variable file, which is smaller than the four static instances it
|
||||
// replaces (280 KB against 305 KB) and carries every weight between them.
|
||||
name: "Fraunces",
|
||||
css: "https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,100..900;1,9..144,100..900&display=block",
|
||||
keep: ["latin", "latin-ext"],
|
||||
},
|
||||
];
|
||||
|
||||
async function text(url) {
|
||||
const r = await fetch(url, { headers: { "User-Agent": UA } });
|
||||
if (!r.ok) throw new Error(`${r.status} for ${url}`);
|
||||
return r.text();
|
||||
}
|
||||
|
||||
fs.mkdirSync(OUT, { recursive: true });
|
||||
let css = `/* Bundled with the Word editor — see addon-build/docx-editor/fetch-fonts.mjs.
|
||||
Regenerate with \`npm run fonts\`; do not edit by hand. */\n`;
|
||||
let total = 0;
|
||||
|
||||
for (const fam of FAMILIES) {
|
||||
const sheet = await text(fam.css);
|
||||
// Google's stylesheet is a run of /* subset */ + @font-face blocks.
|
||||
const blocks = sheet.split("/*").slice(1);
|
||||
let n = 0;
|
||||
for (const raw of blocks) {
|
||||
const subset = raw.slice(0, raw.indexOf("*/")).trim();
|
||||
if (!fam.keep.includes(subset)) continue;
|
||||
const block = raw.slice(raw.indexOf("*/") + 2);
|
||||
const url = /src:\s*url\(([^)]+)\)/.exec(block)?.[1];
|
||||
if (!url) continue;
|
||||
const style = /font-style:\s*(\w+)/.exec(block)?.[1] || "normal";
|
||||
const weight = /font-weight:\s*([\d\s]+)/.exec(block)?.[1].trim() || "400";
|
||||
const range = /unicode-range:\s*([^;]+);/.exec(block)?.[1].trim();
|
||||
|
||||
const file = `${fam.name.toLowerCase()}-${subset}-${style}-${weight.replace(/\s+/g, "_")}.woff2`;
|
||||
const bytes = Buffer.from(await (await fetch(url, { headers: { "User-Agent": UA } })).arrayBuffer());
|
||||
fs.writeFileSync(path.join(OUT, file), bytes);
|
||||
total += bytes.length;
|
||||
n++;
|
||||
|
||||
css += `@font-face {\n font-family: '${fam.name}';\n font-style: ${style};\n` +
|
||||
` font-weight: ${weight};\n font-display: block;\n` +
|
||||
` src: url('fonts/${file}') format('woff2');\n` +
|
||||
(range ? ` unicode-range: ${range};\n` : "") + `}\n`;
|
||||
}
|
||||
console.log(`${fam.name}: ${n} file(s)`);
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.resolve(OUT, "../fonts.css"), css);
|
||||
console.log(`\n${(total / 1024).toFixed(0)} KB of woff2 in ${path.relative(path.resolve(here, "../.."), OUT)}`);
|
||||
console.log(`stylesheet: bundled-addons/docx-editor/fonts.css`);
|
||||
|
|
@ -6,7 +6,8 @@
|
|||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node build.mjs",
|
||||
"icons": "node make-icons.mjs"
|
||||
"icons": "node make-icons.mjs",
|
||||
"fonts": "node fetch-fonts.mjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"docx": "^9.5.1",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,30 @@ channel and no way in.
|
|||
The cost is about 400 KB compressed in the installer, most of it the
|
||||
vendored editor libraries.
|
||||
|
||||
## The page, and the fonts
|
||||
|
||||
The sheet is drawn at the size the document says it is — A4 stays A4, margins
|
||||
come from its own `sectPr` — and CSS `zoom` scales the whole thing to fit the
|
||||
window. Scaling rather than widening is the point: a page stretched to the
|
||||
window would break every line somewhere different from where the printed page
|
||||
breaks it. The footer carries the control, and **Fit width** is the default
|
||||
because a page marooned in the middle of a wide window wastes the screen. The
|
||||
choice is remembered per editor, not per document.
|
||||
|
||||
Ubuntu and Fraunces ship with the add-on, in `fonts/`, because Windows has
|
||||
neither and a font offered in the ribbon that the machine lacks is a font the
|
||||
user picks and then cannot see. Regenerate with `npm run fonts`; licences are
|
||||
in `fonts/LICENSES.txt`. They cost about 700 KB, most of it Ubuntu's Cyrillic
|
||||
and Greek coverage — dropping those subsets would roughly halve it.
|
||||
|
||||
Two wrinkles worth knowing. The editor is on `file://`, where Chromium
|
||||
registers `@font-face` rules but refuses to fetch the font files, so the
|
||||
add-on reads them and hands the page a stylesheet with the woff2 inlined as
|
||||
data URLs; the same inlined copy goes into the PDF export, whose print window
|
||||
runs from a temp folder where a relative `url()` would resolve to nothing. If
|
||||
either path fails the ribbon labels those two families "(not available)"
|
||||
rather than pretending.
|
||||
|
||||
## The icon
|
||||
|
||||
`icon.svg` is the one drawing. `npm run icons` rasterises it to
|
||||
|
|
|
|||
|
|
@ -148,10 +148,17 @@ input.rnum { width: 52px; cursor: text; text-align: center; }
|
|||
.banner .btn { border-color: var(--line); background: var(--panel2); }
|
||||
|
||||
/* ---- document surface ------------------------------------------------ */
|
||||
/* The page is drawn at the size the document says it is — A4 stays A4 —
|
||||
and `zoom` scales the whole thing to fit the window. Scaling rather than
|
||||
widening is the point: a page stretched to the window would break every
|
||||
line where the printed page does not. Chromium's `zoom` affects layout,
|
||||
unlike a transform, so the board scrolls correctly and ProseMirror's
|
||||
coordinate maths keeps working. */
|
||||
.board { flex: 1; overflow: auto; background: var(--board); padding: 20px 16px 60px; }
|
||||
.sheet { max-width: 8.27in; margin: 0 auto; background: var(--paper);
|
||||
.sheet { width: var(--page-w, 8.27in); margin: 0 auto; background: var(--paper);
|
||||
color: var(--paper-ink); box-shadow: 0 2px 18px var(--paper-edge);
|
||||
padding: 0.9in 1in; min-height: 60vh; }
|
||||
padding: var(--page-mt, .9in) var(--page-mr, 1in) var(--page-mb, .9in) var(--page-ml, 1in);
|
||||
min-height: var(--page-h, auto); zoom: var(--zoom, 1); }
|
||||
.sheet:focus { outline: none; }
|
||||
.sheet .ProseMirror { outline: none; min-height: 50vh; }
|
||||
|
||||
|
|
@ -196,6 +203,11 @@ input.rnum { width: 52px; cursor: text; text-align: center; }
|
|||
color: var(--ink); border-radius: 5px; cursor: pointer;
|
||||
padding: 3px 7px; font: inherit; font-size: 11px; flex: 0 0 auto; }
|
||||
.footer .fbtn:hover { border-color: rgb(from var(--acid) r g b / .55); }
|
||||
.footer .zoomer { display: inline-flex; align-items: center; gap: 4px; }
|
||||
.footer .fsel { border: 1px solid var(--line); background: var(--panel2); color: var(--ink);
|
||||
border-radius: 5px; font: inherit; font-size: 11px; padding: 2px 4px;
|
||||
cursor: pointer; }
|
||||
.footer .fsel:hover { border-color: rgb(from var(--acid) r g b / .55); }
|
||||
|
||||
/* ---- dialogs --------------------------------------------------------- */
|
||||
.scrim { position: fixed; inset: 0; background: rgba(4,7,12,.6); z-index: 80;
|
||||
|
|
@ -237,7 +249,9 @@ input.rnum { width: 52px; cursor: text; text-align: center; }
|
|||
.topbar, .ribbon, .footer, .banners, .pop, .scrim, .dropzone { display: none !important; }
|
||||
html, body { height: auto; overflow: visible; background: #fff; }
|
||||
.board { overflow: visible; padding: 0; background: #fff; }
|
||||
.sheet { box-shadow: none; max-width: none; margin: 0; padding: 0; background: #fff; color: #000; }
|
||||
/* On paper the page box is the paper; zoom and the screen's margins go. */
|
||||
.sheet { box-shadow: none; width: auto; margin: 0; padding: 0; background: #fff;
|
||||
color: #000; zoom: 1; min-height: 0; }
|
||||
/* Page breaks and widow control come from lib/doc-css.js, which carries
|
||||
its own @media print block so Ctrl+P and the PDF export agree. */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,19 @@
|
|||
<div class="footer">
|
||||
<span class="stat" id="stat-words">0 words</span>
|
||||
<span class="stat" id="stat-pages">1 page</span>
|
||||
<span class="stat zoomer">
|
||||
<button class="fbtn" id="zoom-out" title="Zoom out (Ctrl+-)">−</button>
|
||||
<select class="fsel" id="zoom" title="How large the page is drawn">
|
||||
<option value="fit">Fit width</option>
|
||||
<option value="page">Whole page</option>
|
||||
<option value="0.75">75%</option>
|
||||
<option value="1">100%</option>
|
||||
<option value="1.25">125%</option>
|
||||
<option value="1.5">150%</option>
|
||||
<option value="2">200%</option>
|
||||
</select>
|
||||
<button class="fbtn" id="zoom-in" title="Zoom in (Ctrl++)">+</button>
|
||||
</span>
|
||||
<span class="stat"><button class="fbtn" id="open-folder">Open folder</button></span>
|
||||
<span class="msg" id="msg"></span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,10 +34,15 @@ const DE = () => window.DocxEditor;
|
|||
const AUTOSAVE_MS = 20_000;
|
||||
const WORDS_PER_PAGE = 500;
|
||||
|
||||
// Ubuntu and Fraunces ship with the add-on (see fonts.css); the rest are
|
||||
// whatever the machine already has. A font offered in the ribbon but absent
|
||||
// from the machine is a font the user picks and then cannot see, which is
|
||||
// why the two that Windows lacks are bundled rather than merely listed.
|
||||
const BUNDLED_FONTS = ["Ubuntu", "Fraunces"];
|
||||
const FONTS = [
|
||||
"Calibri", "Cambria", "Georgia", "Times New Roman", "Arial", "Helvetica",
|
||||
"Verdana", "Tahoma", "Trebuchet MS", "Garamond", "Book Antiqua",
|
||||
"Courier New", "Consolas", "Segoe UI",
|
||||
"Courier New", "Consolas", "Segoe UI", "Ubuntu", "Fraunces",
|
||||
];
|
||||
const TEXT_COLORS = [
|
||||
"000000", "404040", "808080", "BFBFBF", "FFFFFF", "C00000", "FF0000", "FFC000",
|
||||
|
|
@ -61,6 +66,12 @@ let autosaveTimer = null;
|
|||
// add-on here and drops the file in Downloads.
|
||||
let savedTarget = null; // {name} — the path itself stays in the add-on
|
||||
|
||||
// How large the page is drawn. "fit" and "page" recompute as the window
|
||||
// changes; a number is a fixed multiplier. Kept per editor rather than per
|
||||
// document — it is a property of the screen you are looking at, not of the
|
||||
// file.
|
||||
let zoomMode = "fit";
|
||||
|
||||
// --- open documents -------------------------------------------------------
|
||||
//
|
||||
// The editor holds several documents at once, the way the browser holds
|
||||
|
|
@ -744,6 +755,9 @@ function wireRibbon() {
|
|||
$("file-saveas").onclick = () => saveAs();
|
||||
$("file-pdf").onclick = () => exportPdf();
|
||||
$("file-print").onclick = () => window.print();
|
||||
$("zoom").onchange = (e) => setZoom(e.target.value);
|
||||
$("zoom-in").onclick = () => stepZoom(1);
|
||||
$("zoom-out").onclick = () => stepZoom(-1);
|
||||
$("about").onclick = openAbout;
|
||||
$("discard").onclick = () => closeTab();
|
||||
$("open-folder").onclick = async () => {
|
||||
|
|
@ -769,6 +783,37 @@ function wireRibbon() {
|
|||
// lives in lib/doc-css.js rather than editor.css. Injecting it here (rather
|
||||
// than linking a second stylesheet) keeps the export and the screen reading
|
||||
// from one string.
|
||||
// The bundled webfonts, fetched from the add-on with the woff2 already
|
||||
// inlined as data URLs.
|
||||
//
|
||||
// A plain <link> to fonts.css does not work here: the page is on file://,
|
||||
// where Chromium registers the @font-face rules but refuses to fetch the
|
||||
// font files themselves — the family appears in document.fonts and every
|
||||
// glyph still comes out in the fallback face. Data URLs sidestep the fetch
|
||||
// entirely, and the add-on is the only side that can read the files.
|
||||
async function installFontCss() {
|
||||
try {
|
||||
const res = await window.silentmode?.invoke("fontCss", {});
|
||||
if (res && res.css) {
|
||||
const el = document.createElement("style");
|
||||
el.id = "bundled-fonts";
|
||||
el.textContent = res.css;
|
||||
document.head.append(el);
|
||||
await document.fonts.ready;
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("[docx-editor] bundled fonts unavailable:", e);
|
||||
}
|
||||
// Without them, a document that asks for Ubuntu or Fraunces still saves
|
||||
// correctly — Word will use its own copy — it just isn't drawn faithfully
|
||||
// here, so say so rather than letting the ribbon imply otherwise.
|
||||
for (const name of BUNDLED_FONTS) {
|
||||
const opt = [...$("font-family").options].find((o) => o.value === name);
|
||||
if (opt) opt.textContent = name + " (not available)";
|
||||
}
|
||||
}
|
||||
|
||||
function installDocCss() {
|
||||
const el = document.createElement("style");
|
||||
el.id = "doc-css";
|
||||
|
|
@ -785,6 +830,77 @@ function syncPageRule() {
|
|||
document.head.append(el);
|
||||
}
|
||||
el.textContent = DE().docCss.pageRule(docSetup);
|
||||
syncPageGeometry();
|
||||
applyZoom();
|
||||
}
|
||||
|
||||
// The sheet is drawn at the size the document claims, margins included, so
|
||||
// what is on screen is the page rather than a generic rectangle.
|
||||
function pageInches() {
|
||||
const page = (docSetup && docSetup.page) || {};
|
||||
const size = page.size || {};
|
||||
const m = page.margin || {};
|
||||
const inch = (twips, fallback) => {
|
||||
const n = Number(twips);
|
||||
return Number.isFinite(n) && n > 0 ? n / 1440 : fallback;
|
||||
};
|
||||
return {
|
||||
w: inch(size.width, 8.27), h: inch(size.height, 11.69),
|
||||
top: inch(m.top, 1), right: inch(m.right, 1),
|
||||
bottom: inch(m.bottom, 1), left: inch(m.left, 1),
|
||||
};
|
||||
}
|
||||
|
||||
function syncPageGeometry() {
|
||||
const p = pageInches();
|
||||
const root = document.documentElement.style;
|
||||
root.setProperty("--page-w", p.w + "in");
|
||||
root.setProperty("--page-h", p.h + "in");
|
||||
root.setProperty("--page-mt", p.top + "in");
|
||||
root.setProperty("--page-mr", p.right + "in");
|
||||
root.setProperty("--page-mb", p.bottom + "in");
|
||||
root.setProperty("--page-ml", p.left + "in");
|
||||
}
|
||||
|
||||
const ZOOM_MIN = 0.4, ZOOM_MAX = 4;
|
||||
|
||||
function applyZoom() {
|
||||
const board = $("board");
|
||||
if (!board) return;
|
||||
const p = pageInches();
|
||||
const style = getComputedStyle(board);
|
||||
const padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
|
||||
const availW = board.clientWidth - padding - 2;
|
||||
const availH = board.clientHeight - parseFloat(style.paddingTop) - 24;
|
||||
|
||||
let z;
|
||||
if (zoomMode === "fit") z = availW / (p.w * 96);
|
||||
else if (zoomMode === "page") z = Math.min(availW / (p.w * 96), availH / (p.h * 96));
|
||||
else z = parseFloat(zoomMode) || 1;
|
||||
|
||||
z = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, z));
|
||||
document.documentElement.style.setProperty("--zoom", String(z));
|
||||
const sel = $("zoom");
|
||||
if (sel && sel.value !== zoomMode) sel.value = zoomMode;
|
||||
return z;
|
||||
}
|
||||
|
||||
function setZoom(mode) {
|
||||
zoomMode = mode;
|
||||
applyZoom();
|
||||
try { window.silentmode?.storage?.set("zoom", mode); } catch {}
|
||||
if (view) view.focus();
|
||||
}
|
||||
|
||||
// Stepping from a fit mode starts at whatever that fit worked out to, so the
|
||||
// first click doesn't jump somewhere unrelated to what is on screen.
|
||||
function stepZoom(dir) {
|
||||
const steps = [0.5, 0.75, 1, 1.25, 1.5, 2, 3];
|
||||
const now = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--zoom")) || 1;
|
||||
const next = dir > 0
|
||||
? steps.find((v) => v > now + 0.01)
|
||||
: [...steps].reverse().find((v) => v < now - 0.01);
|
||||
if (next) setZoom(String(next));
|
||||
}
|
||||
|
||||
// The document as a standalone HTML page: ProseMirror's own DOM serialisation
|
||||
|
|
@ -829,6 +945,10 @@ function buildPlugins() {
|
|||
"Mod-Tab": () => { cycleDoc(1); return true; },
|
||||
"Shift-Mod-Tab": () => { cycleDoc(-1); return true; },
|
||||
"Mod-p": () => { window.print(); return true; },
|
||||
"Mod-=": () => { stepZoom(1); return true; },
|
||||
"Mod-+": () => { stepZoom(1); return true; },
|
||||
"Mod--": () => { stepZoom(-1); return true; },
|
||||
"Mod-0": () => { setZoom("fit"); return true; },
|
||||
"Mod-Enter": (state, dispatch) => {
|
||||
if (dispatch) dispatch(state.tr.replaceSelectionWith(schema.nodes.page_break.create()).scrollIntoView());
|
||||
return true;
|
||||
|
|
@ -1440,8 +1560,24 @@ async function boot() {
|
|||
}
|
||||
schema = DE().schema.build();
|
||||
installDocCss();
|
||||
try {
|
||||
const saved = await window.silentmode?.storage?.get("zoom", "fit");
|
||||
if (saved) zoomMode = String(saved);
|
||||
} catch {}
|
||||
syncPageRule();
|
||||
wireRibbon();
|
||||
// After wireRibbon, which is what fills the font menu this may have to
|
||||
// annotate.
|
||||
await installFontCss();
|
||||
|
||||
// A fit mode is a statement about the window, so it has to be recomputed
|
||||
// when the window changes.
|
||||
let resizeTimer = null;
|
||||
window.addEventListener("resize", () => {
|
||||
if (zoomMode !== "fit" && zoomMode !== "page") return;
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(applyZoom, 60);
|
||||
});
|
||||
|
||||
// Whole-window drop target, so dropping a file anywhere works and not
|
||||
// only over the page surface.
|
||||
|
|
|
|||
162
bundled-addons/docx-editor/fonts.css
Normal file
162
bundled-addons/docx-editor/fonts.css
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/* Bundled with the Word editor — see addon-build/docx-editor/fetch-fonts.mjs.
|
||||
Regenerate with `npm run fonts`; do not edit by hand. */
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-cyrillic-italic-400.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-greek-italic-400.woff2') format('woff2');
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-ext-italic-400.woff2') format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-italic-400.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-cyrillic-italic-700.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-greek-italic-700.woff2') format('woff2');
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-ext-italic-700.woff2') format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-italic-700.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-cyrillic-normal-400.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-greek-normal-400.woff2') format('woff2');
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-ext-normal-400.woff2') format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-normal-400.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-cyrillic-normal-700.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-greek-normal-700.woff2') format('woff2');
|
||||
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-ext-normal-700.woff2') format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Ubuntu';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: block;
|
||||
src: url('fonts/ubuntu-latin-normal-700.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fraunces';
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-display: block;
|
||||
src: url('fonts/fraunces-latin-ext-italic-100_900.woff2') format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fraunces';
|
||||
font-style: italic;
|
||||
font-weight: 100 900;
|
||||
font-display: block;
|
||||
src: url('fonts/fraunces-latin-italic-100_900.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fraunces';
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: block;
|
||||
src: url('fonts/fraunces-latin-ext-normal-100_900.woff2') format('woff2');
|
||||
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Fraunces';
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: block;
|
||||
src: url('fonts/fraunces-latin-normal-100_900.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
211
bundled-addons/docx-editor/fonts/LICENSES.txt
Normal file
211
bundled-addons/docx-editor/fonts/LICENSES.txt
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
Fonts bundled with the Theseus Word editor
|
||||
==========================================
|
||||
|
||||
Both families are redistributable and are shipped unmodified, as woff2
|
||||
subsets built by Google Fonts. Regenerate with:
|
||||
|
||||
cd TheseusNavigator/addon-build/docx-editor && npm run fonts
|
||||
|
||||
They are bundled rather than fetched at runtime: an extension in a browser
|
||||
built around not phoning home should not ask a font CDN what a document
|
||||
looks like every time one is opened.
|
||||
|
||||
--- Ubuntu — Ubuntu Font Licence 1.0 ---
|
||||
Copyright 2010-2011 Canonical Ltd.
|
||||
https://fonts.google.com/specimen/Ubuntu/license
|
||||
|
||||
-------------------------------
|
||||
UBUNTU FONT LICENCE Version 1.0
|
||||
-------------------------------
|
||||
|
||||
PREAMBLE
|
||||
This licence allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely. The fonts, including any derivative works, can be
|
||||
bundled, embedded, and redistributed provided the terms of this licence
|
||||
are met. The fonts and derivatives, however, cannot be released under
|
||||
any other licence. The requirement for fonts to remain under this
|
||||
licence does not require any document created using the fonts or their
|
||||
derivatives to be published under this licence, as long as the primary
|
||||
purpose of the document is not to be a vehicle for the distribution of
|
||||
the fonts.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this licence and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Original Version" refers to the collection of Font Software components
|
||||
as received under this licence.
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to
|
||||
a new environment.
|
||||
|
||||
"Copyright Holder(s)" refers to all individuals and companies who have a
|
||||
copyright ownership of the Font Software.
|
||||
|
||||
"Substantially Changed" refers to Modified Versions which can be easily
|
||||
identified as dissimilar to the Font Software by users of the Font
|
||||
Software comparing the Original Version with the Modified Version.
|
||||
|
||||
To "Propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification and with or without charging
|
||||
a redistribution fee), making available to the public, and in some
|
||||
countries other activities as well.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
This licence does not grant any rights under trademark law and all such
|
||||
rights are reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of the Font Software, to propagate the Font Software, subject to
|
||||
the below conditions:
|
||||
|
||||
1) Each copy of the Font Software must contain the above copyright
|
||||
notice and this licence. These can be included either as stand-alone
|
||||
text files, human-readable headers or in the appropriate machine-
|
||||
readable metadata fields within text or binary files as long as those
|
||||
fields can be easily viewed by the user.
|
||||
|
||||
2) The font name complies with the following:
|
||||
(a) The Original Version must retain its name, unmodified.
|
||||
(b) Modified Versions which are Substantially Changed must be renamed to
|
||||
avoid use of the name of the Original Version or similar names entirely.
|
||||
(c) Modified Versions which are not Substantially Changed must be
|
||||
renamed to both (i) retain the name of the Original Version and (ii) add
|
||||
additional naming elements to distinguish the Modified Version from the
|
||||
Original Version. The name of such Modified Versions must be the name of
|
||||
the Original Version, with "derivative X" where X represents the name of
|
||||
the new work, appended to that name.
|
||||
|
||||
3) The name(s) of the Copyright Holder(s) and any contributor to the
|
||||
Font Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except (i) as required by this licence, (ii) to
|
||||
acknowledge the contribution(s) of the Copyright Holder(s) or (iii) with
|
||||
their explicit written permission.
|
||||
|
||||
4) The Font Software, modified or unmodified, in part or in whole, must
|
||||
be distributed entirely under this licence, and must not be distributed
|
||||
under any other licence. The requirement for fonts to remain under this
|
||||
licence does not affect any document created using the Font Software,
|
||||
except any version of the Font Software extracted from a document
|
||||
created using the Font Software may only be distributed under this
|
||||
licence.
|
||||
|
||||
TERMINATION
|
||||
This licence becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
||||
COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER
|
||||
DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
|
||||
--- Fraunces — SIL Open Font License 1.1 ---
|
||||
Copyright 2019 The Fraunces Project Authors (https://github.com/undercasetype/Fraunces)
|
||||
https://fonts.google.com/specimen/Fraunces/license
|
||||
|
||||
Copyright 2018 The Fraunces Project Authors (https://github.com/undercasetype/Fraunces)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-italic-400.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-italic-400.woff2
Normal file
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-italic-700.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-italic-700.woff2
Normal file
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-normal-400.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-normal-400.woff2
Normal file
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-normal-700.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-greek-normal-700.woff2
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-italic-400.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-italic-400.woff2
Normal file
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-italic-700.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-italic-700.woff2
Normal file
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-normal-400.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-normal-400.woff2
Normal file
Binary file not shown.
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-normal-700.woff2
Normal file
BIN
bundled-addons/docx-editor/fonts/ubuntu-latin-normal-700.woff2
Normal file
Binary file not shown.
|
|
@ -311,11 +311,38 @@ module.exports = {
|
|||
//
|
||||
// A temp file rather than a data: URL: a document with a few photographs
|
||||
// in it runs to megabytes, and long data: URLs get truncated.
|
||||
// The bundled webfonts, as @font-face rules with the woff2 inlined.
|
||||
// The print page is loaded from a temp folder, so a relative url() would
|
||||
// resolve to nothing there — and a PDF whose text falls back to a
|
||||
// different typeface is exactly the drift the shared stylesheet was
|
||||
// meant to prevent. Read once, kept for the session.
|
||||
let inlinedFontCss = null;
|
||||
function fontCss() {
|
||||
if (inlinedFontCss !== null) return inlinedFontCss;
|
||||
try {
|
||||
const css = fs.readFileSync(path.join(api.folder, "fonts.css"), "utf8");
|
||||
inlinedFontCss = css.replace(/url\('fonts\/([^']+)'\)/g, (whole, file) => {
|
||||
try {
|
||||
const b64 = fs.readFileSync(path.join(api.folder, "fonts", file)).toString("base64");
|
||||
return `url('data:font/woff2;base64,${b64}')`;
|
||||
} catch { return whole; }
|
||||
});
|
||||
} catch (e) {
|
||||
api.log("no bundled fonts to inline:", e?.message);
|
||||
inlinedFontCss = "";
|
||||
}
|
||||
return inlinedFontCss;
|
||||
}
|
||||
|
||||
api.onMessage("fontCss", () => ({ css: fontCss() }));
|
||||
|
||||
api.onMessage("renderPdf", async (payload) => {
|
||||
const { BrowserWindow } = api.require("electron");
|
||||
const p = payload || {};
|
||||
const html = String(p.html || "");
|
||||
let html = String(p.html || "");
|
||||
if (!html) throw new Error("no document to render");
|
||||
const fonts = fontCss();
|
||||
if (fonts) html = html.replace("</head>", `<style>${fonts}</style></head>`);
|
||||
|
||||
const tmp = path.join(scratchDir, `print-${Date.now()}.html`);
|
||||
fs.writeFileSync(tmp, html, "utf8");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue