Make adding images declarative and simple
This commit is contained in:
@ -16,7 +16,6 @@ export interface IMediaDataTransformation {
|
||||
|
||||
export interface IMediaData {
|
||||
readonly stream: Buffer | Uint8Array | ArrayBuffer;
|
||||
readonly path?: string;
|
||||
readonly fileName: string;
|
||||
readonly transformation: IMediaDataTransformation;
|
||||
}
|
||||
|
@ -3,10 +3,7 @@ import { expect } from "chai";
|
||||
import { SinonStub, stub } from "sinon";
|
||||
|
||||
import * as convenienceFunctions from "convenience-functions";
|
||||
import { Formatter } from "export/formatter";
|
||||
|
||||
import { File } from "../file";
|
||||
import { Paragraph } from "../paragraph";
|
||||
import { Media } from "./media";
|
||||
|
||||
describe("Media", () => {
|
||||
@ -18,69 +15,6 @@ describe("Media", () => {
|
||||
(convenienceFunctions.uniqueId as SinonStub).restore();
|
||||
});
|
||||
|
||||
describe("#addImage", () => {
|
||||
it("should add image", () => {
|
||||
const file = new File();
|
||||
const image = Media.addImage({
|
||||
document: file,
|
||||
data: "",
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
});
|
||||
|
||||
let tree = new Formatter().format(new Paragraph(image));
|
||||
expect(tree["w:p"]).to.be.an.instanceof(Array);
|
||||
|
||||
tree = new Formatter().format(image);
|
||||
expect(tree["w:r"]).to.be.an.instanceof(Array);
|
||||
});
|
||||
|
||||
it("should ensure the correct relationship id is used when adding image", () => {
|
||||
// tslint:disable-next-line:no-any
|
||||
|
||||
const file = new File();
|
||||
const image1 = Media.addImage({
|
||||
document: file,
|
||||
data: "test",
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
});
|
||||
const tree = new Formatter().format(new Paragraph(image1));
|
||||
const inlineElements = tree["w:p"][0]["w:r"][0]["w:drawing"][0]["wp:inline"];
|
||||
const graphicData = inlineElements.find((x) => x["a:graphic"]);
|
||||
|
||||
expect(graphicData["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"]).to.deep.equal({
|
||||
_attr: {
|
||||
"r:embed": `rId{test.png}`,
|
||||
cstate: "none",
|
||||
},
|
||||
});
|
||||
|
||||
const image2 = Media.addImage({
|
||||
document: file,
|
||||
data: "test",
|
||||
transformation: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
});
|
||||
const tree2 = new Formatter().format(new Paragraph(image2));
|
||||
const inlineElements2 = tree2["w:p"][0]["w:r"][0]["w:drawing"][0]["wp:inline"];
|
||||
const graphicData2 = inlineElements2.find((x) => x["a:graphic"]);
|
||||
|
||||
expect(graphicData2["a:graphic"][1]["a:graphicData"][1]["pic:pic"][2]["pic:blipFill"][0]["a:blip"]).to.deep.equal({
|
||||
_attr: {
|
||||
"r:embed": `rId{test.png}`,
|
||||
cstate: "none",
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#addMedia", () => {
|
||||
it("should add media", () => {
|
||||
const image = new Media().addMedia("", {
|
||||
@ -129,35 +63,30 @@ describe("Media", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#getMedia", () => {
|
||||
it("should get media", () => {
|
||||
describe("#addImage", () => {
|
||||
it("should add media", () => {
|
||||
const media = new Media();
|
||||
media.addMedia("", {
|
||||
width: 100,
|
||||
height: 100,
|
||||
});
|
||||
|
||||
const image = media.getMedia("test.png");
|
||||
|
||||
expect(image.fileName).to.equal("test.png");
|
||||
expect(image.transformation).to.deep.equal({
|
||||
pixels: {
|
||||
x: 100,
|
||||
y: 100,
|
||||
media.addImage("test2.png", {
|
||||
stream: Buffer.from(""),
|
||||
fileName: "",
|
||||
transformation: {
|
||||
pixels: {
|
||||
x: Math.round(1),
|
||||
y: Math.round(1),
|
||||
},
|
||||
emus: {
|
||||
x: Math.round(1 * 9525),
|
||||
y: Math.round(1 * 9525),
|
||||
},
|
||||
},
|
||||
flip: undefined,
|
||||
emus: {
|
||||
x: 952500,
|
||||
y: 952500,
|
||||
},
|
||||
rotation: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("Get media", () => {
|
||||
const media = new Media();
|
||||
|
||||
expect(() => media.getMedia("test.png")).to.throw();
|
||||
expect(media.Array).to.be.lengthOf(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,12 +1,9 @@
|
||||
import { uniqueId } from "convenience-functions";
|
||||
|
||||
import { IFloating } from "../drawing";
|
||||
import { File } from "../file";
|
||||
import { PictureRun } from "../paragraph";
|
||||
import { IMediaData } from "./data";
|
||||
// import { Image } from "./image";
|
||||
|
||||
interface IMediaTransformation {
|
||||
export interface IMediaTransformation {
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly flip?: {
|
||||
@ -17,48 +14,19 @@ interface IMediaTransformation {
|
||||
}
|
||||
|
||||
export class Media {
|
||||
public static addImage(options: {
|
||||
readonly document: File;
|
||||
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
||||
readonly transformation: IMediaTransformation;
|
||||
readonly floating?: IFloating;
|
||||
}): PictureRun {
|
||||
// Workaround to expose id without exposing to API
|
||||
const mediaData = options.document.Media.addMedia(options.data, options.transformation);
|
||||
return new PictureRun(mediaData, { floating: options.floating });
|
||||
}
|
||||
|
||||
private readonly map: Map<string, IMediaData>;
|
||||
|
||||
constructor() {
|
||||
this.map = new Map<string, IMediaData>();
|
||||
}
|
||||
|
||||
public getMedia(key: string): IMediaData {
|
||||
const data = this.map.get(key);
|
||||
public addMedia(data: Buffer | string | Uint8Array | ArrayBuffer, transformation: IMediaTransformation): IMediaData {
|
||||
const key = `${uniqueId()}.png`;
|
||||
|
||||
if (data === undefined) {
|
||||
throw new Error(`Cannot find image with the key ${key}`);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public addMedia(buffer: Buffer | string | Uint8Array | ArrayBuffer, transformation: IMediaTransformation): IMediaData {
|
||||
return this.createMedia(`${uniqueId()}.png`, transformation, buffer);
|
||||
}
|
||||
|
||||
private createMedia(
|
||||
key: string,
|
||||
transformation: IMediaTransformation,
|
||||
data: Buffer | string | Uint8Array | ArrayBuffer,
|
||||
filePath?: string,
|
||||
): IMediaData {
|
||||
const newData = typeof data === "string" ? this.convertDataURIToBinary(data) : data;
|
||||
|
||||
const imageData: IMediaData = {
|
||||
stream: newData,
|
||||
path: filePath,
|
||||
fileName: key,
|
||||
transformation: {
|
||||
pixels: {
|
||||
@ -79,14 +47,12 @@ export class Media {
|
||||
return imageData;
|
||||
}
|
||||
|
||||
public addImage(key: string, mediaData: IMediaData): void {
|
||||
this.map.set(key, mediaData);
|
||||
}
|
||||
|
||||
public get Array(): readonly IMediaData[] {
|
||||
const array = new Array<IMediaData>();
|
||||
|
||||
this.map.forEach((data) => {
|
||||
array.push(data);
|
||||
});
|
||||
|
||||
return array;
|
||||
return Array.from(this.map.values());
|
||||
}
|
||||
|
||||
private convertDataURIToBinary(dataURI: string): Uint8Array {
|
||||
|
Reference in New Issue
Block a user