Skip to content

Commit

Permalink
v8 - add hacky support for attribute / string renders
Browse files Browse the repository at this point in the history
  • Loading branch information
fennifith committed Sep 6, 2019
1 parent b5ba5c0 commit ac7174a
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 14 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ container(
#### Script Tag

```html
<script type="text/javascript" src="https://unpkg.com/declarativ@0.0.7/dist/declarativ.js"></script>
<script type="text/javascript" src="https://unpkg.com/declarativ@0.0.8/dist/declarativ.js"></script>
```

(the module will be included in the global scope as the `declarativ` variable)
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": [
Expand Down
36 changes: 27 additions & 9 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,26 +137,41 @@ 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));
})
}

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);
});
}

Expand All @@ -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);
});
}

Expand All @@ -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) {
Expand All @@ -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);

Expand Down
36 changes: 35 additions & 1 deletion src/util/dom-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

/**
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,13 @@ describe("Element Tests", () => {
expect(
await el.p(Promise.resolve("Hello!")).renderString()
).to.be.equal("<p>Hello!</p>");
})
});

it("should render tag attributes", async function() {
expect(
await el.p().attr("id", "render").renderString()
).to.be.equal('<p id="render"></p>')
});
});

describe("Data Binding", () => {
Expand Down

0 comments on commit ac7174a

Please sign in to comment.