typography-stylecss 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/utils.js ADDED
@@ -0,0 +1,120 @@
1
+ const parser = require('postcss-selector-parser')
2
+ const parseSelector = parser()
3
+
4
+ function isObject(value) {
5
+ return typeof value === 'object' && value !== null
6
+ }
7
+
8
+ function isPlainObject(value) {
9
+ if (typeof value !== 'object' || value === null) {
10
+ return false
11
+ }
12
+
13
+ if (Object.prototype.toString.call(value) !== '[object Object]') {
14
+ return false
15
+ }
16
+
17
+ if (Object.getPrototypeOf(value) === null) {
18
+ return true
19
+ }
20
+
21
+ let proto = value
22
+ while (Object.getPrototypeOf(proto) !== null) {
23
+ proto = Object.getPrototypeOf(proto)
24
+ }
25
+
26
+ return Object.getPrototypeOf(value) === proto
27
+ }
28
+
29
+ function merge(target, ...sources) {
30
+ if (!sources.length) return target
31
+ const source = sources.shift()
32
+
33
+ if (isObject(target) && isObject(source)) {
34
+ for (const key in source) {
35
+ if (Array.isArray(source[key])) {
36
+ if (!target[key]) target[key] = []
37
+ source[key].forEach((item, index) => {
38
+ if (isPlainObject(item) && isPlainObject(target[key][index])) {
39
+ target[key][index] = merge(target[key][index], item)
40
+ } else {
41
+ target[key][index] = item
42
+ }
43
+ })
44
+ } else if (isPlainObject(source[key])) {
45
+ if (!target[key]) target[key] = {}
46
+ merge(target[key], source[key])
47
+ } else {
48
+ target[key] = source[key]
49
+ }
50
+ }
51
+ }
52
+
53
+ return merge(target, ...sources)
54
+ }
55
+
56
+ function castArray(value) {
57
+ return Array.isArray(value) ? value : [value]
58
+ }
59
+
60
+ module.exports = {
61
+ isObject,
62
+ isPlainObject,
63
+ merge,
64
+ castArray,
65
+ isUsableColor(color, values) {
66
+ return isPlainObject(values) && color !== 'gray' && values[600]
67
+ },
68
+
69
+ /**
70
+ * @param {string} selector
71
+ */
72
+ commonTrailingPseudos(selector) {
73
+ let ast = parseSelector.astSync(selector)
74
+
75
+ /** @type {import('postcss-selector-parser').Pseudo[][]} */
76
+ let matrix = []
77
+
78
+ // Put the pseudo elements in reverse order in a sparse, column-major 2D array
79
+ for (let [i, sel] of ast.nodes.entries()) {
80
+ for (const [j, child] of [...sel.nodes].reverse().entries()) {
81
+ // We only care about pseudo elements
82
+ if (child.type !== 'pseudo' || !child.value.startsWith('::')) {
83
+ break
84
+ }
85
+
86
+ matrix[j] = matrix[j] || []
87
+ matrix[j][i] = child
88
+ }
89
+ }
90
+
91
+ let trailingPseudos = parser.selector()
92
+
93
+ // At this point the pseudo elements are in a column-major 2D array
94
+ // This means each row contains one "column" of pseudo elements from each selector
95
+ // We can compare all the pseudo elements in a row to see if they are the same
96
+ for (const pseudos of matrix) {
97
+ // It's a sparse 2D array so there are going to be holes in the rows
98
+ // We skip those
99
+ if (!pseudos) {
100
+ continue
101
+ }
102
+
103
+ let values = new Set(pseudos.map((p) => p.value))
104
+
105
+ // The pseudo elements are not the same
106
+ if (values.size > 1) {
107
+ break
108
+ }
109
+
110
+ pseudos.forEach((pseudo) => pseudo.remove())
111
+ trailingPseudos.prepend(pseudos[0])
112
+ }
113
+
114
+ if (trailingPseudos.nodes.length) {
115
+ return [trailingPseudos.toString(), ast.toString()]
116
+ }
117
+
118
+ return [null, selector]
119
+ },
120
+ }