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

View File

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

View File

@ -40,7 +40,10 @@ const getSiblings = (elem) => {
}; };
const getText = (node) => { 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) => { const hasAttrib = (elem, name) => {

View File

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

View File

@ -74,7 +74,8 @@ module.exports = function (data) {
sax.oncdata = function (cdata) { sax.oncdata = function (cdata) {
pushToContent({ pushToContent({
cdata: cdata, type: 'cdata',
value: cdata,
}); });
}; };
@ -115,9 +116,15 @@ module.exports = function (data) {
sax.ontext = function (text) { sax.ontext = function (text) {
// prevent trimming of meaningful whitespace inside textual tags // prevent trimming of meaningful whitespace inside textual tags
if (textElems.includes(current.elem) && !data.prefix) { if (textElems.includes(current.elem) && !data.prefix) {
pushToContent({ text: text }); pushToContent({
type: 'text',
value: text,
});
} else if (/\S/.test(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) { elems.forEach(function (elem) {
if (elem.isElem('style')) { if (elem.isElem('style')) {
// <style> element if (elem.content[0].type === 'text' || elem.content[0].type === 'cdata') {
var styleCss = elem.content[0].text || elem.content[0].cdata || []; const styleCss = elem.content[0].value;
var DATA = const minified = csso.minify(styleCss, minifyOptionsForStylesheet).css;
styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0 // TODO figure out if this check is necessary
? 'cdata' if (styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0) {
: 'text'; elem.content[0].type = 'cdata';
elem.content[0].value = minified;
elem.content[0][DATA] = csso.minify( } else {
styleCss, elem.content[0].type = 'text';
minifyOptionsForStylesheet elem.content[0].value = minified;
).css; }
}
} else { } else {
// style attribute // style attribute
var elemStyle = elem.attr('style').value; var elemStyle = elem.attr('style').value;

View File

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

View File

@ -30,7 +30,8 @@ exports.fn = function (item, params) {
!( !(
params.removeAny || params.removeAny ||
item.isEmpty() || 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 () { describe('text nodes', function () {
it('should contain preserved whitespace', function () { it('should contain preserved whitespace', function () {
const textNode = root.content[3].content[1].content[0].content[1]; 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 ');
}); });
}); });