UNPKG

luda

Version:

A library helps to build cross-framework UI components.

122 lines (102 loc) 3.79 kB
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 = @constructor 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 @root = luda root return unless rootEl = @root.els[0] @root = luda rootEl if @root.length > 1 @id = rootEl[expando] ||= guid() return inses[@id].instance if @id 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[@id] = {instance: this, traversal: traversal, watcher: watcher} _access rootEl, C.id, inses[@id] create.call this if create = C.helpers.create log "#{C.id} ID: #{@id} created.", 'Root element', rootEl, 'Cache', inses[@id] @create: (selector, ctx) -> C = this selector = @root if Type.isDocument(@root) or not selector luda(selector, ctx).els.map (el) -> new C el @destroy: (selector, ctx) -> C = this inses = @instances selector = @root if Type.isDocument(@root) 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 @help: (key, val) -> @help = createMounter @helpers, 'helping' @help key, val @include: (key, val) -> C = this fn = (name, value) -> C.included.push name value @include = createMounter @prototype, 'including', fn @include key, val @protect: (key, val) -> @protect = createMounter @prototype, 'protecting' @protect key, val @contains: (selector, ctx) -> inses = @instances luda(selector, ctx).els.some (el) -> (id = el[expando]) and inses[id] @each: (callback) -> Object.values(@instances).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: -> @constructor export default Base