source: frontend/node_modules/tailwindcss/src/lib/collapseDuplicateDeclarations.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 2.9 KB
RevLine 
[9af201e]1export default function collapseDuplicateDeclarations() {
2 return (root) => {
3 root.walkRules((node) => {
4 let seen = new Map()
5 let droppable = new Set([])
6 let byProperty = new Map()
7
8 node.walkDecls((decl) => {
9 // This could happen if we have nested selectors. In that case the
10 // parent will loop over all its declarations but also the declarations
11 // of nested rules. With this we ensure that we are shallowly checking
12 // declarations.
13 if (decl.parent !== node) {
14 return
15 }
16
17 if (seen.has(decl.prop)) {
18 // Exact same value as what we have seen so far
19 if (seen.get(decl.prop).value === decl.value) {
20 // Keep the last one, drop the one we've seen so far
21 droppable.add(seen.get(decl.prop))
22 // Override the existing one with the new value. This is necessary
23 // so that if we happen to have more than one declaration with the
24 // same value, that we keep removing the previous one. Otherwise we
25 // will only remove the *first* one.
26 seen.set(decl.prop, decl)
27 return
28 }
29
30 // Not the same value, so we need to check if we can merge it so
31 // let's collect it first.
32 if (!byProperty.has(decl.prop)) {
33 byProperty.set(decl.prop, new Set())
34 }
35
36 byProperty.get(decl.prop).add(seen.get(decl.prop))
37 byProperty.get(decl.prop).add(decl)
38 }
39
40 seen.set(decl.prop, decl)
41 })
42
43 // Drop all the duplicate declarations with the exact same value we've
44 // already seen so far.
45 for (let decl of droppable) {
46 decl.remove()
47 }
48
49 // Analyze the declarations based on its unit, drop all the declarations
50 // with the same unit but the last one in the list.
51 for (let declarations of byProperty.values()) {
52 let byUnit = new Map()
53
54 for (let decl of declarations) {
55 let unit = resolveUnit(decl.value)
56 if (unit === null) {
57 // We don't have a unit, so should never try and collapse this
58 // value. This is because we can't know how to do it in a correct
59 // way (e.g.: overrides for older browsers)
60 continue
61 }
62
63 if (!byUnit.has(unit)) {
64 byUnit.set(unit, new Set())
65 }
66
67 byUnit.get(unit).add(decl)
68 }
69
70 for (let declarations of byUnit.values()) {
71 // Get all but the last one
72 let removableDeclarations = Array.from(declarations).slice(0, -1)
73
74 for (let decl of removableDeclarations) {
75 decl.remove()
76 }
77 }
78 }
79 })
80 }
81}
82
83let UNITLESS_NUMBER = Symbol('unitless-number')
84
85function resolveUnit(input) {
86 let result = /^-?\d*.?\d+([\w%]+)?$/g.exec(input)
87
88 if (result) {
89 return result[1] ?? UNITLESS_NUMBER
90 }
91
92 return null
93}
Note: See TracBrowser for help on using the repository browser.