@codady/utils 0.0.37 → 0.0.39

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 (55) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/dist/utils.cjs.js +651 -54
  3. package/dist/utils.cjs.min.js +3 -3
  4. package/dist/utils.esm.js +651 -54
  5. package/dist/utils.esm.min.js +3 -3
  6. package/dist/utils.umd.js +651 -54
  7. package/dist/utils.umd.min.js +3 -3
  8. package/dist.zip +0 -0
  9. package/examples/ajax-get.html +59 -0
  10. package/examples/ajax-hook.html +55 -0
  11. package/examples/ajax-method.html +36 -0
  12. package/examples/ajax-post.html +37 -0
  13. package/examples/buildUrl.html +99 -0
  14. package/examples/escapeHTML.html +140 -0
  15. package/examples/getUrlHash.html +71 -0
  16. package/examples/renderTpl.html +272 -0
  17. package/modules.js +23 -3
  18. package/modules.ts +22 -3
  19. package/package.json +1 -1
  20. package/src/ajax.js +363 -0
  21. package/src/ajax.ts +450 -0
  22. package/src/buildUrl.js +64 -0
  23. package/src/buildUrl.ts +86 -0
  24. package/src/capitalize - /345/211/257/346/234/254.js" +19 -0
  25. package/src/capitalize.js +19 -0
  26. package/src/capitalize.ts +20 -0
  27. package/src/cleanQueryString.js +19 -0
  28. package/src/cleanQueryString.ts +20 -0
  29. package/src/comma - /345/211/257/346/234/254.js" +2 -0
  30. package/src/escapeCharsMaps.js +73 -0
  31. package/src/escapeCharsMaps.ts +74 -0
  32. package/src/escapeHTML.js +23 -25
  33. package/src/escapeHTML.ts +29 -25
  34. package/src/escapeRegexMaps.js +19 -0
  35. package/src/escapeRegexMaps.ts +26 -0
  36. package/src/getBodyHTML.js +53 -0
  37. package/src/getBodyHTML.ts +61 -0
  38. package/src/getEl.js +1 -1
  39. package/src/getEl.ts +6 -5
  40. package/src/getEls.js +1 -1
  41. package/src/getEls.ts +5 -5
  42. package/src/getUrlHash.js +37 -0
  43. package/src/getUrlHash.ts +39 -0
  44. package/src/isEmpty.js +24 -23
  45. package/src/isEmpty.ts +26 -23
  46. package/src/renderTpl.js +37 -14
  47. package/src/renderTpl.ts +38 -18
  48. package/src/renderTpt.js +73 -0
  49. package/src/sliceStrEnd.js +63 -0
  50. package/src/sliceStrEnd.ts +60 -0
  51. package/src/toSingleLine.js +9 -0
  52. package/src/toSingleLine.ts +9 -0
  53. package/src/escapeHtmlChars - /345/211/257/346/234/254.js" +0 -28
  54. package/src/escapeHtmlChars.js +0 -28
  55. package/src/escapeHtmlChars.ts +0 -29
