UNPKG

rendex

Version:
305 lines (228 loc) 6.83 kB
'use strict'; var _getContext = function(node,context){ return (node.render.context && node.render.context[context]) ? node.render.context[context] : node.render; } var _path = function(path, obj){ if( path.length === 1 ){ return obj[ path[0] ]; } var prop = path.shift(); return _path( path, obj[prop] ); } var _pathEq = function(path, value){ return function(obj){ if( Array.isArray(path) && path.length > 0 ){ var pval = _path( path.slice(), obj ); return (typeof pval === 'undefined' || pval === value); } throw("Invalid 'path' property"); } } var _extend = function (obj, src) { return Object.assign({}, obj, src ); } var _isActive = function(x){return x.active} var _filterShow = function( show, items){ return show ? items.filter(_pathEq(show.path, show.value)) : items; } var _makeOption = function(name, value){ var obj = {}; obj[ name ] = value; return obj; } var _nodeContent = function(m,a){ return m && m[ a ] } var _extendRuntimeRefOptions = function(obj, src, model){ return src.reduce( function(m,a){ if( a.id ){ var node = model.get( a.id ); if( node ){ if( a.path ){ return _extend( m, _makeOption(a.name, a.path.reduce(_nodeContent, node) )); } else{ return _extend( m, _makeOption(a.name, node )); } } throw("Runtime options error. Node '" + a.id +"' not found"); } return m; }, obj); } var _extendRuntimeFuncOptions = function(obj, src, data, func){ return src.reduce( function(m,a){ if( a.func ){ var fn = func[ a.func ]; if( fn ){ return _extend( m, _makeOption(a.name, fn.call(null, data, a.params)) ); } throw("Runtime options error. Function '" + a.func +"' not found"); } return m; }, obj); } var renderTemplate = function(data, tmpl){ var templateFunc = data.$templates[ tmpl ]; if(!templateFunc){ throw( data.$id + ": template '" + tmpl + "' not found" ); } templateFunc.call( null, data ); } var renderNode = function(data, template){ var $id = data.$id; var $context = data.$context; var $model = data.$model; var $templates = data.$templates; var $options = data.$options; var $index = data.$index; var $parent = data.$parent; var $siblings = data.$siblings; var $functions = data.$functions; var $node = $model.get( $id ); if(!$node){ throw("Cannot find node with id " + $id + "'" ); } $context = $node.context || $context; var tmpl = template; if( $node.render ) { if( $node.render.options ){ $options = _extend( $options, $node.render.options ); } if( $node.render.runtime && $node.render.runtime.options ){ $options = _extendRuntimeRefOptions( $options, $node.render.runtime.options, $model ); $options = _extendRuntimeFuncOptions( $options, $node.render.runtime.options, {$id,$model,$index,$parent,$siblings}, $functions ); } var ctx = _getContext($node, $context); if( ctx.options ){ $options = _extend( $options, ctx.options ); } if( ctx.runtime && ctx.runtime.options ){ $options = _extendRuntimeRefOptions( $options, ctx.runtime.options, $model ); $options = _extendRuntimeFuncOptions( $options, ctx.runtime.options, {$id,$model,$index,$parent,$siblings}, $functions ); } tmpl = tmpl || ctx.template; } tmpl = tmpl || $options.defaultTemplate; if( !tmpl ){ throw("Undefined template for context '" + $context + "' of node '" + $id + "'" ); } var _data = { $id: $id, $node: $node, $context: $context, $model: $model, $templates: $templates, $functions: $functions, $options: $options, $parent: $parent, $siblings: $siblings, $index: $index }; renderTemplate( _data, tmpl ); } var renderBranch = function(data, branchname, range, filter){ var $id = data.$id; var $node = data.$node; var $context = data.$context; var $model = data.$model; var $templates = data.$templates; var $options = data.$options; var $functions = data.$functions; var $index = data.$index; var $parent = data.$parent; var $siblings = data.$siblings; if( !$node.branch ){ return; } var bx = Array.isArray($node.branch) ? $node.branch : $node.branch[ branchname ]; if( !bx ){ return; } if( $node.render ) { var ctx = _getContext($node, $context); var branch, template, func; if( ctx.branchByName && ctx.branchByName[ branchname ] ){ branch = ctx.branchByName[ branchname ]; var swallow = (branch.swallow || []).find(_isActive); if( swallow ){ bx = [swallow]; branch = null; } else{ var skipTo = (branch.skipTo || []).filter(_isActive); if( skipTo.length ){ bx = skipTo; branch = null; } } } else{ branch = ctx.branch; } if( branch ){ bx = _filterShow( branch.show, bx ); if( branch.options ){ $options = _extend( $options, branch.options ); } if( branch.runtime && branch.runtime.options ){ $options = _extendRuntimeRefOptions( $options, branch.runtime.options, $model ); $options = _extendRuntimeFuncOptions( $options, branch.runtime.options, {$id,$model,$index,$parent,$siblings}, $functions ); } template = branch.template; } } bx.forEach( (item, index) => { if( !range || (index >= range[0] && index < range[1]) ){ var _options = $options; if( item.options ){ _options = _extend( $options, item.options ); } if( item.runtime && item.runtime.options ){ _options = _extendRuntimeRefOptions( $options, item.runtime.options, $model ); _options = _extendRuntimeFuncOptions( $options, item.runtime.options, {$id:item.id, $model,$index:index,$parent:$node,$siblings:bx}, $functions ); } var _context = item.context || $context; var _data = { $id: item.id, $context: _context, $model: $model, $templates: $templates, $functions: $functions, $options: _options, $parent: $node, $siblings: bx, $index: index }; if( filter ){ func = $functions[ filter ]; if( !func ){ throw("Undefined function '"+ filter + "'"); } } if( !filter || func(_data) ){ renderNode(_data, template); } } }); } var render = function(d){ var node = d.model.get(d.id); var data = { $id: d.id, $context: d.context, $model: d.model, $templates: d.templates, $options: d.options || {}, $functions: d.functions || {}, $parent: null, $siblings: [], $index: 0 }; renderNode( data ); } exports.renderTemplate = renderTemplate; exports.renderNode = renderNode; exports.renderBranch = renderBranch; exports.render = render;