diff --git a/index.html b/index.html
index 399677d..aeda74c 100644
--- a/index.html
+++ b/index.html
@@ -20,6 +20,7 @@
+
@@ -263,25 +264,25 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel
-
+
-
-
- {{ bufferline.date | date:'HH' }}:{{ bufferline.date | date:'mm' }}
+ |
+
+ :{{ bufferline.date | date:'mm' }}
|
- {{ part.text }} |
+ |
-
+
-
-
-
-
+
+
+
+
-
-
+
+
|
diff --git a/js/bindonce.js b/js/bindonce.js
new file mode 100644
index 0000000..2408909
--- /dev/null
+++ b/js/bindonce.js
@@ -0,0 +1,269 @@
+'use strict';
+/**
+ * Bindonce - Zero watches binding for AngularJs
+ * @version v0.2.2 - 2013-05-07
+ * @link https://github.com/Pasvaz/bindonce
+ * @author Pasquale Vazzana
+ * @license MIT License, http://www.opensource.org/licenses/MIT
+ */
+
+ angular.module('pasvaz.bindonce', [])
+
+ .directive('bindonce', function()
+ {
+ var toBoolean = function(value)
+ {
+ if (value && value.length !== 0)
+ {
+ var v = angular.lowercase("" + value);
+ value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
+ }
+ else
+ {
+ value = false;
+ }
+ return value;
+ }
+
+ var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
+ if (isNaN(msie))
+ {
+ msie = parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
+ }
+
+ var bindonceDirective =
+ {
+ restrict: "AM",
+ controller: ['$scope', '$element', '$attrs', '$interpolate', function($scope, $element, $attrs, $interpolate)
+ {
+ var showHideBinder = function(elm, attr, value)
+ {
+ var show = (attr == 'show') ? '' : 'none';
+ var hide = (attr == 'hide') ? '' : 'none';
+ elm.css('display', toBoolean(value) ? show : hide);
+ }
+ var classBinder = function(elm, value)
+ {
+ if (angular.isObject(value) && !angular.isArray(value))
+ {
+ var results = [];
+ angular.forEach(value, function(value, index)
+ {
+ if (value) results.push(index);
+ });
+ value = results;
+ }
+ if (value)
+ {
+ elm.addClass(angular.isArray(value) ? value.join(' ') : value);
+ }
+ }
+
+ var ctrl =
+ {
+ watcherRemover : undefined,
+ binders : [],
+ group : $attrs.boName,
+ element : $element,
+ ran : false,
+
+ addBinder : function(binder)
+ {
+ this.binders.push(binder);
+
+ // In case of late binding (when using the directive bo-name/bo-parent)
+ // it happens only when you use nested bindonce, if the bo-children
+ // are not dom children the linking can follow another order
+ if (this.ran)
+ {
+ this.runBinders();
+ }
+ },
+
+ setupWatcher : function(bindonceValue)
+ {
+ var that = this;
+ this.watcherRemover = $scope.$watch(bindonceValue, function(newValue)
+ {
+ if (newValue == undefined) return;
+ that.removeWatcher();
+ that.runBinders();
+ }, true);
+ },
+
+ removeWatcher : function()
+ {
+ if (this.watcherRemover != undefined)
+ {
+ this.watcherRemover();
+ this.watcherRemover = undefined;
+ }
+ },
+
+ runBinders : function()
+ {
+ var i, max;
+ for (i = 0, max = this.binders.length; i < max; i ++)
+ {
+ var binder = this.binders[i];
+ if (this.group && this.group != binder.group ) continue;
+ var value = binder.scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value);
+ switch(binder.attr)
+ {
+ case 'if':
+ if (toBoolean(value))
+ {
+ binder.transclude(binder.scope.$new(), function (clone)
+ {
+ var parent = binder.element.parent();
+ var afterNode = binder.element && binder.element[binder.element.length - 1];
+ var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
+ var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
+ angular.forEach(clone, function(node)
+ {
+ parentNode.insertBefore(node, afterNextSibling);
+ });
+ });
+ }
+ break;
+ case 'hide':
+ case 'show':
+ showHideBinder(binder.element, binder.attr, value);
+ break;
+ case 'class':
+ classBinder(binder.element, value);
+ break;
+ case 'text':
+ binder.element.text(value);
+ break;
+ case 'html':
+ binder.element.html(value);
+ break;
+ case 'style':
+ binder.element.css(value);
+ break;
+ case 'src':
+ binder.element.attr(binder.attr, value);
+ if (msie) binder.element.prop('src', value);
+ case 'attr':
+ angular.forEach(binder.attrs, function(attrValue, attrKey)
+ {
+ var newAttr, newValue;
+ if (attrKey.match(/^boAttr./) && binder.attrs[attrKey])
+ {
+ newAttr = attrKey.replace(/^boAttr/, '').replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
+ newValue = binder.scope.$eval(binder.attrs[attrKey]);
+ binder.element.attr(newAttr, newValue);
+ }
+ });
+ break;
+ case 'href':
+ case 'alt':
+ case 'title':
+ case 'id':
+ case 'value':
+ binder.element.attr(binder.attr, value);
+ break;
+ }
+ }
+ this.ran = true;
+ this.binders = [];
+ }
+ }
+
+ return ctrl;
+ }],
+
+ link: function(scope, elm, attrs, bindonceController)
+ {
+ var value = (attrs.bindonce) ? scope.$eval(attrs.bindonce) : true;
+ if (value != undefined)
+ {
+ bindonceController.runBinders();
+ }
+ else
+ {
+ bindonceController.setupWatcher(attrs.bindonce);
+ elm.bind("$destroy", bindonceController.removeWatcher);
+ }
+ }
+ };
+
+ return bindonceDirective;
+});
+
+angular.forEach(
+[
+ {directiveName:'boShow', attribute: 'show'},
+ {directiveName:'boIf', attribute: 'if', transclude: 'element', terminal: true, priority:1000},
+ {directiveName:'boHide', attribute:'hide'},
+ {directiveName:'boClass', attribute:'class'},
+ {directiveName:'boText', attribute:'text'},
+ {directiveName:'boHtml', attribute:'html'},
+ {directiveName:'boSrcI', attribute:'src', interpolate:true},
+ {directiveName:'boSrc', attribute:'src'},
+ {directiveName:'boHrefI', attribute:'href', interpolate:true},
+ {directiveName:'boHref', attribute:'href'},
+ {directiveName:'boAlt', attribute:'alt'},
+ {directiveName:'boTitle', attribute:'title'},
+ {directiveName:'boId', attribute:'id'},
+ {directiveName:'boStyle', attribute:'style'},
+ {directiveName:'boValue', attribute:'value'},
+ {directiveName:'boAttr', attribute:'attr'}
+],
+function(boDirective)
+{
+ var childPriority = 200;
+ return angular.module('pasvaz.bindonce').directive(boDirective.directiveName, function()
+ {
+ var bindonceDirective =
+ {
+ priority: boDirective.priority || childPriority,
+ transclude: boDirective.transclude || false,
+ terminal: boDirective.terminal || false,
+ require: '^bindonce',
+ compile: function (tElement, tAttrs, transclude)
+ {
+ return function(scope, elm, attrs, bindonceController)
+ {
+ var name = attrs.boParent;
+ if (name && bindonceController.group != name)
+ {
+ var element = bindonceController.element.parent();
+ bindonceController = undefined;
+ var parentValue;
+
+ while (element[0].nodeType != 9 && element.length)
+ {
+ if ((parentValue = element.data('$bindonceController'))
+ && parentValue.group == name)
+ {
+ bindonceController = parentValue
+ break;
+ }
+ element = element.parent();
+ }
+ if (!bindonceController)
+ {
+ throw Error("No bindonce controller: " + name);
+ }
+ }
+
+ bindonceController.addBinder(
+ {
+ element : elm,
+ attr : boDirective.attribute,
+ attrs : attrs,
+ value : attrs[boDirective.directiveName],
+ interpolate : boDirective.interpolate,
+ group : name,
+ transclude : transclude,
+ scope : scope
+ });
+ }
+ }
+ }
+
+ return bindonceDirective;
+ });
+});
diff --git a/js/websockets.js b/js/websockets.js
index 7c0c625..e14309e 100644
--- a/js/websockets.js
+++ b/js/websockets.js
@@ -1,4 +1,4 @@
-var weechat = angular.module('weechat', ['ngRoute', 'localStorage', 'weechatModels', 'plugins', 'ngSanitize']);
+var weechat = angular.module('weechat', ['ngRoute', 'localStorage', 'weechatModels', 'plugins', 'ngSanitize', 'pasvaz.bindonce']);
weechat.filter('toArray', function () {
'use strict';