UNPKG

neft

Version:

Universal Platform

181 lines (146 loc) 4.78 kB
'use strict' utils = require 'src/utils' assert = require 'src/assert' log = require 'src/log' signal = require 'src/signal' Dict = require 'src/dict' List = require 'src/list' Binding = require 'src/binding' assert = assert.scope 'View.Input' log = log.scope 'View', 'Input' class DocumentBinding extends Binding @New = (binding, ctx, target) -> target ?= new DocumentBinding binding, ctx Binding.New binding, ctx, target constructor: (binding, ctx) -> super binding, ctx @args = ctx.file.inputArgs `//<development>` @failed = false @failCheckPending = false `//</development>` getItemById: (item) -> if item is 'this' @ctx else if item is 'refs' @args[0] else if item is 'props' @args[1] else if item is 'state' @args[2] `//<development>` failCheckQueue = [] failCheckQueuePending = false checkFails = -> while binding = failCheckQueue.pop() err = failCheckQueue.pop() if binding.failed log.error "Error in '#{binding.ctx.text}', file '#{binding.ctx.file.path}':\n#{err}" binding.failCheckPending = false failCheckQueuePending = false return onError: (err) -> @failed = true unless @failCheckPending @failCheckPending = true failCheckQueue.push err, @ unless failCheckQueuePending failCheckQueuePending = true setImmediate checkFails return `//</development>` update: -> # disable updates for reverted files unless @ctx.file.isRendered @ctx.isDirty = true return `//<development>` @failed = false `//</development>` super() getValue: -> @ctx.getValue() setValue: (val) -> @ctx.setValue val module.exports = (File) -> class Input extends signal.Emitter {Element} = File {Tag} = Element @__name__ = 'Input' @__path__ = 'File.Input' JSON_CTOR_ID = @JSON_CTOR_ID = File.JSON_CTORS.push(Input) - 1 i = 1 JSON_NODE = @JSON_NODE = i++ JSON_TEXT = @JSON_TEXT = i++ JSON_BINDING = @JSON_BINDING = i++ JSON_ARGS_LENGTH = @JSON_ARGS_LENGTH = i @_fromJSON = (file, arr, obj) -> unless obj node = file.node.getChildByAccessPath arr[JSON_NODE] obj = new Input file, node, arr[JSON_TEXT], arr[JSON_BINDING] obj RE = @RE = new RegExp '([^$]*)\\${([^}]*)}([^$]*)', 'gm' @test = (str) -> RE.lastIndex = 0 RE.test str if utils.isServer @parse = require('./input/parser').parse initBindingConfig = (cfg) -> cfg.func ?= new Function 'refs', 'props', 'state', cfg.body cfg.tree ?= [cfg.func, cfg.connections] return constructor: (@file, @node, @text, @bindingConfig) -> assert.instanceOf @file, File assert.instanceOf @node, File.Element assert.isString @text assert.isObject @bindingConfig super() @target = null @context = null @isDirty = false @binding = null initBindingConfig @bindingConfig `//<development>` if @constructor is Input Object.seal @ `//</development>` signal.Emitter.createSignal @, 'onTargetChange' signal.Emitter.createSignal @, 'onContextChange' registerBinding: -> assert.isNotDefined @binding @binding = DocumentBinding.New @bindingConfig.tree, @ if @bindingConfig.updateOnCreate @isDirty = true return render: -> oldTarget = @target oldContext = @context @target = @file.scope @context = @file.context if oldTarget isnt @target @onTargetChange.emit() if oldContext isnt @context @onContextChange.emit() return onRender: -> if @isDirty @isDirty = false @binding.update() return revert: -> return clone: (original, file) -> node = original.node.getCopiedElement @node, file.node new Input file, node, @text, @bindingConfig toJSON: (key, arr) -> unless arr arr = new Array JSON_ARGS_LENGTH arr[0] = JSON_CTOR_ID arr[JSON_NODE] = @node.getAccessPath @file.node arr[JSON_TEXT] = @text arr[JSON_BINDING] = body: @bindingConfig.body connections: @bindingConfig.connections updateOnCreate: @bindingConfig.updateOnCreate arr @Text = require('./input/text.coffee') File, @ @Prop = require('./input/prop.coffee') File, @