From 512551c4f4be9590b907b380c0053a5b07628b13 Mon Sep 17 00:00:00 2001 From: chris Date: Mon, 21 Apr 2025 15:42:22 +0200 Subject: [PATCH] FEAT: chainChild - chain of single elements --- src/builder.js | 61 ++++++++++++++++++++--- src/component.js | 7 +++ src/componentAncestry/wrapperComponent.js | 39 ++++++++++++++- src/modifier.js | 11 ++++ 4 files changed, 111 insertions(+), 7 deletions(-) diff --git a/src/builder.js b/src/builder.js index 5953e76..384509f 100644 --- a/src/builder.js +++ b/src/builder.js @@ -11,11 +11,21 @@ const builder = { components: { parent: {}, current: {}, - previous: {}, + previous: null, next: {}, openedChain: {} }, + /** + * Convenience function for the ChildbearerComponent.chainChild() method. + * @param {Component} callComponent + * @returns {builder} + */ + _nextComponent(callComponent) { + this.components.previous = callComponent; + return this; + }, + /** * @property {Function(Component|*): Component} */ @@ -139,6 +149,10 @@ const builder = { if (modifier) { return compel.modifier(modifier); } + if (this.components.previous) { + compel._parentComponent = this.components.previous; + this.components.previous = null; + } return compel; }, @@ -171,12 +185,19 @@ const builder = { * @returns {InputComponent} */ input: function (type, attr = {}, modifier = null) { - return new InputComponent( + let comp = new InputComponent( document.createElement("input"), Object.assign({ "type": type }, attr), modifier ) .addStyleClass(`el-input`); + + if (this.components.previous) { + comp._parentComponent = this.components.previous; + this.components.previous = null; + } + + return comp; }, @@ -298,12 +319,19 @@ const builder = { * @returns {InputComponent} */ textarea: function (attr = {}, modifier = null) { - return new InputComponent( + let comp = new InputComponent( document.createElement("textarea"), attr, modifier ) .addStyleClass(`el-textarea`); + + if (this.components.previous) { + comp._parentComponent = this.components.previous; + this.components.previous = null; + } + + return comp; }, /** @@ -420,7 +448,14 @@ const builder = { * @param {Modifier} modifier * @returns {Row} */ - row: function (attr = {}, modifier = null) { return new Row(attr, modifier) }, + row: function (attr = {}, modifier = null) { + let comp = new Row(attr, modifier); + if (this.components.previous) { + comp._parentComponent = this.components.previous; + this.components.previous = null; + } + return comp; + }, /** * @@ -429,7 +464,14 @@ const builder = { * @param {Modifier} modifier * @returns {Column} */ - column: function (attr = {}, modifier = null) { return new Column(attr, modifier) }, + column: function (attr = {}, modifier = null) { + let comp = new Column(attr, modifier); + if (this.components.previous) { + comp._parentComponent = this.components.previous; + this.components.previous = null; + } + return comp; + }, /** * @@ -437,7 +479,14 @@ const builder = { * @param {Modifier} modifier * @returns {FlexContainerComponent} */ - section: function (attr = {}, modifier = null) { return new FlexContainerComponent(attr, modifier, "section") }, + section: function (attr = {}, modifier = null) { + let comp = new FlexContainerComponent(attr, modifier, "section"); + if (this.components.previous) { + comp._parentComponent = this.components.previous; + this.components.previous = null; + } + return comp; + }, /** * diff --git a/src/component.js b/src/component.js index a9ec18f..d79ecec 100644 --- a/src/component.js +++ b/src/component.js @@ -417,6 +417,13 @@ class Component extends StyleAndScriptStoringComponent { * @returns {WebTrinity} the constructed HTMLElement of this Component. */ generate(modifier = null, styleStore = null, functionStore = null) { + if (this._parentComponent) { + let parent = this._parentComponent; + this._parentComponent = null; + return parent.childContext(this) + .generate(modifier, styleStore, functionStore); + } + if (modifier) { this._modifier = modifier .join(this._modifier); diff --git a/src/componentAncestry/wrapperComponent.js b/src/componentAncestry/wrapperComponent.js index 3d1b701..48d5a9f 100644 --- a/src/componentAncestry/wrapperComponent.js +++ b/src/componentAncestry/wrapperComponent.js @@ -28,6 +28,10 @@ class ElementWrapper { * @type {string} */ _givenName; + /** + * @type {Component} + */ + _parentComponent; /** * Initializes the component @@ -197,9 +201,42 @@ class ChildbearerComponent extends ElementWrapper { if (!(component instanceof Component)) { this.childContext(component.toComponent()) } else { - this._children.push(component); + this._children.push(component.end()); } } return this; } + + /** + * Ends chain for the current component. + * Returns the builder object. + * The Component that is selected there will be set as child to this one. + * + * This funciton is a convenience function. + * Mainly to offer the possibility to reduce the depth of method chains. + * Especially in the case of components with only one child. + * + * @returns {builder} the given + */ + chainChild() { + return builder._nextComponent(this); + } + + /** + * Ends a chainChild - chain. + * If components are setup as chainChild + * they would be wrongfully taken through childContext(). + * Therefore thoose chains are recursively resolved through this method. + * @returns {Component} + */ + end() { + let parent = this._parentComponent; + if (parent) { + this._parentComponent = null; + return parent + .childContext(this) + .end(); + } + return this; + } } diff --git a/src/modifier.js b/src/modifier.js index b48934b..2d38fef 100644 --- a/src/modifier.js +++ b/src/modifier.js @@ -416,4 +416,15 @@ class ChainableModifier extends Modifier { .modifier(this) .childContext(innerComponent); } + + /** + * Calls chainChild() from Component (ChildbearerComponent) + * @see {ChildbearerComponent.chainChild} + * @returns {builder} + */ + chainChild() { + return this._component + .modifier(this) + .chainChild() + } }