create addImageToOdtFile

This commit is contained in:
Clémence Fernandez 2025-09-15 16:35:12 +02:00
parent 1c54f226cb
commit ecb6a48cb0
2 changed files with 51 additions and 28 deletions

View File

@ -184,12 +184,18 @@ class TemplateBlock{
/** @type {Node[]} */ /** @type {Node[]} */
#middleContent; #middleContent;
/**@type {any} */
#addImageToOdtFile;
/** /**
* *
* @param {Node} startNode * @param {Node} startNode
* @param {Node} endNode * @param {Node} endNode
* @param {(OdfjsImage) => string} addImageToOdtFile
*/ */
constructor(startNode, endNode){ constructor(startNode, endNode, addImageToOdtFile){
this.#addImageToOdtFile = addImageToOdtFile
// @ts-expect-error xmldom.Node // @ts-expect-error xmldom.Node
this.#commonAncestor = findCommonAncestor(startNode, endNode) this.#commonAncestor = findCommonAncestor(startNode, endNode)
@ -233,7 +239,7 @@ class TemplateBlock{
const startChild = this.startBranch.at(1) const startChild = this.startBranch.at(1)
if(startChild /*&& startChild !== */){ if(startChild /*&& startChild !== */){
//console.log('[fillBlockContentTemplate] startChild', startChild.nodeName, startChild.textContent) //console.log('[fillBlockContentTemplate] startChild', startChild.nodeName, startChild.textContent)
fillOdtElementTemplate(startChild, compartement) fillOdtElementTemplate(startChild, compartement, this.#addImageToOdtFile)
} }
//console.log('[fillBlockContentTemplate] after startChild') //console.log('[fillBlockContentTemplate] after startChild')
@ -241,7 +247,7 @@ class TemplateBlock{
// if content consists of several parts of an {#each}{/each} // if content consists of several parts of an {#each}{/each}
// when arriving to the {/each}, it will be alone (and imbalanced) // when arriving to the {/each}, it will be alone (and imbalanced)
// and will trigger an error // and will trigger an error
fillOdtElementTemplate(Array.from(this.#middleContent), compartement) fillOdtElementTemplate(Array.from(this.#middleContent), compartement, this.#addImageToOdtFile)
//console.log('[fillBlockContentTemplate] after middleContent') //console.log('[fillBlockContentTemplate] after middleContent')
@ -251,7 +257,7 @@ class TemplateBlock{
if(endChild){ if(endChild){
//console.log('[fillBlockContentTemplate] endChild', endChild.nodeName, endChild.textContent) //console.log('[fillBlockContentTemplate] endChild', endChild.nodeName, endChild.textContent)
fillOdtElementTemplate(endChild, compartement) fillOdtElementTemplate(endChild, compartement, this.#addImageToOdtFile)
} }
//console.log('[fillBlockContentTemplate] after endChild') //console.log('[fillBlockContentTemplate] after endChild')
@ -349,7 +355,7 @@ class TemplateBlock{
} }
} }
return new TemplateBlock(startLeafCloneNode, endLeafCloneNode) return new TemplateBlock(startLeafCloneNode, endLeafCloneNode, this.#addImageToOdtFile)
} }
} }
@ -428,8 +434,9 @@ function findPlacesToFillInString(str, compartment) {
* @param {Node} ifClosingMarkerNode * @param {Node} ifClosingMarkerNode
* @param {string} ifBlockConditionExpression * @param {string} ifBlockConditionExpression
* @param {Compartment} compartment * @param {Compartment} compartment
* // TODO type,addImageToOdtFile
*/ */
function fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, ifBlockConditionExpression, compartment) { function fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, ifBlockConditionExpression, compartment, addImageToOdtFile) {
//const docEl = ifOpeningMarkerNode.ownerDocument.documentElement //const docEl = ifOpeningMarkerNode.ownerDocument.documentElement
const conditionValue = compartment.evaluate(ifBlockConditionExpression) const conditionValue = compartment.evaluate(ifBlockConditionExpression)
@ -445,11 +452,11 @@ function fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode,
ifElseMarkerNode.childNodes.length, ifElseMarkerNode.textContent ifElseMarkerNode.childNodes.length, ifElseMarkerNode.textContent
)*/ )*/
thenTemplateBlock = new TemplateBlock(ifOpeningMarkerNode, ifElseMarkerNode) thenTemplateBlock = new TemplateBlock(ifOpeningMarkerNode, ifElseMarkerNode, addImageToOdtFile)
elseTemplateBlock = new TemplateBlock(ifElseMarkerNode, ifClosingMarkerNode) elseTemplateBlock = new TemplateBlock(ifElseMarkerNode, ifClosingMarkerNode, addImageToOdtFile)
} }
else { else {
thenTemplateBlock = new TemplateBlock(ifOpeningMarkerNode, ifClosingMarkerNode) thenTemplateBlock = new TemplateBlock(ifOpeningMarkerNode, ifClosingMarkerNode, addImageToOdtFile)
} }
if(conditionValue) { if(conditionValue) {
@ -488,14 +495,15 @@ function fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode,
* @param {string} itemExpression * @param {string} itemExpression
* @param {Node} endNode * @param {Node} endNode
* @param {Compartment} compartment * @param {Compartment} compartment
* // TODO type addImageToOdtFile
*/ */
function fillEachBlock(startNode, iterableExpression, itemExpression, endNode, compartment) { function fillEachBlock(startNode, iterableExpression, itemExpression, endNode, compartment, addImageToOdtFile) {
//console.log('fillEachBlock', iterableExpression, itemExpression) //console.log('fillEachBlock', iterableExpression, itemExpression)
const docEl = startNode.ownerDocument.documentElement const docEl = startNode.ownerDocument.documentElement
//console.log('[fillEachBlock] docEl', docEl.textContent) //console.log('[fillEachBlock] docEl', docEl.textContent)
const repeatedTemplateBlock = new TemplateBlock(startNode, endNode) const repeatedTemplateBlock = new TemplateBlock(startNode, endNode, addImageToOdtFile)
// Find the iterable in the data // Find the iterable in the data
let iterable = compartment.evaluate(iterableExpression) let iterable = compartment.evaluate(iterableExpression)
@ -589,9 +597,10 @@ const EACH = eachStartMarkerRegex.source
* *
* @param {RootElementArgument | RootElementArgument[]} rootElements * @param {RootElementArgument | RootElementArgument[]} rootElements
* @param {Compartment} compartment * @param {Compartment} compartment
* @param {(OdfjsImage) => string} addImageToOdtFile
* @returns {void} * @returns {void}
*/ */
export default function fillOdtElementTemplate(rootElements, compartment) { export default function fillOdtElementTemplate(rootElements, compartment, addImageToOdtFile) {
if(!Array.isArray(rootElements)){ if(!Array.isArray(rootElements)){
rootElements = [rootElements] rootElements = [rootElements]
@ -678,7 +687,7 @@ export default function fillOdtElementTemplate(rootElements, compartment) {
// execute replacement loop // execute replacement loop
//console.log('start of fillEachBlock') //console.log('start of fillEachBlock')
fillEachBlock(eachOpeningMarkerNode, eachBlockIterableExpression, eachBlockItemExpression, eachClosingMarkerNode, compartment) fillEachBlock(eachOpeningMarkerNode, eachBlockIterableExpression, eachBlockItemExpression, eachClosingMarkerNode, compartment, addImageToOdtFile)
//console.log('end of fillEachBlock') //console.log('end of fillEachBlock')
@ -753,7 +762,7 @@ export default function fillOdtElementTemplate(rootElements, compartment) {
// found an {#if} and its corresponding {/if} // found an {#if} and its corresponding {/if}
// execute replacement loop // execute replacement loop
fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, ifBlockConditionExpression, compartment) fillIfBlock(ifOpeningMarkerNode, ifElseMarkerNode, ifClosingMarkerNode, ifBlockConditionExpression, compartment, addImageToOdtFile)
ifOpeningMarkerNode = undefined ifOpeningMarkerNode = undefined
ifElseMarkerNode = undefined ifElseMarkerNode = undefined
@ -789,19 +798,19 @@ export default function fillOdtElementTemplate(rootElements, compartment) {
} else { } else {
const imageMarker = findImageMarker(currentNode.data, compartment) const imageMarker = findImageMarker(currentNode.data, compartment)
if (imageMarker){ if (imageMarker){
console.log({imageMarker}, "dans le if") console.log({imageMarker}, "dans le if imageMarker")
if (imageMarker.odfjsImage) { if (imageMarker.odfjsImage) {
// TODO : const href = addImageToOdtFile(imageMarker.odfjsImage)
// - Rajouter un fichier image dans le odt avec le ArrayBuffer comme contenu (ou autre type) // TODO :
// - Rajouter un suffixe/titre (donc peut-être changer l'api pour que photo ça soit un objet qui contienne arraybuffer et d'autres choses) // - Rajouter un fichier image dans le odt avec le ArrayBuffer comme contenu (ou autre type)
// - puis remplacer le texte par peut-être <draw:image et peut-être <draw:frame et peut être pas ici // - puis remplacer le texte par peut-être <draw:image et peut-être <draw:frame et peut être pas ici
// <draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="char" // <draw:frame draw:style-name="fr1" draw:name="Image1" text:anchor-type="char"
// svg:width="7.28cm" svg:height="10.239cm" draw:z-index="0"> // svg:width="7.28cm" svg:height="10.239cm" draw:z-index="0">
// <draw:image xlink:href="Pictures/100000000000016C00000200F498F14E.jpg" // <draw:image xlink:href="Pictures/100000000000016C00000200F498F14E.jpg"
// xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad" // xlink:type="simple" xlink:show="embed" xlink:actuate="onLoad"
// draw:mime-type="image/jpeg" /> // draw:mime-type="image/jpeg" />
// </draw:frame> // </draw:frame>
} else { } else {
throw new Error(`No valid OdfjsImage value has been found for expression: ${imageMarker.expression}`) throw new Error(`No valid OdfjsImage value has been found for expression: ${imageMarker.expression}`)
} }

View File

@ -12,6 +12,7 @@ lockdown();
/** @import {Reader, ZipWriterAddDataOptions} from '@zip.js/zip.js' */ /** @import {Reader, ZipWriterAddDataOptions} from '@zip.js/zip.js' */
/** @import {ODFManifest} from '../manifest.js' */ /** @import {ODFManifest} from '../manifest.js' */
/** @import {OdfjsImage} from '../../types.js' */
/** @typedef {ArrayBuffer} ODTFile */ /** @typedef {ArrayBuffer} ODTFile */
@ -23,11 +24,12 @@ const ODTMimetype = 'application/vnd.oasis.opendocument.text'
* *
* @param {Document} document * @param {Document} document
* @param {Compartment} compartment * @param {Compartment} compartment
* @param {(OdfjsImage) => string} addImageToOdtFile
* @returns {void} * @returns {void}
*/ */
function fillOdtDocumentTemplate(document, compartment) { function fillOdtDocumentTemplate(document, compartment, addImageToOdtFile) {
prepareTemplateDOMTree(document) prepareTemplateDOMTree(document)
fillOdtElementTemplate(document, compartment) fillOdtElementTemplate(document, compartment, addImageToOdtFile)
} }
@ -65,6 +67,16 @@ export default async function fillOdtTemplate(odtTemplate, data) {
/** @type {{filename: string, content: Reader, options?: ZipWriterAddDataOptions}[]} */ /** @type {{filename: string, content: Reader, options?: ZipWriterAddDataOptions}[]} */
const zipEntriesToAdd = [] const zipEntriesToAdd = []
/**
* Return href
* @param {OdfjsImage} odfjsImage
* @returns {string}
*/
function addImageToOdtFile(odfjsImage) {
// console.log({odfjsImage})
zipEntriesToAdd.push({content: new Uint8ArrayReader(new Uint8Array(odfjsImage.content)), filename: `Pictures/${odfjsImage.fileName}`})
}
// Parcourir chaque entrée du fichier ODT // Parcourir chaque entrée du fichier ODT
for await(const entry of entries) { for await(const entry of entries) {
const filename = entry.filename const filename = entry.filename
@ -96,13 +108,15 @@ export default async function fillOdtTemplate(odtTemplate, data) {
// @ts-ignore // @ts-ignore
const contentXml = await entry.getData(new TextWriter()); const contentXml = await entry.getData(new TextWriter());
const contentDocument = parseXML(contentXml); const contentDocument = parseXML(contentXml);
const compartment = new Compartment({ const compartment = new Compartment({
globals: data, globals: data,
__options__: true __options__: true
}) })
fillOdtDocumentTemplate(contentDocument, compartment) fillOdtDocumentTemplate(contentDocument, compartment, addImageToOdtFile)
const updatedContentXml = serializeToString(contentDocument) const updatedContentXml = serializeToString(contentDocument)