fix: a frame behind the text can be picked again
The browser hit-tests a behind-text frame last of all — the page and every paragraph over it come first — so a cover picture could not be clicked at all: the caret landed in the text as if it were not there. A mousedown over one now goes to the frame's own node view, which selects and drags it as any other frame; text painted over the point still wins, as the caret does in both products. A box's node view mirrors renderHTML's data-wrap for it, as an image's already did. Claude-Session: https://claude.ai/code/session_01Wzs2qG6Y5qm7mKmJHfu44G
This commit is contained in:
1 parent
9f5ecd8071
commit
9dfaeb4032
4 files changed
+97
-1
No files matched your search
@@ -13,6 +13,7 @@ const ORDERED_DEFAULTS: Record<string, unknown> = {
|
||||
joinPrev: false, // pageBreaks.ts's split marker; the export merges the halves
|
||||
marginLeft: 0, marginRight: 0, marginTop: 0, marginBottom: 0, // a table's, once a command has touched them
|
||||
alt: '', inFront: false, paddingCm: 0.15, flipV: false, textVertical: false, // the editor's own picture and box defaults
|
||||
wrapFromPage: false,
|
||||
// index attrs the DOCX TOC field has no switch for come back at their defaults
|
||||
maxLevel: MAX_HEADING_LEVEL, leader: '.', citationStyle: 'key',
|
||||
};
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// A frame whose vertical offset counts from the page the anchor lands on (Word's
|
||||
// positionV relativeFrom="page", ODF's style:vertical-rel="page") keeps that relation
|
||||
// through both formats — read as paragraph-relative it would move on every re-open.
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { buildOdt } from '../../src/lib/export/odt';
|
||||
import { importOdt } from '../../src/lib/import/odt';
|
||||
import { buildDocx } from '../../src/lib/export/docx';
|
||||
import { importDocx } from '../../src/lib/import/docx';
|
||||
|
||||
type N = any;
|
||||
|
||||
const PNG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAD0lEQVR4nGNgYPgPRmAKABf2A/1+6zfzAAAAAElFTkSuQmCC';
|
||||
|
||||
const doc: N = { type: 'doc', content: [
|
||||
{ type: 'paragraph', content: [
|
||||
{ type: 'image', attrs: { src: PNG, width: 200, height: 100, wrap: 'through', wrapOffset: 1, wrapOffsetY: 17.6, wrapFromPage: true } },
|
||||
{ type: 'textBox', attrs: { width: 300, height: 120, wrap: 'through', wrapOffset: 0, wrapOffsetY: 5.5, wrapFromPage: true, fillColor: '#34ABA2' },
|
||||
content: [{ type: 'paragraph' }] },
|
||||
] },
|
||||
{ type: 'paragraph', content: [{ type: 'text', text: 'Body' }] },
|
||||
] };
|
||||
|
||||
const find = (n: N, type: string): N => {
|
||||
if (n.type === type) return n;
|
||||
for (const c of n.content ?? []) { const hit = find(c, type); if (hit) return hit; }
|
||||
return null;
|
||||
};
|
||||
|
||||
describe('a frame placed against the page', () => {
|
||||
it('round-trips through ODF', async () => {
|
||||
const back = importOdt(await buildOdt(doc)).content as N;
|
||||
expect(find(back, 'image').attrs).toMatchObject({ wrapFromPage: true, wrapOffsetY: 17.6 });
|
||||
expect(find(back, 'textBox').attrs).toMatchObject({ wrapFromPage: true, wrapOffsetY: 5.5 });
|
||||
});
|
||||
|
||||
it('round-trips through DOCX', async () => {
|
||||
const back = importDocx(await buildDocx(doc)).content as N;
|
||||
expect(find(back, 'image').attrs).toMatchObject({ wrapFromPage: true, wrapOffsetY: 17.6 });
|
||||
expect(find(back, 'textBox').attrs).toMatchObject({ wrapFromPage: true, wrapOffsetY: 5.5 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user