@pageboard/html 0.16.17 → 0.17.1
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/elements/table.js +1 -1
- package/package.json +2 -2
- package/ui/form.css +5 -0
- package/ui/form.js +32 -23
- package/ui/image.js +25 -31
- package/ui/select.js +3 -1
package/elements/table.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pageboard/html",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"homepage": "https://github.com/pageboard/client#readme",
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"nouislider": "^15.8.1",
|
|
18
|
-
"postinstall": "^0.11.
|
|
18
|
+
"postinstall": "^0.11.2"
|
|
19
19
|
},
|
|
20
20
|
"postinstall": {
|
|
21
21
|
"nouislider/dist/nouislider.js": "link lib/",
|
package/ui/form.css
CHANGED
package/ui/form.js
CHANGED
|
@@ -18,16 +18,20 @@ class HTMLElementForm extends Page.create(HTMLFormElement) {
|
|
|
18
18
|
return obj;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
static improveHtmlFor(node) {
|
|
22
|
+
const indexes = {};
|
|
23
|
+
for (const label of node.querySelectorAll('input+label[for^="for-"]')) {
|
|
24
|
+
const { previousElementSibling: input, htmlFor } = label;
|
|
25
|
+
const [pre, name] = htmlFor.split('-');
|
|
26
|
+
if (input.name != name) continue;
|
|
27
|
+
const index = indexes[name] = (indexes[name] ?? 0) + 1;
|
|
28
|
+
input.id = label.htmlFor = `${pre}-${name}-${index}`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
static patch(state) {
|
|
22
33
|
state.finish(() => {
|
|
23
|
-
|
|
24
|
-
for (const label of document.querySelectorAll('input+label[for^="for-"]')) {
|
|
25
|
-
const { previousElementSibling: input, htmlFor } = label;
|
|
26
|
-
const [pre, name] = htmlFor.split('-');
|
|
27
|
-
if (input.name != name) continue;
|
|
28
|
-
const index = indexes[name] = (indexes[name] ?? 0) + 1;
|
|
29
|
-
input.id = label.htmlFor = `${pre}-${name}-${index}`;
|
|
30
|
-
}
|
|
34
|
+
HTMLElementForm.improveHtmlFor(document);
|
|
31
35
|
});
|
|
32
36
|
}
|
|
33
37
|
|
|
@@ -187,6 +191,7 @@ class HTMLElementForm extends Page.create(HTMLFormElement) {
|
|
|
187
191
|
const vars = [];
|
|
188
192
|
for (const node of this.querySelectorAll("element-fieldset-list")) {
|
|
189
193
|
if (node.fill) vars.push(...node.fill(query));
|
|
194
|
+
HTMLElementForm.improveHtmlFor(node);
|
|
190
195
|
}
|
|
191
196
|
|
|
192
197
|
for (const elem of this.elements) {
|
|
@@ -310,7 +315,6 @@ class HTMLElementForm extends Page.create(HTMLFormElement) {
|
|
|
310
315
|
}
|
|
311
316
|
|
|
312
317
|
const scope = state.scope.copy();
|
|
313
|
-
scope.$request = form.read(true, e.submitter);
|
|
314
318
|
try {
|
|
315
319
|
const prelist = Array.from(form.elements)
|
|
316
320
|
.filter(node => Boolean(node.presubmit) && !node.disabled);
|
|
@@ -318,10 +322,14 @@ class HTMLElementForm extends Page.create(HTMLFormElement) {
|
|
|
318
322
|
for (const node of prelist) {
|
|
319
323
|
await node.presubmit(state);
|
|
320
324
|
}
|
|
321
|
-
|
|
322
|
-
scope.$
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
} catch (err) {
|
|
326
|
+
scope.$response = err;
|
|
327
|
+
}
|
|
328
|
+
form.enable();
|
|
329
|
+
scope.$request = form.read(true, e.submitter);
|
|
330
|
+
form.disable();
|
|
331
|
+
form.classList.add('loading');
|
|
332
|
+
try {
|
|
325
333
|
scope.$response = await state.fetch(
|
|
326
334
|
form.method,
|
|
327
335
|
e.submitter?.getAttribute('formaction') || form.action,
|
|
@@ -381,34 +389,35 @@ Page.define(`element-form`, HTMLElementForm, 'form');
|
|
|
381
389
|
|
|
382
390
|
/* these methods must be available even on non-upgraded elements */
|
|
383
391
|
HTMLFormElement.prototype.enable = function () {
|
|
384
|
-
for (
|
|
385
|
-
|
|
392
|
+
for (const elem of this.elements) {
|
|
393
|
+
if (elem.matches('fieldset')) continue;
|
|
394
|
+
const fieldset = elem.closest('fieldset');
|
|
395
|
+
if (fieldset?.disabled) continue;
|
|
386
396
|
elem.disabled = false;
|
|
387
397
|
if (elem.hasAttribute('disabled')) elem.removeAttribute('disabled');
|
|
388
398
|
}
|
|
389
399
|
};
|
|
390
400
|
HTMLFormElement.prototype.disable = function () {
|
|
391
|
-
for (
|
|
392
|
-
|
|
401
|
+
for (const elem of this.elements) {
|
|
402
|
+
if (elem.matches('fieldset')) continue;
|
|
393
403
|
elem.disabled = true;
|
|
394
404
|
}
|
|
395
405
|
};
|
|
396
406
|
|
|
397
407
|
HTMLSelectElement.prototype.fill = function (val) {
|
|
398
408
|
if (!Array.isArray(val)) val = [val];
|
|
399
|
-
for (
|
|
400
|
-
const opt = this.options[i];
|
|
409
|
+
for (const opt of this.options) {
|
|
401
410
|
opt.selected = val.includes(opt.value);
|
|
402
411
|
}
|
|
403
412
|
};
|
|
404
413
|
HTMLSelectElement.prototype.reset = function () {
|
|
405
|
-
for (
|
|
406
|
-
|
|
414
|
+
for (const opt of this.options) {
|
|
415
|
+
opt.selected = opt.defaultSelected;
|
|
407
416
|
}
|
|
408
417
|
};
|
|
409
418
|
HTMLSelectElement.prototype.save = function () {
|
|
410
|
-
for (
|
|
411
|
-
|
|
419
|
+
for (const opt of this.options) {
|
|
420
|
+
opt.defaultSelected = opt.selected;
|
|
412
421
|
}
|
|
413
422
|
};
|
|
414
423
|
|
package/ui/image.js
CHANGED
|
@@ -10,6 +10,14 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
10
10
|
|
|
11
11
|
#defer;
|
|
12
12
|
|
|
13
|
+
get image() {
|
|
14
|
+
let img = this.firstElementChild;
|
|
15
|
+
if (!img || !img.matches('img')) {
|
|
16
|
+
img = this.insertBefore(this.ownerDocument.createElement('img'), this.firstChild);
|
|
17
|
+
}
|
|
18
|
+
return img;
|
|
19
|
+
}
|
|
20
|
+
|
|
13
21
|
get dimensions() {
|
|
14
22
|
// dimension in pixels of the (extracted) source image
|
|
15
23
|
let w = parseInt(this.dataset.width);
|
|
@@ -58,24 +66,17 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
58
66
|
set crop({ x, y, w, h, z }) {
|
|
59
67
|
this.dataset.crop = [x, y, w, h, z].join(';');
|
|
60
68
|
}
|
|
61
|
-
get image() {
|
|
62
|
-
let img = this.firstElementChild;
|
|
63
|
-
if (!img || !img.matches('img')) {
|
|
64
|
-
img = this.insertBefore(this.ownerDocument.createElement('img'), this.firstChild);
|
|
65
|
-
}
|
|
66
|
-
return img;
|
|
67
|
-
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
patch() {
|
|
70
71
|
const {
|
|
71
72
|
dataset: d,
|
|
72
73
|
image,
|
|
73
74
|
dimensions: { w, h },
|
|
74
75
|
constructor,
|
|
75
|
-
currentSrc
|
|
76
|
+
currentSrc: src
|
|
76
77
|
} = this;
|
|
77
78
|
this.classList.remove('loading');
|
|
78
|
-
if (
|
|
79
|
+
if (src != this.options.src) {
|
|
79
80
|
this.classList.remove('error');
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -84,21 +85,13 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
84
85
|
image.width = w || d.width;
|
|
85
86
|
image.height = h || d.height;
|
|
86
87
|
image.alt = d.alt ?? "";
|
|
87
|
-
|
|
88
|
-
if (!cur) {
|
|
88
|
+
if (!src) {
|
|
89
89
|
this.placeholder();
|
|
90
|
-
} else if (
|
|
91
|
-
image.setAttribute('src',
|
|
90
|
+
} else if (src.startsWith('data:')) {
|
|
91
|
+
image.setAttribute('src', src);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
patch() {
|
|
96
|
-
this.#meta();
|
|
97
|
-
}
|
|
98
|
-
paint() {
|
|
99
|
-
this.#meta();
|
|
100
|
-
}
|
|
101
|
-
|
|
102
95
|
get currentSrc() {
|
|
103
96
|
return this.image?.currentSrc;
|
|
104
97
|
}
|
|
@@ -142,19 +135,20 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
142
135
|
}
|
|
143
136
|
|
|
144
137
|
reveal(state) {
|
|
145
|
-
|
|
146
|
-
|
|
138
|
+
const { src } = this.options;
|
|
139
|
+
if (!src) {
|
|
140
|
+
this.placeholder("Empty image");
|
|
147
141
|
return;
|
|
148
142
|
}
|
|
149
143
|
if (this.classList.contains('loading')) {
|
|
150
144
|
return;
|
|
151
145
|
}
|
|
152
146
|
const img = this.image;
|
|
153
|
-
const srcLoc = Page.parse(
|
|
147
|
+
const srcLoc = Page.parse(src);
|
|
154
148
|
const reqSrc = this.requestSrc(srcLoc);
|
|
155
149
|
if (!reqSrc) {
|
|
156
150
|
img.setAttribute('src', '');
|
|
157
|
-
}
|
|
151
|
+
} else if (reqSrc != this.currentSrc) {
|
|
158
152
|
this.classList.add('loading');
|
|
159
153
|
this.#defer?.resolve();
|
|
160
154
|
this.#defer = new Deferred();
|
|
@@ -169,11 +163,11 @@ const HTMLElementImageConstructor = Superclass => class extends Superclass {
|
|
|
169
163
|
captureError(e) {
|
|
170
164
|
this.classList.remove('loading');
|
|
171
165
|
this.classList.add('error');
|
|
172
|
-
this.placeholder(
|
|
173
|
-
this.#defer?.reject(new Error(this.currentSrc));
|
|
166
|
+
this.placeholder(this.options.src);
|
|
174
167
|
}
|
|
175
|
-
placeholder(
|
|
168
|
+
placeholder(src) {
|
|
176
169
|
this.image.removeAttribute('src');
|
|
170
|
+
if (src) this.#defer?.reject(new Error(src));
|
|
177
171
|
}
|
|
178
172
|
close() {
|
|
179
173
|
this.#defer?.resolve();
|
|
@@ -192,10 +186,10 @@ class HTMLElementInlineImage extends HTMLElementImageConstructor(Page.create(HTM
|
|
|
192
186
|
return this;
|
|
193
187
|
}
|
|
194
188
|
|
|
195
|
-
placeholder(
|
|
196
|
-
if (
|
|
189
|
+
placeholder(src) {
|
|
190
|
+
if (src) {
|
|
197
191
|
this.image.src = "data:image/svg+xml," + encodeURIComponent(
|
|
198
|
-
`<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 ${this.image.width} ${this.image.height}"><text text-anchor="middle" dominant-baseline="central" x="50%" y="50%" fill="#aaa"
|
|
192
|
+
`<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 ${this.image.width} ${this.image.height}"><text text-anchor="middle" dominant-baseline="central" x="50%" y="50%" fill="#aaa">∅</text></svg>`);
|
|
199
193
|
} else {
|
|
200
194
|
this.image.removeAttribute('src');
|
|
201
195
|
}
|
package/ui/select.js
CHANGED
|
@@ -56,7 +56,9 @@ class HTMLElementSelect extends Page.Element {
|
|
|
56
56
|
set value(v) {
|
|
57
57
|
this.getAttribute('value', v);
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
captureAllClick(e, state) {
|
|
60
|
+
if (this.classList.contains('active')) this.classList.remove('active');
|
|
61
|
+
}
|
|
60
62
|
handleClick(e, state) {
|
|
61
63
|
if (state.scope.$write) return;
|
|
62
64
|
if (this.disabled) return;
|