bootstrap5-toggle 5.2.0-rc2 → 5.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 +17 -12
- package/README.template.md +11 -6
- package/css/bootstrap5-toggle.css +1 -1
- package/css/bootstrap5-toggle.min.css +1 -1
- package/js/bootstrap5-toggle.ecmas.js +343 -154
- package/js/bootstrap5-toggle.ecmas.js.map +1 -1
- package/js/bootstrap5-toggle.ecmas.min.js +2 -2
- package/js/bootstrap5-toggle.ecmas.min.js.map +1 -1
- package/js/bootstrap5-toggle.jquery.js +341 -152
- package/js/bootstrap5-toggle.jquery.js.map +1 -1
- package/js/bootstrap5-toggle.jquery.min.js +2 -2
- package/js/bootstrap5-toggle.jquery.min.js.map +1 -1
- package/package.json +18 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Copyright Notice
|
|
2
|
-
* bootstrap5-toggle v5.2.0
|
|
2
|
+
* bootstrap5-toggle v5.2.0
|
|
3
3
|
* https://palcarazm.github.io/bootstrap5-toggle/
|
|
4
4
|
* @author 2011-2014 Min Hur (https://github.com/minhur)
|
|
5
5
|
* @author 2018-2019 Brent Ely (https://github.com/gitbrent)
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
DOMBuilder.prototype.createInvCheckbox = function (offValue) {
|
|
136
136
|
var invCheckbox = this.checkbox.cloneNode(true);
|
|
137
137
|
invCheckbox.value = offValue;
|
|
138
|
-
invCheckbox.
|
|
138
|
+
invCheckbox.dataset.toggle = "invert-toggle";
|
|
139
139
|
invCheckbox.removeAttribute("id");
|
|
140
140
|
return invCheckbox;
|
|
141
141
|
};
|
|
@@ -151,8 +151,8 @@
|
|
|
151
151
|
DOMBuilder.prototype.renderToggle = function (_a) {
|
|
152
152
|
var _b;
|
|
153
153
|
var style = _a.style, width = _a.width, height = _a.height, tabindex = _a.tabindex;
|
|
154
|
-
this.toggle.
|
|
155
|
-
this.toggle.
|
|
154
|
+
this.toggle.className = "toggle btn ".concat(this.sizeClass, " ").concat(style);
|
|
155
|
+
this.toggle.dataset.toggle = "toggle";
|
|
156
156
|
this.toggle.tabIndex = tabindex;
|
|
157
157
|
this.toggle.role = "button";
|
|
158
158
|
(_b = this.checkbox.parentElement) === null || _b === void 0 ? void 0 : _b.insertBefore(this.toggle, this.checkbox);
|
|
@@ -170,7 +170,7 @@
|
|
|
170
170
|
*/
|
|
171
171
|
DOMBuilder.prototype.createToggleGroup = function () {
|
|
172
172
|
var toggleGroup = document.createElement("div");
|
|
173
|
-
toggleGroup.
|
|
173
|
+
toggleGroup.className = "toggle-group";
|
|
174
174
|
toggleGroup.appendChild(this.toggleOn);
|
|
175
175
|
toggleGroup.appendChild(this.toggleOff);
|
|
176
176
|
toggleGroup.appendChild(this.toggleHandle);
|
|
@@ -188,10 +188,10 @@
|
|
|
188
188
|
*/
|
|
189
189
|
DOMBuilder.prototype.createToggleSpan = function (label, style, title) {
|
|
190
190
|
var toggleSpan = document.createElement("span");
|
|
191
|
-
toggleSpan.
|
|
191
|
+
toggleSpan.className = "btn ".concat(this.sizeClass, " ").concat(style);
|
|
192
192
|
toggleSpan.innerHTML = label;
|
|
193
193
|
if (title)
|
|
194
|
-
toggleSpan.
|
|
194
|
+
toggleSpan.title = title;
|
|
195
195
|
return toggleSpan;
|
|
196
196
|
};
|
|
197
197
|
/**
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
*/
|
|
202
202
|
DOMBuilder.prototype.createToggleHandle = function () {
|
|
203
203
|
var toggleHandle = document.createElement("span");
|
|
204
|
-
toggleHandle.
|
|
204
|
+
toggleHandle.className = "toggle-handle btn ".concat(this.sizeClass);
|
|
205
205
|
return toggleHandle;
|
|
206
206
|
};
|
|
207
207
|
/**
|
|
@@ -212,15 +212,6 @@
|
|
|
212
212
|
* @param height The height of the toggle element.
|
|
213
213
|
*/
|
|
214
214
|
DOMBuilder.prototype.handleToggleSize = function (width, height) {
|
|
215
|
-
function calcH(toggleSpan) {
|
|
216
|
-
var styles = window.getComputedStyle(toggleSpan);
|
|
217
|
-
var height = toggleSpan.offsetHeight;
|
|
218
|
-
var borderTopWidth = parseFloat(styles.borderTopWidth);
|
|
219
|
-
var borderBottomWidth = parseFloat(styles.borderBottomWidth);
|
|
220
|
-
var paddingTop = parseFloat(styles.paddingTop);
|
|
221
|
-
var paddingBottom = parseFloat(styles.paddingBottom);
|
|
222
|
-
return (height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom);
|
|
223
|
-
}
|
|
224
215
|
if (width) {
|
|
225
216
|
this.toggle.style.width = width;
|
|
226
217
|
}
|
|
@@ -241,20 +232,50 @@
|
|
|
241
232
|
this.toggleOff.classList.add("toggle-off");
|
|
242
233
|
// C: Finally, set lineHeight if needed
|
|
243
234
|
if (height) {
|
|
244
|
-
this.toggleOn.style.lineHeight = calcH(this.toggleOn) + "px";
|
|
245
|
-
this.toggleOff.style.lineHeight = calcH(this.toggleOff) + "px";
|
|
235
|
+
this.toggleOn.style.lineHeight = DOMBuilder.calcH(this.toggleOn) + "px";
|
|
236
|
+
this.toggleOff.style.lineHeight = DOMBuilder.calcH(this.toggleOff) + "px";
|
|
246
237
|
}
|
|
247
238
|
};
|
|
239
|
+
/**
|
|
240
|
+
* Calculates the height of the toggle element that should be used for the line-height property.
|
|
241
|
+
* This calculation is used when the toggle element is given a height that is not explicitly set.
|
|
242
|
+
* The calculation takes into account the height of the toggle element, the border-top and border-bottom widths,
|
|
243
|
+
* and the padding-top and padding-bottom of the toggle element.
|
|
244
|
+
* @param toggleSpan The HTMLElement that represents the toggle element.
|
|
245
|
+
* @returns The height of the toggle element that should be used for the line-height property.
|
|
246
|
+
*/
|
|
247
|
+
DOMBuilder.calcH = function (toggleSpan) {
|
|
248
|
+
var styles = globalThis.window.getComputedStyle(toggleSpan);
|
|
249
|
+
var height = toggleSpan.offsetHeight;
|
|
250
|
+
var borderTopWidth = Number.parseFloat(styles.borderTopWidth);
|
|
251
|
+
var borderBottomWidth = Number.parseFloat(styles.borderBottomWidth);
|
|
252
|
+
var paddingTop = Number.parseFloat(styles.paddingTop);
|
|
253
|
+
var paddingBottom = Number.parseFloat(styles.paddingBottom);
|
|
254
|
+
return (height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom);
|
|
255
|
+
};
|
|
248
256
|
/**
|
|
249
257
|
* Renders the toggle element based on the provided state if the toggle is already built.
|
|
250
258
|
* This method should be called whenever the state of the toggle changes.
|
|
251
259
|
* @param {ToggleState} state The state of the toggle element.
|
|
252
260
|
*/
|
|
253
261
|
DOMBuilder.prototype.render = function (state) {
|
|
254
|
-
this.toggle.classList.remove(this.onStyle, this.offStyle, "off", "indeterminate");
|
|
255
262
|
this.lastState = state;
|
|
256
263
|
if (!this.isBuilt)
|
|
257
264
|
return;
|
|
265
|
+
this.updateToggleByValue(state);
|
|
266
|
+
this.updateToggleByChecked(state);
|
|
267
|
+
this.updateToggleByState(state);
|
|
268
|
+
};
|
|
269
|
+
/************* ✨ Windsurf Command ⭐ *************/
|
|
270
|
+
/**
|
|
271
|
+
* Updates the class of the toggle element based on the provided state.
|
|
272
|
+
* Removes any existing on/off/indeterminate classes and adds the appropriate class based on the state.
|
|
273
|
+
* If the state is indeterminate, adds the 'indeterminate' class and either the on or off class based on the checked attribute.
|
|
274
|
+
* @param {ToggleState} state The state of the toggle element.
|
|
275
|
+
*/
|
|
276
|
+
/******* 9e620de0-7e60-44a0-b26d-be36099794af *******/
|
|
277
|
+
DOMBuilder.prototype.updateToggleByValue = function (state) {
|
|
278
|
+
this.toggle.classList.remove(this.onStyle, this.offStyle, "off", "indeterminate");
|
|
258
279
|
switch (state.value) {
|
|
259
280
|
case ToggleStateValue.ON:
|
|
260
281
|
this.toggle.classList.add(this.onStyle);
|
|
@@ -272,42 +293,78 @@
|
|
|
272
293
|
}
|
|
273
294
|
break;
|
|
274
295
|
}
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Updates the toggle element based on the provided state.
|
|
299
|
+
* Calls {@link DOMBuilder.updateCheckboxByChecked} and {@link DOMBuilder.updateInvCheckboxByChecked} to update the checkbox and inverted checkbox elements respectively.
|
|
300
|
+
* @param {ToggleState} state The state of the toggle element.
|
|
301
|
+
*/
|
|
302
|
+
DOMBuilder.prototype.updateToggleByChecked = function (state) {
|
|
303
|
+
this.updateCheckboxByChecked(state);
|
|
304
|
+
this.updateInvCheckboxByChecked(state);
|
|
305
|
+
};
|
|
306
|
+
/**
|
|
307
|
+
* Updates the checkbox element based on the provided state.
|
|
308
|
+
* Sets the checked attribute of the checkbox based on the state's checked attribute.
|
|
309
|
+
* Sets the disabled and readonly attributes of the checkbox based on the state's status.
|
|
310
|
+
* Adds or removes the 'disabled' class from the toggle element based on the state's status.
|
|
311
|
+
* @param {ToggleState} state The state of the toggle element.
|
|
312
|
+
*/
|
|
313
|
+
DOMBuilder.prototype.updateCheckboxByChecked = function (state) {
|
|
275
314
|
this.checkbox.checked = state.checked;
|
|
276
|
-
if (this.invCheckbox)
|
|
277
|
-
this.invCheckbox.checked = !state.checked;
|
|
278
|
-
this.toggle.classList.add(state.checked ? this.onStyle : this.offStyle);
|
|
279
315
|
switch (state.status) {
|
|
280
316
|
case ToggleStateStatus.ENABLED:
|
|
281
|
-
this.toggle.classList.remove("disabled");
|
|
282
|
-
this.toggle.removeAttribute("disabled");
|
|
283
317
|
this.checkbox.disabled = false;
|
|
284
318
|
this.checkbox.readOnly = false;
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
this.invCheckbox.readOnly = false;
|
|
288
|
-
}
|
|
319
|
+
this.toggle.classList.remove("disabled");
|
|
320
|
+
this.toggle.removeAttribute("disabled");
|
|
289
321
|
break;
|
|
290
322
|
case ToggleStateStatus.DISABLED:
|
|
291
|
-
this.toggle.classList.add("disabled");
|
|
292
|
-
this.toggle.setAttribute("disabled", "");
|
|
293
323
|
this.checkbox.disabled = true;
|
|
294
324
|
this.checkbox.readOnly = false;
|
|
295
|
-
if (this.invCheckbox) {
|
|
296
|
-
this.invCheckbox.disabled = true;
|
|
297
|
-
this.invCheckbox.readOnly = false;
|
|
298
|
-
}
|
|
299
|
-
break;
|
|
300
|
-
case ToggleStateStatus.READONLY:
|
|
301
325
|
this.toggle.classList.add("disabled");
|
|
302
326
|
this.toggle.setAttribute("disabled", "");
|
|
327
|
+
break;
|
|
328
|
+
case ToggleStateStatus.READONLY:
|
|
303
329
|
this.checkbox.disabled = false;
|
|
304
330
|
this.checkbox.readOnly = true;
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
this.invCheckbox.readOnly = true;
|
|
308
|
-
}
|
|
331
|
+
this.toggle.classList.add("disabled");
|
|
332
|
+
this.toggle.setAttribute("disabled", "");
|
|
309
333
|
break;
|
|
310
334
|
}
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* Updates the inverted checkbox element based on the provided state.
|
|
338
|
+
* Sets the checked attribute of the inverted checkbox to the opposite of the state's checked attribute.
|
|
339
|
+
* Sets the disabled and readonly attributes of the inverted checkbox based on the state's status.
|
|
340
|
+
* @param {ToggleState} state The state of the toggle element.
|
|
341
|
+
*/
|
|
342
|
+
DOMBuilder.prototype.updateInvCheckboxByChecked = function (state) {
|
|
343
|
+
if (!this.invCheckbox)
|
|
344
|
+
return;
|
|
345
|
+
this.invCheckbox.checked = !state.checked;
|
|
346
|
+
switch (state.status) {
|
|
347
|
+
case ToggleStateStatus.ENABLED:
|
|
348
|
+
this.invCheckbox.disabled = false;
|
|
349
|
+
this.invCheckbox.readOnly = false;
|
|
350
|
+
break;
|
|
351
|
+
case ToggleStateStatus.DISABLED:
|
|
352
|
+
this.invCheckbox.disabled = true;
|
|
353
|
+
this.invCheckbox.readOnly = false;
|
|
354
|
+
break;
|
|
355
|
+
case ToggleStateStatus.READONLY:
|
|
356
|
+
this.invCheckbox.disabled = false;
|
|
357
|
+
this.invCheckbox.readOnly = true;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Updates the indeterminate attribute of the checkbox and inverted checkbox elements based on the provided state.
|
|
363
|
+
* If the state is indeterminate, sets the indeterminate attribute of the checkbox and inverted checkbox to true and removes the name attribute.
|
|
364
|
+
* If the state is not indeterminate, sets the indeterminate attribute of the checkbox and inverted checkbox to false and sets the name attribute to the provided name.
|
|
365
|
+
* @param {ToggleState} state The state of the toggle element.
|
|
366
|
+
*/
|
|
367
|
+
DOMBuilder.prototype.updateToggleByState = function (state) {
|
|
311
368
|
if (state.indeterminate) {
|
|
312
369
|
this.checkbox.indeterminate = true;
|
|
313
370
|
this.checkbox.removeAttribute("name");
|
|
@@ -343,10 +400,10 @@
|
|
|
343
400
|
* Also disconnects the ResizeObserver if it was used.
|
|
344
401
|
*/
|
|
345
402
|
DOMBuilder.prototype.destroy = function () {
|
|
346
|
-
var _a, _b
|
|
403
|
+
var _a, _b;
|
|
347
404
|
(_a = this.toggle.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(this.checkbox, this.toggle);
|
|
348
|
-
|
|
349
|
-
(
|
|
405
|
+
this.toggle.remove();
|
|
406
|
+
(_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
350
407
|
this.resizeObserver = undefined;
|
|
351
408
|
this.isBuilt = false;
|
|
352
409
|
};
|
|
@@ -364,6 +421,7 @@
|
|
|
364
421
|
"'": "'",
|
|
365
422
|
"/": "/"
|
|
366
423
|
};
|
|
424
|
+
// Using replace with regex for single-pass character mapping compatible with ES5
|
|
367
425
|
return text.replace(/[&<>"'/]/g, function (m) { return map[m]; });
|
|
368
426
|
}
|
|
369
427
|
/**
|
|
@@ -391,6 +449,46 @@
|
|
|
391
449
|
function OptionResolver() {
|
|
392
450
|
}
|
|
393
451
|
/**
|
|
452
|
+
* Gets a sanitized attribute value from an HTML element
|
|
453
|
+
* @param element HTMLInputElement to read
|
|
454
|
+
* @param attrName Attribute name
|
|
455
|
+
* @param options method options
|
|
456
|
+
* @param options.sanitized Flag to indicate if the attribute value needs to be sanitized (default: `true`)
|
|
457
|
+
* @returns Sanitized attribute value or null
|
|
458
|
+
*/
|
|
459
|
+
OptionResolver.getAttr = function (element, attrName, opts) {
|
|
460
|
+
var _a = (opts !== null && opts !== void 0 ? opts : {}).sanitized, sanitized = _a === void 0 ? true : _a;
|
|
461
|
+
var value = element.getAttribute(attrName);
|
|
462
|
+
return sanitized ? sanitize(value) : value;
|
|
463
|
+
};
|
|
464
|
+
/**
|
|
465
|
+
* Returns the value of an attribute, user-provided value, or default value
|
|
466
|
+
* @param element HTMLInputElement to read
|
|
467
|
+
* @param attrName Attribute name
|
|
468
|
+
* @param userValue Value provided by the user
|
|
469
|
+
* @param defaultValue Default value if neither attribute nor user value exists
|
|
470
|
+
* @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
|
|
471
|
+
* @returns Final attribute value
|
|
472
|
+
*/
|
|
473
|
+
OptionResolver.getAttrOrDefault = function (element, attrName, userValue, defaultValue, sanitized) {
|
|
474
|
+
if (sanitized === void 0) { sanitized = true; }
|
|
475
|
+
return OptionResolver.getAttr(element, attrName, { sanitized: sanitized }) || userValue || defaultValue;
|
|
476
|
+
};
|
|
477
|
+
/**
|
|
478
|
+
* Returns the value of an attribute, user-provided value, or marks as deprecated
|
|
479
|
+
* @param element HTMLInputElement to read
|
|
480
|
+
* @param attrName Attribute name
|
|
481
|
+
* @param userValue Value provided by the user
|
|
482
|
+
* @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
|
|
483
|
+
* @returns Final attribute value or DeprecationConfig.value if not found
|
|
484
|
+
*/
|
|
485
|
+
OptionResolver.getAttrOrDeprecation = function (element, attrName, userValue, sanitized) {
|
|
486
|
+
if (sanitized === void 0) { sanitized = true; }
|
|
487
|
+
return OptionResolver.getAttr(element, attrName, { sanitized: sanitized }) ||
|
|
488
|
+
userValue ||
|
|
489
|
+
DeprecationConfig.value;
|
|
490
|
+
};
|
|
491
|
+
/**
|
|
394
492
|
* Resolves all toggle options from the element and user options
|
|
395
493
|
* @param element HTMLInputElement representing the toggle
|
|
396
494
|
* @param userOptions Options provided by the user
|
|
@@ -444,44 +542,6 @@
|
|
|
444
542
|
tristate: false,
|
|
445
543
|
name: null,
|
|
446
544
|
};
|
|
447
|
-
/**
|
|
448
|
-
* Gets a sanitized attribute value from an HTML element
|
|
449
|
-
* @param element HTMLInputElement to read
|
|
450
|
-
* @param attrName Attribute name
|
|
451
|
-
* @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
|
|
452
|
-
* @returns Sanitized attribute value or null
|
|
453
|
-
*/
|
|
454
|
-
OptionResolver.getAttr = function (element, attrName, sanitized) {
|
|
455
|
-
if (sanitized === void 0) { sanitized = true; }
|
|
456
|
-
return sanitized ? sanitize(element.getAttribute(attrName)) : element.getAttribute(attrName);
|
|
457
|
-
};
|
|
458
|
-
/**
|
|
459
|
-
* Returns the value of an attribute, user-provided value, or default value
|
|
460
|
-
* @param element HTMLInputElement to read
|
|
461
|
-
* @param attrName Attribute name
|
|
462
|
-
* @param userValue Value provided by the user
|
|
463
|
-
* @param defaultValue Default value if neither attribute nor user value exists
|
|
464
|
-
* @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
|
|
465
|
-
* @returns Final attribute value
|
|
466
|
-
*/
|
|
467
|
-
OptionResolver.getAttrOrDefault = function (element, attrName, userValue, defaultValue, sanitized) {
|
|
468
|
-
if (sanitized === void 0) { sanitized = true; }
|
|
469
|
-
return OptionResolver.getAttr(element, attrName, sanitized) || userValue || defaultValue;
|
|
470
|
-
};
|
|
471
|
-
/**
|
|
472
|
-
* Returns the value of an attribute, user-provided value, or marks as deprecated
|
|
473
|
-
* @param element HTMLInputElement to read
|
|
474
|
-
* @param attrName Attribute name
|
|
475
|
-
* @param userValue Value provided by the user
|
|
476
|
-
* @param sanitized Flag to indicate if the attribute value needs to be sanitized (default: {@code true})
|
|
477
|
-
* @returns Final attribute value or DeprecationConfig.value if not found
|
|
478
|
-
*/
|
|
479
|
-
OptionResolver.getAttrOrDeprecation = function (element, attrName, userValue, sanitized) {
|
|
480
|
-
if (sanitized === void 0) { sanitized = true; }
|
|
481
|
-
return OptionResolver.getAttr(element, attrName, sanitized) ||
|
|
482
|
-
userValue ||
|
|
483
|
-
DeprecationConfig.value;
|
|
484
|
-
};
|
|
485
545
|
return OptionResolver;
|
|
486
546
|
}());
|
|
487
547
|
/** Types of deprecation source */
|
|
@@ -582,14 +642,29 @@
|
|
|
582
642
|
*/
|
|
583
643
|
StateReducer.prototype.getElementState = function (element) {
|
|
584
644
|
var checked = element.checked;
|
|
585
|
-
var status
|
|
645
|
+
var status;
|
|
646
|
+
if (element.disabled) {
|
|
647
|
+
status = ToggleStateStatus.DISABLED;
|
|
648
|
+
}
|
|
649
|
+
else if (element.readOnly) {
|
|
650
|
+
status = ToggleStateStatus.READONLY;
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
status = ToggleStateStatus.ENABLED;
|
|
654
|
+
}
|
|
586
655
|
var indeterminate = this.isTristate && element.indeterminate;
|
|
656
|
+
var value;
|
|
657
|
+
if (indeterminate) {
|
|
658
|
+
value = ToggleStateValue.INDETERMINATE;
|
|
659
|
+
}
|
|
660
|
+
else if (checked) {
|
|
661
|
+
value = ToggleStateValue.ON;
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
value = ToggleStateValue.OFF;
|
|
665
|
+
}
|
|
587
666
|
return {
|
|
588
|
-
value:
|
|
589
|
-
? ToggleStateValue.INDETERMINATE
|
|
590
|
-
: checked
|
|
591
|
-
? ToggleStateValue.ON
|
|
592
|
-
: ToggleStateValue.OFF,
|
|
667
|
+
value: value,
|
|
593
668
|
checked: checked,
|
|
594
669
|
status: status,
|
|
595
670
|
indeterminate: indeterminate,
|
|
@@ -626,87 +701,115 @@
|
|
|
626
701
|
* If the toggle is currently in the target state of the action, the action will return {@code false}.
|
|
627
702
|
* If the toggle is in the indeterminate state and the action is {@code ToggleActionType.DETERMINATE},
|
|
628
703
|
* the toggle will be set to the checked state.
|
|
629
|
-
* If the action is {@code ToggleActionType.
|
|
704
|
+
* If the action is {@code ToggleActionType.NEXT} :
|
|
630
705
|
* - For a tristate toggle, the toggle will do ON -> INDETERMINATE -> OFF -> INDETERMINATE -> ON.
|
|
631
706
|
* - For a non-tristate toggle, the toggle will do ON -> OFF -> ON.
|
|
632
707
|
*/
|
|
633
708
|
StateReducer.prototype.do = function (action) {
|
|
709
|
+
var actionsRequiringInteract = [
|
|
710
|
+
ToggleActionType.ON,
|
|
711
|
+
ToggleActionType.OFF,
|
|
712
|
+
ToggleActionType.TOGGLE,
|
|
713
|
+
ToggleActionType.INDETERMINATE,
|
|
714
|
+
ToggleActionType.DETERMINATE,
|
|
715
|
+
ToggleActionType.NEXT,
|
|
716
|
+
ToggleActionType.READONLY,
|
|
717
|
+
];
|
|
718
|
+
if (actionsRequiringInteract.includes(action) && !this.canInteract())
|
|
719
|
+
return false;
|
|
634
720
|
switch (action) {
|
|
635
721
|
case ToggleActionType.ON:
|
|
636
|
-
|
|
637
|
-
return false;
|
|
638
|
-
if (this.state.value === ToggleStateValue.ON)
|
|
639
|
-
return false;
|
|
640
|
-
this.state = __assign(__assign({}, this.state), { value: ToggleStateValue.ON, checked: true, indeterminate: false });
|
|
641
|
-
return true;
|
|
722
|
+
return this.setValueIfChanged(ToggleStateValue.ON, true, false);
|
|
642
723
|
case ToggleActionType.OFF:
|
|
643
|
-
|
|
644
|
-
return false;
|
|
645
|
-
if (this.state.value === ToggleStateValue.OFF)
|
|
646
|
-
return false;
|
|
647
|
-
this.state = __assign(__assign({}, this.state), { value: ToggleStateValue.OFF, checked: false, indeterminate: false });
|
|
648
|
-
return true;
|
|
724
|
+
return this.setValueIfChanged(ToggleStateValue.OFF, false, false);
|
|
649
725
|
case ToggleActionType.TOGGLE:
|
|
650
|
-
if (!this.canInteract())
|
|
651
|
-
return false;
|
|
652
726
|
if (this.state.value === ToggleStateValue.ON)
|
|
653
727
|
return this.do(ToggleActionType.OFF);
|
|
654
728
|
if (this.state.value === ToggleStateValue.OFF)
|
|
655
729
|
return this.do(ToggleActionType.ON);
|
|
656
730
|
return false;
|
|
657
731
|
case ToggleActionType.INDETERMINATE:
|
|
658
|
-
|
|
659
|
-
return false;
|
|
660
|
-
if (this.state.value === ToggleStateValue.INDETERMINATE)
|
|
661
|
-
return false;
|
|
662
|
-
this.state = __assign(__assign({}, this.state), { value: ToggleStateValue.INDETERMINATE, indeterminate: true });
|
|
663
|
-
return true;
|
|
732
|
+
return this.setValueIfChanged(ToggleStateValue.INDETERMINATE, undefined, true);
|
|
664
733
|
case ToggleActionType.DETERMINATE:
|
|
665
|
-
if (!this.canInteract())
|
|
666
|
-
return false;
|
|
667
734
|
if (this.state.value != ToggleStateValue.INDETERMINATE)
|
|
668
735
|
return false;
|
|
669
|
-
this.
|
|
670
|
-
? ToggleStateValue.ON
|
|
671
|
-
: ToggleStateValue.OFF, indeterminate: false });
|
|
672
|
-
return true;
|
|
736
|
+
return this.setValue(this.state.checked ? ToggleStateValue.ON : ToggleStateValue.OFF, this.state.checked, false);
|
|
673
737
|
case ToggleActionType.NEXT:
|
|
674
|
-
|
|
675
|
-
return false;
|
|
676
|
-
if (this.isTristate) {
|
|
677
|
-
if (this.state.value === ToggleStateValue.ON ||
|
|
678
|
-
this.state.value === ToggleStateValue.OFF)
|
|
679
|
-
return this.do(ToggleActionType.INDETERMINATE);
|
|
680
|
-
if (this.state.value === ToggleStateValue.INDETERMINATE &&
|
|
681
|
-
this.state.checked)
|
|
682
|
-
return this.do(ToggleActionType.OFF);
|
|
683
|
-
if (this.state.value === ToggleStateValue.INDETERMINATE &&
|
|
684
|
-
!this.state.checked)
|
|
685
|
-
return this.do(ToggleActionType.ON);
|
|
686
|
-
}
|
|
687
|
-
else {
|
|
688
|
-
if (this.state.value === ToggleStateValue.ON)
|
|
689
|
-
return this.do(ToggleActionType.OFF);
|
|
690
|
-
if (this.state.value === ToggleStateValue.OFF)
|
|
691
|
-
return this.do(ToggleActionType.ON);
|
|
692
|
-
}
|
|
693
|
-
return false;
|
|
738
|
+
return this.doNext();
|
|
694
739
|
case ToggleActionType.DISABLE:
|
|
695
|
-
|
|
696
|
-
return false;
|
|
697
|
-
this.state = __assign(__assign({}, this.state), { status: ToggleStateStatus.DISABLED });
|
|
698
|
-
return true;
|
|
740
|
+
return this.setStatusIfChanged(ToggleStateStatus.DISABLED);
|
|
699
741
|
case ToggleActionType.ENABLE:
|
|
700
|
-
|
|
701
|
-
return false;
|
|
702
|
-
this.state = __assign(__assign({}, this.state), { status: ToggleStateStatus.ENABLED });
|
|
703
|
-
return true;
|
|
742
|
+
return this.setStatusIfChanged(ToggleStateStatus.ENABLED);
|
|
704
743
|
case ToggleActionType.READONLY:
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
744
|
+
return this.setStatus(ToggleStateStatus.READONLY);
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
/**
|
|
748
|
+
* Sets the state of the toggle to the provided value.
|
|
749
|
+
* If checked or indeterminate is provided, sets the corresponding property of the state to the provided value.
|
|
750
|
+
* Otherwise, leaves the property unchanged.
|
|
751
|
+
* @param value The value of the toggle to set.
|
|
752
|
+
* @param checked The checked state of the toggle to set. If not provided, the property is left unchanged.
|
|
753
|
+
* @param indeterminate The indeterminate state of the toggle to set. If not provided, the property is left unchanged.
|
|
754
|
+
* @returns A boolean indicating whether the state was updated.
|
|
755
|
+
*/
|
|
756
|
+
StateReducer.prototype.setValue = function (value, checked, indeterminate) {
|
|
757
|
+
this.state = __assign(__assign({}, this.state), { value: value, checked: checked !== null && checked !== void 0 ? checked : this.state.checked, indeterminate: indeterminate !== null && indeterminate !== void 0 ? indeterminate : this.state.indeterminate });
|
|
758
|
+
return true;
|
|
759
|
+
};
|
|
760
|
+
/**
|
|
761
|
+
* Sets the state of the toggle to the provided value if the value is different from the current state.
|
|
762
|
+
* If checked or indeterminate is provided, sets the corresponding property of the state to the provided value.
|
|
763
|
+
* Otherwise, leaves the property unchanged.
|
|
764
|
+
* @returns A boolean indicating whether the state was updated.
|
|
765
|
+
*/
|
|
766
|
+
StateReducer.prototype.setValueIfChanged = function (value, checked, indeterminate) {
|
|
767
|
+
if (this.state.value === value)
|
|
768
|
+
return false;
|
|
769
|
+
return this.setValue(value, checked, indeterminate);
|
|
770
|
+
};
|
|
771
|
+
/**
|
|
772
|
+
* Sets the status of the toggle to the provided value.
|
|
773
|
+
* @param status The new status of the toggle.
|
|
774
|
+
* @returns A boolean indicating whether the state was updated.
|
|
775
|
+
*/
|
|
776
|
+
StateReducer.prototype.setStatus = function (status) {
|
|
777
|
+
this.state = __assign(__assign({}, this.state), { status: status });
|
|
778
|
+
return true;
|
|
779
|
+
};
|
|
780
|
+
/**
|
|
781
|
+
* Sets the status of the toggle to the provided value if the value is different from the current status.
|
|
782
|
+
* @param status The new status of the toggle.
|
|
783
|
+
* @returns A boolean indicating whether the state was updated.
|
|
784
|
+
*/
|
|
785
|
+
StateReducer.prototype.setStatusIfChanged = function (status) {
|
|
786
|
+
if (this.state.status === status)
|
|
787
|
+
return false;
|
|
788
|
+
return this.setStatus(status);
|
|
789
|
+
};
|
|
790
|
+
/**
|
|
791
|
+
* Applies the next action based on the current state of the toggle.
|
|
792
|
+
* If the toggle is tristate, cycles through the on, off, and indeterminate states.
|
|
793
|
+
* If the toggle is not tristate, cycles through the on and off states.
|
|
794
|
+
* @returns A boolean indicating whether the state was updated.
|
|
795
|
+
*/
|
|
796
|
+
StateReducer.prototype.doNext = function () {
|
|
797
|
+
if (this.isTristate) {
|
|
798
|
+
if (this.state.value === ToggleStateValue.ON || this.state.value === ToggleStateValue.OFF) {
|
|
799
|
+
return this.do(ToggleActionType.INDETERMINATE);
|
|
800
|
+
}
|
|
801
|
+
if (this.state.value === ToggleStateValue.INDETERMINATE) {
|
|
802
|
+
return this.state.checked
|
|
803
|
+
? this.do(ToggleActionType.OFF)
|
|
804
|
+
: this.do(ToggleActionType.ON);
|
|
805
|
+
}
|
|
709
806
|
}
|
|
807
|
+
else {
|
|
808
|
+
return this.state.value === ToggleStateValue.ON
|
|
809
|
+
? this.do(ToggleActionType.OFF)
|
|
810
|
+
: this.do(ToggleActionType.ON);
|
|
811
|
+
}
|
|
812
|
+
return false;
|
|
710
813
|
};
|
|
711
814
|
return StateReducer;
|
|
712
815
|
}());
|
|
@@ -723,6 +826,19 @@
|
|
|
723
826
|
this.pointer = null;
|
|
724
827
|
this.SCROLL_THRESHOLD = 10;
|
|
725
828
|
this.eventsBound = false;
|
|
829
|
+
this.suppressExternalSync = false;
|
|
830
|
+
this.originalDescriptors = new Map();
|
|
831
|
+
/**
|
|
832
|
+
* Handles the change event of the input element of the toggle.
|
|
833
|
+
* This event listener is responsible for detecting when the input element
|
|
834
|
+
* of the toggle changes its state and triggering the update method to keep the toggle in sync.
|
|
835
|
+
*/
|
|
836
|
+
this.onExternalChange = function () {
|
|
837
|
+
_this.update(true);
|
|
838
|
+
};
|
|
839
|
+
this.onFormReset = function () {
|
|
840
|
+
setTimeout(function () { return _this.onExternalChange(); }, 0);
|
|
841
|
+
};
|
|
726
842
|
/**
|
|
727
843
|
* Handles pointer down events by initiating the toggle action and setting up
|
|
728
844
|
* listeners for pointer movement, release, and cancellation.
|
|
@@ -811,8 +927,54 @@
|
|
|
811
927
|
this.stateReducer = new StateReducer(element, this.options.tristate);
|
|
812
928
|
this.domBuilder = new DOMBuilder(element, this.options, this.stateReducer.get());
|
|
813
929
|
this.bindEventListeners();
|
|
930
|
+
this.interceptInputProperties();
|
|
814
931
|
this.element.bsToggle = this;
|
|
815
932
|
}
|
|
933
|
+
/**
|
|
934
|
+
* Intercepts the following input properties to detect external changes:
|
|
935
|
+
* - checked
|
|
936
|
+
* - disabled
|
|
937
|
+
* - readonly
|
|
938
|
+
* - indeterminate
|
|
939
|
+
* This method is used to detect changes made to the input element directly,
|
|
940
|
+
* rather than through the BootstrapToggle API. It is used to maintain the
|
|
941
|
+
* state of the toggle in cases where the user changes the input element
|
|
942
|
+
* directly, rather than through the API.
|
|
943
|
+
* @returns void
|
|
944
|
+
*/
|
|
945
|
+
Toggle.prototype.interceptInputProperties = function () {
|
|
946
|
+
var _this = this;
|
|
947
|
+
var props = ["checked", "disabled", "readOnly", "indeterminate"];
|
|
948
|
+
props.forEach(function (prop) {
|
|
949
|
+
var descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(_this.element), prop);
|
|
950
|
+
if (!(descriptor === null || descriptor === void 0 ? void 0 : descriptor.set))
|
|
951
|
+
return;
|
|
952
|
+
_this.originalDescriptors.set(prop, descriptor);
|
|
953
|
+
Object.defineProperty(_this.element, prop, {
|
|
954
|
+
configurable: true,
|
|
955
|
+
get: function () { return descriptor.get.call(_this.element); },
|
|
956
|
+
set: function (value) {
|
|
957
|
+
descriptor.set.call(_this.element, value);
|
|
958
|
+
if (_this.suppressExternalSync)
|
|
959
|
+
return;
|
|
960
|
+
_this.onExternalChange();
|
|
961
|
+
},
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
};
|
|
965
|
+
/**
|
|
966
|
+
* Restores the original input properties of the toggle element.
|
|
967
|
+
* This method is used to restore the original descriptors of the input properties
|
|
968
|
+
* which were intercepted by the BootstrapToggle to detect external changes.
|
|
969
|
+
* @returns void
|
|
970
|
+
*/
|
|
971
|
+
Toggle.prototype.restoreInputProperties = function () {
|
|
972
|
+
var _this = this;
|
|
973
|
+
this.originalDescriptors.forEach(function (descriptor, prop) {
|
|
974
|
+
Object.defineProperty(_this.element, prop, descriptor);
|
|
975
|
+
});
|
|
976
|
+
this.originalDescriptors.clear();
|
|
977
|
+
};
|
|
816
978
|
/**
|
|
817
979
|
* Binds event listeners to the toggle element.
|
|
818
980
|
* This method is called by the constructor and is responsible for
|
|
@@ -827,6 +989,7 @@
|
|
|
827
989
|
Toggle.prototype.bindEventListeners = function () {
|
|
828
990
|
if (this.eventsBound)
|
|
829
991
|
return;
|
|
992
|
+
this.bindFormResetListener();
|
|
830
993
|
this.bindPointerEventListener();
|
|
831
994
|
this.bindKeyboardEventListener();
|
|
832
995
|
this.bindLabelEventListener();
|
|
@@ -846,11 +1009,24 @@
|
|
|
846
1009
|
Toggle.prototype.unbindEventListeners = function () {
|
|
847
1010
|
if (!this.eventsBound)
|
|
848
1011
|
return;
|
|
1012
|
+
this.unbindFormResetListener();
|
|
849
1013
|
this.unbindPointerEventListener();
|
|
850
1014
|
this.unbindKeyboardEventListener();
|
|
851
1015
|
this.unbindLabelEventListener();
|
|
852
1016
|
this.eventsBound = false;
|
|
853
1017
|
};
|
|
1018
|
+
Toggle.prototype.bindFormResetListener = function () {
|
|
1019
|
+
var form = this.element.form;
|
|
1020
|
+
if (!form)
|
|
1021
|
+
return;
|
|
1022
|
+
form.addEventListener("reset", this.onFormReset);
|
|
1023
|
+
};
|
|
1024
|
+
Toggle.prototype.unbindFormResetListener = function () {
|
|
1025
|
+
var form = this.element.form;
|
|
1026
|
+
if (!form)
|
|
1027
|
+
return;
|
|
1028
|
+
form.removeEventListener("reset", this.onFormReset);
|
|
1029
|
+
};
|
|
854
1030
|
/**
|
|
855
1031
|
* Binds a pointerdown event listener to the root element of the toggle.
|
|
856
1032
|
* The event listener is responsible for handling pointer events (e.g. mouse clicks, touch events)
|
|
@@ -938,11 +1114,17 @@
|
|
|
938
1114
|
*/
|
|
939
1115
|
Toggle.prototype.apply = function (action, silent) {
|
|
940
1116
|
if (silent === void 0) { silent = false; }
|
|
941
|
-
if (this.stateReducer.do(action))
|
|
1117
|
+
if (!this.stateReducer.do(action))
|
|
1118
|
+
return;
|
|
1119
|
+
this.suppressExternalSync = true;
|
|
1120
|
+
try {
|
|
942
1121
|
this.domBuilder.render(this.stateReducer.get());
|
|
943
1122
|
if (!silent)
|
|
944
1123
|
this.trigger();
|
|
945
1124
|
}
|
|
1125
|
+
finally {
|
|
1126
|
+
this.suppressExternalSync = false;
|
|
1127
|
+
}
|
|
946
1128
|
};
|
|
947
1129
|
/**
|
|
948
1130
|
* Toggles the state of the toggle.
|
|
@@ -1024,10 +1206,16 @@
|
|
|
1024
1206
|
* @param {boolean} silent A boolean indicating whether to trigger the change event after synchronizing the toggle state.
|
|
1025
1207
|
*/
|
|
1026
1208
|
Toggle.prototype.update = function (silent) {
|
|
1027
|
-
this.
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
this.
|
|
1209
|
+
this.suppressExternalSync = true;
|
|
1210
|
+
try {
|
|
1211
|
+
this.stateReducer.sync(this.element);
|
|
1212
|
+
this.domBuilder.render(this.stateReducer.get());
|
|
1213
|
+
if (!silent)
|
|
1214
|
+
this.trigger();
|
|
1215
|
+
}
|
|
1216
|
+
finally {
|
|
1217
|
+
this.suppressExternalSync = false;
|
|
1218
|
+
}
|
|
1031
1219
|
};
|
|
1032
1220
|
/**
|
|
1033
1221
|
* Triggers the change event on the toggle's input element.
|
|
@@ -1045,6 +1233,7 @@
|
|
|
1045
1233
|
*After calling this method, the toggle element will be removed from the DOM and all event listeners will be unbound.
|
|
1046
1234
|
*/
|
|
1047
1235
|
Toggle.prototype.destroy = function () {
|
|
1236
|
+
this.restoreInputProperties();
|
|
1048
1237
|
this.unbindEventListeners();
|
|
1049
1238
|
this.domBuilder.destroy();
|
|
1050
1239
|
delete this.element.bsToggle;
|