pardus-options-library 2.7.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.
Files changed (42) hide show
  1. package/README.md +323 -0
  2. package/eslint.config.js +38 -0
  3. package/package.json +32 -0
  4. package/src/classes/abstract/abstract-button.js +116 -0
  5. package/src/classes/abstract/abstract-toggle-button.js +145 -0
  6. package/src/classes/contents-area.js +22 -0
  7. package/src/classes/description-element.js +80 -0
  8. package/src/classes/disableable-html-element.js +48 -0
  9. package/src/classes/html-element.js +189 -0
  10. package/src/classes/info-element.js +56 -0
  11. package/src/classes/options/abstract-array-option.js +38 -0
  12. package/src/classes/options/abstract-option.js +189 -0
  13. package/src/classes/options/boolean-option.js +24 -0
  14. package/src/classes/options/grouped-options.js +61 -0
  15. package/src/classes/options/key-down-disable-button.js +20 -0
  16. package/src/classes/options/key-down-option.js +178 -0
  17. package/src/classes/options/key-down-set-key-button.js +18 -0
  18. package/src/classes/options/numeric-option.js +40 -0
  19. package/src/classes/options/select-option.js +74 -0
  20. package/src/classes/options/text-area-option.js +39 -0
  21. package/src/classes/options-box.js +200 -0
  22. package/src/classes/options-content.js +178 -0
  23. package/src/classes/options-group.js +114 -0
  24. package/src/classes/pardus-options-utility.js +139 -0
  25. package/src/classes/pardus-options.js +144 -0
  26. package/src/classes/save-button-row/load-button.js +21 -0
  27. package/src/classes/save-button-row/preset-label.js +95 -0
  28. package/src/classes/save-button-row/preset-row.js +106 -0
  29. package/src/classes/save-button-row/presets.js +57 -0
  30. package/src/classes/save-button-row/reset-button.js +21 -0
  31. package/src/classes/save-button-row/save-button-row.js +69 -0
  32. package/src/classes/save-button-row/save-button.js +21 -0
  33. package/src/classes/tabs/sub-tab.js +66 -0
  34. package/src/classes/tabs/tab-content.js +149 -0
  35. package/src/classes/tabs/tab-label.js +45 -0
  36. package/src/classes/tabs/tab.js +66 -0
  37. package/src/classes/tabs/tabs-element.js +25 -0
  38. package/src/classes/tabs/tabs-row.js +44 -0
  39. package/src/classes/tip-box.js +69 -0
  40. package/src/classes/version-row.js +14 -0
  41. package/src/index.js +13 -0
  42. package/webpack.config.cjs +16 -0
