From ea0ced7a64a62fe97f80b4e9df73338f8a977bbf Mon Sep 17 00:00:00 2001 From: eavichay Date: Thu, 8 Dec 2016 15:26:45 +0200 Subject: [PATCH] fixing some issues --- SlimElement.js | 56 +++++++++++++++++++++++++++++---- components/s-repeat.js | 22 ++++++++----- example/Kanban/KanbanDemo.html | 2 ++ example/Kanban/KanbanModel.js | 8 ++--- example/Kanban/kanban-app.html | 10 +++--- example/Kanban/kanban-column.js | 25 +++++++++++++++ example/Kanban/kanban-item.js | 22 +++++++++++++ 7 files changed, 123 insertions(+), 22 deletions(-) create mode 100644 example/Kanban/kanban-column.js create mode 100644 example/Kanban/kanban-item.js diff --git a/SlimElement.js b/SlimElement.js index 3ab207b..50db72b 100644 --- a/SlimElement.js +++ b/SlimElement.js @@ -72,8 +72,22 @@ return camel.replace(/([A-Z])/g, '-$1').toLowerCase(); } + function __describeRepeater(attribute) { + + return { + type: "R", + attribute: attribute.nodeName, + properties: [attribute.nodeValue], + source: attribute.ownerElement.parentBind + } + } + function __describeAttribute(attribute) { + if (attribute.nodeName === 'slim-repeat') { + return __describeRepeater(attribute) + } + const rxInject = /\{(.+[^(\((.+)\))])\}/.exec(attribute.nodeValue) const rxProp = /\[(.+[^(\((.+)\))])\]/.exec(attribute.nodeValue) const rxMethod = /\[(.+)(\((.+)\)){1}\]/.exec(attribute.nodeValue) @@ -104,6 +118,17 @@ child[dashToCamel(descriptor.attribute)] = window.SlimInjector.getInjector(descriptor.factory)() } + function __repeater(descriptor) { + let sRepeat = document.createElement('s-repeat') + sRepeat.setAttribute('source', descriptor.properties[0]) + sRepeat.parentBind = descriptor.source + descriptor.child.removeAttribute('slim-repeat') + descriptor.child.parentNode.insertBefore(sRepeat, descriptor.child) + sRepeat.appendChild(descriptor.child) + sRepeat.createdCallback(true) + sRepeat.update() + } + function __bind(source, target, descriptor) { descriptor.properties.forEach( prop => { source.__bindings[prop] = source.__bindings[prop] || { @@ -124,6 +149,7 @@ if (result !== undefined) { target[dashToCamel(descriptor.attribute)] = result target.setAttribute(camelToDash(descriptor.attribute), result) + source.update() } } @@ -150,10 +176,15 @@ */ get template() { return null } + get isSlim() { + return true + } + //noinspection JSMethodCanBeStatic get updateOnAttributes() { return [] } + onBeforeCreated() {} onCreated() {} beforeRender() {} render() {} @@ -180,16 +211,22 @@ /** * Lifecycle */ - createdCallback() { + createdCallback(force) { + if (!this.isAttached && !force) return + this.onBeforeCreated() this.__bindings = {} this.__bindingTree = document.createElement('slim-component') - this._captureBindings() - this._applyBindings() + this._bindingCycle() this.onCreated() this.dispatchEvent(new Event('elementCreated', {bubbles:true})) this._renderCycle() } + _bindingCycle() { + this._captureBindings() + this._applyBindings() + } + _renderCycle(skipTree = false) { this.beforeRender() @@ -209,14 +246,19 @@ return obj; } - for (let child of this.querySelectorAll('*[bind]')) { + let allChildren = this.querySelectorAll('*[bind]') + allChildren = Array.prototype.slice.call(allChildren).concat(this) + for (let child of allChildren) { + if (child.sourceTextContent) { + child.textContent = child.sourceTextContent + } var match = child.textContent.match(/\[\[([\w|.]+)\]\]/g) child.sourceTextContent = child.textContent; if (match) { for (var i = 0; i < match.length; i++) { - let result = x(this, match[i].match(/([^\[].+[^\]])/)[0]) + let result = x(child.parentBind || this, match[i].match(/([^\[].+[^\]])/)[0]) if (result) { - child.innerText = child.innerText.replace(match[i], result) + child.textContent = child.textContent.replace(match[i], result) } } @@ -310,6 +352,8 @@ __bind(this, descriptor.child, descriptor) } else if (descriptor.type === 'I') { __inject(descriptor, descriptor.child) + } else if (descriptor.type === 'R') { + __repeater(descriptor, descriptor.child) } }) } diff --git a/components/s-repeat.js b/components/s-repeat.js index b67bfbc..a0ec7d6 100644 --- a/components/s-repeat.js +++ b/components/s-repeat.js @@ -2,10 +2,6 @@ Slim('s-repeat', class SlimRepeat extends SlimBaseElement { - afterRender() { - this.update() - } - get sourceData() { try { return this.parentBind[this.getAttribute('source')] @@ -21,20 +17,32 @@ update() { this.innerHTML = '' + let childrenToAdd = [] for (let dataItem of this.sourceData) { for (let child of this.__bindingTree.children) { - let node = document.importNode(child, false) + let node = child.cloneNode(true) + node.parentBind = node node.data = dataItem + if (!node.parentBind) { + node.parentBind = node + } for (let prop in dataItem) { node[prop] = dataItem[prop] if (!(typeof dataItem[prop] === "function") && !(typeof dataItem[prop] === "object")) { node.setAttribute(prop, dataItem[prop]) } } - this.appendChild(node) - node.update() + if (node.isSlim) { + node.createdCallback(true) + } else { + this._applyTextBindings.bind(node)() + } + childrenToAdd.push(node) } } + for (let child of childrenToAdd) { + this.appendChild(child) + } } }) })() \ No newline at end of file diff --git a/example/Kanban/KanbanDemo.html b/example/Kanban/KanbanDemo.html index 12592dc..32fd144 100644 --- a/example/Kanban/KanbanDemo.html +++ b/example/Kanban/KanbanDemo.html @@ -6,6 +6,8 @@ + + diff --git a/example/Kanban/KanbanModel.js b/example/Kanban/KanbanModel.js index d6a8c6d..f2bc832 100644 --- a/example/Kanban/KanbanModel.js +++ b/example/Kanban/KanbanModel.js @@ -6,18 +6,18 @@ class KanbanModel { constructor() { - this.lists = ['Todo', 'In-Progress', 'Done'] + this.columns = [{name: 'Todo'},{name:'In-Progress'},{name:'Done'}] this.tasks = [] } getTasks(column) { - return tasks.filter( task => { + return this.tasks.filter( task => { return task.column === column }) } - addTask(name = 'New Task', description = '') { - let newTask = { name, description} + addTask(title = 'New Task', description = '') { + let newTask = { title, description} newTask.column = 'Todo' this.tasks.push(newTask) } diff --git a/example/Kanban/kanban-app.html b/example/Kanban/kanban-app.html index 0c6406a..62abb4b 100644 --- a/example/Kanban/kanban-app.html +++ b/example/Kanban/kanban-app.html @@ -2,15 +2,15 @@ Slim('kanban-app', class extends SlimBaseElement { + get template() { - return ` -[[model.hello]]
-` + return `` } - onCreated() { - this.wtf = "Hello" + get columns() { + return this.model.columns } + }) diff --git a/example/Kanban/kanban-column.js b/example/Kanban/kanban-column.js new file mode 100644 index 0000000..01a8e00 --- /dev/null +++ b/example/Kanban/kanban-column.js @@ -0,0 +1,25 @@ +;(function(){ + + + Slim('kanban-column', class extends SlimBaseElement { + + + get template() { + return `
[[data.name]]
` + } + + onAdded() { + console.log(this.myTasks) + } + + get myTasks() { + return this.model.getTasks(this.data.name) + } + + + }) + + + + +})() \ No newline at end of file diff --git a/example/Kanban/kanban-item.js b/example/Kanban/kanban-item.js new file mode 100644 index 0000000..f9d55b5 --- /dev/null +++ b/example/Kanban/kanban-item.js @@ -0,0 +1,22 @@ +;(function(){ + + + Slim('kanban-item', class extends SlimBaseElement { + + + + get template() { + return `[[data.title]]` + } + + + + + + + }) + + + + +})() \ No newline at end of file