Skip to content

Commit

Permalink
before/after render added to render cycle
Browse files Browse the repository at this point in the history
  • Loading branch information
eavichay committed Jan 10, 2017
1 parent 0d1d16f commit d251de5
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 50 deletions.
95 changes: 51 additions & 44 deletions Slim.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ class Slim extends HTMLElement {
}

static plugin(phase, plugin) {
if (phase !== 'create' && phase !== 'beforeRender' && phase !== 'afterRender') {
throw "Supported phase can be create, beforeRender or afterRender only"
if (phase !== 'create' && phase !== 'beforeRender' && phase !== 'afterRender' && phase !== 'beforeDestroy') {
throw "Supported phase can be create, beforeDestroy, beforeRender or afterRender only"
}
Slim.__plugins[phase].push(plugin)
}
Expand Down Expand Up @@ -125,14 +125,14 @@ class Slim extends HTMLElement {
if (!source.__lookupSetter__(prop)) source.__defineSetter__(prop, function(x) {
this._bindings[prop].value = x
if (descriptor.sourceText) {
descriptor.target.textContent = descriptor.sourceText
descriptor.target.innerText = descriptor.sourceText
}
this._executeBindings()
})
let executor
if (descriptor.type === 'P') {
executor = () => {
let value = Slim.__lookup(source, prop).obj //this._bindings[prop].value
let value = Slim.__lookup(source, prop).obj
descriptor.target[ Slim.__dashToCamel(descriptor.attribute) ] = value
descriptor.target.setAttribute( descriptor.attribute, value )
}
Expand All @@ -146,7 +146,7 @@ class Slim extends HTMLElement {
} else if (descriptor.type === 'T') {
executor = () => {
let source = descriptor.target._boundParent
descriptor.target.textContent = descriptor.target.textContent.replace(`[[${prop}]]`, Slim.__lookup(source, prop).obj)
descriptor.target.innerText = descriptor.target.innerText.replace(`[[${prop}]]`, Slim.__lookup(source, prop).obj)
}
} else if (descriptor.type === 'R') {
executor = () => {
Expand Down Expand Up @@ -236,7 +236,13 @@ class Slim extends HTMLElement {
this.update()
}

detachedCallback() {
Slim.__runPlugins('beforeDestroy', this)
this.onDestroy()
}

initialize(forceNewVirtualDOM = false) {
this._executeByBindAttribute = true
this._bindings = this._bindings || {}
this._boundChildren = this._boundChildren || []
this.alternateTemplate = this.alternateTemplate || null
Expand All @@ -249,6 +255,7 @@ class Slim extends HTMLElement {
get isSlim() { return true }
get template() { return null }

onDestroy() { /* abstract */ }
onBeforeCreated() { /* abstract */ }
onCreated() { /* abstract */}
onBeforeRender() { /* abstract */ }
Expand All @@ -258,19 +265,30 @@ class Slim extends HTMLElement {
}

render(template) {
Slim.__runPlugins('beforeRender', this)
this.onBeforeRender()
this.alternateTemplate = template
this.initialize(true)
this.innerHTML = ''
this._captureBindings()
Slim.__moveChildren( this._virtualDOM, this, true )
this._executeBindings()
this.onAfterRender()
Slim.__runPlugins('afterRender', this)
}


_executeBindings() {
this.findAll('[bind]').forEach( child => {
if (child.sourceText) {
child.textContent = child.sourceText
let children
if (this._executeByBindAttribute == false) {
children = this._boundChildren
} else {
children = this.findAll('*[bind]')
}
children.forEach( child => {
// this._boundChildren.forEach( child => {
if (child.sourceText !== undefined) {
child.innerText = child.sourceText
}
})
Object.keys(this._bindings).forEach( property => {
Expand All @@ -296,6 +314,9 @@ class Slim extends HTMLElement {

let allChildren = Array.prototype.slice.call( this._virtualDOM.querySelectorAll('*') )
for (let child of allChildren) {
if (child === this._virtualDOM) {
alert('fuck')
}
child._boundParent = child._boundParent || this
this._boundChildren.push(child)
if (child.getAttribute('slim-id')) {
Expand All @@ -307,6 +328,10 @@ class Slim extends HTMLElement {
if (child.attributes) for (let i = 0; i < child.attributes.length; i++) {
let desc = Slim.__processAttribute(child.attributes[i], child)
if (desc) descriptors.push(desc)
if (child.attributes[i].nodeName.indexOf('#') == '0') {
let refName = child.attributes[i].nodeName.slice(1)
this[refName] = child
}
}

descriptors = descriptors.sort( (a) => {
Expand All @@ -331,17 +356,8 @@ class Slim extends HTMLElement {

allChildren = Array.prototype.slice.call( this._virtualDOM.querySelectorAll('*[bind]'))

const x = function getDescendantProp(obj, desc) {
var arr = desc.split(".");
var prop = arr[0]
while(arr.length && obj) {
obj = obj[prop = arr.shift()]
}
return {source: desc, prop:prop, obj:obj};
}

for (let child of allChildren) {
let match = child.textContent.match(/\[\[([\w|.]+)\]\]/g)
let match = child.innerText.match(/\[\[([\w|.]+)\]\]/g)
if (match) {
let properties = []
for (let i = 0; i < match.length; i++) {
Expand All @@ -352,9 +368,9 @@ class Slim extends HTMLElement {
type: 'T',
properties: properties,
target: child,
sourceText: child.textContent
sourceText: child.innerText
}
descriptor.target.sourceText = descriptor.sourceText
child.sourceText = child.innerText
this.__bind(descriptor)
}
}
Expand Down Expand Up @@ -400,32 +416,23 @@ class SlimRepeater extends Slim {
this.clones = []
this.innerHTML = ''

if (Slim.__isWCSupported) {
this.sourceData.forEach( (dataItem, index ) => {
let clone = this.sourceNode.cloneNode(true)
// clone.innerHTML = this.sourceNode.innerHTML
clone.removeAttribute('slim-repeat')
clone.data = dataItem
clone.data_index = index
clone.data_source = this.sourceData
clone.sourceText = clone.textContent
this.clones.push(clone)
this.insertAdjacentElement('beforeEnd', clone)
})
} else {
this.sourceData.forEach( (dataItem, index ) => {
let clone = this.sourceNode.cloneNode(true)
clone.removeAttribute('slim-repeat')
clone.setAttribute('slim-repeat-index', index)
this.sourceData.forEach( (dataItem, index) => {
let clone = this.sourceNode.cloneNode(true)
clone.removeAttribute('slim-repeat')
clone.setAttribute('slim-repeat-index', index)
if (!Slim.__isWCSupported) {
this.insertAdjacentHTML('beforeEnd', clone.outerHTML)
clone = this.find('*[slim-repeat-index="' + index.toString() + '"]')
clone.data = dataItem
clone.data_index = index
clone.data_source = this.sourceData
clone.sourceText = clone.textContent
this.clones.push(clone)
})
}
}
clone.data = dataItem
clone.data_index = index
clone.data_source = this.sourceData
clone.sourceText = clone.innerText
if (Slim.__isWCSupported) {
this.insertAdjacentElement('beforeEnd', clone)
}
this.clones.push(clone)
})
this._captureBindings()
for (let clone of this.clones) {
clone.data = clone.data
Expand Down
5 changes: 3 additions & 2 deletions example/tests/bind-child.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Slim.tag('bind-child', class extends Slim {

get template() {
return `<div bind>[[data.label]] Click for value [[updateCount]] / [[renderCount]]</div>`
return `<div #myDiv bind>[[data.label]] Click for value [[updateCount]] / [[renderCount]]</div>`
}

onBeforeCreated() {
Expand All @@ -21,10 +21,11 @@ Slim.tag('bind-child', class extends Slim {
}

onAfterRender() {
this.mydiv.style.color = 'red'
this.onclick = ()=>{
this.customRender = !this.customRender;
if (this.customRender) {
this.render(`<div prop="[[data.label]]" bind>[[data.label]] : [[data.value]] - [[updateCount]] / [[renderCount]]</div>`)
this.render(`<div #mydiv prop="[[data.label]]" bind>[[data.label]] : [[data.value]] - [[updateCount]] / [[renderCount]]</div>`)
} else {
this.render()
}
Expand Down
6 changes: 5 additions & 1 deletion example/tests/bind-parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ Slim.tag('bind-parent', class extends Slim {

get template() {
return `
<div calc="[[calcMinus(myProp, urProp)]]"><span minus="[calcMinus(myProp, urProp)]" bind>[[wProp]]</div>
<h1 bind>[[myTitle]]</h1>
<div calc="[[calcMinus(myProp, urProp)]]"><span minus="[[calcMinus(myProp, urProp)]]" bind>[[wProp]]</div>
<div slim-repeat="items" bind>[[data.label]] >>> [[data.value]]</div>
<hr/>
<li slim-repeat="items"><div>Div</div><span bind>Label [[data.label]]</span></li>
Expand All @@ -19,6 +20,7 @@ Slim.tag('bind-parent', class extends Slim {
}

onBeforeCreated() {
this.myTitle = "Binding Test"
this.myProp = 0
this.urProp = 1
this.wProp = this.myProp + this.urProp
Expand All @@ -41,6 +43,7 @@ Slim.tag('bind-parent', class extends Slim {
setTimeout( () => {
this.myProp = Math.random()
this.urProp = Math.random()
this.wProp = this.myProp + this.urProp
let l = parseInt(Math.random() * 5)
let tmpItems = []
for (let a = l; a >=0 ; a--) {
Expand All @@ -55,6 +58,7 @@ Slim.tag('bind-parent', class extends Slim {
setTimeout( () => {
this.myProp = Math.random()
this.urProp = Math.random()
this.wProp = this.myProp + this.urProp
let l = parseInt(Math.random() * 5)
let tmpItems = []
for (let a = l; a >=0 ; a--) {
Expand Down
2 changes: 1 addition & 1 deletion example/tests/bind-test.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@


<bind-parent>
<li slim-repeat="items"><bind-child a-prop="[[myProp]]" b-prop="[[urProp]]"></bind-child></li>
<li slim-repeat="items"><span bind>[[data_index]]</span><bind-child a-prop="[[myProp]]" b-prop="[[urProp]]"></bind-child></li>
<br/>
<hr/>
<tree-list bind-wprop="[[wProp]]" slim-repeat="tree"></tree-list>
Expand Down
8 changes: 6 additions & 2 deletions framework/components/basic-elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,19 @@ Slim.tag('s-input-model', class extends SlimModel {
Slim.tag('s-editable-input', class extends Slim {

get template() {
return `<span slim-id="label" bind>[[text]]</span><input slim-id="inp" type="text" value=[[text]] />`
return `<span #label bind>[[text]]</span><input #inp type="text" value=[[text]] />`
}

onBeforeCreated() {
this._executeByBindAttribute = true
}

onCreated() {
this._boundProperty = this.getAttribute('text')
if (this._boundProperty && this._boundProperty.indexOf('@' === 0)) {
this._boundProperty = this._boundProperty.replace('@', '')
this.text = this._boundParent[ this._boundProperty ]
}
this.text = this._boundParent[ this._boundProperty ]

this.style.position = 'relative'
this.inp.style.display = 'none'
Expand Down
3 changes: 3 additions & 0 deletions framework/tests/slim-ui-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ Slim.tag('slim-ui-test', class extends Slim {

Slim.tag('editable-ui-test', class extends Slim {

onBeforeCreated() {
this._executeByBindAttribute = false
}

get template() {
return '<div bind>Hello, [[myText]]</div><s-editable-input text="@myText"></s-editable-input>'
Expand Down

0 comments on commit d251de5

Please sign in to comment.