1
0
mirror of https://github.com/svg/svgo.git synced 2025-07-29 20:21:14 +03:00

Drop createContentItem from public api and JSAPI node wrappers

This commit is contained in:
Bogdan Chadkin
2022-10-02 12:00:44 +03:00
parent 50e836d5a4
commit 516c6e1fc1
10 changed files with 51 additions and 90 deletions

View File

@ -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 {<T extends XastNode>(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);
};

View File

@ -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;

View File

@ -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;

2
lib/svgo/jsAPI.d.ts vendored
View File

@ -1,2 +0,0 @@
declare let obj: any;
export = obj;

View File

@ -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;

View File

@ -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,
});
}
}
},

View File

@ -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];
}
},
},

View File

@ -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 (

View File

@ -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 <use>
for (const pathNode of list) {

View File

@ -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({});
});
});