diff --git a/src/lib/components/HeaderFooterLayer.svelte b/src/lib/components/HeaderFooterLayer.svelte index 042fd0b..f82b9c5 100644 --- a/src/lib/components/HeaderFooterLayer.svelte +++ b/src/lib/components/HeaderFooterLayer.svelte @@ -155,18 +155,14 @@ if (zone === 'footer') return { ...b, top: b.top + b.height - height, height }; return { ...b, height }; } - // Double-click target: the whole margin band the zone sits in, edge to edge, not just - // the zone box — the band above the body is the header's, as it is in LibreOffice. - function hitBox(zone: HfZone, page: number) { + // Double-click target: the zone's ::after grows the box out to the page edges, so the + // whole margin band opens the zone (as in LibreOffice) without a box of its own — a + // second element per zone is a hundred more to lay out on every pass. + function hitVars(zone: HfZone, page: number, z: { top: number; left: number; width: number; height: number }) { const box = boxOf(page); - const z = zoneBox(zone, page); - const m = marginsOf(page); - if (zone === 'header') { - const bottom = Math.max(box.top + cmToPx(m.top), z.top + z.height); - return { top: box.top, left: box.left, width: box.width, height: bottom - box.top }; - } - const top = Math.min(box.top + box.height - cmToPx(m.bottom), z.top); - return { top, left: box.left, width: box.width, height: box.top + box.height - top }; + const edge = zone === 'header' ? z.top - box.top : box.top + box.height - z.top - z.height; + return ` --hit-${zone === 'header' ? 'top' : 'bottom'}: ${-edge}px;` + + ` --hit-left: ${box.left - z.left}px; --hit-right: ${box.left + box.width - z.left - z.width}px;`; } const boxStyle = (b: { top: number; left: number; width: number; height: number }) => `top: ${b.top}px; left: ${b.left}px; width: ${b.width}px; height: ${b.height}px;`; @@ -488,18 +484,16 @@
{#each pages as p} {#each ['header', 'footer'] as const as zone} - {#if interactive} -
startEdit(zone, p)} role="button" tabindex="-1">
- {/if} {#if !(interactive && hfActive === zone && editingPage === p)} {@const html = zoneHtml(zone, p)} {@const total = html.includes('data-page-field="count"') ? numPages : 0} {@const chapters = html.includes('data-page-field="chapter"') ? chapterStarts : null} + {@const zb = zoneBox(zone, p)}
interactive && startEdit(zone, p)} role="button" tabindex="-1" @@ -602,11 +596,15 @@ justify-content: flex-end; } - /* The margin band around a zone, double-clickable like the zone itself. Painted - before it, so the zone keeps the events inside its own box. */ - .hf-hit { + /* The margin band around the zone, double-clickable like the zone itself. Not on the + edited zone, where it would swallow the clicks into the live editor. */ + .hf-zone:not(.hf-active)::after { + content: ''; position: absolute; - pointer-events: auto; + top: var(--hit-top, 0); + bottom: var(--hit-bottom, 0); + left: var(--hit-left, 0); + right: var(--hit-right, 0); } /* Empty zone: invisible until hovered, then show a faint double-click hint. */ @@ -621,8 +619,7 @@ .hf-footer.hf-empty::before { margin-top: auto; } - .hf-empty:hover::before, - .hf-hit:hover + .hf-zone.hf-empty::before { + .hf-empty:hover::before { opacity: 0.6; }