Skip to content

Commit

Permalink
v4.1.1 for angular 1.3 compat
Browse files Browse the repository at this point in the history
  • Loading branch information
cgross committed Oct 19, 2014
1 parent fe72f9a commit b3163c2
Show file tree
Hide file tree
Showing 48 changed files with 3,322 additions and 2,400 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Only the values you'd like overriden need to be specified.


## Release History
* v4.1.1 - Compatibility with Angular 1.3.
* v4.1.0
* Change to how `delay` and `minDuration` work together. If specified together, `minDuration` will only take effect if the promise was active through the delay. For example, if `delay`=200 and `minDuration`=500 and the actual promise only took 100ms, no indicator will be shown. If the delay threshold is reached, the indicator will show for `minDuration` ms rather than `minDuration` minus `delay` as it had been before.
* Backdrop now fades in with no movement. Message still animates in from the top.
Expand Down
322 changes: 166 additions & 156 deletions angular-busy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,86 +3,96 @@ angular.module('cgBusy',[]);
//loosely modeled after angular-promise-tracker
angular.module('cgBusy').factory('_cgBusyTrackerFactory',['$timeout','$q',function($timeout,$q){

return function(){
return function(){

var tracker = {};
tracker.promises = [];
tracker.delayPromise = null;
tracker.durationPromise = null;
var tracker = {};
tracker.promises = [];
tracker.delayPromise = null;
tracker.durationPromise = null;
tracker.delayJustFinished = false;

tracker.reset = function(options){
tracker.minDuration = options.minDuration;
tracker.reset = function(options){
tracker.minDuration = options.minDuration;

tracker.promises = [];
angular.forEach(options.promises,function(p){
if (!p || p.$cgBusyFulfilled) {
return;
}
addPromiseLikeThing(p);
});
tracker.promises = [];
angular.forEach(options.promises,function(p){
if (!p || p.$cgBusyFulfilled) {
return;
}
addPromiseLikeThing(p);
});

if (tracker.promises.length === 0) {
//if we have no promises then dont do the delay or duration stuff
return;
}
if (tracker.promises.length === 0) {
//if we have no promises then dont do the delay or duration stuff
return;
}

tracker.delayJustFinished = false;
if (options.delay) {
tracker.delayPromise = $timeout(function(){
tracker.delayPromise = null;
if (options.delay) {
tracker.delayPromise = $timeout(function(){
tracker.delayPromise = null;
tracker.delayJustFinished = true;
},parseInt(options.delay,10));
}
},parseInt(options.delay,10));
}
if (options.minDuration) {
tracker.durationPromise = $timeout(function(){
tracker.durationPromise = null;
},parseInt(options.minDuration,10) + (options.delay ? parseInt(options.delay,10) : 0));
}
};
};

tracker.isPromise = function(promiseThing){
var then = promiseThing && (promiseThing.then || promiseThing.$then ||
(promiseThing.$promiseThing && promiseThing.$promiseThing.then));

return typeof then !== 'undefined';
};

tracker.callThen = function(promiseThing,success,error){
var promise;
if (promiseThing.then || promiseThing.$then){
promise = promiseThing;
} else if (promiseThing.$promise){
promise = promiseThing.$promise;
} else if (promiseThing.denodeify){
promise = $q.when(promiseThing);
}

var then = (promise.then || promise.$them);

then.call(promise,success,error);
};

tracker.getThen = function(promise){
var then = promise && (promise.then || promise.$then ||
(promise.$promise && promise.$promise.then));
var addPromiseLikeThing = function(promise){

if (promise.denodeify) {
return $q.when(promise).then;
if (!tracker.isPromise(promise)) {
throw new Error('cgBusy expects a promise (or something that has a .promise or .$promise');
}

return then;
};

var addPromiseLikeThing = function(promise){
var then = tracker.getThen(promise);

if (!then) {
throw new Error('cgBusy expects a promise (or something that has a .promise or .$promise');
}

if (tracker.promises.indexOf(promise) !== -1){
return;
}
tracker.promises.push(promise);

then(function(){
promise.$cgBusyFulfilled = true;
if (tracker.promises.indexOf(promise) === -1) {
return;
}
tracker.promises.splice(tracker.promises.indexOf(promise),1);
},function(){
promise.$cgBusyFulfilled = true;
if (tracker.promises.indexOf(promise) === -1) {
return;
}
tracker.promises.splice(tracker.promises.indexOf(promise),1);
});
};

tracker.active = function(){
if (tracker.delayPromise){
return false;
}
if (tracker.promises.indexOf(promise) !== -1){
return;
}
tracker.promises.push(promise);

tracker.callThen(promise, function(){
promise.$cgBusyFulfilled = true;
if (tracker.promises.indexOf(promise) === -1) {
return;
}
tracker.promises.splice(tracker.promises.indexOf(promise),1);
},function(){
promise.$cgBusyFulfilled = true;
if (tracker.promises.indexOf(promise) === -1) {
return;
}
tracker.promises.splice(tracker.promises.indexOf(promise),1);
});
};

tracker.active = function(){
if (tracker.delayPromise){
return false;
}

if (!tracker.delayJustFinished){
if (tracker.durationPromise){
Expand All @@ -96,135 +106,135 @@ angular.module('cgBusy').factory('_cgBusyTrackerFactory',['$timeout','$q',functi
tracker.delayJustFinished = false;
return tracker.promises.length > 0;
}
};
};

return tracker;
return tracker;

};
};
}]);

angular.module('cgBusy').value('cgBusyDefaults',{});

angular.module('cgBusy').directive('cgBusy',['$compile','$templateCache','cgBusyDefaults','$http','_cgBusyTrackerFactory',
function($compile,$templateCache,cgBusyDefaults,$http,_cgBusyTrackerFactory){
return {
restrict: 'A',
link: function(scope, element, attrs, fn) {

//Apply position:relative to parent element if necessary
var position = element.css('position');
if (position === 'static' || position === '' || typeof position === 'undefined'){
element.css('position','relative');
}

var templateElement;
function($compile,$templateCache,cgBusyDefaults,$http,_cgBusyTrackerFactory){
return {
restrict: 'A',
link: function(scope, element, attrs, fn) {

//Apply position:relative to parent element if necessary
var position = element.css('position');
if (position === 'static' || position === '' || typeof position === 'undefined'){
element.css('position','relative');
}

var templateElement;
var backdropElement;
var currentTemplate;
var templateScope;
var backdrop;
var tracker = _cgBusyTrackerFactory();
var currentTemplate;
var templateScope;
var backdrop;
var tracker = _cgBusyTrackerFactory();

var defaults = {
templateUrl: 'angular-busy.html',
delay:0,
minDuration:0,
backdrop: true,
message:'Please Wait...'
};
var defaults = {
templateUrl: 'angular-busy.html',
delay:0,
minDuration:0,
backdrop: true,
message:'Please Wait...'
};

angular.extend(defaults,cgBusyDefaults);
angular.extend(defaults,cgBusyDefaults);

scope.$watchCollection(attrs.cgBusy,function(options){
scope.$watchCollection(attrs.cgBusy,function(options){

if (!options) {
options = {promise:null};
}
if (!options) {
options = {promise:null};
}

if (angular.isString(options)) {
throw new Error('Invalid value for cg-busy. cgBusy no longer accepts string ids to represent promises/trackers.');
}
if (angular.isString(options)) {
throw new Error('Invalid value for cg-busy. cgBusy no longer accepts string ids to represent promises/trackers.');
}

//is it an array (of promises) or one promise
if (angular.isArray(options) || tracker.getThen(options)) {
options = {promise:options};
}
//is it an array (of promises) or one promise
if (angular.isArray(options) || tracker.isPromise(options)) {
options = {promise:options};
}

options = angular.extend(angular.copy(defaults),options);
options = angular.extend(angular.copy(defaults),options);

if (!options.templateUrl){
options.templateUrl = defaults.templateUrl;
}
if (!options.templateUrl){
options.templateUrl = defaults.templateUrl;
}

if (!angular.isArray(options.promise)){
options.promise = [options.promise];
}
if (!angular.isArray(options.promise)){
options.promise = [options.promise];
}

// options.promise = angular.isArray(options.promise) ? options.promise : [options.promise];
// options.message = options.message ? options.message : 'Please Wait...';
// options.template = options.template ? options.template : cgBusyTemplateName;
// options.minDuration = options.minDuration ? options.minDuration : 0;
// options.delay = options.delay ? options.delay : 0;
// options.promise = angular.isArray(options.promise) ? options.promise : [options.promise];
// options.message = options.message ? options.message : 'Please Wait...';
// options.template = options.template ? options.template : cgBusyTemplateName;
// options.minDuration = options.minDuration ? options.minDuration : 0;
// options.delay = options.delay ? options.delay : 0;

if (!templateScope) {
templateScope = scope.$new();
}
if (!templateScope) {
templateScope = scope.$new();
}

templateScope.$message = options.message;
templateScope.$message = options.message;

if (!angular.equals(tracker.promises,options.promise)) {
tracker.reset({
promises:options.promise,
delay:options.delay,
minDuration: options.minDuration
});
}
if (!angular.equals(tracker.promises,options.promise)) {
tracker.reset({
promises:options.promise,
delay:options.delay,
minDuration: options.minDuration
});
}

templateScope.$cgBusyIsActive = function() {
return tracker.active();
};
templateScope.$cgBusyIsActive = function() {
return tracker.active();
};


if (!templateElement || currentTemplate !== options.templateUrl || backdrop !== options.backdrop) {
if (!templateElement || currentTemplate !== options.templateUrl || backdrop !== options.backdrop) {

if (templateElement) {
templateElement.remove();
}
if (templateElement) {
templateElement.remove();
}
if (backdropElement){
backdropElement.remove();
}

currentTemplate = options.templateUrl;
backdrop = options.backdrop;
currentTemplate = options.templateUrl;
backdrop = options.backdrop;

$http.get(currentTemplate,{cache: $templateCache}).success(function(indicatorTemplate){
$http.get(currentTemplate,{cache: $templateCache}).success(function(indicatorTemplate){

options.backdrop = typeof options.backdrop === 'undefined' ? true : options.backdrop;
options.backdrop = typeof options.backdrop === 'undefined' ? true : options.backdrop;

if (options.backdrop){
var backdrop = '<div class="cg-busy cg-busy-backdrop cg-busy-backdrop-animation ng-hide" ng-show="$cgBusyIsActive()"></div>';
backdropElement = $compile(backdrop)(templateScope);
element.append(backdropElement);
}

var template = '<div class="cg-busy cg-busy-animation ng-hide" ng-show="$cgBusyIsActive()">' + indicatorTemplate + '</div>';
templateElement = $compile(template)(templateScope);

angular.element(templateElement.children()[0])
.css('position','absolute')
.css('top',0)
.css('left',0)
.css('right',0)
.css('bottom',0);
element.append(templateElement);

}).error(function(data){
throw new Error('Template specified for cgBusy ('+options.templateUrl+') could not be loaded. ' + data);
});
}

},true);
}
};
}
]);
var template = '<div class="cg-busy cg-busy-animation ng-hide" ng-show="$cgBusyIsActive()">' + indicatorTemplate + '</div>';
templateElement = $compile(template)(templateScope);

angular.element(templateElement.children()[0])
.css('position','absolute')
.css('top',0)
.css('left',0)
.css('right',0)
.css('bottom',0);
element.append(templateElement);

}).error(function(data){
throw new Error('Template specified for cgBusy ('+options.templateUrl+') could not be loaded. ' + data);
});
}

},true);
}
};
}
]);

Loading

0 comments on commit b3163c2

Please sign in to comment.