summaryrefslogtreecommitdiff
path: root/node_modules/postcss-merge-longhand/src/lib/decl/boxBase.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/postcss-merge-longhand/src/lib/decl/boxBase.js')
-rw-r--r--node_modules/postcss-merge-longhand/src/lib/decl/boxBase.js117
1 files changed, 117 insertions, 0 deletions
diff --git a/node_modules/postcss-merge-longhand/src/lib/decl/boxBase.js b/node_modules/postcss-merge-longhand/src/lib/decl/boxBase.js
new file mode 100644
index 00000000..c995b712
--- /dev/null
+++ b/node_modules/postcss-merge-longhand/src/lib/decl/boxBase.js
@@ -0,0 +1,117 @@
+'use strict';
+const stylehacks = require('stylehacks');
+const canMerge = require('../canMerge.js');
+const getDecls = require('../getDecls.js');
+const minifyTrbl = require('../minifyTrbl.js');
+const parseTrbl = require('../parseTrbl.js');
+const insertCloned = require('../insertCloned.js');
+const mergeRules = require('../mergeRules.js');
+const mergeValues = require('../mergeValues.js');
+const trbl = require('../trbl.js');
+const isCustomProp = require('../isCustomProp.js');
+const canExplode = require('../canExplode.js');
+
+/**
+ * @param {string} prop
+ * @return {{explode: (rule: import('postcss').Rule) => void, merge: (rule: import('postcss').Rule) => void}}
+ */
+module.exports = (prop) => {
+ const properties = trbl.map((direction) => `${prop}-${direction}`);
+ /** @type {(rule: import('postcss').Rule) => void} */
+ const cleanup = (rule) => {
+ let decls = getDecls(rule, [prop].concat(properties));
+
+ while (decls.length) {
+ const lastNode = decls[decls.length - 1];
+
+ // remove properties of lower precedence
+ const lesser = decls.filter(
+ (node) =>
+ !stylehacks.detect(lastNode) &&
+ !stylehacks.detect(node) &&
+ node !== lastNode &&
+ node.important === lastNode.important &&
+ lastNode.prop === prop &&
+ node.prop !== lastNode.prop
+ );
+
+ for (const node of lesser) {
+ node.remove();
+ }
+ decls = decls.filter((node) => !lesser.includes(node));
+
+ // get duplicate properties
+ let duplicates = decls.filter(
+ (node) =>
+ !stylehacks.detect(lastNode) &&
+ !stylehacks.detect(node) &&
+ node !== lastNode &&
+ node.important === lastNode.important &&
+ node.prop === lastNode.prop &&
+ !(!isCustomProp(node) && isCustomProp(lastNode))
+ );
+
+ for (const node of duplicates) {
+ node.remove();
+ }
+ decls = decls.filter(
+ (node) => node !== lastNode && !duplicates.includes(node)
+ );
+ }
+ };
+
+ const processor = {
+ /** @type {(rule: import('postcss').Rule) => void} */
+ explode: (rule) => {
+ rule.walkDecls(new RegExp('^' + prop + '$', 'i'), (decl) => {
+ if (!canExplode(decl)) {
+ return;
+ }
+
+ if (stylehacks.detect(decl)) {
+ return;
+ }
+
+ const values = parseTrbl(decl.value);
+
+ trbl.forEach((direction, index) => {
+ insertCloned(
+ /** @type {import('postcss').Rule} */ (decl.parent),
+ decl,
+ {
+ prop: properties[index],
+ value: values[index],
+ }
+ );
+ });
+
+ decl.remove();
+ });
+ },
+ /** @type {(rule: import('postcss').Rule) => void} */
+ merge: (rule) => {
+ mergeRules(rule, properties, (rules, lastNode) => {
+ if (canMerge(rules) && !rules.some(stylehacks.detect)) {
+ insertCloned(
+ /** @type {import('postcss').Rule} */ (lastNode.parent),
+ lastNode,
+ {
+ prop,
+ value: minifyTrbl(mergeValues(...rules)),
+ }
+ );
+ for (const node of rules) {
+ node.remove();
+ }
+
+ return true;
+ }
+ return false;
+ });
+
+ cleanup(rule);
+ },
+ };
+
+ return processor;
+};