angular.module('podcast.directives', []) .directive('pullToRefresh', function() { return function(scope, element, attrs, feedItems) { var myScroll, pullDownEl, pullDownOffset, wrapper = angular.element('
'); element.contents().wrap(wrapper[0]); wrapper.prepend('
' + 'Pull down to refresh...' + '
'); pullDownEl = document.getElementById('pullDown'); pullDownOffset = pullDownEl.offsetHeight; //TODO: get ID from context somehow? myScroll = new iScroll(element[0], { useTransition: true, topOffset: pullDownOffset, vScrollbar: false, onRefresh: function () { if (pullDownEl.className.match('loading')) { pullDownEl.className = ''; pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...'; } }, onScrollMove: function () { if (this.y > 5 && !pullDownEl.className.match('flip')) { pullDownEl.className = 'flip'; pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...'; this.minScrollY = 0; } else if (this.y < 5 && pullDownEl.className.match('flip')) { pullDownEl.className = ''; pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...'; this.minScrollY = -pullDownOffset; } }, onScrollEnd: function () { if (pullDownEl.className.match('flip')) { pullDownEl.className = 'loading'; pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...'; scope.downloadItems(function(feedItem, feed) { if (undefined === feed) { myScroll.refresh(); } else { pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading ' + feed.title + '...'; } }); } } }); scope.$watch( function() { return scope.queue; }, function() { myScroll.refresh(); }, true ); } }) .directive('hold', ['$timeout', function($timeout) { return function(scope, element, attrs) { var startTime, moved, holdTimer = false; element.bind('touchstart', function(event) { startTime = new Date().getTime(); $timeout.cancel(holdTimer); holdTimer = $timeout(function() { scope.$eval(attrs.hold); }, 500); }); element.bind('touchmove', function() { $timeout.cancel(holdTimer); }); element.bind('touchend', function(event) { if (new Date().getTime() - startTime > 500) { event.preventDefault(); } else { $timeout.cancel(holdTimer); element[0].click(); } }); } }]) .directive('scroll', function() { return function(scope, element, attrs, feedItems) { var scroll = new iScroll(element[0], {vScrollbar: false}); }; }) .directive('blob', function() { return function postLink(scope, element, attrs) { var updateImage = function () { var blob = scope.$eval(attrs.blob); if (blob !== undefined) { var imgUrl = window.URL.createObjectURL(blob); element.attr('src', imgUrl); window.URL.revokeObjectURL(imgUrl); } }; scope.$watch( function() { return scope.$eval(attrs.blob); }, function() { updateImage(); }, true ); }; }) .directive('setting', function() { return { restrict: 'A', require: '?ngModel', priority: 1, link: function(scope, element, attrs, ngModel) { if (!ngModel) { return; } ngModel.$render = function() { if (ngModel.$modelValue.value !== '') { ngModel.$viewValue = ngModel.$modelValue.value; } }; } }; }) .directive('ngFocus', ['$parse', function($parse) { return function(scope, element, attr) { var fn = $parse(attr['ngFocus']); element.bind('focus', function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); } }]) .directive('ngBlur', ['$parse', function($parse) { return function(scope, element, attr) { var fn = $parse(attr['ngBlur']); element.bind('blur', function(event) { scope.$apply(function() { fn(scope, {$event:event}); }); }); } }]) ;