Skip to content

Commit c29e91f

Browse files
authored
refactor: optimize postcss task (#5085)
1 parent 67565d5 commit c29e91f

File tree

9 files changed

+223
-17
lines changed

9 files changed

+223
-17
lines changed

.reuse/dep5

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,6 @@ Copyright: 2020 SAP SE or an SAP affiliate company and OpenUI5 contributors
3030
License: Apache-2.0
3131

3232

33-
Files: packages/playground/assets/js/webcomponentsjs/* packages/ie11/src/thirdparty/Array.from.js packages/ie11/src/thirdparty/events-polyfills.js packages/ie11/src/thirdparty/Object.assign.js packages/ie11/src/thirdparty/template.js packages/ie11/src/thirdparty/webcomponents-sd-ce-pf.js
34-
Copyright: 2018 The Polymer Project Authors
35-
License: BSD-3-Clause-Clear
36-
3733
Files: packages/base/dist/sap/ui/thirdparty/caja-html-sanitizer.js
3834
Copyright: Google Inc.
3935
License: Apache-2.0
@@ -46,3 +42,11 @@ License: MIT
4642
Files: packages/playground/assets/js/vendor/lunr.min.js
4743
Copyright: 2017 Oliver Nightingale
4844
License: MIT
45+
46+
Files: packages/tools/lib/copy-and-watch/index.js
47+
Copyright: 2017 Aleksandr Zonov
48+
License: MIT
49+
50+
Files: packages/tools/lib/postcss-combine-duplicated-selectors/index.js
51+
Copyright: 2016 Christian Murphy
52+
License: MIT

packages/base/hash.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
X8vjgfCUlDRvJz9L9e5OzLqCCdQ=
1+
owW4JG1/w/h6BH4GK+Akd5v6xzc=

packages/theming/config/postcss.themes/postcss.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const combineSelectors = require('postcss-combine-duplicated-selectors');
1+
const combineSelectors = require('@ui5/webcomponents-tools/lib/postcss-combine-duplicated-selectors/index.js');
22
const postcssImport = require('postcss-import');
33
const cssnano = require('cssnano');
44
const postcssCSStoJSON = require('@ui5/webcomponents-tools/lib/postcss-css-to-json/index.js');

packages/theming/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
"json-beautify": "^1.1.1",
4141
"nps": "^5.10.0",
4242
"postcss": "^8.4.5",
43-
"postcss-combine-duplicated-selectors": "^10.0.3",
4443
"postcss-import": "^14.0.2",
4544
"resolve": "^1.20.0"
4645
},

packages/tools/components-package/postcss.themes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const postcssImport = require('postcss-import');
2-
const combineSelectors = require('postcss-combine-duplicated-selectors');
2+
const combineSelectors = require('../lib/postcss-combine-duplicated-selectors/index.js');
33
const postcssCSStoJSON = require('../lib/postcss-css-to-json/index.js');
44
const postcssCSStoESM = require('../lib/postcss-css-to-esm/index.js');
55
const cssnano = require('cssnano');

packages/tools/lib/copy-and-watch/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2017
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
125
const fs = require('fs');
226
const path = require('path');
327
const chokidar = require('chokidar');
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2016 Christian Murphy
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
const parser = require('postcss-selector-parser');
26+
const name = "postcss-combine-duplicated-selectors";
27+
28+
/**
29+
* Ensure that attributes with different quotes match.
30+
* @param {Object} selector - postcss selector node
31+
*/
32+
function normalizeAttributes(selector) {
33+
selector.walkAttributes((node) => {
34+
if (node.value) {
35+
// remove quotes
36+
node.value = node.value.replace(/'|\\'|"|\\"/g, '');
37+
}
38+
});
39+
}
40+
41+
/**
42+
* Sort class and id groups alphabetically
43+
* @param {Object} selector - postcss selector node
44+
*/
45+
function sortGroups(selector) {
46+
selector.each((subSelector) => {
47+
subSelector.nodes.sort((a, b) => {
48+
// different types cannot be sorted
49+
if (a.type !== b.type) {
50+
return 0;
51+
}
52+
53+
// sort alphabetically
54+
return a.value < b.value ? -1 : 1;
55+
});
56+
});
57+
58+
selector.sort((a, b) => (a.nodes.join('') < b.nodes.join('') ? -1 : 1));
59+
}
60+
61+
/**
62+
* Remove duplicated properties
63+
* @param {Object} selector - postcss selector node
64+
* @param {Boolean} exact
65+
*/
66+
function removeDupProperties(selector, exact) {
67+
if (!exact) { // Remove duplicated properties, regardless of value
68+
const retainedProps = new Set();
69+
70+
for (let actIndex = selector.nodes.length - 1; actIndex >= 1; actIndex--) {
71+
const prop = selector.nodes[actIndex].prop;
72+
if (prop !== undefined) {
73+
if (!retainedProps.has(prop)) {
74+
retainedProps.add(prop); // Mark the prop as retained, all other occurrences must be removed
75+
} else {
76+
selector.nodes[actIndex].remove(); // This occurrence of the prop must be removed
77+
}
78+
}
79+
}
80+
} else {
81+
// Remove duplicated properties from bottom to top ()
82+
for (let actIndex = selector.nodes.length - 1; actIndex >= 1; actIndex--) {
83+
for (let befIndex = actIndex - 1; befIndex >= 0; befIndex--) {
84+
if (
85+
selector.nodes[actIndex].prop === selector.nodes[befIndex].prop &&
86+
selector.nodes[actIndex].value === selector.nodes[befIndex].value
87+
) {
88+
selector.nodes[befIndex].remove();
89+
actIndex--;
90+
}
91+
}
92+
}
93+
}
94+
}
95+
96+
const uniformStyle = parser((selector) => {
97+
normalizeAttributes(selector);
98+
sortGroups(selector);
99+
});
100+
101+
const defaultOptions = {
102+
removeDuplicatedProperties: false,
103+
};
104+
105+
module.exports = (options) => {
106+
options = Object.assign({}, defaultOptions, options);
107+
return {
108+
postcssPlugin: name,
109+
prepare() {
110+
// Create a map to store maps
111+
const mapTable = new Map();
112+
// root map to store root selectors
113+
mapTable.set('root', new Map());
114+
115+
return {
116+
Rule: (rule) => {
117+
let map;
118+
// Check selector parent for any at rule
119+
if (rule.parent.type === 'atrule') {
120+
// Use name and query params as the key
121+
const query =
122+
rule.parent.name.toLowerCase() +
123+
rule.parent.params.replace(/\s+/g, '');
124+
125+
// See if this query key is already in the map table
126+
map = mapTable.has(query) ? // If it is use it
127+
mapTable.get(query) : // if not set it and get it
128+
mapTable.set(query, new Map()).get(query);
129+
} else {
130+
// Otherwise we are dealing with a selector in the root
131+
map = mapTable.get('root');
132+
}
133+
134+
// create a uniform selector
135+
const selector = uniformStyle.processSync(rule.selector, {
136+
lossless: false,
137+
});
138+
139+
if (map.has(selector)) {
140+
// store original rule as destination
141+
const destination = map.get(selector);
142+
143+
// check if node has already been processed
144+
if (destination === rule) return;
145+
146+
// move declarations to original rule
147+
while (rule.nodes.length > 0) {
148+
destination.append(rule.nodes[0]);
149+
}
150+
// remove duplicated rule
151+
rule.remove();
152+
153+
if (
154+
options.removeDuplicatedProperties ||
155+
options.removeDuplicatedValues
156+
) {
157+
removeDupProperties(
158+
destination,
159+
options.removeDuplicatedValues,
160+
);
161+
}
162+
} else {
163+
if (
164+
options.removeDuplicatedProperties ||
165+
options.removeDuplicatedValues
166+
) {
167+
removeDupProperties(rule, options.removeDuplicatedValues);
168+
}
169+
// add new selector to symbol table
170+
map.set(selector, rule);
171+
}
172+
},
173+
};
174+
},
175+
};
176+
};
177+
178+
module.exports.postcss = true;

packages/tools/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@
5656
"nps": "^5.10.0",
5757
"postcss": "^8.4.5",
5858
"postcss-cli": "^9.1.0",
59-
"postcss-combine-duplicated-selectors": "^10.0.3",
6059
"postcss-import": "^14.0.2",
60+
"postcss-selector-parser": "^6.0.10",
6161
"properties-reader": "^2.2.0",
6262
"recursive-readdir": "^2.2.2",
6363
"resolve": "^1.20.0",

yarn.lock

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5611,13 +5611,6 @@ postcss-colormin@^4.0.3:
56115611
postcss "^7.0.0"
56125612
postcss-value-parser "^3.0.0"
56135613

5614-
postcss-combine-duplicated-selectors@^10.0.3:
5615-
version "10.0.3"
5616-
resolved "https://registry.yarnpkg.com/postcss-combine-duplicated-selectors/-/postcss-combine-duplicated-selectors-10.0.3.tgz#71e8b6783e99cd560cf08ba7b896ad0db318c11c"
5617-
integrity sha512-IP0BmwFloCskv7DV7xqvzDXqMHpwdczJa6ZvIW8abgHdcIHs9mCJX2ltFhu3EwA51ozp13DByng30+Ke+eIExA==
5618-
dependencies:
5619-
postcss-selector-parser "^6.0.4"
5620-
56215614
postcss-convert-values@^4.0.1:
56225615
version "4.0.1"
56235616
resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz#ca3813ed4da0f812f9d43703584e449ebe189a7f"
@@ -5860,7 +5853,15 @@ postcss-selector-parser@^3.0.0:
58605853
indexes-of "^1.0.1"
58615854
uniq "^1.0.1"
58625855

5863-
postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
5856+
postcss-selector-parser@^6.0.10:
5857+
version "6.0.10"
5858+
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
5859+
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
5860+
dependencies:
5861+
cssesc "^3.0.0"
5862+
util-deprecate "^1.0.2"
5863+
5864+
postcss-selector-parser@^6.0.2:
58645865
version "6.0.9"
58655866
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f"
58665867
integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==

0 commit comments

Comments
 (0)