agentcss 0.25.5 → 0.26.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/01-tokens/behavior/labels.js +44 -0
- package/02-primitives/combobox/combobox.js +26 -3
- package/02-primitives/date-range/date-range.js +27 -5
- package/02-primitives/popover/popover.js +22 -2
- package/02-primitives/select/select.js +23 -2
- package/02-primitives/upload/upload.js +50 -17
- package/03-patterns/content/content.css +13 -1
- package/03-patterns/content/demo.html +1 -1
- package/03-patterns/drawer/drawer.js +44 -6
- package/03-patterns/dropdown/dropdown.js +21 -1
- package/03-patterns/overlay/overlay.js +39 -2
- package/03-patterns/pagination/pagination.js +37 -10
- package/03-patterns/tooltip/tooltip.js +17 -2
- package/03-patterns/tree/tree.js +21 -1
- package/04-recipes/analysis-report/demo.html +1 -1
- package/04-recipes/data-showcase/demo.html +2 -2
- package/04-recipes/longform/content.html +989 -74
- package/04-recipes/longform/longform.html +3 -3
- package/04-recipes/report/demo.html +1 -1
- package/04-recipes/table/README.md +22 -0
- package/04-recipes/table/demo.html +6 -6
- package/09-assets/bar/bar.js +28 -4
- package/09-assets/model-viewer/model-viewer.js +44 -12
- package/09-assets/scientific-plot/demo.html +6 -6
- package/API.md +32 -0
- package/CHANGELOG.md +129 -0
- package/CONTRIBUTING.md +4 -3
- package/README.md +19 -2
- package/README.zh-CN.md +18 -2
- package/SECURITY.md +16 -4
- package/START-HERE.md +14 -14
- package/SUPPORT.md +2 -2
- package/ai/components.json +9 -4
- package/ai/pdf.js +50 -8
- package/dist/01-tokens/behavior/labels.js +11 -0
- package/dist/02-primitives/combobox/combobox.js +25 -3
- package/dist/02-primitives/date-range/date-range.js +26 -5
- package/dist/02-primitives/popover/popover.js +14 -1
- package/dist/02-primitives/select/select.js +22 -2
- package/dist/02-primitives/upload/upload.js +47 -17
- package/dist/03-patterns/content/content.css +1 -1
- package/dist/03-patterns/drawer/drawer.js +32 -4
- package/dist/03-patterns/dropdown/dropdown.js +20 -1
- package/dist/03-patterns/overlay/overlay.js +25 -1
- package/dist/03-patterns/pagination/pagination.js +34 -10
- package/dist/03-patterns/tooltip/tooltip.js +14 -2
- package/dist/03-patterns/tree/tree.js +20 -1
- package/dist/09-assets/bar/bar.js +23 -4
- package/dist/09-assets/model-viewer/model-viewer.js +38 -12
- package/dist/COSTS.md +14 -14
- package/docs/ACCESSIBILITY.md +2 -2
- package/docs/L10N.md +92 -0
- package/docs/LAYER-BASELINE.md +2 -2
- package/docs/RELEASE-PROCESS.md +7 -1
- package/docs/VERIFY-RELEASE.md +7 -2
- package/index.html +1 -1
- package/llms-full.txt +2 -2
- package/package.json +17 -6
- package/types/index.d.ts +218 -13
package/START-HERE.md
CHANGED
|
@@ -39,39 +39,39 @@
|
|
|
39
39
|
| 标签 / 徽章 | `02-primitives/badge/badge.css` | 141 | — | 有状态标记就要("已披露""停牌") |
|
|
40
40
|
| 卡片 | `02-primitives/card/card.css` | 283 | — | 有分组内容就要 |
|
|
41
41
|
| 单选 / 多选 | `02-primitives/choice/choice.css` | 434 | — | 单选 / 多选就要 |
|
|
42
|
-
| 下拉选择 | `02-primitives/select/select.css` | 151 | **必需
|
|
43
|
-
| 可搜索选择 | `02-primitives/combobox/combobox.css` | 223 | **必需
|
|
42
|
+
| 下拉选择 | `02-primitives/select/select.css` | 151 | **必需 652** (`select.js`) | 原生 select 的外观或交互不够用就要 |
|
|
43
|
+
| 可搜索选择 | `02-primitives/combobox/combobox.css` | 223 | **必需 503** (`combobox.js`) | 选项多到要搜索,或要选多个并留成标签就要 |
|
|
44
44
|
| 开关 | `02-primitives/switch/switch.css` | 429 | — | 有"立即生效的设置"就要 |
|
|
45
45
|
| 分隔线 | `02-primitives/separator/separator.css` | 73 | — | 要分开内容块就要 |
|
|
46
46
|
| 加载骨架 | `02-primitives/skeleton/skeleton.css` | 114 | — | 数据还没到、先把版式占住就要 |
|
|
47
47
|
| 进度条 / 环 | `02-primitives/progress/progress.css` | 228 | — | 有耗时过程要给进度就要 |
|
|
48
|
-
| 浮层气泡 | `02-primitives/popover/popover.css` | 187 | **必需
|
|
49
|
-
| 日期区间 | `02-primitives/date-range/date-range.css` | 206 | **必需
|
|
48
|
+
| 浮层气泡 | `02-primitives/popover/popover.css` | 187 | **必需 345** (`popover.js`) | 要一段信息贴着触发元素浮出来就要 |
|
|
49
|
+
| 日期区间 | `02-primitives/date-range/date-range.css` | 206 | **必需 332** (`date-range.js`) | 要选起止日期就要 |
|
|
50
50
|
| 标签页 | `03-patterns/tabs/tabs.css` | 172 | **必需 316** (`tabs.js`) | 同层级内容切换就要 |
|
|
51
51
|
| 折叠面板 | `03-patterns/accordion/accordion.css` | 453 | **必需 389** (`accordion.js`) | 长表单分段就要 |
|
|
52
|
-
| 动作菜单 | `03-patterns/dropdown/dropdown.css` | 135 | **必需
|
|
53
|
-
| 文字提示 | `03-patterns/tooltip/tooltip.css` | 89 | **必需
|
|
54
|
-
| 分页 | `03-patterns/pagination/pagination.css` | 195 | **必需
|
|
55
|
-
| 树形 | `03-patterns/tree/tree.css` | 122 | **必需
|
|
56
|
-
| 侧边抽屉 | `03-patterns/drawer/drawer.css` | 145 | **必需
|
|
57
|
-
| 弹窗 / 吐司 | `03-patterns/overlay/overlay.css` | 338 | **必需
|
|
52
|
+
| 动作菜单 | `03-patterns/dropdown/dropdown.css` | 135 | **必需 575** (`dropdown.js`) | 要一组动作(新建 / 导出 / 删除)就要 |
|
|
53
|
+
| 文字提示 | `03-patterns/tooltip/tooltip.css` | 89 | **必需 299** (`tooltip.js`) | 图标按钮或缩写需要一句话解释就要 |
|
|
54
|
+
| 分页 | `03-patterns/pagination/pagination.css` | 195 | **必需 428** (`pagination.js`) | 数据多到要翻页就要 |
|
|
55
|
+
| 树形 | `03-patterns/tree/tree.css` | 122 | **必需 484** (`tree.js`) | 层级数据(文件 / 组织 / 分类)要展开就要 |
|
|
56
|
+
| 侧边抽屉 | `03-patterns/drawer/drawer.css` | 145 | **必需 416** (`drawer.js`) | 要从侧边滑出面板就要 |
|
|
57
|
+
| 弹窗 / 吐司 | `03-patterns/overlay/overlay.css` | 338 | **必需 734** (`overlay.js`) | 需要弹层(吐司 / 模态)就要 |
|
|
58
58
|
| 状态(空 / 加载 / 错 / 成功) | `03-patterns/states/states.css` | 269 | — | **凡是会异步取数就要** |
|
|
59
59
|
| 表单校验 | `03-patterns/form-validation/form-validation.css` | 274 | — | 提交前要校验就要 |
|
|
60
60
|
| 列表增删 | `03-patterns/list/list.css` | 162 | 可选 201 (`flip.js`,FLIP 增删动画,纯增强) | 列表会动态增删就要 |
|
|
61
61
|
| 导航 / 目录 | `03-patterns/nav/nav.css` | 314 | **必需 425** (`nav.js`) · 可选 111 (`toc.js`,自动生成目录,纯增强) | 顶部要导航,或长文要目录就要 |
|
|
62
|
-
| 长文排版 | `03-patterns/content/content.css` |
|
|
62
|
+
| 长文排版 | `03-patterns/content/content.css` | 298 | — | 写文档 / 长文就要 |
|
|
63
63
|
| delta | `02-primitives/delta/delta.css` | 113 | — | |
|
|
64
64
|
| metric | `02-primitives/metric/metric.css` | 157 | — | |
|
|
65
65
|
| timeline | `02-primitives/timeline/timeline.css` | 152 | — | 有一串按时间排的事件(公告 / 大事记 / 版本记录)就要 |
|
|
66
|
-
| upload | `02-primitives/upload/upload.css` | 490 | 可选
|
|
66
|
+
| upload | `02-primitives/upload/upload.css` | 490 | 可选 709 (`upload.js`,拖放 / 文件列表 / 校验;没有它基础形态照常工作) | |
|
|
67
67
|
| reveal | `03-patterns/reveal/reveal.css` | 93 | 可选 175 (`reveal.js`,入场动效,纯增强;没有它内容直接可见) | |
|
|
68
68
|
| analysis-report | `04-recipes/analysis-report/analysis-report.css` | 226 | — | |
|
|
69
69
|
| app-shell | `04-recipes/app-shell/app-shell.css` | 588 | **必需 289** (`shell-nav.js`) | |
|
|
70
70
|
| detail-page | `04-recipes/detail-page/detail-page.css` | 190 | — | |
|
|
71
71
|
| report | `04-recipes/report/report.css` | 369 | — | |
|
|
72
72
|
| table | `04-recipes/table/table.css` | 409 | — | |
|
|
73
|
-
| bar | `09-assets/bar/bar.css` | 181 | **必需
|
|
74
|
-
| model-viewer | `09-assets/model-viewer/model-viewer.css` | 143 | **必需
|
|
73
|
+
| bar | `09-assets/bar/bar.css` | 181 | **必需 348** (`bar.js`) | |
|
|
74
|
+
| model-viewer | `09-assets/model-viewer/model-viewer.css` | 143 | **必需 464** (`model-viewer.js`) | |
|
|
75
75
|
| scientific-plot | `09-assets/scientific-plot/scientific-plot.css` | 141 | **必需 604** (`scientific-plot.js`) | |
|
|
76
76
|
| sparkline | `09-assets/sparkline/sparkline.css` | 158 | **必需 508** (`sparkline.js`) | |
|
|
77
77
|
|
package/SUPPORT.md
CHANGED
|
@@ -97,9 +97,9 @@ grep 一条都数不到),还有 `skip "…"`(这台机器跑不了的门
|
|
|
97
97
|
|
|
98
98
|
### 试过一次的(🔍 人工实测,无回归保护)
|
|
99
99
|
|
|
100
|
-
7 行数据来自在真实设备上打开 [`capability-probe.html`](10-review/webview/capability-probe.html)。
|
|
100
|
+
7 行数据来自在真实设备上打开 [`capability-probe.html`](https://github.com/owain323/frontend-lib/blob/master/10-review/webview/capability-probe.html)。
|
|
101
101
|
完整 UA 与逐项结论在 [`docs/LAYER-BASELINE.md`](docs/LAYER-BASELINE.md);
|
|
102
|
-
15 项能力分别是什么、怎么自己复跑一遍,在 [`10-review/webview/RESULTS.md`](10-review/webview/RESULTS.md)。
|
|
102
|
+
15 项能力分别是什么、怎么自己复跑一遍,在 [`10-review/webview/RESULTS.md`](https://github.com/owain323/frontend-lib/blob/master/10-review/webview/RESULTS.md)。
|
|
103
103
|
本节 7 行**全部是 `🔍`** —— 没有一行有自动化守着。
|
|
104
104
|
|
|
105
105
|
| 入口 | UA 自述的环境 | 实测 | 缺什么 |
|
package/ai/components.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
3
|
"generatedBy": "05-audit/gen-ai-contract.py",
|
|
4
|
-
"libraryVersion": "0.
|
|
4
|
+
"libraryVersion": "0.26.0",
|
|
5
5
|
"$comment": "机器可读的组件契约。slots = BEM 元素名(在本库里元素名就是插槽名),states.enum = 组件会在 DOM 上写出的 data-* 取值,states.legacyClass = 仍未收敛到 data 属性的历史状态类(INVARIANT I-8 未达标)。printPolicy = 这个组件在纸上会发生什么(空数组 = 原样保留);pagination = 内容是否被分页裁过(server 不许与 expand 同时出现,否则展开的只是当前一页)。",
|
|
6
6
|
"maturityCriteria": {
|
|
7
7
|
"alpha": "缺 demo.html 或缺 05-audit 下的专属门禁 ⇒ 还没被机器验证过,不要用",
|
|
@@ -249,11 +249,13 @@
|
|
|
249
249
|
},
|
|
250
250
|
"aria": {
|
|
251
251
|
"roles": [
|
|
252
|
-
"img"
|
|
252
|
+
"img",
|
|
253
|
+
"region"
|
|
253
254
|
],
|
|
254
255
|
"attrs": [
|
|
255
256
|
"hidden",
|
|
256
|
-
"label"
|
|
257
|
+
"label",
|
|
258
|
+
"labelledby"
|
|
257
259
|
]
|
|
258
260
|
},
|
|
259
261
|
"usesOtherNamespaces": [],
|
|
@@ -2411,7 +2413,9 @@
|
|
|
2411
2413
|
"legacyClass": []
|
|
2412
2414
|
},
|
|
2413
2415
|
"aria": {
|
|
2414
|
-
"roles": [
|
|
2416
|
+
"roles": [
|
|
2417
|
+
"region"
|
|
2418
|
+
],
|
|
2415
2419
|
"attrs": [
|
|
2416
2420
|
"hidden",
|
|
2417
2421
|
"label"
|
|
@@ -2475,6 +2479,7 @@
|
|
|
2475
2479
|
"aria": {
|
|
2476
2480
|
"roles": [
|
|
2477
2481
|
"alert",
|
|
2482
|
+
"region",
|
|
2478
2483
|
"status"
|
|
2479
2484
|
],
|
|
2480
2485
|
"attrs": [
|
package/ai/pdf.js
CHANGED
|
@@ -75,6 +75,35 @@ const DEFAULT_MARGIN = '18mm 15mm';
|
|
|
75
75
|
* **找不到就明确报错,不许静默降级**。
|
|
76
76
|
* 漂移由 `05-audit/pdf-export-gate.js` 的 E8 交叉核对(两边都找到时必须是同一个文件)。
|
|
77
77
|
*/
|
|
78
|
+
/* Playwright 实际会用到的可执行文件名。只收这几个 —— 名字表越宽,
|
|
79
|
+
越可能在缓存目录里认错文件(例如 README、脚本)。 */
|
|
80
|
+
const PW_EXE = [
|
|
81
|
+
'chrome', 'chrome.exe',
|
|
82
|
+
'chrome-headless-shell', 'chrome-headless-shell.exe',
|
|
83
|
+
'headless_shell', 'headless_shell.exe',
|
|
84
|
+
'Chromium', 'Google Chrome for Testing', 'Google Chrome for Testing.exe',
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
/** 在 Playwright 的 chromium* 目录里按文件名找可执行文件(有界递归,depth 层) */
|
|
88
|
+
function scanForExe(dir, depth) {
|
|
89
|
+
let names;
|
|
90
|
+
try { names = fs.readdirSync(dir); } catch (e) { return null; }
|
|
91
|
+
const dirs = [];
|
|
92
|
+
for (const n of names) {
|
|
93
|
+
const p = path.join(dir, n);
|
|
94
|
+
let st;
|
|
95
|
+
try { st = fs.statSync(p); } catch (e) { continue; }
|
|
96
|
+
if (st.isDirectory()) { dirs.push(p); continue; }
|
|
97
|
+
if (PW_EXE.indexOf(n) !== -1) return p;
|
|
98
|
+
}
|
|
99
|
+
if (depth <= 0) return null;
|
|
100
|
+
for (const d of dirs) {
|
|
101
|
+
const hit = scanForExe(d, depth - 1);
|
|
102
|
+
if (hit) return hit;
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
78
107
|
function chromeCandidates() {
|
|
79
108
|
const out = [];
|
|
80
109
|
if (process.env.AGENTCSS_CHROME) out.push(process.env.AGENTCSS_CHROME);
|
|
@@ -97,18 +126,28 @@ function chromeCandidates() {
|
|
|
97
126
|
out.push('/usr/bin/google-chrome', '/usr/bin/google-chrome-stable',
|
|
98
127
|
'/usr/bin/chromium', '/usr/bin/chromium-browser', '/snap/bin/chromium');
|
|
99
128
|
}
|
|
100
|
-
/* CI 上没有系统 Chrome:Playwright 装的那份也得认,否则"能导出"
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
/* CI 上没有系统 Chrome:Playwright 装的那份也得认,否则"能导出"只在开发机上成立。
|
|
130
|
+
⚠️ **不写死目录布局**。Playwright 改过两次命名:
|
|
131
|
+
chrome-linux/chrome → chrome-linux64/chrome
|
|
132
|
+
chrome-linux/headless_shell → chrome-headless-shell-linux64/chrome-headless-shell
|
|
133
|
+
写死布局的结果就是"某天起突然 no-chrome"(外部审计 F5 实测:
|
|
134
|
+
干净环境里 `npm ci && npx playwright install chromium` 之后依然找不到)。
|
|
135
|
+
⇒ 在 chromium* 目录下按**可执行文件名**有界递归找,布局怎么变都还能找到。
|
|
136
|
+
⚠️ Windows 的根目录是 %LOCALAPPDATA%\ms-playwright —— `~/.cache` 在 Windows 上不存在。 */
|
|
137
|
+
const roots = [
|
|
138
|
+
process.env.PLAYWRIGHT_BROWSERS_PATH,
|
|
139
|
+
process.env.LOCALAPPDATA && path.join(process.env.LOCALAPPDATA, 'ms-playwright'),
|
|
140
|
+
path.join(os.homedir(), '.cache/ms-playwright'),
|
|
141
|
+
path.join(os.homedir(), 'Library/Caches/ms-playwright'),
|
|
142
|
+
].filter(Boolean);
|
|
143
|
+
for (const root of roots) {
|
|
103
144
|
let names;
|
|
104
145
|
try { names = fs.readdirSync(root); } catch (e) { continue; }
|
|
105
146
|
for (const n of names) {
|
|
106
147
|
if (!/^chromium/.test(n)) continue;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
out.push(path.join(root, n, ...rel.split('/')));
|
|
111
|
-
}
|
|
148
|
+
/* 深度 4:macOS 的 .app 包多两层(见 browser.js 同一处注释) */
|
|
149
|
+
const hit = scanForExe(path.join(root, n), 4);
|
|
150
|
+
if (hit) out.push(hit);
|
|
112
151
|
}
|
|
113
152
|
}
|
|
114
153
|
return out.filter(Boolean);
|
|
@@ -351,4 +390,7 @@ function overBudgetMessage(got, budget, spec, margin, out, box, injected) {
|
|
|
351
390
|
module.exports = {
|
|
352
391
|
exportPdf, resolveChrome, normalizeMargin, paperSpec, PAPERS,
|
|
353
392
|
DEFAULT_PAPER, DEFAULT_MARGIN,
|
|
393
|
+
/* 只为可测性导出:浏览器发现逻辑必须在"没有系统 Chrome"的机器上也能被验证,
|
|
394
|
+
否则它只会在 CI 上坏、而开发机永远绿。 */
|
|
395
|
+
chromeCandidates,
|
|
354
396
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var flLabels = function (defaults, src) {
|
|
2
|
+
src = src || {};
|
|
3
|
+
var out = {};
|
|
4
|
+
var k;
|
|
5
|
+
for (k in defaults) {
|
|
6
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
7
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return out;
|
|
11
|
+
};
|
|
@@ -119,6 +119,28 @@ return true;
|
|
|
119
119
|
var uid = 0;
|
|
120
120
|
|
|
121
121
|
function create(root, opt) {
|
|
122
|
+
|
|
123
|
+
var DEFAULT_LABELS = {
|
|
124
|
+
suggest: '建议',
|
|
125
|
+
input: '输入',
|
|
126
|
+
noMatch: function (q) { return '没有匹配「' + q + '」的选项'; },
|
|
127
|
+
empty: '暂无可选'
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
var flLabels = function (defaults, src) {
|
|
131
|
+
src = src || {};
|
|
132
|
+
var out = {};
|
|
133
|
+
var k;
|
|
134
|
+
for (k in defaults) {
|
|
135
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
136
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
143
|
+
|
|
122
144
|
opt = opt || {};
|
|
123
145
|
var input = root.querySelector('[data-combo-input]');
|
|
124
146
|
var list = root.querySelector('[data-combo-list]');
|
|
@@ -147,14 +169,14 @@ var activeIdx = -1;
|
|
|
147
169
|
var shown = [];
|
|
148
170
|
|
|
149
171
|
list.setAttribute('role', 'listbox');
|
|
150
|
-
list.setAttribute('aria-label', opt.label ||
|
|
172
|
+
list.setAttribute('aria-label', opt.label || L.suggest);
|
|
151
173
|
input.setAttribute('role', 'combobox');
|
|
152
174
|
input.setAttribute('aria-autocomplete', 'list');
|
|
153
175
|
input.setAttribute('aria-expanded', 'false');
|
|
154
176
|
input.setAttribute('aria-controls', list.id);
|
|
155
177
|
if (!input.id) input.id = 'combo-input-' + seq;
|
|
156
178
|
if (!input.getAttribute('aria-label') && !root.querySelector('label[for="' + input.id + '"]')) {
|
|
157
|
-
input.setAttribute('aria-label', opt.label ||
|
|
179
|
+
input.setAttribute('aria-label', opt.label || L.input);
|
|
158
180
|
}
|
|
159
181
|
|
|
160
182
|
function esc(s) {
|
|
@@ -190,7 +212,7 @@ return String(s).replace(/[&<>"]/g, function (c) {
|
|
|
190
212
|
if (!shown.length) {
|
|
191
213
|
/* @html-sink escaped — 插值只有 q,且过了 esc() */
|
|
192
214
|
list.innerHTML = '<li class="combo__empty" role="presentation">' +
|
|
193
|
-
(q ?
|
|
215
|
+
(q ? L.noMatch(esc(q)) : L.empty) + '</li>';
|
|
194
216
|
return;
|
|
195
217
|
}
|
|
196
218
|
var ql = q.toLowerCase();
|
|
@@ -94,6 +94,27 @@ return { from: iso(start), to: iso(end) };
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
function create(root, opt) {
|
|
97
|
+
|
|
98
|
+
var flLabels = function (defaults, src) {
|
|
99
|
+
src = src || {};
|
|
100
|
+
var out = {};
|
|
101
|
+
var k;
|
|
102
|
+
for (k in defaults) {
|
|
103
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
104
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
var DEFAULT_LABELS = {
|
|
111
|
+
requiredEnd: '请填写结束日期。',
|
|
112
|
+
requiredStart: '请填写开始日期。',
|
|
113
|
+
order: function (f, t) { return '开始日期不能晚于结束日期(当前:' + f + ' → ' + t + ')。'; },
|
|
114
|
+
min: function (min) { return '开始日期不能早于 ' + min + '。'; },
|
|
115
|
+
max: function (max) { return '结束日期不能晚于 ' + max + '。'; }
|
|
116
|
+
};
|
|
117
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
97
118
|
opt = opt || {};
|
|
98
119
|
var from = root.querySelector('[data-dr-from]');
|
|
99
120
|
var to = root.querySelector('[data-dr-to]');
|
|
@@ -132,14 +153,14 @@ return Math.round((b - a) / 86400000) + 1;
|
|
|
132
153
|
function validate() {
|
|
133
154
|
var f = from.value, t = to.value;
|
|
134
155
|
if (!f && !t) { setError(''); paintSummary(''); return true; }
|
|
135
|
-
if (f && !t) { setError(
|
|
136
|
-
if (!f && t) { setError(
|
|
156
|
+
if (f && !t) { setError(L.requiredEnd); return false; }
|
|
157
|
+
if (!f && t) { setError(L.requiredStart); return false; }
|
|
137
158
|
if (f > t) {
|
|
138
|
-
setError(
|
|
159
|
+
setError(L.order(f, t));
|
|
139
160
|
return false;
|
|
140
161
|
}
|
|
141
|
-
if (opt.min && f < opt.min) { setError(
|
|
142
|
-
if (opt.max && t > opt.max) { setError(
|
|
162
|
+
if (opt.min && f < opt.min) { setError(L.min(opt.min)); return false; }
|
|
163
|
+
if (opt.max && t > opt.max) { setError(L.max(opt.max)); return false; }
|
|
143
164
|
setError('');
|
|
144
165
|
paintSummary(f + ' → ' + t + '(' + days(f, t) + ' 天)');
|
|
145
166
|
return true;
|
|
@@ -148,10 +148,11 @@ box.setAttribute('inert', '');
|
|
|
148
148
|
|
|
149
149
|
box.setAttribute('role', 'dialog');
|
|
150
150
|
box.setAttribute('aria-label', opts.label || '');
|
|
151
|
+
var bodyHtml = sanitizeHtml(opts.html || '', opts.sanitize);
|
|
151
152
|
|
|
152
153
|
box.innerHTML =
|
|
153
154
|
'<span class="popover__arrow" aria-hidden="true"></span>'+
|
|
154
|
-
'<div class="popover__body">'+
|
|
155
|
+
'<div class="popover__body">'+ bodyHtml + '</div>';
|
|
155
156
|
|
|
156
157
|
positionArrow(box, trigger);
|
|
157
158
|
anchor.appendChild(box);
|
|
@@ -230,6 +231,17 @@ el: box,
|
|
|
230
231
|
return api;
|
|
231
232
|
}
|
|
232
233
|
|
|
234
|
+
var SANITIZER = null;
|
|
235
|
+
|
|
236
|
+
function setSanitizer(fn) {
|
|
237
|
+
SANITIZER = (typeof fn === 'function') ? fn : null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function sanitizeHtml(html, perCall) {
|
|
241
|
+
var fn = (typeof perCall === 'function') ? perCall : SANITIZER;
|
|
242
|
+
return fn ? String(fn(String(html))) : String(html);
|
|
243
|
+
}
|
|
244
|
+
|
|
233
245
|
function positionArrow(box, trigger) {
|
|
234
246
|
var arrow = box.querySelector('.popover__arrow');
|
|
235
247
|
if (!arrow) return;
|
|
@@ -256,5 +268,6 @@ closeAll: function () { if (current) current.close(); },
|
|
|
256
268
|
get current() { return current; },
|
|
257
269
|
};
|
|
258
270
|
|
|
271
|
+
Popover.setSanitizer = setSanitizer;
|
|
259
272
|
global.Popover = Popover;
|
|
260
273
|
})(typeof window !== 'undefined' ? window : globalThis);
|
|
@@ -213,6 +213,26 @@ return true;
|
|
|
213
213
|
var uid = 0;
|
|
214
214
|
|
|
215
215
|
function create(root, opt) {
|
|
216
|
+
|
|
217
|
+
var DEFAULT_LABELS = {
|
|
218
|
+
option: '选项',
|
|
219
|
+
placeholder: '请选择'
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
var flLabels = function (defaults, src) {
|
|
223
|
+
src = src || {};
|
|
224
|
+
var out = {};
|
|
225
|
+
var k;
|
|
226
|
+
for (k in defaults) {
|
|
227
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
228
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return out;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
235
|
+
|
|
216
236
|
opt = opt || {};
|
|
217
237
|
var btn = root.querySelector('[data-select-btn]');
|
|
218
238
|
var list = root.querySelector('[data-select-list]');
|
|
@@ -253,7 +273,7 @@ seed(opt.value);
|
|
|
253
273
|
|
|
254
274
|
list.setAttribute('role', 'listbox');
|
|
255
275
|
if (isMulti) list.setAttribute('aria-multiselectable', 'true');
|
|
256
|
-
list.setAttribute('aria-label', opt.label ||
|
|
276
|
+
list.setAttribute('aria-label', opt.label || L.option);
|
|
257
277
|
btn.setAttribute('aria-haspopup', 'listbox');
|
|
258
278
|
btn.setAttribute('aria-expanded', 'false');
|
|
259
279
|
btn.setAttribute('aria-controls', list.id);
|
|
@@ -293,7 +313,7 @@ var texts = [];
|
|
|
293
313
|
for (var i = 0; i < options.length; i++) {
|
|
294
314
|
if (hasValue(valueOfOpt(options[i]))) texts.push(optText(options[i]));
|
|
295
315
|
}
|
|
296
|
-
return texts.length ? texts.join('、') : (opt.placeholder ||
|
|
316
|
+
return texts.length ? texts.join('、') : (opt.placeholder || L.placeholder);
|
|
297
317
|
}
|
|
298
318
|
|
|
299
319
|
function optText(o) {
|
|
@@ -32,7 +32,38 @@ error: 'M8 1.7a6.3 6.3 0 1 0 0 12.6A6.3 6.3 0 0 0 8 1.7zM8 4.9v3.4M8 11.1v.5',
|
|
|
32
32
|
remove: 'M4.2 4.2l7.6 7.6M11.8 4.2l-7.6 7.6'
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
var
|
|
35
|
+
var DEFAULT_LABELS = {
|
|
36
|
+
pending: '待上传',
|
|
37
|
+
done: '已完成',
|
|
38
|
+
error: '失败',
|
|
39
|
+
remove: function (name) { return '移除 ' + name; },
|
|
40
|
+
uploading: function (pct) { return '上传中 ' + Math.round(pct) + '%'; },
|
|
41
|
+
countMax: function (n) { return '最多 ' + n + ' 个文件'; },
|
|
42
|
+
sizeMax: function (limit) { return '超过 ' + limit; },
|
|
43
|
+
type: '类型不支持',
|
|
44
|
+
folder: '请拖入文件,不支持文件夹',
|
|
45
|
+
none: function (reason) { return reason ? '未添加任何文件:' + reason : '未添加任何文件'; },
|
|
46
|
+
noDrop: '当前浏览器不支持拖放,请点「选择文件」',
|
|
47
|
+
noDropShort: '当前浏览器不支持拖放,请点选择文件',
|
|
48
|
+
summary: function (added, total, rejected) {
|
|
49
|
+
var s = '已添加 ' + added + ' 个文件,共 ' + total + ' 个';
|
|
50
|
+
if (rejected) s += ';' + rejected + ' 个未通过校验';
|
|
51
|
+
return s;
|
|
52
|
+
},
|
|
53
|
+
removed: function (name, rest) { return '已移除 ' + name + ',还剩 ' + rest + ' 个'; }
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
var flLabels = function (defaults, src) {
|
|
57
|
+
src = src || {};
|
|
58
|
+
var out = {};
|
|
59
|
+
var k;
|
|
60
|
+
for (k in defaults) {
|
|
61
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
62
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
};
|
|
36
67
|
|
|
37
68
|
function humanSize(n) {
|
|
38
69
|
if (typeof n !== 'number' || n < 0) return '';
|
|
@@ -110,6 +141,7 @@ function Upload(root, opts) {
|
|
|
110
141
|
var opt = opts || {};
|
|
111
142
|
|
|
112
143
|
this.root = root;
|
|
144
|
+
this.labels = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
113
145
|
this.input = root.querySelector('.upload__input');
|
|
114
146
|
this.list = root.querySelector('.upload__list');
|
|
115
147
|
this.status = root.querySelector('.upload__status');
|
|
@@ -209,15 +241,15 @@ var accept = this.input.getAttribute('accept');
|
|
|
209
241
|
for (var i = 0; i < incoming.length; i++) {
|
|
210
242
|
var f = incoming[i];
|
|
211
243
|
if (maxFiles && keep.length >= maxFiles) {
|
|
212
|
-
rejected.push({ file: f, reason: 'count', text:
|
|
244
|
+
rejected.push({ file: f, reason: 'count', text: this.labels.countMax(maxFiles) });
|
|
213
245
|
continue;
|
|
214
246
|
}
|
|
215
247
|
if (this.maxSize && f.size > this.maxSize) {
|
|
216
|
-
rejected.push({ file: f, reason: 'size', text:
|
|
248
|
+
rejected.push({ file: f, reason: 'size', text: this.labels.sizeMax(humanSize(this.maxSize)) });
|
|
217
249
|
continue;
|
|
218
250
|
}
|
|
219
251
|
if (!matchesAccept(f, accept)) {
|
|
220
|
-
rejected.push({ file: f, reason: 'type', text:
|
|
252
|
+
rejected.push({ file: f, reason: 'type', text: this.labels.type });
|
|
221
253
|
continue;
|
|
222
254
|
}
|
|
223
255
|
keep.push(f);
|
|
@@ -231,7 +263,7 @@ var r = this._validate(incoming);
|
|
|
231
263
|
if (dirCount) {
|
|
232
264
|
r.rejected.push({
|
|
233
265
|
file: { name: dirCount + ' 个文件夹', size: 0 },
|
|
234
|
-
reason: 'dir', text:
|
|
266
|
+
reason: 'dir', text: this.labels.folder
|
|
235
267
|
});
|
|
236
268
|
}
|
|
237
269
|
|
|
@@ -239,7 +271,7 @@ if (!r.keep.length) {
|
|
|
239
271
|
|
|
240
272
|
this.rejected = r.rejected;
|
|
241
273
|
this.render();
|
|
242
|
-
this.announce(r.rejected.length ?
|
|
274
|
+
this.announce(this.labels.none(r.rejected.length ? r.rejected[0].text : ''));
|
|
243
275
|
flEmit(this.root, 'fl-upload', {
|
|
244
276
|
files: currentFiles(this.input), added: 0, rejected: r.rejected
|
|
245
277
|
});
|
|
@@ -249,9 +281,9 @@ return false;
|
|
|
249
281
|
if (!writeFiles(this.input, r.keep)) {
|
|
250
282
|
|
|
251
283
|
this.rejected = [{ file: r.keep[0], reason: 'unsupported',
|
|
252
|
-
text:
|
|
284
|
+
text: this.labels.noDrop }];
|
|
253
285
|
this.render();
|
|
254
|
-
this.announce(
|
|
286
|
+
this.announce(this.labels.noDropShort);
|
|
255
287
|
return false;
|
|
256
288
|
}
|
|
257
289
|
|
|
@@ -317,7 +349,7 @@ mark.appendChild(iconEl(state === 'done' ? 'done' : state === 'error' ? 'error'
|
|
|
317
349
|
|
|
318
350
|
var sr = document.createElement('span');
|
|
319
351
|
sr.className = 'upload__status';
|
|
320
|
-
sr.textContent =
|
|
352
|
+
sr.textContent = this.labels[state] || '';
|
|
321
353
|
mark.appendChild(sr);
|
|
322
354
|
|
|
323
355
|
var name = document.createElement('span');
|
|
@@ -346,12 +378,12 @@ this.paintProgress(bar0, pct);
|
|
|
346
378
|
var rm = document.createElement('button');
|
|
347
379
|
rm.className = 'upload__remove';
|
|
348
380
|
rm.type = 'button';
|
|
349
|
-
rm.setAttribute('aria-label',
|
|
381
|
+
rm.setAttribute('aria-label', this.labels.remove(file.name || ''));
|
|
350
382
|
rm.appendChild(iconEl('remove'));
|
|
351
383
|
rm.addEventListener('click', function () { self.removeAt(index); });
|
|
352
384
|
li.appendChild(rm);
|
|
353
385
|
|
|
354
|
-
if (pct != null && pct >= 0) meta.textContent =
|
|
386
|
+
if (pct != null && pct >= 0) meta.textContent = self.labels.uploading(pct);
|
|
355
387
|
}
|
|
356
388
|
|
|
357
389
|
return li;
|
|
@@ -396,7 +428,7 @@ mark.innerHTML = '';
|
|
|
396
428
|
mark.appendChild(iconEl('done'));
|
|
397
429
|
var sr = document.createElement('span');
|
|
398
430
|
sr.className = 'upload__status';
|
|
399
|
-
sr.textContent =
|
|
431
|
+
sr.textContent = this.labels.done;
|
|
400
432
|
mark.appendChild(sr);
|
|
401
433
|
}
|
|
402
434
|
if (meta && f) meta.textContent = humanSize(f.size);
|
|
@@ -417,7 +449,7 @@ li.insertBefore(bar, rmBtn || null);
|
|
|
417
449
|
}
|
|
418
450
|
this.paintProgress(bar, pct);
|
|
419
451
|
|
|
420
|
-
if (meta) meta.textContent =
|
|
452
|
+
if (meta) meta.textContent = this.labels.uploading(pct);
|
|
421
453
|
},
|
|
422
454
|
|
|
423
455
|
removeAt: function (i) {
|
|
@@ -435,7 +467,7 @@ if (li && li.parentNode) li.parentNode.removeChild(li);
|
|
|
435
467
|
|
|
436
468
|
this.rebind();
|
|
437
469
|
this.syncCount();
|
|
438
|
-
this.announce(
|
|
470
|
+
this.announce(this.labels.removed(removed.name || '文件', rest.length));
|
|
439
471
|
flEmit(this.root, 'fl-upload', {
|
|
440
472
|
files: rest, added: 0, removed: removed, rejected: []
|
|
441
473
|
});
|
|
@@ -467,9 +499,7 @@ this._announceTimer = global.setTimeout(function () { el.textContent = msg; }, 6
|
|
|
467
499
|
|
|
468
500
|
summary: function (added, rejected) {
|
|
469
501
|
var total = currentFiles(this.input).length;
|
|
470
|
-
|
|
471
|
-
if (rejected) s += ';' + rejected + ' 个未通过校验';
|
|
472
|
-
return s;
|
|
502
|
+
return this.labels.summary(added, total, rejected);
|
|
473
503
|
},
|
|
474
504
|
|
|
475
505
|
destroy: function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.prose {max-width:var(--measure-prose);color:var(--text-primary);}.prose > * + * {margin-top:var(--sp-4);}.prose > h1, .prose > h2, .prose > h3, .prose > h4, .prose > h5, .prose > h6 {font-family:var(--sans);font-weight:500;line-height:var(--lh-tight);letter-spacing:-0.008em;margin:var(--sp-7) 0 0;}.prose > h1 {font-size:var(--fs-2xl);margin-top:0;}.prose > h2 {font-size:var(--fs-lg);padding-top:var(--sp-5);border-top:2px solid var(--accent);max-width:92%;}.prose > h3 {font-size:var(--fs-md);}.prose > h4, .prose > h5, .prose > h6 {font-size:var(--fs-base);color:var(--text-secondary);}.prose > p {margin:0;line-height:1.75;}.prose > code, .prose > li > code, .prose > td > code, .prose > th > code {font-family:var(--mono);font-size:0.88em;background:var(--surface-sunken);border:1px solid var(--border-decor);border-radius:3px;padding:0.05em 0.3em;}.prose > pre > code, .prose > pre {font-family:inherit;font-size:inherit;background:none;border:none;padding:0;border-radius:0;}.prose > ul, .prose > ol {padding-inline-start:1.5em;margin:0;}.prose > ul {list-style:disc;}.prose > ol {list-style:decimal;}.prose li + li {margin-top:var(--sp-2);}.prose li > ul, .prose li > ol {margin-top:var(--sp-2);}.prose li > ul {list-style:circle;}.prose > blockquote {margin:var(--sp-5) 0;padding:0 0 0 var(--sp-4);border-inline-start:3px solid var(--accent);}.prose > blockquote > p {color:var(--text-secondary);font-size:var(--fs-md);line-height:1.6;}.prose > blockquote > blockquote {margin:var(--sp-3) 0;}.prose > pre {margin:0;padding:var(--sp-4);background:var(--surface-sunken);border-inline-start:3px solid var(--border-decor-str);border-radius:0 var(--r-sm) var(--r-sm) 0;overflow-x:auto;font-family:var(--mono);font-size:var(--fs-xs);line-height:1.6;tab-size:4;-webkit-overflow-scrolling:touch;}.prose > pre:not([class]) {border-inline-start-color:var(--border-decor);}.prose > table {width:100%;border-collapse:collapse;table-layout:auto;font-size:var(--fs-sm);}.prose > table th, .prose > table td {text-align:start;padding:var(--sp-2) var(--sp-4) var(--sp-2) 0;border-bottom:1px solid var(--border-decor);vertical-align:top;}.prose > table th {font-weight:500;font-size:var(--fs-xs);color:var(--text-secondary);}.prose > table tbody tr:last-child td {border-bottom:1px solid var(--border-decor-str);}.prose > hr {margin:var(--sp-7) 0;border:0;border-top:1px solid var(--border-decor);height:0;}.prose
|
|
1
|
+
.prose {max-width:var(--measure-prose);color:var(--text-primary);}.prose > * + * {margin-top:var(--sp-4);}.prose > h1, .prose > h2, .prose > h3, .prose > h4, .prose > h5, .prose > h6 {font-family:var(--sans);font-weight:500;line-height:var(--lh-tight);letter-spacing:-0.008em;margin:var(--sp-7) 0 0;}.prose > h1 {font-size:var(--fs-2xl);margin-top:0;}.prose > h2 {font-size:var(--fs-lg);padding-top:var(--sp-5);border-top:2px solid var(--accent);max-width:92%;}.prose > h3 {font-size:var(--fs-md);}.prose > h4, .prose > h5, .prose > h6 {font-size:var(--fs-base);color:var(--text-secondary);}.prose > p {margin:0;line-height:1.75;}.prose > code, .prose > li > code, .prose > td > code, .prose > th > code {font-family:var(--mono);font-size:0.88em;background:var(--surface-sunken);border:1px solid var(--border-decor);border-radius:3px;padding:0.05em 0.3em;}.prose > pre > code, .prose > pre {font-family:inherit;font-size:inherit;background:none;border:none;padding:0;border-radius:0;}.prose > ul, .prose > ol {padding-inline-start:1.5em;margin:0;}.prose > ul {list-style:disc;}.prose > ol {list-style:decimal;}.prose li + li {margin-top:var(--sp-2);}.prose li > ul, .prose li > ol {margin-top:var(--sp-2);}.prose li > ul {list-style:circle;}.prose > blockquote {margin:var(--sp-5) 0;padding:0 0 0 var(--sp-4);border-inline-start:3px solid var(--accent);}.prose > blockquote > p {color:var(--text-secondary);font-size:var(--fs-md);line-height:1.6;}.prose > blockquote > blockquote {margin:var(--sp-3) 0;}.prose > pre {margin:0;padding:var(--sp-4);background:var(--surface-sunken);border-inline-start:3px solid var(--border-decor-str);border-radius:0 var(--r-sm) var(--r-sm) 0;overflow-x:auto;font-family:var(--mono);font-size:var(--fs-xs);line-height:1.6;tab-size:4;-webkit-overflow-scrolling:touch;}.prose > pre:not([class]) {border-inline-start-color:var(--border-decor);}.prose > table {width:100%;border-collapse:collapse;table-layout:auto;font-size:var(--fs-sm);}.prose > table th, .prose > table td {text-align:start;padding:var(--sp-2) var(--sp-4) var(--sp-2) 0;border-bottom:1px solid var(--border-decor);vertical-align:top;}.prose > table th {font-weight:500;font-size:var(--fs-xs);color:var(--text-secondary);}.prose > table tbody tr:last-child td {border-bottom:1px solid var(--border-decor-str);}.prose > hr {margin:var(--sp-7) 0;border:0;border-top:1px solid var(--border-decor);height:0;}.prose img {max-width:100%;height:auto;display:block;border-radius:var(--r-sm);}.prose a {color:var(--accent);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;}@media (hover:hover) and (pointer:fine) {.prose a:hover {color:var(--text-primary);}}.prose a:focus-visible {outline:2px solid var(--accent);outline-offset:2px;}.prose > a[target="_blank"]::after {content:" ↗";font-size:0.8em;vertical-align:0.1em;}.prose > del, .prose > s, .prose > li > del, .prose > li > s {color:var(--text-tertiary);}.prose .task-list-item {list-style:none;margin-inline-start:-1.5em;}.prose .task-list-item input[type="checkbox"] {margin-inline-end:var(--sp-2);vertical-align:middle;}.prose .task-list-item input[disabled] {accent-color:var(--accent);}.prose :focus-visible {outline:2px solid var(--accent);outline-offset:2px;}.prose a:visited {color:var(--accent);text-decoration:underline;text-underline-offset:2px;}
|
|
@@ -171,8 +171,34 @@ top: 'drawer--top',
|
|
|
171
171
|
bottom: 'drawer--bottom'
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
+
var SANITIZER = null;
|
|
175
|
+
|
|
176
|
+
function setSanitizer(fn) {
|
|
177
|
+
SANITIZER = (typeof fn === 'function') ? fn : null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function sanitizeHtml(html, perCall) {
|
|
181
|
+
var fn = (typeof perCall === 'function') ? perCall : SANITIZER;
|
|
182
|
+
return fn ? String(fn(String(html))) : String(html);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
var DEFAULT_LABELS = { dialog: '抽屉', close: '关闭' };
|
|
186
|
+
|
|
187
|
+
var flLabels = function (defaults, src) {
|
|
188
|
+
src = src || {};
|
|
189
|
+
var out = {};
|
|
190
|
+
var k;
|
|
191
|
+
for (k in defaults) {
|
|
192
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
193
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
};
|
|
198
|
+
|
|
174
199
|
function open(opt) {
|
|
175
200
|
opt = opt || {};
|
|
201
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
176
202
|
var place = opt.place || 'right';
|
|
177
203
|
var placeCls = PLACE_CLASS[place];
|
|
178
204
|
if (!placeCls) placeCls = PLACE_CLASS.right;
|
|
@@ -191,7 +217,7 @@ d.setAttribute('role', 'dialog');
|
|
|
191
217
|
d.setAttribute('aria-modal', 'true');
|
|
192
218
|
if (!d.id) d.id = 'drawer-' + (new Date()).getTime();
|
|
193
219
|
if (opt.title) d.setAttribute('aria-labelledby', d.id + '-title');
|
|
194
|
-
else d.setAttribute('aria-label', opt.label ||
|
|
220
|
+
else d.setAttribute('aria-label', opt.label || L.dialog);
|
|
195
221
|
d.tabIndex = -1;
|
|
196
222
|
|
|
197
223
|
var head = document.createElement('div');
|
|
@@ -203,15 +229,17 @@ h.textContent = opt.title || '';
|
|
|
203
229
|
var closeBtn = document.createElement('button');
|
|
204
230
|
closeBtn.className = 'drawer__close';
|
|
205
231
|
closeBtn.type = 'button';
|
|
206
|
-
closeBtn.setAttribute('aria-label',
|
|
232
|
+
closeBtn.setAttribute('aria-label', L.close);
|
|
207
233
|
closeBtn.textContent = '\u00D7';
|
|
208
234
|
head.appendChild(h);
|
|
209
235
|
head.appendChild(closeBtn);
|
|
210
236
|
|
|
211
237
|
var body = document.createElement('div');
|
|
212
238
|
body.className = 'drawer__body';
|
|
239
|
+
if (typeof opt.content === 'string') {
|
|
213
240
|
|
|
214
|
-
|
|
241
|
+
body.innerHTML = sanitizeHtml(opt.content, opt.sanitize);
|
|
242
|
+
}
|
|
215
243
|
else if (opt.content) body.appendChild(opt.content);
|
|
216
244
|
|
|
217
245
|
d.appendChild(head);
|
|
@@ -311,5 +339,5 @@ if (opt.onClose) opt.onClose();
|
|
|
311
339
|
return { el: d, close: close };
|
|
312
340
|
}
|
|
313
341
|
|
|
314
|
-
global.Drawer = { open: open };
|
|
342
|
+
global.Drawer = { open: open, setSanitizer: setSanitizer };
|
|
315
343
|
})(typeof window !== 'undefined' ? window : globalThis);
|