From ac7174ac50821985392ec827454432b39c350561 Mon Sep 17 00:00:00 2001 From: James Fenn <18jafenn90@gmail.com> Date: Fri, 6 Sep 2019 17:36:39 -0400 Subject: [PATCH] v8 - add hacky support for attribute / string renders --- README.md | 2 +- package-lock.json | 2 +- package.json | 2 +- src/component.js | 36 +++++++++++++++++++++++++++--------- src/util/dom-wrapper.js | 36 +++++++++++++++++++++++++++++++++++- test.js | 8 +++++++- 6 files changed, 72 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 36573f2..8fac25d 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ container( #### Script Tag ```html - + ``` (the module will be included in the global scope as the `declarativ` variable) diff --git a/package-lock.json b/package-lock.json index 172ebd5..bd60ef5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "declarativ", - "version": "0.0.7", + "version": "0.0.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index eab88b8..9517392 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "declarativ", - "version": "0.0.7", + "version": "0.0.8", "description": "This is definitely not JSX.", "main": "src/index.js", "files": [ diff --git a/src/component.js b/src/component.js index ddd3834..238066f 100644 --- a/src/component.js +++ b/src/component.js @@ -137,17 +137,32 @@ class Component extends Node { } /** - * Calls the passed function on the rendered element. * - * @param {function(HTMLElement|jQuery, Object)} fun + * @param {function(ElementImpl, Object)} fun * @returns {Component} */ - run(fun) { + runWrapped(fun) { let node = this.clone(); node.tasks = new PendingTasks(this.tasks).push(fun); return node; } + /** + * Calls the passed function on the rendered element. + * + * @param {function(HTMLElement|jQuery|string, Object)} fun + * @returns {Component} + */ + run(fun) { + return this.runWrapped((e, data) => fun(e.get(), data)); + } + + runWrappedWithValue(value, fun) { + return this.runWrapped(async function(element, data) { + return fun(element, await (new DataResolvable(value)).resolve(data)); + }) + } + runWithValue(value, fun) { return this.run(async function(element, data) { return fun(element, await (new DataResolvable(value)).resolve(data)); @@ -155,8 +170,8 @@ class Component extends Node { } attr(name, value) { - return this.runWithValue(value, (element, resolvedValue) => { - dom.element(element).attr(name, resolvedValue); + return this.runWrappedWithValue(value, (element, resolvedValue) => { + element.attr(name, resolvedValue); }); } @@ -165,8 +180,8 @@ class Component extends Node { } on(event, fun) { - return this.run((element) => { - dom.element(element).on(event, fun); + return this.runWrapped((element) => { + element.on(event, fun); }); } @@ -183,7 +198,10 @@ class Component extends Node { // TODO: support attribute values / this.tasks.call() on string returns // render HTML structure - return this.template(innerHtml, data); + let str = this.template(innerHtml, data); + let strImpl = dom.element(str); + await this.tasks.call(strImpl, data); + return strImpl.get(); } async render(parentData, tempElement) { @@ -204,7 +222,7 @@ class Component extends Node { // render HTML structure let element = dom.createHtml(this.template(innerHtml, data)); let elementImpl = dom.element(element); - await this.tasks.call(element, data); + await this.tasks.call(elementImpl, data); if (tempElement) dom.element(tempElement).replaceWith(element); diff --git a/src/util/dom-wrapper.js b/src/util/dom-wrapper.js index 55926b4..44d7f24 100644 --- a/src/util/dom-wrapper.js +++ b/src/util/dom-wrapper.js @@ -102,6 +102,38 @@ class ElementImpl { empty() { throw "No clear implementation" } + + get() { + return this.element; + } +} + +/** + * The most hacky and basic possible implementation + * for string HTML parsing / manipulation. + * + * @class StringElementImpl + */ +class StringElementImpl extends ElementImpl { + constructor(element) { + super(element); + this.attrs = {}; + } + + setAttr(name, value) { + this.attrs[name] = value; + } + + getAttr(name) { + return this.attrs[name]; + } + + get() { + let index = this.element.indexOf(">"); + return this.element.slice(0, index) + + Object.keys(this.attrs).map((key) => ` ${key}="${this.attrs[key]}"`) + + this.element.slice(index); + } } /** @@ -231,12 +263,14 @@ function createText(str) { * Provides an implementation of basic DOM functions for a * specified element. * - * @param {HTMLElementImpl|HTMLElement|jQuery} e The element to provide an implementation for. + * @param {HTMLElementImpl|HTMLElement|jQuery|string} e The element to provide an implementation for. * @returns {ElementImpl} */ function element(e) { if (e instanceof ElementImpl) return e; + else if (typeof e === "string") + return new StringElementImpl(e); else if (e instanceof HTMLElement) return new HTMLElementImpl(e); else if (e instanceof jQuery) diff --git a/test.js b/test.js index 9e11e5b..d2dbf31 100644 --- a/test.js +++ b/test.js @@ -108,7 +108,13 @@ describe("Element Tests", () => { expect( await el.p(Promise.resolve("Hello!")).renderString() ).to.be.equal("
Hello!
"); - }) + }); + + it("should render tag attributes", async function() { + expect( + await el.p().attr("id", "render").renderString() + ).to.be.equal('') + }); }); describe("Data Binding", () => {