From 57b196eb033298c4ba1c2fa1e05e998ce33e87e5 Mon Sep 17 00:00:00 2001 From: Pasvaz Date: Tue, 3 Sep 2013 00:39:41 +0200 Subject: [PATCH] Fix issue #14 Fix issue #13 Fix issue #6 Fix indentations. --- bindonce.js | 267 +++++++++++++++++++++++++++++----------------------- 1 file changed, 151 insertions(+), 116 deletions(-) diff --git a/bindonce.js b/bindonce.js index 7708548..2e8b9fb 100644 --- a/bindonce.js +++ b/bindonce.js @@ -9,123 +9,145 @@ 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; - } - - return { - restrict: "AM", - controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { - 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() - { - for (var data in this.binders) - { - var binder = this.binders[data]; - if (this.group && this.group != binder.group ) continue; - var value = $scope.$eval(binder.value); + .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() + { + for (var data in this.binders) + { + var binder = this.binders[data]; + if (this.group && this.group != binder.group ) continue; + var value = $scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value); switch(binder.attr) { case 'hide': case 'show': - showHideBinder(binder.element, binder.attr, value); - break; + showHideBinder(binder.element, binder.attr, value); + break; case 'class': - classBinder(binder.element, value); - break; + classBinder(binder.element, value); + break; case 'text': - binder.element.text(value); - break; + binder.element.text(value); + break; case 'html': - binder.element.html(value); - break; + binder.element.html(value); + break; + case 'style': + binder.element.css(value); + break; case 'src': + binder.element.attr(binder.attr, value); + // attr.$set(attrName, value); + if (msie) binder.element.prop('src', value); case 'href': case 'alt': case 'title': case 'id': - case 'style': case 'value': - binder.element.attr(binder.attr, value); - break; + binder.element.attr(binder.attr, value); + break; } } - this.ran = true; - this.binders = []; + this.ran = true; + this.binders = []; } } return ctrl; }], - link: function(scope, elm, attrs, bindonceController) { + link: function(scope, elm, attrs, bindonceController) + { var value = (attrs.bindonce) ? scope.$eval(attrs.bindonce) : true; if (value != undefined) { @@ -138,28 +160,32 @@ } } }; + + return bindonceDirective; }); -angular.forEach({ - 'boShow' : 'show', - 'boHide' : 'hide', - 'boClass' : 'class', - 'boText' : 'text', - 'boHtml' : 'html', - 'boSrc' : 'src', - 'boHref' : 'href', - 'boAlt' : 'alt', - 'boTitle' : 'title', - 'boId' : 'id', - 'boStyle' : 'style', - 'boValue' : 'value' -}, -function(tag, attribute) +angular.forEach( +[ + {directiveName:'boShow', attribute: 'show'}, + {directiveName:'boHide', attribute:'hide'}, + {directiveName:'boClass', attribute:'class'}, + {directiveName:'boText', attribute:'text'}, + {directiveName:'boHtml', attribute:'html'}, + {directiveName:'boSrc', attribute:'src', 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'} +], +function(boDirective) { var childPriority = 200; - return angular.module('pasvaz.bindonce').directive(attribute, function() + return angular.module('pasvaz.bindonce').directive(boDirective.directiveName, function() { - return { + var bindonceDirective = + { priority: childPriority, require: '^bindonce', link: function(scope, elm, attrs, bindonceController) @@ -186,9 +212,18 @@ function(tag, attribute) throw Error("No bindonce controller: " + name); } } - bindonceController.addBinder({element: elm, attr:tag, value: attrs[attribute], group: name}); + + bindonceController.addBinder( + { + element : elm, + attr : boDirective.attribute, + value : attrs[boDirective.directiveName], + interpolate : boDirective.interpolate, + group : name + }); } } - }); -}); + return bindonceDirective; + }); +}); \ No newline at end of file