`;
tabs.forEach((tab, i) => {
- h += `
- ${tab.html()}
-
`;
+ h += `
`;
+ if ( tab.factory ) {
+ tab_placeholders[i] = Placeholder();
+ h += tab_placeholders[i].html;
+ } else {
+ h += tab.html();
+ }
+ h += `
`;
});
h += `
`;
@@ -85,7 +92,13 @@ async function UIWindowSettings(options){
}
});
const $el_window = $(el_window);
- tabs.forEach(tab => tab.init($el_window));
+ tabs.forEach((tab, i) => {
+ tab.init && tab.init($el_window);
+ if ( tab.factory ) {
+ const component = tab.factory();
+ component.attach(tab_placeholders[i]);
+ }
+ });
$(el_window).on('click', '.settings-sidebar-item', function(){
const $this = $(this);
diff --git a/src/css/style.css b/src/css/style.css
index 0913d78b9..37fd04c0f 100644
--- a/src/css/style.css
+++ b/src/css/style.css
@@ -3709,6 +3709,10 @@ fieldset[name=number-code] {
height: 45px;
}
+.thin-card {
+ padding: 0 15px;
+}
+
.settings-card strong {
font-weight: 500;
}
diff --git a/src/init_async.js b/src/init_async.js
index 212310431..40aca629c 100644
--- a/src/init_async.js
+++ b/src/init_async.js
@@ -3,6 +3,10 @@ logger.info('start -> async initialization');
import './util/TeePromise.js';
import './util/Component.js';
+import './UI/Components/Frame.js';
+import './UI/Components/Glyph.js';
+import './UI/Components/ActionCard.js';
+import './UI/Components/NotifCard.js';
logger.info('end -> async initialization');
globalThis.init_promise.resolve();
diff --git a/src/init_sync.js b/src/init_sync.js
index 44277a2f6..cea2e5347 100644
--- a/src/init_sync.js
+++ b/src/init_sync.js
@@ -84,7 +84,8 @@ logger.info('start -> blocking initialization');
}
if ( registry_.classes_m[id] ) {
- throw new Error(`Class with ID ${id} already registered`);
+ // throw new Error(`Class with ID ${id} already registered`);
+ return;
}
registry_.classes_m[id] = cls;
diff --git a/src/util/Component.js b/src/util/Component.js
index 9b08ba12e..813ce00b7 100644
--- a/src/util/Component.js
+++ b/src/util/Component.js
@@ -34,14 +34,23 @@ export const Component = def(class Component extends HTMLElement {
});
}
- constructor (property_values) {
- super();
-
+ _set_dom_based_on_render_mode () {
if ( this.constructor.RENDER_MODE === Component.NO_SHADOW ) {
this.dom_ = this;
} else {
this.dom_ = this.attachShadow({ mode: 'open' });
}
+ }
+
+ constructor (property_values) {
+ super();
+
+ property_values = property_values || {};
+
+ // We allow a subclass of component to define custom behavior
+ // for the `RENDER_MODE` static property. This is so JustHTML
+ // can have ths `no_shadow: true` option.
+ this._set_dom_based_on_render_mode({ property_values });
this.values_ = {};
@@ -104,6 +113,10 @@ export const Component = def(class Component extends HTMLElement {
}
get (key) {
+ if ( ! this.values_.hasOwnProperty(key) ) {
+ throw new Error(`Unknown property \`${key}\` in ${
+ this.constructor.ID || this.constructor.name}`);
+ }
return this.values_[key].get();
}
@@ -130,6 +143,11 @@ export const Component = def(class Component extends HTMLElement {
return;
}
+ if ( destination instanceof ShadowRoot ) {
+ destination.appendChild(this);
+ return;
+ }
+
if ( destination.$ === 'placeholder' ) {
destination.replaceWith(this);
return;
@@ -162,6 +180,14 @@ export const Component = def(class Component extends HTMLElement {
get_api_ () {
return {
listen: (name, callback) => {
+ if ( Array.isArray(name) ) {
+ const names = name;
+ for ( const name of names ) {
+ this.values_[name].sub((_, more) => {
+ callback(this, { ...more, name });
+ });
+ }
+ }
this.values_[name].sub(callback);
callback(this.values_[name].get(), {});
}
diff --git a/src/util/Placeholder.js b/src/util/Placeholder.js
index 48bf60197..5515a9f7b 100644
--- a/src/util/Placeholder.js
+++ b/src/util/Placeholder.js
@@ -18,7 +18,7 @@
*
* @returns {PlaceholderReturn}
*/
-const Placeholder = () => {
+const Placeholder = def(() => {
const id = Placeholder.get_next_id_();
return {
$: 'placeholder',
@@ -29,7 +29,7 @@ const Placeholder = () => {
place.replaceWith(el);
}
};
-};
+}, 'util.Placeholder');
const anti_collision = `94d2cb6b85a1`; // Arbitrary random string
Placeholder.next_id_ = 0;