@unocss/transformer-directives 0.26.2 → 0.27.0

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/README.md CHANGED
@@ -21,7 +21,24 @@ Unocss({
21
21
 
22
22
  ## Usage
23
23
 
24
- Currently only `@apply` is supported.
24
+ ```css
25
+ .custom-div {
26
+ @apply text-center my-0 font-medium;
27
+ }
28
+ ```
29
+
30
+ Will be transformed to:
31
+
32
+ ```css
33
+ .custom-div {
34
+ margin-top: 0rem;
35
+ margin-bottom: 0rem;
36
+ text-align: center;
37
+ font-weight: 500;
38
+ }
39
+ ```
40
+
41
+ > Currently only `@apply` is supported.
25
42
 
26
43
  ## License
27
44
 
package/dist/index.cjs CHANGED
@@ -4,266 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const core = require('@unocss/core');
6
6
  const cssTree = require('css-tree');
7
- const require$$0 = require('path');
8
- require('crypto');
9
-
10
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
11
-
12
- const require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0);
13
7
 
14
8
  const regexCssId = /\.(css|postcss|sass|scss|less|stylus|styl)$/;
15
9
 
16
- var utils = {};
17
-
18
- const path = require$$0__default;
19
- const WIN_SLASH = '\\\\/';
20
- const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
21
-
22
- /**
23
- * Posix glob regex
24
- */
25
-
26
- const DOT_LITERAL = '\\.';
27
- const PLUS_LITERAL = '\\+';
28
- const QMARK_LITERAL = '\\?';
29
- const SLASH_LITERAL = '\\/';
30
- const ONE_CHAR = '(?=.)';
31
- const QMARK = '[^/]';
32
- const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
33
- const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
34
- const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
35
- const NO_DOT = `(?!${DOT_LITERAL})`;
36
- const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
37
- const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
38
- const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
39
- const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
40
- const STAR = `${QMARK}*?`;
41
-
42
- const POSIX_CHARS = {
43
- DOT_LITERAL,
44
- PLUS_LITERAL,
45
- QMARK_LITERAL,
46
- SLASH_LITERAL,
47
- ONE_CHAR,
48
- QMARK,
49
- END_ANCHOR,
50
- DOTS_SLASH,
51
- NO_DOT,
52
- NO_DOTS,
53
- NO_DOT_SLASH,
54
- NO_DOTS_SLASH,
55
- QMARK_NO_DOT,
56
- STAR,
57
- START_ANCHOR
58
- };
59
-
60
- /**
61
- * Windows glob regex
62
- */
63
-
64
- const WINDOWS_CHARS = {
65
- ...POSIX_CHARS,
66
-
67
- SLASH_LITERAL: `[${WIN_SLASH}]`,
68
- QMARK: WIN_NO_SLASH,
69
- STAR: `${WIN_NO_SLASH}*?`,
70
- DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
71
- NO_DOT: `(?!${DOT_LITERAL})`,
72
- NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
73
- NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
74
- NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
75
- QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
76
- START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
77
- END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
78
- };
79
-
80
- /**
81
- * POSIX Bracket Regex
82
- */
83
-
84
- const POSIX_REGEX_SOURCE = {
85
- alnum: 'a-zA-Z0-9',
86
- alpha: 'a-zA-Z',
87
- ascii: '\\x00-\\x7F',
88
- blank: ' \\t',
89
- cntrl: '\\x00-\\x1F\\x7F',
90
- digit: '0-9',
91
- graph: '\\x21-\\x7E',
92
- lower: 'a-z',
93
- print: '\\x20-\\x7E ',
94
- punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
95
- space: ' \\t\\r\\n\\v\\f',
96
- upper: 'A-Z',
97
- word: 'A-Za-z0-9_',
98
- xdigit: 'A-Fa-f0-9'
99
- };
100
-
101
- var constants = {
102
- MAX_LENGTH: 1024 * 64,
103
- POSIX_REGEX_SOURCE,
104
-
105
- // regular expressions
106
- REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
107
- REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
108
- REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
109
- REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
110
- REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
111
- REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
112
-
113
- // Replace globs with equivalent patterns to reduce parsing time.
114
- REPLACEMENTS: {
115
- '***': '*',
116
- '**/**': '**',
117
- '**/**/**': '**'
118
- },
119
-
120
- // Digits
121
- CHAR_0: 48, /* 0 */
122
- CHAR_9: 57, /* 9 */
123
-
124
- // Alphabet chars.
125
- CHAR_UPPERCASE_A: 65, /* A */
126
- CHAR_LOWERCASE_A: 97, /* a */
127
- CHAR_UPPERCASE_Z: 90, /* Z */
128
- CHAR_LOWERCASE_Z: 122, /* z */
129
-
130
- CHAR_LEFT_PARENTHESES: 40, /* ( */
131
- CHAR_RIGHT_PARENTHESES: 41, /* ) */
132
-
133
- CHAR_ASTERISK: 42, /* * */
134
-
135
- // Non-alphabetic chars.
136
- CHAR_AMPERSAND: 38, /* & */
137
- CHAR_AT: 64, /* @ */
138
- CHAR_BACKWARD_SLASH: 92, /* \ */
139
- CHAR_CARRIAGE_RETURN: 13, /* \r */
140
- CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
141
- CHAR_COLON: 58, /* : */
142
- CHAR_COMMA: 44, /* , */
143
- CHAR_DOT: 46, /* . */
144
- CHAR_DOUBLE_QUOTE: 34, /* " */
145
- CHAR_EQUAL: 61, /* = */
146
- CHAR_EXCLAMATION_MARK: 33, /* ! */
147
- CHAR_FORM_FEED: 12, /* \f */
148
- CHAR_FORWARD_SLASH: 47, /* / */
149
- CHAR_GRAVE_ACCENT: 96, /* ` */
150
- CHAR_HASH: 35, /* # */
151
- CHAR_HYPHEN_MINUS: 45, /* - */
152
- CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
153
- CHAR_LEFT_CURLY_BRACE: 123, /* { */
154
- CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
155
- CHAR_LINE_FEED: 10, /* \n */
156
- CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
157
- CHAR_PERCENT: 37, /* % */
158
- CHAR_PLUS: 43, /* + */
159
- CHAR_QUESTION_MARK: 63, /* ? */
160
- CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
161
- CHAR_RIGHT_CURLY_BRACE: 125, /* } */
162
- CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
163
- CHAR_SEMICOLON: 59, /* ; */
164
- CHAR_SINGLE_QUOTE: 39, /* ' */
165
- CHAR_SPACE: 32, /* */
166
- CHAR_TAB: 9, /* \t */
167
- CHAR_UNDERSCORE: 95, /* _ */
168
- CHAR_VERTICAL_LINE: 124, /* | */
169
- CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
170
-
171
- SEP: path.sep,
172
-
173
- /**
174
- * Create EXTGLOB_CHARS
175
- */
176
-
177
- extglobChars(chars) {
178
- return {
179
- '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
180
- '?': { type: 'qmark', open: '(?:', close: ')?' },
181
- '+': { type: 'plus', open: '(?:', close: ')+' },
182
- '*': { type: 'star', open: '(?:', close: ')*' },
183
- '@': { type: 'at', open: '(?:', close: ')' }
184
- };
185
- },
186
-
187
- /**
188
- * Create GLOB_CHARS
189
- */
190
-
191
- globChars(win32) {
192
- return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
193
- }
194
- };
195
-
196
- (function (exports) {
197
-
198
- const path = require$$0__default;
199
- const win32 = process.platform === 'win32';
200
- const {
201
- REGEX_BACKSLASH,
202
- REGEX_REMOVE_BACKSLASH,
203
- REGEX_SPECIAL_CHARS,
204
- REGEX_SPECIAL_CHARS_GLOBAL
205
- } = constants;
206
-
207
- exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
208
- exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
209
- exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
210
- exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
211
- exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
212
-
213
- exports.removeBackslashes = str => {
214
- return str.replace(REGEX_REMOVE_BACKSLASH, match => {
215
- return match === '\\' ? '' : match;
216
- });
217
- };
218
-
219
- exports.supportsLookbehinds = () => {
220
- const segs = process.version.slice(1).split('.').map(Number);
221
- if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
222
- return true;
223
- }
224
- return false;
225
- };
226
-
227
- exports.isWindows = options => {
228
- if (options && typeof options.windows === 'boolean') {
229
- return options.windows;
230
- }
231
- return win32 === true || path.sep === '\\';
232
- };
233
-
234
- exports.escapeLast = (input, char, lastIdx) => {
235
- const idx = input.lastIndexOf(char, lastIdx);
236
- if (idx === -1) return input;
237
- if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
238
- return `${input.slice(0, idx)}\\${input.slice(idx)}`;
239
- };
240
-
241
- exports.removePrefix = (input, state = {}) => {
242
- let output = input;
243
- if (output.startsWith('./')) {
244
- output = output.slice(2);
245
- state.prefix = './';
246
- }
247
- return output;
248
- };
249
-
250
- exports.wrapOutput = (input, state = {}, options = {}) => {
251
- const prepend = options.contains ? '' : '^';
252
- const append = options.contains ? '' : '$';
253
-
254
- let output = `${prepend}(?:${input})${append}`;
255
- if (state.negated === true) {
256
- output = `(?:^(?!${output}).*$)`;
257
- }
258
- return output;
259
- };
260
- }(utils));
261
-
262
- const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
263
- const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
264
- const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));
265
- forbiddenIdentifiers.add('');
266
-
267
10
  function transformerDirectives() {
268
11
  return {
269
12
  name: "css-directive",
@@ -274,32 +17,32 @@ function transformerDirectives() {
274
17
  }
275
18
  };
276
19
  }