@@ -0,0 +1,272 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>模板引擎渲染实验场 - 2026 规范重构版</title>
7
+ <style>
8
+ :root {
9
+ --primary: #3498db;
10
+ --dark: #2c3e50;
11
+ --bg: #f4f7f9;
12
+ }
13
+
14
+ body {
15
+ font-family: "PingFang SC", system-ui, sans-serif;
16
+ line-height: 1.6;
17
+ max-width: 1100px;
18
+ margin: 0 auto;
19
+ padding: 30px;
20
+ background: var(--bg);
21
+ color: var(--dark);
22
+ }
23
+
24
+ h1 {
25
+ border-left: 5px solid var(--primary);
26
+ padding-left: 15px;
27
+ font-size: 1.8rem;
28
+ margin-bottom: 5px;
29
+ }
30
+
31
+ .intro {
32
+ color: #7f8c8d;
33
+ margin-bottom: 30px;
34
+ font-size: 0.95rem;
35
+ }
36
+
37
+ /* 案例卡片样式 */
38
+ .case-card {
39
+ background: white;
40
+ border-radius: 12px;
41
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
42
+ margin-bottom: 30px;
43
+ border: 1px solid #e1e8ed;
44
+ overflow: hidden;
45
+ }
46
+
47
+ .case-header {
48
+ background: var(--dark);
49
+ color: white;
50
+ padding: 12px 20px;
51
+ font-weight: bold;
52
+ display: flex;
53
+ justify-content: space-between;
54
+ align-items: center;
55
+ }
56
+
57
+ .case-body {
58
+ display: grid;
59
+ grid-template-columns: 1fr 1fr;
60
+ gap: 25px;
61
+ padding: 20px;
62
+ }
63
+
64
+ /* 模块标题 */
65
+ .section-title {
66
+ font-size: 0.75rem;
67
+ color: #95a5a6;
68
+ text-transform: uppercase;
69
+ margin-bottom: 10px;
70
+ font-weight: 700;
71
+ letter-spacing: 1px;
72
+ display: flex;
73
+ align-items: center;
74
+ }
75
+
76
+ .section-title::before {
77
+ content: "";
78
+ display: inline-block;
79
+ width: 4px;
80
+ height: 12px;
81
+ background: var(--primary);
82
+ margin-right: 8px;
83
+ }
84
+
85
+ pre {
86
+ background: #1e272e;
87
+ color: #d2dae2;
88
+ padding: 15px;
89
+ border-radius: 6px;
90
+ margin: 0;
91
+ font-size: 0.85rem;
92
+ overflow-x: auto;
93
+ border: 1px solid #000;
94
+ }
95
+
96
+ .output-rendered {
97
+ border: 1px solid #dcdde1;
98
+ border-radius: 6px;
99
+ padding: 15px;
100
+ background: #fff;
101
+ min-height: 60px;
102
+ white-space: pre-wrap;
103
+ border: 1px solid #dcdde1;
104
+ }
105
+
106
+ .output-source {
107
+ background: #fff5e6;
108
+ border: 1px solid #ffeaa7;
109
+ padding: 15px;
110
+ border-radius: 6px;
111
+ font-family: monospace;
112
+ font-size: 0.85rem;
113
+ word-break: break-all;
114
+ color: #d35400;
115
+ }
116
+
117
+ .tag {
118
+ background: var(--primary);
119
+ font-size: 0.7rem;
120
+ padding: 3px 10px;
121
+ border-radius: 20px;
122
+ }
123
+
124
+ .desc-text {
125
+ font-size: 0.85rem;
126
+ color: #57606f;
127
+ margin-top: 10px;
128
+ background: #f1f2f6;
129
+ padding: 8px 12px;
130
+ border-radius: 4px;
131
+ }
132
+
133
+
134
+ @media (max-width: 800px) {
135
+ .case-body {
136
+ grid-template-columns: 1fr;
137
+ }
138
+ }
139
+ </style>
140
+ </head>
141
+
142
+ <body>
143
+
144
+ <h1>模板引擎渲染实验场</h1>
145
+ <p class="intro">采用 <code>&lt;script type="text/template"&gt;</code> 方式解耦模板与逻辑,彻底解决编辑器语法报错问题。</p>
146
+
147
+ <script type="text/template" id="tpl-basic">
148
+ 用户:{{ user.name }} (ID: {{ user.id }})
149
+ 总分计算:{{ (math.score + math.bonus) * 1.2 }} 分
150
+ </script>
151
+
152
+ <script type="text/template" id="tpl-xss">
153
+ 最新留言:{{ comment }}
154
+ </script>
155
+
156
+ <script type="text/template" id="tpl-logic">
157
+ {{ if(this.score >= 60) { /}}
158
+ <b style="color:green">✅ 状态:考核通过</b>
159
+ {{ } else { /}}
160
+ <b style="color:red">❌ 状态:需重修</b>
161
+ {{ } /}}
162
+ </script>
163
+
164
+ <script type="text/template" id="tpl-attr">
165
+ <input type="text" value="{{ val }}" title="{{ val }}">
166
+ </script>
167
+
168
+ <script type="text/template" id="tpl-multiline">
169
+ 第一行:{{ line1 }}
170
+ 第二行:{{ line2 }}
171
+ --- 模板自带多行演示 ---
172
+ 这是模板里的第一行内容
173
+ 这是模板里的第二行内容
174
+ </script>
175
+
176
+ <div id="demo-root"></div>
177
+
178
+ <script src="../dist/utils.umd.js"></script>
179
+
180
+ <script>
181
+ /**
182
+ * 案例配置列表
183
+ * templateId: 对应上面定义在 HTML 里的 script ID
184
+ */
185
+ const cases = [
186
+ {
187
+ title: "1. 基础文本与数值运算",
188
+ desc: "测试简单的变量替换、深层对象访问以及数学表达式运算。",
189
+ templateId: "tpl-basic",
190
+ data: {
191
+ user: { name: "张三", id: 8801 },
192
+ math: { score: 80, bonus: 10 }
193
+ },
194
+ opts: {}
195
+ },
196
+ {
197
+ title: "2. 安全防御:防止 XSS 攻击",
198
+ desc: "展示 'basic' 强度如何转义危险脚本,确保输出结果安全。",
199
+ templateId: "tpl-xss",
200
+ data: { comment: "<script>alert('危险')<\/script>你好,这是黑客的问候" },
201
+ opts: { escape: 'basic' }
202
+ },
203
+ {
204
+ title: "3. 逻辑控制 (if/else)",
205
+ desc: "使用 / 后缀标识原生 JS 语句。此时 > 符号在 script 标签内不会引发编辑器报错。",
206
+ templateId: "tpl-logic",
207
+ data: { score: 85 },
208
+ opts: { strict: true }
209
+ },
210
+ {
211
+ title: "4. HTML 属性安全保护",
212
+ desc: "使用 'attribute' 强度处理引号,防止属性被非法闭合。",
213
+ templateId: "tpl-attr",
214
+ data: { val: '双引号 " 和单引号 \' 的混合测试' },
215
+ opts: { escape: 'attribute' }
216
+ },
217
+ {
218
+ title: "6. 多行文本保留测试",
219
+ desc: "验证 toSingleLine 是否会误删数据中的换行。期望结果:预览中应保持换行。",
220
+ templateId: "tpl-multiline",
221
+ data: {
222
+ line1: "我是动态数据的第一行",
223
+ line2: "我是动态数据的第二行"
224
+ },
225
+ opts: {}
226
+ }
227
+ ];
228
+
229
+ const root = document.getElementById('demo-root');
230
+
231
+ cases.forEach(c => {
232
+ // A. 从 script 标签获取原始模板内容
233
+ const templateElement = document.getElementById(c.templateId);
234
+ const rawTemplate = templateElement ? templateElement.innerHTML.trim() : "";
235
+
236
+ // B. 执行渲染
237
+ let result = "";
238
+ try {
239
+ result = utils.renderTpl(rawTemplate, c.data, c.opts);
240
+ } catch (e) {
241
+ result = "渲染异常:" + e.message;
242
+ }
243
+
244
+ // C. 动态创建 UI
245
+ const card = document.createElement('div');
246
+ card.className = 'case-card';
247
+ card.innerHTML = `
248
+ <div class="case-header">
249
+ <span>${c.title}</span>
250
+ <span class="tag">模式: ${c.opts.escape || '不转义'}</span>
251
+ </div>
252
+ <div class="case-body">
253
+ <div>
254
+ <div class="section-title">输入模板与数据</div>
255
+ <pre>模板 (来自 #${c.templateId}):\n${rawTemplate}\n\n数据:\n${JSON.stringify(c.data, null, 2)}</pre>
256
+ <div class="desc-text">ℹ️ ${c.desc}</div>
257
+ </div>
258
+ <div>
259
+ <div class="section-title">渲染产物 (HTML 源码)</div>
260
+ <div class="output-source">${result.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')}</div>
261
+
262
+ <div class="section-title" style="margin-top:20px;">浏览器渲染预览</div>
263
+ <div class="output-rendered">${result}</div>
264
+ </div>
265
+ </div>
266
+ `;
267
+ root.appendChild(card);
268
+ });
269
+ </script>
270
+ </body>
271
+
272
+ </html>
package/modules.js CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
- * Last modified: 2026/01/15 18:57:17
2
+ * Last modified: 2026/01/20 13:55:43
3
3
  */
