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

Convert cdata and text nodes to xast

Ref https://github.com/syntax-tree/xast

More consistent naming and distinction by type looks a bit cleaner.
This commit is contained in:
Bogdan Chadkin
2021-03-10 16:02:37 +03:00
parent 10ac712282
commit c50decb438
9 changed files with 55 additions and 38 deletions

View File

@ -189,7 +189,10 @@ function csstreeToStyleDeclaration(declaration) {
* @return {string|Array} CSS string or empty array if no styles are set
*/
function getCssStr(elem) {
return elem.content[0].text || elem.content[0].cdata || [];
if (elem.content[0].type === 'text' || elem.content[0].type === 'cdata') {
return elem.content[0].value;
}
return '';
}
/**
@ -200,15 +203,11 @@ function getCssStr(elem) {
* @return {Object} reference to field with CSS
*/
function setCssStr(elem, css) {
// in case of cdata field
if (elem.content[0].cdata) {
elem.content[0].cdata = css;
return elem.content[0].cdata;
if (elem.content[0].type === 'text' || elem.content[0].type === 'cdata') {
elem.content[0].value = css;
return elem.content[0].value;
}
// in case of text field + if nothing was set yet
elem.content[0].text = css;
return elem.content[0].text;
return css;
}
module.exports.flattenToSelectors = flattenToSelectors;

View File

@ -154,8 +154,9 @@ const computeStyle = (node) => {
) {
const children = styleNode.content || [];
for (const child of children) {
const css = child.text || child.cdata;
stylesheet.push(...parseStylesheet(css, dynamic));
if (child.type === 'text' || child.type === 'cdata') {
stylesheet.push(...parseStylesheet(child.value, dynamic));
}
}
}
}

View File

@ -40,7 +40,10 @@ const getSiblings = (elem) => {
};
const getText = (node) => {
return node.content[0].text || node.content[0].cdata || '';
if (node.content[0].type === 'text' && node.content[0].type === 'cdata') {
return node.content[0].value;
}
return '';
};
const hasAttrib = (elem, name) => {

View File

@ -99,16 +99,16 @@ JS2SVG.prototype.convert = function (data) {
data.content.forEach(function (item) {
if (item.elem) {
svg += this.createElem(item);
} else if (item.text) {
svg += this.createText(item.text);
} else if (item.type === 'text') {
svg += this.createText(item);
} else if (item.type === 'doctype') {
svg += this.createDoctype(item);
} else if (item.type === 'instruction') {
svg += this.createProcInst(item);
} else if (item.type === 'comment') {
svg += this.createComment(item);
} else if (item.cdata) {
svg += this.createCDATA(item.cdata);
} else if (item.type === 'cdata') {
svg += this.createCDATA(item);
}
}, this);
}
@ -184,9 +184,10 @@ JS2SVG.prototype.createComment = function (node) {
*
* @return {String}
*/
JS2SVG.prototype.createCDATA = function (cdata) {
JS2SVG.prototype.createCDATA = function (node) {
const { value } = node;
return (
this.createIndent() + this.config.cdataStart + cdata + this.config.cdataEnd
this.createIndent() + this.config.cdataStart + value + this.config.cdataEnd
);
};
@ -308,11 +309,12 @@ JS2SVG.prototype.createAttrs = function (elem) {
*
* @return {String}
*/
JS2SVG.prototype.createText = function (text) {
JS2SVG.prototype.createText = function (node) {
const { value } = node;
return (
this.createIndent() +
this.config.textStart +
text.replace(this.config.regEntities, this.config.encodeEntity) +
value.replace(this.config.regEntities, this.config.encodeEntity) +
(this.textContext ? '' : this.config.textEnd)
);
};

View File

@ -74,7 +74,8 @@ module.exports = function (data) {
sax.oncdata = function (cdata) {
pushToContent({
cdata: cdata,
type: 'cdata',
value: cdata,
});
};
@ -115,9 +116,15 @@ module.exports = function (data) {
sax.ontext = function (text) {
// prevent trimming of meaningful whitespace inside textual tags
if (textElems.includes(current.elem) && !data.prefix) {
pushToContent({ text: text });
pushToContent({
type: 'text',
value: text,
});
} else if (/\S/.test(text)) {
pushToContent({ text: text.trim() });
pushToContent({
type: 'text',
value: text.trim(),
});
}
};

View File

@ -38,17 +38,18 @@ exports.fn = function (ast, options) {
elems.forEach(function (elem) {
if (elem.isElem('style')) {
// <style> element
var styleCss = elem.content[0].text || elem.content[0].cdata || [];
var DATA =
styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0
? 'cdata'
: 'text';
elem.content[0][DATA] = csso.minify(
styleCss,
minifyOptionsForStylesheet
).css;
if (elem.content[0].type === 'text' || elem.content[0].type === 'cdata') {
const styleCss = elem.content[0].value;
const minified = csso.minify(styleCss, minifyOptionsForStylesheet).css;
// TODO figure out if this check is necessary
if (styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0) {
elem.content[0].type = 'cdata';
elem.content[0].value = minified;
} else {
elem.content[0].type = 'text';
elem.content[0].value = minified;
}
}
} else {
// style attribute
var elemStyle = elem.attr('style').value;

View File

@ -203,7 +203,10 @@ exports.fn = function (node, opts, extra) {
return node;
}
var cssStr = node.content[0].text || node.content[0].cdata || [];
var cssStr = '';
if (node.content[0].type === 'text' || node.content[0].type === 'cdata') {
cssStr = node.content[0].value;
}
var cssAst = {};
try {
@ -246,7 +249,7 @@ exports.fn = function (node, opts, extra) {
});
// update <style>s
node.content[0].text = csstree.generate(cssAst);
node.content[0].value = csstree.generate(cssAst);
return node;
}

View File

@ -30,7 +30,8 @@ exports.fn = function (item, params) {
!(
params.removeAny ||
item.isEmpty() ||
standardDescs.test(item.content[0].text)
(item.content[0].type === 'text' &&
standardDescs.test(item.content[0].value))
)
);
};

View File

@ -135,7 +135,7 @@ describe('svg2js', function () {
describe('text nodes', function () {
it('should contain preserved whitespace', function () {
const textNode = root.content[3].content[1].content[0].content[1];
return expect(textNode.content[0].text).to.equal(' test ');
return expect(textNode.content[0].value).to.equal(' test ');
});
});