From 516c6e1fc1ee5bd32ba205e95fe6dab468667034 Mon Sep 17 00:00:00 2001 From: Bogdan Chadkin Date: Sun, 2 Oct 2022 12:00:44 +0300 Subject: [PATCH] Drop createContentItem from public api and JSAPI node wrappers --- lib/parser.js | 17 ++++++++++------- lib/svgo-node.js | 4 +--- lib/svgo.js | 12 ------------ lib/svgo/jsAPI.d.ts | 2 -- lib/svgo/jsAPI.js | 12 ------------ plugins/collapseGroups.js | 9 +++++---- plugins/mergeStyles.js | 21 ++++++++++++++------- plugins/removeUselessDefs.js | 8 +++++--- plugins/reusePaths.js | 32 ++++++++++++++++---------------- test/jsapi/_index.test.js | 24 ------------------------ 10 files changed, 51 insertions(+), 90 deletions(-) delete mode 100644 lib/svgo/jsAPI.d.ts delete mode 100644 lib/svgo/jsAPI.js delete mode 100644 test/jsapi/_index.test.js diff --git a/lib/parser.js b/lib/parser.js index 79357c31..8c40eda0 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -10,11 +10,11 @@ * @typedef {import('./types').XastCdata} XastCdata * @typedef {import('./types').XastText} XastText * @typedef {import('./types').XastParent} XastParent + * @typedef {import('./types').XastChild} XastChild */ // @ts-ignore sax will be replaced with something else later const SAX = require('@trysound/sax'); -const JSAPI = require('./svgo/jsAPI.js'); const { textElems } = require('../plugins/_collections.js'); class SvgoParserError extends Error { @@ -94,7 +94,7 @@ const parseSvg = (data, from) => { /** * @type {XastRoot} */ - const root = new JSAPI({ type: 'root', children: [] }); + const root = { type: 'root', children: [] }; /** * @type {XastParent} */ @@ -105,12 +105,15 @@ const parseSvg = (data, from) => { const stack = [root]; /** - * @type {(node: T) => T} + * @type {(node: XastChild) => void} */ const pushToContent = (node) => { - const wrapped = new JSAPI(node, current); - current.children.push(wrapped); - return wrapped; + // TODO remove legacy parentNode in v4 + Object.defineProperty(node, 'parentNode', { + writable: true, + value: current, + }); + current.children.push(node); }; /** @@ -199,7 +202,7 @@ const parseSvg = (data, from) => { for (const [name, attr] of Object.entries(data.attributes)) { element.attributes[name] = attr.value; } - element = pushToContent(element); + pushToContent(element); current = element; stack.push(element); }; diff --git a/lib/svgo-node.js b/lib/svgo-node.js index 47e5cf7d..ee019ed8 100644 --- a/lib/svgo-node.js +++ b/lib/svgo-node.js @@ -4,9 +4,7 @@ const os = require('os'); const fs = require('fs'); const { pathToFileURL } = require('url'); const path = require('path'); -const { optimize: optimizeAgnostic, createContentItem } = require('./svgo.js'); - -exports.createContentItem = createContentItem; +const { optimize: optimizeAgnostic } = require('./svgo.js'); const importConfig = async (configFile) => { let config; diff --git a/lib/svgo.js b/lib/svgo.js index 0e958613..80891992 100644 --- a/lib/svgo.js +++ b/lib/svgo.js @@ -4,7 +4,6 @@ const { defaultPlugins, resolvePluginConfig } = require('./svgo/config.js'); const { parseSvg } = require('./parser.js'); const { stringifySvg } = require('./stringifier.js'); const { invokePlugins } = require('./svgo/plugins.js'); -const JSAPI = require('./svgo/jsAPI.js'); const { encodeSVGDatauri } = require('./svgo/tools.js'); const optimize = (input, config) => { @@ -64,14 +63,3 @@ const optimize = (input, config) => { return svgjs; }; exports.optimize = optimize; - -/** - * The factory that creates a content item with the helper methods. - * - * @param {Object} data which is passed to jsAPI constructor - * @returns {JSAPI} content item - */ -const createContentItem = (data) => { - return new JSAPI(data); -}; -exports.createContentItem = createContentItem; diff --git a/lib/svgo/jsAPI.d.ts b/lib/svgo/jsAPI.d.ts deleted file mode 100644 index a11ba35f..00000000 --- a/lib/svgo/jsAPI.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare let obj: any; -export = obj; diff --git a/lib/svgo/jsAPI.js b/lib/svgo/jsAPI.js deleted file mode 100644 index 7b8d7742..00000000 --- a/lib/svgo/jsAPI.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -var JSAPI = function (data, parentNode) { - Object.assign(this, data); - if (this.type === 'element') { - Object.defineProperty(this, 'parentNode', { - writable: true, - value: parentNode, - }); - } -}; -module.exports = JSAPI; diff --git a/plugins/collapseGroups.js b/plugins/collapseGroups.js index 35bfedf3..6897d2d4 100644 --- a/plugins/collapseGroups.js +++ b/plugins/collapseGroups.js @@ -122,11 +122,12 @@ exports.fn = () => { // replace current node with all its children const index = parentNode.children.indexOf(node); parentNode.children.splice(index, 1, ...node.children); - // TODO remove in v3 + // TODO remove legacy parentNode in v4 for (const child of node.children) { - // @ts-ignore parentNode is forbidden for public usage - // and will be moved in v3 - child.parentNode = parentNode; + Object.defineProperty(child, 'parentNode', { + writable: true, + value: parentNode, + }); } } }, diff --git a/plugins/mergeStyles.js b/plugins/mergeStyles.js index 157207b0..b8967b11 100644 --- a/plugins/mergeStyles.js +++ b/plugins/mergeStyles.js @@ -2,10 +2,10 @@ /** * @typedef {import('../lib/types').XastElement} XastElement + * @typedef {import('../lib/types').XastChild} XastChild */ const { visitSkip, detachNodeFromParent } = require('../lib/xast.js'); -const JSAPI = require('../lib/svgo/jsAPI.js'); exports.name = 'mergeStyles'; exports.type = 'visitor'; @@ -25,6 +25,9 @@ exports.fn = () => { */ let firstStyleElement = null; let collectedStyles = ''; + /** + * @type {'text' | 'cdata'} + */ let styleContentType = 'text'; return { @@ -80,12 +83,16 @@ exports.fn = () => { firstStyleElement = node; } else { detachNodeFromParent(node, parentNode); - firstStyleElement.children = [ - new JSAPI( - { type: styleContentType, value: collectedStyles }, - firstStyleElement - ), - ]; + /** + * @type {XastChild} + */ + const child = { type: styleContentType, value: collectedStyles }; + // TODO remove legacy parentNode in v4 + Object.defineProperty(child, 'parentNode', { + writable: true, + value: firstStyleElement, + }); + firstStyleElement.children = [child]; } }, }, diff --git a/plugins/removeUselessDefs.js b/plugins/removeUselessDefs.js index 586591b6..90fb98a9 100644 --- a/plugins/removeUselessDefs.js +++ b/plugins/removeUselessDefs.js @@ -32,10 +32,12 @@ exports.fn = () => { if (usefulNodes.length === 0) { detachNodeFromParent(node, parentNode); } - // TODO remove in SVGO 3 + // TODO remove legacy parentNode in v4 for (const usefulNode of usefulNodes) { - // @ts-ignore parentNode is legacy - usefulNode.parentNode = node; + Object.defineProperty(usefulNode, 'parentNode', { + writable: true, + value: node, + }); } node.children = usefulNodes; } else if ( diff --git a/plugins/reusePaths.js b/plugins/reusePaths.js index 79ba5c20..b08b259e 100644 --- a/plugins/reusePaths.js +++ b/plugins/reusePaths.js @@ -6,8 +6,6 @@ * @typedef {import('../lib/types').XastNode} XastNode */ -const JSAPI = require('../lib/svgo/jsAPI.js'); - exports.type = 'visitor'; exports.name = 'reusePaths'; exports.active = false; @@ -52,16 +50,17 @@ exports.fn = () => { /** * @type {XastElement} */ - const rawDefs = { + const defsTag = { type: 'element', name: 'defs', attributes: {}, children: [], }; - /** - * @type {XastElement} - */ - const defsTag = new JSAPI(rawDefs, node); + // TODO remove legacy parentNode in v4 + Object.defineProperty(defsTag, 'parentNode', { + writable: true, + value: node, + }); let index = 0; for (const list of paths.values()) { if (list.length > 1) { @@ -69,26 +68,27 @@ exports.fn = () => { /** * @type {XastElement} */ - const rawPath = { + const reusablePath = { type: 'element', name: 'path', attributes: { ...list[0].attributes }, children: [], }; - delete rawPath.attributes.transform; + delete reusablePath.attributes.transform; let id; - if (rawPath.attributes.id == null) { + if (reusablePath.attributes.id == null) { id = 'reuse-' + index; index += 1; - rawPath.attributes.id = id; + reusablePath.attributes.id = id; } else { - id = rawPath.attributes.id; + id = reusablePath.attributes.id; delete list[0].attributes.id; } - /** - * @type {XastElement} - */ - const reusablePath = new JSAPI(rawPath, defsTag); + // TODO remove legacy parentNode in v4 + Object.defineProperty(reusablePath, 'parentNode', { + writable: true, + value: defsTag, + }); defsTag.children.push(reusablePath); // convert paths to for (const pathNode of list) { diff --git a/test/jsapi/_index.test.js b/test/jsapi/_index.test.js deleted file mode 100644 index 13c8c0eb..00000000 --- a/test/jsapi/_index.test.js +++ /dev/null @@ -1,24 +0,0 @@ -'use strict'; - -const { createContentItem } = require('../../lib/svgo.js'); -const JSAPI = require('../../lib/svgo/jsAPI.js'); - -describe('svgo api', function () { - it('should has createContentItem method', function () { - expect(createContentItem).toBeInstanceOf(Function); - }); - - it('should be able to create content item', function () { - var item = createContentItem({ - elem: 'elementName', - }); - expect(item).toBeInstanceOf(JSAPI); - expect(item.elem).toEqual('elementName'); - }); - - it('should be able create content item without argument', function () { - var item = createContentItem(); - expect(item).toBeInstanceOf(JSAPI); - expect(item).toEqual({}); - }); -});