From 02974ba683198d623daeab07debd514c8a74cf81 Mon Sep 17 00:00:00 2001 From: John Kenny Date: Sun, 11 Aug 2024 09:19:21 -0700 Subject: [PATCH] Disable inline styles by default if CSS at rules are present. --- plugins/inlineStyles.js | 18 +++++++++----- plugins/plugins-types.d.ts | 2 ++ test/plugins/inlineStyles.13.svg.txt | 4 ++++ test/plugins/inlineStyles.14.svg.txt | 2 +- test/plugins/inlineStyles.29.svg.txt | 35 ++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 test/plugins/inlineStyles.29.svg.txt diff --git a/plugins/inlineStyles.js b/plugins/inlineStyles.js index 26b4314b8..e2e9cd25d 100644 --- a/plugins/inlineStyles.js +++ b/plugins/inlineStyles.js @@ -39,6 +39,7 @@ const preservedPseudos = [ */ export const fn = (root, params) => { const { + disableIfAtRulesPresent = true, onlyMatchedOnce = true, removeMatchedSelectors = true, useMqs = ['', 'screen'], @@ -58,11 +59,12 @@ export const fn = (root, params) => { * }[]} */ let selectors = []; + let deoptimized = false; return { element: { enter: (node, parentNode) => { - if (node.name === 'foreignObject') { + if (deoptimized || node.name === 'foreignObject') { return visitSkip; } if (node.name !== 'style' || node.children.length === 0) { @@ -103,14 +105,18 @@ export const fn = (root, params) => { const atrule = this.atrule; // skip media queries not included into useMqs param - let mediaQuery = ''; + let atRuleText = ''; if (atrule != null) { - mediaQuery = atrule.name; + atRuleText = atrule.name; if (atrule.prelude != null) { - mediaQuery += ` ${csstree.generate(atrule.prelude)}`; + atRuleText += ` ${csstree.generate(atrule.prelude)}`; } } - if (!useMqs.includes(mediaQuery)) { + if (disableIfAtRulesPresent && atRuleText !== '') { + deoptimized = true; + return; + } + if (!useMqs.includes(atRuleText)) { return; } @@ -167,7 +173,7 @@ export const fn = (root, params) => { root: { exit: () => { - if (styles.length === 0) { + if (deoptimized || styles.length === 0) { return; } const sortedSelectors = selectors diff --git a/plugins/plugins-types.d.ts b/plugins/plugins-types.d.ts index bdd5de8ba..579d6a288 100644 --- a/plugins/plugins-types.d.ts +++ b/plugins/plugins-types.d.ts @@ -77,6 +77,8 @@ type DefaultPlugins = { }; mergeStyles: void; inlineStyles: { + /** If true, do not inline styles if any CSS at rules are present. */ + disableIfAtRulesPresent?: boolean; /** * Inlines selectors that match once only. * diff --git a/test/plugins/inlineStyles.13.svg.txt b/test/plugins/inlineStyles.13.svg.txt index b352cda99..7f4098ac5 100644 --- a/test/plugins/inlineStyles.13.svg.txt +++ b/test/plugins/inlineStyles.13.svg.txt @@ -64,3 +64,7 @@ + +@@@ + +{"disableIfAtRulesPresent":false} \ No newline at end of file diff --git a/test/plugins/inlineStyles.14.svg.txt b/test/plugins/inlineStyles.14.svg.txt index 22c635849..003e5f28c 100644 --- a/test/plugins/inlineStyles.14.svg.txt +++ b/test/plugins/inlineStyles.14.svg.txt @@ -27,4 +27,4 @@ @@@ -{"useMqs": ["media only screen and (min-device-width:320px) and (max-device-width:480px) and (-webkit-min-device-pixel-ratio:2)"]} +{"useMqs": ["media only screen and (min-device-width:320px) and (max-device-width:480px) and (-webkit-min-device-pixel-ratio:2)"],"disableIfAtRulesPresent":false} diff --git a/test/plugins/inlineStyles.29.svg.txt b/test/plugins/inlineStyles.29.svg.txt new file mode 100644 index 000000000..84dbed253 --- /dev/null +++ b/test/plugins/inlineStyles.29.svg.txt @@ -0,0 +1,35 @@ +Styles should not be inlined in the presence of media queries. + +See: https://github.com/svg/svgo/issues/1834 + +=== + + + + + + +@@@ + + + + +