Skip to content

Commit fca5e03

Browse files
committed
Load image data into data attribute. Optionally embed data attribute when saving.
1 parent cd11eb1 commit fca5e03

1 file changed

Lines changed: 43 additions & 12 deletions

File tree

src/processors/obfProcessor.ts

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,24 @@ interface ObfGrid {
7070
order?: Array<Array<string | number | null>>;
7171
}
7272

73+
interface ObfImage {
74+
id: string;
75+
data?: string;
76+
path?: string;
77+
url?: string;
78+
width?: number;
79+
height?: number;
80+
content_type?: string;
81+
license?: {
82+
type?: string;
83+
copyright_notice_url?: string;
84+
source_url?: string;
85+
author_name?: string;
86+
author_url?: string;
87+
author_email?: string;
88+
};
89+
}
90+
7391
interface ObfBoard {
7492
format?: string;
7593
id: string;
@@ -79,7 +97,7 @@ interface ObfBoard {
7997
description_html?: string;
8098
buttons: ObfButton[];
8199
grid?: ObfGrid;
82-
images?: any[];
100+
images?: ObfImage[];
83101
sounds?: any[];
84102
}
85103

@@ -132,7 +150,7 @@ class ObfProcessor extends BaseProcessor {
132150
/**
133151
* Extract an image from the ZIP file and convert to data URL
134152
*/
135-
private async extractImageAsDataUrl(imageId: string, images: any[]): Promise<string | null> {
153+
private async extractImageAsDataUrl(imageId: string, images: ObfImage[]): Promise<string | null> {
136154
// Check cache first
137155
if (this.imageCache.has(imageId)) {
138156
return this.imageCache.get(imageId) ?? null;
@@ -147,8 +165,8 @@ class ObfProcessor extends BaseProcessor {
147165
}
148166

149167
// If image has data property, use that
150-
if ((imageData as { data?: string }).data) {
151-
const dataUrl = (imageData as { data: string }).data;
168+
if (imageData.data) {
169+
const dataUrl = imageData.data;
152170
this.imageCache.set(imageId, dataUrl);
153171
return dataUrl;
154172
}
@@ -158,7 +176,7 @@ class ObfProcessor extends BaseProcessor {
158176
// Images are typically stored in an 'images' folder or root
159177
const possiblePaths = [
160178
imageData.path, // Explicit path if provided
161-
`images/${imageData.filename || imageId}`, // Standard images folder
179+
`images/${imageData.path || imageId}`, // Standard images folder
162180
imageData.id, // Just the ID
163181
].filter(Boolean);
164182

@@ -181,8 +199,8 @@ class ObfProcessor extends BaseProcessor {
181199
}
182200

183201
// If image has a URL, use that as fallback
184-
if ((imageData as { url?: string }).url) {
185-
const url = (imageData as { url: string }).url;
202+
if (imageData.url) {
203+
const url = imageData.url;
186204
this.imageCache.set(imageId, url);
187205
return url;
188206
}
@@ -654,13 +672,21 @@ class ObfProcessor extends BaseProcessor {
654672
private createObfBoardFromPage(
655673
page: AACPage,
656674
fallbackName: string,
657-
metadata?: AACTreeMetadata
675+
metadata?: AACTreeMetadata,
676+
embedData = false
658677
): ObfBoard {
659678
const { rows, columns, order, buttonPositions } = this.buildGridMetadata(page);
660679
const boardName =
661680
metadata?.name && page.id === metadata?.defaultHomePageId
662681
? metadata.name
663682
: page.name || fallbackName;
683+
let images: ObfImage[] = Array.isArray(page.images) ? page.images : [];
684+
if (!embedData) {
685+
images = images.map((image) => {
686+
delete image.data;
687+
return image;
688+
});
689+
}
664690

665691
return {
666692
format: OBF_FORMAT_VERSION,
@@ -702,7 +728,7 @@ class ObfProcessor extends BaseProcessor {
702728
hidden: button.visibility === 'Hidden' || false,
703729
};
704730
}),
705-
images: Array.isArray(page.images) ? page.images : [],
731+
images,
706732
sounds: Array.isArray(page.sounds) ? page.sounds : [],
707733
};
708734
}
@@ -748,7 +774,7 @@ class ObfProcessor extends BaseProcessor {
748774
return await readBinaryFromInput(outputPath);
749775
}
750776

751-
async saveFromTree(tree: AACTree, outputPath: string): Promise<void> {
777+
async saveFromTree(tree: AACTree, outputPath: string, embedData = false): Promise<void> {
752778
const { writeTextToPath, writeBinaryToPath, pathExists, mkDir, join } =
753779
this.options.fileAdapter;
754780
if (outputPath.endsWith('.obf')) {
@@ -758,12 +784,17 @@ class ObfProcessor extends BaseProcessor {
758784
throw new Error('No pages to save');
759785
}
760786

761-
const obfBoard = this.createObfBoardFromPage(rootPage, 'Exported Board', tree.metadata);
787+
const obfBoard = this.createObfBoardFromPage(
788+
rootPage,
789+
'Exported Board',
790+
tree.metadata,
791+
embedData
792+
);
762793
await writeTextToPath(outputPath, JSON.stringify(obfBoard, null, 2));
763794
} else {
764795
const getPageFilename = (id: string): string => (id.endsWith('.obf') ? id : `${id}.obf`);
765796
const files = Object.values(tree.pages).map((page) => {
766-
const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata);
797+
const obfBoard = this.createObfBoardFromPage(page, 'Board', tree.metadata, embedData);
767798
const obfContent = JSON.stringify(obfBoard, null, 2);
768799
const name = getPageFilename(page.id);
769800
return {

0 commit comments

Comments
 (0)