From 7b67969774cfc678a3e9f4999b9a8fa4cacbf239 Mon Sep 17 00:00:00 2001 From: Steffen Becker Date: Mon, 15 Jun 2026 15:48:15 +0200 Subject: [PATCH] feat: header/footer position --- src/App.svelte | 18 ++++- src/lib/editor/Editor.svelte | 7 +- src/lib/editor/HeaderFooterLayer.svelte | 15 ++-- src/lib/editor/ToolbarExpanded.svelte | 93 ++++++++++++++++++++++++- src/lib/export/odt.ts | 35 +++++++--- src/lib/import/odt.ts | 6 ++ src/lib/import/styleResolver.ts | 12 ++++ src/lib/storage/headerFooter.ts | 37 +++++++++- 8 files changed, 197 insertions(+), 26 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 9e73a5a..598b4d2 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -10,7 +10,7 @@ import { loadTheme, saveTheme, applyTheme, loadToolbarExpanded, saveToolbarExpanded, loadFormattingMarks, saveFormattingMarks, type ThemeMode } from './lib/storage/theme'; import { loadPageMargins, savePageMargins, type PageMargins } from './lib/storage/pageMargins'; import { loadOrientation, saveOrientation, type Orientation } from './lib/storage/pageOrientation'; - import { loadHfDoc, saveHfDoc, type HfDoc, type HfZone } from './lib/storage/headerFooter'; + import { loadHfDoc, saveHfDoc, loadHfDistances, saveHfDistances, DEFAULT_HF_DISTANCES, type HfDoc, type HfZone, type HfDistances } from './lib/storage/headerFooter'; let editor: Editor | null = $state(null); let tick: number = $state(0); @@ -21,6 +21,7 @@ // top toolbars target hfEditor instead of the body editor (activeEditor below). let headerDoc: HfDoc = $state(loadHfDoc('header')); let footerDoc: HfDoc = $state(loadHfDoc('footer')); + let hfDistances: HfDistances = $state(loadHfDistances()); let hfEditor: Editor | null = $state(null); let hfActive: HfZone | null = $state(null); let hfTick: number = $state(0); @@ -56,6 +57,10 @@ saveHfDoc('footer', footerDoc); }); + $effect(() => { + saveHfDistances(hfDistances); + }); + function setZoom(value: number) { zoom = Math.max(20, Math.min(300, value)); localStorage.setItem('odf-editor-zoom', String(zoom)); @@ -83,7 +88,10 @@ async function handleExport() { if (editor) { - await exportToOdt(editor, pageMargins, pageOrientation, { header: headerDoc, footer: footerDoc, pageCount: numPages }); + await exportToOdt(editor, pageMargins, pageOrientation, { + header: headerDoc, footer: footerDoc, pageCount: numPages, + headerDistanceCm: hfDistances.header, footerDistanceCm: hfDistances.footer, + }); } } @@ -112,6 +120,10 @@ hfActive = null; headerDoc = result.header; footerDoc = result.footer; + hfDistances = { + header: result.headerDistanceCm ?? DEFAULT_HF_DISTANCES.header, + footer: result.footerDistanceCm ?? DEFAULT_HF_DISTANCES.footer, + }; if (result.warnings.length) { console.warn('[import] Unsupported content in opened file:', result.warnings); @@ -248,6 +260,7 @@ bind:showFormattingMarks bind:pageMargins bind:pageOrientation + bind:hfDistances hfActive={hfActive} onEditZone={(zone) => (hfActive = zone)} /> @@ -262,6 +275,7 @@ bind:hfEditor bind:hfActive bind:hfTick + {hfDistances} {zoom} {showFormattingMarks} {pageMargins} diff --git a/src/lib/editor/Editor.svelte b/src/lib/editor/Editor.svelte index 263cf9f..e6cc8e0 100644 --- a/src/lib/editor/Editor.svelte +++ b/src/lib/editor/Editor.svelte @@ -9,7 +9,7 @@ import { saveDocument, loadDocument } from '../storage/autosave'; import { applyMarginVars, DEFAULT_MARGINS, type PageMargins } from '../storage/pageMargins'; import { applyOrientationVars, type Orientation } from '../storage/pageOrientation'; - import type { HfDoc, HfZone } from '../storage/headerFooter'; + import { DEFAULT_HF_DISTANCES, type HfDoc, type HfZone, type HfDistances } from '../storage/headerFooter'; import { FORCE_PAGE_RECALC, type TableBreakBand } from './pageBreaks'; import { recordTransaction, resetHistoryLog } from './historyLog.svelte'; import '../../styles/editor.css'; @@ -19,12 +19,12 @@ let { editor = $bindable(), tick = $bindable(0), currentPage = $bindable(1), numPages = $bindable(1), zoom = 100, showFormattingMarks = false, pageMargins = DEFAULT_MARGINS, orientation = 'portrait', - headerDoc = $bindable(null), footerDoc = $bindable(null), + headerDoc = $bindable(null), footerDoc = $bindable(null), hfDistances = DEFAULT_HF_DISTANCES, hfEditor = $bindable(null), hfActive = $bindable(null), hfTick = $bindable(0), }: { editor: Editor | null; tick: number; currentPage: number; numPages: number; zoom: number; showFormattingMarks?: boolean; pageMargins?: PageMargins; orientation?: Orientation; - headerDoc?: HfDoc; footerDoc?: HfDoc; + headerDoc?: HfDoc; footerDoc?: HfDoc; hfDistances?: HfDistances; hfEditor?: Editor | null; hfActive?: HfZone | null; hfTick?: number; } = $props(); @@ -420,6 +420,7 @@ {currentPage} {pageMargins} {orientation} + {hfDistances} /> diff --git a/src/lib/editor/HeaderFooterLayer.svelte b/src/lib/editor/HeaderFooterLayer.svelte index 2b9247a..7c8c8ef 100644 --- a/src/lib/editor/HeaderFooterLayer.svelte +++ b/src/lib/editor/HeaderFooterLayer.svelte @@ -1,7 +1,7 @@