(function(){ 'use strict'; angular.module('herald.pagination' , ['angularUtils.directives.dirPagination']) .config(['paginationTemplateProvider', function(paginationTemplateProvider) { paginationTemplateProvider.setPath('/bower_components/angular-utils-pagination/dirPagination.tpl.html'); }]) .factory('PaginationFactory', function() { var KEYS = { page: 'X-Paginate-Page', limit: 'X-Paginate-Limit', elements: 'X-Paginate-Elements', pages: 'X-Paginate-Pages' }; function isNotNil(testable) { return testable !== null && testable !== undefined; } function Pagination(page, limit, elements, pages) { function isNumeric(input) { return !isNaN(input) && input !== ''; } var self = { page: parseInt(page), limit: parseInt(limit), elements: null, pages: null, listener: null, this: this }; if (!isNumeric(page) || self.page < 1) { throw new TypeError('Value for pagination page is invalid: ' + page); } if (!isNumeric(limit) || self.limit < 1) { throw new TypeError('Value for pagination limit is invalid: ' + limit); } if (isNotNil(elements) && isNumeric(elements)) { self.elements = parseInt(elements); } if (isNotNil(pages) && isNumeric(pages)) { self.pages = parseInt(pages); } function verifyPage(candidate) { var icand = parseInt(candidate); if (!isNumeric(candidate) || icand < 1) { throw new TypeError('Value for pagination page is invalid: ' + candidate); } if (isNotNil(self.this.pages()) && icand > self.this.pages()) { throw new TypeError('Value for pagination page is invalid: ' + candidate + ', max page: ' + self.this.pages()); } return icand; } this.page = function(set) { if (isNotNil(set)) { var candidate = verifyPage(set); if (isNotNil(self.listener)) { self.listener(candidate); } self.page = candidate; } return self.page; }; this.next = function() { var actual = this.page(); this.page(actual + 1); }; this.previous = function() { var actual = this.page(); this.page(actual - 1); }; this.hasNext = function() { return (isNotNil(this.pages()) && this.page()+1 <= this.pages()); }; this.hasPrevious = function() { return (this.page()-1 >= 1); }; this.limit = function() { return self.limit; }; this.elements = function(set) { if (isNotNil(set)) { self.elements = parseInt(set); } return self.elements; }; this.pages = function(set) { if (isNotNil(set)) { self.pages = parseInt(set); } return self.pages; }; this.toHeaders = function() { var headers = {}; headers[KEYS.page] = this.page() + ''; headers[KEYS.limit] = this.limit() + ''; return headers; }; this.setPageChangeListener = function(listener) { self.listener = listener; }; } var DEFAULT = new Pagination(1, 15); return { DEFAULT: DEFAULT, fromHeaders: function(headersGetter) { var page = isNotNil(headersGetter(KEYS.page)) ? headersGetter(KEYS.page) : DEFAULT.page(); var limit = isNotNil(headersGetter(KEYS.limit)) ? headersGetter(KEYS.limit) : DEFAULT.limit(); var elements = headersGetter(KEYS.elements); var pages = headersGetter(KEYS.pages); return new Pagination(page, limit, elements, pages); }, create: function(page, limit) { return new Pagination(page, limit); }, createPageCache: function(maxSeconds) { var loaded = []; var times = []; function isLoaded(pageNumber) { var now = new Date(); if (loaded[pageNumber] === undefined) { return false; } var ealier = times[pageNumber]; var delta = (now - ealier) / 1000.0; return delta <= maxSeconds; } return { isLoaded: isLoaded, get: function(pageNumber) { if (!isLoaded(pageNumber)) { return undefined; } return loaded[pageNumber]; }, set: function(pageNumber, data) { loaded[pageNumber] = data; times[pageNumber] = new Date(); } }; } }; }); })();