From c01bdead80f2e5482f5d41cc2b4b6b76d05e783e Mon Sep 17 00:00:00 2001 From: Kyle Welsby Date: Fri, 6 Mar 2020 12:13:53 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Simple=20documentation=20for=20c?= =?UTF-8?q?ore=20document=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintignore | 4 +- .gitignore | 3 +- __tests__/Document.test.js | 5 +- __tests__/__snapshots__/Document.test.js.snap | 94 ------------ package-lock.json | 142 ++++++++++++++++-- package.json | 2 + src/Document.js | 20 ++- src/Presentation.js | 10 ++ src/Style.js | 11 +- 9 files changed, 173 insertions(+), 118 deletions(-) diff --git a/.eslintignore b/.eslintignore index 9e54f1f..94046c7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,5 @@ lib node_modules -coverage \ No newline at end of file +coverage +out +docs \ No newline at end of file diff --git a/.gitignore b/.gitignore index e0c1948..4a04714 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ coverage *DS_Store __tests__/__fixtures__/output.odp lib -*.tgz \ No newline at end of file +*.tgz +docs \ No newline at end of file diff --git a/__tests__/Document.test.js b/__tests__/Document.test.js index 8f1738d..95da4a1 100644 --- a/__tests__/Document.test.js +++ b/__tests__/Document.test.js @@ -22,10 +22,7 @@ async function readFixture(filename) { const masterStylesFile = files.find(f => f.path === 'styles.xml'); const contentFile = files.find(f => f.path === 'content.xml'); const presentation = new Presentation(JSON.parse(toJson(contentFile.data))); - const style = new Style( - JSON.parse(toJson(masterStylesFile.data)), - presentation - ); + const style = new Style(JSON.parse(toJson(masterStylesFile.data))); const subject = new Document(); return { presentation, diff --git a/__tests__/__snapshots__/Document.test.js.snap b/__tests__/__snapshots__/Document.test.js.snap index 2a8e0c4..0389e70 100644 --- a/__tests__/__snapshots__/Document.test.js.snap +++ b/__tests__/__snapshots__/Document.test.js.snap @@ -3025,100 +3025,6 @@ Array [ ] `; -exports[`Document mergeStyles master-page contains the master frames 1`] = ` -Array [ - Array [ - Object { - "draw:image": Object { - "text:p": Object {}, - "xlink:actuate": "onLoad", - "xlink:href": "Pictures/100000000000032000000258E080B12F.jpg", - "xlink:show": "embed", - "xlink:type": "simple", - }, - "draw:layer": "backgroundobjects", - "draw:style-name": "Mgr1", - "draw:text-style-name": "MP1", - "svg:height": "21cm", - "svg:width": "28cm", - "svg:x": "-0.001cm", - "svg:y": "-0.001cm", - }, - Object { - "draw:layer": "backgroundobjects", - "draw:text-box": Object {}, - "presentation:class": "title", - "presentation:placeholder": "true", - "presentation:style-name": "prs-novelty-title", - "svg:height": "3.506cm", - "svg:width": "23.911cm", - "svg:x": "2.058cm", - "svg:y": "1.943cm", - }, - Object { - "draw:layer": "backgroundobjects", - "draw:text-box": Object {}, - "presentation:class": "outline", - "presentation:placeholder": "true", - "presentation:style-name": "prs-novelty-outline1", - "svg:height": "13.23cm", - "svg:width": "23.384cm", - "svg:x": "2.285cm", - "svg:y": "5.938cm", - }, - ], - Array [ - Object { - "draw:layer": "backgroundobjects", - "draw:text-box": Object { - "draw:corner-radius": "0.065cm", - }, - "presentation:class": "title", - "presentation:placeholder": "true", - "presentation:style-name": "prs-strategy-title", - "svg:height": "3.506cm", - "svg:width": "23.911cm", - "svg:x": "2.058cm", - "svg:y": "0.325cm", - }, - Object { - "draw:layer": "backgroundobjects", - "draw:text-box": Object {}, - "presentation:class": "outline", - "presentation:placeholder": "true", - "presentation:style-name": "prs-strategy-outline1", - "svg:height": "13.23cm", - "svg:width": "23.548cm", - "svg:x": "3.023cm", - "svg:y": "6.178cm", - }, - Object { - "draw:image": Object { - "text:p": Object {}, - "xlink:actuate": "onLoad", - "xlink:href": "Pictures/2000023600002305000012CD3628FC8C.wmf", - "xlink:show": "embed", - "xlink:type": "simple", - }, - "draw:layer": "backgroundobjects", - "draw:style-name": "Mgr1", - "draw:text-style-name": "MP1", - "svg:height": "2.937cm", - "svg:width": "5.47cm", - "svg:x": "22.048cm", - "svg:y": "17.365cm", - }, - ], -] -`; - -exports[`Document mergeStyles master-page contains the master style names 1`] = ` -Array [ - "prs-novelty", - "prs-strategy", -] -`; - exports[`Document mergeStyles merges style content from the presentation into the document style 1`] = ` Object { "office:document-styles": Object { diff --git a/package-lock.json b/package-lock.json index d461d48..daadef7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -313,8 +313,7 @@ "@babel/parser": { "version": "7.7.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz", - "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==", - "dev": true + "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.7.4", @@ -1454,7 +1453,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -1749,6 +1747,11 @@ "safe-buffer": "^5.1.1" } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1946,6 +1949,14 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "catharsis": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", + "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", + "requires": { + "lodash": "^4.17.14" + } + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -2664,6 +2675,11 @@ "once": "^1.4.0" } }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -5648,12 +5664,48 @@ } } }, + "js2xmlparser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", + "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", + "requires": { + "xmlcreate": "^2.0.3" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsdoc": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.3.tgz", + "integrity": "sha512-Yf1ZKA3r9nvtMWHO1kEuMZTlHOF8uoQ0vyo5eH7SQy5YeIiHM+B0DgKnn+X6y6KDYZcF7G2SPkKF+JORCXWE/A==", + "requires": { + "@babel/parser": "^7.4.4", + "bluebird": "^3.5.4", + "catharsis": "^0.8.11", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.0", + "klaw": "^3.0.0", + "markdown-it": "^8.4.2", + "markdown-it-anchor": "^5.0.2", + "marked": "^0.7.0", + "mkdirp": "^0.5.1", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.0.1", + "taffydb": "2.6.2", + "underscore": "~1.9.1" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + } + } + }, "jsdom": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", @@ -5762,6 +5814,14 @@ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "requires": { + "graceful-fs": "^4.1.9" + } + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -5804,6 +5864,14 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, + "linkify-it": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", + "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", + "requires": { + "uc.micro": "^1.0.1" + } + }, "lint-staged": { "version": "9.5.0", "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz", @@ -6207,8 +6275,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.sortby": { "version": "4.7.0", @@ -6386,6 +6453,33 @@ "object-visit": "^1.0.0" } }, + "markdown-it": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz", + "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==", + "requires": { + "argparse": "^1.0.7", + "entities": "~1.1.1", + "linkify-it": "^2.0.0", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + } + }, + "markdown-it-anchor": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz", + "integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ==" + }, + "marked": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", + "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -6480,7 +6574,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" }, @@ -6488,8 +6581,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -7325,6 +7417,14 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requizzle": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", + "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", + "requires": { + "lodash": "^4.17.14" + } + }, "resolve": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.1.tgz", @@ -7793,8 +7893,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", @@ -7967,8 +8066,7 @@ "strip-json-comments": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==" }, "supports-color": { "version": "7.1.0", @@ -8009,6 +8107,11 @@ "string-width": "^3.0.0" } }, + "taffydb": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", + "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=" + }, "tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", @@ -8199,6 +8302,11 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "uglify-js": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz", @@ -8235,6 +8343,11 @@ "through": "^2.3.8" } }, + "underscore": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", + "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==" + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", @@ -8529,6 +8642,11 @@ "node-expat": "^2.3.18" } }, + "xmlcreate": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", + "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index fd2b1bf..4060527 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "test": "jest", "lint": "eslint .", "lint:fix": "eslint --fix .", + "docs": "jsdoc src --destination docs", "build": "BABEL_ENV=production babel src --out-dir lib", "prepublish": "npm run lint && npm run test && npm run build" }, @@ -63,6 +64,7 @@ "commander": "^4.1.1", "debug": "^4.1.1", "decompress": "^4.2.0", + "jsdoc": "^3.6.3", "jszip": "^3.2.2", "prettier": "^1.19.1", "shvl": "^2.0.0", diff --git a/src/Document.js b/src/Document.js index 270260f..92bd64d 100644 --- a/src/Document.js +++ b/src/Document.js @@ -1,3 +1,4 @@ +/** @module Document */ import { get, set } from 'shvl'; import JSZip from 'jszip'; import decompress from 'decompress'; @@ -9,6 +10,10 @@ import { extractArray } from './utils'; import Presentation from './Presentation'; import Style from './Style'; +/** + * Class representing a new presentation document to merge files into + * @extends EventEmitter + */ export default class Document extends EventEmitter { constructor() { super({ captureRejections: true }); @@ -44,17 +49,17 @@ export default class Document extends EventEmitter { ]; } + /** + * Merge the given file to the document + * @param {string} file The file path to merge to the document + */ async mergeFile(file) { const files = await decompress(file); const content = files.find(f => f.path === 'content.xml'); const stylesDocument = files.find(f => f.path === 'styles.xml'); let manifest = this.mergeManifest(files); let pres = new Presentation(JSON.parse(toJson(content.data)), this.counter); - let style = new Style( - JSON.parse(toJson(stylesDocument.data)), - pres, - manifest - ); + let style = new Style(JSON.parse(toJson(stylesDocument.data)), manifest); this.mergeContent(pres, manifest); this.mergeStyles(style, manifest); this.counter = this.counter + 1; @@ -131,6 +136,11 @@ export default class Document extends EventEmitter { }; } + /** + * Pipe the merged files through the ZIP stream to return the expected encapulation for presentaitons. + * + * @param {stream.WriteStream} stream The output stream for the zipped contents to write to + */ pipe(stream) { let promise = new Promise((resolve, reject) => { this._zipFiles() diff --git a/src/Presentation.js b/src/Presentation.js index ab66897..1a08ef4 100644 --- a/src/Presentation.js +++ b/src/Presentation.js @@ -1,6 +1,16 @@ +/** @module Presentation */ import { get } from 'shvl'; import { namespaces, uuid } from './utils'; + +/** + * Class prepresenting `content.xml` in the presentation document + */ export default class Presentation { + /** + * Create a presentation content representation. + * @param {object} presentation JSON representation of content.xml + * @param {string} id unique identifier for the presentation + */ constructor(presentation, id) { this.id = id; if (id === undefined) { diff --git a/src/Style.js b/src/Style.js index b13a840..d642042 100644 --- a/src/Style.js +++ b/src/Style.js @@ -1,7 +1,16 @@ +/** @module Style */ import { moveImageReferences, namespaces } from './utils'; +/** + * Class prepresenting `style.xml` in the presentation document + */ export default class Style { - constructor(content, _, manifest) { + /** + * Create a style representation + * @param {object} content JSON representation of `style.xml` document + * @param {array} manifest The document manifest of image assets + */ + constructor(content, manifest) { this.data = moveImageReferences(content, manifest); this.namespaces = namespaces(content['office:document-styles']); }