styimat 1.4.0 → 1.6.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.
Files changed (4) hide show
  1. package/README.md +263 -24
  2. package/package.json +1 -1
  3. package/styimat.js +1451 -1380
  4. package/styimat.min.js +154 -126
package/styimat.min.js CHANGED
@@ -1,3 +1,7 @@
1
+ /*!
2
+ * MIT License
3
+ * Copyright (c) 2025 王小玗
4
+ */
1
5
  /**
2
6
  * CSS 变量预处理库 - 增强版
3
7
  * 支持 CSS 变量预处理、嵌套选择器和嵌套变量
@@ -19,15 +23,15 @@ mathPrecision:6};
19
23
  // 全局P3支持检测结果
20
24
  let p3Supported=null;
21
25
  /**
22
- * 检测浏览器是否支持 Display P3
23
- * @returns {boolean} 是否支持P3
24
- */function detectP3Support(){if(p3Supported!==null)return p3Supported;if(typeof window==="undefined"||!window.CSS){p3Supported=false;return false}try{p3Supported=CSS.supports("color","color(display-p3 1 0 0)")}catch(error){console.warn("P3支持检测失败:",error);p3Supported=false}return p3Supported}
26
+ * 检测浏览器是否支持 Display P3
27
+ * @returns {boolean} 是否支持P3
28
+ */function detectP3Support(){if(p3Supported!==null)return p3Supported;if(typeof window==="undefined"||!window.CSS){p3Supported=false;return false}try{p3Supported=CSS.supports("color","color(display-p3 1 0 0)")}catch(error){console.warn("P3支持检测失败:",error);p3Supported=false}return p3Supported}
25
29
  /**
26
- * 解析一行CSS(可能多个语句在同一行,可能最后一个语句没有分号)
27
- * 返回格式:[{属性名:值}, {属性名:值}, ...]
28
- * @param {string} cssString - 要解析的CSS字符串
29
- * @returns {Array} 包含属性名值对象的数组
30
- */function parseSingleLineCSS(cssString){
30
+ * 解析一行CSS(可能多个语句在同一行,可能最后一个语句没有分号)
31
+ * 返回格式:[{属性名:值}, {属性名:值}, ...]
32
+ * @param {string} cssString - 要解析的CSS字符串
33
+ * @returns {Array} 包含属性名值对象的数组
34
+ */function parseSingleLineCSS(cssString){
31
35
  // 移除首尾空白字符
32
36
  let str=cssString.trim();
33
37
  // 如果以分号结尾,移除最后一个分号
@@ -60,20 +64,20 @@ if(value.endsWith(";")){value=value.slice(0,-1).trim()}
60
64
  // 添加到结果数组
61
65
  result.push({[property]:value})}return result}
