summaryrefslogtreecommitdiff
path: root/node_modules/svgo/plugins/convertStyleToAttrs.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-10-14 15:05:55 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-10-14 15:05:55 +0800
commitc06f7ee0a40255214c477e13d9b956a7e07c2900 (patch)
treef5982a568ef8fab865d0142e71c7494fea3e4c1b /node_modules/svgo/plugins/convertStyleToAttrs.js
parent3fd9400d4dccc25aa29b5702216732e0b7542073 (diff)
postcss,(plugins): nanocss, postcss-preset-env
Diffstat (limited to 'node_modules/svgo/plugins/convertStyleToAttrs.js')
-rw-r--r--node_modules/svgo/plugins/convertStyleToAttrs.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/node_modules/svgo/plugins/convertStyleToAttrs.js b/node_modules/svgo/plugins/convertStyleToAttrs.js
new file mode 100644
index 00000000..5d5107d6
--- /dev/null
+++ b/node_modules/svgo/plugins/convertStyleToAttrs.js
@@ -0,0 +1,137 @@
+'use strict';
+
+const { attrsGroups } = require('./_collections');
+
+exports.name = 'convertStyleToAttrs';
+exports.description = 'converts style to attributes';
+
+/**
+ * @type {(...args: string[]) => string}
+ */
+const g = (...args) => {
+ return '(?:' + args.join('|') + ')';
+};
+
+const stylingProps = attrsGroups.presentation;
+const rEscape = '\\\\(?:[0-9a-f]{1,6}\\s?|\\r\\n|.)'; // Like \" or \2051. Code points consume one space.
+const rAttr = '\\s*(' + g('[^:;\\\\]', rEscape) + '*?)\\s*'; // attribute name like ‘fill’
+const rSingleQuotes = "'(?:[^'\\n\\r\\\\]|" + rEscape + ")*?(?:'|$)"; // string in single quotes: 'smth'
+const rQuotes = '"(?:[^"\\n\\r\\\\]|' + rEscape + ')*?(?:"|$)'; // string in double quotes: "smth"
+const rQuotedString = new RegExp('^' + g(rSingleQuotes, rQuotes) + '$');
+// Parentheses, E.g.: url(data:image/png;base64,iVBO...).
+// ':' and ';' inside of it should be threated as is. (Just like in strings.)
+const rParenthesis =
+ '\\(' + g('[^\'"()\\\\]+', rEscape, rSingleQuotes, rQuotes) + '*?' + '\\)';
+// The value. It can have strings and parentheses (see above). Fallbacks to anything in case of unexpected input.
+const rValue =
+ '\\s*(' +
+ g(
+ '[^!\'"();\\\\]+?',
+ rEscape,
+ rSingleQuotes,
+ rQuotes,
+ rParenthesis,
+ '[^;]*?'
+ ) +
+ '*?' +
+ ')';
+// End of declaration. Spaces outside of capturing groups help to do natural trimming.
+const rDeclEnd = '\\s*(?:;\\s*|$)';
+// Important rule
+const rImportant = '(\\s*!important(?![-(\\w]))?';
+// Final RegExp to parse CSS declarations.
+const regDeclarationBlock = new RegExp(
+ rAttr + ':' + rValue + rImportant + rDeclEnd,
+ 'ig'
+);
+// Comments expression. Honors escape sequences and strings.
+const regStripComments = new RegExp(
+ g(rEscape, rSingleQuotes, rQuotes, '/\\*[^]*?\\*/'),
+ 'ig'
+);
+
+/**
+ * Convert style in attributes. Cleanups comments and illegal declarations (without colon) as a side effect.
+ *
+ * @example
+ * <g style="fill:#000; color: #fff;">
+ * ⬇
+ * <g fill="#000" color="#fff">
+ *
+ * @example
+ * <g style="fill:#000; color: #fff; -webkit-blah: blah">
+ * ⬇
+ * <g fill="#000" color="#fff" style="-webkit-blah: blah">
+ *
+ * @author Kir Belevich
+ *
+ * @type {import('./plugins-types').Plugin<'convertStyleToAttrs'>}
+ */
+exports.fn = (_root, params) => {
+ const { keepImportant = false } = params;
+ return {
+ element: {
+ enter: (node) => {
+ if (node.attributes.style != null) {
+ // ['opacity: 1', 'color: #000']
+ let styles = [];
+ /**
+ * @type {Record<string, string>}
+ */
+ const newAttributes = {};
+
+ // Strip CSS comments preserving escape sequences and strings.
+ const styleValue = node.attributes.style.replace(
+ regStripComments,
+ (match) => {
+ return match[0] == '/'
+ ? ''
+ : match[0] == '\\' && /[-g-z]/i.test(match[1])
+ ? match[1]
+ : match;
+ }
+ );
+
+ regDeclarationBlock.lastIndex = 0;
+ // eslint-disable-next-line no-cond-assign
+ for (var rule; (rule = regDeclarationBlock.exec(styleValue)); ) {
+ if (!keepImportant || !rule[3]) {
+ styles.push([rule[1], rule[2]]);
+ }
+ }
+
+ if (styles.length) {
+ styles = styles.filter(function (style) {
+ if (style[0]) {
+ var prop = style[0].toLowerCase(),
+ val = style[1];
+
+ if (rQuotedString.test(val)) {
+ val = val.slice(1, -1);
+ }
+
+ if (stylingProps.includes(prop)) {
+ newAttributes[prop] = val;
+
+ return false;
+ }
+ }
+
+ return true;
+ });
+
+ Object.assign(node.attributes, newAttributes);
+
+ if (styles.length) {
+ node.attributes.style = styles
+ .map((declaration) => declaration.join(':'))
+ .join(';');
+ } else {
+ delete node.attributes.style;
+ }
+ }
+ }
+ },
+ },
+ };
+};