From 7a4f302f9848b51d799d1fc6d0bb905a3998b82c Mon Sep 17 00:00:00 2001 From: Piotr Majewski Date: Thu, 2 Mar 2017 10:07:49 +0100 Subject: [PATCH] feat: support tbody, tfoot, and tr elements --- angular-busy.html | 5 ---- angular-busy.js | 53 +++++++++++++++++++++++++++--------- dist/angular-busy.js | 58 +++++++++++++++++++++++++++------------- dist/angular-busy.min.js | 2 +- 4 files changed, 81 insertions(+), 37 deletions(-) diff --git a/angular-busy.html b/angular-busy.html index f3f0756..b0e5c42 100755 --- a/angular-busy.html +++ b/angular-busy.html @@ -1,7 +1,5 @@
-
-
@@ -16,9 +14,6 @@
-
{{$message}}
-
-
\ No newline at end of file diff --git a/angular-busy.js b/angular-busy.js index ac35e41..4d2ddd7 100755 --- a/angular-busy.js +++ b/angular-busy.js @@ -118,16 +118,30 @@ angular.module('cgBusy').factory('_cgBusyTrackerFactory',['$timeout','$q',functi angular.module('cgBusy').value('cgBusyDefaults',{}); -angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory', - function($compile,$templateCache,cgBusyDefaults,$http,_cgBusyTrackerFactory){ +angular.module('cgBusy').directive('cgBusy',['$compile', '$document', '$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory', + function ($compile, $document, $templateCache, cgBusyDefaults, $http, _cgBusyTrackerFactory) { + var tableContainers = ['TBODY', 'THEAD', 'TFOOT', 'TR']; + var body = angular.element($document[0].body); return { restrict: 'A', link: function(scope, element, attrs, fn) { - + //Elements like tbody , thead, tfooter, tr don't allow other - non table elements + var isTableContainer = tableContainers.indexOf(element[0].nodeName) !== -1; //Apply position:relative to parent element if necessary - var position = element.css('position'); - if (position === 'static' || position === '' || typeof position === 'undefined'){ - element.css('position','relative'); + if (!isTableContainer) { + var position = element.css('position'); + if (position === 'static' || position === '' || typeof position === 'undefined'){ + element.css('position','relative'); + } + } else { + scope.$on('$destroy', function() { + if (templateElement) { + templateElement.remove(); + } + if (backdropElement) { + backdropElement.remove(); + } + }); } var templateElement; @@ -136,6 +150,13 @@ angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusy var templateScope; var backdrop; var tracker = _cgBusyTrackerFactory(); + var container = isTableContainer ? body : element; + var loaderPosition = { + top:0, + left:0, + right:0, + bottom:0 + } var defaults = { templateUrl: 'angular-busy.html', @@ -217,19 +238,25 @@ angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusy if (options.backdrop){ var backdrop = '
'; backdropElement = $compile(backdrop)(templateScope); - element.append(backdropElement); + container.append(backdropElement); } var template = '
' + indicatorTemplate.data + '
'; templateElement = $compile(template)(templateScope); + if (isTableContainer) { + var rect = element[0].getClientRects()[0]; + loaderPosition = { + top: rect.top + 'px', + left: rect.left +'px', + height: rect.bottom - rect.top + 'px', + width: rect.right - rect.left + 'px' + } + } angular.element(templateElement.children()[0]) - .css('position','absolute') - .css('top',0) - .css('left',0) - .css('right',0) - .css('bottom',0); - element.append(templateElement); + .css('position','absolute') + .css(loaderPosition); + container.append(templateElement) }, function(data){ throw new Error('Template specified for cgBusy ('+options.templateUrl+') could not be loaded. ' + data); diff --git a/dist/angular-busy.js b/dist/angular-busy.js index c696ebd..bdef9cf 100644 --- a/dist/angular-busy.js +++ b/dist/angular-busy.js @@ -118,16 +118,30 @@ angular.module('cgBusy').factory('_cgBusyTrackerFactory',['$timeout','$q',functi angular.module('cgBusy').value('cgBusyDefaults',{}); -angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory', - function($compile,$templateCache,cgBusyDefaults,$http,_cgBusyTrackerFactory){ +angular.module('cgBusy').directive('cgBusy',['$compile', '$document', '$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory', + function ($compile, $document, $templateCache, cgBusyDefaults, $http, _cgBusyTrackerFactory) { + var tableContainers = ['TBODY', 'THEAD', 'TFOOT', 'TR']; + var body = angular.element($document[0].body); return { restrict: 'A', link: function(scope, element, attrs, fn) { - + //Elements like tbody , thead, tfooter, tr don't allow other - non table elements + var isTableContainer = tableContainers.indexOf(element[0].nodeName) !== -1; //Apply position:relative to parent element if necessary - var position = element.css('position'); - if (position === 'static' || position === '' || typeof position === 'undefined'){ - element.css('position','relative'); + if (!isTableContainer) { + var position = element.css('position'); + if (position === 'static' || position === '' || typeof position === 'undefined'){ + element.css('position','relative'); + } + } else { + scope.$on('$destroy', function() { + if (templateElement) { + templateElement.remove(); + } + if (backdropElement) { + backdropElement.remove(); + } + }); } var templateElement; @@ -136,6 +150,13 @@ angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusy var templateScope; var backdrop; var tracker = _cgBusyTrackerFactory(); + var container = isTableContainer ? body : element; + var loaderPosition = { + top:0, + left:0, + right:0, + bottom:0 + } var defaults = { templateUrl: 'angular-busy.html', @@ -217,19 +238,25 @@ angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusy if (options.backdrop){ var backdrop = '
'; backdropElement = $compile(backdrop)(templateScope); - element.append(backdropElement); + container.append(backdropElement); } var template = '
' + indicatorTemplate.data + '
'; templateElement = $compile(template)(templateScope); + if (isTableContainer) { + var rect = element[0].getClientRects()[0]; + loaderPosition = { + top: rect.top + 'px', + left: rect.left +'px', + height: rect.bottom - rect.top + 'px', + width: rect.right - rect.left + 'px' + } + } angular.element(templateElement.children()[0]) - .css('position','absolute') - .css('top',0) - .css('left',0) - .css('right',0) - .css('bottom',0); - element.append(templateElement); + .css('position','absolute') + .css(loaderPosition); + container.append(templateElement) }, function(data){ throw new Error('Template specified for cgBusy ('+options.templateUrl+') could not be loaded. ' + data); @@ -248,9 +275,7 @@ angular.module('cgBusy').run(['$templateCache', function($templateCache) { $templateCache.put('angular-busy.html', "
\n" + - "\n" + "
\n" + - "\n" + "
\n" + "
\n" + "
\n" + @@ -265,11 +290,8 @@ angular.module('cgBusy').run(['$templateCache', function($templateCache) { "
\n" + "
\n" + "
\n" + - "\n" + "
{{$message}}
\n" + - "\n" + "
\n" + - "\n" + "
" ); diff --git a/dist/angular-busy.min.js b/dist/angular-busy.min.js index 4e6f58c..c691c48 100644 --- a/dist/angular-busy.min.js +++ b/dist/angular-busy.min.js @@ -1 +1 @@ -angular.module("cgBusy",[]),angular.module("cgBusy").factory("_cgBusyTrackerFactory",["$timeout","$q",function(a,b){return function(){var c={};c.promises=[],c.delayPromise=null,c.durationPromise=null,c.delayJustFinished=!1,c.reset=function(b){c.minDuration=b.minDuration,c.promises=[],angular.forEach(b.promises,function(a){a&&!a.$cgBusyFulfilled&&d(a)}),0!==c.promises.length&&(c.delayJustFinished=!1,b.delay&&(c.delayPromise=a(function(){c.delayPromise=null,c.delayJustFinished=!0},parseInt(b.delay,10))),b.minDuration&&(c.durationPromise=a(function(){c.durationPromise=null},parseInt(b.minDuration,10)+(b.delay?parseInt(b.delay,10):0))))},c.isPromise=function(a){var b=a&&(a.then||a.$then||a.$promise&&a.$promise.then);return"undefined"!=typeof b},c.callThen=function(a,c,d){var e;a.then||a.$then?e=a:a.$promise?e=a.$promise:a.denodeify&&(e=b.when(a));var f=e.then||e.$then;f.call(e,c,d)};var d=function(a){if(!c.isPromise(a))throw new Error("cgBusy expects a promise (or something that has a .promise or .$promise");-1===c.promises.indexOf(a)&&(c.promises.push(a),c.callThen(a,function(){a.$cgBusyFulfilled=!0,-1!==c.promises.indexOf(a)&&c.promises.splice(c.promises.indexOf(a),1)},function(){a.$cgBusyFulfilled=!0,-1!==c.promises.indexOf(a)&&c.promises.splice(c.promises.indexOf(a),1)}))};return c.active=function(){return c.delayPromise?!1:c.delayJustFinished?(c.delayJustFinished=!1,0===c.promises.length&&(c.durationPromise=null),c.promises.length>0):c.durationPromise?!0:c.promises.length>0},c}}]),angular.module("cgBusy").value("cgBusyDefaults",{}),angular.module("cgBusy").directive("cgBusy",["$compile","$templateCache","cgBusyDefaults","$http","_cgBusyTrackerFactory",function(a,b,c,d,e){return{restrict:"A",link:function(f,g,h){var i=g.css("position");("static"===i||""===i||"undefined"==typeof i)&&g.css("position","relative");var j,k,l,m,n,o=e(),p={templateUrl:"angular-busy.html",delay:0,minDuration:0,backdrop:!0,message:"Please Wait...",wrapperClass:"cg-busy cg-busy-animation"};angular.extend(p,c),f.$watchCollection(h.cgBusy,function(c){if(c||(c={promise:null}),angular.isString(c))throw new Error("Invalid value for cg-busy. cgBusy no longer accepts string ids to represent promises/trackers.");(angular.isArray(c)||o.isPromise(c))&&(c={promise:c}),c=angular.extend(angular.copy(p),c),c.templateUrl||(c.templateUrl=p.templateUrl),angular.isArray(c.promise)||(c.promise=[c.promise]),m||(m=f.$new()),m.$message=c.message,angular.equals(o.promises,c.promise)||o.reset({promises:c.promise,delay:c.delay,minDuration:c.minDuration}),m.$cgBusyIsActive=function(){return o.active()},j&&l===c.templateUrl&&n===c.backdrop||(j&&j.remove(),k&&k.remove(),l=c.templateUrl,n=c.backdrop,d.get(l,{cache:b}).then(function(b){if(c.backdrop="undefined"==typeof c.backdrop?!0:c.backdrop,c.backdrop){var d='
';k=a(d)(m),g.append(k)}var e='
'+b.data+"
";j=a(e)(m),angular.element(j.children()[0]).css("position","absolute").css("top",0).css("left",0).css("right",0).css("bottom",0),g.append(j)},function(a){throw new Error("Template specified for cgBusy ("+c.templateUrl+") could not be loaded. "+a)}))},!0)}}}]),angular.module("cgBusy").run(["$templateCache",function(a){"use strict";a.put("angular-busy.html",'
\n\n
\n\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n\n
{{$message}}
\n\n
\n\n
')}]); \ No newline at end of file +angular.module("cgBusy",[]),angular.module("cgBusy").factory("_cgBusyTrackerFactory",["$timeout","$q",function(a,b){return function(){var c={};c.promises=[],c.delayPromise=null,c.durationPromise=null,c.delayJustFinished=!1,c.reset=function(b){c.minDuration=b.minDuration,c.promises=[],angular.forEach(b.promises,function(a){a&&!a.$cgBusyFulfilled&&d(a)}),0!==c.promises.length&&(c.delayJustFinished=!1,b.delay&&(c.delayPromise=a(function(){c.delayPromise=null,c.delayJustFinished=!0},parseInt(b.delay,10))),b.minDuration&&(c.durationPromise=a(function(){c.durationPromise=null},parseInt(b.minDuration,10)+(b.delay?parseInt(b.delay,10):0))))},c.isPromise=function(a){var b=a&&(a.then||a.$then||a.$promise&&a.$promise.then);return"undefined"!=typeof b},c.callThen=function(a,c,d){var e;a.then||a.$then?e=a:a.$promise?e=a.$promise:a.denodeify&&(e=b.when(a));var f=e.then||e.$then;f.call(e,c,d)};var d=function(a){if(!c.isPromise(a))throw new Error("cgBusy expects a promise (or something that has a .promise or .$promise");-1===c.promises.indexOf(a)&&(c.promises.push(a),c.callThen(a,function(){a.$cgBusyFulfilled=!0,-1!==c.promises.indexOf(a)&&c.promises.splice(c.promises.indexOf(a),1)},function(){a.$cgBusyFulfilled=!0,-1!==c.promises.indexOf(a)&&c.promises.splice(c.promises.indexOf(a),1)}))};return c.active=function(){return c.delayPromise?!1:c.delayJustFinished?(c.delayJustFinished=!1,0===c.promises.length&&(c.durationPromise=null),c.promises.length>0):c.durationPromise?!0:c.promises.length>0},c}}]),angular.module("cgBusy").value("cgBusyDefaults",{}),angular.module("cgBusy").directive("cgBusy",["$compile","$document","$templateCache","cgBusyDefaults","$http","_cgBusyTrackerFactory",function(a,b,c,d,e,f){var g=["TBODY","THEAD","TFOOT","TR"],h=angular.element(b[0].body);return{restrict:"A",link:function(b,i,j,k){var l=-1!==g.indexOf(i[0].nodeName);if(l)b.$on("$destroy",function(){n&&n.remove(),o&&o.remove()});else{var m=i.css("position");("static"===m||""===m||"undefined"==typeof m)&&i.css("position","relative")}var n,o,p,q,r,s=f(),t=l?h:i,u={top:0,left:0,right:0,bottom:0},v={templateUrl:"angular-busy.html",delay:0,minDuration:0,backdrop:!0,message:"Please Wait...",wrapperClass:"cg-busy cg-busy-animation"};angular.extend(v,d),b.$watchCollection(j.cgBusy,function(d){if(d||(d={promise:null}),angular.isString(d))throw new Error("Invalid value for cg-busy. cgBusy no longer accepts string ids to represent promises/trackers.");(angular.isArray(d)||s.isPromise(d))&&(d={promise:d}),d=angular.extend(angular.copy(v),d),d.templateUrl||(d.templateUrl=v.templateUrl),angular.isArray(d.promise)||(d.promise=[d.promise]),q||(q=b.$new()),q.$message=d.message,angular.equals(s.promises,d.promise)||s.reset({promises:d.promise,delay:d.delay,minDuration:d.minDuration}),q.$cgBusyIsActive=function(){return s.active()},n&&p===d.templateUrl&&r===d.backdrop||(n&&n.remove(),o&&o.remove(),p=d.templateUrl,r=d.backdrop,e.get(p,{cache:c}).then(function(b){if(d.backdrop="undefined"==typeof d.backdrop?!0:d.backdrop,d.backdrop){var c='
';o=a(c)(q),t.append(o)}var e='
'+b.data+"
";if(n=a(e)(q),l){var f=i[0].getClientRects()[0];u={top:f.top+"px",left:f.left+"px",height:f.bottom-f.top+"px",width:f.right-f.left+"px"}}angular.element(n.children()[0]).css("position","absolute").css(u),t.append(n)},function(a){throw new Error("Template specified for cgBusy ("+d.templateUrl+") could not be loaded. "+a)}))},!0)}}}]),angular.module("cgBusy").run(["$templateCache",function(a){"use strict";a.put("angular-busy.html",'
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
{{$message}}
\n
\n
')}]); \ No newline at end of file