This repository has been archived on 2023-03-25. You can view files and clone it, but cannot push or open issues or pull requests.
mightyscape-1.1-deprecated/extensions/svgo-inkscape/node_modules/svgo/lib/svgo/svg2js.js
2020-07-30 01:16:18 +02:00

163 lines
3.2 KiB
JavaScript

'use strict';
var SAX = require('sax'),
JSAPI = require('./jsAPI');
var config = {
strict: true,
trim: false,
normalize: true,
lowercase: true,
xmlns: true,
position: false
};
/**
* Convert SVG (XML) string to SVG-as-JS object.
*
* @param {String} data input data
* @param {Function} callback
*/
module.exports = function(data, callback) {
var sax = SAX.parser(config.strict, config),
root = new JSAPI({ elem: '#document' }),
current = root,
stack = [root],
textContext = null;
function pushToContent(content) {
content = new JSAPI(content, current);
(current.content = current.content || []).push(content);
return content;
}
sax.ondoctype = function(doctype) {
pushToContent({
doctype: doctype
});
};
sax.onprocessinginstruction = function(data) {
pushToContent({
processinginstruction: data
});
};
sax.oncomment = function(comment) {
pushToContent({
comment: comment.trim()
});
};
sax.oncdata = function(cdata) {
pushToContent({
cdata: cdata
});
};
sax.onopentag = function(data) {
var elem = {
elem: data.name,
prefix: data.prefix,
local: data.local
};
if (Object.keys(data.attributes).length) {
elem.attrs = {};
for (var name in data.attributes) {
elem.attrs[name] = {
name: name,
value: data.attributes[name].value,
prefix: data.attributes[name].prefix,
local: data.attributes[name].local
};
}
}
elem = pushToContent(elem);
current = elem;
// Save info about <text> tag to prevent trimming of meaningful whitespace
if (data.name == 'text' && !data.prefix) {
textContext = current;
}
stack.push(elem);
};
sax.ontext = function(text) {
if (/\S/.test(text) || textContext) {
if (!textContext)
text = text.trim();
pushToContent({
text: text
});
}
};
sax.onclosetag = function() {
var last = stack.pop();
// Trim text inside <text> tag.
if (last == textContext) {
trim(textContext);
textContext = null;
}
current = stack[stack.length - 1];
};
sax.onerror = function(e) {
callback({ error: 'Error in parsing: ' + e.message });
};
sax.onend = function() {
if (!this.error) callback(root);
};
sax.write(data).close();
function trim(elem) {
if (!elem.content) return elem;
var start = elem.content[0],
end = elem.content[elem.content.length - 1];
while (start && start.content && !start.text) start = start.content[0];
if (start && start.text) start.text = start.text.replace(/^\s+/, '');
while (end && end.content && !end.text) end = end.content[end.content.length - 1];
if (end && end.text) end.text = end.text.replace(/\s+$/, '');
return elem;
}
};