agentcss 0.25.6 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/01-tokens/README.md +1 -1
- package/01-tokens/behavior/labels.js +44 -0
- package/01-tokens/responsive-demo.html +1 -1
- package/01-tokens/tokens.core.css +1 -1
- package/01-tokens/tokens.css +2 -2
- package/02-primitives/combobox/combobox.js +26 -3
- package/02-primitives/date-range/date-range.js +28 -6
- package/02-primitives/popover/popover.js +22 -2
- package/02-primitives/select/select.js +23 -2
- package/02-primitives/timeline/demo.html +1 -1
- 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/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.css +1 -1
- package/03-patterns/overlay/overlay.js +39 -2
- package/03-patterns/pagination/pagination.js +37 -10
- package/03-patterns/states/states.css +1 -1
- 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/app-shell/README.md +1 -1
- package/04-recipes/app-shell/demo.html +1 -1
- package/04-recipes/data-showcase/demo.html +2 -2
- package/04-recipes/longform/content.html +993 -78
- package/04-recipes/longform/longform.html +3 -3
- package/04-recipes/report/demo.html +3 -3
- package/04-recipes/table/README.md +23 -1
- package/04-recipes/table/demo.html +7 -7
- package/09-assets/bar/bar.css +1 -1
- package/09-assets/bar/bar.js +28 -4
- package/09-assets/model-viewer/model-viewer.js +45 -13
- package/09-assets/scientific-plot/demo.html +6 -6
- package/AGENTS.md +3 -1
- package/API.md +32 -0
- package/CHANGELOG.md +174 -5
- package/CONTRIBUTING.md +44 -3
- package/README.md +19 -0
- package/README.zh-CN.md +18 -0
- package/SECURITY.md +16 -4
- package/START-HERE.md +25 -18
- package/ai/START-HERE.md +40 -6
- package/ai/check-html.js +658 -0
- package/ai/cli.js +557 -67
- package/ai/components.json +9 -4
- package/ai/pdf.js +52 -10
- package/ai/recipes.json +86 -0
- package/ai/scaffold.js +195 -0
- package/ai/shot.js +345 -0
- package/ai/validate.js +65 -6
- 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 +20 -20
- package/docs/ACCESSIBILITY.md +3 -3
- package/docs/ARCHITECTURE.md +116 -0
- package/docs/L10N.md +92 -0
- package/docs/LAYER-BASELINE.md +2 -2
- package/docs/PRINT.md +3 -3
- package/docs/RELEASE-PROCESS.md +59 -3
- package/docs/STABILITY.md +1 -1
- package/docs/VERIFY-RELEASE.md +24 -2
- package/index.html +3 -3
- package/llms-full.txt +18 -4
- package/llms.txt +26 -5
- package/package.json +4 -2
- package/types/index.d.ts +218 -13
|
@@ -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);
|
|
@@ -295,6 +295,25 @@ return Array.prototype.slice.call(menu.querySelectorAll(FOCUSABLE));
|
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
function create(root, opt) {
|
|
298
|
+
|
|
299
|
+
var DEFAULT_LABELS = {
|
|
300
|
+
menu: '菜单'
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
var flLabels = function (defaults, src) {
|
|
304
|
+
src = src || {};
|
|
305
|
+
var out = {};
|
|
306
|
+
var k;
|
|
307
|
+
for (k in defaults) {
|
|
308
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
309
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
316
|
+
|
|
298
317
|
opt = opt || {};
|
|
299
318
|
var btn = root.querySelector('[data-dd-btn]') || root.querySelector('button');
|
|
300
319
|
var menu = root.querySelector('[data-dd-menu]');
|
|
@@ -305,7 +324,7 @@ var active = -1;
|
|
|
305
324
|
|
|
306
325
|
menu.setAttribute('role', 'menu');
|
|
307
326
|
if (!menu.getAttribute('aria-label') && !menu.getAttribute('aria-labelledby')) {
|
|
308
|
-
menu.setAttribute('aria-label', opt.label ||
|
|
327
|
+
menu.setAttribute('aria-label', opt.label || L.menu);
|
|
309
328
|
}
|
|
310
329
|
Array.prototype.forEach.call(menu.querySelectorAll('li'), function (li) {
|
|
311
330
|
|
|
@@ -156,8 +156,27 @@ error: 'toast--error',
|
|
|
156
156
|
warning: 'toast--warning'
|
|
157
157
|
};
|
|
158
158
|
|
|
159
|
+
var DEFAULT_LABELS = {
|
|
160
|
+
closeToast: '关闭提示'
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
var flLabels = function (defaults, src) {
|
|
164
|
+
src = src || {};
|
|
165
|
+
var out = {};
|
|
166
|
+
var k;
|
|
167
|
+
for (k in defaults) {
|
|
168
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
169
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return out;
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
var TOAST_LIMIT = 4;
|
|
176
|
+
|
|
159
177
|
function toast(opts) {
|
|
160
178
|
opts = opts || {};
|
|
179
|
+
var L = flLabels(DEFAULT_LABELS, opts && opts.labels);
|
|
161
180
|
|
|
162
181
|
var region = document.querySelector('.toast-region');
|
|
163
182
|
if (!region) {
|
|
@@ -203,7 +222,7 @@ el.appendChild(timer);
|
|
|
203
222
|
var closeBtn = document.createElement('button');
|
|
204
223
|
closeBtn.className = 'toast__close';
|
|
205
224
|
closeBtn.type = 'button';
|
|
206
|
-
closeBtn.setAttribute('aria-label',
|
|
225
|
+
closeBtn.setAttribute('aria-label', L.closeToast);
|
|
207
226
|
closeBtn.textContent = '×';
|
|
208
227
|
el.appendChild(closeBtn);
|
|
209
228
|
|
|
@@ -220,6 +239,11 @@ if (el.parentNode) el.parentNode.removeChild(el);
|
|
|
220
239
|
}
|
|
221
240
|
|
|
222
241
|
closeBtn.addEventListener('click', close);
|
|
242
|
+
|
|
243
|
+
var max = (opts.maxVisible === undefined) ? TOAST_LIMIT : opts.maxVisible;
|
|
244
|
+
while (max > 0 && region.children.length >= max) {
|
|
245
|
+
region.removeChild(region.firstChild);
|
|
246
|
+
}
|
|
223
247
|
region.appendChild(el);
|
|
224
248
|
|
|
225
249
|
var timerId = auto > 0 ? setTimeout(close, auto) : null;
|
|
@@ -61,12 +61,36 @@ if (total > 1) out.push(total);
|
|
|
61
61
|
return out;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
var DEFAULT_LABELS = {
|
|
65
|
+
nav: '分页',
|
|
66
|
+
prev: '上一页',
|
|
67
|
+
next: '下一页',
|
|
68
|
+
page: function (p, isCurrent) {
|
|
69
|
+
return '第 ' + p + ' 页' + (isCurrent ? '(当前页)' : '');
|
|
70
|
+
},
|
|
71
|
+
status: function (page, pages) { return '第 ' + page + ' 页 / 共 ' + pages + ' 页'; },
|
|
72
|
+
live: function (page, pages) { return '第 ' + page + ' 页,共 ' + pages + ' 页'; }
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
var flLabels = function (defaults, src) {
|
|
76
|
+
src = src || {};
|
|
77
|
+
var out = {};
|
|
78
|
+
var k;
|
|
79
|
+
for (k in defaults) {
|
|
80
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
81
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return out;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function Pagination(node, opts) {
|
|
65
88
|
this.node = node;
|
|
89
|
+
this.labels = flLabels(DEFAULT_LABELS, opts && opts.labels);
|
|
66
90
|
this.total = Math.max(1, parseInt(node.getAttribute('data-total') || '1', 10));
|
|
67
91
|
this.size = Math.max(1, parseInt(node.getAttribute('data-page-size') || '20', 10));
|
|
68
92
|
this.page = Math.max(1, parseInt(node.getAttribute('data-page') || '1', 10));
|
|
69
|
-
this.label = node.getAttribute('aria-label') ||
|
|
93
|
+
this.label = node.getAttribute('aria-label') || this.labels.nav;
|
|
70
94
|
this.pages = Math.max(1, Math.ceil(this.total / this.size));
|
|
71
95
|
this.onChange = null;
|
|
72
96
|
|
|
@@ -186,7 +210,7 @@ if (cur && cur.focus) cur.focus();
|
|
|
186
210
|
|
|
187
211
|
Pagination.prototype.announce = function () {
|
|
188
212
|
if (!this.liveNode) return;
|
|
189
|
-
this.liveNode.textContent =
|
|
213
|
+
this.liveNode.textContent = this.labels.live(this.page, this.pages);
|
|
190
214
|
};
|
|
191
215
|
|
|
192
216
|
Pagination.prototype.render = function () {
|
|
@@ -194,6 +218,7 @@ if (!this.listNode) return;
|
|
|
194
218
|
var L = this.listNode;
|
|
195
219
|
while (L.firstChild) L.removeChild(L.firstChild);
|
|
196
220
|
var self = this;
|
|
221
|
+
var T = this.labels;
|
|
197
222
|
|
|
198
223
|
function addBtn(text, ariaLabel, goto, disabled) {
|
|
199
224
|
var li = el('li', 'pagination__item');
|
|
@@ -208,7 +233,7 @@ L.appendChild(li);
|
|
|
208
233
|
return b;
|
|
209
234
|
}
|
|
210
235
|
|
|
211
|
-
addBtn('‹',
|
|
236
|
+
addBtn('‹', T.prev, 'prev', self.page <= 1);
|
|
212
237
|
|
|
213
238
|
var win = pageWindow(self.page, self.pages, SLOTS);
|
|
214
239
|
for (var i = 0; i < win.length; i++) {
|
|
@@ -227,7 +252,7 @@ var li2 = el('li', 'pagination__item');
|
|
|
227
252
|
var b2 = el('button', 'pagination__link', String(p));
|
|
228
253
|
b2.type = 'button';
|
|
229
254
|
b2.setAttribute('data-goto', String(p));
|
|
230
|
-
b2.setAttribute('aria-label',
|
|
255
|
+
b2.setAttribute('aria-label', T.page(p, isCur));
|
|
231
256
|
if (isCur) {
|
|
232
257
|
b2.setAttribute('aria-current', 'page');
|
|
233
258
|
b2.setAttribute('aria-disabled', 'true');
|
|
@@ -236,20 +261,19 @@ li2.appendChild(b2);
|
|
|
236
261
|
L.appendChild(li2);
|
|
237
262
|
}
|
|
238
263
|
|
|
239
|
-
addBtn('›',
|
|
264
|
+
addBtn('›', T.next, 'next', self.page >= self.pages);
|
|
240
265
|
|
|
241
266
|
if (this.statusNode) {
|
|
242
|
-
this.statusNode.textContent =
|
|
243
|
-
'第 '+ self.page + ' 页 / 共 ' + self.pages + ' 页';
|
|
267
|
+
this.statusNode.textContent = T.status(self.page, self.pages);
|
|
244
268
|
}
|
|
245
269
|
};
|
|
246
270
|
|
|
247
271
|
var API = {
|
|
248
272
|
|
|
249
|
-
create: function (node) {
|
|
273
|
+
create: function (node, opts) {
|
|
250
274
|
if (!node) return null;
|
|
251
275
|
if (node.__pg) return node.__pg;
|
|
252
|
-
node.__pg = new Pagination(node);
|
|
276
|
+
node.__pg = new Pagination(node, opts);
|
|
253
277
|
return node.__pg;
|
|
254
278
|
},
|
|
255
279
|
|
|
@@ -99,6 +99,18 @@ if (k >= 0) shared.stack.splice(k, 1);
|
|
|
99
99
|
|
|
100
100
|
var uid = 0;
|
|
101
101
|
|
|
102
|
+
var LABELS = { region: '组件提示' };
|
|
103
|
+
|
|
104
|
+
function setLabels(patch) {
|
|
105
|
+
if (!patch) return;
|
|
106
|
+
for (var k in LABELS) {
|
|
107
|
+
if (Object.prototype.hasOwnProperty.call(LABELS, k)
|
|
108
|
+
&& patch[k] !== undefined && patch[k] !== null) {
|
|
109
|
+
LABELS[k] = patch[k];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
102
114
|
function ensureStyle() {
|
|
103
115
|
if (document.getElementById('tooltip-css')) return;
|
|
104
116
|
|
|
@@ -115,7 +127,7 @@ r.setAttribute('role', 'tooltip');
|
|
|
115
127
|
r.setAttribute('aria-live', 'polite');
|
|
116
128
|
r.setAttribute('aria-atomic', 'true');
|
|
117
129
|
|
|
118
|
-
r.setAttribute('aria-label',
|
|
130
|
+
r.setAttribute('aria-label', LABELS.region);
|
|
119
131
|
r.style.cssText =
|
|
120
132
|
'position:absolute;width:1px;height:1px;padding:0;margin:-1px;'+
|
|
121
133
|
'overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0';
|
|
@@ -211,5 +223,5 @@ el.setAttribute('aria-describedby', cur ? (cur + ' ' + id) : id);
|
|
|
211
223
|
el.setAttribute('data-tooltip', text);
|
|
212
224
|
}
|
|
213
225
|
|
|
214
|
-
global.Tooltip = { attach: attach };
|
|
226
|
+
global.Tooltip = { attach: attach, setLabels: setLabels };
|
|
215
227
|
})(typeof window !== 'undefined' ? window : globalThis);
|
|
@@ -196,11 +196,30 @@ return true;
|
|
|
196
196
|
var uid = 0;
|
|
197
197
|
|
|
198
198
|
function create(root, opt) {
|
|
199
|
+
|
|
200
|
+
var DEFAULT_LABELS = {
|
|
201
|
+
tree: '树形视图'
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
var flLabels = function (defaults, src) {
|
|
205
|
+
src = src || {};
|
|
206
|
+
var out = {};
|
|
207
|
+
var k;
|
|
208
|
+
for (k in defaults) {
|
|
209
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
210
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
var L = flLabels(DEFAULT_LABELS, opt && opt.labels);
|
|
217
|
+
|
|
199
218
|
opt = opt || {};
|
|
200
219
|
root.classList.add('tree');
|
|
201
220
|
if (!root.getAttribute('role')) root.setAttribute('role', 'tree');
|
|
202
221
|
if (!root.getAttribute('aria-label') && !root.getAttribute('aria-labelledby')) {
|
|
203
|
-
root.setAttribute('aria-label', opt.label ||
|
|
222
|
+
root.setAttribute('aria-label', opt.label || L.tree);
|
|
204
223
|
}
|
|
205
224
|
|
|
206
225
|
var items = [];
|
|
@@ -27,9 +27,30 @@ e.setAttribute(k, String(attrs[k]));
|
|
|
27
27
|
return e;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
var DEFAULT_TEXT = {
|
|
31
|
+
series: function (i) { return '系列 ' + i; },
|
|
32
|
+
clipped: function (n, isStack, max) {
|
|
33
|
+
return '有 ' + n + ' 个' + (isStack ? '类目的合计' : '数据')
|
|
34
|
+
+ '超出量程(上限 ' + max + '),已按上限截断显示。';
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
var flLabels = function (defaults, src) {
|
|
39
|
+
src = src || {};
|
|
40
|
+
var out = {};
|
|
41
|
+
var k;
|
|
42
|
+
for (k in defaults) {
|
|
43
|
+
if (Object.prototype.hasOwnProperty.call(defaults, k)) {
|
|
44
|
+
out[k] = (src[k] === undefined || src[k] === null) ? defaults[k] : src[k];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
};
|
|
49
|
+
|
|
30
50
|
function draw(opt) {
|
|
31
51
|
opt = opt || {};
|
|
32
52
|
var host = opt.host;
|
|
53
|
+
var T = flLabels(DEFAULT_TEXT, opt && opt.text);
|
|
33
54
|
if (!host) throw new Error('bar.draw: 缺少 host');
|
|
34
55
|
if (opt.max === undefined || opt.max === null) {
|
|
35
56
|
|
|
@@ -187,7 +208,7 @@ sw.className = 'bar__legend-swatch ' + SERIES_CLS[si % SERIES_STYLES] +
|
|
|
187
208
|
|
|
188
209
|
li.appendChild(sw);
|
|
189
210
|
var tx = document.createElement('span');
|
|
190
|
-
tx.textContent = se.name || (
|
|
211
|
+
tx.textContent = se.name || T.series(si + 1);
|
|
191
212
|
li.appendChild(tx);
|
|
192
213
|
legendEl.appendChild(li);
|
|
193
214
|
});
|
|
@@ -202,9 +223,7 @@ host.appendChild(p);
|
|
|
202
223
|
} else if (clipped.length) {
|
|
203
224
|
var p2 = document.createElement('p');
|
|
204
225
|
p2.className = 'bar__note';
|
|
205
|
-
p2.textContent =
|
|
206
|
-
(mode === 'stack' ? '类目的合计' : '数据') +
|
|
207
|
-
'超出量程(上限 '+ max + '),已按上限截断显示。';
|
|
226
|
+
p2.textContent = T.clipped(clipped.length, mode === 'stack', max);
|
|
208
227
|
host.appendChild(p2);
|
|
209
228
|
}
|
|
210
229
|
|
|
@@ -62,7 +62,7 @@ this.ui = el('div', 'mv__ui');
|
|
|
62
62
|
this.ui.appendChild(this.makeIdle());
|
|
63
63
|
n.appendChild(this.ui);
|
|
64
64
|
|
|
65
|
-
this.btn = el('button', 'mv__btn',
|
|
65
|
+
this.btn = el('button', 'mv__btn', LABELS.load);
|
|
66
66
|
this.btn.type = 'button';
|
|
67
67
|
this.btn.addEventListener('click', function () { self.load(); });
|
|
68
68
|
this.ui.appendChild(this.btn);
|
|
@@ -70,23 +70,23 @@ this.ui.appendChild(this.btn);
|
|
|
70
70
|
this.hint = el('p', 'mv__hint');
|
|
71
71
|
|
|
72
72
|
var fname = el('code', null, this.src.split('/').pop() || '—');
|
|
73
|
-
var strong = el('b', null,
|
|
74
|
-
this.hint.appendChild(document.createTextNode(
|
|
73
|
+
var strong = el('b', null, LABELS.hintStrong);
|
|
74
|
+
this.hint.appendChild(document.createTextNode(LABELS.hintBefore));
|
|
75
75
|
this.hint.appendChild(fname);
|
|
76
|
-
this.hint.appendChild(document.createTextNode(
|
|
76
|
+
this.hint.appendChild(document.createTextNode(LABELS.hintBetween));
|
|
77
77
|
this.hint.appendChild(strong);
|
|
78
|
-
this.hint.appendChild(document.createTextNode(
|
|
78
|
+
this.hint.appendChild(document.createTextNode(LABELS.hintTail));
|
|
79
79
|
this.ui.appendChild(this.hint);
|
|
80
80
|
|
|
81
81
|
if (!hasWebGL()) {
|
|
82
|
-
this.fail(
|
|
82
|
+
this.fail(LABELS.noWebGL);
|
|
83
83
|
this.btn.disabled = true;
|
|
84
84
|
}
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
Viewer.prototype.makeIdle = function () {
|
|
88
88
|
var box = el('div', 'mv__stage');
|
|
89
|
-
box.appendChild(el('div', 'mv__ph',
|
|
89
|
+
box.appendChild(el('div', 'mv__ph', LABELS.placeholder));
|
|
90
90
|
return box;
|
|
91
91
|
};
|
|
92
92
|
|
|
@@ -95,14 +95,14 @@ if (this.timer) { clearTimeout(this.timer); this.timer = null; }
|
|
|
95
95
|
this.state = 'error';
|
|
96
96
|
this.ui.innerHTML = '';
|
|
97
97
|
var s = el('div', 'mv__stage mv__stage--err');
|
|
98
|
-
s.appendChild(el('div', 'mv__ph',
|
|
98
|
+
s.appendChild(el('div', 'mv__ph', LABELS.placeholder));
|
|
99
99
|
var p = el('p', 'mv__err', msg);
|
|
100
100
|
s.appendChild(p);
|
|
101
101
|
this.ui.appendChild(s);
|
|
102
102
|
if (this.btn) this.ui.appendChild(this.btn);
|
|
103
103
|
if (this.btn) {
|
|
104
104
|
this.btn.disabled = false;
|
|
105
|
-
this.btn.textContent =
|
|
105
|
+
this.btn.textContent = LABELS.retry;
|
|
106
106
|
}
|
|
107
107
|
};
|
|
108
108
|
|
|
@@ -117,12 +117,12 @@ this.state = 'loading';
|
|
|
117
117
|
|
|
118
118
|
this.ui.innerHTML = '';
|
|
119
119
|
var stage = el('div', 'mv__stage');
|
|
120
|
-
this.statusNode = el('p', 'mv__status',
|
|
120
|
+
this.statusNode = el('p', 'mv__status', LABELS.preparing);
|
|
121
121
|
stage.appendChild(this.statusNode);
|
|
122
122
|
this.ui.appendChild(stage);
|
|
123
123
|
|
|
124
124
|
var t0 = (window.performance && performance.now) ? performance.now() : Date.now();
|
|
125
|
-
this.status(
|
|
125
|
+
this.status(LABELS.preparingEngine);
|
|
126
126
|
this.boot(null, t0, 0);
|
|
127
127
|
|
|
128
128
|
var self0 = this;
|
|
@@ -205,7 +205,7 @@ xhr.open('GET', this.src, true);
|
|
|
205
205
|
xhr.onprogress = function (e) {
|
|
206
206
|
if (e.lengthComputable && e.total) {
|
|
207
207
|
self1.lastBytes = e.total;
|
|
208
|
-
self1.status(
|
|
208
|
+
self1.status(LABELS.downloading(Math.round(e.loaded / e.total * 100)));
|
|
209
209
|
}
|
|
210
210
|
};
|
|
211
211
|
xhr.onload = function () {
|
|
@@ -292,6 +292,30 @@ self.fail('模型加载失败:' + msg + '。请确认 ' + self.src + ' 已部
|
|
|
292
292
|
}
|
|
293
293
|
};
|
|
294
294
|
|
|
295
|
+
var LABELS = {
|
|
296
|
+
load: '加载 3D 模型',
|
|
297
|
+
placeholder: '3D 模型',
|
|
298
|
+
retry: '重试',
|
|
299
|
+
preparing: '正在准备…',
|
|
300
|
+
preparingEngine: '正在准备 3D 引擎…',
|
|
301
|
+
hintBefore: '模型 ',
|
|
302
|
+
hintBetween: ' 会',
|
|
303
|
+
hintStrong: '点击后才下载',
|
|
304
|
+
hintTail: ',首屏不占流量。',
|
|
305
|
+
downloading: function (pct) { return '正在下载模型 ' + pct + '%'; },
|
|
306
|
+
noWebGL: '这台设备的浏览器不支持 WebGL,无法显示 3D 模型。'
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
function setLabels(patch) {
|
|
310
|
+
if (!patch) return;
|
|
311
|
+
for (var k in LABELS) {
|
|
312
|
+
if (Object.prototype.hasOwnProperty.call(LABELS, k)
|
|
313
|
+
&& patch[k] !== undefined && patch[k] !== null) {
|
|
314
|
+
LABELS[k] = patch[k];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
295
319
|
var ModelViewer = {
|
|
296
320
|
|
|
297
321
|
update: function (root) {
|
|
@@ -317,6 +341,8 @@ list[i].__mv = new Viewer(list[i]);
|
|
|
317
341
|
},
|
|
318
342
|
};
|
|
319
343
|
|
|
344
|
+
ModelViewer.setLabels = setLabels;
|
|
345
|
+
|
|
320
346
|
if (typeof window !== 'undefined') window.ModelViewer = ModelViewer;
|
|
321
347
|
|
|
322
348
|
if (document.readyState === 'loading') {
|