@pageboard/html 0.16.16 → 0.17.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/elements/table.js +19 -7
- package/package.json +2 -2
- package/ui/form.css +5 -0
- package/ui/form.js +13 -8
- package/ui/image.js +25 -31
- package/ui/input-date.js +0 -2
- package/ui/select.js +3 -1
package/elements/table.js
CHANGED
|
@@ -125,9 +125,8 @@ exports.table_cell = {
|
|
|
125
125
|
properties: {
|
|
126
126
|
align: {
|
|
127
127
|
title: 'Align',
|
|
128
|
-
default: "",
|
|
129
128
|
anyOf: [{
|
|
130
|
-
const:
|
|
129
|
+
const: null,
|
|
131
130
|
title: "Left",
|
|
132
131
|
icon: '<i class="icon align left"></i>'
|
|
133
132
|
}, {
|
|
@@ -163,12 +162,14 @@ exports.table_cell = {
|
|
|
163
162
|
},
|
|
164
163
|
inplace: true,
|
|
165
164
|
contents: "block+",
|
|
166
|
-
tag: 'td',
|
|
165
|
+
tag: 'td:not([is])',
|
|
167
166
|
parse: function(dom) {
|
|
168
167
|
const d = {};
|
|
169
|
-
if (dom.
|
|
170
|
-
else if (dom.
|
|
171
|
-
if (dom.
|
|
168
|
+
if (dom.classList.contains('center')) d.align = 'center';
|
|
169
|
+
else if (dom.classList.contains('right')) d.align = 'right';
|
|
170
|
+
if (dom.classList.contains('selectable')) d.selectable = true;
|
|
171
|
+
if (dom.rowspan) d.rowspan = dom.rowspan;
|
|
172
|
+
if (dom.colspan) d.colspan = dom.colspan;
|
|
172
173
|
return d;
|
|
173
174
|
},
|
|
174
175
|
html: '<td class="[align|post: aligned] [selectable]" rowspan="[rowspan]" colspan="[colspan]"></td>'
|
|
@@ -216,10 +217,21 @@ exports.table_head_cell = {
|
|
|
216
217
|
}]
|
|
217
218
|
}
|
|
218
219
|
},
|
|
220
|
+
parse: function (dom) {
|
|
221
|
+
const d = {};
|
|
222
|
+
if (dom.classList.contains('center')) d.align = 'center';
|
|
223
|
+
else if (dom.classList.contains('right')) d.align = 'right';
|
|
224
|
+
if (dom.classList.contains('selectable')) d.selectable = true;
|
|
225
|
+
if (dom.rowspan) d.rowspan = dom.rowspan;
|
|
226
|
+
if (dom.colspan) d.colspan = dom.colspan;
|
|
227
|
+
if (dom.scope) d.scope = dom.scope;
|
|
228
|
+
if (dom.dataset.width) d.width = parseInt(dom.dataset.width) || null;
|
|
229
|
+
return d;
|
|
230
|
+
},
|
|
219
231
|
contents: "block+",
|
|
220
232
|
tag: 'th',
|
|
221
233
|
inplace: true,
|
|
222
|
-
html: '<th class="[align|post: aligned] [width|as:colnums|post: wide]" rowspan="[rowspan]" colspan="[colspan]" scope="[scope]"></th>',
|
|
234
|
+
html: '<th class="[align|post: aligned] [width|as:colnums|post: wide]" data-width="[width]" rowspan="[rowspan]" colspan="[colspan]" scope="[scope]"></th>',
|
|
223
235
|
stylesheets: [
|
|
224
236
|
"../ui/table.css"
|
|
225
237
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pageboard/html",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
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) {
|
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/input-date.js
CHANGED
|
@@ -4,8 +4,6 @@ class HTMLElementInputDate extends Page.create(HTMLInputElement) {
|
|
|
4
4
|
if (this.hasAttribute('value')) this.setAttribute('value', this.getAttribute('value'));
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
// FIXME: doesn't initialize itself with already set "value" attribute
|
|
8
|
-
|
|
9
7
|
setAttribute(name, value) {
|
|
10
8
|
if (name == "value") {
|
|
11
9
|
this.value = value;
|
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;
|