diff --git a/lib/xast.js b/lib/xast.js index 4b9d4960..49edf692 100644 --- a/lib/xast.js +++ b/lib/xast.js @@ -39,22 +39,6 @@ const matches = (node, selector) => { }; exports.matches = matches; -/** - * @type {(node: XastChild, name: string) => null | XastChild} - */ -const closestByName = (node, name) => { - let currentNode = node; - while (currentNode) { - if (currentNode.type === 'element' && currentNode.name === name) { - return currentNode; - } - // @ts-ignore parentNode is hidden from public usage - currentNode = currentNode.parentNode; - } - return null; -}; -exports.closestByName = closestByName; - const visitSkip = Symbol(); exports.visitSkip = visitSkip; diff --git a/plugins/removeHiddenElems.js b/plugins/removeHiddenElems.js index a8499e24..16140f4a 100644 --- a/plugins/removeHiddenElems.js +++ b/plugins/removeHiddenElems.js @@ -1,8 +1,9 @@ 'use strict'; const { + visit, + visitSkip, querySelector, - closestByName, detachNodeFromParent, } = require('../lib/xast.js'); const { collectStylesheet, computeStyle } = require('../lib/style.js'); @@ -67,6 +68,30 @@ exports.fn = (root, params) => { } = params; const stylesheet = collectStylesheet(root); + visit(root, { + element: { + enter: (node, parentNode) => { + // transparent element inside clipPath still affect clipped elements + if (node.name === 'clipPath') { + return visitSkip; + } + const computedStyle = computeStyle(stylesheet, node); + // opacity="0" + // + // https://www.w3.org/TR/SVG11/masking.html#ObjectAndGroupOpacityProperties + if ( + opacity0 && + computedStyle.opacity && + computedStyle.opacity.type === 'static' && + computedStyle.opacity.value === '0' + ) { + detachNodeFromParent(node, parentNode); + return; + } + }, + }, + }); + return { element: { enter: (node, parentNode) => { @@ -102,21 +127,6 @@ exports.fn = (root, params) => { return; } - // opacity="0" - // - // https://www.w3.org/TR/SVG11/masking.html#ObjectAndGroupOpacityProperties - if ( - opacity0 && - computedStyle.opacity && - computedStyle.opacity.type === 'static' && - computedStyle.opacity.value === '0' && - // transparent element inside clipPath still affect clipped elements - closestByName(node, 'clipPath') == null - ) { - detachNodeFromParent(node, parentNode); - return; - } - // Circles with zero radius // // https://www.w3.org/TR/SVG11/shapes.html#CircleElementRAttribute