input-duration 3.1.0 → 3.2.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/README.md +18 -2
- package/docs/InputDuration.html +3506 -528
- package/docs/index.js.html +466 -181
- package/index.js +276 -14
- package/package.json +1 -1
package/docs/index.js.html
CHANGED
|
@@ -19,53 +19,115 @@
|
|
|
19
19
|
|
|
20
20
|
<h1 class="page-title">Source: index.js</h1>
|
|
21
21
|
|
|
22
|
-
<h1>Hi from bob</h1>Hi from bobQ!!!</h1>
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
|
|
26
|
+
|
|
27
27
|
<section>
|
|
28
28
|
<article>
|
|
29
29
|
<pre class="prettyprint source linenums"><code>/**
|
|
30
30
|
* This is jsdoc 'auto' documentation see https://jsdoc.app/
|
|
31
|
-
*
|
|
31
|
+
* npm install -g jsdoc
|
|
32
|
+
* jsdoc index.js -d ./docs/
|
|
33
|
+
*
|
|
34
|
+
*
|
|
32
35
|
* @fileoverview INPUT-DURATION
|
|
33
|
-
* @file INPUT-DURATION
|
|
36
|
+
* @file INPUT-DURATION
|
|
34
37
|
* @author Stephan Luis
|
|
35
38
|
* @see <a href="https://www.npmjs.com/package/input-duration">NPM input-duration</a>
|
|
36
39
|
* @see <a href="https://github.com/StephanLuis/input-duration">GitHub input-duration</a>
|
|
37
|
-
* @copyright MIT License, Copyright (c) 2022
|
|
40
|
+
* @copyright MIT License, Copyright (c) 2022
|
|
41
|
+
* @version 2.2.8 (release)
|
|
38
42
|
*/
|
|
39
43
|
|
|
40
44
|
|
|
41
45
|
|
|
42
46
|
/**
|
|
43
47
|
* Class for the Input-Duration webcomponent
|
|
48
|
+
*
|
|
49
|
+
* Boolean attributes `no-hours`, `no-minutes`, `no-seconds`, and
|
|
50
|
+
* `no-microseconds` hide their respective fields. String attributes
|
|
51
|
+
* `hours-divider`, `minutes-divider`, `seconds-divider`, and
|
|
52
|
+
* `microseconds-divider` customize the separators; the last adds a suffix
|
|
53
|
+
* after milliseconds. Divider values are rendered as text.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* <input-duration no-microseconds hours-divider="h " microseconds-divider="ms"></input-duration>
|
|
57
|
+
*
|
|
44
58
|
* @class InputDuration
|
|
45
59
|
* @extends HTMLElement
|
|
46
60
|
*/
|
|
47
61
|
|
|
48
62
|
class InputDuration extends HTMLElement {
|
|
63
|
+
/**
|
|
64
|
+
* HTML attributes that update the component when changed.
|
|
65
|
+
*
|
|
66
|
+
* @static
|
|
67
|
+
* @returns {string[]} Observed value, visibility, and divider attributes.
|
|
68
|
+
*/
|
|
69
|
+
static get observedAttributes() {
|
|
70
|
+
return [
|
|
71
|
+
'value',
|
|
72
|
+
'no-hours',
|
|
73
|
+
'no-minutes',
|
|
74
|
+
'no-seconds',
|
|
75
|
+
'no-microseconds',
|
|
76
|
+
'hours-divider',
|
|
77
|
+
'minutes-divider',
|
|
78
|
+
'seconds-divider',
|
|
79
|
+
'microseconds-divider'
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
|
|
49
83
|
constructor() {
|
|
50
84
|
|
|
51
85
|
super();
|
|
52
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Shadow root containing this component's controls.
|
|
89
|
+
* @type {ShadowRoot}
|
|
90
|
+
*/
|
|
53
91
|
this.myElement = this.attachShadow({ mode: 'open' });
|
|
54
92
|
|
|
55
|
-
// needed for setting inputs when value attribute is added to chronlyHMS
|
|
56
|
-
// <chronly-hms id="bobPrepop" value="99:09:09.999"></chronly-hms>
|
|
57
|
-
|
|
58
|
-
this.value = this.getAttribute('value');
|
|
59
|
-
|
|
60
93
|
this.boot();
|
|
61
94
|
|
|
62
95
|
} // end constructor
|
|
63
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Updates the rendered control when an observed attribute changes.
|
|
99
|
+
*
|
|
100
|
+
* @param {string} name - Changed attribute name.
|
|
101
|
+
* @param {?string} oldValue - Previous attribute value.
|
|
102
|
+
* @param {?string} newValue - New attribute value, or null when removed.
|
|
103
|
+
* @returns {void}
|
|
104
|
+
*/
|
|
105
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
106
|
+
|
|
107
|
+
if (oldValue === newValue) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (name !== 'value') {
|
|
112
|
+
this.updateVisibleFields();
|
|
113
|
+
this.updateDividers();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (newValue === null) {
|
|
118
|
+
this.resetInputs();
|
|
119
|
+
} else if (this.isValidValue(newValue)) {
|
|
120
|
+
this.setInputValues(newValue);
|
|
121
|
+
} else {
|
|
122
|
+
this.warnInvalidValue(newValue);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
64
126
|
|
|
65
127
|
/**
|
|
66
128
|
* get the input-duration value, pulls values from each input
|
|
67
|
-
* so in js use var x = document.querySelector("#bobPrepop").value;
|
|
68
|
-
* @
|
|
129
|
+
* so in js use var x = document.querySelector("#bobPrepop").value;
|
|
130
|
+
* @returns {?string} Duration in `HH:mm:ss.SSS` format, or null before initialization.
|
|
69
131
|
*/
|
|
70
132
|
|
|
71
133
|
get value() {
|
|
@@ -89,69 +151,84 @@ class InputDuration extends HTMLElement {
|
|
|
89
151
|
|
|
90
152
|
|
|
91
153
|
/**
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
* @
|
|
95
|
-
* @
|
|
154
|
+
* Sets the duration using the fixed `HH:mm:ss.SSS` format.
|
|
155
|
+
*
|
|
156
|
+
* @param {string} val - Duration string, such as `05:05:05.005`.
|
|
157
|
+
* @returns {void}
|
|
96
158
|
*/
|
|
97
159
|
|
|
98
160
|
set value(val) {
|
|
99
161
|
|
|
100
162
|
// for setting the value in js (like document.querySelector("#bobPrepop").value = "05:05:05.005")
|
|
101
|
-
if (val) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (/(^[0-9][0-9]):([0-5][0-9]):([0-5][0-9])\.([0-9][0-9][0-9]$)/.exec(val)) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
// split val
|
|
111
|
-
|
|
112
|
-
var timeArray = val.split(/[.:]+/);
|
|
113
|
-
|
|
114
|
-
console.log('time array is ' + timeArray[0] + ':' + timeArray[1] + ':' + timeArray[2] + ':' + timeArray[3]);
|
|
115
|
-
|
|
116
|
-
console.log('this.id = ' + this.id);
|
|
117
|
-
|
|
118
|
-
setTimeout(() => {
|
|
119
|
-
|
|
120
|
-
this.myElement.querySelector('input[name="startHours"]').value = timeArray[0];
|
|
121
|
-
this.myElement.querySelector('input[name="startMinutes"]').value = timeArray[1];
|
|
122
|
-
this.myElement.querySelector('input[name="startSeconds"]').value = timeArray[2];
|
|
123
|
-
this.myElement.querySelector('input[name="startMilliSecs"]').value = timeArray[3];
|
|
124
|
-
|
|
125
|
-
}, 0);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
this.setAttribute('value', val);
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
else {
|
|
133
|
-
|
|
134
|
-
console.warn(`The specified value ${val} does not conform to the required format. The format is "HH:mm:ss.SSS" where HH is 00-99, mm is 00-59, ss is 00-59, and SSS is 000-999.`);
|
|
163
|
+
if (!val) {
|
|
164
|
+
this.resetInputs();
|
|
165
|
+
this.removeAttribute('value');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
135
168
|
|
|
136
|
-
|
|
169
|
+
if (typeof val !== 'string' || !this.isValidValue(val)) {
|
|
170
|
+
this.warnInvalidValue(val);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
137
173
|
|
|
138
|
-
|
|
139
|
-
// gives a False bool and removes value from Webcomponent chronlyHMS
|
|
174
|
+
this.setInputValues(val);
|
|
140
175
|
|
|
141
|
-
|
|
176
|
+
if (this.getAttribute('value') !== val) {
|
|
177
|
+
this.setAttribute('value', val);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
142
180
|
|
|
143
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Checks whether a value follows the supported duration format and ranges.
|
|
183
|
+
*
|
|
184
|
+
* @param {*} val - Candidate value.
|
|
185
|
+
* @returns {boolean} Whether the value is valid `HH:mm:ss.SSS`.
|
|
186
|
+
*/
|
|
187
|
+
isValidValue(val) {
|
|
188
|
+
return typeof val === 'string' &&
|
|
189
|
+
/^[0-9]{2}:[0-5][0-9]:[0-5][0-9]\.[0-9]{3}$/.test(val);
|
|
190
|
+
}
|
|
144
191
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Copies a validated duration string into the four shadow inputs.
|
|
194
|
+
*
|
|
195
|
+
* @param {string} val - Valid duration in `HH:mm:ss.SSS` format.
|
|
196
|
+
* @returns {void}
|
|
197
|
+
*/
|
|
198
|
+
setInputValues(val) {
|
|
199
|
+
const timeArray = val.split(/[.:]+/);
|
|
200
|
+
const inputNames = ['startHours', 'startMinutes', 'startSeconds', 'startMilliSecs'];
|
|
201
|
+
|
|
202
|
+
inputNames.forEach((name, index) => {
|
|
203
|
+
const input = this.myElement.querySelector(`input[name="${name}"]`);
|
|
204
|
+
input.value = timeArray[index];
|
|
205
|
+
input.oldValue = input.value;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
149
208
|
|
|
150
|
-
|
|
209
|
+
/**
|
|
210
|
+
* Resets all duration fields to zero.
|
|
211
|
+
*
|
|
212
|
+
* @returns {void}
|
|
213
|
+
*/
|
|
214
|
+
resetInputs() {
|
|
215
|
+
const defaults = ['00', '00', '00', '000'];
|
|
216
|
+
const inputs = this.myElement.querySelectorAll('.timeCase input');
|
|
151
217
|
|
|
152
|
-
|
|
218
|
+
inputs.forEach((input, index) => {
|
|
219
|
+
input.value = defaults[index];
|
|
220
|
+
input.oldValue = input.value;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
153
223
|
|
|
154
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Reports a value that does not match the supported duration format.
|
|
226
|
+
*
|
|
227
|
+
* @param {*} val - Rejected value.
|
|
228
|
+
* @returns {void}
|
|
229
|
+
*/
|
|
230
|
+
warnInvalidValue(val) {
|
|
231
|
+
console.warn(`The specified value ${val} does not conform to the required format. The format is "HH:mm:ss.SSS" where HH is 00-99, mm is 00-59, ss is 00-59, and SSS is 000-999.`);
|
|
155
232
|
}
|
|
156
233
|
|
|
157
234
|
|
|
@@ -178,17 +255,13 @@ class InputDuration extends HTMLElement {
|
|
|
178
255
|
|
|
179
256
|
/**
|
|
180
257
|
* eventlistener that adds arrow key input of values (up/down) and place toggling (left/right) triggered by
|
|
181
|
-
* the change event of the input
|
|
258
|
+
* the change event of the input
|
|
182
259
|
* @method
|
|
183
260
|
* @see boot()
|
|
184
261
|
*/
|
|
185
262
|
|
|
186
263
|
addArrowKeyInput() {
|
|
187
264
|
|
|
188
|
-
console.log('1 this: ' + this);
|
|
189
|
-
console.log('1 this.myElement: ' + this.myElement);
|
|
190
|
-
console.log('1 this.myElement active: ' + this.myElement);
|
|
191
|
-
|
|
192
265
|
var mE = this.myElement;
|
|
193
266
|
|
|
194
267
|
// Left and Right arrow key toggle between HMSmS
|
|
@@ -259,18 +332,20 @@ class InputDuration extends HTMLElement {
|
|
|
259
332
|
var spanIn = document.createElement("div");
|
|
260
333
|
|
|
261
334
|
spanIn.classList.add('timeCase');
|
|
335
|
+
spanIn.setAttribute('part', 'control');
|
|
262
336
|
|
|
263
337
|
var template = document.createElement('template');
|
|
264
338
|
|
|
265
339
|
template.innerHTML = `
|
|
266
|
-
<input type="number" class="sH D2 ts_digit" name="startHours" data-tp="1" min="-1" max="100" value="00" >
|
|
267
|
-
<span class="bds-h">:</span>
|
|
268
|
-
<input type="number" class="sM D2 ts_digit" name="startMinutes" data-tp="2" min="-1" max="60" value="00">
|
|
269
|
-
<span class="bds-m">:</span>
|
|
270
|
-
<input type="number" class="sS D2 ts_digit" name="startSeconds" data-tp="3" min="-1" max="60" value="00">
|
|
271
|
-
<span class="bds-s">.</span>
|
|
272
|
-
<input type="number" class="sMS D3 ts_digit" name="startMilliSecs" data-tp="4" min="-10" max="1010" step="10" value="000">
|
|
273
|
-
<
|
|
340
|
+
<input type="number" class="sH D2 ts_digit" part="field field-hours" name="startHours" data-tp="1" min="-1" max="100" value="00" >
|
|
341
|
+
<span class="bds-h" part="divider divider-hours-minutes">:</span>
|
|
342
|
+
<input type="number" class="sM D2 ts_digit" part="field field-minutes" name="startMinutes" data-tp="2" min="-1" max="60" value="00">
|
|
343
|
+
<span class="bds-m" part="divider divider-minutes-seconds">:</span>
|
|
344
|
+
<input type="number" class="sS D2 ts_digit" part="field field-seconds" name="startSeconds" data-tp="3" min="-1" max="60" value="00">
|
|
345
|
+
<span class="bds-s" part="divider divider-seconds-milliseconds">.</span>
|
|
346
|
+
<input type="number" class="sMS D3 ts_digit" part="field field-milliseconds" name="startMilliSecs" data-tp="4" min="-10" max="1010" step="10" value="000">
|
|
347
|
+
<span class="bds-ms" part="divider divider-milliseconds-suffix" style="display: none"></span>
|
|
348
|
+
<div id="svgContainer" part="icon">
|
|
274
349
|
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true"
|
|
275
350
|
focusable="false" data-prefix="fal" data-icon="stopwatch" class="svg-inline--fa fa-stopwatch fa-w-14"
|
|
276
351
|
role="img" viewBox="0 0 448 512">
|
|
@@ -278,82 +353,103 @@ class InputDuration extends HTMLElement {
|
|
|
278
353
|
</svg>
|
|
279
354
|
</div>
|
|
280
355
|
<style>
|
|
281
|
-
|
|
282
|
-
|
|
356
|
+
:host {
|
|
357
|
+
display: inline-block;
|
|
358
|
+
color: inherit;
|
|
359
|
+
font: inherit;
|
|
360
|
+
vertical-align: middle;
|
|
361
|
+
--input-duration-gap: 0.08em;
|
|
362
|
+
--input-duration-padding: 0.4em 0.55em;
|
|
363
|
+
--input-duration-border-color: #9aa6b2;
|
|
364
|
+
--input-duration-border-radius: 0.4em;
|
|
365
|
+
--input-duration-background: transparent;
|
|
366
|
+
--input-duration-color: inherit;
|
|
367
|
+
--input-duration-focus-color: #2196f3;
|
|
368
|
+
--input-duration-focus-outline: 3px solid #2196f3;
|
|
369
|
+
--input-duration-focus-outline-offset: 2px;
|
|
370
|
+
--input-duration-divider-color: currentColor;
|
|
371
|
+
--input-duration-divider-opacity: 0.7;
|
|
372
|
+
--input-duration-disabled-color: GrayText;
|
|
373
|
+
--input-duration-icon-color: inherit;
|
|
283
374
|
}
|
|
284
375
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
376
|
+
.timeCase,
|
|
377
|
+
.timeCase[part~="control"] {
|
|
378
|
+
display: inline-flex;
|
|
379
|
+
align-items: center;
|
|
380
|
+
gap: var(--input-duration-gap);
|
|
381
|
+
max-width: 100%;
|
|
382
|
+
padding: var(--input-duration-padding);
|
|
383
|
+
border: 1px solid var(--input-duration-border-color);
|
|
384
|
+
border-radius: var(--input-duration-border-radius);
|
|
385
|
+
background: var(--input-duration-background);
|
|
386
|
+
color: var(--input-duration-color);
|
|
387
|
+
font-variant-numeric: tabular-nums;
|
|
388
|
+
line-height: 1.4;
|
|
389
|
+
white-space: nowrap;
|
|
294
390
|
}
|
|
295
391
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
width: 15px;
|
|
301
|
-
padding-top:1px;
|
|
392
|
+
.timeCase:focus-within {
|
|
393
|
+
border-color: var(--input-duration-focus-color);
|
|
394
|
+
outline: var(--input-duration-focus-outline);
|
|
395
|
+
outline-offset: var(--input-duration-focus-outline-offset);
|
|
302
396
|
}
|
|
303
397
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
398
|
+
.timeCase input {
|
|
399
|
+
box-sizing: content-box;
|
|
400
|
+
width: 2ch;
|
|
401
|
+
min-width: 2ch;
|
|
402
|
+
margin: 0;
|
|
403
|
+
padding: 0;
|
|
404
|
+
border: 0;
|
|
405
|
+
outline: 0;
|
|
406
|
+
background: transparent;
|
|
407
|
+
color: inherit;
|
|
408
|
+
font: inherit;
|
|
409
|
+
font-variant-numeric: tabular-nums;
|
|
410
|
+
text-align: center;
|
|
411
|
+
caret-color: transparent;
|
|
412
|
+
appearance: textfield;
|
|
307
413
|
}
|
|
308
414
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
/* Chrome, Safari, Edge, Opera */
|
|
313
|
-
|
|
314
|
-
input::-webkit-outer-spin-button,
|
|
315
|
-
input::-webkit-inner-spin-button {
|
|
316
|
-
-webkit-appearance: none;
|
|
317
|
-
margin: 0;
|
|
415
|
+
.timeCase input.D3 {
|
|
416
|
+
width: 3ch;
|
|
417
|
+
min-width: 3ch;
|
|
318
418
|
}
|
|
319
419
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
/* -moz-appearance: textfield; */
|
|
325
|
-
-moz-appearance: textarea;
|
|
326
|
-
-webkit-appearance: textarea;
|
|
420
|
+
.timeCase input::-webkit-outer-spin-button,
|
|
421
|
+
.timeCase input::-webkit-inner-spin-button {
|
|
422
|
+
margin: 0;
|
|
423
|
+
appearance: none;
|
|
327
424
|
}
|
|
328
425
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
padding: 2px;
|
|
426
|
+
.timeCase span {
|
|
427
|
+
color: var(--input-duration-divider-color);
|
|
428
|
+
opacity: var(--input-duration-divider-opacity);
|
|
333
429
|
}
|
|
334
430
|
|
|
431
|
+
#svgContainer {
|
|
432
|
+
display: inline-flex;
|
|
433
|
+
width: 1em;
|
|
434
|
+
height: 1em;
|
|
435
|
+
flex: 0 0 auto;
|
|
436
|
+
align-items: center;
|
|
437
|
+
justify-content: center;
|
|
438
|
+
margin-left: 0.2em;
|
|
439
|
+
color: var(--input-duration-icon-color);
|
|
440
|
+
}
|
|
335
441
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
/* between digit span */
|
|
341
|
-
.bds{
|
|
342
|
-
padding-bottom: 1px;
|
|
442
|
+
#svgContainer svg {
|
|
443
|
+
display: block;
|
|
444
|
+
width: 100%;
|
|
445
|
+
height: 100%;
|
|
343
446
|
}
|
|
344
447
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
color: black;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
*:disabled {
|
|
354
|
-
background-color: grey;
|
|
355
|
-
color: lightgrey;
|
|
356
|
-
opacity: .6;
|
|
448
|
+
.timeCase input:disabled {
|
|
449
|
+
background: transparent;
|
|
450
|
+
color: var(--input-duration-disabled-color);
|
|
451
|
+
cursor: not-allowed;
|
|
452
|
+
opacity: 0.65;
|
|
357
453
|
}
|
|
358
454
|
</style> `
|
|
359
455
|
|
|
@@ -366,7 +462,7 @@ class InputDuration extends HTMLElement {
|
|
|
366
462
|
|
|
367
463
|
/**
|
|
368
464
|
* eventlistener that adds number looping for up and down keys triggered by
|
|
369
|
-
* the change event of the input
|
|
465
|
+
* the change event of the input
|
|
370
466
|
* @method
|
|
371
467
|
* @see boot()
|
|
372
468
|
*/
|
|
@@ -432,7 +528,7 @@ class InputDuration extends HTMLElement {
|
|
|
432
528
|
|
|
433
529
|
|
|
434
530
|
/**
|
|
435
|
-
* eventlistener that
|
|
531
|
+
* eventlistener that filters number input and advances between fields
|
|
436
532
|
* @method
|
|
437
533
|
* @see boot()
|
|
438
534
|
*/
|
|
@@ -445,26 +541,13 @@ class InputDuration extends HTMLElement {
|
|
|
445
541
|
// Digit input 0-9 (typed in by user)
|
|
446
542
|
|
|
447
543
|
function setInputFilter(inputElement, inputFilter) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
window.kue = event;
|
|
456
|
-
|
|
457
|
-
if (/^([0-9]?)$/.test(event.key)) {
|
|
458
|
-
if (inputFilter(this.value)) {
|
|
459
|
-
this.oldValue = this.value;
|
|
460
|
-
this.oldSelectionStart = this.selectionStart;
|
|
461
|
-
this.oldSelectionEnd = this.selectionEnd;
|
|
462
|
-
} else if (this.hasOwnProperty("oldValue")) {
|
|
463
|
-
this.value = this.oldValue;
|
|
464
|
-
// this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd);
|
|
465
|
-
} else {
|
|
466
|
-
this.value = "";
|
|
467
|
-
}
|
|
544
|
+
inputElement.oldValue = inputElement.value;
|
|
545
|
+
|
|
546
|
+
inputElement.addEventListener('input', function () {
|
|
547
|
+
if (inputFilter(this.value)) {
|
|
548
|
+
this.oldValue = this.value;
|
|
549
|
+
} else {
|
|
550
|
+
this.value = this.oldValue;
|
|
468
551
|
}
|
|
469
552
|
});
|
|
470
553
|
}
|
|
@@ -478,7 +561,7 @@ class InputDuration extends HTMLElement {
|
|
|
478
561
|
var newV = /^([0-9]?|[0-9][0-9]?)$/.test(value);
|
|
479
562
|
|
|
480
563
|
|
|
481
|
-
if (value.length === 2) {
|
|
564
|
+
if (newV && value.length === 2) {
|
|
482
565
|
|
|
483
566
|
mE.querySelector('input.sM').focus();
|
|
484
567
|
mE.querySelector('input.sM').select();
|
|
@@ -495,7 +578,7 @@ class InputDuration extends HTMLElement {
|
|
|
495
578
|
|
|
496
579
|
var newV = /^([0-9]?|[0-5][0-9]?)$/.test(value);
|
|
497
580
|
|
|
498
|
-
if (value > 5 || value.length === 2) {
|
|
581
|
+
if (newV && (value > 5 || value.length === 2)) {
|
|
499
582
|
|
|
500
583
|
mE.querySelector('input.sS').focus();
|
|
501
584
|
mE.querySelector('input.sS').select();
|
|
@@ -511,7 +594,7 @@ class InputDuration extends HTMLElement {
|
|
|
511
594
|
|
|
512
595
|
var newV = /^([0-9]?|[0-5][0-9]?)$/.test(value);
|
|
513
596
|
|
|
514
|
-
if (value > 5 || value.length === 2) {
|
|
597
|
+
if (newV && (value > 5 || value.length === 2)) {
|
|
515
598
|
|
|
516
599
|
mE.querySelector('input.sMS').focus();
|
|
517
600
|
mE.querySelector('input.sMS').select();
|
|
@@ -529,7 +612,7 @@ class InputDuration extends HTMLElement {
|
|
|
529
612
|
var newV = /^([0-9]?|[0-9][0-9]?|[0-9][0-9][0-9]?)$/.test(value);
|
|
530
613
|
|
|
531
614
|
|
|
532
|
-
if (value.length === 3) {
|
|
615
|
+
if (newV && value.length === 3) {
|
|
533
616
|
|
|
534
617
|
mE.querySelector('input.sMS').blur();
|
|
535
618
|
|
|
@@ -543,7 +626,7 @@ class InputDuration extends HTMLElement {
|
|
|
543
626
|
|
|
544
627
|
/**
|
|
545
628
|
* eventlistener that adds 0s to preface numbers less than 10 triggered by
|
|
546
|
-
* the change event of the input
|
|
629
|
+
* the change event of the input
|
|
547
630
|
* @method
|
|
548
631
|
* @see boot()
|
|
549
632
|
*/
|
|
@@ -567,11 +650,11 @@ class InputDuration extends HTMLElement {
|
|
|
567
650
|
}));
|
|
568
651
|
|
|
569
652
|
}
|
|
570
|
-
|
|
653
|
+
|
|
571
654
|
|
|
572
655
|
/**
|
|
573
656
|
* eventlistener that adds click to activate input of values by the keyboard triggered by
|
|
574
|
-
* the click event of the input
|
|
657
|
+
* the click event of the input
|
|
575
658
|
* @method
|
|
576
659
|
* @see boot()
|
|
577
660
|
*/
|
|
@@ -584,7 +667,7 @@ class InputDuration extends HTMLElement {
|
|
|
584
667
|
|
|
585
668
|
/**
|
|
586
669
|
* eventlistener that adds key filtering to stop letters (or other non-numerics) from being input triggered by
|
|
587
|
-
* the keypress event of the input
|
|
670
|
+
* the keypress event of the input
|
|
588
671
|
* @method
|
|
589
672
|
* @see boot()
|
|
590
673
|
*/
|
|
@@ -606,25 +689,30 @@ class InputDuration extends HTMLElement {
|
|
|
606
689
|
}
|
|
607
690
|
|
|
608
691
|
/**
|
|
609
|
-
* Stop event propigation from the timeCase up through the DOM so when keys
|
|
692
|
+
* Stop event propigation from the timeCase up through the DOM so when keys
|
|
610
693
|
* are being used they don't affect other controls (like volume on plyr)
|
|
611
694
|
* @method
|
|
612
695
|
*/
|
|
613
696
|
|
|
614
697
|
removeEprop() {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
698
|
+
|
|
699
|
+
var closure = this;
|
|
700
|
+
|
|
701
|
+
closure.shadowRoot.querySelector('.timeCase')
|
|
702
|
+
.addEventListener('keydown', function (event) { event.stopPropagation();});
|
|
703
|
+
|
|
704
|
+
// document.querySelectorAll('input-duration').forEach(x => x.shadowRoot.querySelector('.timeCase')
|
|
705
|
+
// .addEventListener('keydown', function (event) { event.stopPropagation();}));
|
|
618
706
|
|
|
619
707
|
}
|
|
620
708
|
|
|
621
709
|
|
|
622
|
-
|
|
710
|
+
|
|
623
711
|
// formatting and behaviour options
|
|
624
712
|
|
|
625
713
|
/**
|
|
626
714
|
* disables entire control => read-only
|
|
627
|
-
* @method
|
|
715
|
+
* @method
|
|
628
716
|
*/
|
|
629
717
|
|
|
630
718
|
disable() {
|
|
@@ -639,31 +727,228 @@ class InputDuration extends HTMLElement {
|
|
|
639
727
|
|
|
640
728
|
|
|
641
729
|
/**
|
|
642
|
-
*
|
|
643
|
-
*
|
|
730
|
+
* Hides the hours field and its adjacent divider.
|
|
731
|
+
* Sets the `no-hours` attribute.
|
|
732
|
+
*
|
|
733
|
+
* @returns {void}
|
|
644
734
|
*/
|
|
735
|
+
hideHours() {
|
|
736
|
+
this.setAttribute('no-hours', '');
|
|
737
|
+
}
|
|
645
738
|
|
|
739
|
+
/**
|
|
740
|
+
* Shows the hours field and its adjacent divider.
|
|
741
|
+
* Removes the `no-hours` attribute.
|
|
742
|
+
*
|
|
743
|
+
* @returns {void}
|
|
744
|
+
*/
|
|
745
|
+
showHours() {
|
|
746
|
+
this.removeAttribute('no-hours');
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Backward-compatible alias for {@link InputDuration#hideHours}.
|
|
751
|
+
*
|
|
752
|
+
* @returns {void}
|
|
753
|
+
*/
|
|
646
754
|
noHours() {
|
|
755
|
+
this.hideHours();
|
|
756
|
+
}
|
|
647
757
|
|
|
648
|
-
|
|
758
|
+
/**
|
|
759
|
+
* Hides the minutes field and its adjacent divider.
|
|
760
|
+
* Sets the `no-minutes` attribute.
|
|
761
|
+
*
|
|
762
|
+
* @returns {void}
|
|
763
|
+
*/
|
|
764
|
+
hideMinutes() {
|
|
765
|
+
this.setAttribute('no-minutes', '');
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Shows the minutes field and its adjacent divider.
|
|
770
|
+
* Removes the `no-minutes` attribute.
|
|
771
|
+
*
|
|
772
|
+
* @returns {void}
|
|
773
|
+
*/
|
|
774
|
+
showMinutes() {
|
|
775
|
+
this.removeAttribute('no-minutes');
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Backward-compatible alias for {@link InputDuration#hideMinutes}.
|
|
780
|
+
*
|
|
781
|
+
* @returns {void}
|
|
782
|
+
*/
|
|
783
|
+
noMinutes() {
|
|
784
|
+
this.hideMinutes();
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Hides the seconds field and its adjacent divider.
|
|
789
|
+
* Sets the `no-seconds` attribute.
|
|
790
|
+
*
|
|
791
|
+
* @returns {void}
|
|
792
|
+
*/
|
|
793
|
+
hideSeconds() {
|
|
794
|
+
this.setAttribute('no-seconds', '');
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Shows the seconds field and its adjacent divider.
|
|
799
|
+
* Removes the `no-seconds` attribute.
|
|
800
|
+
*
|
|
801
|
+
* @returns {void}
|
|
802
|
+
*/
|
|
803
|
+
showSeconds() {
|
|
804
|
+
this.removeAttribute('no-seconds');
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Backward-compatible alias for {@link InputDuration#hideSeconds}.
|
|
809
|
+
*
|
|
810
|
+
* @returns {void}
|
|
811
|
+
*/
|
|
812
|
+
noSeconds() {
|
|
813
|
+
this.hideSeconds();
|
|
814
|
+
}
|
|
649
815
|
|
|
650
|
-
|
|
816
|
+
/**
|
|
817
|
+
* Hides the milliseconds field and its adjacent divider or suffix.
|
|
818
|
+
* Sets the `no-microseconds` attribute.
|
|
819
|
+
*
|
|
820
|
+
* @returns {void}
|
|
821
|
+
*/
|
|
822
|
+
hideMicroSeconds() {
|
|
823
|
+
this.setAttribute('no-microseconds', '');
|
|
824
|
+
}
|
|
651
825
|
|
|
652
|
-
|
|
826
|
+
/**
|
|
827
|
+
* Shows the milliseconds field and its adjacent divider or suffix.
|
|
828
|
+
* Removes the `no-microseconds` attribute.
|
|
829
|
+
*
|
|
830
|
+
* @returns {void}
|
|
831
|
+
*/
|
|
832
|
+
showMicroSeconds() {
|
|
833
|
+
this.removeAttribute('no-microseconds');
|
|
834
|
+
}
|
|
653
835
|
|
|
836
|
+
/**
|
|
837
|
+
* Backward-compatible alias for {@link InputDuration#hideMicroSeconds}.
|
|
838
|
+
*
|
|
839
|
+
* @returns {void}
|
|
840
|
+
*/
|
|
841
|
+
noMicroSeconds() {
|
|
842
|
+
this.hideMicroSeconds();
|
|
843
|
+
}
|
|
654
844
|
|
|
655
|
-
|
|
845
|
+
/**
|
|
846
|
+
* Replaces the hours/minutes separator.
|
|
847
|
+
* Also available through the `hours-divider` attribute.
|
|
848
|
+
*
|
|
849
|
+
* @param {string} text - Divider text to display.
|
|
850
|
+
* @returns {void}
|
|
851
|
+
*/
|
|
852
|
+
setHoursDivider(text) {
|
|
853
|
+
this.setAttribute('hours-divider', text);
|
|
854
|
+
}
|
|
656
855
|
|
|
657
|
-
|
|
856
|
+
/**
|
|
857
|
+
* Replaces the minutes/seconds separator.
|
|
858
|
+
* Also available through the `minutes-divider` attribute.
|
|
859
|
+
*
|
|
860
|
+
* @param {string} text - Divider text to display.
|
|
861
|
+
* @returns {void}
|
|
862
|
+
*/
|
|
863
|
+
setMinutesDivider(text) {
|
|
864
|
+
this.setAttribute('minutes-divider', text);
|
|
865
|
+
}
|
|
658
866
|
|
|
867
|
+
/**
|
|
868
|
+
* Replaces the seconds/milliseconds separator.
|
|
869
|
+
* Also available through the `seconds-divider` attribute.
|
|
870
|
+
*
|
|
871
|
+
* @param {string} text - Divider text to display.
|
|
872
|
+
* @returns {void}
|
|
873
|
+
*/
|
|
874
|
+
setSecondsDivider(text) {
|
|
875
|
+
this.setAttribute('seconds-divider', text);
|
|
659
876
|
}
|
|
660
|
-
|
|
877
|
+
|
|
878
|
+
/**
|
|
879
|
+
* Sets a suffix to display after milliseconds.
|
|
880
|
+
* Also available through the `microseconds-divider` attribute.
|
|
881
|
+
*
|
|
882
|
+
* @param {string} text - Suffix text to display.
|
|
883
|
+
* @returns {void}
|
|
884
|
+
*/
|
|
885
|
+
setMicroSecondsDivider(text) {
|
|
886
|
+
this.setAttribute('microseconds-divider', text);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Synchronizes field and divider visibility with the `no-*` attributes.
|
|
891
|
+
*
|
|
892
|
+
* @returns {void}
|
|
893
|
+
*/
|
|
894
|
+
updateVisibleFields() {
|
|
895
|
+
const hiddenFields = {
|
|
896
|
+
'no-hours': '.sH',
|
|
897
|
+
'no-minutes': '.sM',
|
|
898
|
+
'no-seconds': '.sS',
|
|
899
|
+
'no-microseconds': '.sMS'
|
|
900
|
+
};
|
|
901
|
+
const hiddenDividers = {
|
|
902
|
+
'.bds-h': ['no-hours', 'no-minutes'],
|
|
903
|
+
'.bds-m': ['no-seconds'],
|
|
904
|
+
'.bds-s': ['no-microseconds'],
|
|
905
|
+
'.bds-ms': ['no-microseconds']
|
|
906
|
+
};
|
|
907
|
+
|
|
908
|
+
for (const [attribute, selector] of Object.entries(hiddenFields)) {
|
|
909
|
+
const field = this.myElement.querySelector(selector);
|
|
910
|
+
field.style.display = this.hasAttribute(attribute) ? 'none' : '';
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
for (const [selector, attributes] of Object.entries(hiddenDividers)) {
|
|
914
|
+
const divider = this.myElement.querySelector(selector);
|
|
915
|
+
const shouldHide = attributes.some(attribute => this.hasAttribute(attribute));
|
|
916
|
+
divider.style.display = shouldHide ? 'none' : '';
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* Synchronizes divider text with the corresponding divider attributes.
|
|
922
|
+
*
|
|
923
|
+
* @returns {void}
|
|
924
|
+
*/
|
|
925
|
+
updateDividers() {
|
|
926
|
+
const dividers = {
|
|
927
|
+
'hours-divider': ['.bds-h', ':'],
|
|
928
|
+
'minutes-divider': ['.bds-m', ':'],
|
|
929
|
+
'seconds-divider': ['.bds-s', '.'],
|
|
930
|
+
'microseconds-divider': ['.bds-ms', '']
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
for (const [attribute, [selector, defaultText]] of Object.entries(dividers)) {
|
|
934
|
+
const divider = this.myElement.querySelector(selector);
|
|
935
|
+
const text = this.getAttribute(attribute) ?? defaultText;
|
|
936
|
+
divider.textContent = text;
|
|
937
|
+
if (selector === '.bds-ms') {
|
|
938
|
+
divider.style.display = text && !this.hasAttribute('no-microseconds') ? '' : 'none';
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
661
943
|
// end class
|
|
662
944
|
|
|
663
945
|
|
|
664
|
-
|
|
946
|
+
customElements.define('input-duration', InputDuration);
|
|
947
|
+
|
|
948
|
+
export default InputDuration;
|
|
665
949
|
|
|
666
|
-
// an option is to make all above an IIFE
|
|
950
|
+
// an option is to make all above an IIFE
|
|
951
|
+
</code></pre>
|
|
667
952
|
</article>
|
|
668
953
|
</section>
|
|
669
954
|
|
|
@@ -679,7 +964,7 @@ export default customElements.define('input-duration', InputDuration);
|
|
|
679
964
|
<br class="clear">
|
|
680
965
|
|
|
681
966
|
<footer>
|
|
682
|
-
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.
|
|
967
|
+
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.5</a> on Thu Nov 05 2026 14:15:36 GMT+0000 (Coordinated Universal Time)
|
|
683
968
|
</footer>
|
|
684
969
|
|
|
685
970
|
<script> prettyPrint(); </script>
|