62
66
  /**
63
- * 查找不在引号内的第一个冒号位置
64
- * @param {string} str
65
- * @returns {number}
66
- */function findFirstColonOutsideQuotes(str){let inQuotes=false;let quoteChar="";for(let i=0;i<str.length;i++){const char=str[i];
67
+ * 查找不在引号内的第一个冒号位置
68
+ * @param {string} str
69
+ * @returns {number}
70
+ */function findFirstColonOutsideQuotes(str){let inQuotes=false;let quoteChar="";for(let i=0;i<str.length;i++){const char=str[i];
67
71
  // 处理引号
68
72
  if((char==='"'||char==="'")&&!inQuotes){inQuotes=true;quoteChar=char}else if(char===quoteChar&&inQuotes){inQuotes=false;quoteChar=""}
69
73
  // 如果找到冒号且不在引号内,返回位置
70
74
  if(char===":"&&!inQuotes){return i}}return-1}
71
75
  /**
72
- * 增强的数学表达式解析和计算
73
- * @param {string} expression - 数学表达式
74
- * @param {Object} config - 配置对象
75
- * @returns {string} 计算结果
76
- */function evaluateMathExpression(expression,config){
76
+ * 增强的数学表达式解析和计算
77
+ * @param {string} expression - 数学表达式
78
+ * @param {Object} config - 配置对象
79
+ * @returns {string} 计算结果
80
+ */function evaluateMathExpression(expression,config){
77
81
  // 如果禁用math()增强,则返回原始表达式
78
82
  if(!config.enableMath){return`math(${expression})`}try{
79
83
  // 清理表达式:移除空白字符
@@ -87,21 +91,21 @@ return processUnitExpression(cleanExpr,result)}else{
87
91
  // 纯数字表达式,直接计算结果
88
92
  return roundNumber(result,config.mathPrecision)}}catch(error){console.warn("math()表达式解析失败:",expression,error);return`math(${expression})`}}
89
93
  /**
90
- * 解析数学表达式
91
- * @param {string} expr - 清理后的表达式
92
- * @param {Object} config - 配置对象
93
- * @returns {number} 计算结果
94
- */function parseMathExpression(expr,config){
94
+ * 解析数学表达式
95
+ * @param {string} expr - 清理后的表达式
96
+ * @param {Object} config - 配置对象
97
+ * @returns {number} 计算结果
98
+ */function parseMathExpression(expr,config){
95
99
  // 处理括号
96
100
  while(expr.includes("(")&&expr.includes(")")){const start=expr.lastIndexOf("(");const end=expr.indexOf(")",start);if(end===-1)break;const inner=expr.substring(start+1,end);const innerResult=parseMathExpression(inner,config);expr=expr.substring(0,start)+innerResult+expr.substring(end+1)}
97
101
  // 现在expr应该没有括号了
98
102
  return evaluateSimpleExpression(expr,config)}
99
103
  /**
100
- * 评估简单表达式(无括号)
101
- * @param {string} expr - 简单表达式
102
- * @param {Object} config - 配置对象
103
- * @returns {number} 计算结果
104
- */function evaluateSimpleExpression(expr,config){
104
+ * 评估简单表达式(无括号)
105
+ * @param {string} expr - 简单表达式
106
+ * @param {Object} config - 配置对象
107
+ * @returns {number} 计算结果
108
+ */function evaluateSimpleExpression(expr,config){
105
109
  // 处理操作符优先级:乘除优先于加减
106
110
  const operators=[{regex:/([\d.]+(?:[a-zA-Z%]+)?)\*([\d.]+(?:[a-zA-Z%]+)?)/,handler:multiply},{regex:/([\d.]+(?:[a-zA-Z%]+)?)\/([\d.]+(?:[a-zA-Z%]+)?)/,handler:divide},{regex:/([\d.]+(?:[a-zA-Z%]+)?)\+([\d.]+(?:[a-zA-Z%]+)?)/,handler:add},{regex:/([\d.]+(?:[a-zA-Z%]+)?)-([\d.]+(?:[a-zA-Z%]+)?)/,handler:subtract}];let lastExpr=expr;
107
111
  // 按照优先级处理操作符
@@ -113,23 +117,23 @@ if(expr!==lastExpr){return evaluateSimpleExpression(expr,config)}
113
117
  // 解析最终结果
114
118
  const parsed=parseValueWithUnit(expr);return parsed.value}
115
119
  /**
116
- * 解析带单位的数值
117
- * @param {string} str - 字符串值
118
- * @returns {Object} {value: number, unit: string}
119
- */function parseValueWithUnit(str){
120
+ * 解析带单位的数值
121
+ * @param {string} str - 字符串值
122
+ * @returns {Object} {value: number, unit: string}
123
+ */function parseValueWithUnit(str){
120
124
  // 匹配数值和单位
121
125
  const match=str.match(/^([\d.]+)([a-zA-Z%]*)$/);if(!match){throw new Error(`无法解析值: ${str}`)}const value=parseFloat(match[1]);const unit=match[2]||"";return{value:value,unit:unit}}
122
126
  /**
123
- * 检查表达式是否包含单位
124
- * @param {string} expr - 表达式
125
- * @returns {boolean} 是否包含单位
126
- */function hasUnits(expr){return/[a-zA-Z%]/.test(expr)}
127
+ * 检查表达式是否包含单位
128
+ * @param {string} expr - 表达式
129
+ * @returns {boolean} 是否包含单位
130
+ */function hasUnits(expr){return/[a-zA-Z%]/.test(expr)}
127
131
  /**
128
- * 处理带单位的表达式
129
- * @param {string} originalExpr - 原始表达式
130
- * @param {number} result - 计算结果
131
- * @returns {string} 处理后的表达式
132
- */function processUnitExpression(originalExpr,result){
132
+ * 处理带单位的表达式
133
+ * @param {string} originalExpr - 原始表达式
134
+ * @param {number} result - 计算结果
135
+ * @returns {string} 处理后的表达式
136
+ */function processUnitExpression(originalExpr,result){
133
137
  // 提取原始表达式中的单位
134
138
  const unitMatch=originalExpr.match(/([a-zA-Z%]+)(?!.*[a-zA-Z%])/);if(unitMatch){return result+unitMatch[1]}
135
139
  // 如果没有明确单位,检查是否为百分比
@@ -151,19 +155,19 @@ return{value:`${a.value}${a.unit}+${b.value}${b.unit}`,unit:""}}function subtrac
151
155
  // 单位不匹配,返回原始表达式
152
156
  return{value:`${a.value}${a.unit}-${b.value}${b.unit}`,unit:""}}
153
157
  /**
154
- * 四舍五入到指定精度
155
- * @param {number} num - 要四舍五入的数字
156
- * @param {number} precision - 精度
157
- * @returns {string} 四舍五入后的数字字符串
158
- */function roundNumber(num,precision=6){const factor=Math.pow(10,precision);const rounded=Math.round(num*factor)/factor;
158
+ * 四舍五入到指定精度
159
+ * @param {number} num - 要四舍五入的数字
160
+ * @param {number} precision - 精度
161
+ * @returns {string} 四舍五入后的数字字符串
162
+ */function roundNumber(num,precision=6){const factor=Math.pow(10,precision);const rounded=Math.round(num*factor)/factor;
159
163
  // 移除不必要的尾随零
160
164
  const str=rounded.toString();if(str.includes(".")){return str.replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,"")}return str}
161
165
  /**
162
- * 处理所有的math()函数
163
- * @param {string} cssValue - CSS属性值
164
- * @param {Object} config - 配置对象
165
- * @returns {string} 转换后的CSS值
166
- */function processMathFunctions(cssValue,config){if(!config.enableMath){return cssValue}let result=cssValue;
166
+ * 处理所有的math()函数
167
+ * @param {string} cssValue - CSS属性值
168
+ * @param {Object} config - 配置对象
169
+ * @returns {string} 转换后的CSS值
170
+ */function processMathFunctions(cssValue,config){if(!config.enableMath){return cssValue}let result=cssValue;
167
171
  // 匹配math()函数
168
172
  const mathRegex=/math\(([^)]+)\)/gi;
169
173
  // 递归处理嵌套的math()函数
@@ -171,11 +175,11 @@ const processMath=str=>str.replace(mathRegex,(match,expression)=>evaluateMathExp
171
175
  // 递归处理,直到没有更多math()函数
172
176
  let lastResult;do{lastResult=result;result=processMath(result)}while(result!==lastResult&&result.includes("math("));return result}
173
177
  /**
174
- * 解析并转换所有的 Lab 和 LCH 颜色(全局一次性处理)
175
- * @param {string} cssValue - CSS属性值
176
- * @param {Object} config - 配置对象
177
- * @returns {string} 转换后的CSS值
178
- */function convertAllLabLchColors(cssValue,config){if(!config.convertLabToRGB&&!config.convertLchToRGB){return cssValue}let result=cssValue;
178
+ * 解析并转换所有的 Lab 和 LCH 颜色(全局一次性处理)
179
+ * @param {string} cssValue - CSS属性值
180
+ * @param {Object} config - 配置对象
181
+ * @returns {string} 转换后的CSS值
182
+ */function convertAllLabLchColors(cssValue,config){if(!config.convertLabToRGB&&!config.convertLchToRGB){return cssValue}let result=cssValue;
179
183
  // 首先处理特殊的十六进制格式
180
184
  result=parseHexColorFormats(result,config);
181
185
  // 一次性处理所有的 lab() 和 lch() 函数
@@ -193,11 +197,11 @@ processedColors.set(match,converted);return converted});
193
197
  // 递归处理,直到没有更多颜色函数
194
198
  let lastResult;do{lastResult=result;result=processColorFunctions(result)}while(result!==lastResult);return result}
195
199
  /**
196
- * 解析十六进制颜色格式:lab#L16A16B16 或 lch#L16C16H
197
- * @param {string} value - 颜色值
198
- * @param {Object} config - 配置对象
199
- * @returns {string} 转换后的CSS颜色
200
- */function parseHexColorFormats(value,config){let result=value;
200
+ * 解析十六进制颜色格式:lab#L16A16B16 或 lch#L16C16H
201
+ * @param {string} value - 颜色值
202
+ * @param {Object} config - 配置对象
203
+ * @returns {string} 转换后的CSS颜色
204
+ */function parseHexColorFormats(value,config){let result=value;
201
205
  // 使用正则表达式一次性匹配所有 lab# 和 lch# 格式
202
206
  const hexLabRegex=/lab#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/gi;const hexLchRegex=/lch#([0-9a-f]{2})([0-9a-f]{2})(\d{1,3})/gi;
203
207
  // 存储处理过的十六进制颜色,避免重复处理
@@ -217,11 +221,11 @@ const C=parseInt(C_hex,16)/255*150;// 0-150
217
221
  const H=parseInt(H_dec)/100*360;// 0-360
218
222
  const lab=lchToLab(L,C,H);const converted=generateColorString(lab.L,lab.a,lab.b,config);processedHexColors.set(match,converted);return converted}catch(error){console.warn(`无法解析lch#十六进制颜色: ${match}`,error);return match}});return result}
219
223
  /**
220
- * 转换单个 lab() 颜色函数
221
- * @param {string} labString - lab() 颜色字符串
222
- * @param {Object} config - 配置对象
223
- * @returns {string} 转换后的颜色字符串
224
- */function convertSingleLabColor(labString,config){
224
+ * 转换单个 lab() 颜色函数
225
+ * @param {string} labString - lab() 颜色字符串
226
+ * @param {Object} config - 配置对象
227
+ * @returns {string} 转换后的颜色字符串
228
+ */function convertSingleLabColor(labString,config){
225
229
  // 使用更精确的正则匹配 lab() 函数
226
230
  const labRegex=/lab\(\s*([\d.]+)(%?)\s+([\d.-]+)\s+([\d.-]+)(?:\s*\/\s*([\d.%]+))?\s*\)/i;const match=labString.match(labRegex);if(!match){return labString}try{
227
231
  // 转换为数字
@@ -234,11 +238,11 @@ if(L<0)L=0;if(L>100)L=100}const A=parseFloat(match[3]);const B=parseFloat(match[
234
238
  // 处理 alpha 通道(如果有)
235
239
  const alphaValue=match[5]!==undefined?match[5].includes("%")?parseFloat(match[5])/100:parseFloat(match[5]):null;return generateColorString(L,A,B,config,alphaValue)}catch(error){console.warn(`无法转换LAB颜色: ${labString}`,error);return labString}}
236
240
  /**
237
- * 转换单个 lch() 颜色函数
238
- * @param {string} lchString - lch() 颜色字符串
239
- * @param {Object} config - 配置对象
240
- * @returns {string} 转换后的颜色字符串
241
- */function convertSingleLchColor(lchString,config){
241
+ * 转换单个 lch() 颜色函数
242
+ * @param {string} lchString - lch() 颜色字符串
243
+ * @param {Object} config - 配置对象
244
+ * @returns {string} 转换后的颜色字符串
245
+ */function convertSingleLchColor(lchString,config){
242
246
  // 使用更精确的正则匹配 lch() 函数
243
247
  const lchRegex=/lch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(deg)?(?:\s*\/\s*([\d.%]+))?\s*\)/i;const match=lchString.match(lchRegex);if(!match){return lchString}try{
244
248
  // 转换为数字
@@ -257,12 +261,12 @@ const lab=lchToLab(L,C,H);
257
261
  // 处理 alpha 通道(如果有)
258
262
  const alphaValue=match[6]!==undefined?match[6].includes("%")?parseFloat(match[6])/100:parseFloat(match[6]):null;return generateColorString(lab.L,lab.a,lab.b,config,alphaValue)}catch(error){console.warn(`无法转换LCH颜色: ${lchString}`,error);return lchString}}
259
263
  /**
260
- * LCH 转换为 Lab (CSS标准)
261
- * @param {number} L - 明度 0-100 或 0%-100%
262
- * @param {number} C - 色度 >=0
263
- * @param {number} H - 色相角 0-360 度
264
- * @returns {Object} Lab 值 {L, a, b}
265
- */function lchToLab(L,C,H){
264
+ * LCH 转换为 Lab (CSS标准)
265
+ * @param {number} L - 明度 0-100 或 0%-100%
266
+ * @param {number} C - 色度 >=0
267
+ * @param {number} H - 色相角 0-360 度
268
+ * @returns {Object} Lab 值 {L, a, b}
269
+ */function lchToLab(L,C,H){
266
270
  // 角度转换为弧度
267
271
  const H_rad=H*Math.PI/180;
268
272
  // LCH -> Lab 转换公式
@@ -286,12 +290,12 @@ const[X,Y,Z]=labToXyz(L,a,b);const[linearR,linearG,linearB]=xyzToLinearRgb(X,Y,Z
286
290
  // 返回钳制后的 RGB 值
287
291
  return{r:clamp(r),g:clamp(g),b:clamp(bOut)}}
288
292
  /**
289
- * Lab -> Display P3 转换
290
- * @param {number} L - 明度 0-100
291
- * @param {number} a - a分量
292
- * @param {number} b - b分量
293
- * @returns {Object} P3颜色 {r, g, b}
294
- */function labToP3(L,a,b){
293
+ * Lab -> Display P3 转换
294
+ * @param {number} L - 明度 0-100
295
+ * @param {number} a - a分量
296
+ * @param {number} b - b分量
297
+ * @returns {Object} P3颜色 {r, g, b}
298
+ */function labToP3(L,a,b){
295
299
  // 1. Lab -> XYZ (使用与RGB相同的转换)
296
300
  const labToXyz=(L,a,b)=>{const refX=.95047;const refY=1;const refZ=1.08883;const epsilon=.008856;const kappa=903.3;const fy=(L+16)/116;const fx=a/500+fy;const fz=fy-b/200;const xr=fx**3>epsilon?fx**3:(116*fx-16)/kappa;const yr=L>kappa*epsilon?((L+16)/116)**3:L/kappa;const zr=fz**3>epsilon?fz**3:(116*fz-16)/kappa;return[xr*refX,yr*refY,zr*refZ]};
297
301
  // 2. XYZ -> Linear P3
@@ -307,24 +311,24 @@ try{const[X,Y,Z]=labToXyz(L,a,b);const[linearR,linearG,linearB]=xyzToLinearP3(X,
307
311
  // 转换为0-1范围的浮点数用于P3颜色格式
308
312
  return{r:Math.max(0,Math.min(1,r)),g:Math.max(0,Math.min(1,g)),b:Math.max(0,Math.min(1,bOut))}}catch(error){console.warn("P3转换失败:",error);const rgb=preciseLabToRGB(L,a,b);return{r:rgb.r/255,g:rgb.g/255,b:rgb.b/255}}}
309
313
  /**
310
- * 生成颜色字符串(根据P3支持情况输出P3或RGB)
311
- * @param {number} L - Lab L值
312
- * @param {number} a - Lab a值
313
- * @param {number} b - Lab b值
314
- * @param {Object} config - 配置对象
315
- * @param {number|null} alpha - 透明度值
316
- * @returns {string} CSS颜色字符串
317
- */function generateColorString(L,a,b,config,alpha=null){if(!config.enableP3||!detectP3Support()){
314
+ * 生成颜色字符串(根据P3支持情况输出P3或RGB)
315
+ * @param {number} L - Lab L值
316
+ * @param {number} a - Lab a值
317
+ * @param {number} b - Lab b值
318
+ * @param {Object} config - 配置对象
319
+ * @param {number|null} alpha - 透明度值
320
+ * @returns {string} CSS颜色字符串
321
+ */function generateColorString(L,a,b,config,alpha=null){if(!config.enableP3||!detectP3Support()){
318
322
  // 使用RGB
319
323
  const rgb=preciseLabToRGB(L,a,b);if(alpha!==null){return`rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`}return`rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`}else{
320
324
  // 使用P3
321
325
  const p3=labToP3(L,a,b);if(alpha!==null){return`color(display-p3 ${p3.r.toFixed(4)} ${p3.g.toFixed(4)} ${p3.b.toFixed(4)} / ${alpha})`}return`color(display-p3 ${p3.r.toFixed(4)} ${p3.g.toFixed(4)} ${p3.b.toFixed(4)})`}}
322
326
  /**
323
- * 处理CSS值,根据配置转换LAB、LCH颜色和math()函数
324
- * @param {string} value - CSS属性值
325
- * @param {Object} config - 配置对象
326
- * @returns {string} 处理后的值
327
- */function processCSSValue(value,config){let result=value;
327
+ * 处理CSS值,根据配置转换LAB、LCH颜色和math()函数
328
+ * @param {string} value - CSS属性值
329
+ * @param {Object} config - 配置对象
330
+ * @returns {string} 处理后的值
331
+ */function processCSSValue(value,config){let result=value;
328
332
  // 1. 首先处理math()函数
329
333
  if(config.enableMath){result=processMathFunctions(result,config)}
330
334
  // 2. 然后处理LAB和LCH颜色
@@ -435,52 +439,76 @@ detectP3Support:detectP3Support,
435
439
  // 数学计算工具方法
436
440
  math:{
437
441
  /**
438
- * 计算数学表达式
439
- * @param {string} expression - 数学表达式
440
- * @returns {string} 计算结果
441
- */
442
+ * 计算数学表达式
443
+ * @param {string} expression - 数学表达式
444
+ * @returns {string} 计算结果
445
+ */
442
446
  evaluate:function(expression){return evaluateMathExpression(expression,defaultConfig)},
443
447
  /**
444
- * 解析带单位的数值
445
- * @param {string} value - 带单位的字符串
446
- * @returns {Object} {value: number, unit: string}
447
- */
448
+ * 解析带单位的数值
449
+ * @param {string} value - 带单位的字符串
450
+ * @returns {Object} {value: number, unit: string}
451
+ */
448
452
  parseUnit:parseValueWithUnit,
449
453
  /**
450
- * 四舍五入数字
451
- * @param {number} num - 要四舍五入的数字
452
- * @param {number} precision - 精度
453
- * @returns {string} 四舍五入后的数字字符串
454
- */
454
+ * 四舍五入数字
455
+ * @param {number} num - 要四舍五入的数字
456
+ * @param {number} precision - 精度
457
+ * @returns {string} 四舍五入后的数字字符串
458
+ */
455
459
  round:roundNumber,
456
460
  /**
457
- * 测试数学表达式
458
- * @param {string} expression - 要测试的表达式
459
- * @param {Object} testConfig - 测试配置
460
- * @returns {Object} 测试结果
461
- */
461
+ * 测试数学表达式
462
+ * @param {string} expression - 要测试的表达式
463
+ * @param {Object} testConfig - 测试配置
464
+ * @returns {Object} 测试结果
465
+ */
462
466
  test:function(expression,testConfig={}){const config={...defaultConfig,...testConfig};try{const result=evaluateMathExpression(expression,config);return{success:true,expression:expression,result:result,parsed:parseValueWithUnit(result.replace(/^calc\(|\)$/g,""))}}catch(error){return{success:false,expression:expression,error:error.message}}}},
463
467
  // 颜色转换工具方法
464
468
  colorUtils:{labToRGB:preciseLabToRGB,lchToLab:lchToLab,lchToRGB:function(L,C,H){const lab=lchToLab(L,C,H);return preciseLabToRGB(lab.L,lab.a,lab.b)},labToP3:labToP3,lchToP3:function(L,C,H){const lab=lchToLab(L,C,H);return labToP3(lab.L,lab.a,lab.b)},parseHexLab:function(hexString){const match=hexString.match(/lab#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i);if(!match)return null;const L_hex=match[1];const A_hex=match[2];const B_hex=match[3];const L=parseInt(L_hex,16)/255*100;const A=(parseInt(A_hex,16)-128)*1.5;const B=(parseInt(B_hex,16)-128)*1.5;return preciseLabToRGB(L,A,B)},parseHexLch:function(hexString){const match=hexString.match(/lch#([0-9a-f]{2})([0-9a-f]{2})(\d{1,3})/i);if(!match)return null;const L_hex=match[1];const C_hex=match[2];const H_dec=match[3];const L=parseInt(L_hex,16)/255*100;const C=parseInt(C_hex,16)/255*150;const H=parseInt(H_dec)/100*360;const lab=lchToLab(L,C,H);return preciseLabToRGB(lab.L,lab.a,lab.b)},
465
469
  /**
466
- * 生成颜色字符串(根据P3支持情况)
467
- * @param {number} L - Lab L值
468
- * @param {number} a - Lab a值
469
- * @param {number} b - Lab b值
470
- * @param {number|null} alpha - 透明度
471
- * @param {boolean} useP3 - 是否使用P3(自动检测)
472
- * @returns {string} CSS颜色字符串
473
- */
470
+ * 生成颜色字符串(根据P3支持情况)
471
+ * @param {number} L - Lab L值
472
+ * @param {number} a - Lab a值
473
+ * @param {number} b - Lab b值
474
+ * @param {number|null} alpha - 透明度
475
+ * @param {boolean} useP3 - 是否使用P3(自动检测)
476
+ * @returns {string} CSS颜色字符串
477
+ */
474
478
  generateColor:function(L,a,b,alpha=null,useP3=true){return generateColorString(L,a,b,{enableP3:useP3},alpha)},
475
479
  /**
476
- * 解析CSS颜色字符串
477
- * @param {string} colorString - CSS颜色字符串
478
- * @returns {Object} 包含原始Lab值和颜色字符串的对象
479
- */
480
+ * 解析CSS颜色字符串
481
+ * @param {string} colorString - CSS颜色字符串
482
+ * @returns {Object} 包含原始Lab值和颜色字符串的对象
483
+ */
480
484
  parseColor:function(colorString){try{
481
485
  // 尝试解析lab()函数格式
482
486
  const labMatch=colorString.match(/lab\(\s*([\d.]+)(%?)\s+([\d.-]+)\s+([\d.-]+)(?:\s*\/\s*([\d.%]+))?\s*\)/i);if(labMatch){let L=parseFloat(labMatch[1]);const A=parseFloat(labMatch[3]);const B=parseFloat(labMatch[4]);const alpha=labMatch[5]?labMatch[5].includes("%")?parseFloat(labMatch[5])/100:parseFloat(labMatch[5]):null;const colorStr=generateColorString(L,A,B,defaultConfig,alpha);return{L:L,A:A,B:B,alpha:alpha,rgb:preciseLabToRGB(L,A,B),p3:labToP3(L,A,B),colorString:colorStr}}
483
487
  // 尝试解析lch()函数格式
484
488
  const lchMatch=colorString.match(/lch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)(deg)?(?:\s*\/\s*([\d.%]+))?\s*\)/i);if(lchMatch){let L=parseFloat(lchMatch[1]);const C=parseFloat(lchMatch[3]);let H=parseFloat(lchMatch[4]);const alpha=lchMatch[6]?lchMatch[6].includes("%")?parseFloat(lchMatch[6])/100:parseFloat(lchMatch[6]):null;const lab=lchToLab(L,C,H);const colorStr=generateColorString(lab.L,lab.a,lab.b,defaultConfig,alpha);return{L:L,C:C,H:H,alpha:alpha,lab:lab,rgb:preciseLabToRGB(lab.L,lab.a,lab.b),p3:labToP3(lab.L,lab.a,lab.b),colorString:colorStr}}return null}catch(error){console.warn("无法解析颜色:",colorString,error);return null}}}};
489
+ // 创建一个可调用的主函数
490
+ const styimat=function(...args){
491
+ // 检查是否是模板字符串调用(标签函数)
492
+ if(args.length>1||args[0]&&args[0].raw){
493
+ // 处理模板字符串
494
+ return handleTemplateTag(...args)}
495
+ // 获取第一个参数
496
+ const firstArg=args[0];
497
+ // 如果传入CSS文本,则编译并返回结果
498
+ if(typeof firstArg==="string"){return convert(firstArg,{...defaultConfig,...args[1]})}
499
+ // 如果传入配置对象,则应用配置
500
+ if(typeof firstArg==="object"&&firstArg!==null){defaultConfig={...defaultConfig,...firstArg};return styimat}
501
+ // 如果没有参数,执行自动处理
502
+ if(args.length===0){return apply()}return styimat};
503
+ // 处理模板字符串的函数
504
+ function handleTemplateTag(strings,...values){
505
+ // 拼接模板字符串
506
+ let cssText=strings[0];for(let i=0;i<values.length;i++){
507
+ // 处理插值(支持字符串、数字、函数等)
508
+ const value=values[i];let result="";if(typeof value==="function"){result=value()}else if(Array.isArray(value)){result=value.join(" ")}else{result=String(value!=null?value:"")}cssText+=result+strings[i+1]}
509
+ // 使用convert函数处理
510
+ return convert(cssText,defaultConfig)}
511
+ // 将API的所有方法复制到主函数上
512
+ Object.assign(styimat,api);Object.setPrototypeOf(styimat,Function.prototype);
485
513
  // 自动初始化
486
- if(typeof window!=="undefined"){apply();Object.defineProperty(window.HTMLElement.prototype,"cssVar",{get(){const element=this;return new Proxy({},{get(target,prop){const varName=prop.startsWith("--")?prop:`--${prop}`;return element.style.getPropertyValue(varName)},set(target,prop,value){const varName=prop.startsWith("--")?prop:`--${prop}`;element.style.setProperty(varName,value);return true}})}})}return api});
514
+ if(typeof window!=="undefined"){apply();Object.defineProperty(window.HTMLElement.prototype,"cssVar",{get(){const element=this;return new Proxy(()=>{},{get(target,prop){const varName=prop.startsWith("--")?prop:`--${prop}`;return element.style.getPropertyValue(varName)},set(target,prop,value){const varName=prop.startsWith("--")?prop:`--${prop}`;element.style.setProperty(varName,value);return true},apply(target,thisArg,argumentsList){const prop=argumentsList[0];const value=argumentsList[1];const varName=prop.startsWith("--")?prop:`--${prop}`;if(value===undefined)return element.style.getPropertyValue(varName);element.style.setProperty(varName,value)}})}})}return styimat});