@@ -0,0 +1,80 @@
1
+ import HtmlElement from './html-element.js';
2
+
3
+ /**
4
+ * Controls the description for a specific OptionsBox, only one description per OptionsBox permitted
5
+ * @private
6
+ */
7
+ export default class DescriptionElement extends HtmlElement {
8
+ constructor({
9
+ id,
10
+ description = '',
11
+ imageLeft = '',
12
+ imageRight = '',
13
+ }) {
14
+ super(id);
15
+ this.backContainer = '';
16
+ this.description = description;
17
+ this.imageLeft = imageLeft;
18
+ this.imageRight = imageRight;
19
+ this.alignment = '';
20
+ this.frontContainer = {
21
+ styling: 'style="display: none;"',
22
+ id: '',
23
+ setId(idToSet) {
24
+ this.id = idToSet;
25
+ },
26
+ setStyle(style) {
27
+ this.styling = `style="${style}"`;
28
+ },
29
+ toString() {
30
+ return '';
31
+ },
32
+ };
33
+ this.frontContainer.setId(id);
34
+ }
35
+
36
+ addImageLeft(imageSrc) {
37
+ this.imageLeft = imageSrc;
38
+ this.refreshElement();
39
+ }
40
+
41
+ addImageRight(imageSrc) {
42
+ this.imageRight = imageSrc;
43
+ this.refreshElement();
44
+ }
45
+
46
+ setDescription(description) {
47
+ this.description = description;
48
+ this.refreshElement();
49
+ }
50
+
51
+ setAlignment(alignment) {
52
+ this.alignment = alignment;
53
+ this.refreshElement();
54
+ }
55
+
56
+ toString() {
57
+ let html = `<tr id=${this.id} style=''><td><table><tbody><tr>`;
58
+
59
+ if (this.imageLeft && this.imageLeft !== '') {
60
+ html = `${html}<td><img src="${this.imageLeft}"></td>`;
61
+ }
62
+
63
+ // If there's no specific alignment, work out the most ideal one to use
64
+ if (this.alignment === '') {
65
+ if (this.imageLeft === '' && this.imageRight === '') {
66
+ html = `${html}<td align="left">${this.description}</td>`;
67
+ } else {
68
+ html = `${html}<td align="center">${this.description}</td>`;
69
+ }
70
+ } else {
71
+ html = `${html}<td align="${this.alignment}">${this.description}</td>`;
72
+ }
73
+
74
+ if (this.imageRight && this.imageRight !== '') {
75
+ html = `${html}<td><img src="${this.imageRight}"></td>`;
76
+ }
77
+
78
+ return `${html}</tr></tbody></table></td></tr>`;
79
+ }
80
+ }
@@ -0,0 +1,48 @@
1
+ import HtmlElement from './html-element.js';
2
+
3
+ /**
4
+ * @class DisableableHtmlElement
5
+ * @extends HtmlElement
6
+ * @abstract
7
+ */
8
+ export default class DisableableHtmlElement extends HtmlElement {
9
+ /**
10
+ * Create an HTML element that can be disabled
11
+ * @param {object} params Object containing parameters
12
+ * @param {string} params.id The id of the string. Must be unique.
13
+ * @param {boolean} params.disabled Whether the element is disabled or not
14
+ */
15
+ constructor({
16
+ id,
17
+ disabled = false,
18
+ }) {
19
+ super(id);
20
+ this.disabled = disabled;
21
+ }
22
+
23
+ /**
24
+ * Disables this element and all nested elements
25
+ * @function DisableableHtmlElement#disable
26
+ */
27
+ disable() {
28
+ this.setDisabled(true);
29
+ this.refreshElement();
30
+ }
31
+
32
+ /**
33
+ * Enables this element and all nested elements
34
+ * @function DisableableHtmlElement#enable
35
+ */
36
+ enable() {
37
+ this.setDisabled(false);
38
+ this.refreshElement();
39
+ }
40
+
41
+ /**
42
+ * Allows disabling or enabling ths element and all nested elements without refreshing
43
+ * @function DisableableHtmlElement#setDisabled
44
+ */
45
+ setDisabled(disabled = false) {
46
+ this.disabled = disabled;
47
+ }
48
+ }
@@ -0,0 +1,189 @@
1
+ /**
2
+ * @class HtmlElement
3
+ */
4
+ export default class HtmlElement {
5
+ /**
6
+ * @constructor HtmlElement
7
+ * @param {string} id HTML identifier for the element. Must be globally unique.
8
+ */
9
+ constructor(id) {
10
+ // Make sure it is a valid html identifier
11
+ if (!id || id === '') {
12
+ throw new Error('Id cannot be empty.');
13
+ }
14
+ const validIds = /^[a-zA-Z][\w:.-]*$/;
15
+ if (!validIds.test(id)) {
16
+ throw new Error(`Id '${id}' is not a valid HTML identifier.`);
17
+ }
18
+
19
+ this.id = id;
20
+ this.afterRefreshHooks = [];
21
+ this.beforeRefreshHooks = [];
22
+ }
23
+
24
+ /**
25
+ * Add an event listener to the element
26
+ * @function HtmlElement#addEventListener
27
+ * @param {string} eventName Name of the event to listen for
28
+ * @param {function} listener Listener to call when the event fires
29
+ */
30
+ addEventListener(eventName, listener, opts = false) {
31
+ if (this.getElement()) {
32
+ this.getElement().addEventListener(eventName, listener, opts);
33
+ }
34
+
35
+ if (opts && Object.hasOwn(opts, 'ephemeral') && opts.ephemeral) {
36
+ return;
37
+ }
38
+
39
+ this.addAfterRefreshHook(() => {
40
+ if (this.getElement()) {
41
+ this.getElement().addEventListener(eventName, listener, opts);
42
+ }
43
+ });
44
+ }
45
+
46
+ /**
47
+ * Remove an event listener from the element
48
+ * @function HtmlElement#removeEventListener
49
+ * @param {string} eventName Name of the event to listen for
50
+ * @param {function} listener Listener to call when the event fires
51
+ */
52
+ removeEventListener(eventName, listener) {
53
+ if (this.getElement()) {
54
+ this.getElement().removeEventListener(eventName, listener);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Return a string representation of the html element
60
+ * @function HtmlElement#toString
61
+ * @returns {string} String representation of the html element
62
+ */
63
+ toString() {
64
+ return `<div id='${this.id}'></div>`;
65
+ }
66
+
67
+ /**
68
+ * Run all hooks that should be called prior to refreshing the element
69
+ * @function HtmlElement#beforeRefreshElement
70
+ */
71
+ beforeRefreshElement() {
72
+ for (const func of this.beforeRefreshHooks) {
73
+ func();
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Run all hooks that should be called after refreshing the element
79
+ * @function HtmlElement#afterRefreshElement
80
+ * @param {object} opts Optional arguments to be passed to the hooks
81
+ */
82
+ afterRefreshElement(opts = {}) {
83
+ for (const func of this.afterRefreshHooks) {
84
+ func(opts);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Add a hook to run after the element is refreshed
90
+ * @function HtmlElement#addAfterRefreshElement
91
+ * @param {function} func Function to call after the element is refreshed
92
+ */
93
+ addAfterRefreshHook(func) {
94
+ this.afterRefreshHooks.push(func);
95
+ }
96
+
97
+ /**
98
+ * Refresh the element in the dom
99
+ * @function HtmlElement#refreshElement
100
+ */
101
+ refreshElement() {
102
+ this.beforeRefreshElement();
103
+ this.getElement().replaceWith(this.toElement());
104
+ this.afterRefreshElement();
105
+ }
106
+
107
+ /**
108
+ * Gets how much the element should be offset from the top of the DOM
109
+ * @function HtmlElement#getOffsetTop
110
+ * @returns {integer} Pixels the element is offset from the top of the DOM
111
+ */
112
+ getOffsetTop() {
113
+ let currentOffset = this.getElement().offsetTop + this.getElement().offsetHeight;
114
+ let parent = this.getElement().offsetParent;
115
+
116
+ while (parent !== null) {
117
+ currentOffset += parent.offsetTop;
118
+ parent = parent.offsetParent;
119
+ }
120
+
121
+ return currentOffset;
122
+ }
123
+
124
+ /**
125
+ * Gets how much the element should be offset from the left of the DOM
126
+ * @function HtmlElement#getOffsetLeft
127
+ * @returns {integer} Pixels the element is offset from the left of the DOM
128
+ */
129
+ getOffsetLeft() {
130
+ let currentOffset = this.getElement().offsetLeft;
131
+ let parent = this.getElement().offsetParent;
132
+
133
+ while (parent !== null) {
134
+ currentOffset += parent.offsetLeft;
135
+ parent = parent.offsetParent;
136
+ }
137
+
138
+ return currentOffset;
139
+ }
140
+
141
+ /**
142
+ * Gets the element
143
+ * @function HtmlElement#getElement
144
+ * @returns {element} Element
145
+ */
146
+ getElement() {
147
+ return document.getElementById(this.id);
148
+ }
149
+
150
+ /**
151
+ * Creates the element within the DOM from the string representation
152
+ * @function HtmlElement#toElement
153
+ * @returns {element} Element
154
+ */
155
+ toElement() {
156
+ const template = document.createElement('template');
157
+ template.innerHTML = this.toString();
158
+ return template.content.firstChild;
159
+ }
160
+
161
+ /**
162
+ * Appends a child element to the element within the DOM
163
+ * @function HtmlElement#appendChild
164
+ * @param {element} child The child to append
165
+ * @returns {element} The child element
166
+ */
167
+ appendChild(ele) {
168
+ return document.getElementById(this.id).appendChild(ele);
169
+ }
170
+
171
+ /**
172
+ * Appends a child element to the element if it was a table within the DOM
173
+ * @function HtmlElement#appendTableChild
174
+ * @param {element} child The child to append
175
+ * @returns {element} The child element
176
+ */
177
+ appendTableChild(ele) {
178
+ return document.getElementById(this.id).firstChild.appendChild(ele);
179
+ }
180
+
181
+ /**
182
+ * Sets the innerHTML property of the element
183
+ * @function HtmlElement#setHTML
184
+ * @param {html} html to set inside the element
185
+ */
186
+ setHTML(html) {
187
+ this.innerHtml = html;
188
+ }
189
+ }
@@ -0,0 +1,56 @@
1
+ import HtmlElement from './html-element.js';
2
+ import PardusOptionsUtility from './pardus-options-utility.js';
3
+ import PardusOptions from './pardus-options.js';
4
+
5
+ /**
6
+ * @class InfoElement
7
+ * @extends HtmlElement
8
+ */
9
+ export default class InfoElement extends HtmlElement {
10
+ /**
11
+ * @constructor InfoElement
12
+ * @param {string} id HTML identifier for the element. Must be globally unique.
13
+ * @param {string} description Text to display in the InfoElement box
14
+ * @param {string} title Title to display at the top of the InfoElement box
15
+ * @param {string} [tipBoxPosition=right] The direction the InfoElement should appear in. Either 'right' or 'left'
16
+ */
17
+ constructor({
18
+ id,
19
+ description,
20
+ title,
21
+ tipBoxPosition = 'right',
22
+ }) {
23
+ super(id);
24
+ this.description = description;
25
+ this.title = title;
26
+ this.tipBoxPosition = tipBoxPosition;
27
+
28
+ this.addEventListener('mouseover', () => {
29
+ this.tipBox = PardusOptions.getDefaultTipBox();
30
+ this.tipBox.setContents({
31
+ title: this.title,
32
+ contents: this.description,
33
+ });
34
+
35
+ this.tipBox.setPosition({
36
+ element: this,
37
+ position: this.tipBoxPosition,
38
+ });
39
+
40
+ this.tipBox.show();
41
+ });
42
+
43
+ this.addEventListener('mouseout', () => {
44
+ this.tipBox.hide();
45
+ });
46
+ }
47
+
48
+ /**
49
+ * Return a string representation of the InfoElement
50
+ * @function HtmlElement#toString
51
+ * @returns {string} String representation of the InfoElement
52
+ */
53
+ toString() {
54
+ return `<a id="${this.id}" href="#" onclick="return false;"><img src="${PardusOptionsUtility.getImagePackUrl()}info.gif" class="infoButton" alt=""></a>`;
55
+ }
56
+ }
@@ -0,0 +1,38 @@
1
+ import AbstractOption from './abstract-option.js';
2
+ import PardusOptionsUtility from '../pardus-options-utility.js';
3
+
4
+ export default class AbstractArrayOption extends AbstractOption {
5
+ constructor({
6
+ id,
7
+ variable,
8
+ description,
9
+ defaultValue = [],
10
+ saveFunction = PardusOptionsUtility.defaultSaveFunction,
11
+ getFunction = PardusOptionsUtility.defaultGetFunction,
12
+ }) {
13
+ super({
14
+ id,
15
+ variable,
16
+ description,
17
+ defaultValue,
18
+ saveFunction,
19
+ getFunction,
20
+ });
21
+ }
22
+
23
+ toString() {
24
+ return `<tr id="${this.id}"><td>${this.description}</td><td>${this.getInnerHTML()}</td></tr>`;
25
+ }
26
+
27
+ getInnerHTML() {
28
+ let html = '<table><tbody>';
29
+ const currentValues = this.getValue();
30
+
31
+ for (const value of currentValues) {
32
+ html += `<tr><td><input type="text" value="${value}"></td><td><input type="button" value="-"></td></tr>`;
33
+ }
34
+ html += '<tr><td><input type="text" value=""></td><td><input type="button" value="+"></td></tr>';
35
+ html += '</tbody></table>';
36
+ return html;
37
+ }
38
+ }
@@ -0,0 +1,189 @@
1
+ import DisableableHtmlElement from '../disableable-html-element.js';
2
+ import InfoElement from '../info-element.js';
3
+ import PardusOptionsUtility from '../pardus-options-utility.js';
4
+
5
+ /**
6
+ * @class AbstractOption
7
+ * @extends DisableableHtmlElement
8
+ * @abstract
9
+ */
10
+ export default class AbstractOption extends DisableableHtmlElement {
11
+ constructor({
12
+ id,
13
+ variable,
14
+ description = '',
15
+ defaultValue = false,
16
+ saveFunction = PardusOptionsUtility.defaultSaveFunction,
17
+ getFunction = PardusOptionsUtility.defaultGetFunction,
18
+ shallow = false,
19
+ reverse = false,
20
+ info = null,
21
+ disabled = false,
22
+ styleExtra = '',
23
+ align = 'left',
24
+ }) {
25
+ super({
26
+ id,
27
+ disabled,
28
+ });
29
+ this.variable = variable;
30
+ this.saveFunction = saveFunction;
31
+ this.getFunction = getFunction;
32
+ this.description = description;
33
+ this.info = info;
34
+ this.defaultValue = defaultValue;
35
+ this.inputId = `${this.id}-input`;
36
+ this.shallow = shallow;
37
+ this.reverse = reverse;
38
+ this.styleExtra = styleExtra;
39
+ this.colour = '#D0D1D9';
40
+ this.backgroundColour = '#00001C';
41
+ this.align = align;
42
+
43
+ if (this.disabled) {
44
+ this.colour = '#B5B5B5';
45
+ this.backgroundColour = '#CCCCCC';
46
+ }
47
+
48
+ this.style = `color: ${this.colour};background-color: ${this.backgroundColour};${this.styleExtra}`;
49
+
50
+ if (this.info !== null) {
51
+ this.infoElement = new InfoElement({
52
+ id: `${this.id}-info`,
53
+ description: this.info.description,
54
+ title: this.info.title,
55
+ });
56
+
57
+ this.addAfterRefreshHook(() => {
58
+ this.infoElement.afterRefreshElement();
59
+ });
60
+ } else {
61
+ this.infoElement = '';
62
+ }
63
+ }
64
+
65
+ toString() {
66
+ if (this.shallow) {
67
+ return `<td id='${this.id}'>${this.getInnerHTML()}<label>${this.description}</label>${this.infoElement}</td>`;
68
+ }
69
+ if (this.reverse) {
70
+ return `<tr id='${this.id}'><td>${this.getInnerHTML()}</td><td><label for='${this.inputId}'>${this.description}</label>${this.infoElement}</td></tr>`;
71
+ }
72
+
73
+ if (this.description === '') {
74
+ return `<tr id='${this.id}'><td col='2'>${this.getInnerHTML()}</td></tr>`;
75
+ }
76
+
77
+ return `<tr id='${this.id}'><td><label for='${this.inputId}'>${this.description}:</label>${this.infoElement}</td><td align='${this.align}'>${this.getInnerHTML()}</td></tr>`;
78
+ }
79
+
80
+ /**
81
+ * Get the inner HTML of the options element
82
+ * @abstract
83
+ * @function AbstractOption#getInnerHTML
84
+ * @returns {string} Inner HTML of the options element
85
+ */
86
+ getInnerHTML() {
87
+ return '';
88
+ }
89
+
90
+ /**
91
+ * Gets the last-saved value of the options element
92
+ * @function AbstractOption#getValue
93
+ * @returns {type} Last-saved value of the options element
94
+ */
95
+ getValue(overrideGetFunction = null) {
96
+ if (overrideGetFunction && typeof overrideGetFunction === 'function') {
97
+ return overrideGetFunction(`${PardusOptionsUtility.getVariableName(this.variable)}`, this.defaultValue);
98
+ }
99
+
100
+ return this.getFunction(`${PardusOptionsUtility.getVariableName(this.variable)}`, this.defaultValue);
101
+ }
102
+
103
+ /**
104
+ * Gets the current value of the options element
105
+ * @abstract
106
+ * @function AbstractOption#getCurrentValue
107
+ * @returns {type} Value of the options element
108
+ */
109
+ getCurrentValue() {
110
+ return null;
111
+ }
112
+
113
+ /**
114
+ * Gets the input element for the option
115
+ * @function AbstractOption#getInputElement
116
+ * @returns {object} Input element
117
+ */
118
+ getInputElement() {
119
+ return document.getElementById(this.inputId);
120
+ }
121
+
122
+ /**
123
+ * Resets the saved value of the options element to its default
124
+ * @function AbstractOption#resetValue
125
+ */
126
+ resetValue() {
127
+ this.saveFunction(`${PardusOptionsUtility.getVariableName(this.variable)}`, this.defaultValue);
128
+ }
129
+
130
+ /**
131
+ * Saves the current value of the options element
132
+ * @function AbstractOption#saveValue
133
+ */
134
+ saveValue(overrideSaveFunction = null) {
135
+ if (overrideSaveFunction && typeof overrideSaveFunction === 'function') {
136
+ overrideSaveFunction(`${PardusOptionsUtility.getVariableName(this.variable)}`, this.getCurrentValue());
137
+ } else if (!this.disabled) {
138
+ this.saveFunction(`${PardusOptionsUtility.getVariableName(this.variable)}`, this.getCurrentValue());
139
+ }
140
+ }
141
+
142
+ refreshStyle() {
143
+ this.style = `color: ${this.colour};background-color: ${this.backgroundColour};${this.styleExtra}`;
144
+ if (this.getInputElement()) {
145
+ this.getInputElement().setAttribute('style', this.style);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Disables the input element
151
+ * @function AbstractOption#disable
152
+ */
153
+ disable() {
154
+ this.setDisabled(true);
155
+ if (this.getInputElement()) {
156
+ this.getInputElement().setAttribute('disabled', '');
157
+ this.getInputElement().setAttribute('style', this.style);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Enables the input element
163
+ * @function AbstractOption#enable
164
+ */
165
+ enable() {
166
+ this.setDisabled(false);
167
+ if (this.getInputElement()) {
168
+ this.getInputElement().removeAttribute('disabled');
169
+ this.getInputElement().setAttribute('style', this.style);
170
+ }
171
+ }
172
+
173
+ setDisabled(disabled = false) {
174
+ this.disabled = disabled;
175
+ if (this.disabled) {
176
+ this.colour = '#B5B5B5';
177
+ this.backgroundColour = '#CCCCCC';
178
+ } else {
179
+ this.colour = '#D0D1D9';
180
+ this.backgroundColour = '#00001C';
181
+ }
182
+ this.style = `color: ${this.colour};background-color: ${this.backgroundColour};${this.styleExtra}`;
183
+ }
184
+
185
+ loadValue(value) {
186
+ this.getInputElement().value = value;
187
+ this.saveValue();
188
+ }
189
+ }
@@ -0,0 +1,24 @@
1
+ import AbstractOption from './abstract-option.js';
2
+
3
+ /**
4
+ * @class BooleanOption
5
+ * @extends AbstractOption
6
+ */
7
+ export default class BooleanOption extends AbstractOption {
8
+ getInnerHTML() {
9
+ let checkedStatus = '';
10
+ if (this.getValue() === true) {
11
+ checkedStatus = ' checked';
12
+ }
13
+ return `<input id="${this.inputId}" type="checkbox"${checkedStatus} style="${this.style}" ${this.disabled ? 'disabled' : ''}>`;
14
+ }
15
+
16
+ /**
17
+ * Gets the current value of the boolean options element
18
+ * @function BooleanOption#getCurrentValue
19
+ * @returns {boolean} Value of the boolean options element
20
+ */
21
+ getCurrentValue() {
22
+ return this.getInputElement().checked;
23
+ }
24
+ }
@@ -0,0 +1,61 @@
1
+ import HtmlElement from '../html-element.js';
2
+ import BooleanOption from './boolean-option.js';
3
+ import PardusOptionsUtility from '../pardus-options-utility.js';
4
+
5
+ export default class GroupedOptions extends HtmlElement {
6
+ constructor({
7
+ id,
8
+ description,
9
+ saveFunction = PardusOptionsUtility.defaultSaveFunction,
10
+ getFunction = PardusOptionsUtility.defaultGetFunction,
11
+ }) {
12
+ super(id);
13
+ this.description = description;
14
+ this.saveFunction = saveFunction;
15
+ this.getFunction = getFunction;
16
+ this.options = [];
17
+ }
18
+
19
+ toString() {
20
+ return `<tr id="${this.id}"><td>${this.description}</td><td>${this.getInnerHTML()}</td></tr>`;
21
+ }
22
+
23
+ getInnerHTML() {
24
+ let html = '<table><tbody><tr>';
25
+ for (const option of this.options) {
26
+ html += option;
27
+ }
28
+ html += '</tr></tbody></table>';
29
+ return html;
30
+ }
31
+
32
+ saveValue() {
33
+ for (const option of this.options) {
34
+ option.saveValue();
35
+ }
36
+ }
37
+
38
+ addBooleanOption({
39
+ variable,
40
+ description,
41
+ defaultValue = false,
42
+ saveFunction = this.saveFunction,
43
+ getFunction = this.getFunction,
44
+ }) {
45
+ const booleanOptions = {
46
+ id: `${this.id}-option-${this.options.length}`,
47
+ variable,
48
+ description,
49
+ defaultValue,
50
+ saveFunction,
51
+ getFunction,
52
+ shallow: true,
53
+ };
54
+
55
+ const newBooleanOption = new BooleanOption(booleanOptions);
56
+
57
+ this.options.push(newBooleanOption);
58
+ this.refreshElement();
59
+ return newBooleanOption;
60
+ }
61
+ }