@pageboard/html 0.10.14 → 0.10.17

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/card.js CHANGED
@@ -18,7 +18,7 @@ exports.cards = {
18
18
  shape: {
19
19
  title: 'Shape',
20
20
  anyOf: [{
21
- type: 'null',
21
+ const: null,
22
22
  title: 'Default',
23
23
  }, {
24
24
  const: "square",
@@ -33,9 +33,8 @@ exports.cards = {
33
33
  },
34
34
  responsive: {
35
35
  title: 'Responsive',
36
- nullable: true,
37
36
  anyOf: [{
38
- title: 'Disable',
37
+ title: 'No',
39
38
  const: null
40
39
  }, {
41
40
  title: 'Stackable',
package/elements/form.js CHANGED
@@ -92,7 +92,7 @@ exports.api_form = {
92
92
  title: 'Method',
93
93
  nullable: true,
94
94
  type: "string",
95
- pattern: "^(\\w+\\.\\w+)?$"
95
+ pattern: /^(\w+\.\w+)?$/.source
96
96
  },
97
97
  parameters: {
98
98
  title: 'Parameters',
package/elements/grid.js CHANGED
@@ -17,8 +17,10 @@ exports.grid = {
17
17
  },
18
18
  responsive: {
19
19
  title: 'Responsive',
20
- nullable: true,
21
20
  anyOf: [{
21
+ title: 'No',
22
+ const: null
23
+ }, {
22
24
  title: 'Stackable',
23
25
  const: 'stackable'
24
26
  }, {
@@ -67,9 +69,8 @@ exports.grid_row = {
67
69
  properties: {
68
70
  responsive: {
69
71
  title: 'Responsive',
70
- nullable: true,
71
72
  anyOf: [{
72
- title: 'Disable',
73
+ title: 'No',
73
74
  const: null
74
75
  }, {
75
76
  title: 'Stackable',
package/elements/image.js CHANGED
@@ -12,8 +12,9 @@ exports.image = {
12
12
  url: {
13
13
  title: 'Address',
14
14
  description: 'Local or remote URL',
15
- nullable: true,
16
15
  anyOf: [{
16
+ type: "null"
17
+ }, {
17
18
  type: "string",
18
19
  format: "uri"
19
20
  }, {
@@ -156,8 +157,9 @@ exports.inlineImage = {
156
157
  url: {
157
158
  title: 'Address',
158
159
  description: 'Local or remote URL',
159
- nullable: true,
160
160
  anyOf: [{
161
+ type: "null"
162
+ }, {
161
163
  type: "string",
162
164
  format: "uri"
163
165
  }, {
@@ -156,8 +156,8 @@ exports.input_text = {
156
156
  nodes: 'inline*'
157
157
  },
158
158
  patterns: {
159
- tel: '^(\\(\\d+\\))? *\\d+([ .\\-]?\\d+)*$',
160
- email: '^[\\w.!#$%&\'*+\\/=?^`{|}~-]+@\\w(?:[\\w-]{0,61}\\w)?(?:\\.\\w(?:[\\w-]{0,61}\\w)?)*$'
159
+ tel: /^(\(\d+\))? *\d+([ .\-]?\d+)*$/.source,
160
+ email: /^[\w.!#$%&'*+\/=?^`{|}~-]+@\w(?:[\w-]{0,61}\w)?(?:\.\w(?:[\w-]{0,61}\w)?)*$/.source
161
161
  },
162
162
  html: `<div class="[width|num: wide] field [type|eq:hidden:hidden:]">
163
163
  <label block-content="label">Label</label>
@@ -106,8 +106,9 @@ exports.layout = {
106
106
  image: {
107
107
  title: 'Image',
108
108
  description: 'Local or remote URL',
109
- nullable: true,
110
109
  anyOf: [{
110
+ type: "null"
111
+ }, {
111
112
  type: "string",
112
113
  format: "uri"
113
114
  }, {
@@ -168,7 +169,7 @@ exports.layout = {
168
169
  size: {
169
170
  title: 'Size',
170
171
  anyOf: [{
171
- type: 'null',
172
+ const: null,
172
173
  title: 'Auto'
173
174
  }, {
174
175
  const: 'cover',
@@ -181,7 +182,7 @@ exports.layout = {
181
182
  position: {
182
183
  title: 'Position',
183
184
  anyOf: [{
184
- type: 'null',
185
+ const: null,
185
186
  title: 'Top Left'
186
187
  }, {
187
188
  const: 'top center',
@@ -212,7 +213,7 @@ exports.layout = {
212
213
  repeat: {
213
214
  title: 'Repeat',
214
215
  anyOf: [{
215
- type: 'null',
216
+ const: null,
216
217
  title: 'Repeat'
217
218
  }, {
218
219
  const: 'no-repeat',
@@ -234,7 +235,7 @@ exports.layout = {
234
235
  attachment: {
235
236
  title: 'Attachment',
236
237
  anyOf: [{
237
- type: 'null',
238
+ const: null,
238
239
  title: 'Local'
239
240
  }, {
240
241
  const: 'scroll',
package/elements/media.js CHANGED
@@ -8,8 +8,9 @@ exports.video = {
8
8
  url: {
9
9
  title: 'Address',
10
10
  description: 'Local or remote URL',
11
- nullable: true,
12
11
  anyOf: [{
12
+ type: "null"
13
+ }, {
13
14
  type: "string",
14
15
  format: "uri"
15
16
  }, {
@@ -88,8 +89,9 @@ exports.audio = {
88
89
  url: {
89
90
  title: 'Address',
90
91
  description: 'Local or remote URL',
91
- nullable: true,
92
92
  anyOf: [{
93
+ type: "null"
94
+ }, {
93
95
  type: "string",
94
96
  format: "uri"
95
97
  }, {
package/elements/menu.js CHANGED
@@ -9,7 +9,6 @@ exports.menu = {
9
9
  properties: {
10
10
  direction: {
11
11
  title: 'Direction',
12
- nullable: true,
13
12
  anyOf: [{
14
13
  const: null,
15
14
  title: "Horizontal"
@@ -37,7 +36,6 @@ exports.menu_group = {
37
36
  properties: {
38
37
  position: {
39
38
  title: 'Position',
40
- nullable: true,
41
39
  anyOf: [{
42
40
  const: null,
43
41
  title: "Left"
@@ -153,7 +151,6 @@ exports.menu_item_dropdown = {
153
151
  properties: {
154
152
  position: {
155
153
  title: 'Position',
156
- nullable: true,
157
154
  anyOf: [{
158
155
  const: null,
159
156
  title: "Left"
package/elements/page.js CHANGED
@@ -16,9 +16,8 @@ exports.page.properties.transition = {
16
16
  properties: {
17
17
  close: {
18
18
  title: 'Close',
19
- nullable: true,
20
19
  anyOf: [{
21
- type: 'null',
20
+ const: null,
22
21
  title: 'None'
23
22
  }, {
24
23
  const: 'tr-up',
@@ -39,9 +38,8 @@ exports.page.properties.transition = {
39
38
  },
40
39
  open: {
41
40
  title: 'Open',
42
- nullable: true,
43
41
  anyOf: [{
44
- type: 'null',
42
+ const: null,
45
43
  title: 'None'
46
44
  }, {
47
45
  const: 'tr-up',
@@ -128,7 +128,7 @@ exports.heading = {
128
128
  id: {
129
129
  nullable: true,
130
130
  type: 'string',
131
- pattern: '^[a-z0-9-]*$'
131
+ pattern: /^[a-z0-9-]*$/.source
132
132
  }
133
133
  },
134
134
  contents: {
@@ -27,7 +27,7 @@ exports.rating = {
27
27
  title: 'Color',
28
28
  anyOf: [{
29
29
  title: 'Default',
30
- type: 'null'
30
+ const: null
31
31
  }, {
32
32
  title: 'Star',
33
33
  const: "star"
package/lib/nouislider.js CHANGED
@@ -2,7 +2,7 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
3
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.noUiSlider = {}));
5
- }(this, (function (exports) { 'use strict';
5
+ })(this, (function (exports) { 'use strict';
6
6
 
7
7
  exports.PipsMode = void 0;
8
8
  (function (PipsMode) {
@@ -127,7 +127,7 @@
127
127
  : doc.body.scrollTop;
128
128
  return {
129
129
  x: x,
130
- y: y
130
+ y: y,
131
131
  };
132
132
  }
133
133
  // we provide a function to compute constants instead
@@ -140,18 +140,18 @@
140
140
  ? {
141
141
  start: "pointerdown",
142
142
  move: "pointermove",
143
- end: "pointerup"
143
+ end: "pointerup",
144
144
  }
145
145
  : window.navigator.msPointerEnabled
146
146
  ? {
147
147
  start: "MSPointerDown",
148
148
  move: "MSPointerMove",
149
- end: "MSPointerUp"
149
+ end: "MSPointerUp",
150
150
  }
151
151
  : {
152
152
  start: "mousedown touchstart",
153
153
  move: "mousemove touchmove",
154
- end: "mouseup touchend"
154
+ end: "mouseup touchend",
155
155
  };
156
156
  }
157
157
  // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
@@ -163,7 +163,7 @@
163
163
  var opts = Object.defineProperty({}, "passive", {
164
164
  get: function () {
165
165
  supportsPassive = true;
166
- }
166
+ },
167
167
  });
168
168
  // @ts-ignore
169
169
  window.addEventListener("test", null, opts);
@@ -384,18 +384,18 @@
384
384
  stepBefore: {
385
385
  startValue: this.xVal[j - 2],
386
386
  step: this.xNumSteps[j - 2],
387
- highestStep: this.xHighestCompleteStep[j - 2]
387
+ highestStep: this.xHighestCompleteStep[j - 2],
388
388
  },
389
389
  thisStep: {
390
390
  startValue: this.xVal[j - 1],
391
391
  step: this.xNumSteps[j - 1],
392
- highestStep: this.xHighestCompleteStep[j - 1]
392
+ highestStep: this.xHighestCompleteStep[j - 1],
393
393
  },
394
394
  stepAfter: {
395
395
  startValue: this.xVal[j],
396
396
  step: this.xNumSteps[j],
397
- highestStep: this.xHighestCompleteStep[j]
398
- }
397
+ highestStep: this.xHighestCompleteStep[j],
398
+ },
399
399
  };
400
400
  };
401
401
  Spectrum.prototype.countStepDecimals = function () {
@@ -481,7 +481,7 @@
481
481
  to: function (value) {
482
482
  return value === undefined ? "" : value.toFixed(2);
483
483
  },
484
- from: Number
484
+ from: Number,
485
485
  };
486
486
  var cssClasses = {
487
487
  target: "target",
@@ -519,12 +519,12 @@
519
519
  valueVertical: "value-vertical",
520
520
  valueNormal: "value-normal",
521
521
  valueLarge: "value-large",
522
- valueSub: "value-sub"
522
+ valueSub: "value-sub",
523
523
  };
524
524
  // Namespaces of internal event listeners
525
525
  var INTERNAL_EVENT_NS = {
526
526
  tooltips: ".__tooltips",
527
- aria: ".__aria"
527
+ aria: ".__aria",
528
528
  };
529
529
  //endregion
530
530
  function testStep(parsed, entry) {
@@ -714,6 +714,7 @@
714
714
  var hover = entry.indexOf("hover") >= 0;
715
715
  var unconstrained = entry.indexOf("unconstrained") >= 0;
716
716
  var dragAll = entry.indexOf("drag-all") >= 0;
717
+ var smoothSteps = entry.indexOf("smooth-steps") >= 0;
717
718
  if (fixed) {
718
719
  if (parsed.handles !== 2) {
719
720
  throw new Error("noUiSlider: 'fixed' behaviour must be used with 2 handles");
@@ -728,10 +729,11 @@
728
729
  tap: tap || snap,
729
730
  drag: drag,
730
731
  dragAll: dragAll,
732
+ smoothSteps: smoothSteps,
731
733
  fixed: fixed,
732
734
  snap: snap,
733
735
  hover: hover,
734
- unconstrained: unconstrained
736
+ unconstrained: unconstrained,
735
737
  };
736
738
  }
737
739
  function testTooltips(parsed, entry) {
@@ -817,7 +819,7 @@
817
819
  animate: true,
818
820
  animationDuration: 300,
819
821
  ariaFormat: defaultFormatter,
820
- format: defaultFormatter
822
+ format: defaultFormatter,
821
823
  };
822
824
  // Tests are executed in the order they are presented here.
823
825
  var tests = {
@@ -844,7 +846,7 @@
844
846
  documentElement: { r: false, t: testDocumentElement },
845
847
  cssPrefix: { r: true, t: testCssPrefix },
846
848
  cssClasses: { r: true, t: testCssClasses },
847
- handleAttributes: { r: false, t: testHandleAttributes }
849
+ handleAttributes: { r: false, t: testHandleAttributes },
848
850
  };
849
851
  var defaults = {
850
852
  connect: false,
@@ -856,7 +858,7 @@
856
858
  cssClasses: cssClasses,
857
859
  keyboardPageMultiplier: 5,
858
860
  keyboardMultiplier: 1,
859
- keyboardDefaultStep: 10
861
+ keyboardDefaultStep: 10,
860
862
  };
861
863
  // AriaFormat defaults to regular format, if any.
862
864
  if (options.format && !options.ariaFormat) {
@@ -888,7 +890,7 @@
888
890
  // Pips don't move, so we can place them using left/top.
889
891
  var styles = [
890
892
  ["left", "top"],
891
- ["right", "bottom"]
893
+ ["right", "bottom"],
892
894
  ];
893
895
  parsed.style = styles[parsed.dir][parsed.ort];
894
896
  return parsed;
@@ -1273,7 +1275,7 @@
1273
1275
  var format = pips.format || {
1274
1276
  to: function (value) {
1275
1277
  return String(Math.round(value));
1276
- }
1278
+ },
1277
1279
  };
1278
1280
  scope_Pips = scope_Target.appendChild(addMarking(spread, filter, format));
1279
1281
  return scope_Pips;
@@ -1472,6 +1474,14 @@
1472
1474
  scope_Body.removeEventListener("selectstart", preventDefault);
1473
1475
  }
1474
1476
  }
1477
+ if (options.events.smoothSteps) {
1478
+ data.handleNumbers.forEach(function (handleNumber) {
1479
+ setHandle(handleNumber, scope_Locations[handleNumber], true, true, false, false);
1480
+ });
1481
+ data.handleNumbers.forEach(function (handleNumber) {
1482
+ fireEvent("update", handleNumber);
1483
+ });
1484
+ }
1475
1485
  data.handleNumbers.forEach(function (handleNumber) {
1476
1486
  fireEvent("change", handleNumber);
1477
1487
  fireEvent("set", handleNumber);
@@ -1509,21 +1519,21 @@
1509
1519
  pageOffset: event.pageOffset,
1510
1520
  handleNumbers: data.handleNumbers,
1511
1521
  buttonsProperty: event.buttons,
1512
- locations: scope_Locations.slice()
1522
+ locations: scope_Locations.slice(),
1513
1523
  });
1514
1524
  var endEvent = attachEvent(actions.end, scope_DocumentElement, eventEnd, {
1515
1525
  target: event.target,
1516
1526
  handle: handle,
1517
1527
  listeners: listeners,
1518
1528
  doNotReject: true,
1519
- handleNumbers: data.handleNumbers
1529
+ handleNumbers: data.handleNumbers,
1520
1530
  });
1521
1531
  var outEvent = attachEvent("mouseout", scope_DocumentElement, documentLeave, {
1522
1532
  target: event.target,
1523
1533
  handle: handle,
1524
1534
  listeners: listeners,
1525
1535
  doNotReject: true,
1526
- handleNumbers: data.handleNumbers
1536
+ handleNumbers: data.handleNumbers,
1527
1537
  });
1528
1538
  // We want to make sure we pushed the listeners in the listener list rather than creating
1529
1539
  // a new one as it has already been passed to the event handlers.
@@ -1668,7 +1678,7 @@
1668
1678
  // These events are only bound to the visual handle
1669
1679
  // element, not the 'real' origin element.
1670
1680
  attachEvent(actions.start, handle.children[0], eventStart, {
1671
- handleNumbers: [index]
1681
+ handleNumbers: [index],
1672
1682
  });
1673
1683
  });
1674
1684
  }
@@ -1679,7 +1689,7 @@
1679
1689
  // Fire hover events
1680
1690
  if (behaviour.hover) {
1681
1691
  attachEvent(actions.move, scope_Base, eventHover, {
1682
- hover: true
1692
+ hover: true,
1683
1693
  });
1684
1694
  }
1685
1695
  // Make the range draggable.
@@ -1710,7 +1720,7 @@
1710
1720
  attachEvent(actions.start, eventHolder, eventStart, {
1711
1721
  handles: handlesToDrag,
1712
1722
  handleNumbers: handleNumbersToDrag,
1713
- connect: connect
1723
+ connect: connect,
1714
1724
  });
1715
1725
  });
1716
1726
  });
@@ -1771,7 +1781,7 @@
1771
1781
  });
1772
1782
  }
1773
1783
  // Split out the handle positioning logic so the Move event can use it, too
1774
- function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue) {
1784
+ function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue, smoothSteps) {
1775
1785
  var distance;
1776
1786
  // For sliders with multiple handles, limit movement to the other handle.
1777
1787
  // Apply the margin option by adding it to the handle positions.
@@ -1810,7 +1820,9 @@
1810
1820
  to = Math.min(to, distance);
1811
1821
  }
1812
1822
  }
1813
- to = scope_Spectrum.getStep(to);
1823
+ if (!smoothSteps) {
1824
+ to = scope_Spectrum.getStep(to);
1825
+ }
1814
1826
  // Limit percentage to the 0 - 100 range
1815
1827
  to = limit(to);
1816
1828
  // Return false if handle can't move
@@ -1830,6 +1842,7 @@
1830
1842
  var proposals = locations.slice();
1831
1843
  // Store first handle now, so we still have it in case handleNumbers is reversed
1832
1844
  var firstHandle = handleNumbers[0];
1845
+ var smoothSteps = options.events.smoothSteps;
1833
1846
  var b = [!upward, upward];
1834
1847
  var f = [upward, !upward];
1835
1848
  // Copy handleNumbers so we don't change the dataset
@@ -1842,7 +1855,7 @@
1842
1855
  // Step 1: get the maximum percentage that any of the handles can move
1843
1856
  if (handleNumbers.length > 1) {
1844
1857
  handleNumbers.forEach(function (handleNumber, o) {
1845
- var to = checkHandlePosition(proposals, handleNumber, proposals[handleNumber] + proposal, b[o], f[o], false);
1858
+ var to = checkHandlePosition(proposals, handleNumber, proposals[handleNumber] + proposal, b[o], f[o], false, smoothSteps);
1846
1859
  // Stop if one of the handles can't move.
1847
1860
  if (to === false) {
1848
1861
  proposal = 0;
@@ -1860,7 +1873,8 @@
1860
1873
  var state = false;
1861
1874
  // Step 2: Try to set the handles with the found percentage
1862
1875
  handleNumbers.forEach(function (handleNumber, o) {
1863
- state = setHandle(handleNumber, locations[handleNumber] + proposal, b[o], f[o]) || state;
1876
+ state =
1877
+ setHandle(handleNumber, locations[handleNumber] + proposal, b[o], f[o], false, smoothSteps) || state;
1864
1878
  });
1865
1879
  // Step 3: If a handle moved, fire events
1866
1880
  if (state) {
@@ -1905,9 +1919,9 @@
1905
1919
  }
1906
1920
  // Test suggested values and apply margin, step.
1907
1921
  // if exactInput is true, don't run checkHandlePosition, then the handle can be placed in between steps (#436)
1908
- function setHandle(handleNumber, to, lookBackward, lookForward, exactInput) {
1922
+ function setHandle(handleNumber, to, lookBackward, lookForward, exactInput, smoothSteps) {
1909
1923
  if (!exactInput) {
1910
- to = checkHandlePosition(scope_Locations, handleNumber, to, lookBackward, lookForward, false);
1924
+ to = checkHandlePosition(scope_Locations, handleNumber, to, lookBackward, lookForward, false, smoothSteps);
1911
1925
  }
1912
1926
  if (to === false) {
1913
1927
  return false;
@@ -2059,7 +2073,7 @@
2059
2073
  if (options.snap) {
2060
2074
  return [
2061
2075
  value - nearbySteps.stepBefore.startValue || null,
2062
- nearbySteps.stepAfter.startValue - value || null
2076
+ nearbySteps.stepAfter.startValue - value || null,
2063
2077
  ];
2064
2078
  }
2065
2079
  // If the next value in this step moves into the next step,
@@ -2118,7 +2132,7 @@
2118
2132
  "step",
2119
2133
  "format",
2120
2134
  "pips",
2121
- "tooltips"
2135
+ "tooltips",
2122
2136
  ];
2123
2137
  // Only change options that we're actually passed to update.
2124
2138
  updateAble.forEach(function (name) {
@@ -2203,7 +2217,7 @@
2203
2217
  getOrigins: function () {
2204
2218
  return scope_Handles;
2205
2219
  },
2206
- pips: pips // Issue #594
2220
+ pips: pips, // Issue #594
2207
2221
  };
2208
2222
  return scope_Self;
2209
2223
  }
@@ -2228,13 +2242,13 @@
2228
2242
  // A reference to the default classes, allows global changes.
2229
2243
  // Use the cssClasses option for changes to one slider.
2230
2244
  cssClasses: cssClasses,
2231
- create: initialize
2245
+ create: initialize,
2232
2246
  };
2233
2247
 
2234
2248
  exports.create = initialize;
2235
2249
  exports.cssClasses = cssClasses;
2236
- exports['default'] = nouislider;
2250
+ exports["default"] = nouislider;
2237
2251
 
2238
2252
  Object.defineProperty(exports, '__esModule', { value: true });
2239
2253
 
2240
- })));
2254
+ }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pageboard/html",
3
- "version": "0.10.14",
3
+ "version": "0.10.17",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "formdata-polyfill": "^4.0.10",
27
- "nouislider": "^15.5.0",
27
+ "nouislider": "^15.5.1",
28
28
  "object-fit-images": "^3.2.4",
29
29
  "postinstall-bundle": "^0.7.4"
30
30
  },
package/ui/form.js CHANGED
@@ -33,27 +33,26 @@ class HTMLCustomFormElement extends HTMLFormElement {
33
33
  delete state.query.submit;
34
34
  state.finish(() => {
35
35
  if (state.status != 200) return;
36
- const e = document.createEvent('HTMLEvents');
37
- e.initEvent('submit', true, true);
38
- this.dispatchEvent(e);
36
+ this.dispatchEvent(new Event('submit', {
37
+ bubbles: true,
38
+ cancelable: true
39
+ }));
39
40
  });
40
41
  }
41
- read(withDefaults) {
42
+ read(withDefaults = false) {
42
43
  const fd = new FormData(this);
43
44
  const query = {};
44
45
  fd.forEach((val, key) => {
45
- if (val == null || val == "") {
46
- const cur = this.querySelectorAll(`[name="${key}"]`).slice(-1).pop();
47
- if (cur.required == false) {
48
- val = undefined;
49
- } else {
50
- val = null;
51
- }
46
+ const cur = this.querySelectorAll(`[name="${key}"]`).slice(-1).pop();
47
+ if (cur.type == "file") {
48
+ val = cur.value;
52
49
  }
50
+ if (val == "") val = null;
51
+ // build array-like values
53
52
  const old = query[key];
54
53
  if (old !== undefined) {
55
54
  if (!Array.isArray(old)) {
56
- query[key] = [old];
55
+ query[key] = old == null ? [] : [old];
57
56
  }
58
57
  if (val !== undefined) query[key].push(val);
59
58
  } else {
@@ -61,37 +60,48 @@ class HTMLCustomFormElement extends HTMLFormElement {
61
60
  }
62
61
  });
63
62
 
63
+ // withDefaults: keep value if equals to its default
64
+ // else unset value
64
65
  for (const node of this.elements) {
65
- if (node.name == null || node.name == "" || node.type == "button") continue;
66
+ const { name, type } = node;
67
+ if (name == null || name == "" || type == "button") {
68
+ continue;
69
+ }
66
70
  let val = node.value;
67
71
  if (val == "") val = null;
68
- if (node.type == "radio") {
69
- if (!withDefaults && node.checked == node.defaultChecked && query[node.name] == val) {
70
- query[node.name] = undefined;
71
- }
72
- } else if (node.type == "checkbox") {
73
- if (!(node.name in query)) {
74
- if (!withDefaults) query[node.name] = undefined;
75
- }
76
- } else if (node.type == "hidden") {
77
- // always include them
78
- } else {
79
- let defVal = node.defaultValue;
80
- if (defVal == "") defVal = null;
81
- if (!withDefaults && query[node.name] == defVal) {
82
- query[node.name] = undefined;
83
- } else {
84
- // not yet using form-associated custom input
85
- query[node.name] = node.value;
86
- }
87
- }
88
- if (query[node.name] === undefined && withDefaults) {
89
- query[node.name] = null;
72
+ let defVal = node.defaultValue;
73
+ if (defVal == "") defVal = null;
74
+
75
+ switch (type) {
76
+ case "radio":
77
+ if (!withDefaults && node.checked == node.defaultChecked) {
78
+ if (query[name] == val) {
79
+ query[name] = undefined;
80
+ }
81
+ }
82
+ break;
83
+ case "checkbox":
84
+ if (!withDefaults) {
85
+ if (!(name in query)) {
86
+ query[name] = undefined;
87
+ }
88
+ }
89
+ break;
90
+ case "hidden":
91
+ break;
92
+ default:
93
+ if (withDefaults) {
94
+ if (query[name] === undefined) {
95
+ query[name] = defVal;
96
+ }
97
+ } else if (val === defVal) {
98
+ query[name] = node.required ? null : undefined;
99
+ }
90
100
  }
91
101
  }
102
+ // FIXME use e.submitter polyfill when available
103
+ // https://github.com/Financial-Times/polyfill-library/issues/1111
92
104
  const btn = document.activeElement;
93
- // FIXME https://github.com/whatwg/html/issues/3195 use e.submitter polyfill
94
- // https://github.com/whatwg/xhr/issues/262 it's a mess
95
105
  if (btn && btn.type == "submit" && btn.name && btn.value) {
96
106
  query[btn.name] = btn.value;
97
107
  }
@@ -345,7 +355,8 @@ HTMLInputElement.prototype.fill = function (val) {
345
355
  if (this.type == "radio" || this.type == "checkbox") {
346
356
  this.checked = val;
347
357
  } else if (this.type == "file") {
348
- this.setAttribute('value', val);
358
+ if (val == '' || val == null) this.removeAttribute('value');
359
+ else this.setAttribute('value', val);
349
360
  } else {
350
361
  this.value = val;
351
362
  }
@@ -363,7 +374,7 @@ HTMLInputElement.prototype.save = function () {
363
374
  if (this.type == "radio" || this.type == "checkbox") {
364
375
  this.defaultChecked = this.checked;
365
376
  } else if (this.type == "file") {
366
- this.defaultValue = this.getAttribute('value');
377
+ this.defaultValue = this.getAttribute('value') || '';
367
378
  } else {
368
379
  this.defaultValue = this.value;
369
380
  }
@@ -381,11 +392,13 @@ Object.defineProperty(HTMLInputElement.prototype, 'defaultValue', {
381
392
  configurable: true,
382
393
  enumerable: true,
383
394
  get: function () {
395
+ // FIXME might not be needed anymore
384
396
  if (this.form?.method == "get") return '';
385
397
  else return this.getAttribute('value');
386
398
  },
387
399
  set: function (val) {
388
- this.setAttribute('value', val);
400
+ if (val == '' || val == null) this.removeAttribute('value');
401
+ else this.setAttribute('value', val);
389
402
  }
390
403
  });
391
404
 
package/ui/input-file.js CHANGED
@@ -14,7 +14,6 @@ class HTMLElementInputFile extends HTMLInputElement {
14
14
  super();
15
15
  if (this.init) this.init();
16
16
  this.save();
17
-
18
17
  }
19
18
  get defaultValue() {
20
19
  return this.#defaultValue;
@@ -26,7 +25,7 @@ class HTMLElementInputFile extends HTMLInputElement {
26
25
  return this.getAttribute('value');
27
26
  }
28
27
  set value(str) {
29
- if (str != null) {
28
+ if (str) {
30
29
  this.setAttribute('value', str);
31
30
  } else {
32
31
  this.removeAttribute('value');
package/ui/input-range.js CHANGED
@@ -81,9 +81,10 @@ class HTMLElementInputRange extends HTMLInputElement {
81
81
  helper.classList.remove('indeterminate');
82
82
  if (isInt) values = values.map((n) => parseInt(n));
83
83
  this.rangeValue = values;
84
- const e = document.createEvent('HTMLEvents');
85
- e.initEvent('change', true, true);
86
- this.dispatchEvent(e);
84
+ this.dispatchEvent(new Event('change', {
85
+ bubbles: true,
86
+ cancelable: true
87
+ }));
87
88
  });
88
89
  helper.addEventListener('keydown', this, true);
89
90
  helper.addEventListener('dblclick', this, true);
@@ -92,9 +93,10 @@ class HTMLElementInputRange extends HTMLInputElement {
92
93
  handleEvent(e) {
93
94
  if (e.type == "dblclick" || e.keyCode == 8 || e.keyCode == 46) {
94
95
  this.fill();
95
- const ne = document.createEvent('HTMLEvents');
96
- ne.initEvent('change', true, true);
97
- this.dispatchEvent(ne);
96
+ this.dispatchEvent(new Event('change', {
97
+ bubbles: true,
98
+ cancelable: true
99
+ }));
98
100
  }
99
101
  }
100
102
 
package/ui/menu.css CHANGED
@@ -45,14 +45,17 @@
45
45
  display: flex;
46
46
  flex-direction: column;
47
47
  }
48
+ .right.burger .popup.item > .placer {
49
+ left: auto;
50
+ right:0;
51
+ }
48
52
  .right.popup.item > .placer > div {
49
53
  left:auto;
50
54
  right:0;
51
55
  }
52
56
  .fixed.popup.item > .placer > div {
53
- position:fixed;
54
- max-width: 100%;
55
- max-height: 100%;
57
+ max-width: 100vw;
58
+ max-height: 100vh;
56
59
  }
57
60
  .center.popup.item > .placer > div {
58
61
  transform: translateX(-50%);
package/ui/menu.js CHANGED
@@ -27,15 +27,17 @@ class HTMLElementMenu extends VirtualHTMLElement {
27
27
  const menu = this.firstElementChild;
28
28
  const helper = this.lastElementChild;
29
29
  helper.lastElementChild.lastElementChild.appendChild(this.toHelper(menu));
30
- this.observer = new ResizeObserver((entries, observer) => {
31
- window.requestAnimationFrame(() => {
32
- const styles = window.getComputedStyle(this);
33
- const parentWidth = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight) + this.offsetWidth;
34
- const menuWidth = menu.offsetWidth;
35
- this.classList.toggle('burger', parentWidth <= menuWidth);
30
+ state.finish(() => {
31
+ this.observer = new ResizeObserver((entries, observer) => {
32
+ window.requestAnimationFrame(() => {
33
+ const styles = window.getComputedStyle(this);
34
+ const parentWidth = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight) + this.offsetWidth;
35
+ const menuWidth = menu.offsetWidth;
36
+ this.classList.toggle('burger', parentWidth <= menuWidth);
37
+ });
36
38
  });
39
+ this.observer.observe(this.parentNode);
37
40
  });
38
- this.observer.observe(this.parentNode);
39
41
  }
40
42
  close(state) {
41
43
  if (this.observer) this.observer.disconnect();
@@ -55,7 +57,7 @@ class HTMLElementMenu extends VirtualHTMLElement {
55
57
  } else {
56
58
  const padding = this.offsetTop + this.offsetHeight;
57
59
  const menu = tosser.lastElementChild.lastElementChild;
58
- menu.style.maxHeight = `calc(100% - ${padding}px)`;
60
+ menu.style.maxHeight = `calc(100vh - ${padding}px)`;
59
61
  }
60
62
  } else if (item) {
61
63
  this.active = item != this.active ? item : null;
package/ui/query-tags.js CHANGED
@@ -90,9 +90,10 @@ class HTMLElementQueryTags extends VirtualHTMLElement {
90
90
  else if (control.selected) control.selected = false;
91
91
  else if (control.reset) control.reset();
92
92
  else if (control.value) control.value = "";
93
- const e = document.createEvent('HTMLEvents');
94
- e.initEvent('submit', true, true);
95
- control.form.dispatchEvent(e);
93
+ control.form.dispatchEvent(new Event('submit', {
94
+ bubbles: true,
95
+ cancelable: true
96
+ }));
96
97
  }
97
98
  label.remove();
98
99
  }