luda
Version:
A library helps to build cross-framework UI components.
122 lines (102 loc) • 3.79 kB
text/coffeescript
import luda from '../../base/luda.coffee'
import createMounter from '../../base/create-mounter.coffee'
import expando from '../../base/expando.coffee'
import guid from '../../base/guid.coffee'
import Type from '../../base/type.coffee'
import log from '../../log/log.coffee'
import {_access} from '../../cache/helpers/access.coffee'
import {addEvents, removeEvents} from './events.coffee'
import {addTraversal, cleanTraversal} from './traversal.coffee'
import {watch, stopWatch} from './watch.coffee'
class Base
win: luda window
doc: luda document
constructor: (root) ->
C =
proto = C.prototype
inses = C.instances
unless Type.isString(C.root) or Type.isDocument C.root
throw new Error 'Component root can only be selectors or document'
return root if root instanceof C
root = C.root if Type.isDocument C.root
= luda root
return unless rootEl = .els[0]
= luda rootEl if .length > 1
= rootEl[expando] ||= guid()
return inses[ ].instance if of inses
if (listen = C.helpers.listen) and not C.eventsBinded
addEvents C
C.eventsBinded = true
if (find = C.helpers.find) and not C.traversalAdded
addTraversal C
C.traversalAdded = true
traversal = {} if proto.cleanTraversal
if traversal and not C.watches
if definedWatch = C.helpers.watch
C.helpers.watch = ->
watches = definedWatch.call this
watches.node ||= []
watches.node.unshift [proto.cleanTraversal]
watches
else
C.helpers.watch = -> {node: [[proto.cleanTraversal]]}
watcher = watch C, this if C.helpers.watch
inses[ ] = {instance: this, traversal: traversal, watcher: watcher}
_access rootEl, C.id, inses[ ]
create.call this if create = C.helpers.create
log "#{C.id} ID: #{@id} created.",
'Root element', rootEl, 'Cache', inses[ ]
: (selector, ctx) ->
C = this
selector = if Type.isDocument( ) or not selector
luda(selector, ctx).els.map (el) -> new C el
: (selector, ctx) ->
C = this
inses =
selector = if Type.isDocument( ) or not selector
luda(selector, ctx).els.forEach (rootEl) ->
return unless id = rootEl[expando]
return unless id of inses
instance = inses[id].instance
watcher = inses[id].watcher
destroy.call instance if destroy = C.helpers.destroy
stopWatch instance, watcher if watcher
delete inses[id]
_access rootEl, C.id, null
log "#{C.id} ID: #{id} destroied.",
'Root element', rootEl, 'Cache', inses[id]
hasInstances = Object.keys(inses).length
if not hasInstances and C.eventsBinded
removeEvents C
C.eventsBinded = false
this
: (key, val) ->
= createMounter , 'helping'
key, val
: (key, val) ->
C = this
fn = (name, value) ->
C.included.push name
value
= createMounter , 'including', fn
key, val
: (key, val) ->
= createMounter , 'protecting'
key, val
: (selector, ctx) ->
inses =
luda(selector, ctx).els.some (el) ->
(id = el[expando]) and inses[id]
: (callback) ->
Object.values( ).some (cache, index) ->
instance = cache.instance
rootEl = instance.root.els[0]
callback(instance, rootEl, index, cache) is false
this
Object.defineProperty Base.prototype, 'html',
get: -> luda document.documentElement
Object.defineProperty Base.prototype, 'body',
get: -> luda document.body
Object.defineProperty Base.prototype, 'con',
get: ->
export default Base