Commit b0833136 by Edgar HIPP

Fix for issue with null tags

parent ad79e03e
...@@ -73,7 +73,6 @@ ...@@ -73,7 +73,6 @@
"no-duplicate-case": 2, "no-duplicate-case": 2,
"no-else-return": 2, "no-else-return": 2,
"no-empty": 2, "no-empty": 2,
"no-empty-label": 2,
"no-empty-character-class": 2, "no-empty-character-class": 2,
"no-eval": 2, "no-eval": 2,
"no-ex-assign": 2, "no-ex-assign": 2,
...@@ -113,15 +112,14 @@ ...@@ -113,15 +112,14 @@
"no-obj-calls": 2, "no-obj-calls": 2,
"no-octal": 2, "no-octal": 2,
"no-octal-escape": 2, "no-octal-escape": 2,
"no-param-reassign": 0,
"no-path-concat": 2, "no-path-concat": 2,
"no-process-env": 2, "no-process-env": 2,
"no-process-exit": 2, "no-process-exit": 2,
"no-proto": 2, "no-proto": 2,
"no-redeclare": 2, "no-redeclare": 2,
"no-regex-spaces": 2, "no-regex-spaces": 2,
"no-restricted-modules": 0, "no-restricted-modules": 2,
"no-restricted-syntax": 0, "no-restricted-syntax": 2,
"no-return-assign": 2, "no-return-assign": 2,
"no-script-url": 2, "no-script-url": 2,
"no-self-compare": 2, "no-self-compare": 2,
...@@ -136,17 +134,16 @@ ...@@ -136,17 +134,16 @@
"no-trailing-spaces": 2, "no-trailing-spaces": 2,
"no-undef": 2, "no-undef": 2,
"no-undef-init": 0, "no-undef-init": 0,
"no-undefined": 0,
"no-underscore-dangle": 0, "no-underscore-dangle": 0,
"no-unexpected-multiline": 2, "no-unexpected-multiline": 2,
"no-unneeded-ternary": 2, "no-unneeded-ternary": 2,
"no-unreachable": 2, "no-unreachable": 2,
"no-unused-expressions": 2, "no-unused-expressions": 2,
"no-unused-vars": 2, "no-unused-vars": 2,
"no-use-before-define": [2, "nofunc"], "no-use-before-define": ["error", { "functions" : true }],
"no-useless-call": 2, "no-useless-call": 2,
"no-useless-concat": 2, "no-useless-concat": 2,
"no-var": 0, "no-var": 2,
"no-void": 2, "no-void": 2,
"no-warning-comments": [2, {"terms": ["todo", "fixme"], "location": "anywhere"}], "no-warning-comments": [2, {"terms": ["todo", "fixme"], "location": "anywhere"}],
"no-with": 2, "no-with": 2,
...@@ -172,10 +169,9 @@ ...@@ -172,10 +169,9 @@
"space-before-blocks": 2, "space-before-blocks": 2,
"space-before-keywords": 0, "space-before-keywords": 0,
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
"space-after-keywords": 2, "keyword-spacing": 2,
"space-in-parens": [2, "never"], "space-in-parens": [2, "never"],
"space-infix-ops": 2, "space-infix-ops": 2,
"space-return-throw-case": 2,
"space-unary-ops": [2, {"words": true, "nonwords": false}], "space-unary-ops": [2, {"words": true, "nonwords": false}],
"spaced-comment": [2, "always"], "spaced-comment": [2, "always"],
"use-isnan": 2, "use-isnan": 2,
......
"use strict"; "use strict";
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding // public method for encoding
module.exports.encode = function (input) { module.exports.encode = function (input) {
var output = ""; let output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4; let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0; let i = 0;
while (i < input.length) { while (i < input.length) {
chr1 = input.charCodeAt(i++); chr1 = input.charCodeAt(i++);
......
"use strict"; "use strict";
var DOMParser = require("xmldom").DOMParser; const DOMParser = require("xmldom").DOMParser;
var XMLSerializer = require("xmldom").XMLSerializer; const XMLSerializer = require("xmldom").XMLSerializer;
const DocUtils = {};
var DocUtils = {};
DocUtils.xml2Str = function (xmlNode) { DocUtils.xml2Str = function (xmlNode) {
var a = new XMLSerializer(); const a = new XMLSerializer();
return a.serializeToString(xmlNode); return a.serializeToString(xmlNode);
}; };
DocUtils.str2xml = function (str, errorHandler) { DocUtils.str2xml = function (str, errorHandler) {
var parser = new DOMParser({errorHandler}); const parser = new DOMParser({errorHandler});
return parser.parseFromString(str, "text/xml"); return parser.parseFromString(str, "text/xml");
}; };
...@@ -24,7 +23,7 @@ DocUtils.decodeUtf8 = function (s) { ...@@ -24,7 +23,7 @@ DocUtils.decodeUtf8 = function (s) {
return decodeURIComponent(escape(DocUtils.convertSpaces(s))); return decodeURIComponent(escape(DocUtils.convertSpaces(s)));
} }
catch (e) { catch (e) {
var err = new Error("End"); const err = new Error("End");
err.properties.data = s; err.properties.data = s;
err.properties.explanation = "Could not decode string to UFT8"; err.properties.explanation = "Could not decode string to UFT8";
throw err; throw err;
...@@ -43,15 +42,16 @@ DocUtils.pregMatchAll = function (regex, content) { ...@@ -43,15 +42,16 @@ 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 is a string, content is the content. It returns an array of all matches with their offset, for example:
regex=la regex=la
content=lolalolilala content=lolalolilala
returns: [{0:'la',offset:2},{0:'la',offset:8},{0:'la',offset:10}] returns: [{0: 'la',offset: 2},{0: 'la',offset: 8},{0: 'la',offset: 10}]
*/ */
if (typeof regex !== "object") { if (typeof regex !== "object") {
regex = (new RegExp(regex, "g")); regex = (new RegExp(regex, "g"));
} }
var matchArray = []; const matchArray = [];
var replacer = function (...pn) { const replacer = function () {
const pn = Array.prototype.slice.call(arguments);
pn.pop(); pn.pop();
var offset = pn.pop(); const offset = pn.pop();
// add match so that pn[0] = whole match, pn[1]= first parenthesis,... // add match so that pn[0] = whole match, pn[1]= first parenthesis,...
pn.offset = offset; pn.offset = offset;
return matchArray.push(pn); return matchArray.push(pn);
......
"use strict"; "use strict";
var XmlTemplater = require("docxtemplater").XmlTemplater; const XmlTemplater = require("docxtemplater").XmlTemplater;
const QrCode = require("qrcode-reader");
var QrCode = require("qrcode-reader");
module.exports = class DocxQrCode { module.exports = class DocxQrCode {
constructor(imageData, xmlTemplater, imgName = "", num, getDataFromString) { constructor(imageData, xmlTemplater, imgName, num, getDataFromString) {
this.xmlTemplater = xmlTemplater; this.xmlTemplater = xmlTemplater;
this.imgName = imgName; this.imgName = imgName || "";
this.num = num; this.num = num;
this.getDataFromString = getDataFromString; this.getDataFromString = getDataFromString;
this.callbacked = false; this.callbacked = false;
...@@ -18,12 +17,12 @@ module.exports = class DocxQrCode { ...@@ -18,12 +17,12 @@ module.exports = class DocxQrCode {
} }
decode(callback) { decode(callback) {
this.callback = callback; this.callback = callback;
var self = this; const self = this;
this.qr = new QrCode(); this.qr = new QrCode();
this.qr.callback = function () { this.qr.callback = function () {
self.ready = true; self.ready = true;
self.result = this.result; self.result = this.result;
var testdoc = new XmlTemplater(this.result, const testdoc = new XmlTemplater(this.result,
{fileTypeConfig: self.xmlTemplater.fileTypeConfig, {fileTypeConfig: self.xmlTemplater.fileTypeConfig,
tags: self.xmlTemplater.tags, tags: self.xmlTemplater.tags,
Tags: self.xmlTemplater.Tags, Tags: self.xmlTemplater.Tags,
...@@ -36,8 +35,8 @@ module.exports = class DocxQrCode { ...@@ -36,8 +35,8 @@ module.exports = class DocxQrCode {
return this.qr.decode({width: this.data.width, height: this.data.height}, this.data.decoded); return this.qr.decode({width: this.data.width, height: this.data.height}, this.data.decoded);
} }
searchImage() { searchImage() {
var cb = (_err, data = this.data.data) => { const cb = (_err, data) => {
this.data = data; this.data = data || this.data.data;
return this.callback(this, this.imgName, this.num); return this.callback(this, this.imgName, this.num);
}; };
if (!(this.result != null)) { return cb(); } if (!(this.result != null)) { return cb(); }
......
"use strict"; "use strict";
var DocUtils = require("./docUtils"); const DocUtils = require("./docUtils");
var imageExtensions = ["gif", "jpeg", "jpg", "emf", "png"]; const imageExtensions = ["gif", "jpeg", "jpg", "emf", "png"];
const imageListRegex = /[^.]+\.([^.]+)/;
module.exports = class ImgManager { module.exports = class ImgManager {
constructor(zip, fileName) { constructor(zip, fileName) {
...@@ -11,17 +12,17 @@ module.exports = class ImgManager { ...@@ -11,17 +12,17 @@ module.exports = class ImgManager {
this.endFileName = this.fileName.replace(/^.*?([a-z0-9]+)\.xml$/, "$1"); this.endFileName = this.fileName.replace(/^.*?([a-z0-9]+)\.xml$/, "$1");
} }
getImageList() { getImageList() {
var regex = / [^.]+ \. ([^.]+) /; const imageList = [];
var imageList = [];
Object.keys(this.zip.files).forEach(function (path) { Object.keys(this.zip.files).forEach(function (path) {
var extension = path.replace(regex, "$1"); const extension = path.replace(imageListRegex, "$1");
if (imageExtensions.indexOf(extension) >= 0) { if (imageExtensions.indexOf(extension) >= 0) {
imageList.push({path: path, files: this.zip.files[path]}); imageList.push({path: path, files: this.zip.files[path]});
} }
}); });
return imageList; return imageList;
} }
setImage(fileName, data, options = {}) { setImage(fileName, data, options) {
options = options || {};
this.zip.remove(fileName); this.zip.remove(fileName);
return this.zip.file(fileName, data, options); return this.zip.file(fileName, data, options);
} }
...@@ -29,14 +30,14 @@ module.exports = class ImgManager { ...@@ -29,14 +30,14 @@ module.exports = class ImgManager {
return this.zip.files[fileName] != null; return this.zip.files[fileName] != null;
} }
loadImageRels() { loadImageRels() {
var file = this.zip.files[`word/_rels/${this.endFileName}.xml.rels`] || this.zip.files["word/_rels/document.xml.rels"]; const file = this.zip.files[`word/_rels/${this.endFileName}.xml.rels`] || this.zip.files["word/_rels/document.xml.rels"];
if (file === undefined) { return; } if (file === undefined) { return; }
var content = DocUtils.decodeUtf8(file.asText()); const content = DocUtils.decodeUtf8(file.asText());
this.xmlDoc = DocUtils.str2xml(content); this.xmlDoc = DocUtils.str2xml(content);
// Get all Rids // Get all Rids
var RidArray = []; const RidArray = [];
var iterable = this.xmlDoc.getElementsByTagName("Relationship"); const iterable = this.xmlDoc.getElementsByTagName("Relationship");
for (var i = 0, tag; i < iterable.length; i++) { for (let i = 0, tag; i < iterable.length; i++) {
tag = iterable[i]; tag = iterable[i];
RidArray.push(parseInt(tag.getAttribute("Id").substr(3), 10)); RidArray.push(parseInt(tag.getAttribute("Id").substr(3), 10));
} }
...@@ -46,17 +47,17 @@ module.exports = class ImgManager { ...@@ -46,17 +47,17 @@ module.exports = class ImgManager {
} }
// 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) // 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) { addExtensionRels(contentType, extension) {
var content = this.zip.files["[Content_Types].xml"].asText(); const content = this.zip.files["[Content_Types].xml"].asText();
var xmlDoc = DocUtils.str2xml(content); const xmlDoc = DocUtils.str2xml(content);
var addTag = true; let addTag = true;
var defaultTags = xmlDoc.getElementsByTagName("Default"); const defaultTags = xmlDoc.getElementsByTagName("Default");
for (var i = 0, tag; i < defaultTags.length; i++) { for (let i = 0, tag; i < defaultTags.length; i++) {
tag = defaultTags[i]; tag = defaultTags[i];
if (tag.getAttribute("Extension") === extension) { addTag = false; } if (tag.getAttribute("Extension") === extension) { addTag = false; }
} }
if (addTag) { if (addTag) {
var types = xmlDoc.getElementsByTagName("Types")[0]; const types = xmlDoc.getElementsByTagName("Types")[0];
var newTag = xmlDoc.createElement("Default"); const newTag = xmlDoc.createElement("Default");
newTag.namespaceURI = null; newTag.namespaceURI = null;
newTag.setAttribute("ContentType", contentType); newTag.setAttribute("ContentType", contentType);
newTag.setAttribute("Extension", extension); newTag.setAttribute("Extension", extension);
...@@ -65,13 +66,16 @@ module.exports = class ImgManager { ...@@ -65,13 +66,16 @@ module.exports = class ImgManager {
} }
} }
// Adding an image and returns it's Rid // Adding an image and returns it's Rid
addImageRels(imageName, imageData, i = 0) { addImageRels(imageName, imageData, i) {
var realImageName = i === 0 ? imageName : imageName + `(${i})`; if (i == null) {
i = 0;
}
const realImageName = i === 0 ? imageName : imageName + `(${i})`;
if ((this.zip.files[`word/media/${realImageName}`] != null)) { if ((this.zip.files[`word/media/${realImageName}`] != null)) {
return this.addImageRels(imageName, imageData, i + 1); return this.addImageRels(imageName, imageData, i + 1);
} }
this.maxRid++; this.maxRid++;
var file = { const file = {
name: `word/media/${realImageName}`, name: `word/media/${realImageName}`,
data: imageData, data: imageData,
options: { options: {
...@@ -83,10 +87,10 @@ module.exports = class ImgManager { ...@@ -83,10 +87,10 @@ module.exports = class ImgManager {
}, },
}; };
this.zip.file(file.name, file.data, file.options); this.zip.file(file.name, file.data, file.options);
var extension = realImageName.replace(/[^.]+\.([^.]+)/, "$1"); const extension = realImageName.replace(/[^.]+\.([^.]+)/, "$1");
this.addExtensionRels(`image/${extension}`, extension); this.addExtensionRels(`image/${extension}`, extension);
var relationships = this.xmlDoc.getElementsByTagName("Relationships")[0]; const relationships = this.xmlDoc.getElementsByTagName("Relationships")[0];
var newTag = this.xmlDoc.createElement("Relationship"); const newTag = this.xmlDoc.createElement("Relationship");
newTag.namespaceURI = null; newTag.namespaceURI = null;
newTag.setAttribute("Id", `rId${this.maxRid}`); newTag.setAttribute("Id", `rId${this.maxRid}`);
newTag.setAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"); newTag.setAttribute("Type", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image");
...@@ -95,9 +99,10 @@ module.exports = class ImgManager { ...@@ -95,9 +99,10 @@ module.exports = class ImgManager {
this.setImage(`word/_rels/${this.endFileName}.xml.rels`, DocUtils.encodeUtf8(DocUtils.xml2Str(this.xmlDoc))); this.setImage(`word/_rels/${this.endFileName}.xml.rels`, DocUtils.encodeUtf8(DocUtils.xml2Str(this.xmlDoc)));
return this.maxRid; return this.maxRid;
} }
getImageName(id = 0) { getImageName(id) {
var nameCandidate = "Copie_" + id + ".png"; id = id || 0;
var fullPath = this.getFullPath(nameCandidate); const nameCandidate = "Copie_" + id + ".png";
const fullPath = this.getFullPath(nameCandidate);
if (this.hasImage(fullPath)) { if (this.hasImage(fullPath)) {
return this.getImageName(id + 1); return this.getImageName(id + 1);
} }
...@@ -106,12 +111,12 @@ module.exports = class ImgManager { ...@@ -106,12 +111,12 @@ module.exports = class ImgManager {
getFullPath(imgName) { return `word/media/${imgName}`; } getFullPath(imgName) { return `word/media/${imgName}`; }
// This is to get an image by it's rId (returns null if no img was found) // This is to get an image by it's rId (returns null if no img was found)
getImageByRid(rId) { getImageByRid(rId) {
var relationships = this.xmlDoc.getElementsByTagName("Relationship"); const relationships = this.xmlDoc.getElementsByTagName("Relationship");
for (var i = 0, relationship; i < relationships.length; i++) { for (let i = 0, relationship; i < relationships.length; i++) {
relationship = relationships[i]; relationship = relationships[i];
var cRId = relationship.getAttribute("Id"); const cRId = relationship.getAttribute("Id");
if (rId === cRId) { if (rId === cRId) {
var path = relationship.getAttribute("Target"); const path = relationship.getAttribute("Target");
if (path.substr(0, 6) === "media/") { if (path.substr(0, 6) === "media/") {
return this.zip.files[`word/${path}`]; return this.zip.files[`word/${path}`];
} }
......
"use strict"; "use strict";
var DocUtils = require("./docUtils"); const DocUtils = require("./docUtils");
var DocxQrCode = require("./docxQrCode"); const DocxQrCode = require("./docxQrCode");
var PNG = require("png-js"); const PNG = require("png-js");
var base64encode = require("./base64").encode; const base64encode = require("./base64").encode;
module.exports = class ImgReplacer { module.exports = class ImgReplacer {
constructor(xmlTemplater, imgManager) { constructor(xmlTemplater, imgManager) {
...@@ -20,8 +20,8 @@ module.exports = class ImgReplacer { ...@@ -20,8 +20,8 @@ module.exports = class ImgReplacer {
replaceImages() { replaceImages() {
this.qr = []; this.qr = [];
this.xmlTemplater.numQrCode += this.imgMatches.length; this.xmlTemplater.numQrCode += this.imgMatches.length;
var iterable = this.imgMatches; const iterable = this.imgMatches;
for (var imgNum = 0, match; imgNum < iterable.length; imgNum++) { for (let imgNum = 0, match; imgNum < iterable.length; imgNum++) {
match = iterable[imgNum]; match = iterable[imgNum];
this.replaceImage(match, imgNum); this.replaceImage(match, imgNum);
} }
...@@ -35,7 +35,7 @@ module.exports = class ImgReplacer { ...@@ -35,7 +35,7 @@ module.exports = class ImgReplacer {
return this.popQrQueue(this.imgManager.fileName + "-" + docxqrCode.num, false); return this.popQrQueue(this.imgManager.fileName + "-" + docxqrCode.num, false);
} }
getXmlImg(match) { getXmlImg(match) {
var baseDocument = `<?xml version="1.0" ?> const baseDocument = `<?xml version="1.0" ?>
<w:document <w:document
mc:Ignorable="w14 wp14" mc:Ignorable="w14 wp14"
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
...@@ -54,7 +54,7 @@ module.exports = class ImgReplacer { ...@@ -54,7 +54,7 @@ module.exports = class ImgReplacer {
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">${match[0]}</w:document> xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">${match[0]}</w:document>
`; `;
var f = function (e) { const f = function (e) {
if (e === "fatalError") { if (e === "fatalError") {
throw new Error("fatalError"); throw new Error("fatalError");
} }
...@@ -62,46 +62,46 @@ module.exports = class ImgReplacer { ...@@ -62,46 +62,46 @@ module.exports = class ImgReplacer {
return DocUtils.str2xml(baseDocument, f); return DocUtils.str2xml(baseDocument, f);
} }
replaceImage(match, imgNum) { replaceImage(match, imgNum) {
var num = parseInt(Math.random() * 10000, 10); const num = parseInt(Math.random() * 10000, 10);
var xmlImg; let xmlImg;
try { try {
xmlImg = this.getXmlImg(match); xmlImg = this.getXmlImg(match);
} }
catch (e) { catch (e) {
return; return;
} }
var tagrId = xmlImg.getElementsByTagName("a:blip")[0]; const tagrId = xmlImg.getElementsByTagName("a:blip")[0];
if (tagrId === undefined) { throw new Error("tagRiD undefined !"); } if (tagrId === undefined) { throw new Error("tagRiD undefined !"); }
var rId = tagrId.getAttribute("r:embed"); const rId = tagrId.getAttribute("r:embed");
var tag = xmlImg.getElementsByTagName("wp:docPr")[0]; const tag = xmlImg.getElementsByTagName("wp:docPr")[0];
if (tag === undefined) { throw new Error("tag undefined"); } if (tag === undefined) { throw new Error("tag undefined"); }
// if image is already a replacement then do nothing // if image is already a replacement then do nothing
if (tag.getAttribute("name").substr(0, 6) === "Copie_") { return; } if (tag.getAttribute("name").substr(0, 6) === "Copie_") { return; }
var imgName = this.imgManager.getImageName(); const imgName = this.imgManager.getImageName();
this.pushQrQueue(this.imgManager.fileName + "-" + num, true); this.pushQrQueue(this.imgManager.fileName + "-" + num, true);
var newId = this.imgManager.addImageRels(imgName, ""); const newId = this.imgManager.addImageRels(imgName, "");
this.xmlTemplater.imageId++; this.xmlTemplater.imageId++;
var oldFile = this.imgManager.getImageByRid(rId); const oldFile = this.imgManager.getImageByRid(rId);
this.imgManager.setImage(this.imgManager.getFullPath(imgName), oldFile.data, {binary: true}); this.imgManager.setImage(this.imgManager.getFullPath(imgName), oldFile.data, {binary: true});
tag.setAttribute("name", `${imgName}`); tag.setAttribute("name", `${imgName}`);
tagrId.setAttribute("r:embed", `rId${newId}`); tagrId.setAttribute("r:embed", `rId${newId}`);
var imageTag = xmlImg.getElementsByTagName("w:drawing")[0]; const imageTag = xmlImg.getElementsByTagName("w:drawing")[0];
if (imageTag === undefined) { throw new Error("imageTag undefined"); } if (imageTag === undefined) { throw new Error("imageTag undefined"); }
var replacement = DocUtils.xml2Str(imageTag); const replacement = DocUtils.xml2Str(imageTag);
this.xmlTemplater.content = this.xmlTemplater.content.replace(match[0], replacement); this.xmlTemplater.content = this.xmlTemplater.content.replace(match[0], replacement);
return this.decodeImage(oldFile, imgName, num, imgNum); return this.decodeImage(oldFile, imgName, num, imgNum);
} }
decodeImage(oldFile, imgName, num, imgNum) { decodeImage(oldFile, imgName, num, imgNum) {
var mockedQrCode = {xmlTemplater: this.xmlTemplater, imgName: imgName, data: oldFile.asBinary(), num: num}; const mockedQrCode = {xmlTemplater: this.xmlTemplater, imgName: imgName, data: oldFile.asBinary(), num: num};
if (!/\.png$/.test(oldFile.name)) { if (!/\.png$/.test(oldFile.name)) {
return this.imageSetter(mockedQrCode); return this.imageSetter(mockedQrCode);
} }
return ((imgName) => { return ((imgName) => {
var base64 = base64encode(oldFile.asBinary()); const base64 = base64encode(oldFile.asBinary());
var binaryData = new Buffer(base64, "base64"); const binaryData = new Buffer(base64, "base64");
var png = new PNG(binaryData); const png = new PNG(binaryData);
var finished = (a) => { const finished = (a) => {
png.decoded = a; png.decoded = a;
try { try {
this.qr[imgNum] = new DocxQrCode(png, this.xmlTemplater, imgName, num, this.getDataFromString); this.qr[imgNum] = new DocxQrCode(png, this.xmlTemplater, imgName, num, this.getDataFromString);
......
"use strict"; "use strict";
var SubContent = require("docxtemplater").SubContent; const SubContent = require("docxtemplater").SubContent;
var ImgManager = require("./imgManager"); const ImgManager = require("./imgManager");
var ImgReplacer = require("./imgReplacer"); const ImgReplacer = require("./imgReplacer");
class ImageModule { class ImageModule {
constructor(options = {}) { constructor(options) {
this.options = options; this.options = options || {};
if (!(this.options.centered != null)) { this.options.centered = false; } if (!(this.options.centered != null)) { this.options.centered = false; }
if (!(this.options.getImage != null)) { throw new Error("You should pass getImage"); } if (!(this.options.getImage != null)) { throw new Error("You should pass getImage"); }
if (!(this.options.getSize != null)) { throw new Error("You should pass getSize"); } if (!(this.options.getSize != null)) { throw new Error("You should pass getSize"); }
...@@ -16,7 +16,7 @@ class ImageModule { ...@@ -16,7 +16,7 @@ class ImageModule {
handleEvent(event, eventData) { handleEvent(event, eventData) {
if (event === "rendering-file") { if (event === "rendering-file") {
this.renderingFileName = eventData; this.renderingFileName = eventData;
var gen = this.manager.getInstance("gen"); const gen = this.manager.getInstance("gen");
this.imgManager = new ImgManager(gen.zip, this.renderingFileName); this.imgManager = new ImgManager(gen.zip, this.renderingFileName);
this.imgManager.loadImageRels(); this.imgManager.loadImageRels();
} }
...@@ -26,7 +26,7 @@ class ImageModule { ...@@ -26,7 +26,7 @@ class ImageModule {
} }
get(data) { get(data) {
if (data === "loopType") { if (data === "loopType") {
var templaterState = this.manager.getInstance("templaterState"); const templaterState = this.manager.getInstance("templaterState");
if (templaterState.textInsideTag[0] === "%") { if (templaterState.textInsideTag[0] === "%") {
return "image"; return "image";
} }
...@@ -34,14 +34,14 @@ class ImageModule { ...@@ -34,14 +34,14 @@ class ImageModule {
return null; return null;
} }
getNextImageName() { getNextImageName() {
var name = `image_generated_${this.imageNumber}.png`; const name = `image_generated_${this.imageNumber}.png`;
this.imageNumber++; this.imageNumber++;
return name; return name;
} }
replaceBy(text, outsideElement) { replaceBy(text, outsideElement) {
var xmlTemplater = this.manager.getInstance("xmlTemplater"); const xmlTemplater = this.manager.getInstance("xmlTemplater");
var templaterState = this.manager.getInstance("templaterState"); const templaterState = this.manager.getInstance("templaterState");
var subContent = new SubContent(xmlTemplater.content); let subContent = new SubContent(xmlTemplater.content);
subContent = subContent.getInnerTag(templaterState); subContent = subContent.getInnerTag(templaterState);
subContent = subContent.getOuterXml(outsideElement); subContent = subContent.getOuterXml(outsideElement);
return xmlTemplater.replaceXml(subContent, text); return xmlTemplater.replaceXml(subContent, text);
...@@ -50,42 +50,41 @@ class ImageModule { ...@@ -50,42 +50,41 @@ class ImageModule {
return Math.round(pixel * 9525); return Math.round(pixel * 9525);
} }
replaceTag() { replaceTag() {
var scopeManager = this.manager.getInstance("scopeManager"); const scopeManager = this.manager.getInstance("scopeManager");
var templaterState = this.manager.getInstance("templaterState"); const templaterState = this.manager.getInstance("templaterState");
var xmlTemplater = this.manager.getInstance("xmlTemplater"); const xmlTemplater = this.manager.getInstance("xmlTemplater");
var tagXml = xmlTemplater.fileTypeConfig.tagsXmlArray[0]; const tagXml = xmlTemplater.fileTypeConfig.tagsXmlArray[0];
const tagXmlParagraph = tagXml.substr(0, 1) + ":p";
var tag = templaterState.textInsideTag.substr(1); const tag = templaterState.textInsideTag.substr(1);
var tagValue = scopeManager.getValue(tag); const tagValue = scopeManager.getValue(tag);
const startEnd = `<${tagXml}></${tagXml}>`;
const outsideElement = this.options.centered ? tagXmlParagraph : tagXml;
if (tagValue == null) { if (tagValue == null) {
return this.replaceBy(startEnd, tagXml); return this.replaceBy(startEnd, tagXml);
} }
var tagXmlParagraph = tagXml.substr(0, 1) + ":p"; let imgBuffer;
var startEnd = `<${tagXml}></${tagXml}>`;
var imgBuffer;
try { try {
imgBuffer = this.options.getImage(tagValue, tag); imgBuffer = this.options.getImage(tagValue, tag);
} }
catch (e) { catch (e) {
return this.replaceBy(startEnd, tagXml); return this.replaceBy(startEnd, tagXml);
} }
var imageRels = this.imgManager.loadImageRels(); const imageRels = this.imgManager.loadImageRels();
if (!imageRels) { if (!imageRels) {
return; return;
} }
var rId = imageRels.addImageRels(this.getNextImageName(), imgBuffer); const rId = imageRels.addImageRels(this.getNextImageName(), imgBuffer);
var sizePixel = this.options.getSize(imgBuffer, tagValue, tag); const sizePixel = this.options.getSize(imgBuffer, tagValue, tag);
var size = [this.convertPixelsToEmus(sizePixel[0]), this.convertPixelsToEmus(sizePixel[1])]; const size = [this.convertPixelsToEmus(sizePixel[0]), this.convertPixelsToEmus(sizePixel[1])];
var newText = this.options.centered ? this.getImageXmlCentered(rId, size) : this.getImageXml(rId, size); const newText = this.options.centered ? this.getImageXmlCentered(rId, size) : this.getImageXml(rId, size);
var outsideElement = this.options.centered ? tagXmlParagraph : tagXml;
return this.replaceBy(newText, outsideElement); return this.replaceBy(newText, outsideElement);
} }
replaceQr() { replaceQr() {
var xmlTemplater = this.manager.getInstance("xmlTemplater"); const xmlTemplater = this.manager.getInstance("xmlTemplater");
var imR = new ImgReplacer(xmlTemplater, this.imgManager); const imR = new ImgReplacer(xmlTemplater, this.imgManager);
imR.getDataFromString = (result, cb) => { imR.getDataFromString = (result, cb) => {
if ((this.options.getImageAsync != null)) { if ((this.options.getImageAsync != null)) {
return this.options.getImageAsync(result, cb); return this.options.getImageAsync(result, cb);
...@@ -96,7 +95,7 @@ class ImageModule { ...@@ -96,7 +95,7 @@ class ImageModule {
return this.qrQueue.push(num); return this.qrQueue.push(num);
}; };
imR.popQrQueue = (num) => { imR.popQrQueue = (num) => {
var found = this.qrQueue.indexOf(num); const found = this.qrQueue.indexOf(num);
if (found !== -1) { if (found !== -1) {
this.qrQueue.splice(found, 1); this.qrQueue.splice(found, 1);
} }
...@@ -105,7 +104,7 @@ class ImageModule { ...@@ -105,7 +104,7 @@ class ImageModule {
} }
if (this.qrQueue.length === 0) { return this.finished(); } if (this.qrQueue.length === 0) { return this.finished(); }
}; };
var num = parseInt(Math.random() * 10000, 10); const num = parseInt(Math.random() * 10000, 10);
imR.pushQrQueue("rendered-" + num); imR.pushQrQueue("rendered-" + num);
try { try {
imR.findImages().replaceImages(); imR.findImages().replaceImages();
...@@ -113,7 +112,7 @@ class ImageModule { ...@@ -113,7 +112,7 @@ class ImageModule {
catch (e) { catch (e) {
this.on("error", e); this.on("error", e);
} }
var f = () => imR.popQrQueue("rendered-" + num); const f = () => imR.popQrQueue("rendered-" + num);
return setTimeout(f, 1); return setTimeout(f, 1);
} }
finished() {} finished() {}
......
"use strict"; "use strict";
var fs = require("fs"); const fs = require("fs");
var DocxGen = require("docxtemplater"); const DocxGen = require("docxtemplater");
var expect = require("chai").expect; const expect = require("chai").expect;
var path = require("path"); const path = require("path");
var fileNames = [ const fileNames = [
"imageAfterLoop.docx", "imageAfterLoop.docx",
"imageExample.docx", "imageExample.docx",
"imageHeaderFooterExample.docx", "imageHeaderFooterExample.docx",
...@@ -16,9 +16,31 @@ var fileNames = [ ...@@ -16,9 +16,31 @@ var fileNames = [
"qrExample2.docx", "qrExample2.docx",
"qrHeader.docx", "qrHeader.docx",
"qrHeaderNoImage.docx", "qrHeaderNoImage.docx",
"expectedNoImage.docx",
]; ];
var opts = null; const shouldBeSame = function (zip1, zip2) {
if (typeof zip1 === "string") {
zip1 = new DocxGen(docX[zip1].loadedContent).getZip();
}
if (typeof zip2 === "string") {
zip2 = new DocxGen(docX[zip2].loadedContent).getZip();
}
return (() => {
const result = [];
Object.keys(zip1.files).map(function (filePath) {
expect(zip1.files[filePath].options.date).not.to.be.equal(zip2.files[filePath].options.date, "Date differs");
expect(zip1.files[filePath].name).to.be.equal(zip2.files[filePath].name, "Name differs");
expect(zip1.files[filePath].options.dir).to.be.equal(zip2.files[filePath].options.dir, "IsDir differs");
expect(zip1.files[filePath].asText().length).to.be.equal(zip2.files[filePath].asText().length, "Content differs");
result.push(expect(zip1.files[filePath].asText()).to.be.equal(zip2.files[filePath].asText(), "Content differs"));
});
return result;
})();
};
let opts = null;
beforeEach(function () { beforeEach(function () {
opts = {}; opts = {};
opts.getImage = function (tagValue) { opts.getImage = function (tagValue) {
...@@ -30,21 +52,21 @@ beforeEach(function () { ...@@ -30,21 +52,21 @@ beforeEach(function () {
opts.centered = false; opts.centered = false;
}); });
var ImageModule = require("../js/index.js"); const ImageModule = require("./index.js");
var docX = {}; const docX = {};
var stripNonNormalCharacters = (string) => { const stripNonNormalCharacters = (string) => {
return string.replace(/\n|\r|\t/g, ""); return string.replace(/\n|\r|\t/g, "");
}; };
var expectNormalCharacters = (string1, string2) => { const expectNormalCharacters = (string1, string2) => {
return expect(stripNonNormalCharacters(string1)).to.be.equal(stripNonNormalCharacters(string2)); return expect(stripNonNormalCharacters(string1)).to.be.equal(stripNonNormalCharacters(string2));
}; };
var loadFile = function (name) { const loadFile = function (name) {
if ((fs.readFileSync != null)) { return fs.readFileSync(path.resolve(__dirname, "..", "examples", name), "binary"); } if ((fs.readFileSync != null)) { return fs.readFileSync(path.resolve(__dirname, "..", "examples", name), "binary"); }
var xhrDoc = new XMLHttpRequest(); const xhrDoc = new XMLHttpRequest();
xhrDoc.open("GET", "../examples/" + name, false); xhrDoc.open("GET", "../examples/" + name, false);
if (xhrDoc.overrideMimeType) { if (xhrDoc.overrideMimeType) {
xhrDoc.overrideMimeType("text/plain; charset=x-user-defined"); xhrDoc.overrideMimeType("text/plain; charset=x-user-defined");
...@@ -53,249 +75,262 @@ var loadFile = function (name) { ...@@ -53,249 +75,262 @@ var loadFile = function (name) {
return xhrDoc.response; return xhrDoc.response;
}; };
var loadAndRender = function (d, name, data) { const loadAndRender = function (d, name, data) {
return d.load(docX[name].loadedContent).setData(data).render(); return d.load(docX[name].loadedContent).setData(data).render();
}; };
for (var i = 0, name; i < fileNames.length; i++) { for (let i = 0, name; i < fileNames.length; i++) {
name = fileNames[i]; name = fileNames[i];
var content = loadFile(name); const content = loadFile(name);
docX[name] = new DocxGen(); docX[name] = new DocxGen();
docX[name].loadedContent = content; docX[name].loadedContent = content;
} }
describe("image adding with {% image} syntax", function () { describe("image adding with {% image} syntax", function () {
it("should work with one image", function () { it("should work with one image", function () {
var name = "imageExample.docx"; const name = "imageExample.docx";
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
docX[name].attachModule(imageModule); const doc = new DocxGen(docX[name].loadedContent);
var out = loadAndRender(docX[name], name, {image: "examples/image.png"}); doc.attachModule(imageModule);
const out = loadAndRender(doc, name, {image: "examples/image.png"});
var zip = out.getZip(); const zip = out.getZip();
fs.writeFile("test7.docx", zip.generate({type: "nodebuffer"})); fs.writeFile("test7.docx", zip.generate({type: "nodebuffer"}));
var imageFile = zip.files["word/media/image_generated_1.png"]; const imageFile = zip.files["word/media/image_generated_1.png"];
expect((typeof imageFile !== "undefined" && imageFile !== null), "No image file found").to.equal(true); expect((typeof imageFile !== "undefined" && imageFile !== null), "No image file found").to.equal(true);
expect(imageFile.asText().length).to.be.within(17417, 17440); expect(imageFile.asText().length).to.be.within(17417, 17440);
var relsFile = zip.files["word/_rels/document.xml.rels"]; const relsFile = zip.files["word/_rels/document.xml.rels"];
expect((typeof relsFile !== "undefined" && relsFile !== null), "No rels file found").to.equal(true); expect((typeof relsFile !== "undefined" && relsFile !== null), "No rels file found").to.equal(true);
var relsFileContent = relsFile.asText(); const relsFileContent = relsFile.asText();
expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" Target=\"endnotes.xml\"/><Relationship Id=\"hId0\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header0.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/></Relationships>"); expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" Target=\"endnotes.xml\"/><Relationship Id=\"hId0\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header0.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/></Relationships>");
var documentFile = zip.files["word/document.xml"]; const documentFile = zip.files["word/document.xml"];
expect((typeof documentFile !== "undefined" && documentFile !== null), "No document file found").to.equal(true); expect((typeof documentFile !== "undefined" && documentFile !== null), "No document file found").to.equal(true);
return documentFile.asText(); documentFile.asText();
});
it("should work with image tag == null", function () {
const name = "imageExample.docx";
const imageModule = new ImageModule(opts);
const doc = new DocxGen(docX[name].loadedContent);
doc.attachModule(imageModule);
const out = loadAndRender(doc, name, {});
const zip = out.getZip();
fs.writeFile("test8.docx", zip.generate({type: "nodebuffer"}));
shouldBeSame(zip, "expectedNoImage.docx");
}); });
it("should work with centering", function () { it("should work with centering", function () {
var d = new DocxGen(); const d = new DocxGen();
var name = "imageExample.docx"; const name = "imageExample.docx";
opts.centered = true; opts.centered = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
d.attachModule(imageModule); d.attachModule(imageModule);
var out = loadAndRender(d, name, {image: "examples/image.png"}); const out = loadAndRender(d, name, {image: "examples/image.png"});
var zip = out.getZip(); const zip = out.getZip();
fs.writeFile("test_center.docx", zip.generate({type: "nodebuffer"})); fs.writeFile("test_center.docx", zip.generate({type: "nodebuffer"}));
var imageFile = zip.files["word/media/image_generated_1.png"]; const imageFile = zip.files["word/media/image_generated_1.png"];
expect((typeof imageFile !== "undefined" && imageFile !== null)).to.equal(true); expect((typeof imageFile !== "undefined" && imageFile !== null)).to.equal(true);
expect(imageFile.asText().length).to.be.within(17417, 17440); expect(imageFile.asText().length).to.be.within(17417, 17440);
var relsFile = zip.files["word/_rels/document.xml.rels"]; const relsFile = zip.files["word/_rels/document.xml.rels"];
expect((typeof relsFile !== "undefined" && relsFile !== null)).to.equal(true); expect((typeof relsFile !== "undefined" && relsFile !== null)).to.equal(true);
var relsFileContent = relsFile.asText(); const relsFileContent = relsFile.asText();
expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" Target=\"endnotes.xml\"/><Relationship Id=\"hId0\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header0.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/></Relationships>"); expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" Target=\"endnotes.xml\"/><Relationship Id=\"hId0\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header0.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/></Relationships>");
var documentFile = zip.files["word/document.xml"]; const documentFile = zip.files["word/document.xml"];
expect((typeof documentFile !== "undefined" && documentFile !== null)).to.equal(true); expect((typeof documentFile !== "undefined" && documentFile !== null)).to.equal(true);
return documentFile.asText(); documentFile.asText();
}); });
it("should work with loops", function () { it("should work with loops", function () {
var name = "imageLoopExample.docx"; const name = "imageLoopExample.docx";
opts.centered = true; opts.centered = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
var out = loadAndRender(docX[name], name, {images: ["examples/image.png", "examples/image2.png"]}); const out = loadAndRender(docX[name], name, {images: ["examples/image.png", "examples/image2.png"]});
var zip = out.getZip(); const zip = out.getZip();
var imageFile = zip.files["word/media/image_generated_1.png"]; const imageFile = zip.files["word/media/image_generated_1.png"];
expect((typeof imageFile !== "undefined" && imageFile !== null)).to.equal(true); expect((typeof imageFile !== "undefined" && imageFile !== null)).to.equal(true);
expect(imageFile.asText().length).to.be.within(17417, 17440); expect(imageFile.asText().length).to.be.within(17417, 17440);
var imageFile2 = zip.files["word/media/image_generated_2.png"]; const imageFile2 = zip.files["word/media/image_generated_2.png"];
expect((typeof imageFile2 !== "undefined" && imageFile2 !== null)).to.equal(true); expect((typeof imageFile2 !== "undefined" && imageFile2 !== null)).to.equal(true);
expect(imageFile2.asText().length).to.be.within(7177, 7181); expect(imageFile2.asText().length).to.be.within(7177, 7181);
var relsFile = zip.files["word/_rels/document.xml.rels"]; const relsFile = zip.files["word/_rels/document.xml.rels"];
expect((typeof relsFile !== "undefined" && relsFile !== null)).to.equal(true); expect((typeof relsFile !== "undefined" && relsFile !== null)).to.equal(true);
var relsFileContent = relsFile.asText(); const relsFileContent = relsFile.asText();
expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" Target=\"endnotes.xml\"/><Relationship Id=\"hId0\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header0.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/><Relationship Id=\"rId7\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_2.png\"/></Relationships>"); expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes\" Target=\"footnotes.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes\" Target=\"endnotes.xml\"/><Relationship Id=\"hId0\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header0.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/><Relationship Id=\"rId7\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_2.png\"/></Relationships>");
var documentFile = zip.files["word/document.xml"]; const documentFile = zip.files["word/document.xml"];
expect((typeof documentFile !== "undefined" && documentFile !== null)).to.equal(true); expect((typeof documentFile !== "undefined" && documentFile !== null)).to.equal(true);
var buffer = zip.generate({type: "nodebuffer"}); const buffer = zip.generate({type: "nodebuffer"});
return fs.writeFile("test_multi.docx", buffer); fs.writeFile("test_multi.docx", buffer);
}); });
return it("should work with image in header/footer", function () { it("should work with image in header/footer", function () {
var name = "imageHeaderFooterExample.docx"; const name = "imageHeaderFooterExample.docx";
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
var out = loadAndRender(docX[name], name, {image: "examples/image.png"}); const out = loadAndRender(docX[name], name, {image: "examples/image.png"});
var zip = out.getZip(); const zip = out.getZip();
var imageFile = zip.files["word/media/image_generated_1.png"]; const imageFile = zip.files["word/media/image_generated_1.png"];
expect((typeof imageFile !== "undefined" && imageFile !== null)).to.equal(true); expect((typeof imageFile !== "undefined" && imageFile !== null)).to.equal(true);
expect(imageFile.asText().length).to.be.within(17417, 17440); expect(imageFile.asText().length).to.be.within(17417, 17440);
var imageFile2 = zip.files["word/media/image_generated_2.png"]; const imageFile2 = zip.files["word/media/image_generated_2.png"];
expect((typeof imageFile2 !== "undefined" && imageFile2 !== null)).to.equal(true); expect((typeof imageFile2 !== "undefined" && imageFile2 !== null)).to.equal(true);
expect(imageFile2.asText().length).to.be.within(17417, 17440); expect(imageFile2.asText().length).to.be.within(17417, 17440);
var relsFile = zip.files["word/_rels/document.xml.rels"]; const relsFile = zip.files["word/_rels/document.xml.rels"];
expect((typeof relsFile !== "undefined" && relsFile !== null)).to.equal(true); expect((typeof relsFile !== "undefined" && relsFile !== null)).to.equal(true);
var relsFileContent = relsFile.asText(); const relsFileContent = relsFile.asText();
expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/></Relationships>"); expectNormalCharacters(relsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/></Relationships>");
var headerRelsFile = zip.files["word/_rels/header1.xml.rels"]; const headerRelsFile = zip.files["word/_rels/header1.xml.rels"];
expect((typeof headerRelsFile !== "undefined" && headerRelsFile !== null)).to.equal(true); expect((typeof headerRelsFile !== "undefined" && headerRelsFile !== null)).to.equal(true);
var headerRelsFileContent = headerRelsFile.asText(); const headerRelsFileContent = headerRelsFile.asText();
expectNormalCharacters(headerRelsFileContent, `<?xml version="1.0" encoding="UTF-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image_generated_2.png"/> expectNormalCharacters(headerRelsFileContent, `<?xml version="1.0" encoding="UTF-8"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image_generated_2.png"/>
</Relationships>`); </Relationships>`);
var footerRelsFile = zip.files["word/_rels/footer1.xml.rels"]; const footerRelsFile = zip.files["word/_rels/footer1.xml.rels"];
expect((typeof footerRelsFile !== "undefined" && footerRelsFile !== null)).to.equal(true); expect((typeof footerRelsFile !== "undefined" && footerRelsFile !== null)).to.equal(true);
var footerRelsFileContent = footerRelsFile.asText(); const footerRelsFileContent = footerRelsFile.asText();
expectNormalCharacters(footerRelsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/></Relationships>"); expectNormalCharacters(footerRelsFileContent, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\"><Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\" Target=\"header1.xml\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer\" Target=\"footer1.xml\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\" Target=\"fontTable.xml\"/><Relationship Id=\"rId5\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\" Target=\"settings.xml\"/><Relationship Id=\"rId6\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image_generated_1.png\"/></Relationships>");
var documentFile = zip.files["word/document.xml"]; const documentFile = zip.files["word/document.xml"];
expect((typeof documentFile !== "undefined" && documentFile !== null)).to.equal(true); expect((typeof documentFile !== "undefined" && documentFile !== null)).to.equal(true);
var documentContent = documentFile.asText(); const documentContent = documentFile.asText();
expectNormalCharacters(documentContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:document 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:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"><w:body><w:p><w:pPr><w:pStyle w:val=\"Normal\"/><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr></w:r></w:p><w:sectPr><w:headerReference w:type=\"default\" r:id=\"rId2\"/><w:footerReference w:type=\"default\" r:id=\"rId3\"/><w:type w:val=\"nextPage\"/><w:pgSz w:w=\"12240\" w:h=\"15840\"/><w:pgMar w:left=\"1800\" w:right=\"1800\" w:header=\"720\" w:top=\"2810\" w:footer=\"1440\" w:bottom=\"2003\" w:gutter=\"0\"/><w:pgNumType w:fmt=\"decimal\"/><w:formProt w:val=\"false\"/><w:textDirection w:val=\"lrTb\"/><w:docGrid w:type=\"default\" w:linePitch=\"249\" w:charSpace=\"2047\"/></w:sectPr></w:body></w:document>"); expectNormalCharacters(documentContent, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><w:document 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:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"><w:body><w:p><w:pPr><w:pStyle w:val=\"Normal\"/><w:rPr></w:rPr></w:pPr><w:r><w:rPr></w:rPr></w:r></w:p><w:sectPr><w:headerReference w:type=\"default\" r:id=\"rId2\"/><w:footerReference w:type=\"default\" r:id=\"rId3\"/><w:type w:val=\"nextPage\"/><w:pgSz w:w=\"12240\" w:h=\"15840\"/><w:pgMar w:left=\"1800\" w:right=\"1800\" w:header=\"720\" w:top=\"2810\" w:footer=\"1440\" w:bottom=\"2003\" w:gutter=\"0\"/><w:pgNumType w:fmt=\"decimal\"/><w:formProt w:val=\"false\"/><w:textDirection w:val=\"lrTb\"/><w:docGrid w:type=\"default\" w:linePitch=\"249\" w:charSpace=\"2047\"/></w:sectPr></w:body></w:document>");
return fs.writeFile("test_header_footer.docx", zip.generate({type: "nodebuffer"})); fs.writeFile("test_header_footer.docx", zip.generate({type: "nodebuffer"}));
}); });
}); });
describe("qrcode replacing", function () { describe("qrcode replacing", function () {
describe("shoud work without loops", function () { describe("shoud work without loops", function () {
return it("should work with simple", function (done) { it("should work with simple", function (done) {
var name = "qrExample.docx"; const name = "qrExample.docx";
opts.qrCode = true; opts.qrCode = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
imageModule.finished = function () { imageModule.finished = function () {
var zip = docX[name].getZip(); const zip = docX[name].getZip();
var buffer = zip.generate({type: "nodebuffer"}); const buffer = zip.generate({type: "nodebuffer"});
fs.writeFileSync("test_qr.docx", buffer); fs.writeFileSync("test_qr.docx", buffer);
var images = zip.file(/media\/.*.png/); const images = zip.file(/media\/.*.png/);
expect(images.length).to.equal(2); expect(images.length).to.equal(2);
expect(images[0].asText().length).to.equal(826); expect(images[0].asText().length).to.equal(826);
expect(images[1].asText().length).to.be.within(17417, 17440); expect(images[1].asText().length).to.be.within(17417, 17440);
return done(); done();
}; };
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
return loadAndRender(docX[name], name, {image: "examples/image"}); loadAndRender(docX[name], name, {image: "examples/image"});
}); });
}); });
describe("should work with two", function () { describe("should work with two", function () {
return it("should work", function (done) { it("should work", function (done) {
var name = "qrExample2.docx"; const name = "qrExample2.docx";
opts.qrCode = true; opts.qrCode = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
imageModule.finished = function () { imageModule.finished = function () {
var zip = docX[name].getZip(); const zip = docX[name].getZip();
var buffer = zip.generate({type: "nodebuffer"}); const buffer = zip.generate({type: "nodebuffer"});
fs.writeFileSync("test_qr3.docx", buffer); fs.writeFileSync("test_qr3.docx", buffer);
var images = zip.file(/media\/.*.png/); const images = zip.file(/media\/.*.png/);
expect(images.length).to.equal(4); expect(images.length).to.equal(4);
expect(images[0].asText().length).to.equal(859); expect(images[0].asText().length).to.equal(859);
expect(images[1].asText().length).to.equal(826); expect(images[1].asText().length).to.equal(826);
expect(images[2].asText().length).to.be.within(17417, 17440); expect(images[2].asText().length).to.be.within(17417, 17440);
expect(images[3].asText().length).to.be.within(7177, 7181); expect(images[3].asText().length).to.be.within(7177, 7181);
return done(); done();
}; };
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
return loadAndRender(docX[name], name, {image: "examples/image", image2: "examples/image2.png"}); loadAndRender(docX[name], name, {image: "examples/image", image2: "examples/image2.png"});
}); });
}); });
describe("should work qr in headers without extra images", function () { describe("should work qr in headers without extra images", function () {
return it("should work in a header too", function (done) { it("should work in a header too", function (done) {
var name = "qrHeaderNoImage.docx"; const name = "qrHeaderNoImage.docx";
opts.qrCode = true; opts.qrCode = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
imageModule.finished = function () { imageModule.finished = function () {
var zip = docX[name].getZip(); const zip = docX[name].getZip();
var buffer = zip.generate({type: "nodebuffer"}); const buffer = zip.generate({type: "nodebuffer"});
fs.writeFile("test_qr_header_no_image.docx", buffer); fs.writeFile("test_qr_header_no_image.docx", buffer);
var images = zip.file(/media\/.*.png/); const images = zip.file(/media\/.*.png/);
expect(images.length).to.equal(3); expect(images.length).to.equal(3);
expect(images[0].asText().length).to.equal(826); expect(images[0].asText().length).to.equal(826);
expect(images[1].asText().length).to.be.within(12888, 12900); expect(images[1].asText().length).to.be.within(12888, 12900);
expect(images[2].asText().length).to.be.within(17417, 17440); expect(images[2].asText().length).to.be.within(17417, 17440);
return done(); done();
}; };
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
return loadAndRender(docX[name], name, {image: "examples/image", image2: "examples/image2.png"}); loadAndRender(docX[name], name, {image: "examples/image", image2: "examples/image2.png"});
}); });
}); });
describe("should work qr in headers with extra images", function () { describe("should work qr in headers with extra images", function () {
return it("should work in a header too", function (done) { it("should work in a header too", function (done) {
var name = "qrHeader.docx"; const name = "qrHeader.docx";
opts.qrCode = true; opts.qrCode = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
imageModule.finished = function () { imageModule.finished = function () {
var zip = docX[name].getZip(); const zip = docX[name].getZip();
var buffer = zip.generate({type: "nodebuffer"}); const buffer = zip.generate({type: "nodebuffer"});
fs.writeFile("test_qr_header.docx", buffer); fs.writeFile("test_qr_header.docx", buffer);
var images = zip.file(/media\/.*.png/); const images = zip.file(/media\/.*.png/);
expect(images.length).to.equal(3); expect(images.length).to.equal(3);
expect(images[0].asText().length).to.equal(826); expect(images[0].asText().length).to.equal(826);
expect(images[1].asText().length).to.be.within(12888, 12900); expect(images[1].asText().length).to.be.within(12888, 12900);
expect(images[2].asText().length).to.be.within(17417, 17440); expect(images[2].asText().length).to.be.within(17417, 17440);
return done(); done();
}; };
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
return loadAndRender(docX[name], name, {image: "examples/image", image2: "examples/image2.png"}); loadAndRender(docX[name], name, {image: "examples/image", image2: "examples/image2.png"});
}); });
}); });
return describe("should work with image after loop", function () { describe("should work with image after loop", function () {
return it("should work with image after loop", function (done) { it("should work with image after loop", function (done) {
var name = "imageAfterLoop.docx"; const name = "imageAfterLoop.docx";
opts.qrCode = true; opts.qrCode = true;
var imageModule = new ImageModule(opts); const imageModule = new ImageModule(opts);
imageModule.finished = function () { imageModule.finished = function () {
var zip = docX[name].getZip(); const zip = docX[name].getZip();
var buffer = zip.generate({type: "nodebuffer"}); const buffer = zip.generate({type: "nodebuffer"});
fs.writeFile("test_image_after_loop.docx", buffer); fs.writeFile("test_image_after_loop.docx", buffer);
var images = zip.file(/media\/.*.png/); const images = zip.file(/media\/.*.png/);
expect(images.length).to.equal(2); expect(images.length).to.equal(2);
expect(images[0].asText().length).to.be.within(7177, 7181); expect(images[0].asText().length).to.be.within(7177, 7181);
expect(images[1].asText().length).to.be.within(7177, 7181); expect(images[1].asText().length).to.be.within(7177, 7181);
return done(); done();
}; };
docX[name].attachModule(imageModule); docX[name].attachModule(imageModule);
return loadAndRender(docX[name], name, {image: "examples/image2.png", above: [{cell1: "foo", cell2: "bar"}], below: "foo"}); loadAndRender(docX[name], name, {image: "examples/image2.png", above: [{cell1: "foo", cell2: "bar"}], below: "foo"});
}); });
}); });
}); });
...@@ -4,18 +4,19 @@ ...@@ -4,18 +4,19 @@
"description": "Image Module for docxtemplater v1.0", "description": "Image Module for docxtemplater v1.0",
"main": "js/index.js", "main": "js/index.js",
"scripts": { "scripts": {
"compile": "rm js -rf ; mkdir -p test/spec; mkdir -p js; babel es6 --out-dir js; mv js/test.js test/test.js", "compile": "rm js -rf ; mkdir -p test/spec; mkdir -p js; babel es6 --out-dir js",
"test:compiled": "mocha", "test:compiled": "mocha js/test.js",
"test:es6": "mocha es6/test.js",
"lint": "eslint .", "lint": "eslint .",
"test": "npm run compile && npm run test:compiled" "test": "npm run compile && npm run test:compiled"
}, },
"devDependencies": { "devDependencies": {
"babel-cli": "^6.4.0", "babel-cli": "^6.7.5",
"babel-eslint": "^4.1.2", "babel-eslint": "^6.0.2",
"babel-preset-es2015": "^6.3.13", "babel-preset-es2015": "^6.3.13",
"chai": "^3.4.1", "chai": "^3.4.1",
"docxtemplater": "^2.0.0", "docxtemplater": "^2.1.0",
"eslint": "^1.10.3", "eslint": "^2.7.0",
"mocha": "^2.4.5" "mocha": "^2.4.5"
}, },
"repository": { "repository": {
...@@ -25,8 +26,9 @@ ...@@ -25,8 +26,9 @@
"author": "Edgar Hipp", "author": "Edgar Hipp",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"eslint": "^2.7.0",
"png-js": "^0.1.1", "png-js": "^0.1.1",
"qrcode-reader": "0.0.7", "qrcode-reader": "^0.1.1",
"xmldom": "0.1.21" "xmldom": "^0.1.22"
} }
} }
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