4
4
  'use strict';
5
5
  import deepClone from './src/deepClone';
6
6
  import deepCloneToJSON from './src/deepCloneToJSON';
7
7
  import getDataType from './src/getDataType';
8
8
  import wrapArrayMethods from './src/wrapArrayMethods';
9
+ import renderTpl from './src/renderTpl';
9
10
  import requireTypes from './src/requireTypes';
10
11
  import getUniqueId from './src/getUniqueId';
11
12
  import arrayMutableMethods from './src/arrayMutableMethods';
@@ -35,8 +36,17 @@ import typeWriter from './src/typeWriter';
35
36
  import parseLLMStream from './src/parseLLMStream';
36
37
  import toKebabCase from './src/toKebabCase';
37
38
  import trimEmptyLines from './src/trimEmptyLines';
38
- import escapeHtmlChars from './src/escapeHtmlChars';
39
39
  import decodeHtmlEntities from './src/decodeHtmlEntities';
40
+ import escapeHTML from './src/escapeHTML';
41
+ import escapeRegexMaps from './src/escapeRegexMaps';
42
+ import escapeCharsMaps from './src/escapeCharsMaps';
43
+ import toSingleLine from './src/toSingleLine';
44
+ import getBodyHTML from './src/getBodyHTML';
45
+ import getUrlHash from './src/getUrlHash';
46
+ import buildUrl from './src/buildUrl';
47
+ import ajax from './src/ajax';
48
+ import capitalize from './src/capitalize';
49
+ import cleanQueryString from './src/cleanQueryString';
40
50
  const utils = {
41
51
  //executeStr,
42
52
  getDataType,
@@ -74,7 +84,17 @@ const utils = {
74
84
  parseLLMStream,
75
85
  toKebabCase,
76
86
  trimEmptyLines,
77
- escapeHtmlChars,
78
87
  decodeHtmlEntities,
88
+ escapeCharsMaps,
89
+ escapeRegexMaps,
90
+ escapeHTML,
91
+ toSingleLine,
92
+ renderTpl,
93
+ getBodyHTML,
94
+ getUrlHash,
95
+ buildUrl,
96
+ ajax,
97
+ capitalize,
98
+ cleanQueryString,
79
99
  };
80
100
  export default utils;
package/modules.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Last modified: 2026/01/15 18:57:17
2
+ * Last modified: 2026/01/20 13:55:43
3
3
  */
4
4
  'use strict'
5
5
  import deepClone from './src/deepClone';
@@ -43,8 +43,17 @@ import typeWriter from './src/typeWriter';
43
43
  import parseLLMStream from './src/parseLLMStream';
44
44
  import toKebabCase from './src/toKebabCase';
45
45
  import trimEmptyLines from './src/trimEmptyLines';
46
- import escapeHtmlChars from './src/escapeHtmlChars';
47
46
  import decodeHtmlEntities from './src/decodeHtmlEntities';
47
+ import escapeHTML from './src/escapeHTML';
48
+ import escapeRegexMaps from './src/escapeRegexMaps';
49
+ import escapeCharsMaps from './src/escapeCharsMaps';
50
+ import toSingleLine from './src/toSingleLine';
51
+ import getBodyHTML from './src/getBodyHTML';
52
+ import getUrlHash from './src/getUrlHash';
53
+ import buildUrl from './src/buildUrl';
54
+ import ajax from './src/ajax';
55
+ import capitalize from './src/capitalize';
56
+ import cleanQueryString from './src/cleanQueryString';
48
57
 
49
58
  const utils = {
50
59
  //executeStr,
@@ -83,8 +92,18 @@ const utils = {
83
92
  parseLLMStream,
84
93
  toKebabCase,
85
94
  trimEmptyLines,
86
- escapeHtmlChars,
87
95
  decodeHtmlEntities,
96
+ escapeCharsMaps,
97
+ escapeRegexMaps,
98
+ escapeHTML,
99
+ toSingleLine,
100
+ renderTpl,
101
+ getBodyHTML,
102
+ getUrlHash,
103
+ buildUrl,
104
+ ajax,
105
+ capitalize,
106
+ cleanQueryString,
88
107
 
89
108
  };
90
109
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codady/utils",
3
- "version": "0.0.37",
3
+ "version": "0.0.39",
4
4
  "author": "AXUI Development Team",
5
5
  "license": "MIT",
6
6
  "description": "This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.",