UNPKG

dynamictemplate

Version:
551 lines (492 loc) 15.8 kB
(function() { var Binding, List, ListBinding, adiff, boundpartial, createBinding, deep_get, deep_set, functionify, isArray, listadd, listpartial, listpartialize, listrm, listswitch, listsync, multiplex, slice, test, __slice = [].slice, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; slice = Array.prototype.slice; isArray = Array.isArray; deep_get = function(data, keys) { var key, next, _i, _len, _ref; if (data == null) { return; } _ref = keys.split('.'); for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; next = data[key]; if (typeof next === 'function') { next = next.call(data); } data = next; if (data == null) { break; } } return data; }; deep_set = function(data, keys, value) { var key; if (data == null) { return; } keys = keys.split('.'); key = keys.pop(); data = deep_get(data, keys.join('.')); return data != null ? data[key] = value : void 0; }; functionify = function(callback, args) { var method, methods; if (typeof callback !== 'function') { if (isArray(callback)) { methods = callback; callback = function(value) { var method, _i, _len, _ref, _ref1; for (_i = 0, _len = methods.length; _i < _len; _i++) { method = methods[_i]; _ref = isArray(method) ? method : [method], method = _ref[0], args = 2 <= _ref.length ? __slice.call(_ref, 1) : []; if ((_ref1 = this[method]) != null) { _ref1.apply(this, args.concat([value])); } } }; callback.method = methods; } else { method = callback; callback = function(value) { var _ref; return (_ref = this[method]) != null ? _ref.apply(this, args.concat([value])) : void 0; }; callback.method = method; } } else { return function(value) { return callback.apply(this, args.concat([value])); }; } return callback; }; multiplex = function(key, callback, args, action) { var callbacks; if (typeof key === 'object') { callbacks = key; return function() { var _results; _results = []; for (key in callbacks) { callback = callbacks[key]; callback = functionify(callback, args); _results.push(action.call(this, key, callback)); } return _results; }; } else { callback = functionify(callback, args); return function() { return action.call(this, key, callback); }; } }; Binding = (function() { function Binding(data) { this.data = data != null ? data : {}; this._binds = {}; } Binding.prototype.bind = function() { var args, callback, key, that; key = arguments[0], callback = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; if (callback == null) { callback = 'text'; } that = this; return multiplex(key, callback, args, function(key, callback) { var _base, _ref; ((_ref = (_base = that._binds)[key]) != null ? _ref : _base[key] = []).push(callback.bind(this)); return callback.call(this, that.get(key)); }); }; Binding.prototype.unbind = function(key, callback) { var callbacks, fun, i, _i, _len, _ref; if (callback != null) { callbacks = (_ref = this._binds[key]) != null ? _ref : []; for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) { fun = callbacks[i]; if (callback === fun || fun.method === callback) { callbacks.splice(i, 1); } } } else { delete this._binds[key]; } return this; }; Binding.prototype.trigger = function(key, value) { var callback, _i, _len, _ref, _ref1; _ref1 = (_ref = this._binds[key]) != null ? _ref : []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { callback = _ref1[_i]; callback(value); } return this; }; Binding.prototype.set = function(key, value) { deep_set(this.data, key, value); this.trigger(key, value); return value; }; Binding.prototype.get = function(key) { return deep_get(this.data, key); }; Binding.prototype.change = function(data) { var key, value; if (data == null) { data = {}; } for (key in data) { value = data[key]; this.set(key, value); } return this; }; return Binding; })(); Binding.multiplex = multiplex; Binding.Binding = Binding; module.exports = Binding; if (1) { adiff = require('adiff'); List = require('dt-list').List; slice = Array.prototype.slice; isArray = Array.isArray; adiff = adiff({ equal: function(a, b) { if (a && !b) { return false; } if (isArray(a) && a.length !== b.length) { return false; } return a === b; } }, adiff); createBinding = function(value) { if (!(value && typeof value === 'object')) { return value; } return new ListBinding(value); }; boundpartial = function() { var args, binding, create, partial, value; create = arguments[0], value = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; binding = createBinding(value); partial = create.apply(null, [binding].concat(__slice.call(args))); if (typeof binding === 'object') { partial._bind = binding; } return partial; }; listadd = function(items, create, old, value) { var added, i, partial, val, _i, _len; added = []; for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) { val = value[i]; partial = boundpartial(create, val, i); added.push(partial); items.push(partial); } old.value = slice.call(value); return [added, [], []]; }; listrm = function(items, old) { var item, removed, _ref; removed = []; while (items.length) { item = (_ref = items.pop()) != null ? _ref.remove({ soft: false }) : void 0; if (item != null) { removed.push(item); } } old.value = []; return [[], [], removed]; }; listsync = function(items, create, old, value) { var added, changed, dead, i, item, n, patch, removed, _i, _j, _k, _len, _ref, _ref1, _ref2, _ref3, _ref4; _ref = [[], [], {}], added = _ref[0], changed = _ref[1], dead = _ref[2]; _ref1 = adiff.diff(old.value, value); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { patch = _ref1[_i]; for (i = _j = _ref2 = patch[0], _ref3 = patch[0] + patch[1]; _ref2 <= _ref3 ? _j < _ref3 : _j > _ref3; i = _ref2 <= _ref3 ? ++_j : --_j) { dead[i] = items[i]; } for (n = _k = 2, _ref4 = patch.length; 2 <= _ref4 ? _k < _ref4 : _k > _ref4; n = 2 <= _ref4 ? ++_k : --_k) { i = old.value.indexOf(patch[n]); if (i === -1) { patch[n] = boundpartial(create, patch[n], patch[0] + n - 2); added.push(patch[n]); } else { delete dead[i]; patch[n] = items[i]; changed.push(patch[n]); items[i].remove({ soft: true }); } } items.splice.apply(items, patch); } removed = (function() { var _results; _results = []; for (i in dead) { item = dead[i]; _results.push(item.remove({ soft: false })); } return _results; })(); old.value = slice.call(value); return [added, changed, removed]; }; listswitch = function(items, create, old, value) { var len, old_len, _ref; _ref = [old.value.length, value.length], old_len = _ref[0], len = _ref[1]; if (!old_len && !len) { return [[], [], []]; } else if (old_len && !len) { return listrm(items, old); } else if (!old_len && len) { return listadd(items, create, old, value); } else { return listsync(items, create, old, value); } }; listpartialize = function(items, create, old, value) { var added, changed, item, itempartial, removed, _i, _j, _len, _len1, _ref; if (value == null) { value = []; } _ref = listswitch(items, create.bind(this), old, value), added = _ref[0], changed = _ref[1], removed = _ref[2]; for (_i = 0, _len = changed.length; _i < _len; _i++) { item = changed[_i]; this.add(item); } for (_j = 0, _len1 = added.length; _j < _len1; _j++) { itempartial = added[_j]; if (itempartial.run != null) { this.add(itempartial); itempartial.run(); } } return this; }; listpartial = function(items, create, old, value) { var partial; partial = boundpartial(create.bind(this), value); old.value.push(value); items.push(partial); if (partial.run != null) { this.add(partial); partial.run(); } return partial; }; } ListBinding = (function(_super) { __extends(ListBinding, _super); function ListBinding() { this.items = {}; this.values = {}; this.partials = {}; ListBinding.__super__.constructor.apply(this, arguments); } ListBinding.prototype.repeat = function() { var args, callback, items, key, old, that; key = arguments[0], callback = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; if (callback == null) { callback = 'text'; } that = this; old = { value: [] }; items = new List; return multiplex(key, callback, args, function(key, callback) { var _base, _ref; that.items[key] = items; that.values[key] = old; that.partials[key] = listpartial.bind(this, items, callback, old); ((_ref = (_base = that._binds)[key]) != null ? _ref : _base[key] = []).push(listpartialize.bind(this, items, callback, old)); return listpartialize.call(this, items, callback, old, that.get(key)); }); }; ListBinding.prototype.unbind = function(key) { if (this.items[key] != null) { delete this.items[key]; } if (this.values[key] != null) { delete this.values[key]; } if (this.partials[key] != null) { delete this.partials[key]; } return ListBinding.__super__.unbind.apply(this, arguments); }; ListBinding.prototype.set = function(key, value) { var curkey, data, i, k, keys, last_key, next, restkeys, result, _i, _len, _ref, _ref1, _ref2; data = this.data; keys = key.split('.'); last_key = keys.pop(); curkey = ''; for (i = _i = 0, _len = keys.length; _i < _len; i = ++_i) { k = keys[i]; curkey += (curkey && '.' || '') + k; next = data[k]; if (typeof next === 'function') { next = next.call(data); } data = next; if (isArray(data)) { restkeys = keys.slice(i + 1); restkeys.push(last_key); result = (_ref = this.items[curkey][k]) != null ? (_ref1 = _ref._bind) != null ? _ref1.set(restkey.join('.'), value) : void 0 : void 0; if (((_ref2 = this.items[curkey][k]) != null ? _ref2._bind : void 0) != null) { this.trigger(key, result); } return result; } if (data == null) { break; } } if (data != null) { data[last_key] = value; } if (data != null) { this.trigger(key, value); } return value; }; ListBinding.prototype.addTo = function(key, value) { var _base; return typeof (_base = this.partials)[key] === "function" ? _base[key](value) : void 0; }; ListBinding.prototype.removeFrom = function(key, i) { if (this.values[key] == null) { return; } this.values[key].value.splice(i, 1); delete this.items[i]._bind; return this.items.remove(i); }; return ListBinding; })(Binding); if (0) { ListBinding.listpartial = listpartial; ListBinding.listsync = listsync; ListBinding.ListBinding = ListBinding; ListBinding.Binding = ListBinding; module.exports = ListBinding; } test = function() { var Template, data, i, numbers, render, template, tpl; Template = require('./template'); render = require('./render'); template = function(data) { return new Template({ schema: 5, pretty: true }, function() { return this.$html(function() { this.$head(function() { return this.$title("test"); }); return this.$body(function() { return this.$main(function() { this.$div({ "class": 'users' }, function() { return this.$span('foobar'); }); this.$ul({ "class": 'users' }, data.repeat('users', function(user) { return this.$li({ "class": 'user' }, function() { user.bind('title', 'attr', 'title').call(this); this.$div({ "class": 'name' }, user.bind({ 'name': 'text', 'age': ['attr', 'data-age'], 'repo': ['attr', 'data-repo'] })); this.$div({ "class": 'repo' }, user.bind('repo')); this.$div({ "class": 'age' }, user.bind('age')); return this.$div({ "class": 'box' }, user.bind('box.color', 'attr', 'data-color')); }); })); this.$h3("next lotto numbers are …"); return this.$ul({ "class": 'numbers' }, data.repeat('lotto', '$li')); }); }); }); }); }; numbers = (function() { var _i, _results; _results = []; for (i = _i = 1; _i <= 10; i = ++_i) { _results.push(Math.round(Math.random() * 100)); } return _results; })(); data = new ListBinding({ lotto: numbers, users: [ { name: "foobar", age: 3, repo: "git", title: "red box", box: { color: "red" } }, { name: "trololo", age: 6, repo: "hg", title: "pink box", box: { color: "pink" } } ] }); tpl = template(data); tpl.ready(function() { setTimeout(function() { return data.set('users.0.name', "trololo"); }, 500); setTimeout(function() { return data.set('users.0.age', 6); }, 1500); return setTimeout(function() { data.set('users.1.title', "green box"); return data.set('users.1.box.color', "green"); }, 1500); }); return render(tpl).pipe(process.stdout); }; test(); }).call(this);