Commit 53064f9f by Edgar HIPP

Add correct es6

parent 8626af91
"use strict";
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
module.exports.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
}
else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
};
"use strict";
var DOMParser = require("xmldom").DOMParser;
var XMLSerializer = require("xmldom").XMLSerializer;
var DocUtils = {};
DocUtils.xml2Str = function (xmlNode) {
var a = new XMLSerializer();
return a.serializeToString(xmlNode);
};
DocUtils.str2xml = function (str, errorHandler) {
var parser = new DOMParser({errorHandler});
return parser.parseFromString(str, "text/xml");
};
DocUtils.maxArray = function (a) { return Math.max.apply(null, a); };
DocUtils.decodeUtf8 = function (s) {
try {
if (s === undefined) { return undefined; }
// replace Ascii 160 space by the normal space, Ascii 32
return decodeURIComponent(escape(DocUtils.convertSpaces(s)));
}
catch (e) {
var err = new Error("End");
err.properties.data = s;
err.properties.explanation = "Could not decode string to UFT8";
throw err;
}
};
DocUtils.encodeUtf8 = function (s) {
return unescape(encodeURIComponent(s));
};
DocUtils.convertSpaces = function (s) {
return s.replace(new RegExp(String.fromCharCode(160), "g"), " ");
};
DocUtils.pregMatchAll = function (regex, content) {
/* regex is a string, content is the content. It returns an array of all matches with their offset, for example:
regex=la
content=lolalolilala
returns: [{0:'la',offset:2},{0:'la',offset:8},{0:'la',offset:10}]
*/
if (typeof regex !== "object") {
regex = (new RegExp(regex, "g"));
}
var matchArray = [];
var replacer = function (...pn) {
pn.pop();
var offset = pn.pop();
// add match so that pn[0] = whole match, pn[1]= first parenthesis,...
pn.offset = offset;
return matchArray.push(pn);
};
content.replace(regex, replacer);
return matchArray;
};
module.exports = DocUtils;
"use strict";
var XmlTemplater = require("docxtemplater").XmlTemplater;
var QrCode = require("qrcode-reader");
module.exports = class DocxQrCode {
constructor(imageData, xmlTemplater, imgName = "", num, getDataFromString) {
this.xmlTemplater = xmlTemplater;
this.imgName = imgName;
this.num = num;
this.getDataFromString = getDataFromString;
this.callbacked = false;
this.data = imageData;
if (this.data === undefined) { throw new Error("data of qrcode can't be undefined"); }
this.ready = false;
this.result = null;
}
decode(callback) {
this.callback = callback;
var self = this;
this.qr = new QrCode();
this.qr.callback = function () {
self.ready = true;
self.result = this.result;
var testdoc = new XmlTemplater(this.result,
{fileTypeConfig: self.xmlTemplater.fileTypeConfig,
tags: self.xmlTemplater.tags,
Tags: self.xmlTemplater.Tags,
parser: self.xmlTemplater.parser,
});
testdoc.render();
self.result = testdoc.content;
return self.searchImage();
};
return this.qr.decode({width: this.data.width, height: this.data.height}, this.data.decoded);
}
searchImage() {
var cb = (_err, data = this.data.data) => {
this.data = data;
return this.callback(this, this.imgName, this.num);
};
if (!(this.result != null)) { return cb(); }
return this.getDataFromString(this.result, cb);
}
};
"use strict";
var DocUtils = require("./docUtils");
var imageExtensions = ["gif", "jpeg", "jpg", "emf", "png"];
module.exports = class ImgManager {
constructor(zip, fileName) {
this.zip = zip;
this.fileName = fileName;
this.endFileName = this.fileName.replace(/^.*?([a-z0-9]+)\.xml$/, "$1");
}
getImageList() {
var regex = / [^.]+ \. ([^.]+) /;
var imageList = [];
Object.keys(this.zip.files).forEach(function (path) {
var extension = path.replace(regex, "$1");
if (imageExtensions.indexOf(extension) >= 0) {
imageList.push({path: path, files: this.zip.files[path]});
}
});
return imageList;
}
setImage(fileName, data, options = {}) {
this.zip.remove(fileName);
return this.zip.file(fileName, data, options);
}
hasImage(fileName) {
return this.zip.files[fileName] != null;
}
loadImageRels() {
var file = this.zip.files[`word/_rels/${this.endFileName}.xml.rels`] || this.zip.files["word/_rels/document.xml.rels"];
if (file === undefined) { return; }
var content = DocUtils.decodeUtf8(file.asText());
this.xmlDoc = DocUtils.str2xml(content);
// Get all Rids
var RidArray = [];
var iterable = this.xmlDoc.getElementsByTagName("Relationship");
for (var i = 0, tag; i < iterable.length; i++) {
tag = iterable[i];
RidArray.push(parseInt(tag.getAttribute("Id").substr(3), 10));
}
this.maxRid = DocUtils.maxArray(RidArray);
this.imageRels = [];
return this;
}
// Add an extension type in the [Content_Types.xml], is used if for example you want word to be able to read png files (for every extension you add you need a contentType)
addExtensionRels(contentType, extension) {
var content = this.zip.files["[Content_Types].xml"].asText();
var xmlDoc = DocUtils.str2xml(content);
var addTag = true;
var defaultTags = xmlDoc.getElementsByTagName("Default");
for (var i = 0, tag; i < defaultTags.length; i++) {
tag = defaultTags[i];
if (tag.getAttribute("Extension") === extension) { addTag = false; }
}
if (addTag) {
var types = xmlDoc.getElementsByTagName("Types")[0];
var newTag = xmlDoc.createElement("Default");
newTag.namespaceURI = null;
newTag.setAttribute("ContentType", contentType);
newTag.setAttribute("Extension", extension);
types.appendChild(newTag);
return this.setImage("[Content_Types].xml", DocUtils.encodeUtf8(DocUtils.xml2Str(xmlDoc)));
}
}
// Adding an image and returns it's Rid
addImageRels(imageName, imageData, i = 0) {
var realImageName = i === 0 ? imageName : imageName + `(${i})`;
if ((this.zip.files[`word/media/${realImageName}`] != null)) {
return this.addImageRels(imageName, imageData, i + 1);
}
this.maxRid++;
var file = {
name: `word/media/${realImageName}`,
data: imageData,
options: {
base64: false,
binary: true,
compression: null,
date: new Date(),
dir: false,
},
};
this.zip.file(file.name, file.data, file.options);
var extension = realImageName.replace(/[^.]+\.([^.]+)/, "$1");
this.addExtensionRels(`image/${extension}`, extension);
var relationships = this.xmlDoc.getElementsByTagName("Relationships")[0];
var newTag = this.xmlDoc.createElement("Relationship");
newTag.namespaceURI = null;
newTag.setAttribute("Id", `rId${this.maxRid}`);
newTag.setAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
newTag.setAttribute("Target", `media/${realImageName}`);
relationships.appendChild(newTag);
this.setImage(`word/_rels/${this.endFileName}.xml.rels`, DocUtils.encodeUtf8(DocUtils.xml2Str(this.xmlDoc)));
return this.maxRid;
}
getImageName(id = 0) {
var nameCandidate = "Copie_" + id + ".png";
var fullPath = this.getFullPath(nameCandidate);
if (this.hasImage(fullPath)) {
return this.getImageName(id + 1);
}
return nameCandidate;
}
getFullPath(imgName) { return `word/media/${imgName}`; }
// This is to get an image by it's rId (returns null if no img was found)
getImageByRid(rId) {
var relationships = this.xmlDoc.getElementsByTagName("Relationship");
for (var i = 0, relationship; i < relationships.length; i++) {
relationship = relationships[i];
var cRId = relationship.getAttribute("Id");
if (rId === cRId) {
var path = relationship.getAttribute("Target");
if (path.substr(0, 6) === "media/") {
return this.zip.files[`word/${path}`];
}
throw new Error("Rid is not an image");
}
}
throw new Error("No Media with this Rid found");
}
};
"use strict";
var DocUtils = require("./docUtils");
var DocxQrCode = require("./docxQrCode");
var PNG = require("png-js");
var base64encode = require("./base64").encode;
module.exports = class ImgReplacer {
constructor(xmlTemplater, imgManager) {
this.xmlTemplater = xmlTemplater;
this.imgManager = imgManager;
this.imageSetter = this.imageSetter.bind(this);
this.imgMatches = [];
this.xmlTemplater.numQrCode = 0;
}
findImages() {
this.imgMatches = DocUtils.pregMatchAll(/<w:drawing[^>]*>.*?<a:blip.r:embed.*?<\/w:drawing>/g, this.xmlTemplater.content);
return this;
}
replaceImages() {
this.qr = [];
this.xmlTemplater.numQrCode += this.imgMatches.length;
var iterable = this.imgMatches;
for (var imgNum = 0, match; imgNum < iterable.length; imgNum++) {
match = iterable[imgNum];
this.replaceImage(match, imgNum);
}
return this;
}
imageSetter(docxqrCode) {
if (docxqrCode.callbacked === true) { return; }
docxqrCode.callbacked = true;
docxqrCode.xmlTemplater.numQrCode--;
this.imgManager.setImage(`word/media/${docxqrCode.imgName}`, docxqrCode.data, {binary: true});
return this.popQrQueue(this.imgManager.fileName + "-" + docxqrCode.num, false);
}
getXmlImg(match) {
var baseDocument = `<?xml version="1.0" ?>
<w:document
mc:Ignorable="w14 wp14"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
xmlns:w10="urn:schemas-microsoft-com:office:word"
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"
xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">${match[0]}</w:document>
`;
var f = function (e) {
if (e === "fatalError") {
throw new Error("fatalError");
}
};
return DocUtils.str2xml(baseDocument, f);
}
replaceImage(match, imgNum) {
var num = parseInt(Math.random() * 10000, 10);
var xmlImg;
try {
xmlImg = this.getXmlImg(match);
}
catch (e) {
return;
}
var tagrId = xmlImg.getElementsByTagName("a:blip")[0];
if (tagrId === undefined) { throw new Error("tagRiD undefined !"); }
var rId = tagrId.getAttribute("r:embed");
var tag = xmlImg.getElementsByTagName("wp:docPr")[0];
if (tag === undefined) { throw new Error("tag undefined"); }
// if image is already a replacement then do nothing
if (tag.getAttribute("name").substr(0, 6) === "Copie_") { return; }
var imgName = this.imgManager.getImageName();
this.pushQrQueue(this.imgManager.fileName + "-" + num, true);
var newId = this.imgManager.addImageRels(imgName, "");
this.xmlTemplater.imageId++;
var oldFile = this.imgManager.getImageByRid(rId);
this.imgManager.setImage(this.imgManager.getFullPath(imgName), oldFile.data, {binary: true});
tag.setAttribute("name", `${imgName}`);
tagrId.setAttribute("r:embed", `rId${newId}`);
var imageTag = xmlImg.getElementsByTagName("w:drawing")[0];
if (imageTag === undefined) { throw new Error("imageTag undefined"); }
var replacement = DocUtils.xml2Str(imageTag);
this.xmlTemplater.content = this.xmlTemplater.content.replace(match[0], replacement);
return this.decodeImage(oldFile, imgName, num, imgNum);
}
decodeImage(oldFile, imgName, num, imgNum) {
var mockedQrCode = {xmlTemplater: this.xmlTemplater, imgName: imgName, data: oldFile.asBinary(), num: num};
if (!/\.png$/.test(oldFile.name)) {
return this.imageSetter(mockedQrCode);
}
return ((imgName) => {
var base64 = base64encode(oldFile.asBinary());
var binaryData = new Buffer(base64, "base64");
var png = new PNG(binaryData);
var finished = (a) => {
png.decoded = a;
try {
this.qr[imgNum] = new DocxQrCode(png, this.xmlTemplater, imgName, num, this.getDataFromString);
return this.qr[imgNum].decode(this.imageSetter);
}
catch (e) {
return this.imageSetter(mockedQrCode);
}
};
return png.decode(finished);
})(imgName);
}
};
"use strict";
var SubContent = require("docxtemplater").SubContent;
var ImgManager = require("./imgManager");
var ImgReplacer = require("./imgReplacer");
class ImageModule {
constructor(options = {}) {
this.options = options;
if (!(this.options.centered != null)) { this.options.centered = false; }
if (!(this.options.getImage != null)) { throw new Error("You should pass getImage"); }
if (!(this.options.getSize != null)) { throw new Error("You should pass getSize"); }
this.qrQueue = [];
this.imageNumber = 1;
}
handleEvent(event, eventData) {
if (event === "rendering-file") {
this.renderingFileName = eventData;
var gen = this.manager.getInstance("gen");
this.imgManager = new ImgManager(gen.zip, this.renderingFileName);
this.imgManager.loadImageRels();
}
if (event === "rendered") {
if (this.qrQueue.length === 0) { return this.finished(); }
}
}
get(data) {
if (data === "loopType") {
var templaterState = this.manager.getInstance("templaterState");
if (templaterState.textInsideTag[0] === "%") {
return "image";
}
}
return null;
}
getNextImageName() {
var name = `image_generated_${this.imageNumber}.png`;
this.imageNumber++;
return name;
}
replaceBy(text, outsideElement) {
var xmlTemplater = this.manager.getInstance("xmlTemplater");
var templaterState = this.manager.getInstance("templaterState");
var subContent = new SubContent(xmlTemplater.content);
subContent = subContent.getInnerTag(templaterState);
subContent = subContent.getOuterXml(outsideElement);
return xmlTemplater.replaceXml(subContent, text);
}
convertPixelsToEmus(pixel) {
return Math.round(pixel * 9525);
}
replaceTag() {
var scopeManager = this.manager.getInstance("scopeManager");
var templaterState = this.manager.getInstance("templaterState");
var xmlTemplater = this.manager.getInstance("xmlTemplater");
var tagXml = xmlTemplater.fileTypeConfig.tagsXmlArray[0];
var tag = templaterState.textInsideTag.substr(1);
var tagValue = scopeManager.getValue(tag);
if (tagValue == null) {
return this.replaceBy(startEnd, tagXml);
}
var tagXmlParagraph = tagXml.substr(0, 1) + ":p";
var startEnd = `<${tagXml}></${tagXml}>`;
var imgBuffer;
try {
imgBuffer = this.options.getImage(tagValue, tag);
}
catch (e) {
return this.replaceBy(startEnd, tagXml);
}
var imageRels = this.imgManager.loadImageRels();
if (!imageRels) {
return;
}
var rId = imageRels.addImageRels(this.getNextImageName(), imgBuffer);
var sizePixel = this.options.getSize(imgBuffer, tagValue, tag);
var size = [this.convertPixelsToEmus(sizePixel[0]), this.convertPixelsToEmus(sizePixel[1])];
var newText = this.options.centered ? this.getImageXmlCentered(rId, size) : this.getImageXml(rId, size);
var outsideElement = this.options.centered ? tagXmlParagraph : tagXml;
return this.replaceBy(newText, outsideElement);
}
replaceQr() {
var xmlTemplater = this.manager.getInstance("xmlTemplater");
var imR = new ImgReplacer(xmlTemplater, this.imgManager);
imR.getDataFromString = (result, cb) => {
if ((this.options.getImageAsync != null)) {
return this.options.getImageAsync(result, cb);
}
return cb(null, this.options.getImage(result));
};
imR.pushQrQueue = (num) => {
return this.qrQueue.push(num);
};
imR.popQrQueue = (num) => {
var found = this.qrQueue.indexOf(num);
if (found !== -1) {
this.qrQueue.splice(found, 1);
}
else {
this.on("error", new Error(`qrqueue ${num} is not in qrqueue`));
}
if (this.qrQueue.length === 0) { return this.finished(); }
};
var num = parseInt(Math.random() * 10000, 10);
imR.pushQrQueue("rendered-" + num);
try {
imR.findImages().replaceImages();
}
catch (e) {
this.on("error", e);
}
var f = () => imR.popQrQueue("rendered-" + num);
return setTimeout(f, 1);
}
finished() {}
on(event, data) {
if (event === "error") {
throw data;
}
}
handle(type, data) {
if (type === "replaceTag" && data === "image") {
this.replaceTag();
}
if (type === "xmlRendered" && this.options.qrCode) {
this.replaceQr();
}
return null;
}
getImageXml(rId, size) {
return `<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="${size[0]}" cy="${size[1]}"/>
<wp:effectExtent l="0" t="0" r="0" b="0"/>
<wp:docPr id="2" name="Image 2" descr="image"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture 1" descr="image"/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId${rId}">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="${size[0]}" cy="${size[1]}"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
`;
}
getImageXmlCentered(rId, size) {
return ` <w:p>
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:rPr/>
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="${size[0]}" cy="${size[1]}"/>
<wp:docPr id="0" name="Picture" descr=""/>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="Picture" descr=""/>
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1" noChangeArrowheads="1"/>
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId${rId}"/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="${size[0]}" cy="${size[1]}"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:noFill/>
<a:ln w="9525">
<a:noFill/>
<a:miter lim="800000"/>
<a:headEnd/>
<a:tailEnd/>
</a:ln>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>
</w:p>
`;
}
}
module.exports = ImageModule;
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment