@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 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.matches('.center')) d.align = 'center';
170
- else if (dom.matches('.right')) d.align = 'right';
171
- if (dom.matches('.selectable')) d.selectable = true;
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.16.16",
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.1"
18
+ "postinstall": "^0.11.2"
19
19
  },
20
20
  "postinstall": {
21
21
  "nouislider/dist/nouislider.js": "link lib/",
package/ui/form.css CHANGED
@@ -47,6 +47,11 @@ element-select.active.ui.dropdown .menu {
47
47
  position:relative;
48
48
  }
49
49
 
50
+ .ui.form .inline.fields {
51
+ align-items: end;
52
+ margin:0;
53
+ }
54
+
50
55
  .ui.form[method="post"].unsaved button[type="submit"] {
51
56
  text-decoration:underline;
52
57
  }
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
- const indexes = {};
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
- #meta() {
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 (currentSrc != this.options.src) {
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
- const cur = currentSrc;
88
- if (!cur) {
88
+ if (!src) {
89
89
  this.placeholder();
90
- } else if (cur.startsWith('data:')) {
91
- image.setAttribute('src', cur);
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
- if (!this.options.src) {
146
- this.placeholder(true);
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(this.options.src);
147
+ const srcLoc = Page.parse(src);
154
148
  const reqSrc = this.requestSrc(srcLoc);
155
149
  if (!reqSrc) {
156
150
  img.setAttribute('src', '');
157
- } else if (reqSrc != this.currentSrc) {
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(true);
173
- this.#defer?.reject(new Error(this.currentSrc));
166
+ this.placeholder(this.options.src);
174
167
  }
175
- placeholder(error) {
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(error) {
196
- if (error) {
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">${error ? '∅' : ''}</text></svg>`);
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;