112 lines
3.2 KiB
TypeScript
112 lines
3.2 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import { describe, it } from "node:test"
|
|
import {
|
|
normalizeImportedGraphics,
|
|
normalizeLegacyImageAttrs,
|
|
} from "./docs-graphic-import.ts"
|
|
import { extractGraphicPositionsFromDocx } from "./docx-position-import.ts"
|
|
import { computeCropImageStyle } from "./docs-graphic-types.ts"
|
|
|
|
function normalizeImportedTipTap(content: Record<string, unknown>) {
|
|
return normalizeImportedGraphics(normalizeLegacyImageAttrs(content))
|
|
}
|
|
|
|
describe("richtext-import chain", () => {
|
|
it("preserves placement and rotation through full chain", () => {
|
|
const result = normalizeImportedTipTap({
|
|
type: "doc",
|
|
content: [
|
|
{
|
|
type: "paragraph",
|
|
content: [
|
|
{
|
|
type: "image",
|
|
attrs: {
|
|
src: "data:image/png;base64,abc",
|
|
width: 200,
|
|
height: 120,
|
|
placement: "absolute",
|
|
wrap: "square",
|
|
x: 40,
|
|
y: 20,
|
|
rotationDeg: 15,
|
|
floatSide: "right",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
],
|
|
})
|
|
const node = result.content?.[0] as { type?: string; attrs?: Record<string, unknown> }
|
|
assert.equal(node.type, "docsGraphic")
|
|
assert.equal(node.attrs?.placement, "absolute")
|
|
assert.equal(node.attrs?.x, 40)
|
|
assert.equal(node.attrs?.y, 20)
|
|
assert.equal(node.attrs?.rotationDeg, 15)
|
|
assert.equal(node.attrs?.floatSide, "right")
|
|
})
|
|
|
|
it("preserves crop attrs through full chain", () => {
|
|
const result = normalizeImportedTipTap({
|
|
type: "doc",
|
|
content: [
|
|
{
|
|
type: "image",
|
|
attrs: {
|
|
src: "data:image/png;base64,abc",
|
|
cropX: 0.1,
|
|
cropY: 0.2,
|
|
cropWidth: 0.8,
|
|
cropHeight: 0.7,
|
|
},
|
|
},
|
|
],
|
|
})
|
|
const node = result.content?.[0] as { attrs?: Record<string, unknown> }
|
|
assert.equal(node.attrs?.cropX, 0.1)
|
|
assert.equal(node.attrs?.cropY, 0.2)
|
|
assert.equal(node.attrs?.cropWidth, 0.8)
|
|
assert.equal(node.attrs?.cropHeight, 0.7)
|
|
})
|
|
})
|
|
|
|
describe("docx-position-import", () => {
|
|
it("extractGraphicPositionsFromDocx parses inline extent", () => {
|
|
const archive = {
|
|
"word/document.xml": new TextEncoder().encode(`
|
|
<w:document>
|
|
<w:body>
|
|
<w:p>
|
|
<w:drawing>
|
|
<wp:inline>
|
|
<wp:extent cx="914400" cy="457200"/>
|
|
</wp:inline>
|
|
</w:drawing>
|
|
</w:p>
|
|
</w:body>
|
|
</w:document>
|
|
`),
|
|
}
|
|
const positions = extractGraphicPositionsFromDocx(archive)
|
|
assert.equal(positions.length, 1)
|
|
assert.equal(positions[0]?.width, 96)
|
|
assert.equal(positions[0]?.height, 48)
|
|
assert.equal(positions[0]?.placement, "inline")
|
|
assert.equal(positions[0]?.wrap, "inline")
|
|
})
|
|
})
|
|
|
|
describe("docs-graphic-types crop", () => {
|
|
it("computeCropImageStyle returns styles when crop active", () => {
|
|
const style = computeCropImageStyle({
|
|
cropX: 0.1,
|
|
cropY: 0,
|
|
cropWidth: 0.8,
|
|
cropHeight: 1,
|
|
cropShape: "rect",
|
|
})
|
|
assert.ok(style.img.width)
|
|
assert.equal(style.clipPath, undefined)
|
|
})
|
|
})
|