index.cjs.js
3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var postcss = _interopDefault(require('postcss'));
var selectorParser = _interopDefault(require('postcss-selector-parser'));
var index = postcss.plugin('postcss-dir-pseudo-class', opts => {
const dir = Object(opts).dir;
const preserve = Boolean(Object(opts).preserve);
return root => {
// walk rules using the :dir pseudo-class
root.walkRules(/:dir\([^\)]*\)/, rule => {
let currentRule = rule; // conditionally preserve the original rule
if (preserve) {
currentRule = rule.cloneBefore();
} // update the rule selector
currentRule.selector = selectorParser(selectors => {
// for each (comma separated) selector
selectors.nodes.forEach(selector => {
// walk all selector nodes that are :dir pseudo-classes
selector.walk(node => {
if ('pseudo' === node.type && ':dir' === node.value) {
// previous and next selector nodes
const prev = node.prev();
const next = node.next();
const prevIsSpaceCombinator = prev && prev.type && 'combinator' === prev.type && ' ' === prev.value;
const nextIsSpaceCombinator = next && next.type && 'combinator' === next.type && ' ' === next.value; // preserve the selector tree
if (prevIsSpaceCombinator && (nextIsSpaceCombinator || !next)) {
node.replaceWith(selectorParser.universal());
} else {
node.remove();
} // conditionally prepend a combinator before inserting the [dir] attribute
const first = selector.nodes[0];
const firstIsSpaceCombinator = first && 'combinator' === first.type && ' ' === first.value;
const firstIsHtml = first && 'tag' === first.type && 'html' === first.value;
const firstIsRoot = first && 'pseudo' === first.type && ':root' === first.value;
if (first && !firstIsHtml && !firstIsRoot && !firstIsSpaceCombinator) {
selector.prepend(selectorParser.combinator({
value: ' '
}));
} // value of the :dir pseudo-class
const value = node.nodes.toString(); // whether :dir matches the presumed direction
const isdir = dir === value; // [dir] attribute
const dirAttr = selectorParser.attribute({
attribute: 'dir',
operator: '=',
quoteMark: '"',
value: `"${value}"`
}); // not[dir] attribute
const notDirAttr = selectorParser.pseudo({
value: `${firstIsHtml || firstIsRoot ? '' : 'html'}:not`
});
notDirAttr.append(selectorParser.attribute({
attribute: 'dir',
operator: '=',
quoteMark: '"',
value: `"${'ltr' === value ? 'rtl' : 'ltr'}"`
}));
if (isdir) {
// if the direction is presumed
if (firstIsHtml) {
// insert :root after html tag
selector.insertAfter(first, notDirAttr);
} else {
// prepend :root
selector.prepend(notDirAttr);
}
} else if (firstIsHtml) {
// otherwise, insert dir attribute after html tag
selector.insertAfter(first, dirAttr);
} else {
// otherwise, prepend the dir attribute
selector.prepend(dirAttr);
}
}
});
});
}).processSync(currentRule.selector);
});
};
});
module.exports = index;
//# sourceMappingURL=index.cjs.js.map