// Rivets.js // version: 0.9.6 // author: Michael Richards // license: MIT (function() { var Rivets, bindMethod, jQuery, unbindMethod, _ref, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __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; }, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; Rivets = { options: ['prefix', 'templateDelimiters', 'rootInterface', 'preloadData', 'handler', 'executeFunctions'], extensions: ['binders', 'formatters', 'components', 'adapters'], "public": { binders: {}, components: {}, formatters: {}, adapters: {}, prefix: 'rv', templateDelimiters: ['{', '}'], rootInterface: '.', preloadData: true, executeFunctions: false, iterationAlias: function(modelName) { return '%' + modelName + '%'; }, handler: function(context, ev, binding) { return this.call(context, ev, binding.view.models); }, configure: function(options) { var descriptor, key, option, value; if (options == null) { options = {}; } for (option in options) { value = options[option]; if (option === 'binders' || option === 'components' || option === 'formatters' || option === 'adapters') { for (key in value) { descriptor = value[key]; Rivets[option][key] = descriptor; } } else { Rivets["public"][option] = value; } } }, bind: function(el, models, options) { var view; if (models == null) { models = {}; } if (options == null) { options = {}; } view = new Rivets.View(el, models, options); view.bind(); return view; }, init: function(component, el, data) { var scope, template, view; if (data == null) { data = {}; } if (el == null) { el = document.createElement('div'); } component = Rivets["public"].components[component]; template = component.template.call(this, el); if (template instanceof HTMLElement) { while (el.firstChild) { el.removeChild(el.firstChild); } el.appendChild(template); } else { el.innerHTML = template; } scope = component.initialize.call(this, el, data); view = new Rivets.View(el, scope); view.bind(); return view; } } }; if (window['jQuery'] || window['$']) { jQuery = window['jQuery'] || window['$']; _ref = 'on' in jQuery.prototype ? ['on', 'off'] : ['bind', 'unbind'], bindMethod = _ref[0], unbindMethod = _ref[1]; Rivets.Util = { bindEvent: function(el, event, handler) { return jQuery(el)[bindMethod](event, handler); }, unbindEvent: function(el, event, handler) { return jQuery(el)[unbindMethod](event, handler); }, getInputValue: function(el) { var $el; $el = jQuery(el); if ($el.attr('type') === 'checkbox') { return $el.is(':checked'); } else { return $el.val(); } } }; } else { Rivets.Util = { bindEvent: (function() { if ('addEventListener' in window) { return function(el, event, handler) { return el.addEventListener(event, handler, false); }; } return function(el, event, handler) { return el.attachEvent('on' + event, handler); }; })(), unbindEvent: (function() { if ('removeEventListener' in window) { return function(el, event, handler) { return el.removeEventListener(event, handler, false); }; } return function(el, event, handler) { return el.detachEvent('on' + event, handler); }; })(), getInputValue: function(el) { var o, _i, _len, _results; if (el.type === 'checkbox') { return el.checked; } else if (el.type === 'select-multiple') { _results = []; for (_i = 0, _len = el.length; _i < _len; _i++) { o = el[_i]; if (o.selected) { _results.push(o.value); } } return _results; } else { return el.value; } } }; } Rivets.TypeParser = (function() { function TypeParser() {} TypeParser.types = { primitive: 0, keypath: 1 }; TypeParser.parse = function(string) { if (/^'.*'$|^".*"$/.test(string)) { return { type: this.types.primitive, value: string.slice(1, -1) }; } else if (string === 'true') { return { type: this.types.primitive, value: true }; } else if (string === 'false') { return { type: this.types.primitive, value: false }; } else if (string === 'null') { return { type: this.types.primitive, value: null }; } else if (string === 'undefined') { return { type: this.types.primitive, value: void 0 }; } else if (string === '') { return { type: this.types.primitive, value: void 0 }; } else if (isNaN(Number(string)) === false) { return { type: this.types.primitive, value: Number(string) }; } else { return { type: this.types.keypath, value: string }; } }; return TypeParser; })(); Rivets.TextTemplateParser = (function() { function TextTemplateParser() {} TextTemplateParser.types = { text: 0, binding: 1 }; TextTemplateParser.parse = function(template, delimiters) { var index, lastIndex, lastToken, length, substring, tokens, value; tokens = []; length = template.length; index = 0; lastIndex = 0; while (lastIndex < length) { index = template.indexOf(delimiters[0], lastIndex); if (index < 0) { tokens.push({ type: this.types.text, value: template.slice(lastIndex) }); break; } else { if (index > 0 && lastIndex < index) { tokens.push({ type: this.types.text, value: template.slice(lastIndex, index) }); } lastIndex = index + delimiters[0].length; index = template.indexOf(delimiters[1], lastIndex); if (index < 0) { substring = template.slice(lastIndex - delimiters[1].length); lastToken = tokens[tokens.length - 1]; if ((lastToken != null ? lastToken.type : void 0) === this.types.text) { lastToken.value += substring; } else { tokens.push({ type: this.types.text, value: substring }); } break; } value = template.slice(lastIndex, index).trim(); tokens.push({ type: this.types.binding, value: value }); lastIndex = index + delimiters[1].length; } } return tokens; }; return TextTemplateParser; })(); Rivets.View = (function() { function View(els, models, options) { var k, option, v, _base, _i, _j, _len, _len1, _ref1, _ref2, _ref3, _ref4, _ref5; this.els = els; this.models = models; if (options == null) { options = {}; } this.update = __bind(this.update, this); this.publish = __bind(this.publish, this); this.sync = __bind(this.sync, this); this.unbind = __bind(this.unbind, this); this.bind = __bind(this.bind, this); this.select = __bind(this.select, this); this.traverse = __bind(this.traverse, this); this.build = __bind(this.build, this); this.buildBinding = __bind(this.buildBinding, this); this.bindingRegExp = __bind(this.bindingRegExp, this); this.options = __bind(this.options, this); if (!(this.els.jquery || this.els instanceof Array)) { this.els = [this.els]; } _ref1 = Rivets.extensions; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { option = _ref1[_i]; this[option] = {}; if (options[option]) { _ref2 = options[option]; for (k in _ref2) { v = _ref2[k]; this[option][k] = v; } } _ref3 = Rivets["public"][option]; for (k in _ref3) { v = _ref3[k]; if ((_base = this[option])[k] == null) { _base[k] = v; } } } _ref4 = Rivets.options; for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { option = _ref4[_j]; this[option] = (_ref5 = options[option]) != null ? _ref5 : Rivets["public"][option]; } this.build(); } View.prototype.options = function() { var option, options, _i, _len, _ref1; options = {}; _ref1 = Rivets.extensions.concat(Rivets.options); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { option = _ref1[_i]; options[option] = this[option]; } return options; }; View.prototype.bindingRegExp = function() { return new RegExp("^" + this.prefix + "-"); }; View.prototype.buildBinding = function(binding, node, type, declaration) { var context, ctx, dependencies, keypath, options, pipe, pipes; options = {}; pipes = (function() { var _i, _len, _ref1, _results; _ref1 = declaration.match(/((?:'[^']*')*(?:(?:[^\|']*(?:'[^']*')+[^\|']*)+|[^\|]+))|^$/g); _results = []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { pipe = _ref1[_i]; _results.push(pipe.trim()); } return _results; })(); context = (function() { var _i, _len, _ref1, _results; _ref1 = pipes.shift().split('<'); _results = []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { ctx = _ref1[_i]; _results.push(ctx.trim()); } return _results; })(); keypath = context.shift(); options.formatters = pipes; if (dependencies = context.shift()) { options.dependencies = dependencies.split(/\s+/); } return this.bindings.push(new Rivets[binding](this, node, type, keypath, options)); }; View.prototype.build = function() { var el, parse, _i, _len, _ref1; this.bindings = []; parse = (function(_this) { return function(node) { var block, childNode, delimiters, n, parser, text, token, tokens, _i, _j, _len, _len1, _ref1; if (node.nodeType === 3) { parser = Rivets.TextTemplateParser; if (delimiters = _this.templateDelimiters) { if ((tokens = parser.parse(node.data, delimiters)).length) { if (!(tokens.length === 1 && tokens[0].type === parser.types.text)) { for (_i = 0, _len = tokens.length; _i < _len; _i++) { token = tokens[_i]; text = document.createTextNode(token.value); node.parentNode.insertBefore(text, node); if (token.type === 1) { _this.buildBinding('TextBinding', text, null, token.value); } } node.parentNode.removeChild(node); } } } } else if (node.nodeType === 1) { block = _this.traverse(node); } if (!block) { _ref1 = (function() { var _k, _len1, _ref1, _results; _ref1 = node.childNodes; _results = []; for (_k = 0, _len1 = _ref1.length; _k < _len1; _k++) { n = _ref1[_k]; _results.push(n); } return _results; })(); for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { childNode = _ref1[_j]; parse(childNode); } } }; })(this); _ref1 = this.els; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { el = _ref1[_i]; parse(el); } this.bindings.sort(function(a, b) { var _ref2, _ref3; return (((_ref2 = b.binder) != null ? _ref2.priority : void 0) || 0) - (((_ref3 = a.binder) != null ? _ref3.priority : void 0) || 0); }); }; View.prototype.traverse = function(node) { var attribute, attributes, binder, bindingRegExp, block, identifier, regexp, type, value, _i, _j, _len, _len1, _ref1, _ref2, _ref3; bindingRegExp = this.bindingRegExp(); block = node.nodeName === 'SCRIPT' || node.nodeName === 'STYLE'; _ref1 = node.attributes; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { attribute = _ref1[_i]; if (bindingRegExp.test(attribute.name)) { type = attribute.name.replace(bindingRegExp, ''); if (!(binder = this.binders[type])) { _ref2 = this.binders; for (identifier in _ref2) { value = _ref2[identifier]; if (identifier !== '*' && identifier.indexOf('*') !== -1) { regexp = new RegExp("^" + (identifier.replace(/\*/g, '.+')) + "$"); if (regexp.test(type)) { binder = value; } } } } binder || (binder = this.binders['*']); if (binder.block) { block = true; attributes = [attribute]; } } } _ref3 = attributes || node.attributes; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { attribute = _ref3[_j]; if (bindingRegExp.test(attribute.name)) { type = attribute.name.replace(bindingRegExp, ''); this.buildBinding('Binding', node, type, attribute.value); } } if (!block) { type = node.nodeName.toLowerCase(); if (this.components[type] && !node._bound) { this.bindings.push(new Rivets.ComponentBinding(this, node, type)); block = true; } } return block; }; View.prototype.select = function(fn) { var binding, _i, _len, _ref1, _results; _ref1 = this.bindings; _results = []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { binding = _ref1[_i]; if (fn(binding)) { _results.push(binding); } } return _results; }; View.prototype.bind = function() { var binding, _i, _len, _ref1; _ref1 = this.bindings; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { binding = _ref1[_i]; binding.bind(); } }; View.prototype.unbind = function() { var binding, _i, _len, _ref1; _ref1 = this.bindings; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { binding = _ref1[_i]; binding.unbind(); } }; View.prototype.sync = function() { var binding, _i, _len, _ref1; _ref1 = this.bindings; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { binding = _ref1[_i]; if (typeof binding.sync === "function") { binding.sync(); } } }; View.prototype.publish = function() { var binding, _i, _len, _ref1; _ref1 = this.select(function(b) { var _ref1; return (_ref1 = b.binder) != null ? _ref1.publishes : void 0; }); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { binding = _ref1[_i]; binding.publish(); } }; View.prototype.update = function(models) { var binding, key, model, _i, _len, _ref1; if (models == null) { models = {}; } for (key in models) { model = models[key]; this.models[key] = model; } _ref1 = this.bindings; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { binding = _ref1[_i]; if (typeof binding.update === "function") { binding.update(models); } } }; return View; })(); Rivets.Binding = (function() { function Binding(view, el, type, keypath, options) { this.view = view; this.el = el; this.type = type; this.keypath = keypath; this.options = options != null ? options : {}; this.getValue = __bind(this.getValue, this); this.update = __bind(this.update, this); this.unbind = __bind(this.unbind, this); this.bind = __bind(this.bind, this); this.publish = __bind(this.publish, this); this.sync = __bind(this.sync, this); this.set = __bind(this.set, this); this.eventHandler = __bind(this.eventHandler, this); this.formattedValue = __bind(this.formattedValue, this); this.parseFormatterArguments = __bind(this.parseFormatterArguments, this); this.parseTarget = __bind(this.parseTarget, this); this.observe = __bind(this.observe, this); this.setBinder = __bind(this.setBinder, this); this.formatters = this.options.formatters || []; this.dependencies = []; this.formatterObservers = {}; this.model = void 0; this.setBinder(); } Binding.prototype.setBinder = function() { var identifier, regexp, value, _ref1; if (!(this.binder = this.view.binders[this.type])) { _ref1 = this.view.binders; for (identifier in _ref1) { value = _ref1[identifier]; if (identifier !== '*' && identifier.indexOf('*') !== -1) { regexp = new RegExp("^" + (identifier.replace(/\*/g, '.+')) + "$"); if (regexp.test(this.type)) { this.binder = value; this.args = new RegExp("^" + (identifier.replace(/\*/g, '(.+)')) + "$").exec(this.type); this.args.shift(); } } } } this.binder || (this.binder = this.view.binders['*']); if (this.binder instanceof Function) { return this.binder = { routine: this.binder }; } }; Binding.prototype.observe = function(obj, keypath, callback) { return Rivets.sightglass(obj, keypath, callback, { root: this.view.rootInterface, adapters: this.view.adapters }); }; Binding.prototype.parseTarget = function() { var token; token = Rivets.TypeParser.parse(this.keypath); if (token.type === Rivets.TypeParser.types.primitive) { return this.value = token.value; } else { this.observer = this.observe(this.view.models, this.keypath, this.sync); return this.model = this.observer.target; } }; Binding.prototype.parseFormatterArguments = function(args, formatterIndex) { var ai, arg, observer, processedArgs, _base, _i, _len; args = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = args.length; _i < _len; _i++) { arg = args[_i]; _results.push(Rivets.TypeParser.parse(arg)); } return _results; })(); processedArgs = []; for (ai = _i = 0, _len = args.length; _i < _len; ai = ++_i) { arg = args[ai]; processedArgs.push(arg.type === Rivets.TypeParser.types.primitive ? arg.value : ((_base = this.formatterObservers)[formatterIndex] || (_base[formatterIndex] = {}), !(observer = this.formatterObservers[formatterIndex][ai]) ? (observer = this.observe(this.view.models, arg.value, this.sync), this.formatterObservers[formatterIndex][ai] = observer) : void 0, observer.value())); } return processedArgs; }; Binding.prototype.formattedValue = function(value) { var args, fi, formatter, id, processedArgs, _i, _len, _ref1, _ref2; _ref1 = this.formatters; for (fi = _i = 0, _len = _ref1.length; _i < _len; fi = ++_i) { formatter = _ref1[fi]; args = formatter.match(/[^\s']+|'([^']|'[^\s])*'|"([^"]|"[^\s])*"/g); id = args.shift(); formatter = this.view.formatters[id]; processedArgs = this.parseFormatterArguments(args, fi); if ((formatter != null ? formatter.read : void 0) instanceof Function) { value = (_ref2 = formatter.read).call.apply(_ref2, [this.model, value].concat(__slice.call(processedArgs))); } else if (formatter instanceof Function) { value = formatter.call.apply(formatter, [this.model, value].concat(__slice.call(processedArgs))); } } return value; }; Binding.prototype.eventHandler = function(fn) { var binding, handler; handler = (binding = this).view.handler; return function(ev) { return handler.call(fn, this, ev, binding); }; }; Binding.prototype.set = function(value) { var _ref1; value = value instanceof Function && !this.binder["function"] && Rivets["public"].executeFunctions ? this.formattedValue(value.call(this.model)) : this.formattedValue(value); return (_ref1 = this.binder.routine) != null ? _ref1.call(this, this.el, value) : void 0; }; Binding.prototype.sync = function() { var dependency, observer; return this.set((function() { var _i, _j, _len, _len1, _ref1, _ref2, _ref3; if (this.observer) { if (this.model !== this.observer.target) { _ref1 = this.dependencies; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { observer = _ref1[_i]; observer.unobserve(); } this.dependencies = []; if (((this.model = this.observer.target) != null) && ((_ref2 = this.options.dependencies) != null ? _ref2.length : void 0)) { _ref3 = this.options.dependencies; for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) { dependency = _ref3[_j]; observer = this.observe(this.model, dependency, this.sync); this.dependencies.push(observer); } } } return this.observer.value(); } else { return this.value; } }).call(this)); }; Binding.prototype.publish = function() { var args, fi, fiReversed, formatter, id, lastformatterIndex, processedArgs, value, _i, _len, _ref1, _ref2, _ref3; if (this.observer) { value = this.getValue(this.el); lastformatterIndex = this.formatters.length - 1; _ref1 = this.formatters.slice(0).reverse(); for (fiReversed = _i = 0, _len = _ref1.length; _i < _len; fiReversed = ++_i) { formatter = _ref1[fiReversed]; fi = lastformatterIndex - fiReversed; args = formatter.split(/\s+/); id = args.shift(); processedArgs = this.parseFormatterArguments(args, fi); if ((_ref2 = this.view.formatters[id]) != null ? _ref2.publish : void 0) { value = (_ref3 = this.view.formatters[id]).publish.apply(_ref3, [value].concat(__slice.call(processedArgs))); } } return this.observer.setValue(value); } }; Binding.prototype.bind = function() { var dependency, observer, _i, _len, _ref1, _ref2, _ref3; this.parseTarget(); if ((_ref1 = this.binder.bind) != null) { _ref1.call(this, this.el); } if ((this.model != null) && ((_ref2 = this.options.dependencies) != null ? _ref2.length : void 0)) { _ref3 = this.options.dependencies; for (_i = 0, _len = _ref3.length; _i < _len; _i++) { dependency = _ref3[_i]; observer = this.observe(this.model, dependency, this.sync); this.dependencies.push(observer); } } if (this.view.preloadData) { return this.sync(); } }; Binding.prototype.unbind = function() { var ai, args, fi, observer, _i, _len, _ref1, _ref2, _ref3, _ref4; if ((_ref1 = this.binder.unbind) != null) { _ref1.call(this, this.el); } if ((_ref2 = this.observer) != null) { _ref2.unobserve(); } _ref3 = this.dependencies; for (_i = 0, _len = _ref3.length; _i < _len; _i++) { observer = _ref3[_i]; observer.unobserve(); } this.dependencies = []; _ref4 = this.formatterObservers; for (fi in _ref4) { args = _ref4[fi]; for (ai in args) { observer = args[ai]; observer.unobserve(); } } return this.formatterObservers = {}; }; Binding.prototype.update = function(models) { var _ref1, _ref2; if (models == null) { models = {}; } this.model = (_ref1 = this.observer) != null ? _ref1.target : void 0; return (_ref2 = this.binder.update) != null ? _ref2.call(this, models) : void 0; }; Binding.prototype.getValue = function(el) { if (this.binder && (this.binder.getValue != null)) { return this.binder.getValue.call(this, el); } else { return Rivets.Util.getInputValue(el); } }; return Binding; })(); Rivets.ComponentBinding = (function(_super) { __extends(ComponentBinding, _super); function ComponentBinding(view, el, type) { var attribute, bindingRegExp, propertyName, token, _i, _len, _ref1, _ref2; this.view = view; this.el = el; this.type = type; this.unbind = __bind(this.unbind, this); this.bind = __bind(this.bind, this); this.locals = __bind(this.locals, this); this.component = this.view.components[this.type]; this["static"] = {}; this.observers = {}; this.upstreamObservers = {}; bindingRegExp = view.bindingRegExp(); _ref1 = this.el.attributes || []; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { attribute = _ref1[_i]; if (!bindingRegExp.test(attribute.name)) { propertyName = this.camelCase(attribute.name); token = Rivets.TypeParser.parse(attribute.value); if (__indexOf.call((_ref2 = this.component["static"]) != null ? _ref2 : [], propertyName) >= 0) { this["static"][propertyName] = attribute.value; } else if (token.type === Rivets.TypeParser.types.primitive) { this["static"][propertyName] = token.value; } else { this.observers[propertyName] = attribute.value; } } } } ComponentBinding.prototype.sync = function() {}; ComponentBinding.prototype.update = function() {}; ComponentBinding.prototype.publish = function() {}; ComponentBinding.prototype.locals = function() { var key, observer, result, value, _ref1, _ref2; result = {}; _ref1 = this["static"]; for (key in _ref1) { value = _ref1[key]; result[key] = value; } _ref2 = this.observers; for (key in _ref2) { observer = _ref2[key]; result[key] = observer.value(); } return result; }; ComponentBinding.prototype.camelCase = function(string) { return string.replace(/-([a-z])/g, function(grouped) { return grouped[1].toUpperCase(); }); }; ComponentBinding.prototype.bind = function() { var k, key, keypath, observer, option, options, scope, v, _base, _i, _j, _len, _len1, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; if (!this.bound) { _ref1 = this.observers; for (key in _ref1) { keypath = _ref1[key]; this.observers[key] = this.observe(this.view.models, keypath, ((function(_this) { return function(key) { return function() { return _this.componentView.models[key] = _this.observers[key].value(); }; }; })(this)).call(this, key)); } this.bound = true; } if (this.componentView != null) { this.componentView.bind(); } else { this.el.innerHTML = this.component.template.call(this); scope = this.component.initialize.call(this, this.el, this.locals()); this.el._bound = true; options = {}; _ref2 = Rivets.extensions; for (_i = 0, _len = _ref2.length; _i < _len; _i++) { option = _ref2[_i]; options[option] = {}; if (this.component[option]) { _ref3 = this.component[option]; for (k in _ref3) { v = _ref3[k]; options[option][k] = v; } } _ref4 = this.view[option]; for (k in _ref4) { v = _ref4[k]; if ((_base = options[option])[k] == null) { _base[k] = v; } } } _ref5 = Rivets.options; for (_j = 0, _len1 = _ref5.length; _j < _len1; _j++) { option = _ref5[_j]; options[option] = (_ref6 = this.component[option]) != null ? _ref6 : this.view[option]; } this.componentView = new Rivets.View(Array.prototype.slice.call(this.el.childNodes), scope, options); this.componentView.bind(); _ref7 = this.observers; for (key in _ref7) { observer = _ref7[key]; this.upstreamObservers[key] = this.observe(this.componentView.models, key, ((function(_this) { return function(key, observer) { return function() { return observer.setValue(_this.componentView.models[key]); }; }; })(this)).call(this, key, observer)); } } }; ComponentBinding.prototype.unbind = function() { var key, observer, _ref1, _ref2, _ref3; _ref1 = this.upstreamObservers; for (key in _ref1) { observer = _ref1[key]; observer.unobserve(); } _ref2 = this.observers; for (key in _ref2) { observer = _ref2[key]; observer.unobserve(); } return (_ref3 = this.componentView) != null ? _ref3.unbind.call(this) : void 0; }; return ComponentBinding; })(Rivets.Binding); Rivets.TextBinding = (function(_super) { __extends(TextBinding, _super); function TextBinding(view, el, type, keypath, options) { this.view = view; this.el = el; this.type = type; this.keypath = keypath; this.options = options != null ? options : {}; this.sync = __bind(this.sync, this); this.formatters = this.options.formatters || []; this.dependencies = []; this.formatterObservers = {}; } TextBinding.prototype.binder = { routine: function(node, value) { return node.data = value != null ? value : ''; } }; TextBinding.prototype.sync = function() { return TextBinding.__super__.sync.apply(this, arguments); }; return TextBinding; })(Rivets.Binding); Rivets["public"].binders.text = function(el, value) { if (el.textContent != null) { return el.textContent = value != null ? value : ''; } else { return el.innerText = value != null ? value : ''; } }; Rivets["public"].binders.html = function(el, value) { return el.innerHTML = value != null ? value : ''; }; Rivets["public"].binders.show = function(el, value) { return el.style.display = value ? '' : 'none'; }; Rivets["public"].binders.hide = function(el, value) { return el.style.display = value ? 'none' : ''; }; Rivets["public"].binders.enabled = function(el, value) { return el.disabled = !value; }; Rivets["public"].binders.disabled = function(el, value) { return el.disabled = !!value; }; Rivets["public"].binders.checked = { publishes: true, priority: 2000, bind: function(el) { return Rivets.Util.bindEvent(el, 'change', this.publish); }, unbind: function(el) { return Rivets.Util.unbindEvent(el, 'change', this.publish); }, routine: function(el, value) { var _ref1; if (el.type === 'radio') { return el.checked = ((_ref1 = el.value) != null ? _ref1.toString() : void 0) === (value != null ? value.toString() : void 0); } else { return el.checked = !!value; } } }; Rivets["public"].binders.unchecked = { publishes: true, priority: 2000, bind: function(el) { return Rivets.Util.bindEvent(el, 'change', this.publish); }, unbind: function(el) { return Rivets.Util.unbindEvent(el, 'change', this.publish); }, routine: function(el, value) { var _ref1; if (el.type === 'radio') { return el.checked = ((_ref1 = el.value) != null ? _ref1.toString() : void 0) !== (value != null ? value.toString() : void 0); } else { return el.checked = !value; } } }; Rivets["public"].binders.value = { publishes: true, priority: 3000, bind: function(el) { if (!(el.tagName === 'INPUT' && el.type === 'radio')) { this.event = el.tagName === 'SELECT' ? 'change' : 'input'; return Rivets.Util.bindEvent(el, this.event, this.publish); } }, unbind: function(el) { if (!(el.tagName === 'INPUT' && el.type === 'radio')) { return Rivets.Util.unbindEvent(el, this.event, this.publish); } }, routine: function(el, value) { var o, _i, _len, _ref1, _ref2, _ref3, _results; if (el.tagName === 'INPUT' && el.type === 'radio') { return el.setAttribute('value', value); } else if (window.jQuery != null) { el = jQuery(el); if ((value != null ? value.toString() : void 0) !== ((_ref1 = el.val()) != null ? _ref1.toString() : void 0)) { return el.val(value != null ? value : ''); } } else { if (el.type === 'select-multiple') { if (value != null) { _results = []; for (_i = 0, _len = el.length; _i < _len; _i++) { o = el[_i]; _results.push(o.selected = (_ref2 = o.value, __indexOf.call(value, _ref2) >= 0)); } return _results; } } else if ((value != null ? value.toString() : void 0) !== ((_ref3 = el.value) != null ? _ref3.toString() : void 0)) { return el.value = value != null ? value : ''; } } } }; Rivets["public"].binders["if"] = { block: true, priority: 4000, bind: function(el) { var attr, declaration; if (this.marker == null) { attr = [this.view.prefix, this.type].join('-').replace('--', '-'); declaration = el.getAttribute(attr); this.marker = document.createComment(" rivets: " + this.type + " " + declaration + " "); this.bound = false; el.removeAttribute(attr); el.parentNode.insertBefore(this.marker, el); return el.parentNode.removeChild(el); } }, unbind: function() { if (this.nested) { this.nested.unbind(); return this.bound = false; } }, routine: function(el, value) { var key, model, models, _ref1; if (!!value === !this.bound) { if (value) { models = {}; _ref1 = this.view.models; for (key in _ref1) { model = _ref1[key]; models[key] = model; } (this.nested || (this.nested = new Rivets.View(el, models, this.view.options()))).bind(); this.marker.parentNode.insertBefore(el, this.marker.nextSibling); return this.bound = true; } else { el.parentNode.removeChild(el); this.nested.unbind(); return this.bound = false; } } }, update: function(models) { var _ref1; return (_ref1 = this.nested) != null ? _ref1.update(models) : void 0; } }; Rivets["public"].binders.unless = { block: true, priority: 4000, bind: function(el) { return Rivets["public"].binders["if"].bind.call(this, el); }, unbind: function() { return Rivets["public"].binders["if"].unbind.call(this); }, routine: function(el, value) { return Rivets["public"].binders["if"].routine.call(this, el, !value); }, update: function(models) { return Rivets["public"].binders["if"].update.call(this, models); } }; Rivets["public"].binders['on-*'] = { "function": true, priority: 1000, unbind: function(el) { if (this.handler) { return Rivets.Util.unbindEvent(el, this.args[0], this.handler); } }, routine: function(el, value) { if (this.handler) { Rivets.Util.unbindEvent(el, this.args[0], this.handler); } return Rivets.Util.bindEvent(el, this.args[0], this.handler = this.eventHandler(value)); } }; Rivets["public"].binders['each-*'] = { block: true, priority: 4000, bind: function(el) { var attr, view, _i, _len, _ref1; if (this.marker == null) { attr = [this.view.prefix, this.type].join('-').replace('--', '-'); this.marker = document.createComment(" rivets: " + this.type + " "); this.iterated = []; el.removeAttribute(attr); el.parentNode.insertBefore(this.marker, el); el.parentNode.removeChild(el); } else { _ref1 = this.iterated; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { view = _ref1[_i]; view.bind(); } } }, unbind: function(el) { var view, _i, _len, _ref1; if (this.iterated != null) { _ref1 = this.iterated; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { view = _ref1[_i]; view.unbind(); } } }, routine: function(el, collection) { var binding, data, i, index, key, model, modelName, options, previous, template, view, _i, _j, _k, _len, _len1, _len2, _ref1, _ref2, _ref3; modelName = this.args[0]; collection = collection || []; if (this.iterated.length > collection.length) { _ref1 = Array(this.iterated.length - collection.length); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { i = _ref1[_i]; view = this.iterated.pop(); view.unbind(); this.marker.parentNode.removeChild(view.els[0]); } } for (index = _j = 0, _len1 = collection.length; _j < _len1; index = ++_j) { model = collection[index]; data = { index: index }; data[Rivets["public"].iterationAlias(modelName)] = index; data[modelName] = model; if (this.iterated[index] == null) { _ref2 = this.view.models; for (key in _ref2) { model = _ref2[key]; if (data[key] == null) { data[key] = model; } } previous = this.iterated.length ? this.iterated[this.iterated.length - 1].els[0] : this.marker; options = this.view.options(); options.preloadData = true; template = el.cloneNode(true); view = new Rivets.View(template, data, options); view.bind(); this.iterated.push(view); this.marker.parentNode.insertBefore(template, previous.nextSibling); } else if (this.iterated[index].models[modelName] !== model) { this.iterated[index].update(data); } } if (el.nodeName === 'OPTION') { _ref3 = this.view.bindings; for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { binding = _ref3[_k]; if (binding.el === this.marker.parentNode && binding.type === 'value') { binding.sync(); } } } }, update: function(models) { var data, key, model, view, _i, _len, _ref1; data = {}; for (key in models) { model = models[key]; if (key !== this.args[0]) { data[key] = model; } } _ref1 = this.iterated; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { view = _ref1[_i]; view.update(data); } } }; Rivets["public"].binders['class-*'] = function(el, value) { var elClass; elClass = " " + el.className + " "; if (!value === (elClass.indexOf(" " + this.args[0] + " ") !== -1)) { return el.className = value ? "" + el.className + " " + this.args[0] : elClass.replace(" " + this.args[0] + " ", ' ').trim(); } }; Rivets["public"].binders['*'] = function(el, value) { if (value != null) { return el.setAttribute(this.type, value); } else { return el.removeAttribute(this.type); } }; Rivets["public"].formatters['call'] = function() { var args, value; value = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return value.call.apply(value, [this].concat(__slice.call(args))); }; Rivets["public"].adapters['.'] = { id: '_rv', counter: 0, weakmap: {}, weakReference: function(obj) { var id, _base, _name; if (!obj.hasOwnProperty(this.id)) { id = this.counter++; Object.defineProperty(obj, this.id, { value: id }); } return (_base = this.weakmap)[_name = obj[this.id]] || (_base[_name] = { callbacks: {} }); }, cleanupWeakReference: function(ref, id) { if (!Object.keys(ref.callbacks).length) { if (!(ref.pointers && Object.keys(ref.pointers).length)) { return delete this.weakmap[id]; } } }, stubFunction: function(obj, fn) { var map, original, weakmap; original = obj[fn]; map = this.weakReference(obj); weakmap = this.weakmap; return obj[fn] = function() { var callback, k, r, response, _i, _len, _ref1, _ref2, _ref3, _ref4; response = original.apply(obj, arguments); _ref1 = map.pointers; for (r in _ref1) { k = _ref1[r]; _ref4 = (_ref2 = (_ref3 = weakmap[r]) != null ? _ref3.callbacks[k] : void 0) != null ? _ref2 : []; for (_i = 0, _len = _ref4.length; _i < _len; _i++) { callback = _ref4[_i]; callback(); } } return response; }; }, observeMutations: function(obj, ref, keypath) { var fn, functions, map, _base, _i, _len; if (Array.isArray(obj)) { map = this.weakReference(obj); if (map.pointers == null) { map.pointers = {}; functions = ['push', 'pop', 'shift', 'unshift', 'sort', 'reverse', 'splice']; for (_i = 0, _len = functions.length; _i < _len; _i++) { fn = functions[_i]; this.stubFunction(obj, fn); } } if ((_base = map.pointers)[ref] == null) { _base[ref] = []; } if (__indexOf.call(map.pointers[ref], keypath) < 0) { return map.pointers[ref].push(keypath); } } }, unobserveMutations: function(obj, ref, keypath) { var idx, map, pointers; if (Array.isArray(obj) && (obj[this.id] != null)) { if (map = this.weakmap[obj[this.id]]) { if (pointers = map.pointers[ref]) { if ((idx = pointers.indexOf(keypath)) >= 0) { pointers.splice(idx, 1); } if (!pointers.length) { delete map.pointers[ref]; } return this.cleanupWeakReference(map, obj[this.id]); } } } }, observe: function(obj, keypath, callback) { var callbacks, desc, value; callbacks = this.weakReference(obj).callbacks; if (callbacks[keypath] == null) { callbacks[keypath] = []; desc = Object.getOwnPropertyDescriptor(obj, keypath); if (!((desc != null ? desc.get : void 0) || (desc != null ? desc.set : void 0))) { value = obj[keypath]; Object.defineProperty(obj, keypath, { enumerable: true, get: function() { return value; }, set: (function(_this) { return function(newValue) { var cb, map, _i, _len, _ref1; if (newValue !== value) { _this.unobserveMutations(value, obj[_this.id], keypath); value = newValue; if (map = _this.weakmap[obj[_this.id]]) { callbacks = map.callbacks; if (callbacks[keypath]) { _ref1 = callbacks[keypath].slice(); for (_i = 0, _len = _ref1.length; _i < _len; _i++) { cb = _ref1[_i]; if (__indexOf.call(callbacks[keypath], cb) >= 0) { cb(); } } } return _this.observeMutations(newValue, obj[_this.id], keypath); } } }; })(this) }); } } if (__indexOf.call(callbacks[keypath], callback) < 0) { callbacks[keypath].push(callback); } return this.observeMutations(obj[keypath], obj[this.id], keypath); }, unobserve: function(obj, keypath, callback) { var callbacks, idx, map; if (map = this.weakmap[obj[this.id]]) { if (callbacks = map.callbacks[keypath]) { if ((idx = callbacks.indexOf(callback)) >= 0) { callbacks.splice(idx, 1); if (!callbacks.length) { delete map.callbacks[keypath]; this.unobserveMutations(obj[keypath], obj[this.id], keypath); } } return this.cleanupWeakReference(map, obj[this.id]); } } }, get: function(obj, keypath) { return obj[keypath]; }, set: function(obj, keypath, value) { return obj[keypath] = value; } }; Rivets.factory = function(sightglass) { Rivets.sightglass = sightglass; Rivets["public"]._ = Rivets; return Rivets["public"]; }; if (typeof (typeof module !== "undefined" && module !== null ? module.exports : void 0) === 'object') { module.exports = Rivets.factory(require('sightglass')); } else if (typeof define === 'function' && define.amd) { define(['sightglass'], function(sightglass) { return this.rivets = Rivets.factory(sightglass); }); } else { this.rivets = Rivets.factory(sightglass); } }).call(this);