mirror of
https://github.com/shrekbytes/advanced-pdf-export.git
synced 2026-07-22 07:25:03 +00:00
fix: obsidian bot screaming
This commit is contained in:
parent
156677f32d
commit
b338b9074c
7 changed files with 373 additions and 297 deletions
|
|
@ -13,10 +13,6 @@ const external = [
|
|||
"@codemirror/language",
|
||||
"@codemirror/search",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/highlight",
|
||||
"@codemirror/history",
|
||||
"@codemirror/fold",
|
||||
"@codemirror/stream-parser",
|
||||
"@lezer/common",
|
||||
"@lezer/lr",
|
||||
...builtinModules,
|
||||
|
|
@ -28,7 +24,7 @@ const ctx = await esbuild.context({
|
|||
outfile: "main.js",
|
||||
external,
|
||||
format: "cjs",
|
||||
target: "es2018",
|
||||
target: "es2022",
|
||||
platform: "browser",
|
||||
sourcemap: isProduction ? false : "inline",
|
||||
minify: isProduction,
|
||||
|
|
|
|||
82
main.js
82
main.js
File diff suppressed because one or more lines are too long
238
main.ts
238
main.ts
|
|
@ -316,16 +316,16 @@ function splitMarkdownSections(md: string): string[] {
|
|||
.filter(Boolean);
|
||||
}
|
||||
|
||||
async function renderMarkdownToHtml(
|
||||
async function renderMarkdownToEl(
|
||||
app: App,
|
||||
markdown: string,
|
||||
sourcePath: string,
|
||||
component: Component,
|
||||
): Promise<string> {
|
||||
const temp = document.createElement("div");
|
||||
): Promise<HTMLElement> {
|
||||
const temp = activeDocument.createElement("div");
|
||||
await MarkdownRenderer.render(app, markdown, temp, sourcePath, component);
|
||||
postProcessRenderedHTML(temp);
|
||||
return temp.innerHTML;
|
||||
return temp;
|
||||
}
|
||||
|
||||
function slugifyHeading(text: string): string {
|
||||
|
|
@ -583,7 +583,7 @@ const UNSPLITTABLE_TAGS = new Set([
|
|||
const HEIGHT_EPS = 2; // px
|
||||
|
||||
function measureNodesHeight(nodes: HTMLElement[], measureEl: HTMLElement): number {
|
||||
measureEl.innerHTML = "";
|
||||
measureEl.empty();
|
||||
for (const node of nodes) measureEl.appendChild(node.cloneNode(true));
|
||||
return measureEl.getBoundingClientRect().height;
|
||||
}
|
||||
|
|
@ -600,7 +600,7 @@ function makeFitFn(
|
|||
// ── Inline (text) splitter ───────────────────────────────────────────────────
|
||||
|
||||
function trimLeadingWhitespace(el: HTMLElement): void {
|
||||
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
||||
const walker = activeDocument.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
||||
while (walker.nextNode()) {
|
||||
const node = walker.currentNode as Text;
|
||||
const trimmed = (node.textContent ?? "").replace(/^\s+/, "");
|
||||
|
|
@ -613,7 +613,7 @@ function buildInlineSplitAt(
|
|||
el: HTMLElement,
|
||||
splitOffset: number,
|
||||
): [HTMLElement, HTMLElement] | null {
|
||||
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
||||
const walker = activeDocument.createTreeWalker(el, NodeFilter.SHOW_TEXT);
|
||||
let count = 0;
|
||||
let target: Text | null = null;
|
||||
let localOffset = 0;
|
||||
|
|
@ -631,11 +631,11 @@ function buildInlineSplitAt(
|
|||
|
||||
if (!target) return null;
|
||||
|
||||
const range1 = document.createRange();
|
||||
const range1 = activeDocument.createRange();
|
||||
range1.selectNodeContents(el);
|
||||
range1.setEnd(target, localOffset);
|
||||
|
||||
const range2 = document.createRange();
|
||||
const range2 = activeDocument.createRange();
|
||||
range2.selectNodeContents(el);
|
||||
range2.setStart(target, localOffset);
|
||||
|
||||
|
|
@ -750,7 +750,7 @@ function buildTableWithRows(tableEl: HTMLTableElement, rows: HTMLTableRowElement
|
|||
const colgroup = tableEl.querySelector("colgroup");
|
||||
if (colgroup) clone.appendChild(colgroup.cloneNode(true));
|
||||
if (tableEl.tHead) clone.appendChild(tableEl.tHead.cloneNode(true));
|
||||
const tbody = document.createElement("tbody");
|
||||
const tbody = activeDocument.createElement("tbody");
|
||||
for (const row of rows) tbody.appendChild(row.cloneNode(true));
|
||||
clone.appendChild(tbody);
|
||||
return clone;
|
||||
|
|
@ -856,40 +856,42 @@ function splitElement(
|
|||
|
||||
// ── Main pagination loop ─────────────────────────────────────────────────────
|
||||
|
||||
function paginateHTML(
|
||||
html: string,
|
||||
function paginateEl(
|
||||
sourceEl: HTMLElement,
|
||||
contentWidthPx: number,
|
||||
contentHeightPx: number,
|
||||
docCSS: string,
|
||||
): HTMLElement[][] {
|
||||
// Fixed-position sandbox: out of any scroll container, never affects layout.
|
||||
const sandbox = document.createElement("div");
|
||||
sandbox.style.cssText = [
|
||||
// Fixed-position sandbox inside a shadow root so the measurement CSS is
|
||||
// fully scoped and never pollutes the main document. Using adoptedStyleSheets
|
||||
// avoids creating a <style> element.
|
||||
const sandboxHost = activeDocument.createElement("div");
|
||||
sandboxHost.style.cssText = [
|
||||
"position:fixed", "top:0", "left:-99999px",
|
||||
`width:${contentWidthPx}px`,
|
||||
"visibility:hidden", "pointer-events:none", "z-index:-1",
|
||||
].join(";");
|
||||
|
||||
// Inject doc CSS via adoptedStyleSheets to avoid creating a <style> element.
|
||||
const docSheet = new CSSStyleSheet();
|
||||
docSheet.replaceSync(docCSS);
|
||||
const prevSheets = [...document.adoptedStyleSheets];
|
||||
document.adoptedStyleSheets = [...prevSheets, docSheet];
|
||||
const sandboxShadow = sandboxHost.attachShadow({ mode: "open" });
|
||||
|
||||
const inner = document.createElement("div");
|
||||
const sandboxSheet = new CSSStyleSheet();
|
||||
sandboxSheet.replaceSync(docCSS);
|
||||
sandboxShadow.adoptedStyleSheets = [sandboxSheet];
|
||||
|
||||
const inner = activeDocument.createElement("div");
|
||||
inner.className = "mpdf-doc";
|
||||
// Use DOMParser to safely parse the rendered HTML instead of innerHTML.
|
||||
const parsed = new DOMParser().parseFromString(html, "text/html");
|
||||
Array.from(parsed.body.childNodes).forEach((n) => inner.appendChild(document.importNode(n, true)));
|
||||
sandbox.appendChild(inner);
|
||||
for (const child of Array.from(sourceEl.children)) {
|
||||
inner.appendChild(child.cloneNode(true));
|
||||
}
|
||||
sandboxShadow.appendChild(inner);
|
||||
|
||||
// Measurement div: same width, always empty before each measurement.
|
||||
const measure = document.createElement("div");
|
||||
const measure = activeDocument.createElement("div");
|
||||
measure.className = "mpdf-doc";
|
||||
measure.style.cssText = `position:absolute;top:0;left:0;width:${contentWidthPx}px;visibility:hidden;`;
|
||||
sandbox.appendChild(measure);
|
||||
sandboxShadow.appendChild(measure);
|
||||
|
||||
document.body.appendChild(sandbox);
|
||||
activeDocument.body.appendChild(sandboxHost);
|
||||
|
||||
const pages: HTMLElement[][] = [];
|
||||
try {
|
||||
|
|
@ -942,8 +944,7 @@ function paginateHTML(
|
|||
|
||||
if (currentPage.length > 0) pages.push(currentPage);
|
||||
} finally {
|
||||
document.body.removeChild(sandbox);
|
||||
document.adoptedStyleSheets = prevSheets;
|
||||
activeDocument.body.removeChild(sandboxHost);
|
||||
}
|
||||
return pages.length > 0 ? pages : [[]];
|
||||
}
|
||||
|
|
@ -1001,13 +1002,13 @@ function buildPageLayouts(allPages: HTMLElement[][], s: PDFExportSettings): Page
|
|||
// ─── Plugin ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export default class MarkdownPDFPlugin extends Plugin {
|
||||
settings: PDFExportSettings;
|
||||
declare settings: PDFExportSettings;
|
||||
activeModal: PDFExportModal | null = null;
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
this.addCommand({
|
||||
id: "open-advanced-pdf-export",
|
||||
id: "open-panel",
|
||||
name: "Open Panel",
|
||||
callback: () => this.openModal(),
|
||||
});
|
||||
|
|
@ -1033,7 +1034,7 @@ export default class MarkdownPDFPlugin extends Plugin {
|
|||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData() as Partial<PDFExportSettings>);
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
|
|
@ -1221,12 +1222,11 @@ class PDFExportModal extends Modal {
|
|||
zoomSlider.step = "0.05";
|
||||
zoomSlider.value = String(s.previewScale);
|
||||
zoomSlider.addClass("mpdf-zoom-slider");
|
||||
zoomSlider.addEventListener("input", async () => {
|
||||
zoomSlider.addEventListener("input", () => {
|
||||
const v = parseFloat(zoomSlider.value);
|
||||
this.plugin.settings.previewScale = v;
|
||||
zoomLabel.textContent = Math.round(v * 100) + "%";
|
||||
await this.plugin.saveSettings();
|
||||
this.renderPreviewOnly();
|
||||
void this.plugin.saveSettings().then(() => { this.renderPreviewOnly(); });
|
||||
});
|
||||
|
||||
const breakBtn = left.createEl("button", { cls: "mpdf-btn", text: "Insert Page Break" });
|
||||
|
|
@ -1366,15 +1366,15 @@ class PDFExportModal extends Modal {
|
|||
const docCSS = buildDocCSS(s, isRTL);
|
||||
const sourcePath = this.currentFile?.path ?? "pdf-export";
|
||||
|
||||
const sectionHtml = await Promise.all(
|
||||
sections.map((sec) => renderMarkdownToHtml(this.app, sec.trim(), sourcePath, this.renderComponent)),
|
||||
const sectionEls = await Promise.all(
|
||||
sections.map((sec) => renderMarkdownToEl(this.app, sec.trim(), sourcePath, this.renderComponent)),
|
||||
);
|
||||
|
||||
if (token !== this.renderToken) return;
|
||||
|
||||
const allPages: HTMLElement[][] = [];
|
||||
for (const html of sectionHtml) {
|
||||
allPages.push(...paginateHTML(html, contentW, contentH, docCSS));
|
||||
for (const sectionEl of sectionEls) {
|
||||
allPages.push(...paginateEl(sectionEl, contentW, contentH, docCSS));
|
||||
}
|
||||
|
||||
const layouts = buildPageLayouts(allPages, s);
|
||||
|
|
@ -1392,13 +1392,13 @@ class PDFExportModal extends Modal {
|
|||
}
|
||||
|
||||
private showLoading() {
|
||||
this.loadingOverlayEl.addClass("mpdf-loading-overlay--visible");
|
||||
this.loadingOverlayEl.addClass("is-active");
|
||||
this.renderBtn.disabled = true;
|
||||
this.renderBtn.textContent = "Rendering…";
|
||||
}
|
||||
|
||||
private hideLoading() {
|
||||
this.loadingOverlayEl.removeClass("mpdf-loading-overlay--visible");
|
||||
this.loadingOverlayEl.removeClass("is-active");
|
||||
this.renderBtn.disabled = false;
|
||||
this.renderBtn.textContent = "⟳ Render PDF";
|
||||
}
|
||||
|
|
@ -1427,28 +1427,25 @@ class PDFExportModal extends Modal {
|
|||
const scaledH = Math.round(ph * scale);
|
||||
|
||||
const wrap = this.previewEl.createEl("div", { cls: "mpdf-page-wrap" });
|
||||
wrap.style.cssText = `width:${scaledW}px;height:${scaledH}px;position:relative;flex-shrink:0;`;
|
||||
wrap.style.cssText = `width:${scaledW}px;height:${scaledH}px;`;
|
||||
wrap.createEl("div", { cls: "mpdf-page-label", text: `Page ${layout.pageNum} of ${layout.totalPages}` });
|
||||
pageWraps.push(wrap);
|
||||
|
||||
const scaleWrap = wrap.createEl("div", { cls: "mpdf-page-scale" });
|
||||
scaleWrap.style.cssText = `width:${scaledW}px;height:${scaledH}px;overflow:hidden;position:relative;`;
|
||||
scaleWrap.style.cssText = `width:${scaledW}px;height:${scaledH}px;`;
|
||||
|
||||
// Each page renders inside a shadow root so Obsidian's theme CSS cannot
|
||||
// reach the page content across the shadow boundary.
|
||||
const shadowHost = document.createElement("div");
|
||||
shadowHost.style.cssText = [
|
||||
`width:${pw}px`, `height:${ph}px`,
|
||||
`transform:scale(${scale})`, "transform-origin:top left",
|
||||
"position:absolute", "top:0", "left:0",
|
||||
].join(";");
|
||||
const shadowHost = activeDocument.createElement("div");
|
||||
shadowHost.addClass("mpdf-shadow-host");
|
||||
shadowHost.style.cssText = `width:${pw}px;height:${ph}px;transform:scale(${scale});`;
|
||||
scaleWrap.appendChild(shadowHost);
|
||||
|
||||
const shadow = shadowHost.attachShadow({ mode: "open" });
|
||||
|
||||
// Inject shadow CSS via adoptedStyleSheets to avoid creating a <style> element.
|
||||
// Classes mpdf-hf-center / mpdf-hf-end are used by header and footer spans.
|
||||
const shadowCSSText = `
|
||||
// Use adoptedStyleSheets instead of a <style> element — avoids the
|
||||
// no-create-style-element lint rule and keeps shadow CSS fully scoped.
|
||||
const shadowCSS = `
|
||||
:host {
|
||||
display: block;
|
||||
width: ${pw}px;
|
||||
|
|
@ -1461,33 +1458,33 @@ class PDFExportModal extends Modal {
|
|||
}
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
.mpdf-hf-center { flex: 1; text-align: center; }
|
||||
.mpdf-hf-end { margin-left: auto; }
|
||||
.mpdf-hf-right { margin-left: auto; }
|
||||
${docCSS}
|
||||
`;
|
||||
const shadowSheet = new CSSStyleSheet();
|
||||
shadowSheet.replaceSync(shadowCSSText);
|
||||
shadow.adoptedStyleSheets = [shadowSheet];
|
||||
const pageSheet = new CSSStyleSheet();
|
||||
pageSheet.replaceSync(shadowCSS);
|
||||
shadow.adoptedStyleSheets = [pageSheet];
|
||||
|
||||
// ── Header ───────────────────────────────────────────────────────────────
|
||||
const hasHeader = s.showHeader && (layout.headerLeft || layout.headerCenter || layout.headerRight);
|
||||
if (hasHeader) {
|
||||
const hdr = document.createElement("div");
|
||||
const hdr = activeDocument.createElement("div");
|
||||
hdr.style.cssText = [
|
||||
"position:absolute", `top:${mTop * 0.4}px`, `left:${mLeft}px`, `right:${mLeft}px`,
|
||||
"display:flex", "align-items:center",
|
||||
"font-size:9px", "color:#999", `font-family:${fontFamily}`, "white-space:nowrap",
|
||||
].join(";");
|
||||
if (layout.headerCenter) {
|
||||
const span = document.createElement("span");
|
||||
const span = activeDocument.createElement("span");
|
||||
span.className = "mpdf-hf-center";
|
||||
span.textContent = layout.headerCenter;
|
||||
hdr.appendChild(span);
|
||||
} else {
|
||||
const leftSpan = document.createElement("span");
|
||||
const leftSpan = activeDocument.createElement("span");
|
||||
leftSpan.textContent = layout.headerLeft;
|
||||
hdr.appendChild(leftSpan);
|
||||
const rightSpan = document.createElement("span");
|
||||
rightSpan.className = "mpdf-hf-end";
|
||||
const rightSpan = activeDocument.createElement("span");
|
||||
rightSpan.className = "mpdf-hf-right";
|
||||
rightSpan.textContent = layout.headerRight;
|
||||
hdr.appendChild(rightSpan);
|
||||
}
|
||||
|
|
@ -1495,7 +1492,7 @@ class PDFExportModal extends Modal {
|
|||
}
|
||||
|
||||
// ── Content ──────────────────────────────────────────────────────────────
|
||||
const contentDiv = document.createElement("div");
|
||||
const contentDiv = activeDocument.createElement("div");
|
||||
contentDiv.className = "mpdf-doc";
|
||||
if (isRTL) contentDiv.setAttribute("dir", "rtl");
|
||||
// No height/overflow:hidden — the :host clips at the page boundary.
|
||||
|
|
@ -1526,7 +1523,7 @@ class PDFExportModal extends Modal {
|
|||
// Skip empty footer divs (e.g. page 1 when showHeaderFooterOnFirstPage is off).
|
||||
const hasFooter = s.showFooter && (layout.footerLeft || layout.footerRight || layout.footerCenter);
|
||||
if (hasFooter) {
|
||||
const footer = document.createElement("div");
|
||||
const footer = activeDocument.createElement("div");
|
||||
footer.style.cssText = [
|
||||
"position:absolute", "bottom:0", "left:0", "right:0",
|
||||
`height:${footerH}px`, "display:flex", "align-items:center",
|
||||
|
|
@ -1535,16 +1532,16 @@ class PDFExportModal extends Modal {
|
|||
].filter(Boolean).join(";");
|
||||
|
||||
if (layout.footerCenter) {
|
||||
const span = document.createElement("span");
|
||||
const span = activeDocument.createElement("span");
|
||||
span.className = "mpdf-hf-center";
|
||||
span.textContent = layout.footerCenter;
|
||||
footer.appendChild(span);
|
||||
} else {
|
||||
const left = document.createElement("span");
|
||||
const left = activeDocument.createElement("span");
|
||||
left.textContent = layout.footerLeft;
|
||||
footer.appendChild(left);
|
||||
const right = document.createElement("span");
|
||||
right.className = "mpdf-hf-end";
|
||||
const right = activeDocument.createElement("span");
|
||||
right.className = "mpdf-hf-right";
|
||||
right.textContent = layout.footerRight;
|
||||
footer.appendChild(right);
|
||||
}
|
||||
|
|
@ -1779,21 +1776,17 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
.setDesc("Pick a preset to configure the overall document style. Fine-tune any setting below.")
|
||||
.addDropdown((d) => {
|
||||
Object.entries(PRESETS).forEach(([k, v]) => d.addOption(k, v.name));
|
||||
d.setValue(s.preset).onChange(async (v) => {
|
||||
d.setValue(s.preset).onChange((v) => {
|
||||
this.plugin.applyPreset(v);
|
||||
await this.markDirty();
|
||||
// Refresh the form so all controls show the new preset's values,
|
||||
// but do NOT call display() — that would reset the dirty flag.
|
||||
this.buildSettings();
|
||||
void this.markDirty().then(() => { this.buildSettings(); });
|
||||
});
|
||||
})
|
||||
.addButton((b) =>
|
||||
b.setButtonText("Reset Preset")
|
||||
.setTooltip("Reset current preset to its default values")
|
||||
.onClick(async () => {
|
||||
.onClick(() => {
|
||||
this.plugin.applyPreset(s.preset);
|
||||
await this.markDirty();
|
||||
this.buildSettings();
|
||||
void this.markDirty().then(() => { this.buildSettings(); });
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
@ -1801,27 +1794,28 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
new Setting(containerEl).setName("Page").setHeading();
|
||||
new Setting(containerEl).setName("Page size").addDropdown((d) => {
|
||||
Object.keys(PAGE_SIZES).forEach((k) => d.addOption(k, k));
|
||||
d.setValue(s.pageSize).onChange(async (v) => {
|
||||
d.setValue(s.pageSize).onChange((v) => {
|
||||
s.pageSize = v;
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl).setName("Orientation").addDropdown((d) =>
|
||||
d.addOptions({ portrait: "Portrait", landscape: "Landscape" })
|
||||
.setValue(s.orientation)
|
||||
.onChange(async (v) => {
|
||||
.onChange((v) => {
|
||||
s.orientation = v as "portrait" | "landscape";
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
|
||||
// ── Margins ───────────────────────────────────────────────────────────────
|
||||
new Setting(containerEl).setName("Margins (mm)").setHeading();
|
||||
const marginSetting = (name: string, key: keyof PDFExportSettings) =>
|
||||
type MarginKey = "marginTop" | "marginBottom" | "marginLeft" | "marginRight";
|
||||
const marginSetting = (name: string, key: MarginKey) =>
|
||||
new Setting(containerEl).setName(name).addText((t) =>
|
||||
t.setValue(String(s[key])).onChange(async (v) => {
|
||||
Object.assign(s, { [key]: parseInt(v) || 0 });
|
||||
await this.markDirty();
|
||||
t.setValue(String(s[key])).onChange((v) => {
|
||||
s[key] = parseInt(v) || 0;
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
marginSetting("Top", "marginTop");
|
||||
|
|
@ -1843,10 +1837,10 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
"'Courier New', monospace": "Courier New",
|
||||
"__custom__": "Custom…",
|
||||
}).setValue(s.fontFamily)
|
||||
.onChange(async (v) => {
|
||||
.onChange((v) => {
|
||||
s.fontFamily = v;
|
||||
customFontSetting.settingEl.style.display = v === "__custom__" ? "" : "none";
|
||||
await this.markDirty();
|
||||
customFontSetting.settingEl.toggleClass("is-hidden", v !== "__custom__");
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
customFontSetting = new Setting(containerEl)
|
||||
|
|
@ -1855,30 +1849,30 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
.addText((t) =>
|
||||
t.setPlaceholder("e.g. Inter, sans-serif")
|
||||
.setValue(s.customFontName)
|
||||
.onChange(async (v) => { s.customFontName = v; await this.markDirty(); }),
|
||||
.onChange((v) => { s.customFontName = v; void this.markDirty(); }),
|
||||
);
|
||||
customFontSetting.settingEl.style.display = s.fontFamily === "__custom__" ? "" : "none";
|
||||
customFontSetting.settingEl.toggleClass("is-hidden", s.fontFamily !== "__custom__");
|
||||
new Setting(containerEl).setName("Font size (px)").addDropdown((d) => {
|
||||
["10","11","12","13","14","15","16"].forEach((v) => d.addOption(v, v + "px"));
|
||||
d.setValue(String(s.fontSize)).onChange(async (v) => {
|
||||
d.setValue(String(s.fontSize)).onChange((v) => {
|
||||
s.fontSize = parseInt(v);
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
});
|
||||
});
|
||||
new Setting(containerEl).setName("Code font size").addDropdown((d) =>
|
||||
d.addOptions({ "0.75": "0.75em", "0.80": "0.80em", "0.82": "0.82em", "0.85": "0.85em", "0.88": "0.88em", "0.90": "0.90em", "1.0": "1.00em" })
|
||||
.setValue(String(s.codeFontSize))
|
||||
.onChange(async (v) => { s.codeFontSize = parseFloat(v); await this.markDirty(); }),
|
||||
.onChange((v) => { s.codeFontSize = parseFloat(v); void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Line height").addDropdown((d) =>
|
||||
d.addOptions({ "1.4": "Tight (1.4)", "1.6": "Compact (1.6)", "1.75": "Normal (1.75)", "1.85": "Relaxed (1.85)", "2.0": "Double (2.0)" })
|
||||
.setValue(String(s.lineHeight))
|
||||
.onChange(async (v) => { s.lineHeight = parseFloat(v); await this.markDirty(); }),
|
||||
.onChange((v) => { s.lineHeight = parseFloat(v); void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Paragraph spacing").addDropdown((d) =>
|
||||
d.addOptions({ "0": "None", "0.3": "Tight (0.3em)", "0.5": "Normal (0.5em)", "0.65": "Relaxed (0.65em)", "1.0": "Wide (1em)" })
|
||||
.setValue(String(s.paragraphSpacing))
|
||||
.onChange(async (v) => { s.paragraphSpacing = parseFloat(v); await this.markDirty(); }),
|
||||
.onChange((v) => { s.paragraphSpacing = parseFloat(v); void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
.setName("Heading scale")
|
||||
|
|
@ -1886,16 +1880,18 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
.addDropdown((d) =>
|
||||
d.addOptions({ "0.8": "Small (0.8×)", "0.88": "0.88×", "0.9": "Compact (0.9×)", "0.95": "0.95×", "1.0": "Normal (1.0×)", "1.05": "1.05×", "1.1": "Large (1.1×)", "1.2": "XLarge (1.2×)" })
|
||||
.setValue(String(s.headingScale))
|
||||
.onChange(async (v) => { s.headingScale = parseFloat(v); await this.markDirty(); }),
|
||||
.onChange((v) => { s.headingScale = parseFloat(v); void this.markDirty(); }),
|
||||
);
|
||||
|
||||
// ── Colors ────────────────────────────────────────────────────────────────
|
||||
new Setting(containerEl).setName("Colors").setHeading();
|
||||
const colorSetting = (name: string, key: keyof PDFExportSettings) =>
|
||||
type ColorKey = "accentColor" | "bodyColor" | "headingColor" | "pageBackground"
|
||||
| "blockquoteBg" | "blockquoteBorderColor" | "tableHeaderBg" | "codeBackground";
|
||||
const colorSetting = (name: string, key: ColorKey) =>
|
||||
new Setting(containerEl).setName(name).addColorPicker((cp) =>
|
||||
cp.setValue(String(s[key])).onChange(async (v) => {
|
||||
Object.assign(s, { [key]: v });
|
||||
await this.markDirty();
|
||||
cp.setValue(s[key]).onChange((v) => {
|
||||
s[key] = v;
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
colorSetting("Accent color", "accentColor");
|
||||
|
|
@ -1910,70 +1906,70 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
// ── Heading style ─────────────────────────────────────────────────────────
|
||||
new Setting(containerEl).setName("Heading Style").setHeading();
|
||||
new Setting(containerEl).setName("H1 bottom border").addToggle((t) =>
|
||||
t.setValue(s.h1BorderBottom).onChange(async (v) => { s.h1BorderBottom = v; await this.markDirty(); }),
|
||||
t.setValue(s.h1BorderBottom).onChange((v) => { s.h1BorderBottom = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("H2 bottom border").addToggle((t) =>
|
||||
t.setValue(s.h2BorderBottom).onChange(async (v) => { s.h2BorderBottom = v; await this.markDirty(); }),
|
||||
t.setValue(s.h2BorderBottom).onChange((v) => { s.h2BorderBottom = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Center H1").addToggle((t) =>
|
||||
t.setValue(s.centerH1).onChange(async (v) => { s.centerH1 = v; await this.markDirty(); }),
|
||||
t.setValue(s.centerH1).onChange((v) => { s.centerH1 = v; void this.markDirty(); }),
|
||||
);
|
||||
|
||||
// ── Tables ────────────────────────────────────────────────────────────────
|
||||
new Setting(containerEl).setName("Tables").setHeading();
|
||||
new Setting(containerEl).setName("Striped rows").addToggle((t) =>
|
||||
t.setValue(s.tableStriped).onChange(async (v) => { s.tableStriped = v; await this.markDirty(); }),
|
||||
t.setValue(s.tableStriped).onChange((v) => { s.tableStriped = v; void this.markDirty(); }),
|
||||
);
|
||||
|
||||
// ── Header & Footer ───────────────────────────────────────────────────────
|
||||
new Setting(containerEl).setName("Header & Footer").setHeading();
|
||||
new Setting(containerEl).setName("Show header").addToggle((t) =>
|
||||
t.setValue(s.showHeader).onChange(async (v) => { s.showHeader = v; await this.markDirty(); }),
|
||||
t.setValue(s.showHeader).onChange((v) => { s.showHeader = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
.setName("Header text")
|
||||
.setDesc("Appears on every page according to the chosen alignment.")
|
||||
.addText((t) => t.setValue(s.headerText).onChange(async (v) => { s.headerText = v; await this.markDirty(); }));
|
||||
.addText((t) => t.setValue(s.headerText).onChange((v) => { s.headerText = v; void this.markDirty(); }));
|
||||
new Setting(containerEl).setName("Header alignment").addDropdown((d) =>
|
||||
d.addOptions({ left: "Left", center: "Center", right: "Right" })
|
||||
.setValue(s.headerAlignment)
|
||||
.onChange(async (v) => { s.headerAlignment = v as "left"|"center"|"right"; await this.markDirty(); }),
|
||||
.onChange((v) => { s.headerAlignment = v as "left"|"center"|"right"; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Show footer").addToggle((t) =>
|
||||
t.setValue(s.showFooter).onChange(async (v) => { s.showFooter = v; await this.markDirty(); }),
|
||||
t.setValue(s.showFooter).onChange((v) => { s.showFooter = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Footer border").setDesc("Show the separator line above the footer.").addToggle((t) =>
|
||||
t.setValue(s.showFooterBorder).onChange(async (v) => { s.showFooterBorder = v; await this.markDirty(); }),
|
||||
t.setValue(s.showFooterBorder).onChange((v) => { s.showFooterBorder = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
.setName("Footer text")
|
||||
.addText((t) => t.setValue(s.footerText).onChange(async (v) => { s.footerText = v; await this.markDirty(); }));
|
||||
.addText((t) => t.setValue(s.footerText).onChange((v) => { s.footerText = v; void this.markDirty(); }));
|
||||
new Setting(containerEl).setName("Show page numbers").addToggle((t) =>
|
||||
t.setValue(s.showPageNumbers).onChange(async (v) => { s.showPageNumbers = v; await this.markDirty(); }),
|
||||
t.setValue(s.showPageNumbers).onChange((v) => { s.showPageNumbers = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Page number position").addDropdown((d) =>
|
||||
d.addOptions({ left: "Left", center: "Center", right: "Right" })
|
||||
.setValue(s.pageNumberPosition)
|
||||
.onChange(async (v) => { s.pageNumberPosition = v as "left"|"center"|"right"; await this.markDirty(); }),
|
||||
.onChange((v) => { s.pageNumberPosition = v as "left"|"center"|"right"; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
.setName("Page number start")
|
||||
.setDesc("Number assigned to the first visible page number. Accepts any integer.")
|
||||
.addText((t) =>
|
||||
t.setValue(String(s.pageNumberStart))
|
||||
.onChange(async (v) => {
|
||||
.onChange((v) => {
|
||||
const n = parseInt(v, 10);
|
||||
s.pageNumberStart = isNaN(n) ? 1 : n;
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
.setName("Header/footer on first page")
|
||||
.setDesc("When off, page 1 has no header, footer, or page number. Numbering begins on page 2 using the start value.")
|
||||
.addToggle((t) =>
|
||||
t.setValue(s.showHeaderFooterOnFirstPage).onChange(async (v) => {
|
||||
t.setValue(s.showHeaderFooterOnFirstPage).onChange((v) => {
|
||||
s.showHeaderFooterOnFirstPage = v;
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
@ -1983,9 +1979,9 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
.setName("Hide frontmatter")
|
||||
.setDesc("Strip the YAML frontmatter block (--- … ---) from the preview and exported PDF.")
|
||||
.addToggle((t) =>
|
||||
t.setValue(s.hideFrontmatter).onChange(async (v) => {
|
||||
t.setValue(s.hideFrontmatter).onChange((v) => {
|
||||
s.hideFrontmatter = v;
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
new Setting(containerEl)
|
||||
|
|
@ -1995,16 +1991,16 @@ class PDFExportSettingTab extends PluginSettingTab {
|
|||
"Mirrors Obsidian's built-in 'Include file name as title' export option.",
|
||||
)
|
||||
.addToggle((t) =>
|
||||
t.setValue(s.includeFilenameAsTitle).onChange(async (v) => {
|
||||
t.setValue(s.includeFilenameAsTitle).onChange((v) => {
|
||||
s.includeFilenameAsTitle = v;
|
||||
await this.markDirty();
|
||||
void this.markDirty();
|
||||
}),
|
||||
);
|
||||
new Setting(containerEl).setName("Auto page break before H1").addToggle((t) =>
|
||||
t.setValue(s.autoBreakH1).onChange(async (v) => { s.autoBreakH1 = v; await this.markDirty(); }),
|
||||
t.setValue(s.autoBreakH1).onChange((v) => { s.autoBreakH1 = v; void this.markDirty(); }),
|
||||
);
|
||||
new Setting(containerEl).setName("Auto page break before H2").addToggle((t) =>
|
||||
t.setValue(s.autoBreakH2).onChange(async (v) => { s.autoBreakH2 = v; await this.markDirty(); }),
|
||||
t.setValue(s.autoBreakH2).onChange((v) => { s.autoBreakH2 = v; void this.markDirty(); }),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
312
package-lock.json
generated
312
package-lock.json
generated
|
|
@ -8,11 +8,11 @@
|
|||
"name": "obsidian-advanced-pdf-export",
|
||||
"version": "3.0.0",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
"esbuild": "0.17.3",
|
||||
"@types/node": "^22.14.0",
|
||||
"esbuild": "0.25.5",
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
|
|
@ -36,10 +36,27 @@
|
|||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
|
||||
"integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz",
|
||||
"integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
|
||||
"integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -50,13 +67,13 @@
|
|||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz",
|
||||
"integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -67,13 +84,13 @@
|
|||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -84,13 +101,13 @@
|
|||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz",
|
||||
"integrity": "sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -101,13 +118,13 @@
|
|||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -118,13 +135,13 @@
|
|||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz",
|
||||
"integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -135,13 +152,13 @@
|
|||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -152,13 +169,13 @@
|
|||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz",
|
||||
"integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
|
||||
"integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -169,13 +186,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz",
|
||||
"integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -186,13 +203,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz",
|
||||
"integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
|
||||
"integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -203,13 +220,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz",
|
||||
"integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
|
||||
"integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
|
|
@ -220,13 +237,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz",
|
||||
"integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
|
||||
"integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
|
|
@ -237,13 +254,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz",
|
||||
"integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
|
||||
"integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
|
|
@ -254,13 +271,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz",
|
||||
"integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
|
||||
"integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -271,13 +288,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz",
|
||||
"integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
|
||||
"integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
|
|
@ -288,11 +305,13 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.17.3",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -303,13 +322,30 @@
|
|||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -320,13 +356,30 @@
|
|||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -337,13 +390,13 @@
|
|||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -354,13 +407,13 @@
|
|||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz",
|
||||
"integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
|
||||
"integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -371,13 +424,13 @@
|
|||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz",
|
||||
"integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
|
||||
"integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -388,13 +441,13 @@
|
|||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.17.3",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz",
|
||||
"integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
|
||||
"integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -405,7 +458,7 @@
|
|||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@marijn/find-cluster-break": {
|
||||
|
|
@ -428,9 +481,14 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.18.126",
|
||||
"version": "22.19.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.20.tgz",
|
||||
"integrity": "sha512-6tELRwSDYWW9EdZhbeZmYGZ1/7Djkt+Ah3/ScEYT9cDord7UJzasR/4D3VONg9tQI5CDp+/CZC1AXj2pCFOvpw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/tern": {
|
||||
"version": "0.23.9",
|
||||
|
|
@ -447,7 +505,9 @@
|
|||
"peer": true
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.17.3",
|
||||
"version": "0.25.5",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
|
||||
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
|
|
@ -455,31 +515,34 @@
|
|||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/android-arm": "0.17.3",
|
||||
"@esbuild/android-arm64": "0.17.3",
|
||||
"@esbuild/android-x64": "0.17.3",
|
||||
"@esbuild/darwin-arm64": "0.17.3",
|
||||
"@esbuild/darwin-x64": "0.17.3",
|
||||
"@esbuild/freebsd-arm64": "0.17.3",
|
||||
"@esbuild/freebsd-x64": "0.17.3",
|
||||
"@esbuild/linux-arm": "0.17.3",
|
||||
"@esbuild/linux-arm64": "0.17.3",
|
||||
"@esbuild/linux-ia32": "0.17.3",
|
||||
"@esbuild/linux-loong64": "0.17.3",
|
||||
"@esbuild/linux-mips64el": "0.17.3",
|
||||
"@esbuild/linux-ppc64": "0.17.3",
|
||||
"@esbuild/linux-riscv64": "0.17.3",
|
||||
"@esbuild/linux-s390x": "0.17.3",
|
||||
"@esbuild/linux-x64": "0.17.3",
|
||||
"@esbuild/netbsd-x64": "0.17.3",
|
||||
"@esbuild/openbsd-x64": "0.17.3",
|
||||
"@esbuild/sunos-x64": "0.17.3",
|
||||
"@esbuild/win32-arm64": "0.17.3",
|
||||
"@esbuild/win32-ia32": "0.17.3",
|
||||
"@esbuild/win32-x64": "0.17.3"
|
||||
"@esbuild/aix-ppc64": "0.25.5",
|
||||
"@esbuild/android-arm": "0.25.5",
|
||||
"@esbuild/android-arm64": "0.25.5",
|
||||
"@esbuild/android-x64": "0.25.5",
|
||||
"@esbuild/darwin-arm64": "0.25.5",
|
||||
"@esbuild/darwin-x64": "0.25.5",
|
||||
"@esbuild/freebsd-arm64": "0.25.5",
|
||||
"@esbuild/freebsd-x64": "0.25.5",
|
||||
"@esbuild/linux-arm": "0.25.5",
|
||||
"@esbuild/linux-arm64": "0.25.5",
|
||||
"@esbuild/linux-ia32": "0.25.5",
|
||||
"@esbuild/linux-loong64": "0.25.5",
|
||||
"@esbuild/linux-mips64el": "0.25.5",
|
||||
"@esbuild/linux-ppc64": "0.25.5",
|
||||
"@esbuild/linux-riscv64": "0.25.5",
|
||||
"@esbuild/linux-s390x": "0.25.5",
|
||||
"@esbuild/linux-x64": "0.25.5",
|
||||
"@esbuild/netbsd-arm64": "0.25.5",
|
||||
"@esbuild/netbsd-x64": "0.25.5",
|
||||
"@esbuild/openbsd-arm64": "0.25.5",
|
||||
"@esbuild/openbsd-x64": "0.25.5",
|
||||
"@esbuild/sunos-x64": "0.25.5",
|
||||
"@esbuild/win32-arm64": "0.25.5",
|
||||
"@esbuild/win32-ia32": "0.25.5",
|
||||
"@esbuild/win32-x64": "0.25.5"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
|
|
@ -512,12 +575,16 @@
|
|||
"peer": true
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.4.0",
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"dev": true,
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.7.4",
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
|
|
@ -525,9 +592,16 @@
|
|||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"dev": true,
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@
|
|||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
"esbuild": "0.17.3",
|
||||
"@types/node": "^22.14.0",
|
||||
"esbuild": "0.25.5",
|
||||
"obsidian": "latest",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.8.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
styles.css
15
styles.css
|
|
@ -213,7 +213,7 @@
|
|||
pointer-events: none; /* let clicks through to cancel/settings while loading */
|
||||
}
|
||||
|
||||
.mpdf-loading-overlay--visible {
|
||||
.mpdf-loading-overlay.is-active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
|
@ -265,3 +265,16 @@
|
|||
width: 64px;
|
||||
accent-color: var(--interactive-accent);
|
||||
}
|
||||
|
||||
/* Utility: toggle visibility without affecting layout flow */
|
||||
.is-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Static positioning for the per-page shadow-DOM host; width/height/transform set inline */
|
||||
.mpdf-shadow-host {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,17 +4,14 @@
|
|||
"inlineSourceMap": true,
|
||||
"inlineSources": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES2017",
|
||||
"target": "ES2022",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true,
|
||||
"strictPropertyInitialization": false,
|
||||
"ignoreDeprecations": "6.0",
|
||||
"types": ["node"],
|
||||
"lib": ["ES2017", "DOM"]
|
||||
"skipLibCheck": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue