diff --git a/src/core/svgo.cpp b/src/core/svgo.cpp index 33348d43b..e0a1da0ca 100644 --- a/src/core/svgo.cpp +++ b/src/core/svgo.cpp @@ -117,45 +117,63 @@ void SVGO::removeUselessDefs(QDomDocument &doc) QDomElement root = doc.documentElement(); if (root.isNull()) { return; } - QDomElement defs = root.firstChildElement("defs"); - if (defs.isNull()) { return; } + QDomNodeList defsList = doc.elementsByTagNameNS("http://www.w3.org/2000/svg", "defs"); + if (defsList.isEmpty()) { + defsList = doc.elementsByTagName("defs"); + } - QDomNode defChild = defs.firstChild(); - while (!defChild.isNull()) { - QDomNode nextDefChild = defChild.nextSibling(); + QString fullSvgContent = doc.toString(); - if (defChild.isElement()) { - QDomElement defElem = defChild.toElement(); - QString id = defElem.attribute("id"); + for (int d = 0; d < defsList.count(); ++d) { + QDomElement defs = defsList.at(d).toElement(); + QDomNode child = defs.firstChild(); - if (id.isEmpty()) { - defChild = nextDefChild; - continue; - } + while (!child.isNull()) { + QDomNode nextChild = child.nextSibling(); - QString searchId = "#" + id; - bool isReferenced = false; - - QDomNodeList allElements = doc.elementsByTagName("*"); - for (int i = 0; i < allElements.count(); ++i) { - QDomElement elem = allElements.at(i).toElement(); - QDomNamedNodeMap attrs = elem.attributes(); - for (int j = 0; j < attrs.count(); ++j) { - QDomAttr attr = attrs.item(j).toAttr(); - if (attr.value().contains(searchId)) { - isReferenced = true; - break; + if (child.isElement()) { + QDomElement defElem = child.toElement(); + QString id = defElem.attribute("id"); + + if (!id.isEmpty()) { + QString searchId = "#" + id; + if (!isIdReferenced(root, id, defElem)) { + defs.removeChild(child); } } - if (isReferenced) { break; } } + child = nextChild; + } + + if (!defs.hasChildNodes()) { + defs.parentNode().removeChild(defs); + } + } +} - if (!isReferenced) { defs.removeChild(defChild); } +bool SVGO::isIdReferenced(const QDomElement ¤tElement, + const QString &id, + const QDomElement &originalDef) +{ + if (currentElement != originalDef) { + QDomNamedNodeMap attrs = currentElement.attributes(); + QString searchPattern = "#" + id; + for (int i = 0; i < attrs.count(); ++i) { + if (attrs.item(i).toAttr().value().contains(searchPattern)) { + return true; + } + } + } + + QDomElement child = currentElement.firstChildElement(); + while (!child.isNull()) { + if (isIdReferenced(child, id, originalDef)) { + return true; } - defChild = nextDefChild; + child = child.nextSiblingElement(); } - if (!defs.hasChildNodes()) { root.removeChild(defs); } + return false; } void SVGO::removeProcessingInstructions(QDomDocument &doc) diff --git a/src/core/svgo.h b/src/core/svgo.h index 4211fe8d2..9fe204a0e 100644 --- a/src/core/svgo.h +++ b/src/core/svgo.h @@ -40,6 +40,9 @@ namespace Friction private: static bool recursiveOptimize(QDomElement &element); static void removeUselessDefs(QDomDocument &doc); + static bool isIdReferenced(const QDomElement ¤tElement, + const QString &id, + const QDomElement &originalDef); static void removeProcessingInstructions(QDomDocument &doc); static int countElementChildren(const QDomElement &element); static QString minify(const QString &xml);