neft
Version:
Universal Platform
221 lines (166 loc) • 5.37 kB
text/coffeescript
'use strict'
utils = require 'src/utils'
assert = require 'src/assert'
List = require 'src/list'
log = require 'src/log'
eventLoop = require 'src/eventLoop'
{isArray} = Array
assert = assert.scope 'View.Iterator'
log = log.scope 'View', 'Iterator'
module.exports = (File) -> class Iterator
= 'Iterator'
= 'File.Iterator'
JSON_CTOR_ID = = File.JSON_CTORS.push(Iterator) - 1
i = 1
JSON_NAME = i++
JSON_NODE = i++
JSON_TEXT = i++
JSON_ARGS_LENGTH = = i
= (file, arr, obj) ->
unless obj
node = file.node.getChildByAccessPath arr[JSON_NODE]
obj = new Iterator file, node, arr[JSON_NAME]
obj.text = arr[JSON_TEXT]
obj
propsChangeListener = (name) ->
if .isRendered and name is 'n-each'
visibilityChangeListener = (oldValue) ->
value = not oldValue
isHidden = if value then -1 else 1
+= isHidden
if .isRendered and not
if .isRendered and and > 0
return
constructor: (, , ) ->
assert.instanceOf , File
assert.instanceOf , File.Element
assert.isString
assert.notLengthOf , 0
= []
= ''
= null
= false
= false
= 0
= Object.create .inputProps
= utils.bindFunctionContext , @
.onPropsChange propsChangeListener, @
do =>
elem =
while elem
if 'n-if' of elem.props
elem.onVisibleChange visibilityChangeListener, @
elem = elem.parent
`//<development>`
if is Iterator
Object.preventExtensions @
`//</development>`
renderImmediate: ->
unless
= true
eventLoop.setImmediate
return
_renderImmediateCallback: ->
= false
if not and .isRendered
return
render: ->
return if > 0
each = .props['n-each']
# stop if nothing changed
if each is
return
# stop if no data found
if not isArray(each) and not (each instanceof List)
# log.warn "Data is not an array nor List in '#{@text}':\n#{each}"
return
= true
# set as data
= array = each
# listen on changes
if each instanceof List
each.onChange , @
each.onInsert , @
each.onPop , @
# add items
for _, i in array
i
null
revert: ->
{data} = @
if data
if data instanceof List
data.onChange.disconnect , @
data.onInsert.disconnect , @
data.onPop.disconnect , @
= null
= false
return
update: ->
clearData: ->
assert.isObject
while length = .length
length - 1
@
updateItem: (elem, i) ->
unless i?
i = elem
assert.isObject
assert.isInteger i
i
i
@
insertItem: (elem, i) ->
unless i?
i = elem
assert.isObject
assert.isInteger i
{data} = @
usedComponent = File.factory
.splice i, 0, usedComponent
each = data
item = data[i]
# replace
newChild = usedComponent.node
newChild.parent =
newChild.index = i
# render component
.each = each
.index = i
.item = item
usedComponent.scope = .scope
usedComponent.render , .context, null, .inputRefs
# signal
usedComponent.onReplaceByUse.emit @
File.emitNodeSignal usedComponent, 'n-onReplaceByUse', @
@
popItem: (elem, i) ->
unless i?
i = elem
assert.isObject
assert.isInteger i
.children[i].parent = undefined
usedComponent = [i]
usedComponent.scope = null
usedComponent.revert().destroy()
.splice i, 1
@
clone: (original, file) ->
node = original.node.getCopiedElement , file.node
new Iterator file, node,
toJSON: (key, arr) ->
unless arr
arr = new Array JSON_ARGS_LENGTH
arr[0] = JSON_CTOR_ID
arr[JSON_NAME] =
arr[JSON_NODE] = .getAccessPath .node
arr[JSON_TEXT] =
arr