UNPKG

neft

Version:

JavaScript. Everywhere.

162 lines (121 loc) 4.14 kB
'use strict' utils = require 'src/utils' assert = require 'src/assert' log = require 'src/log' assert = assert.scope 'View.Use' log = log.scope 'View', 'Use' module.exports = (File) -> class Use @__name__ = 'Use' @__path__ = 'File.Use' JSON_CTOR_ID = @JSON_CTOR_ID = File.JSON_CTORS.push(Use) - 1 i = 1 JSON_NODE = i++ JSON_ARGS_LENGTH = @JSON_ARGS_LENGTH = i @_fromJSON = (file, arr, obj) -> unless obj node = file.node.getChildByAccessPath arr[JSON_NODE] obj = new Use file, node obj visibilityChangeListener = -> if @file.isRendered and not @isRendered @render() attrsChangeListener = (name) -> if name is 'neft:fragment' @name = @node.attrs['neft:fragment'] if @isRendered @revert() @render() return queue = [] queuePending = false runQueue = -> style = queue.shift() file = queue.shift() if style.isRendered style.renderFragment file if queue.length requestAnimationFrame runQueue else queuePending = false return constructor: (@file, @node) -> assert.instanceOf @file, File assert.instanceOf @node, File.Element @name = @node.attrs['neft:fragment'] @usedFragment = null @isRendered = false @node.onVisibleChange visibilityChangeListener, @ @node.onAttrsChange attrsChangeListener, @ `//<development>` if @constructor is Use Object.preventExtensions @ `//</development>` `//<development>` usesWithNotFoundFragments = [] logUsesWithNoFragments = -> while useElem = usesWithNotFoundFragments.pop() unless useElem.usedFragment log.warn "neft:fragment '#{useElem.name}' can't be find in file '#{useElem.file.path}'" return `//</development>` render: (file) -> assert.instanceOf file, File if file? return unless @node.visible if @isRendered @revert() @isRendered = true useAsync = utils.isClient useAsync &&= @node.attrs.has 'neft:async' useAsync &&= @node.attrs['neft:async'] isnt false if useAsync queue.push this, file unless queuePending requestAnimationFrame runQueue queuePending = true else @renderFragment file return renderFragment: (file) -> fragment = @file.fragments[@name] if not file and not fragment and not File._files[@name] `//<development>` # if usesWithNotFoundFragments.push(@) is 1 # setTimeout logUsesWithNoFragments `//</development>` return usedFragment = file or File.factory(fragment or @name) if file file.parentUse?.detachUsedFragment() unless usedFragment.isClone usedFragment = usedFragment.clone() unless usedFragment.isRendered usedFragment = usedFragment.render null, @file.root, @ usedFragment.node.parent = @node @usedFragment = usedFragment # signal usedFragment.parentUse = @ usedFragment.onReplaceByUse.emit @ File.emitNodeSignal usedFragment, 'neft:onReplaceByUse', @ return revert: -> return unless @isRendered # destroy used fragment if @usedFragment @usedFragment.revert().destroy() @isRendered = false return detachUsedFragment: -> assert.isDefined @usedFragment @usedFragment.node.parent = null @usedFragment.parentUse = null @usedFragment = null return clone: (original, file) -> node = original.node.getCopiedElement @node, file.node new Use file, node toJSON: (key, arr) -> unless arr arr = new Array JSON_ARGS_LENGTH arr[0] = JSON_CTOR_ID arr[JSON_NODE] = @node.getAccessPath @file.node arr