@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 CHANGED
@@ -162,7 +162,7 @@ exports.table_cell = {
162
162
  },
163
163
  inplace: true,
164
164
  contents: "block+",
165
- tag: 'td',
165
+ tag: 'td:not([is])',
166
166
  parse: function(dom) {
167
167
  const d = {};
168
168
  if (dom.classList.contains('center')) d.align = 'center';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageboard/html",
3
- "version": "0.16.17",
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.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) {
@@ -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
- form.enable();
322
- scope.$request = form.read(true, e.submitter);
323
- form.disable();
324
- form.classList.add('loading');
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 (let i = 0; i < this.elements.length; i++) {
385
- const elem = this.elements[i];
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 (let i = 0; i < this.elements.length; i++) {
392
- const elem = this.elements[i];
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 (let i = 0; i < this.options.length; i++) {
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 (let i = 0; i < this.options.length; i++) {
406
- this.options[i].selected = this.options[i].defaultSelected;
414
+ for (const opt of this.options) {
415
+ opt.selected = opt.defaultSelected;
407
416
  }
408
417
  };
409
418
  HTMLSelectElement.prototype.save = function () {
410
- for (let i = 0; i < this.options.length; i++) {
411
- this.options[i].defaultSelected = this.options[i].selected;
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
- #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/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;