1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5 | }) : (function(o, m, k, k2) {
|
6 | if (k2 === undefined) k2 = k;
|
7 | o[k2] = m[k];
|
8 | }));
|
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11 | }) : function(o, v) {
|
12 | o["default"] = v;
|
13 | });
|
14 | var __importStar = (this && this.__importStar) || function (mod) {
|
15 | if (mod && mod.__esModule) return mod;
|
16 | var result = {};
|
17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18 | __setModuleDefault(result, mod);
|
19 | return result;
|
20 | };
|
21 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
22 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
23 | };
|
24 | Object.defineProperty(exports, "__esModule", { value: true });
|
25 | exports.isValidClassName = exports.scopeCSSVar = exports.isCSSVarProp = exports.generateScopedCSSVar = exports.getAlias = exports.getSourcePath = exports.getDeclStylable = exports.findRule = exports.findDeclaration = exports.removeUnusedRules = exports.createSubsetAst = exports.mergeRules = exports.scopeSelector = exports.transformMatchesOnRule = exports.expandCustomSelectors = exports.isValidDeclaration = exports.CUSTOM_SELECTOR_RE = void 0;
|
26 | const lodash_clonedeep_1 = __importDefault(require("lodash.clonedeep"));
|
27 | const path_1 = require("path");
|
28 | const postcss = __importStar(require("postcss"));
|
29 | const replaceRuleSelector_1 = __importDefault(require("postcss-selector-matches/dist/replaceRuleSelector"));
|
30 | const selector_utils_1 = require("./selector-utils");
|
31 | const stylable_value_parsers_1 = require("./stylable-value-parsers");
|
32 | exports.CUSTOM_SELECTOR_RE = /:--[\w-]+/g;
|
33 | function isValidDeclaration(decl) {
|
34 | return typeof decl.value === 'string';
|
35 | }
|
36 | exports.isValidDeclaration = isValidDeclaration;
|
37 | function expandCustomSelectors(rule, customSelectors, diagnostics) {
|
38 | if (rule.selector.includes(':--')) {
|
39 | rule.selector = rule.selector.replace(exports.CUSTOM_SELECTOR_RE, (extensionName, _matches, selector) => {
|
40 | if (!customSelectors[extensionName] && diagnostics) {
|
41 | diagnostics.warn(rule, `The selector '${rule.selector}' is undefined`, {
|
42 | word: rule.selector,
|
43 | });
|
44 | return selector;
|
45 | }
|
46 |
|
47 | return ':matches(' + customSelectors[extensionName] + ')';
|
48 | });
|
49 | return (rule.selector = transformMatchesOnRule(rule, false));
|
50 | }
|
51 | return rule.selector;
|
52 | }
|
53 | exports.expandCustomSelectors = expandCustomSelectors;
|
54 | function transformMatchesOnRule(rule, lineBreak) {
|
55 | return replaceRuleSelector_1.default(rule, { lineBreak });
|
56 | }
|
57 | exports.transformMatchesOnRule = transformMatchesOnRule;
|
58 | function scopeSelector(scopeSelectorRule, targetSelectorRule, rootScopeLevel = false) {
|
59 | const scopingSelectorAst = selector_utils_1.parseSelector(scopeSelectorRule);
|
60 | const targetSelectorAst = selector_utils_1.parseSelector(targetSelectorRule);
|
61 | const nodes = [];
|
62 | targetSelectorAst.nodes.forEach((targetSelector) => {
|
63 | scopingSelectorAst.nodes.forEach((scopingSelector) => {
|
64 | const outputSelector = lodash_clonedeep_1.default(targetSelector);
|
65 | outputSelector.before = scopingSelector.before || outputSelector.before;
|
66 | const first = outputSelector.nodes[0];
|
67 | const parentRef = first.type === 'invalid' && first.value === '&';
|
68 | const globalSelector = first.type === 'nested-pseudo-class' && first.name === 'global';
|
69 | const startsWithScoping = rootScopeLevel
|
70 | ? scopingSelector.nodes.every((node, i) => {
|
71 | const o = outputSelector.nodes[i];
|
72 | for (const k in node) {
|
73 | if (node[k] !== o[k]) {
|
74 | return false;
|
75 | }
|
76 | }
|
77 | return true;
|
78 | })
|
79 | : false;
|
80 | if (first &&
|
81 | first.type !== 'spacing' &&
|
82 | !parentRef &&
|
83 | !startsWithScoping &&
|
84 | !globalSelector) {
|
85 | outputSelector.nodes.unshift(...lodash_clonedeep_1.default(scopingSelector.nodes), {
|
86 | type: 'spacing',
|
87 | value: ' ',
|
88 | });
|
89 | }
|
90 | selector_utils_1.traverseNode(outputSelector, (node, i, nodes) => {
|
91 | if (node.type === 'invalid' && node.value === '&') {
|
92 | nodes.splice(i, 1, ...lodash_clonedeep_1.default(scopingSelector.nodes));
|
93 | }
|
94 | });
|
95 | nodes.push(outputSelector);
|
96 | });
|
97 | });
|
98 | scopingSelectorAst.nodes = nodes;
|
99 | return {
|
100 | selector: selector_utils_1.stringifySelector(scopingSelectorAst),
|
101 | selectorAst: scopingSelectorAst,
|
102 | };
|
103 | }
|
104 | exports.scopeSelector = scopeSelector;
|
105 | function mergeRules(mixinAst, rule) {
|
106 | let mixinRoot = null;
|
107 | mixinAst.walkRules((mixinRule) => {
|
108 | if (mixinRule.selector === '&' && !mixinRoot) {
|
109 | mixinRoot = mixinRule;
|
110 | }
|
111 | else {
|
112 | const parentRule = mixinRule.parent;
|
113 | if (parentRule &&
|
114 | parentRule.type === 'atrule' &&
|
115 | parentRule.name === 'keyframes') {
|
116 | return;
|
117 | }
|
118 | const out = scopeSelector(rule.selector, mixinRule.selector);
|
119 | mixinRule.selector = out.selector;
|
120 |
|
121 | }
|
122 | });
|
123 | if (mixinAst.nodes) {
|
124 | let nextRule = rule;
|
125 | let mixinEntry = null;
|
126 | rule.walkDecls(stylable_value_parsers_1.mixinDeclRegExp, (decl) => {
|
127 | mixinEntry = decl;
|
128 | });
|
129 | if (!mixinEntry) {
|
130 | throw rule.error('missing mixin entry');
|
131 | }
|
132 |
|
133 | mixinAst.nodes.slice().forEach((node) => {
|
134 | if (node === mixinRoot) {
|
135 | node.walkDecls((node) => {
|
136 | rule.insertBefore(mixinEntry, node);
|
137 | });
|
138 | }
|
139 | else if (node.type === 'decl') {
|
140 | rule.insertBefore(mixinEntry, node);
|
141 | }
|
142 | else if (node.type === 'rule' || node.type === 'atrule') {
|
143 | if (rule.parent.last === nextRule) {
|
144 | rule.parent.append(node);
|
145 | }
|
146 | else {
|
147 | rule.parent.insertAfter(nextRule, node);
|
148 | }
|
149 | nextRule = node;
|
150 | }
|
151 | });
|
152 | }
|
153 | return rule;
|
154 | }
|
155 | exports.mergeRules = mergeRules;
|
156 | function createSubsetAst(root, selectorPrefix, mixinTarget, isRoot = false) {
|
157 |
|
158 | const prefixType = selector_utils_1.parseSelector(selectorPrefix).nodes[0].nodes[0];
|
159 | const containsPrefix = containsMatchInFirstChunk.bind(null, prefixType);
|
160 | const mixinRoot = mixinTarget ? mixinTarget : postcss.root();
|
161 | root.nodes.forEach((node) => {
|
162 | if (node.type === 'rule') {
|
163 | const ast = isRoot
|
164 | ? scopeSelector(selectorPrefix, node.selector, true).selectorAst
|
165 | : selector_utils_1.parseSelector(node.selector);
|
166 | const matchesSelectors = isRoot
|
167 | ? ast.nodes
|
168 | : ast.nodes.filter((node) => containsPrefix(node));
|
169 | if (matchesSelectors.length) {
|
170 | const selector = selector_utils_1.stringifySelector({
|
171 | ...ast,
|
172 | nodes: matchesSelectors.map((selectorNode) => {
|
173 | if (!isRoot) {
|
174 | selector_utils_1.fixChunkOrdering(selectorNode, prefixType);
|
175 | }
|
176 | return destructiveReplaceNode(selectorNode, prefixType, {
|
177 | type: 'invalid',
|
178 | value: '&',
|
179 | });
|
180 | }),
|
181 | });
|
182 | mixinRoot.append(node.clone({ selector }));
|
183 | }
|
184 | }
|
185 | else if (node.type === 'atrule') {
|
186 | if (node.name === 'media') {
|
187 | const mediaSubset = createSubsetAst(node, selectorPrefix, postcss.atRule({
|
188 | params: node.params,
|
189 | name: node.name,
|
190 | }), isRoot);
|
191 | if (mediaSubset.nodes) {
|
192 | mixinRoot.append(mediaSubset);
|
193 | }
|
194 | }
|
195 | else if (isRoot) {
|
196 | mixinRoot.append(node.clone());
|
197 | }
|
198 | }
|
199 | else {
|
200 |
|
201 | }
|
202 | });
|
203 | return mixinRoot;
|
204 | }
|
205 | exports.createSubsetAst = createSubsetAst;
|
206 | function removeUnusedRules(ast, meta, _import, usedFiles, resolvePath) {
|
207 | const isUnusedImport = !usedFiles.includes(_import.from);
|
208 | if (isUnusedImport) {
|
209 | const symbols = Object.keys(_import.named).concat(_import.defaultExport);
|
210 | ast.walkRules((rule) => {
|
211 | let shouldOutput = true;
|
212 | selector_utils_1.traverseNode(rule.selectorAst, (node) => {
|
213 |
|
214 | if (symbols.includes(node.name)) {
|
215 | return (shouldOutput = false);
|
216 | }
|
217 | const symbol = meta.mappedSymbols[node.name];
|
218 | if (symbol && (symbol._kind === 'class' || symbol._kind === 'element')) {
|
219 | let extend = symbol[stylable_value_parsers_1.valueMapping.extends] || symbol.alias;
|
220 | extend = extend && extend._kind !== 'import' ? extend.alias || extend : extend;
|
221 | if (extend &&
|
222 | extend._kind === 'import' &&
|
223 | !usedFiles.includes(resolvePath(meta.source, extend.import.from))) {
|
224 | return (shouldOutput = false);
|
225 | }
|
226 | }
|
227 | return undefined;
|
228 | });
|
229 |
|
230 | if (!shouldOutput && rule.selectorAst.nodes.length <= 1) {
|
231 | rule.remove();
|
232 | }
|
233 | });
|
234 | }
|
235 | }
|
236 | exports.removeUnusedRules = removeUnusedRules;
|
237 | function findDeclaration(importNode, test) {
|
238 | const fromIndex = importNode.rule.nodes.findIndex(test);
|
239 | return importNode.rule.nodes[fromIndex];
|
240 | }
|
241 | exports.findDeclaration = findDeclaration;
|
242 |
|
243 | function findRule(root, selector, test = (statement) => statement.prop === stylable_value_parsers_1.valueMapping.extends) {
|
244 | let found = null;
|
245 | root.walkRules(selector, (rule) => {
|
246 | const declarationIndex = rule.nodes ? rule.nodes.findIndex(test) : -1;
|
247 | if (rule.isSimpleSelector && !!~declarationIndex) {
|
248 | found = rule.nodes[declarationIndex];
|
249 | }
|
250 | });
|
251 | return found;
|
252 | }
|
253 | exports.findRule = findRule;
|
254 | function getDeclStylable(decl) {
|
255 | if (decl.stylable) {
|
256 | return decl.stylable;
|
257 | }
|
258 | else {
|
259 | decl.stylable = decl.stylable ? decl.stylable : { sourceValue: '' };
|
260 | return decl.stylable;
|
261 | }
|
262 | }
|
263 | exports.getDeclStylable = getDeclStylable;
|
264 | function destructiveReplaceNode(ast, matchNode, replacementNode) {
|
265 | selector_utils_1.traverseNode(ast, (node) => {
|
266 | if (selector_utils_1.isNodeMatch(node, matchNode)) {
|
267 | node.type = 'selector';
|
268 | node.nodes = [replacementNode];
|
269 | }
|
270 | });
|
271 | return ast;
|
272 | }
|
273 | function containsMatchInFirstChunk(prefixType, selectorNode) {
|
274 | let isMatch = false;
|
275 | selector_utils_1.traverseNode(selectorNode, (node) => {
|
276 | if (node.type === 'operator' || node.type === 'spacing') {
|
277 | return false;
|
278 | }
|
279 | else if (node.type === 'nested-pseudo-class') {
|
280 | return true;
|
281 | }
|
282 | else if (selector_utils_1.isNodeMatch(node, prefixType)) {
|
283 | isMatch = true;
|
284 | return false;
|
285 | }
|
286 | return undefined;
|
287 | });
|
288 | return isMatch;
|
289 | }
|
290 | function getSourcePath(root, diagnostics) {
|
291 | const source = (root.source && root.source.input.file) || '';
|
292 | if (!source) {
|
293 | diagnostics.error(root, 'missing source filename');
|
294 | }
|
295 | else if (!path_1.isAbsolute(source)) {
|
296 | throw new Error('source filename is not absolute path: "' + source + '"');
|
297 | }
|
298 | return source;
|
299 | }
|
300 | exports.getSourcePath = getSourcePath;
|
301 | function getAlias(symbol) {
|
302 | if (symbol._kind === 'class' || symbol._kind === 'element') {
|
303 | if (!symbol[stylable_value_parsers_1.valueMapping.extends]) {
|
304 | return symbol.alias;
|
305 | }
|
306 | }
|
307 | return undefined;
|
308 | }
|
309 | exports.getAlias = getAlias;
|
310 | function generateScopedCSSVar(namespace, varName) {
|
311 | return `--${namespace}-${varName}`;
|
312 | }
|
313 | exports.generateScopedCSSVar = generateScopedCSSVar;
|
314 | function isCSSVarProp(value) {
|
315 | return value.startsWith('--');
|
316 | }
|
317 | exports.isCSSVarProp = isCSSVarProp;
|
318 | function scopeCSSVar(resolver, meta, symbolName) {
|
319 | const importedVar = resolver.deepResolve(meta.mappedSymbols[symbolName]);
|
320 | if (importedVar &&
|
321 | importedVar._kind === 'css' &&
|
322 | importedVar.symbol &&
|
323 | importedVar.symbol._kind === 'cssVar') {
|
324 | return importedVar.symbol.global
|
325 | ? importedVar.symbol.name
|
326 | : generateScopedCSSVar(importedVar.meta.namespace, importedVar.symbol.name.slice(2));
|
327 | }
|
328 | const cssVar = meta.cssVars[symbolName];
|
329 | if (cssVar === null || cssVar === void 0 ? void 0 : cssVar.global) {
|
330 | return symbolName;
|
331 | }
|
332 | else {
|
333 | return generateScopedCSSVar(meta.namespace, symbolName.slice(2));
|
334 | }
|
335 | }
|
336 | exports.scopeCSSVar = scopeCSSVar;
|
337 | function isValidClassName(className) {
|
338 | const test = /^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$/g;
|
339 | return !!className.match(test);
|
340 | }
|
341 | exports.isValidClassName = isValidClassName;
|
342 |
|
\ | No newline at end of file |