277
- async function transformDirectives(css, uno, filename) {
278
- if (!css.includes("@apply"))
279
- return css;
280
- const ast = cssTree.parse(css, {
20
+ async function transformDirectives(code, uno, filename) {
21
+ if (!code.original.includes("@apply"))
22
+ return;
23
+ const ast = cssTree.parse(code.original, {
281
24
  parseAtrulePrelude: false,
282
25
  positions: true,
283
26
  filename
284
27
  });
285
28
  if (ast.type !== "StyleSheet")
286
- return css;
29
+ return;
287
30
  const stack = [];
288
- const processNode = async (node, item, list) => {
31
+ const processNode = async (node, _item, _list) => {
289
32
  if (node.type !== "Rule")
290
33
  return;
291
- await Promise.all(node.block.children.map(async (childNode, childItem) => {
34
+ await Promise.all(node.block.children.map(async (childNode, _childItem) => {
292
35
  if (!(childNode.type === "Atrule" && childNode.name === "apply" && childNode.prelude))
293
36
  return;
294
37
  if (childNode.prelude.type !== "Raw")
295
38
  return;
296
39
  const classNames = core.expandVariantGroup(childNode.prelude.value).split(/\s+/g);
297
- const utils = (await Promise.all(classNames.map((i) => uno.parseToken(i, "-")))).filter(core.notNull).flat().sort((a, b) => a[0] - b[0]).reduce((acc, item2) => {
298
- const target = acc.find((i) => i[1] === item2[1] && i[3] === item2[3]);
40
+ const utils = (await Promise.all(classNames.map((i) => uno.parseToken(i, "-")))).filter(core.notNull).flat().sort((a, b) => a[0] - b[0]).reduce((acc, item) => {
41
+ const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]);
299
42
  if (target)
300
- target[2] += item2[2];
43
+ target[2] += item[2];
301
44
  else
302
- acc.push([...item2]);
45
+ acc.push([...item]);
303
46
  return acc;
304
47
  }, []);
305
48
  if (!utils.length)
@@ -310,8 +53,7 @@ async function transformDirectives(css, uno, filename) {
310
53
  const selector = _selector?.replace(core.regexScopePlaceholder, " ") || _selector;
311
54
  if (parent) {
312
55
  const newNodeCss = `${parent}{${parentSelector}{${body}}}`;
313
- const insertNodeAst = cssTree.parse(newNodeCss);
314
- list.insertList(insertNodeAst.children, item);
56
+ code.appendLeft(node.loc.start.offset, newNodeCss);
315
57
  } else if (selector && selector !== ".\\-") {
316
58
  const selectorAST = cssTree.parse(selector, {
317
59
  context: "selector"
@@ -326,21 +68,20 @@ async function transformDirectives(css, uno, filename) {
326
68
  Object.assign(child, parentSelectorAst);
327
69
  });
328
70
  const newNodeCss = `${cssTree.generate(prelude)}{${body}}`;
329
- const insertNodeAst = cssTree.parse(newNodeCss);
330
- list.insertList(insertNodeAst.children, item);
71
+ code.appendLeft(node.loc.start.offset, newNodeCss);
72
+ } else if (node.block.children.toArray().length === 1) {
73
+ const newNodeCss = `${parentSelector}{${body}}`;
74
+ code.appendLeft(node.loc.start.offset, newNodeCss);
75
+ code.remove(node.loc.start.offset, node.loc.end.offset);
331
76
  } else {
332
- const rules = new cssTree.List().fromArray(body.replace(/;$/, "").split(";")).map((i2) => cssTree.parse(i2, {
333
- context: "declaration"
334
- }));
335
- node.block.children.insertList(rules, childItem);
77
+ code.appendRight(childNode.loc.end.offset, body);
336
78
  }
337
79
  }
338
- node.block.children.remove(childItem);
80
+ code.remove(childNode.loc.start.offset, childNode.loc.end.offset);
339
81
  }).toArray());
340
82
  };
341
83
  cssTree.walk(ast, (...args) => stack.push(processNode(...args)));
342
84
  await Promise.all(stack);
343
- return cssTree.generate(ast);
344
85
  }
345
86
 
346
87
  exports["default"] = transformerDirectives;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { SourceCodeTransformer, UnoGenerator } from '@unocss/core';
2
+ import MagicString from 'magic-string-extra';
2
3
 
3
4
  declare function transformerDirectives(): SourceCodeTransformer;
4
- declare function transformDirectives(css: string, uno: UnoGenerator, filename?: string): Promise<string>;
5
+ declare function transformDirectives(code: MagicString, uno: UnoGenerator, filename?: string): Promise<void>;
5
6
 
6
7
  export { transformerDirectives as default, transformDirectives };
package/dist/index.mjs CHANGED
@@ -1,261 +1,8 @@
1
1
  import { expandVariantGroup, notNull, regexScopePlaceholder } from '@unocss/core';
2
- import { parse, walk, generate, clone, List } from 'css-tree';
3
- import require$$0 from 'path';
4
- import 'crypto';
2
+ import { parse, walk, generate, clone } from 'css-tree';
5
3
 
6
4
  const regexCssId = /\.(css|postcss|sass|scss|less|stylus|styl)$/;
7
5
 
8
- var utils = {};
9
-
10
- const path = require$$0;
11
- const WIN_SLASH = '\\\\/';
12
- const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
13
-
14
- /**
15
- * Posix glob regex
16
- */
17
-
18
- const DOT_LITERAL = '\\.';
19
- const PLUS_LITERAL = '\\+';
20
- const QMARK_LITERAL = '\\?';
21
- const SLASH_LITERAL = '\\/';
22
- const ONE_CHAR = '(?=.)';
23
- const QMARK = '[^/]';
24
- const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
25
- const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
26
- const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
27
- const NO_DOT = `(?!${DOT_LITERAL})`;
28
- const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
29
- const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
30
- const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
31
- const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
32
- const STAR = `${QMARK}*?`;
33
-
34
- const POSIX_CHARS = {
35
- DOT_LITERAL,
36
- PLUS_LITERAL,
37
- QMARK_LITERAL,
38
- SLASH_LITERAL,
39
- ONE_CHAR,
40
- QMARK,
41
- END_ANCHOR,
42
- DOTS_SLASH,
43
- NO_DOT,
44
- NO_DOTS,
45
- NO_DOT_SLASH,
46
- NO_DOTS_SLASH,
47
- QMARK_NO_DOT,
48
- STAR,
49
- START_ANCHOR
50
- };
51
-
52
- /**
53
- * Windows glob regex
54
- */
55
-
56
- const WINDOWS_CHARS = {
57
- ...POSIX_CHARS,
58
-
59
- SLASH_LITERAL: `[${WIN_SLASH}]`,
60
- QMARK: WIN_NO_SLASH,
61
- STAR: `${WIN_NO_SLASH}*?`,
62
- DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
63
- NO_DOT: `(?!${DOT_LITERAL})`,
64
- NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
65
- NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
66
- NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
67
- QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
68
- START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
69
- END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
70
- };
71
-
72
- /**
73
- * POSIX Bracket Regex
74
- */
75
-
76
- const POSIX_REGEX_SOURCE = {
77
- alnum: 'a-zA-Z0-9',
78
- alpha: 'a-zA-Z',
79
- ascii: '\\x00-\\x7F',
80
- blank: ' \\t',
81
- cntrl: '\\x00-\\x1F\\x7F',
82
- digit: '0-9',
83
- graph: '\\x21-\\x7E',
84
- lower: 'a-z',
85
- print: '\\x20-\\x7E ',
86
- punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
87
- space: ' \\t\\r\\n\\v\\f',
88
- upper: 'A-Z',
89
- word: 'A-Za-z0-9_',
90
- xdigit: 'A-Fa-f0-9'
91
- };
92
-
93
- var constants = {
94
- MAX_LENGTH: 1024 * 64,
95
- POSIX_REGEX_SOURCE,
96
-
97
- // regular expressions
98
- REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
99
- REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
100
- REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
101
- REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
102
- REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
103
- REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
104
-
105
- // Replace globs with equivalent patterns to reduce parsing time.
106
- REPLACEMENTS: {
107
- '***': '*',
108
- '**/**': '**',
109
- '**/**/**': '**'
110
- },
111
-
112
- // Digits
113
- CHAR_0: 48, /* 0 */
114
- CHAR_9: 57, /* 9 */
115
-
116
- // Alphabet chars.
117
- CHAR_UPPERCASE_A: 65, /* A */
118
- CHAR_LOWERCASE_A: 97, /* a */
119
- CHAR_UPPERCASE_Z: 90, /* Z */
120
- CHAR_LOWERCASE_Z: 122, /* z */
121
-
122
- CHAR_LEFT_PARENTHESES: 40, /* ( */
123
- CHAR_RIGHT_PARENTHESES: 41, /* ) */
124
-
125
- CHAR_ASTERISK: 42, /* * */
126
-
127
- // Non-alphabetic chars.
128
- CHAR_AMPERSAND: 38, /* & */
129
- CHAR_AT: 64, /* @ */
130
- CHAR_BACKWARD_SLASH: 92, /* \ */
131
- CHAR_CARRIAGE_RETURN: 13, /* \r */
132
- CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
133
- CHAR_COLON: 58, /* : */
134
- CHAR_COMMA: 44, /* , */
135
- CHAR_DOT: 46, /* . */
136
- CHAR_DOUBLE_QUOTE: 34, /* " */
137
- CHAR_EQUAL: 61, /* = */
138
- CHAR_EXCLAMATION_MARK: 33, /* ! */
139
- CHAR_FORM_FEED: 12, /* \f */
140
- CHAR_FORWARD_SLASH: 47, /* / */
141
- CHAR_GRAVE_ACCENT: 96, /* ` */
142
- CHAR_HASH: 35, /* # */
143
- CHAR_HYPHEN_MINUS: 45, /* - */
144
- CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
145
- CHAR_LEFT_CURLY_BRACE: 123, /* { */
146
- CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
147
- CHAR_LINE_FEED: 10, /* \n */
148
- CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
149
- CHAR_PERCENT: 37, /* % */
150
- CHAR_PLUS: 43, /* + */
151
- CHAR_QUESTION_MARK: 63, /* ? */
152
- CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
153
- CHAR_RIGHT_CURLY_BRACE: 125, /* } */
154
- CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
155
- CHAR_SEMICOLON: 59, /* ; */
156
- CHAR_SINGLE_QUOTE: 39, /* ' */
157
- CHAR_SPACE: 32, /* */
158
- CHAR_TAB: 9, /* \t */
159
- CHAR_UNDERSCORE: 95, /* _ */
160
- CHAR_VERTICAL_LINE: 124, /* | */
161
- CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
162
-
163
- SEP: path.sep,
164
-
165
- /**
166
- * Create EXTGLOB_CHARS
167
- */
168
-
169
- extglobChars(chars) {
170
- return {
171
- '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
172
- '?': { type: 'qmark', open: '(?:', close: ')?' },
173
- '+': { type: 'plus', open: '(?:', close: ')+' },
174
- '*': { type: 'star', open: '(?:', close: ')*' },
175
- '@': { type: 'at', open: '(?:', close: ')' }
176
- };
177
- },
178
-
179
- /**
180
- * Create GLOB_CHARS
181
- */
182
-
183
- globChars(win32) {
184
- return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
185
- }
186
- };
187
-
188
- (function (exports) {
189
-
190
- const path = require$$0;
191
- const win32 = process.platform === 'win32';
192
- const {
193
- REGEX_BACKSLASH,
194
- REGEX_REMOVE_BACKSLASH,
195
- REGEX_SPECIAL_CHARS,
196
- REGEX_SPECIAL_CHARS_GLOBAL
197
- } = constants;
198
-
199
- exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
200
- exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
201
- exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
202
- exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
203
- exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
204
-
205
- exports.removeBackslashes = str => {
206
- return str.replace(REGEX_REMOVE_BACKSLASH, match => {
207
- return match === '\\' ? '' : match;
208
- });
209
- };
210
-
211
- exports.supportsLookbehinds = () => {
212
- const segs = process.version.slice(1).split('.').map(Number);
213
- if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
214
- return true;
215
- }
216
- return false;
217
- };
218
-
219
- exports.isWindows = options => {
220
- if (options && typeof options.windows === 'boolean') {
221
- return options.windows;
222
- }
223
- return win32 === true || path.sep === '\\';
224
- };
225
-
226
- exports.escapeLast = (input, char, lastIdx) => {
227
- const idx = input.lastIndexOf(char, lastIdx);
228
- if (idx === -1) return input;
229
- if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
230
- return `${input.slice(0, idx)}\\${input.slice(idx)}`;
231
- };
232
-
233
- exports.removePrefix = (input, state = {}) => {
234
- let output = input;
235
- if (output.startsWith('./')) {
236
- output = output.slice(2);
237
- state.prefix = './';
238
- }
239
- return output;
240
- };
241
-
242
- exports.wrapOutput = (input, state = {}, options = {}) => {
243
- const prepend = options.contains ? '' : '^';
244
- const append = options.contains ? '' : '$';
245
-
246
- let output = `${prepend}(?:${input})${append}`;
247
- if (state.negated === true) {
248
- output = `(?:^(?!${output}).*$)`;
249
- }
250
- return output;
251
- };
252
- }(utils));
253
-
254
- const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
255
- const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
256
- const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));
257
- forbiddenIdentifiers.add('');
258
-
259
6
  function transformerDirectives() {
260
7
  return {
261
8
  name: "css-directive",
@@ -266,32 +13,32 @@ function transformerDirectives() {
266
13
  }
267
14
  };
268
15
  }
269
- async function transformDirectives(css, uno, filename) {
270
- if (!css.includes("@apply"))
271
- return css;
272
- const ast = parse(css, {
16
+ async function transformDirectives(code, uno, filename) {
17
+ if (!code.original.includes("@apply"))
18
+ return;
19
+ const ast = parse(code.original, {
273
20
  parseAtrulePrelude: false,
274
21
  positions: true,
275
22
  filename
276
23
  });
277
24
  if (ast.type !== "StyleSheet")
278
- return css;
25
+ return;
279
26
  const stack = [];
280
- const processNode = async (node, item, list) => {
27
+ const processNode = async (node, _item, _list) => {
281
28
  if (node.type !== "Rule")
282
29
  return;
283
- await Promise.all(node.block.children.map(async (childNode, childItem) => {
30
+ await Promise.all(node.block.children.map(async (childNode, _childItem) => {
284
31
  if (!(childNode.type === "Atrule" && childNode.name === "apply" && childNode.prelude))
285
32
  return;
286
33
  if (childNode.prelude.type !== "Raw")
287
34
  return;
288
35
  const classNames = expandVariantGroup(childNode.prelude.value).split(/\s+/g);
289
- const utils = (await Promise.all(classNames.map((i) => uno.parseToken(i, "-")))).filter(notNull).flat().sort((a, b) => a[0] - b[0]).reduce((acc, item2) => {
290
- const target = acc.find((i) => i[1] === item2[1] && i[3] === item2[3]);
36
+ const utils = (await Promise.all(classNames.map((i) => uno.parseToken(i, "-")))).filter(notNull).flat().sort((a, b) => a[0] - b[0]).reduce((acc, item) => {
37
+ const target = acc.find((i) => i[1] === item[1] && i[3] === item[3]);
291
38
  if (target)
292
- target[2] += item2[2];
39
+ target[2] += item[2];
293
40
  else
294
- acc.push([...item2]);
41
+ acc.push([...item]);
295
42
  return acc;
296
43
  }, []);
297
44
  if (!utils.length)
@@ -302,8 +49,7 @@ async function transformDirectives(css, uno, filename) {
302
49
  const selector = _selector?.replace(regexScopePlaceholder, " ") || _selector;
303
50
  if (parent) {
304
51
  const newNodeCss = `${parent}{${parentSelector}{${body}}}`;
305
- const insertNodeAst = parse(newNodeCss);
306
- list.insertList(insertNodeAst.children, item);
52
+ code.appendLeft(node.loc.start.offset, newNodeCss);
307
53
  } else if (selector && selector !== ".\\-") {
308
54
  const selectorAST = parse(selector, {
309
55
  context: "selector"
@@ -318,21 +64,20 @@ async function transformDirectives(css, uno, filename) {
318
64
  Object.assign(child, parentSelectorAst);
319
65
  });
320
66
  const newNodeCss = `${generate(prelude)}{${body}}`;
321
- const insertNodeAst = parse(newNodeCss);
322
- list.insertList(insertNodeAst.children, item);
67
+ code.appendLeft(node.loc.start.offset, newNodeCss);
68
+ } else if (node.block.children.toArray().length === 1) {
69
+ const newNodeCss = `${parentSelector}{${body}}`;
70
+ code.appendLeft(node.loc.start.offset, newNodeCss);
71
+ code.remove(node.loc.start.offset, node.loc.end.offset);
323
72
  } else {
324
- const rules = new List().fromArray(body.replace(/;$/, "").split(";")).map((i2) => parse(i2, {
325
- context: "declaration"
326
- }));
327
- node.block.children.insertList(rules, childItem);
73
+ code.appendRight(childNode.loc.end.offset, body);
328
74
  }
329
75
  }
330
- node.block.children.remove(childItem);
76
+ code.remove(childNode.loc.start.offset, childNode.loc.end.offset);
331
77
  }).toArray());
332
78
  };
333
79
  walk(ast, (...args) => stack.push(processNode(...args)));
334
80
  await Promise.all(stack);
335
- return generate(ast);
336
81
  }
337
82
 
338
83
  export { transformerDirectives as default, transformDirectives };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unocss/transformer-directives",
3
- "version": "0.26.2",
3
+ "version": "0.27.0",
4
4
  "description": "UnoCSS transformer for `@apply` directive",
5
5
  "keywords": [
6
6
  "unocss",
@@ -30,14 +30,12 @@
30
30
  "main": "./dist/index.cjs",
31
31
  "module": "./dist/index.mjs",
32
32
  "types": "./dist/index.d.ts",
33
- "peerDependencies": {
34
- "@unocss/core": "0.26.2"
35
- },
36
33
  "dependencies": {
34
+ "@unocss/core": "0.27.0",
37
35
  "css-tree": "^2.0.4"
38
36
  },
39
37
  "devDependencies": {
40
- "@unocss/core": "0.26.2"
38
+ "magic-string-extra": "^0.1.2"
41
39
  },
42
40
  "scripts": {
43
41
  "build": "unbuild",