styimat 3.6.0 → 4.1.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 +18 -12
- package/bin/{convert-styimat.js → cli.js} +1 -1
- package/dist/styimat.js +100 -10
- package/dist/styimat.min.js +21 -19
- package/dist/styimat.min.mjs +21 -19
- package/dist/styimat.mjs +101 -11
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ npm install styimat
|
|
|
56
56
|
|
|
57
57
|
### 5. ESModule使用
|
|
58
58
|
```javascript
|
|
59
|
-
import styimat from 'https://
|
|
59
|
+
import styimat from 'https://unpkg.com/styimat/esm'
|
|
60
60
|
const css = `
|
|
61
61
|
$primary: lab(54.7 77.9 80.1);
|
|
62
62
|
.button { background-color: $primary; }
|
|
@@ -66,20 +66,10 @@ const result = styimat.convent(css);
|
|
|
66
66
|
console.log(result);
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
```javascript
|
|
70
|
-
import styimat from 'https://cdn.jsdelivr.net/npm/styimat/styimat.min.mjs'
|
|
71
|
-
const css = `
|
|
72
|
-
$primary: lab(54.7 77.9 80.1);
|
|
73
|
-
.button { background-color: $primary; }
|
|
74
|
-
`;
|
|
75
|
-
|
|
76
|
-
const result = styimat(css);
|
|
77
|
-
console.log(result);
|
|
78
|
-
```
|
|
79
69
|
**也可以按需导入**
|
|
80
70
|
|
|
81
71
|
```javascript
|
|
82
|
-
import { convent, apply } from 'https://
|
|
72
|
+
import { convent, apply } from 'https://unpkg.com/styimat/esm'
|
|
83
73
|
const css = `
|
|
84
74
|
$primary: lab(54.7 77.9 80.1);
|
|
85
75
|
.button { background-color: $primary; }
|
|
@@ -101,6 +91,7 @@ apply();
|
|
|
101
91
|
- **轻量高效** - 无依赖,压缩后仅约 20KB
|
|
102
92
|
- **多种使用方式** - 浏览器、Node.js、命令行均可使用
|
|
103
93
|
- **灵活API** - 支持函数调用、模板标签、对象配置等多种用法
|
|
94
|
+
- **现代ESModule导入** - 支持`import`按需导入
|
|
104
95
|
|
|
105
96
|
## 快速开始
|
|
106
97
|
|
|
@@ -359,6 +350,21 @@ body {
|
|
|
359
350
|
<style src="head.css" e></style>
|
|
360
351
|
```
|
|
361
352
|
|
|
353
|
+
### 别名语法
|
|
354
|
+
|
|
355
|
+
#### 您可以在CSS文件的开头使用别名来让css属性名更简单,应该以`@alias开头`:
|
|
356
|
+
|
|
357
|
+
```css
|
|
358
|
+
@alias bg background-color;
|
|
359
|
+
|
|
360
|
+
/* 然后写您的CSS代码 */
|
|
361
|
+
$primary-color: lab#32a852;
|
|
362
|
+
|
|
363
|
+
body {
|
|
364
|
+
bg: $primary-color;
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
362
368
|
### 配置头语法
|
|
363
369
|
|
|
364
370
|
您可以在CSS文件的开头使用配置头来设置预处理选项,配置行以 `#` 开头:
|
|
@@ -174,7 +174,7 @@ async function convertAndOutput(inputContent, outputFile) {
|
|
|
174
174
|
async function convertStyimat(inputContent) {
|
|
175
175
|
// 尝试从多个位置加载 styimat.js
|
|
176
176
|
const possiblePaths = [
|
|
177
|
-
path.join(__dirname, 'dist', 'styimat.js'),
|
|
177
|
+
path.join(path.dirname(__dirname), 'dist', 'styimat.js'),
|
|
178
178
|
path.join(process.cwd(), 'dist', 'styimat.js'),
|
|
179
179
|
path.join(process.cwd(), 'node_modules', 'styimat', 'dist', 'styimat.js')
|
|
180
180
|
];
|
package/dist/styimat.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* 增强 math() 函数,支持复杂数学计算
|
|
12
12
|
* 支持配置头
|
|
13
13
|
* 支持 @import 语法
|
|
14
|
+
* 支持 @alias 语法
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
17
|
const styimat = (function() {
|
|
@@ -31,6 +32,7 @@ const styimat = (function() {
|
|
|
31
32
|
importBaseUrl: '', // @import 的基础URL
|
|
32
33
|
importCache: true, // 缓存导入的文件
|
|
33
34
|
importTimeout: 5000, // 导入超时时间(毫秒)
|
|
35
|
+
enableAlias: true, // 启用别名功能
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
// 全局P3支持检测结果
|
|
@@ -38,6 +40,9 @@ const styimat = (function() {
|
|
|
38
40
|
|
|
39
41
|
// 导入文件缓存
|
|
40
42
|
const importCache = new Map();
|
|
43
|
+
|
|
44
|
+
// 别名映射表
|
|
45
|
+
const aliasMap = new Map();
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
48
|
* 解析配置头
|
|
@@ -92,6 +97,42 @@ const styimat = (function() {
|
|
|
92
97
|
};
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
/**
|
|
101
|
+
* 解析 @alias 语句
|
|
102
|
+
* @param {string} cssText - CSS文本
|
|
103
|
+
* @returns {Object} {aliases: 别名映射, css: 清理后的CSS}
|
|
104
|
+
*/
|
|
105
|
+
function parseAliasStatements(cssText) {
|
|
106
|
+
const aliases = new Map();
|
|
107
|
+
const lines = cssText.split('\n');
|
|
108
|
+
const cleanLines = [];
|
|
109
|
+
|
|
110
|
+
for (let line of lines) {
|
|
111
|
+
const trimmed = line.trim();
|
|
112
|
+
|
|
113
|
+
// 检查是否是 @alias 语句
|
|
114
|
+
if (trimmed.startsWith('@alias')) {
|
|
115
|
+
const aliasMatch = trimmed.match(/^@alias\s+([a-zA-Z0-9_-]+)\s+(.+?)\s*;$/);
|
|
116
|
+
if (aliasMatch) {
|
|
117
|
+
const aliasName = aliasMatch[1];
|
|
118
|
+
const originalProperty = aliasMatch[2];
|
|
119
|
+
|
|
120
|
+
// 存储别名映射
|
|
121
|
+
aliases.set(aliasName, originalProperty);
|
|
122
|
+
console.log(`注册别名: ${aliasName} -> ${originalProperty}`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
cleanLines.push(line);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
aliases,
|
|
132
|
+
css: cleanLines.join('\n')
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
95
136
|
/**
|
|
96
137
|
* 将连字符分隔的字符串转换为驼峰命名
|
|
97
138
|
* @param {string} str - 输入字符串
|
|
@@ -131,7 +172,7 @@ const styimat = (function() {
|
|
|
131
172
|
* @param {string} cssString - 要解析的CSS字符串
|
|
132
173
|
* @returns {Array} 包含属性名值对象的数组
|
|
133
174
|
*/
|
|
134
|
-
function parseSingleLineCSS(cssString) {
|
|
175
|
+
function parseSingleLineCSS(cssString, aliases=[]) {
|
|
135
176
|
// 移除首尾空白字符
|
|
136
177
|
let str = cssString.trim();
|
|
137
178
|
|
|
@@ -205,7 +246,7 @@ const styimat = (function() {
|
|
|
205
246
|
}
|
|
206
247
|
|
|
207
248
|
// 分割属性名和值
|
|
208
|
-
|
|
249
|
+
let property = declaration.substring(0, colonIndex).trim();
|
|
209
250
|
let value = declaration.substring(colonIndex + 1).trim();
|
|
210
251
|
|
|
211
252
|
// 如果值以分号结尾,移除它(理论上不应该有,但处理一下)
|
|
@@ -213,6 +254,10 @@ const styimat = (function() {
|
|
|
213
254
|
value = value.slice(0, -1).trim();
|
|
214
255
|
}
|
|
215
256
|
|
|
257
|
+
if (aliases.get(property)) {
|
|
258
|
+
property = aliases.get(property);
|
|
259
|
+
}
|
|
260
|
+
|
|
216
261
|
// 添加到结果数组
|
|
217
262
|
result.push({ [property]: value });
|
|
218
263
|
}
|
|
@@ -1035,7 +1080,8 @@ const styimat = (function() {
|
|
|
1035
1080
|
}
|
|
1036
1081
|
|
|
1037
1082
|
// 修复的嵌套解析函数
|
|
1038
|
-
function parseNestedRules(cssText, config) {
|
|
1083
|
+
function parseNestedRules(cssText, config, aliases) {
|
|
1084
|
+
|
|
1039
1085
|
const lines = cssText.split('\n');
|
|
1040
1086
|
const stack = []; // 存储规则信息:{selector, properties, children}
|
|
1041
1087
|
const rootRules = [];
|
|
@@ -1089,7 +1135,7 @@ const styimat = (function() {
|
|
|
1089
1135
|
if (stack.length > 0) {
|
|
1090
1136
|
const currentRule = stack[stack.length - 1];
|
|
1091
1137
|
// 处理属性值中的math()函数和颜色转换
|
|
1092
|
-
const parsed = parseSingleLineCSS(trimmed);
|
|
1138
|
+
const parsed = parseSingleLineCSS(trimmed, aliases);
|
|
1093
1139
|
parsed.forEach(obj => {
|
|
1094
1140
|
const key = Object.keys(obj)[0];
|
|
1095
1141
|
const value = processCSSValue(obj[key], config);
|
|
@@ -1113,11 +1159,11 @@ const styimat = (function() {
|
|
|
1113
1159
|
}
|
|
1114
1160
|
|
|
1115
1161
|
// 将规则树转换为CSS字符串
|
|
1116
|
-
return convertRulesToCSS(rootRules, config);
|
|
1162
|
+
return convertRulesToCSS(rootRules, config, '', aliases);
|
|
1117
1163
|
}
|
|
1118
1164
|
|
|
1119
1165
|
// 将规则树转换为CSS字符串
|
|
1120
|
-
function convertRulesToCSS(rules, config, parentSelector = '') {
|
|
1166
|
+
function convertRulesToCSS(rules, config, parentSelector = '', aliases=[]) {
|
|
1121
1167
|
let result = '';
|
|
1122
1168
|
const isParentAt = parentSelector.startsWith("@");
|
|
1123
1169
|
|
|
@@ -1146,7 +1192,7 @@ const styimat = (function() {
|
|
|
1146
1192
|
result += (isAt ? "" : fullSelector) + ' {\n';
|
|
1147
1193
|
for (const prop of rule.properties) {
|
|
1148
1194
|
// 再次处理属性值(确保math()函数和颜色被转换)
|
|
1149
|
-
const parsed = parseSingleLineCSS(prop);
|
|
1195
|
+
const parsed = parseSingleLineCSS(prop, aliases);
|
|
1150
1196
|
parsed.forEach(obj => {
|
|
1151
1197
|
const key = Object.keys(obj)[0];
|
|
1152
1198
|
const value = processCSSValue(obj[key], config);
|
|
@@ -1158,7 +1204,7 @@ const styimat = (function() {
|
|
|
1158
1204
|
|
|
1159
1205
|
// 递归处理子规则
|
|
1160
1206
|
if (rule.children && rule.children.length > 0) {
|
|
1161
|
-
result += convertRulesToCSS(rule.children, config, fullSelector);
|
|
1207
|
+
result += convertRulesToCSS(rule.children, config, fullSelector, aliases);
|
|
1162
1208
|
}
|
|
1163
1209
|
|
|
1164
1210
|
if (isParentAt){
|
|
@@ -1387,15 +1433,24 @@ const styimat = (function() {
|
|
|
1387
1433
|
const { config: headerConfig, css: cleanedCSS } = parseConfigHeader(cssText);
|
|
1388
1434
|
const finalConfig = { ...defaultConfig, ...customConfig,...headerConfig };
|
|
1389
1435
|
|
|
1436
|
+
// 0. 解析 @alias 语句(如果有)
|
|
1437
|
+
let cssWithAliases = cleanedCSS;
|
|
1438
|
+
let aliases = new Map();
|
|
1439
|
+
if (finalConfig.enableAlias) {
|
|
1440
|
+
const { aliases: parsedAliases, css: cssWithoutAliases } = parseAliasStatements(cssWithAliases);
|
|
1441
|
+
aliases = parsedAliases;
|
|
1442
|
+
cssWithAliases = cssWithoutAliases;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1390
1445
|
// 1. 提取变量定义(区分全局和选择器局部)
|
|
1391
1446
|
const { globalVariables, selectorVariables, cssWithoutVars } =
|
|
1392
|
-
extractVariablesAndCSS(
|
|
1447
|
+
extractVariablesAndCSS(cssWithAliases, finalConfig);
|
|
1393
1448
|
|
|
1394
1449
|
// 2. 解析嵌套规则(如果启用)
|
|
1395
1450
|
let processedCSS = cssWithoutVars.trim();
|
|
1396
1451
|
if (finalConfig.enableNesting && cssWithoutVars.includes('{')) {
|
|
1397
1452
|
try {
|
|
1398
|
-
processedCSS = parseNestedRules(cssWithoutVars, finalConfig);
|
|
1453
|
+
processedCSS = parseNestedRules(cssWithoutVars, finalConfig, aliases);
|
|
1399
1454
|
} catch (error) {
|
|
1400
1455
|
console.warn('嵌套解析失败,使用原始CSS:', error);
|
|
1401
1456
|
}
|
|
@@ -1573,6 +1628,41 @@ const styimat = (function() {
|
|
|
1573
1628
|
}
|
|
1574
1629
|
},
|
|
1575
1630
|
|
|
1631
|
+
// 别名相关方法
|
|
1632
|
+
aliases: {
|
|
1633
|
+
/**
|
|
1634
|
+
* 注册别名
|
|
1635
|
+
* @param {string} alias - 别名
|
|
1636
|
+
* @param {string} property - 原始属性
|
|
1637
|
+
*/
|
|
1638
|
+
add: function(alias, property) {
|
|
1639
|
+
aliasMap.set(alias, property);
|
|
1640
|
+
},
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* 移除别名
|
|
1644
|
+
* @param {string} alias - 别名
|
|
1645
|
+
*/
|
|
1646
|
+
remove: function(alias) {
|
|
1647
|
+
aliasMap.delete(alias);
|
|
1648
|
+
},
|
|
1649
|
+
|
|
1650
|
+
/**
|
|
1651
|
+
* 获取所有别名
|
|
1652
|
+
* @returns {Array} 别名数组
|
|
1653
|
+
*/
|
|
1654
|
+
getAll: function() {
|
|
1655
|
+
return Array.from(aliasMap.entries());
|
|
1656
|
+
},
|
|
1657
|
+
|
|
1658
|
+
/**
|
|
1659
|
+
* 清除所有别名
|
|
1660
|
+
*/
|
|
1661
|
+
clear: function() {
|
|
1662
|
+
aliasMap.clear();
|
|
1663
|
+
}
|
|
1664
|
+
},
|
|
1665
|
+
|
|
1576
1666
|
// 数学计算工具方法
|
|
1577
1667
|
math: {
|
|
1578
1668
|
/**
|
package/dist/styimat.min.js
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* MIT License
|
|
3
3
|
* Copyright (c) 2025 王小玗
|
|
4
|
-
*/const styimat=(function(){let d={rootSelector:":root",variablePrefix:"--",preserveOriginal:!1,indentSize:4,enableNesting:!0,autoProcessStyleTags:!0,styleTagAttribute:"e",convertLabToRGB:!0,convertLchToRGB:!0,enableP3:!0,enableMath:!0,mathPrecision:6,importBaseUrl:"",importCache:!0,importTimeout:5e3},
|
|
5
|
-
`),
|
|
6
|
-
`)}}function
|
|
7
|
-
`),
|
|
8
|
-
|
|
9
|
-
`}c=!1,i=
|
|
10
|
-
|
|
11
|
-
`
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
`
|
|
4
|
+
*/const styimat=(function(){let d={rootSelector:":root",variablePrefix:"--",preserveOriginal:!1,indentSize:4,enableNesting:!0,autoProcessStyleTags:!0,styleTagAttribute:"e",convertLabToRGB:!0,convertLchToRGB:!0,enableP3:!0,enableMath:!0,mathPrecision:6,importBaseUrl:"",importCache:!0,importTimeout:5e3,enableAlias:!0},M=null;const T=new Map,F=new Map;function Y(t){const e={...d},n=t.split(`
|
|
5
|
+
`),s=[];for(let r of n){const o=r.trim();if(o.startsWith("#")){const i=o.substring(1).trim(),c=i.indexOf(" ");if(c!==-1){const a=i.substring(0,c).trim(),l=i.substring(c+1).trim(),u=Q(a);u in e?l==="true"||l==="false"?e[u]=l==="true":!isNaN(l)&&l.trim()!==""?e[u]=Number(l):e[u]=l:console.warn(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${a}`)}else console.warn(`\u65E0\u6548\u7684\u914D\u7F6E\u884C: ${o}`)}else s.push(r)}return{config:e,css:s.join(`
|
|
6
|
+
`)}}function D(t){const e=new Map,n=t.split(`
|
|
7
|
+
`),s=[];for(let r of n){const o=r.trim();if(o.startsWith("@alias")){const i=o.match(/^@alias\s+([a-zA-Z0-9_-]+)\s+(.+?)\s*;$/);if(i){const c=i[1],a=i[2];e.set(c,a),console.log(`\u6CE8\u518C\u522B\u540D: ${c} -> ${a}`);continue}}s.push(r)}return{aliases:e,css:s.join(`
|
|
8
|
+
`)}}function Q(t){return t.replace(/-([a-z])/g,function(e,n){return n.toUpperCase()})}function E(){if(M!==null)return M;if(typeof window>"u"||!window.CSS)return M=!1,!1;try{M=CSS.supports("color","color(display-p3 1 0 0)")}catch(t){console.warn("P3\u652F\u6301\u68C0\u6D4B\u5931\u8D25:",t),M=!1}return M}function V(t,e=[]){let n=t.trim();if(n.endsWith(";")&&(n=n.slice(0,-1)),!n)return[];const s=[];let r="",o=0,i=!1,c="";for(let l=0;l<n.length;l++){const u=n[l];(u==='"'||u==="'")&&!i?(i=!0,c=u):u===c&&i&&(i=!1,c=""),i||(u==="("?o++:u===")"&&o--),u===";"&&!i&&o===0?r.trim()&&(s.push(r.trim()),r=""):r+=u}r.trim()&&s.push(r.trim());const a=[];for(const l of s){if(!l.trim())continue;const u=K(l);if(u===-1){console.warn(`\u65E0\u6548\u7684CSS\u58F0\u660E: "${l}"`);continue}let p=l.substring(0,u).trim(),f=l.substring(u+1).trim();f.endsWith(";")&&(f=f.slice(0,-1).trim()),e.get(p)&&(p=e.get(p)),a.push({[p]:f})}return a}function K(t){let e=!1,n="";for(let s=0;s<t.length;s++){const r=t[s];if((r==='"'||r==="'")&&!e?(e=!0,n=r):r===n&&e&&(e=!1,n=""),r===":"&&!e)return s}return-1}function I(t,e){if(!e.enableMath)return`math(${t})`;try{let n=t.replace(/\s+/g,"");const s=_(n,e);return J(n)?tt(n,s):k(s,e.mathPrecision)}catch(n){return console.warn("math()\u8868\u8FBE\u5F0F\u89E3\u6790\u5931\u8D25:",t,n),`math(${t})`}}function _(t,e){for(;t.includes("(")&&t.includes(")");){const n=t.lastIndexOf("("),s=t.indexOf(")",n);if(s===-1)break;const r=t.substring(n+1,s),o=_(r,e);t=t.substring(0,n)+o+t.substring(s+1)}return Z(t,e)}function Z(t,e){const n=[{regex:/([\d.]+(?:[a-zA-Z%]+)?)\*([\d.]+(?:[a-zA-Z%]+)?)/,handler:et},{regex:/([\d.]+(?:[a-zA-Z%]+)?)\/([\d.]+(?:[a-zA-Z%]+)?)/,handler:nt},{regex:/([\d.]+(?:[a-zA-Z%]+)?)\+([\d.]+(?:[a-zA-Z%]+)?)/,handler:rt},{regex:/([\d.]+(?:[a-zA-Z%]+)?)-([\d.]+(?:[a-zA-Z%]+)?)/,handler:st}];let s=t;for(const o of n){let i;for(;(i=t.match(o.regex))!==null;){const c=x(i[1]),a=x(i[2]),l=o.handler(c,a);t=t.substring(0,i.index)+l.value+t.substring(i.index+i[0].length)}}return t!==s?Z(t,e):x(t).value}function x(t){const e=t.match(/^([\d.]+)([a-zA-Z%]*)$/);if(!e)throw new Error(`\u65E0\u6CD5\u89E3\u6790\u503C: ${t}`);const n=parseFloat(e[1]),s=e[2]||"";return{value:n,unit:s}}function J(t){return/[a-zA-Z%]/.test(t)}function tt(t,e){const n=t.match(/([a-zA-Z%]+)(?!.*[a-zA-Z%])/);return n?e+n[1]:t.includes("%")?e+"%":e+"px"}function et(t,e){return t.unit===e.unit||!t.unit&&!e.unit?{value:t.value*e.value,unit:t.unit||e.unit}:{value:`${t.value}${t.unit}*${e.value}${e.unit}`,unit:""}}function nt(t,e){if(e.value===0)throw new Error("\u9664\u4EE5\u96F6");return t.unit&&!e.unit?{value:t.value/e.value,unit:t.unit}:t.unit===e.unit?{value:t.value/e.value,unit:""}:{value:`${t.value}${t.unit}/${e.value}${e.unit}`,unit:""}}function rt(t,e){return t.unit===e.unit?{value:t.value+e.value,unit:t.unit}:{value:`${t.value}${t.unit}+${e.value}${e.unit}`,unit:""}}function st(t,e){return t.unit===e.unit?{value:t.value-e.value,unit:t.unit}:{value:`${t.value}${t.unit}-${e.value}${e.unit}`,unit:""}}function k(t,e=6){const n=Math.pow(10,e),r=(Math.round(t*n)/n).toString();return r.includes(".")?r.replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,""):r}function ot(t,e){if(!e.enableMath)return t;let n=t;const s=/math\(([^)]+)\)/gi,r=i=>i.replace(s,(c,a)=>I(a,e));let o;do o=n,n=r(n);while(n!==o&&n.includes("math("));return n}function it(t,e){if(!e.convertLabToRGB&&!e.convertLchToRGB)return t;let n=t;n=ct(n,e);const s=/(lab|lch)\([^)]+\)/gi,r=new Map,o=c=>c.replace(s,a=>{if(r.has(a))return r.get(a);let l=a;return a.toLowerCase().startsWith("lab(")?e.convertLabToRGB&&(l=at(a,e)):a.toLowerCase().startsWith("lch(")&&e.convertLchToRGB&&(l=lt(a,e)),r.set(a,l),l});let i;do i=n,n=o(n);while(n!==i);return n}function ct(t,e){let n=t;const s=/lab#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/gi,r=/lch#([0-9a-f]{2})([0-9a-f]{2})(\d{1,3})/gi,o=new Map;return n=n.replace(s,(i,c,a,l)=>{if(o.has(i))return o.get(i);try{const u=parseInt(c,16)/255*100,p=(parseInt(a,16)-128)*1.5,f=(parseInt(l,16)-128)*1.5,h=S(u,p,f,e);return o.set(i,h),h}catch(u){return console.warn(`\u65E0\u6CD5\u89E3\u6790lab#\u5341\u516D\u8FDB\u5236\u989C\u8272: ${i}`,u),i}}),n=n.replace(r,(i,c,a,l)=>{if(o.has(i))return o.get(i);try{const u=parseInt(c,16)/255*100,p=parseInt(a,16)/255*150,f=parseInt(l)/100*360,h=C(u,p,f),m=S(h.L,h.a,h.b,e);return o.set(i,m),m}catch(u){return console.warn(`\u65E0\u6CD5\u89E3\u6790lch#\u5341\u516D\u8FDB\u5236\u989C\u8272: ${i}`,u),i}}),n}function at(t,e){const n=/lab\(\s*([\d.]+)(%?)\s+([\d.-]+)\s+([\d.-]+)(?:\s*\/\s*([\d.%]+))?\s*\)/i,s=t.match(n);if(!s)return t;try{let r=parseFloat(s[1]);s[2]==="%"?r=r:(r<0&&(r=0),r>100&&(r=100));const o=parseFloat(s[3]),i=parseFloat(s[4]),c=s[5]!==void 0?s[5].includes("%")?parseFloat(s[5])/100:parseFloat(s[5]):null;return S(r,o,i,e,c)}catch(r){return console.warn(`\u65E0\u6CD5\u8F6C\u6362LAB\u989C\u8272: ${t}`,r),t}}function lt(t,e){const n=/lch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(deg)?(?:\s*\/\s*([\d.%]+))?\s*\)/i,s=t.match(n);if(!s)return t;try{let r=parseFloat(s[1]);s[2]==="%"?r=r:(r<0&&(r=0),r>100&&(r=100));const o=parseFloat(s[3]);let i=parseFloat(s[4]);o<0&&console.warn(`LCH\u4E2D\u7684C\u503C\u4E0D\u80FD\u4E3A\u8D1F: ${o}`),i=(i%360+360)%360;const c=C(r,o,i),a=s[6]!==void 0?s[6].includes("%")?parseFloat(s[6])/100:parseFloat(s[6]):null;return S(c.L,c.a,c.b,e,a)}catch(r){return console.warn(`\u65E0\u6CD5\u8F6C\u6362LCH\u989C\u8272: ${t}`,r),t}}function C(t,e,n){const s=n*Math.PI/180,r=e*Math.cos(s),o=e*Math.sin(s);return{L:t,a:r,b:o}}function w(t,e,n){const s=(g,b,y)=>{const q=(g+16)/116,O=b/500+q,W=q-y/200,$t=O**3>.008856?O**3:(116*O-16)/903.3,vt=g>903.3*.008856?((g+16)/116)**3:g/903.3,wt=W**3>.008856?W**3:(116*W-16)/903.3;return[$t*.95047,vt*1,wt*1.08883]},r=(g,b,y)=>{const v=[[3.2404542,-1.5371385,-.4985314],[-.969266,1.8760108,.041556],[.0556434,-.2040259,1.0572252]],z=v[0][0]*g+v[0][1]*b+v[0][2]*y,U=v[1][0]*g+v[1][1]*b+v[1][2]*y,X=v[2][0]*g+v[2][1]*b+v[2][2]*y;return[z,U,X]},o=g=>{const b=g<0?-1:1,y=Math.abs(g);return y<=.0031308?b*12.92*y:b*(1.055*Math.pow(y,.4166666666666667)-.055)},i=g=>Math.max(0,Math.min(255,Math.round(g*255))),[c,a,l]=s(t,e,n),[u,p,f]=r(c,a,l),h=o(u),m=o(p),$=o(f);return{r:i(h),g:i(m),b:i($)}}function R(t,e,n){const s=(c,a,l)=>{const $=(c+16)/116,g=a/500+$,b=$-l/200,y=g**3>.008856?g**3:(116*g-16)/903.3,v=c>903.3*.008856?((c+16)/116)**3:c/903.3,z=b**3>.008856?b**3:(116*b-16)/903.3;return[y*.95047,v*1,z*1.08883]},r=(c,a,l)=>{const u=[[2.493496911941425,-.9313836179191239,-.40271078445071684],[-.8294889695615747,1.7626640603183463,.023624685841943577],[.03584583024378447,-.07617238926804182,.9568845240076872]],p=u[0][0]*c+u[0][1]*a+u[0][2]*l,f=u[1][0]*c+u[1][1]*a+u[1][2]*l,h=u[2][0]*c+u[2][1]*a+u[2][2]*l;return[p,f,h]},o=c=>{const a=c<0?-1:1,l=Math.abs(c);return l<=.0031308?a*12.92*l:a*(1.055*Math.pow(l,.4166666666666667)-.055)},i=c=>Math.max(0,Math.min(255,Math.round(c*255)));try{const[c,a,l]=s(t,e,n),[u,p,f]=r(c,a,l),h=o(u),m=o(p),$=o(f);return{r:Math.max(0,Math.min(1,h)),g:Math.max(0,Math.min(1,m)),b:Math.max(0,Math.min(1,$))}}catch(c){console.warn("P3\u8F6C\u6362\u5931\u8D25:",c);const a=w(t,e,n);return{r:a.r/255,g:a.g/255,b:a.b/255}}}function S(t,e,n,s,r=null){if(!s.enableP3||!E()){const o=w(t,e,n);return r!==null?`rgba(${o.r}, ${o.g}, ${o.b}, ${r})`:`rgb(${o.r}, ${o.g}, ${o.b})`}else{const o=R(t,e,n);return r!==null?`color(display-p3 ${o.r.toFixed(4)} ${o.g.toFixed(4)} ${o.b.toFixed(4)} / ${r})`:`color(display-p3 ${o.r.toFixed(4)} ${o.g.toFixed(4)} ${o.b.toFixed(4)})`}}function A(t,e){let n=t;return e.enableMath&&(n=ot(n,e)),(e.convertLabToRGB||e.convertLchToRGB)&&(n=it(n,e)),n}function ut(t,e){const n=t.split(`
|
|
9
|
+
`),s={},r=new Map;let o="",i=null,c=!1,a=0;for(let l of n){const u=l.trim(),p=u.match(/^\$([a-zA-Z0-9_-]+)\s*:\s*(.+?);?$/);if(p){const[,f,h]=p,m=A(H(h.trim(),{...s,...i?r.get(i)||{}:{}}),e);i?(r.has(i)||r.set(i,{}),r.get(i)[f]=m):s[f]=m;continue}if(u.endsWith("{")){i=u.slice(0,-1).trim(),c=!0,o+=l+`
|
|
10
|
+
`;continue}if(u==="}"){if(c&&i&&r.has(i)){const f=r.get(i),h=" ".repeat(a);for(const[m,$]of Object.entries(f))o+=`${h} --${m}: ${$};
|
|
11
|
+
`}c=!1,i=null}o+=l+`
|
|
12
|
+
`,l.includes("{")&&(a+=e.indentSize),l.includes("}")&&(a=Math.max(0,a-e.indentSize))}return{globalVariables:s,selectorVariables:r,cssWithoutVars:o.trim()}}function ft(t,e,n){const s=t.split(`
|
|
13
|
+
`),r=[],o=[];let i=0;for(let c=0;c<s.length;c++){const a=s[c],l=a.trim();if(!l)continue;const u=a.match(/^(\s*)/)[0].length;if(l==="}"){if(r.length>0){const p=r.pop();if(r.length>0){const f=r[r.length-1];f.children||(f.children=[]),f.children.push(p)}else o.push(p)}continue}if(l.endsWith("{")){const f={selector:l.slice(0,-1).trim(),properties:[],children:[]};r.push(f);continue}if(!l.includes("{")&&!l.includes("}")&&l.includes(":")){if(r.length>0){const p=r[r.length-1];V(l,n).forEach(h=>{const m=Object.keys(h)[0],$=A(h[m],e);p.properties.push(`${m}: ${$}`)})}continue}}for(;r.length>0;){const c=r.pop();if(r.length===0)o.push(c);else{const a=r[r.length-1];a.children||(a.children=[]),a.children.push(c)}}return j(o,e,"",n)}function j(t,e,n="",s=[]){let r="";const o=n.startsWith("@");for(const i of t){const c=i.selector.startsWith("@");let a=(o?" ".repeat(e.indentSize):"")+i.selector;if(c&&(a=i.selector+` {
|
|
14
|
+
`),n&&(a.includes("&")?a=a.replace(/&/g,n):a.trim().startsWith(":")?a=n+a:a=n+(o?"":" ")+a),i.properties.length>0){r+=(c?"":a)+` {
|
|
15
|
+
`;for(const l of i.properties)V(l,s).forEach(p=>{const f=Object.keys(p)[0],h=A(p[f],e);r+=(o?" ".repeat(e.indentSize):"")+" ".repeat(e.indentSize)+`${f}: ${h};
|
|
16
|
+
`});r+=o?" ".repeat(e.indentSize)+`}
|
|
15
17
|
`:`}
|
|
16
18
|
|
|
17
|
-
`}
|
|
19
|
+
`}i.children&&i.children.length>0&&(r+=j(i.children,e,a,s)),o&&(r+=`}
|
|
18
20
|
|
|
19
|
-
`)}return
|
|
21
|
+
`)}return r.trim()+`
|
|
20
22
|
|
|
21
|
-
`}function H(t,e){return t.replace(/\$([a-zA-Z0-9_-]+)/g,(
|
|
23
|
+
`}function H(t,e){return t.replace(/\$([a-zA-Z0-9_-]+)/g,(n,s)=>e[s]?`var(--${s})`:n)}function pt(t,e,n,s){let r=t;return r=r.replace(/(?:\$\$|\$)([a-zA-Z0-9_-]+)/g,(o,i)=>o.startsWith("$$")?`attr(${i})`:`var(--${i})`),r=A(r,s),r}function ht(t,e){if(Object.keys(t).length===0)return"";const n=Object.entries(t).map(([s,r])=>{const o=A(H(r,t),e);return" ".repeat(e.indentSize)+`--${s}: ${o};`}).join(`
|
|
22
24
|
`);return`${e.rootSelector} {
|
|
23
|
-
${
|
|
25
|
+
${n}
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
`}function
|
|
27
|
-
`);let
|
|
28
|
-
`}
|
|
29
|
-
`}return
|
|
28
|
+
`}function dt(t,e,n){let s="";const r=t.split(`
|
|
29
|
+
`);let o=null;for(let i of r){const c=i.trim();if(c.endsWith("{")&&(o=c.slice(0,-1).trim()),c==="}"&&o){if(e.has(o)){const a=e.get(o),l=i.match(/^(\s*)/)[0];for(const[u,p]of Object.entries(a))s+=" --"+u+": "+p+`;
|
|
30
|
+
`}o=null}s+=A(i,n)+`
|
|
31
|
+
`}return s.trim()}async function N(t,e){const n=/@import\s+([^;]+?)\s*;/g;return(async r=>{const o=[],i=r.replace(n,(c,a)=>{const l=mt(a,e).then(u=>N(u,e)).catch(u=>(console.warn(`\u65E0\u6CD5\u5BFC\u5165CSS\u6587\u4EF6: ${a}`,u),""));return o.push(l),`__IMPORT_PLACEHOLDER_${o.length-1}__`});if(o.length>0){const c=await Promise.all(o);let a=i;for(let l=0;l<c.length;l++)a=a.replace(`__IMPORT_PLACEHOLDER_${l}__`,c[l]);return a}return i})(t)}async function mt(t,e){if(e.importCache&&T.has(t))return T.get(t);const n=e.importBaseUrl?new URL(t,e.importBaseUrl).href:t;let s;if(typeof process<"u"&&process.versions&&process.versions.node&&typeof require<"u")try{const o=require("fs"),i=require("path");let c=n;n.startsWith(".")&&(c=i.join(process.cwd(),n)),s=o.readFileSync(c,"utf-8")}catch(o){throw new Error(`Node.js\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25: ${n} - ${o.message}`)}else try{const o=new AbortController,i=setTimeout(()=>o.abort(),e.importTimeout),c=await fetch(n,{signal:o.signal,headers:{Accept:"text/css"}});if(clearTimeout(i),!c.ok)throw new Error(`HTTP\u9519\u8BEF: ${c.status} ${c.statusText}`);s=await c.text()}catch(o){throw o.name==="AbortError"?new Error(`\u5BFC\u5165\u8D85\u65F6: ${n}`):new Error(`\u65E0\u6CD5\u83B7\u53D6CSS: ${n} - ${o.message}`)}return e.importCache&&T.set(t,s),s}function L(t,e={}){const n=(o,i)=>{const{config:c,css:a}=Y(o),l={...d,...e,...c};let u=a,p=new Map;if(l.enableAlias){const{aliases:y,css:v}=D(u);p=y,u=v}const{globalVariables:f,selectorVariables:h,cssWithoutVars:m}=ut(u,l);let $=m.trim();if(l.enableNesting&&m.includes("{"))try{$=ft(m,l,p)}catch(y){console.warn("\u5D4C\u5957\u89E3\u6790\u5931\u8D25\uFF0C\u4F7F\u7528\u539F\u59CBCSS:",y)}const g=ht(f,l);let b=$;return h.size>0&&(b=dt($,h,l)),b=pt(b,f,h,l),g+b},s=t&&/@import\s+([^;]+?)\s*;/g.test(t),r={...d,...e};return s?(async()=>{try{const o=await N(t,r);return n(o,r)}catch(o){return console.error("@import\u5904\u7406\u5931\u8D25:",o),n(cleanedCSS,r)}})():n(t,r)}function G(t={}){const e={...d,...t},n=document.querySelectorAll(`style[${e.styleTagAttribute||"e"}]`);return n.forEach(s=>{let r=s.textContent;(async()=>{try{s.getAttribute("src")&&(r="@import "+s.getAttribute("src")+";");const i=await L(r,e),c=document.createElement("style");c.textContent=i,s.parentNode.insertBefore(c,s.nextSibling),e.preserveOriginal?s.style.display="none":s.remove()}catch(i){console.error("\u5904\u7406style\u6807\u7B7E\u5931\u8D25:",i)}})()}),n.length}function gt(t={}){d={...d,...t}}function B(t,e={}){const n={...d,...e};if(t){if(/@import\s+([^;]+?)\s*;/g.test(t))return(async()=>{try{const r=await L(t,n),o=document.createElement("style");return o.textContent=r,document.head.appendChild(o),o}catch(r){return console.error("\u5E94\u7528CSS\u5931\u8D25:",r),null}})();{const r=L(t,n),o=document.createElement("style");return o.textContent=r,document.head.appendChild(o),o}}else document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{G(n)}):G(n)}const bt={convert:L,apply:B,config:gt,supportsP3:E(),detectP3Support:E,imports:{clearCache:function(){T.clear()},setBaseUrl:function(t){d.importBaseUrl=t},setCacheEnabled:function(t){d.importCache=t},setTimeout:function(t){d.importTimeout=t}},aliases:{add:function(t,e){F.set(t,e)},remove:function(t){F.delete(t)},getAll:function(){return Array.from(F.entries())},clear:function(){F.clear()}},math:{evaluate:function(t){return I(t,d)},parseUnit:x,round:k,test:function(t,e={}){const n={...d,...e};try{const s=I(t,n);return{success:!0,expression:t,result:s,parsed:x(s.replace(/^calc\(|\)$/g,""))}}catch(s){return{success:!1,expression:t,error:s.message}}}},colorUtils:{labToRGB:w,lchToLab:C,lchToRGB:function(t,e,n){const s=C(t,e,n);return w(s.L,s.a,s.b)},labToP3:R,lchToP3:function(t,e,n){const s=C(t,e,n);return R(s.L,s.a,s.b)},parseHexLab:function(t){const e=t.match(/lab#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i);if(!e)return null;const n=e[1],s=e[2],r=e[3],o=parseInt(n,16)/255*100,i=(parseInt(s,16)-128)*1.5,c=(parseInt(r,16)-128)*1.5;return w(o,i,c)},parseHexLch:function(t){const e=t.match(/lch#([0-9a-f]{2})([0-9a-f]{2})(\d{1,3})/i);if(!e)return null;const n=e[1],s=e[2],r=e[3],o=parseInt(n,16)/255*100,i=parseInt(s,16)/255*150,c=parseInt(r)/100*360,a=C(o,i,c);return w(a.L,a.a,a.b)},generateColor:function(t,e,n,s=null,r=!0){return S(t,e,n,{enableP3:r},s)},parseColor:function(t){try{const e=t.match(/lab\(\s*([\d.]+)(%?)\s+([\d.-]+)\s+([\d.-]+)(?:\s*\/\s*([\d.%]+))?\s*\)/i);if(e){let s=parseFloat(e[1]);const r=parseFloat(e[3]),o=parseFloat(e[4]),i=e[5]?e[5].includes("%")?parseFloat(e[5])/100:parseFloat(e[5]):null,c=S(s,r,o,d,i);return{L:s,A:r,B:o,alpha:i,rgb:w(s,r,o),p3:R(s,r,o),colorString:c}}const n=t.match(/lch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(deg)?(?:\s*\/\s*([\d.%]+))?\s*\)/i);if(n){let s=parseFloat(n[1]);const r=parseFloat(n[3]);let o=parseFloat(n[4]);const i=n[6]?n[6].includes("%")?parseFloat(n[6])/100:parseFloat(n[6]):null,c=C(s,r,o),a=S(c.L,c.a,c.b,d,i);return{L:s,C:r,H:o,alpha:i,lab:c,rgb:w(c.L,c.a,c.b),p3:R(c.L,c.a,c.b),colorString:a}}return null}catch(e){return console.warn("\u65E0\u6CD5\u89E3\u6790\u989C\u8272:",t,e),null}}}},P=function(...t){if(t.length>1||t[0]&&t[0].raw)return yt(...t);const e=t[0];if(typeof e=="string"){const n=L(e,{...d,...t[1]});return n&&typeof n.then=="function",n}return typeof e=="object"&&e!==null?(d={...d,...e},P):t.length===0?B():P};function yt(t,...e){let n=t[0];for(let r=0;r<e.length;r++){const o=e[r];let i="";typeof o=="function"?i=o():Array.isArray(o)?i=o.join(" "):i=String(o??""),n+=i+t[r+1]}const s=L(n,d);return s&&typeof s.then=="function",s}return Object.assign(P,bt),Object.setPrototypeOf(P,Function.prototype),typeof window<"u"&&(B(),Object.defineProperty(window.HTMLElement.prototype,"cssVar",{get(){const t=this;return new Proxy(()=>{},{get(e,n){const s=n.startsWith("--")?n:`--${n}`;return t.style.getPropertyValue(s)},set(e,n,s){const r=n.startsWith("--")?n:`--${n}`;return t.style.setProperty(r,s),!0},apply(e,n,s){const r=s[0],o=s[1],i=r.startsWith("--")?r:`--${r}`;if(o===void 0)return t.style.getPropertyValue(i);t.style.setProperty(i,o)}})}})),P})();if(typeof define=="function"&&define.amd)define([],()=>styimat);else if(typeof module=="object"&&module.exports)module.exports=styimat;else{const d=globalThis??(typeof self<"u"&&self)??typeof window<"u"&window??global??{};d.styimat=styimat}
|
package/dist/styimat.min.mjs
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* MIT License
|
|
3
3
|
* Copyright (c) 2025 王小玗
|
|
4
|
-
*/const T=(function(){let
|
|
5
|
-
`),
|
|
6
|
-
`)}}function
|
|
7
|
-
`),
|
|
8
|
-
|
|
9
|
-
`}c=!1,
|
|
10
|
-
|
|
11
|
-
`
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
`
|
|
4
|
+
*/const T=(function(){let d={rootSelector:":root",variablePrefix:"--",preserveOriginal:!1,indentSize:4,enableNesting:!0,autoProcessStyleTags:!0,styleTagAttribute:"e",convertLabToRGB:!0,convertLchToRGB:!0,enableP3:!0,enableMath:!0,mathPrecision:6,importBaseUrl:"",importCache:!0,importTimeout:5e3,enableAlias:!0},M=null;const F=new Map,z=new Map;function D(t){const e={...d},n=t.split(`
|
|
5
|
+
`),s=[];for(let r of n){const o=r.trim();if(o.startsWith("#")){const c=o.substring(1).trim(),i=c.indexOf(" ");if(i!==-1){const a=c.substring(0,i).trim(),l=c.substring(i+1).trim(),u=K(a);u in e?l==="true"||l==="false"?e[u]=l==="true":!isNaN(l)&&l.trim()!==""?e[u]=Number(l):e[u]=l:console.warn(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${a}`)}else console.warn(`\u65E0\u6548\u7684\u914D\u7F6E\u884C: ${o}`)}else s.push(r)}return{config:e,css:s.join(`
|
|
6
|
+
`)}}function Q(t){const e=new Map,n=t.split(`
|
|
7
|
+
`),s=[];for(let r of n){const o=r.trim();if(o.startsWith("@alias")){const c=o.match(/^@alias\s+([a-zA-Z0-9_-]+)\s+(.+?)\s*;$/);if(c){const i=c[1],a=c[2];e.set(i,a),console.log(`\u6CE8\u518C\u522B\u540D: ${i} -> ${a}`);continue}}s.push(r)}return{aliases:e,css:s.join(`
|
|
8
|
+
`)}}function K(t){return t.replace(/-([a-z])/g,function(e,n){return n.toUpperCase()})}function I(){if(M!==null)return M;if(typeof window>"u"||!window.CSS)return M=!1,!1;try{M=CSS.supports("color","color(display-p3 1 0 0)")}catch(t){console.warn("P3\u652F\u6301\u68C0\u6D4B\u5931\u8D25:",t),M=!1}return M}function _(t,e=[]){let n=t.trim();if(n.endsWith(";")&&(n=n.slice(0,-1)),!n)return[];const s=[];let r="",o=0,c=!1,i="";for(let l=0;l<n.length;l++){const u=n[l];(u==='"'||u==="'")&&!c?(c=!0,i=u):u===i&&c&&(c=!1,i=""),c||(u==="("?o++:u===")"&&o--),u===";"&&!c&&o===0?r.trim()&&(s.push(r.trim()),r=""):r+=u}r.trim()&&s.push(r.trim());const a=[];for(const l of s){if(!l.trim())continue;const u=J(l);if(u===-1){console.warn(`\u65E0\u6548\u7684CSS\u58F0\u660E: "${l}"`);continue}let p=l.substring(0,u).trim(),f=l.substring(u+1).trim();f.endsWith(";")&&(f=f.slice(0,-1).trim()),e.get(p)&&(p=e.get(p)),a.push({[p]:f})}return a}function J(t){let e=!1,n="";for(let s=0;s<t.length;s++){const r=t[s];if((r==='"'||r==="'")&&!e?(e=!0,n=r):r===n&&e&&(e=!1,n=""),r===":"&&!e)return s}return-1}function B(t,e){if(!e.enableMath)return`math(${t})`;try{let n=t.replace(/\s+/g,"");const s=Z(n,e);return tt(n)?et(n,s):j(s,e.mathPrecision)}catch(n){return console.warn("math()\u8868\u8FBE\u5F0F\u89E3\u6790\u5931\u8D25:",t,n),`math(${t})`}}function Z(t,e){for(;t.includes("(")&&t.includes(")");){const n=t.lastIndexOf("("),s=t.indexOf(")",n);if(s===-1)break;const r=t.substring(n+1,s),o=Z(r,e);t=t.substring(0,n)+o+t.substring(s+1)}return k(t,e)}function k(t,e){const n=[{regex:/([\d.]+(?:[a-zA-Z%]+)?)\*([\d.]+(?:[a-zA-Z%]+)?)/,handler:nt},{regex:/([\d.]+(?:[a-zA-Z%]+)?)\/([\d.]+(?:[a-zA-Z%]+)?)/,handler:rt},{regex:/([\d.]+(?:[a-zA-Z%]+)?)\+([\d.]+(?:[a-zA-Z%]+)?)/,handler:st},{regex:/([\d.]+(?:[a-zA-Z%]+)?)-([\d.]+(?:[a-zA-Z%]+)?)/,handler:ot}];let s=t;for(const o of n){let c;for(;(c=t.match(o.regex))!==null;){const i=x(c[1]),a=x(c[2]),l=o.handler(i,a);t=t.substring(0,c.index)+l.value+t.substring(c.index+c[0].length)}}return t!==s?k(t,e):x(t).value}function x(t){const e=t.match(/^([\d.]+)([a-zA-Z%]*)$/);if(!e)throw new Error(`\u65E0\u6CD5\u89E3\u6790\u503C: ${t}`);const n=parseFloat(e[1]),s=e[2]||"";return{value:n,unit:s}}function tt(t){return/[a-zA-Z%]/.test(t)}function et(t,e){const n=t.match(/([a-zA-Z%]+)(?!.*[a-zA-Z%])/);return n?e+n[1]:t.includes("%")?e+"%":e+"px"}function nt(t,e){return t.unit===e.unit||!t.unit&&!e.unit?{value:t.value*e.value,unit:t.unit||e.unit}:{value:`${t.value}${t.unit}*${e.value}${e.unit}`,unit:""}}function rt(t,e){if(e.value===0)throw new Error("\u9664\u4EE5\u96F6");return t.unit&&!e.unit?{value:t.value/e.value,unit:t.unit}:t.unit===e.unit?{value:t.value/e.value,unit:""}:{value:`${t.value}${t.unit}/${e.value}${e.unit}`,unit:""}}function st(t,e){return t.unit===e.unit?{value:t.value+e.value,unit:t.unit}:{value:`${t.value}${t.unit}+${e.value}${e.unit}`,unit:""}}function ot(t,e){return t.unit===e.unit?{value:t.value-e.value,unit:t.unit}:{value:`${t.value}${t.unit}-${e.value}${e.unit}`,unit:""}}function j(t,e=6){const n=Math.pow(10,e),r=(Math.round(t*n)/n).toString();return r.includes(".")?r.replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,""):r}function ct(t,e){if(!e.enableMath)return t;let n=t;const s=/math\(([^)]+)\)/gi,r=c=>c.replace(s,(i,a)=>B(a,e));let o;do o=n,n=r(n);while(n!==o&&n.includes("math("));return n}function it(t,e){if(!e.convertLabToRGB&&!e.convertLchToRGB)return t;let n=t;n=at(n,e);const s=/(lab|lch)\([^)]+\)/gi,r=new Map,o=i=>i.replace(s,a=>{if(r.has(a))return r.get(a);let l=a;return a.toLowerCase().startsWith("lab(")?e.convertLabToRGB&&(l=lt(a,e)):a.toLowerCase().startsWith("lch(")&&e.convertLchToRGB&&(l=ut(a,e)),r.set(a,l),l});let c;do c=n,n=o(n);while(n!==c);return n}function at(t,e){let n=t;const s=/lab#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/gi,r=/lch#([0-9a-f]{2})([0-9a-f]{2})(\d{1,3})/gi,o=new Map;return n=n.replace(s,(c,i,a,l)=>{if(o.has(c))return o.get(c);try{const u=parseInt(i,16)/255*100,p=(parseInt(a,16)-128)*1.5,f=(parseInt(l,16)-128)*1.5,h=S(u,p,f,e);return o.set(c,h),h}catch(u){return console.warn(`\u65E0\u6CD5\u89E3\u6790lab#\u5341\u516D\u8FDB\u5236\u989C\u8272: ${c}`,u),c}}),n=n.replace(r,(c,i,a,l)=>{if(o.has(c))return o.get(c);try{const u=parseInt(i,16)/255*100,p=parseInt(a,16)/255*150,f=parseInt(l)/100*360,h=C(u,p,f),m=S(h.L,h.a,h.b,e);return o.set(c,m),m}catch(u){return console.warn(`\u65E0\u6CD5\u89E3\u6790lch#\u5341\u516D\u8FDB\u5236\u989C\u8272: ${c}`,u),c}}),n}function lt(t,e){const n=/lab\(\s*([\d.]+)(%?)\s+([\d.-]+)\s+([\d.-]+)(?:\s*\/\s*([\d.%]+))?\s*\)/i,s=t.match(n);if(!s)return t;try{let r=parseFloat(s[1]);s[2]==="%"?r=r:(r<0&&(r=0),r>100&&(r=100));const o=parseFloat(s[3]),c=parseFloat(s[4]),i=s[5]!==void 0?s[5].includes("%")?parseFloat(s[5])/100:parseFloat(s[5]):null;return S(r,o,c,e,i)}catch(r){return console.warn(`\u65E0\u6CD5\u8F6C\u6362LAB\u989C\u8272: ${t}`,r),t}}function ut(t,e){const n=/lch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(deg)?(?:\s*\/\s*([\d.%]+))?\s*\)/i,s=t.match(n);if(!s)return t;try{let r=parseFloat(s[1]);s[2]==="%"?r=r:(r<0&&(r=0),r>100&&(r=100));const o=parseFloat(s[3]);let c=parseFloat(s[4]);o<0&&console.warn(`LCH\u4E2D\u7684C\u503C\u4E0D\u80FD\u4E3A\u8D1F: ${o}`),c=(c%360+360)%360;const i=C(r,o,c),a=s[6]!==void 0?s[6].includes("%")?parseFloat(s[6])/100:parseFloat(s[6]):null;return S(i.L,i.a,i.b,e,a)}catch(r){return console.warn(`\u65E0\u6CD5\u8F6C\u6362LCH\u989C\u8272: ${t}`,r),t}}function C(t,e,n){const s=n*Math.PI/180,r=e*Math.cos(s),o=e*Math.sin(s);return{L:t,a:r,b:o}}function w(t,e,n){const s=(g,b,y)=>{const Y=(g+16)/116,W=b/500+Y,V=Y-y/200,vt=W**3>.008856?W**3:(116*W-16)/903.3,wt=g>903.3*.008856?((g+16)/116)**3:g/903.3,Ct=V**3>.008856?V**3:(116*V-16)/903.3;return[vt*.95047,wt*1,Ct*1.08883]},r=(g,b,y)=>{const v=[[3.2404542,-1.5371385,-.4985314],[-.969266,1.8760108,.041556],[.0556434,-.2040259,1.0572252]],E=v[0][0]*g+v[0][1]*b+v[0][2]*y,X=v[1][0]*g+v[1][1]*b+v[1][2]*y,q=v[2][0]*g+v[2][1]*b+v[2][2]*y;return[E,X,q]},o=g=>{const b=g<0?-1:1,y=Math.abs(g);return y<=.0031308?b*12.92*y:b*(1.055*Math.pow(y,.4166666666666667)-.055)},c=g=>Math.max(0,Math.min(255,Math.round(g*255))),[i,a,l]=s(t,e,n),[u,p,f]=r(i,a,l),h=o(u),m=o(p),$=o(f);return{r:c(h),g:c(m),b:c($)}}function P(t,e,n){const s=(i,a,l)=>{const $=(i+16)/116,g=a/500+$,b=$-l/200,y=g**3>.008856?g**3:(116*g-16)/903.3,v=i>903.3*.008856?((i+16)/116)**3:i/903.3,E=b**3>.008856?b**3:(116*b-16)/903.3;return[y*.95047,v*1,E*1.08883]},r=(i,a,l)=>{const u=[[2.493496911941425,-.9313836179191239,-.40271078445071684],[-.8294889695615747,1.7626640603183463,.023624685841943577],[.03584583024378447,-.07617238926804182,.9568845240076872]],p=u[0][0]*i+u[0][1]*a+u[0][2]*l,f=u[1][0]*i+u[1][1]*a+u[1][2]*l,h=u[2][0]*i+u[2][1]*a+u[2][2]*l;return[p,f,h]},o=i=>{const a=i<0?-1:1,l=Math.abs(i);return l<=.0031308?a*12.92*l:a*(1.055*Math.pow(l,.4166666666666667)-.055)},c=i=>Math.max(0,Math.min(255,Math.round(i*255)));try{const[i,a,l]=s(t,e,n),[u,p,f]=r(i,a,l),h=o(u),m=o(p),$=o(f);return{r:Math.max(0,Math.min(1,h)),g:Math.max(0,Math.min(1,m)),b:Math.max(0,Math.min(1,$))}}catch(i){console.warn("P3\u8F6C\u6362\u5931\u8D25:",i);const a=w(t,e,n);return{r:a.r/255,g:a.g/255,b:a.b/255}}}function S(t,e,n,s,r=null){if(!s.enableP3||!I()){const o=w(t,e,n);return r!==null?`rgba(${o.r}, ${o.g}, ${o.b}, ${r})`:`rgb(${o.r}, ${o.g}, ${o.b})`}else{const o=P(t,e,n);return r!==null?`color(display-p3 ${o.r.toFixed(4)} ${o.g.toFixed(4)} ${o.b.toFixed(4)} / ${r})`:`color(display-p3 ${o.r.toFixed(4)} ${o.g.toFixed(4)} ${o.b.toFixed(4)})`}}function A(t,e){let n=t;return e.enableMath&&(n=ct(n,e)),(e.convertLabToRGB||e.convertLchToRGB)&&(n=it(n,e)),n}function ft(t,e){const n=t.split(`
|
|
9
|
+
`),s={},r=new Map;let o="",c=null,i=!1,a=0;for(let l of n){const u=l.trim(),p=u.match(/^\$([a-zA-Z0-9_-]+)\s*:\s*(.+?);?$/);if(p){const[,f,h]=p,m=A(N(h.trim(),{...s,...c?r.get(c)||{}:{}}),e);c?(r.has(c)||r.set(c,{}),r.get(c)[f]=m):s[f]=m;continue}if(u.endsWith("{")){c=u.slice(0,-1).trim(),i=!0,o+=l+`
|
|
10
|
+
`;continue}if(u==="}"){if(i&&c&&r.has(c)){const f=r.get(c),h=" ".repeat(a);for(const[m,$]of Object.entries(f))o+=`${h} --${m}: ${$};
|
|
11
|
+
`}i=!1,c=null}o+=l+`
|
|
12
|
+
`,l.includes("{")&&(a+=e.indentSize),l.includes("}")&&(a=Math.max(0,a-e.indentSize))}return{globalVariables:s,selectorVariables:r,cssWithoutVars:o.trim()}}function pt(t,e,n){const s=t.split(`
|
|
13
|
+
`),r=[],o=[];let c=0;for(let i=0;i<s.length;i++){const a=s[i],l=a.trim();if(!l)continue;const u=a.match(/^(\s*)/)[0].length;if(l==="}"){if(r.length>0){const p=r.pop();if(r.length>0){const f=r[r.length-1];f.children||(f.children=[]),f.children.push(p)}else o.push(p)}continue}if(l.endsWith("{")){const f={selector:l.slice(0,-1).trim(),properties:[],children:[]};r.push(f);continue}if(!l.includes("{")&&!l.includes("}")&&l.includes(":")){if(r.length>0){const p=r[r.length-1];_(l,n).forEach(h=>{const m=Object.keys(h)[0],$=A(h[m],e);p.properties.push(`${m}: ${$}`)})}continue}}for(;r.length>0;){const i=r.pop();if(r.length===0)o.push(i);else{const a=r[r.length-1];a.children||(a.children=[]),a.children.push(i)}}return H(o,e,"",n)}function H(t,e,n="",s=[]){let r="";const o=n.startsWith("@");for(const c of t){const i=c.selector.startsWith("@");let a=(o?" ".repeat(e.indentSize):"")+c.selector;if(i&&(a=c.selector+` {
|
|
14
|
+
`),n&&(a.includes("&")?a=a.replace(/&/g,n):a.trim().startsWith(":")?a=n+a:a=n+(o?"":" ")+a),c.properties.length>0){r+=(i?"":a)+` {
|
|
15
|
+
`;for(const l of c.properties)_(l,s).forEach(p=>{const f=Object.keys(p)[0],h=A(p[f],e);r+=(o?" ".repeat(e.indentSize):"")+" ".repeat(e.indentSize)+`${f}: ${h};
|
|
16
|
+
`});r+=o?" ".repeat(e.indentSize)+`}
|
|
15
17
|
`:`}
|
|
16
18
|
|
|
17
|
-
`}
|
|
19
|
+
`}c.children&&c.children.length>0&&(r+=H(c.children,e,a,s)),o&&(r+=`}
|
|
18
20
|
|
|
19
|
-
`)}return
|
|
21
|
+
`)}return r.trim()+`
|
|
20
22
|
|
|
21
|
-
`}function
|
|
23
|
+
`}function N(t,e){return t.replace(/\$([a-zA-Z0-9_-]+)/g,(n,s)=>e[s]?`var(--${s})`:n)}function ht(t,e,n,s){let r=t;return r=r.replace(/(?:\$\$|\$)([a-zA-Z0-9_-]+)/g,(o,c)=>o.startsWith("$$")?`attr(${c})`:`var(--${c})`),r=A(r,s),r}function dt(t,e){if(Object.keys(t).length===0)return"";const n=Object.entries(t).map(([s,r])=>{const o=A(N(r,t),e);return" ".repeat(e.indentSize)+`--${s}: ${o};`}).join(`
|
|
22
24
|
`);return`${e.rootSelector} {
|
|
23
|
-
${
|
|
25
|
+
${n}
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
`}function
|
|
27
|
-
`);let
|
|
28
|
-
`}
|
|
29
|
-
`}return
|
|
28
|
+
`}function mt(t,e,n){let s="";const r=t.split(`
|
|
29
|
+
`);let o=null;for(let c of r){const i=c.trim();if(i.endsWith("{")&&(o=i.slice(0,-1).trim()),i==="}"&&o){if(e.has(o)){const a=e.get(o),l=c.match(/^(\s*)/)[0];for(const[u,p]of Object.entries(a))s+=" --"+u+": "+p+`;
|
|
30
|
+
`}o=null}s+=A(c,n)+`
|
|
31
|
+
`}return s.trim()}async function U(t,e){const n=/@import\s+([^;]+?)\s*;/g;return(async r=>{const o=[],c=r.replace(n,(i,a)=>{const l=gt(a,e).then(u=>U(u,e)).catch(u=>(console.warn(`\u65E0\u6CD5\u5BFC\u5165CSS\u6587\u4EF6: ${a}`,u),""));return o.push(l),`__IMPORT_PLACEHOLDER_${o.length-1}__`});if(o.length>0){const i=await Promise.all(o);let a=c;for(let l=0;l<i.length;l++)a=a.replace(`__IMPORT_PLACEHOLDER_${l}__`,i[l]);return a}return c})(t)}async function gt(t,e){if(e.importCache&&F.has(t))return F.get(t);const n=e.importBaseUrl?new URL(t,e.importBaseUrl).href:t;let s;if(typeof process<"u"&&process.versions&&process.versions.node&&typeof require<"u")try{const o=require("fs"),c=require("path");let i=n;n.startsWith(".")&&(i=c.join(process.cwd(),n)),s=o.readFileSync(i,"utf-8")}catch(o){throw new Error(`Node.js\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25: ${n} - ${o.message}`)}else try{const o=new AbortController,c=setTimeout(()=>o.abort(),e.importTimeout),i=await fetch(n,{signal:o.signal,headers:{Accept:"text/css"}});if(clearTimeout(c),!i.ok)throw new Error(`HTTP\u9519\u8BEF: ${i.status} ${i.statusText}`);s=await i.text()}catch(o){throw o.name==="AbortError"?new Error(`\u5BFC\u5165\u8D85\u65F6: ${n}`):new Error(`\u65E0\u6CD5\u83B7\u53D6CSS: ${n} - ${o.message}`)}return e.importCache&&F.set(t,s),s}function L(t,e={}){const n=(o,c)=>{const{config:i,css:a}=D(o),l={...d,...e,...i};let u=a,p=new Map;if(l.enableAlias){const{aliases:y,css:v}=Q(u);p=y,u=v}const{globalVariables:f,selectorVariables:h,cssWithoutVars:m}=ft(u,l);let $=m.trim();if(l.enableNesting&&m.includes("{"))try{$=pt(m,l,p)}catch(y){console.warn("\u5D4C\u5957\u89E3\u6790\u5931\u8D25\uFF0C\u4F7F\u7528\u539F\u59CBCSS:",y)}const g=dt(f,l);let b=$;return h.size>0&&(b=mt($,h,l)),b=ht(b,f,h,l),g+b},s=t&&/@import\s+([^;]+?)\s*;/g.test(t),r={...d,...e};return s?(async()=>{try{const o=await U(t,r);return n(o,r)}catch(o){return console.error("@import\u5904\u7406\u5931\u8D25:",o),n(cleanedCSS,r)}})():n(t,r)}function G(t={}){const e={...d,...t},n=document.querySelectorAll(`style[${e.styleTagAttribute||"e"}]`);return n.forEach(s=>{let r=s.textContent;(async()=>{try{s.getAttribute("src")&&(r="@import "+s.getAttribute("src")+";");const c=await L(r,e),i=document.createElement("style");i.textContent=c,s.parentNode.insertBefore(i,s.nextSibling),e.preserveOriginal?s.style.display="none":s.remove()}catch(c){console.error("\u5904\u7406style\u6807\u7B7E\u5931\u8D25:",c)}})()}),n.length}function bt(t={}){d={...d,...t}}function O(t,e={}){const n={...d,...e};if(t){if(/@import\s+([^;]+?)\s*;/g.test(t))return(async()=>{try{const r=await L(t,n),o=document.createElement("style");return o.textContent=r,document.head.appendChild(o),o}catch(r){return console.error("\u5E94\u7528CSS\u5931\u8D25:",r),null}})();{const r=L(t,n),o=document.createElement("style");return o.textContent=r,document.head.appendChild(o),o}}else document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{G(n)}):G(n)}const yt={convert:L,apply:O,config:bt,supportsP3:I(),detectP3Support:I,imports:{clearCache:function(){F.clear()},setBaseUrl:function(t){d.importBaseUrl=t},setCacheEnabled:function(t){d.importCache=t},setTimeout:function(t){d.importTimeout=t}},aliases:{add:function(t,e){z.set(t,e)},remove:function(t){z.delete(t)},getAll:function(){return Array.from(z.entries())},clear:function(){z.clear()}},math:{evaluate:function(t){return B(t,d)},parseUnit:x,round:j,test:function(t,e={}){const n={...d,...e};try{const s=B(t,n);return{success:!0,expression:t,result:s,parsed:x(s.replace(/^calc\(|\)$/g,""))}}catch(s){return{success:!1,expression:t,error:s.message}}}},colorUtils:{labToRGB:w,lchToLab:C,lchToRGB:function(t,e,n){const s=C(t,e,n);return w(s.L,s.a,s.b)},labToP3:P,lchToP3:function(t,e,n){const s=C(t,e,n);return P(s.L,s.a,s.b)},parseHexLab:function(t){const e=t.match(/lab#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i);if(!e)return null;const n=e[1],s=e[2],r=e[3],o=parseInt(n,16)/255*100,c=(parseInt(s,16)-128)*1.5,i=(parseInt(r,16)-128)*1.5;return w(o,c,i)},parseHexLch:function(t){const e=t.match(/lch#([0-9a-f]{2})([0-9a-f]{2})(\d{1,3})/i);if(!e)return null;const n=e[1],s=e[2],r=e[3],o=parseInt(n,16)/255*100,c=parseInt(s,16)/255*150,i=parseInt(r)/100*360,a=C(o,c,i);return w(a.L,a.a,a.b)},generateColor:function(t,e,n,s=null,r=!0){return S(t,e,n,{enableP3:r},s)},parseColor:function(t){try{const e=t.match(/lab\(\s*([\d.]+)(%?)\s+([\d.-]+)\s+([\d.-]+)(?:\s*\/\s*([\d.%]+))?\s*\)/i);if(e){let s=parseFloat(e[1]);const r=parseFloat(e[3]),o=parseFloat(e[4]),c=e[5]?e[5].includes("%")?parseFloat(e[5])/100:parseFloat(e[5]):null,i=S(s,r,o,d,c);return{L:s,A:r,B:o,alpha:c,rgb:w(s,r,o),p3:P(s,r,o),colorString:i}}const n=t.match(/lch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(deg)?(?:\s*\/\s*([\d.%]+))?\s*\)/i);if(n){let s=parseFloat(n[1]);const r=parseFloat(n[3]);let o=parseFloat(n[4]);const c=n[6]?n[6].includes("%")?parseFloat(n[6])/100:parseFloat(n[6]):null,i=C(s,r,o),a=S(i.L,i.a,i.b,d,c);return{L:s,C:r,H:o,alpha:c,lab:i,rgb:w(i.L,i.a,i.b),p3:P(i.L,i.a,i.b),colorString:a}}return null}catch(e){return console.warn("\u65E0\u6CD5\u89E3\u6790\u989C\u8272:",t,e),null}}}},R=function(...t){if(t.length>1||t[0]&&t[0].raw)return $t(...t);const e=t[0];if(typeof e=="string"){const n=L(e,{...d,...t[1]});return n&&typeof n.then=="function",n}return typeof e=="object"&&e!==null?(d={...d,...e},R):t.length===0?O():R};function $t(t,...e){let n=t[0];for(let r=0;r<e.length;r++){const o=e[r];let c="";typeof o=="function"?c=o():Array.isArray(o)?c=o.join(" "):c=String(o??""),n+=c+t[r+1]}const s=L(n,d);return s&&typeof s.then=="function",s}return Object.assign(R,yt),Object.setPrototypeOf(R,Function.prototype),typeof window<"u"&&(O(),Object.defineProperty(window.HTMLElement.prototype,"cssVar",{get(){const t=this;return new Proxy(()=>{},{get(e,n){const s=n.startsWith("--")?n:`--${n}`;return t.style.getPropertyValue(s)},set(e,n,s){const r=n.startsWith("--")?n:`--${n}`;return t.style.setProperty(r,s),!0},apply(e,n,s){const r=s[0],o=s[1],c=r.startsWith("--")?r:`--${r}`;if(o===void 0)return t.style.getPropertyValue(c);t.style.setProperty(c,o)}})}})),R})();if(typeof define=="function"&&define.amd)define([],()=>T);else if(typeof module=="object"&&module.exports)module.exports=T;else{const d=globalThis??(typeof self<"u"&&self)??typeof window<"u"&window??global??{};d.styimat=T}export default T;export const{convert,apply,config,supportsP3,detectP3Support,imports,aliases,math,colorUtils}=T;
|
package/dist/styimat.mjs
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* 增强 math() 函数,支持复杂数学计算
|
|
12
12
|
* 支持配置头
|
|
13
13
|
* 支持 @import 语法
|
|
14
|
+
* 支持 @alias 语法
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
17
|
const styimat = (function() {
|
|
@@ -31,6 +32,7 @@ const styimat = (function() {
|
|
|
31
32
|
importBaseUrl: '', // @import 的基础URL
|
|
32
33
|
importCache: true, // 缓存导入的文件
|
|
33
34
|
importTimeout: 5000, // 导入超时时间(毫秒)
|
|
35
|
+
enableAlias: true, // 启用别名功能
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
// 全局P3支持检测结果
|
|
@@ -38,6 +40,9 @@ const styimat = (function() {
|
|
|
38
40
|
|
|
39
41
|
// 导入文件缓存
|
|
40
42
|
const importCache = new Map();
|
|
43
|
+
|
|
44
|
+
// 别名映射表
|
|
45
|
+
const aliasMap = new Map();
|
|
41
46
|
|
|
42
47
|
/**
|
|
43
48
|
* 解析配置头
|
|
@@ -92,6 +97,42 @@ const styimat = (function() {
|
|
|
92
97
|
};
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
/**
|
|
101
|
+
* 解析 @alias 语句
|
|
102
|
+
* @param {string} cssText - CSS文本
|
|
103
|
+
* @returns {Object} {aliases: 别名映射, css: 清理后的CSS}
|
|
104
|
+
*/
|
|
105
|
+
function parseAliasStatements(cssText) {
|
|
106
|
+
const aliases = new Map();
|
|
107
|
+
const lines = cssText.split('\n');
|
|
108
|
+
const cleanLines = [];
|
|
109
|
+
|
|
110
|
+
for (let line of lines) {
|
|
111
|
+
const trimmed = line.trim();
|
|
112
|
+
|
|
113
|
+
// 检查是否是 @alias 语句
|
|
114
|
+
if (trimmed.startsWith('@alias')) {
|
|
115
|
+
const aliasMatch = trimmed.match(/^@alias\s+([a-zA-Z0-9_-]+)\s+(.+?)\s*;$/);
|
|
116
|
+
if (aliasMatch) {
|
|
117
|
+
const aliasName = aliasMatch[1];
|
|
118
|
+
const originalProperty = aliasMatch[2];
|
|
119
|
+
|
|
120
|
+
// 存储别名映射
|
|
121
|
+
aliases.set(aliasName, originalProperty);
|
|
122
|
+
console.log(`注册别名: ${aliasName} -> ${originalProperty}`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
cleanLines.push(line);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
aliases,
|
|
132
|
+
css: cleanLines.join('\n')
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
95
136
|
/**
|
|
96
137
|
* 将连字符分隔的字符串转换为驼峰命名
|
|
97
138
|
* @param {string} str - 输入字符串
|
|
@@ -131,7 +172,7 @@ const styimat = (function() {
|
|
|
131
172
|
* @param {string} cssString - 要解析的CSS字符串
|
|
132
173
|
* @returns {Array} 包含属性名值对象的数组
|
|
133
174
|
*/
|
|
134
|
-
function parseSingleLineCSS(cssString) {
|
|
175
|
+
function parseSingleLineCSS(cssString, aliases=[]) {
|
|
135
176
|
// 移除首尾空白字符
|
|
136
177
|
let str = cssString.trim();
|
|
137
178
|
|
|
@@ -205,7 +246,7 @@ const styimat = (function() {
|
|
|
205
246
|
}
|
|
206
247
|
|
|
207
248
|
// 分割属性名和值
|
|
208
|
-
|
|
249
|
+
let property = declaration.substring(0, colonIndex).trim();
|
|
209
250
|
let value = declaration.substring(colonIndex + 1).trim();
|
|
210
251
|
|
|
211
252
|
// 如果值以分号结尾,移除它(理论上不应该有,但处理一下)
|
|
@@ -213,6 +254,10 @@ const styimat = (function() {
|
|
|
213
254
|
value = value.slice(0, -1).trim();
|
|
214
255
|
}
|
|
215
256
|
|
|
257
|
+
if (aliases.get(property)) {
|
|
258
|
+
property = aliases.get(property);
|
|
259
|
+
}
|
|
260
|
+
|
|
216
261
|
// 添加到结果数组
|
|
217
262
|
result.push({ [property]: value });
|
|
218
263
|
}
|
|
@@ -1035,7 +1080,8 @@ const styimat = (function() {
|
|
|
1035
1080
|
}
|
|
1036
1081
|
|
|
1037
1082
|
// 修复的嵌套解析函数
|
|
1038
|
-
function parseNestedRules(cssText, config) {
|
|
1083
|
+
function parseNestedRules(cssText, config, aliases) {
|
|
1084
|
+
|
|
1039
1085
|
const lines = cssText.split('\n');
|
|
1040
1086
|
const stack = []; // 存储规则信息:{selector, properties, children}
|
|
1041
1087
|
const rootRules = [];
|
|
@@ -1089,7 +1135,7 @@ const styimat = (function() {
|
|
|
1089
1135
|
if (stack.length > 0) {
|
|
1090
1136
|
const currentRule = stack[stack.length - 1];
|
|
1091
1137
|
// 处理属性值中的math()函数和颜色转换
|
|
1092
|
-
const parsed = parseSingleLineCSS(trimmed);
|
|
1138
|
+
const parsed = parseSingleLineCSS(trimmed, aliases);
|
|
1093
1139
|
parsed.forEach(obj => {
|
|
1094
1140
|
const key = Object.keys(obj)[0];
|
|
1095
1141
|
const value = processCSSValue(obj[key], config);
|
|
@@ -1113,11 +1159,11 @@ const styimat = (function() {
|
|
|
1113
1159
|
}
|
|
1114
1160
|
|
|
1115
1161
|
// 将规则树转换为CSS字符串
|
|
1116
|
-
return convertRulesToCSS(rootRules, config);
|
|
1162
|
+
return convertRulesToCSS(rootRules, config, '', aliases);
|
|
1117
1163
|
}
|
|
1118
1164
|
|
|
1119
1165
|
// 将规则树转换为CSS字符串
|
|
1120
|
-
function convertRulesToCSS(rules, config, parentSelector = '') {
|
|
1166
|
+
function convertRulesToCSS(rules, config, parentSelector = '', aliases=[]) {
|
|
1121
1167
|
let result = '';
|
|
1122
1168
|
const isParentAt = parentSelector.startsWith("@");
|
|
1123
1169
|
|
|
@@ -1146,7 +1192,7 @@ const styimat = (function() {
|
|
|
1146
1192
|
result += (isAt ? "" : fullSelector) + ' {\n';
|
|
1147
1193
|
for (const prop of rule.properties) {
|
|
1148
1194
|
// 再次处理属性值(确保math()函数和颜色被转换)
|
|
1149
|
-
const parsed = parseSingleLineCSS(prop);
|
|
1195
|
+
const parsed = parseSingleLineCSS(prop, aliases);
|
|
1150
1196
|
parsed.forEach(obj => {
|
|
1151
1197
|
const key = Object.keys(obj)[0];
|
|
1152
1198
|
const value = processCSSValue(obj[key], config);
|
|
@@ -1158,7 +1204,7 @@ const styimat = (function() {
|
|
|
1158
1204
|
|
|
1159
1205
|
// 递归处理子规则
|
|
1160
1206
|
if (rule.children && rule.children.length > 0) {
|
|
1161
|
-
result += convertRulesToCSS(rule.children, config, fullSelector);
|
|
1207
|
+
result += convertRulesToCSS(rule.children, config, fullSelector, aliases);
|
|
1162
1208
|
}
|
|
1163
1209
|
|
|
1164
1210
|
if (isParentAt){
|
|
@@ -1387,15 +1433,24 @@ const styimat = (function() {
|
|
|
1387
1433
|
const { config: headerConfig, css: cleanedCSS } = parseConfigHeader(cssText);
|
|
1388
1434
|
const finalConfig = { ...defaultConfig, ...customConfig,...headerConfig };
|
|
1389
1435
|
|
|
1436
|
+
// 0. 解析 @alias 语句(如果有)
|
|
1437
|
+
let cssWithAliases = cleanedCSS;
|
|
1438
|
+
let aliases = new Map();
|
|
1439
|
+
if (finalConfig.enableAlias) {
|
|
1440
|
+
const { aliases: parsedAliases, css: cssWithoutAliases } = parseAliasStatements(cssWithAliases);
|
|
1441
|
+
aliases = parsedAliases;
|
|
1442
|
+
cssWithAliases = cssWithoutAliases;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1390
1445
|
// 1. 提取变量定义(区分全局和选择器局部)
|
|
1391
1446
|
const { globalVariables, selectorVariables, cssWithoutVars } =
|
|
1392
|
-
extractVariablesAndCSS(
|
|
1447
|
+
extractVariablesAndCSS(cssWithAliases, finalConfig);
|
|
1393
1448
|
|
|
1394
1449
|
// 2. 解析嵌套规则(如果启用)
|
|
1395
1450
|
let processedCSS = cssWithoutVars.trim();
|
|
1396
1451
|
if (finalConfig.enableNesting && cssWithoutVars.includes('{')) {
|
|
1397
1452
|
try {
|
|
1398
|
-
processedCSS = parseNestedRules(cssWithoutVars, finalConfig);
|
|
1453
|
+
processedCSS = parseNestedRules(cssWithoutVars, finalConfig, aliases);
|
|
1399
1454
|
} catch (error) {
|
|
1400
1455
|
console.warn('嵌套解析失败,使用原始CSS:', error);
|
|
1401
1456
|
}
|
|
@@ -1573,6 +1628,41 @@ const styimat = (function() {
|
|
|
1573
1628
|
}
|
|
1574
1629
|
},
|
|
1575
1630
|
|
|
1631
|
+
// 别名相关方法
|
|
1632
|
+
aliases: {
|
|
1633
|
+
/**
|
|
1634
|
+
* 注册别名
|
|
1635
|
+
* @param {string} alias - 别名
|
|
1636
|
+
* @param {string} property - 原始属性
|
|
1637
|
+
*/
|
|
1638
|
+
add: function(alias, property) {
|
|
1639
|
+
aliasMap.set(alias, property);
|
|
1640
|
+
},
|
|
1641
|
+
|
|
1642
|
+
/**
|
|
1643
|
+
* 移除别名
|
|
1644
|
+
* @param {string} alias - 别名
|
|
1645
|
+
*/
|
|
1646
|
+
remove: function(alias) {
|
|
1647
|
+
aliasMap.delete(alias);
|
|
1648
|
+
},
|
|
1649
|
+
|
|
1650
|
+
/**
|
|
1651
|
+
* 获取所有别名
|
|
1652
|
+
* @returns {Array} 别名数组
|
|
1653
|
+
*/
|
|
1654
|
+
getAll: function() {
|
|
1655
|
+
return Array.from(aliasMap.entries());
|
|
1656
|
+
},
|
|
1657
|
+
|
|
1658
|
+
/**
|
|
1659
|
+
* 清除所有别名
|
|
1660
|
+
*/
|
|
1661
|
+
clear: function() {
|
|
1662
|
+
aliasMap.clear();
|
|
1663
|
+
}
|
|
1664
|
+
},
|
|
1665
|
+
|
|
1576
1666
|
// 数学计算工具方法
|
|
1577
1667
|
math: {
|
|
1578
1668
|
/**
|
|
@@ -1854,4 +1944,4 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1854
1944
|
}
|
|
1855
1945
|
|
|
1856
1946
|
export default styimat;
|
|
1857
|
-
export const { convert, apply, config, supportsP3, detectP3Support, imports, math, colorUtils } = styimat;
|
|
1947
|
+
export const { convert, apply, config, supportsP3, detectP3Support, imports, aliases, math, colorUtils } = styimat;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "styimat",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "一个高效的CSS变量预处理库,支持Lab/LCH颜色空间自动转换、嵌套选择器和Display P3广色域,让现代CSS开发更简洁强大。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -25,12 +25,14 @@
|
|
|
25
25
|
"default": "./dist/styimat.min.js"
|
|
26
26
|
},
|
|
27
27
|
"./cli": {
|
|
28
|
-
"import": "./bin/
|
|
29
|
-
"require": "./bin/
|
|
30
|
-
"default": "./bin/
|
|
28
|
+
"import": "./bin/cli.js",
|
|
29
|
+
"require": "./bin/cli.js",
|
|
30
|
+
"default": "./bin/cli.js"
|
|
31
31
|
},
|
|
32
32
|
"./umd": "./dist/styimat.min.js",
|
|
33
|
-
"./esm": "./dist/styimat.min.mjs"
|
|
33
|
+
"./esm": "./dist/styimat.min.mjs",
|
|
34
|
+
"./dist/*": "./dist/*",
|
|
35
|
+
"./bin/*": "./bin/*"
|
|
34
36
|
},
|
|
35
37
|
"browser": "dist/styimat.min.js",
|
|
36
38
|
"unpkg": "dist/styimat.min.js",
|
|
@@ -41,10 +43,10 @@
|
|
|
41
43
|
"dist/styimat.min.mjs",
|
|
42
44
|
"LICENSE",
|
|
43
45
|
"README.md",
|
|
44
|
-
"bin/
|
|
46
|
+
"bin/cli.js"
|
|
45
47
|
],
|
|
46
48
|
"bin": {
|
|
47
|
-
"styimat": "bin/
|
|
49
|
+
"styimat": "bin/cli.js"
|
|
48
50
|
},
|
|
49
51
|
"repository": {
|
|
50
52
|
"type": "git",
|