assetgraph
Version:
An auto discovery dependency graph based optimization framework for web pages and applications
216 lines (208 loc) • 6.67 kB
JavaScript
const JSDOM = require('jsdom').JSDOM;
const Xml = require('./Xml');
const {
addMissingNamespaces,
removeAddedNamespaces,
} = require('../util/svgNamespaces');
class Svg extends Xml {
_initJsdom(text) {
const jsdomSrc = this.isInline ? addMissingNamespaces(text) : text;
return new JSDOM(jsdomSrc, {
url: this.url ? this.url : undefined, // So that errors get reported with the url (awaiting https://github.com/jsdom/jsdom/pull/2630)
contentType: 'application/svg+xml',
});
}
_serializeJsdom(jsdom) {
const serialized = jsdom.serialize();
const svgSrc = this.isInline
? removeAddedNamespaces(serialized)
: serialized;
return `${this.xmlDeclaration}${svgSrc}`;
}
findOutgoingRelationsInParseTree() {
const outgoingRelations = super.findOutgoingRelationsInParseTree();
if (!this.isLoaded) {
return outgoingRelations;
}
const queue = [this.parseTree];
let href;
let isXlink;
while (queue.length > 0) {
const node = queue.shift();
if (node.childNodes) {
for (let i = node.childNodes.length - 1; i >= 0; i -= 1) {
queue.unshift(node.childNodes[i]);
}
}
if (node.nodeType === 1) {
// ELEMENT_NODE
for (const attribute of Array.from(node.attributes)) {
if (/^on/i.test(attribute.nodeName)) {
outgoingRelations.push({
type: 'SvgInlineEventHandler',
attributeName: attribute.nodeName,
to: {
type: 'JavaScript',
isExternalizable: false,
text: `function bogus() {${attribute.nodeValue}}`,
},
node,
});
}
}
const nodeName = node.nodeName.toLowerCase();
if (nodeName === 'script') {
const type = node.getAttribute('type');
if (!type || type === 'text/javascript') {
href = null;
isXlink = null;
if (node.getAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
href = node.getAttributeNS(
'http://www.w3.org/1999/xlink',
'href'
);
isXlink = true;
} else if (node.hasAttribute('href')) {
href = node.getAttribute('href');
isXlink = false;
}
if (typeof href === 'string') {
outgoingRelations.push({
type: 'SvgScript',
isXlink,
href,
node,
});
} else {
outgoingRelations.push({
type: 'SvgScript',
to: {
type: 'JavaScript',
text: node.firstChild ? node.firstChild.nodeValue : '',
},
node,
});
}
}
} else if (nodeName === 'style') {
outgoingRelations.push({
type: 'SvgStyle',
to: {
type: 'Css',
text: node.firstChild ? node.firstChild.nodeValue : '',
},
node,
});
} else if (nodeName === 'image') {
href = null;
isXlink = null;
if (node.getAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
href = node.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
isXlink = true;
} else if (node.hasAttribute('href')) {
href = node.getAttribute('href');
isXlink = false;
}
if (href) {
outgoingRelations.push({
type: 'SvgImage',
isXlink,
href,
node,
});
}
} else if (nodeName === 'a') {
href = null;
isXlink = null;
if (node.getAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
href = node.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
isXlink = true;
} else if (node.hasAttribute('href')) {
href = node.getAttribute('href');
isXlink = false;
}
if (href) {
outgoingRelations.push({
type: 'SvgAnchor',
isXlink,
href,
node,
});
}
} else if (nodeName === 'pattern') {
href = null;
isXlink = null;
if (node.hasAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
href = node.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
isXlink = true;
} else if (node.hasAttribute('href')) {
href = node.getAttribute('href');
isXlink = false;
}
if (href) {
outgoingRelations.push({
type: 'SvgPattern',
isXlink,
href,
node,
});
}
} else if (nodeName === 'use') {
href = null;
isXlink = null;
if (node.hasAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
href = node.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
isXlink = true;
} else if (node.hasAttribute('href')) {
href = node.getAttribute('href');
isXlink = false;
}
if (href) {
outgoingRelations.push({
type: 'SvgUse',
isXlink,
href,
node,
});
}
} else if (nodeName === 'font-face-uri') {
href = null;
isXlink = null;
if (node.hasAttributeNS('http://www.w3.org/1999/xlink', 'href')) {
href = node.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
isXlink = true;
} else if (node.hasAttribute('href')) {
href = node.getAttribute('href');
isXlink = false;
}
if (href) {
outgoingRelations.push({
type: 'SvgFontFaceUri',
isXlink,
href,
node,
});
}
}
if (node.hasAttribute('style')) {
outgoingRelations.push({
type: 'SvgStyleAttribute',
to: {
type: 'Css',
isExternalizable: false,
text: `bogusselector {${node.getAttribute('style')}}`,
},
node,
});
}
}
}
return outgoingRelations;
}
}
Object.assign(Svg.prototype, {
contentType: 'image/svg+xml',
isImage: true,
supportedExtensions: ['.svg'],
});
module.exports = Svg;