You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by ma...@apache.org on 2014/05/28 21:05:19 UTC
[10/29] Upgrade Aurora UI to bootstrap3
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/logs/.gitignore
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/logs/.gitignore b/3rdparty/javascript/bower_components/smart-table/logs/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/logs/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/package.json
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/package.json b/3rdparty/javascript/bower_components/smart-table/package.json
new file mode 100644
index 0000000..4417067
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "Smart-Table",
+ "version": "0.2.1",
+ "description": "a table/grid for AngularJS",
+ "main": "smart-table-module",
+ "directories": {
+ "test": "test",
+ "example": "example-app"
+ },
+ "scripts": {
+ "webServer": "scripts/web-server.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/lorenzofox3/Smart-Table.git"
+ },
+ "keywords": [
+ "table",
+ "grid",
+ "angularjs"
+ ],
+ "author": "Laurent Renard",
+ "license": "MIT",
+ "readmeFilename": "README.md",
+ "devDependencies": {
+ "grunt": "~0.4.1",
+ "grunt-contrib-concat": "~0.3.0",
+ "grunt-contrib-clean": "~0.4.1",
+ "grunt-html2js": "~0.1.3",
+ "grunt-contrib-copy": "~0.4.1",
+ "grunt-contrib-uglify": "~0.2.1",
+ "grunt-regex-replace": "~0.2.5",
+ "grunt-karma": "~0.6.2",
+ "karma-complexity-preprocessor": "~0.1.0"
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.bat
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.bat b/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.bat
new file mode 100644
index 0000000..0b2aee6
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.bat
@@ -0,0 +1,11 @@
+@echo off
+
+REM Windows script for running e2e tests
+REM You have to run server and capture some browser first
+REM
+REM Requirements:
+REM - NodeJS (http://nodejs.org/)
+REM - Karma (npm install -g karma)
+
+set BASE_DIR=%~dp0
+karma start "%BASE_DIR%\..\config\karma-e2e.conf.js" %*
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.sh
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.sh b/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.sh
new file mode 100755
index 0000000..175c108
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/scripts/e2e-test.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+BASE_DIR=`dirname $0`
+
+echo ""
+echo "Starting Karma Server (http://vojtajina.github.com/testacular)"
+echo "-------------------------------------------------------------------"
+
+karma start $BASE_DIR/../config/karma-e2e.conf.js $*
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/scripts/test.bat
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/scripts/test.bat b/3rdparty/javascript/bower_components/smart-table/scripts/test.bat
new file mode 100644
index 0000000..192fa03
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/scripts/test.bat
@@ -0,0 +1,11 @@
+@echo off
+
+REM Windows script for running unit tests
+REM You have to run server and capture some browser first
+REM
+REM Requirements:
+REM - NodeJS (http://nodejs.org/)
+REM - Karma (npm install -g karma)
+
+set BASE_DIR=%~dp0
+karma start "%BASE_DIR%\..\config\karma.conf.js" %*
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/scripts/test.sh
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/scripts/test.sh b/3rdparty/javascript/bower_components/smart-table/scripts/test.sh
new file mode 100755
index 0000000..4c30318
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/scripts/test.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+BASE_DIR=`dirname $0`
+
+echo ""
+echo "Starting Karma Server"
+echo "-------------------------------------------------------------------"
+
+karma start $BASE_DIR/../config/karma.conf.js $*
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/scripts/watchr.rb
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/scripts/watchr.rb b/3rdparty/javascript/bower_components/smart-table/scripts/watchr.rb
new file mode 100755
index 0000000..89ef656
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/scripts/watchr.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env watchr
+
+# config file for watchr http://github.com/mynyml/watchr
+# install: gem install watchr
+# run: watch watchr.rb
+# note: make sure that you have jstd server running (server.sh) and a browser captured
+
+log_file = File.expand_path(File.dirname(__FILE__) + '/../logs/jstd.log')
+
+`cd ..`
+`touch #{log_file}`
+
+puts "String watchr... log file: #{log_file}"
+
+watch( '(app/js|test/unit)' ) do
+ `echo "\n\ntest run started @ \`date\`" > #{log_file}`
+ `scripts/test.sh &> #{log_file}`
+end
+
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/scripts/web-server.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/scripts/web-server.js b/3rdparty/javascript/bower_components/smart-table/scripts/web-server.js
new file mode 100755
index 0000000..3f74441
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/scripts/web-server.js
@@ -0,0 +1,244 @@
+#!/usr/bin/env node
+
+var util = require('util'),
+ http = require('http'),
+ fs = require('fs'),
+ url = require('url'),
+ events = require('events');
+
+var DEFAULT_PORT = 8000;
+
+function main(argv) {
+ new HttpServer({
+ 'GET': createServlet(StaticServlet),
+ 'HEAD': createServlet(StaticServlet)
+ }).start(Number(argv[2]) || DEFAULT_PORT);
+}
+
+function escapeHtml(value) {
+ return value.toString().
+ replace('<', '<').
+ replace('>', '>').
+ replace('"', '"');
+}
+
+function createServlet(Class) {
+ var servlet = new Class();
+ return servlet.handleRequest.bind(servlet);
+}
+
+/**
+ * An Http server implementation that uses a map of methods to decide
+ * action routing.
+ *
+ * @param {Object} Map of method => Handler function
+ */
+function HttpServer(handlers) {
+ this.handlers = handlers;
+ this.server = http.createServer(this.handleRequest_.bind(this));
+}
+
+HttpServer.prototype.start = function(port) {
+ this.port = port;
+ this.server.listen(port);
+ util.puts('Http Server running at http://localhost:' + port + '/');
+};
+
+HttpServer.prototype.parseUrl_ = function(urlString) {
+ var parsed = url.parse(urlString);
+ parsed.pathname = url.resolve('/', parsed.pathname);
+ return url.parse(url.format(parsed), true);
+};
+
+HttpServer.prototype.handleRequest_ = function(req, res) {
+ var logEntry = req.method + ' ' + req.url;
+ if (req.headers['user-agent']) {
+ logEntry += ' ' + req.headers['user-agent'];
+ }
+ util.puts(logEntry);
+ req.url = this.parseUrl_(req.url);
+ var handler = this.handlers[req.method];
+ if (!handler) {
+ res.writeHead(501);
+ res.end();
+ } else {
+ handler.call(this, req, res);
+ }
+};
+
+/**
+ * Handles static content.
+ */
+function StaticServlet() {}
+
+StaticServlet.MimeMap = {
+ 'txt': 'text/plain',
+ 'html': 'text/html',
+ 'css': 'text/css',
+ 'xml': 'application/xml',
+ 'json': 'application/json',
+ 'js': 'application/javascript',
+ 'jpg': 'image/jpeg',
+ 'jpeg': 'image/jpeg',
+ 'gif': 'image/gif',
+ 'png': 'image/png',
+ 'svg': 'image/svg+xml'
+};
+
+StaticServlet.prototype.handleRequest = function(req, res) {
+ var self = this;
+ var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){
+ return String.fromCharCode(parseInt(hex, 16));
+ });
+ var parts = path.split('/');
+ if (parts[parts.length-1].charAt(0) === '.')
+ return self.sendForbidden_(req, res, path);
+ fs.stat(path, function(err, stat) {
+ if (err)
+ return self.sendMissing_(req, res, path);
+ if (stat.isDirectory())
+ return self.sendDirectory_(req, res, path);
+ return self.sendFile_(req, res, path);
+ });
+}
+
+StaticServlet.prototype.sendError_ = function(req, res, error) {
+ res.writeHead(500, {
+ 'Content-Type': 'text/html'
+ });
+ res.write('<!doctype html>\n');
+ res.write('<title>Internal Server Error</title>\n');
+ res.write('<h1>Internal Server Error</h1>');
+ res.write('<pre>' + escapeHtml(util.inspect(error)) + '</pre>');
+ util.puts('500 Internal Server Error');
+ util.puts(util.inspect(error));
+};
+
+StaticServlet.prototype.sendMissing_ = function(req, res, path) {
+ path = path.substring(1);
+ res.writeHead(404, {
+ 'Content-Type': 'text/html'
+ });
+ res.write('<!doctype html>\n');
+ res.write('<title>404 Not Found</title>\n');
+ res.write('<h1>Not Found</h1>');
+ res.write(
+ '<p>The requested URL ' +
+ escapeHtml(path) +
+ ' was not found on this server.</p>'
+ );
+ res.end();
+ util.puts('404 Not Found: ' + path);
+};
+
+StaticServlet.prototype.sendForbidden_ = function(req, res, path) {
+ path = path.substring(1);
+ res.writeHead(403, {
+ 'Content-Type': 'text/html'
+ });
+ res.write('<!doctype html>\n');
+ res.write('<title>403 Forbidden</title>\n');
+ res.write('<h1>Forbidden</h1>');
+ res.write(
+ '<p>You do not have permission to access ' +
+ escapeHtml(path) + ' on this server.</p>'
+ );
+ res.end();
+ util.puts('403 Forbidden: ' + path);
+};
+
+StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) {
+ res.writeHead(301, {
+ 'Content-Type': 'text/html',
+ 'Location': redirectUrl
+ });
+ res.write('<!doctype html>\n');
+ res.write('<title>301 Moved Permanently</title>\n');
+ res.write('<h1>Moved Permanently</h1>');
+ res.write(
+ '<p>The document has moved <a href="' +
+ redirectUrl +
+ '">here</a>.</p>'
+ );
+ res.end();
+ util.puts('301 Moved Permanently: ' + redirectUrl);
+};
+
+StaticServlet.prototype.sendFile_ = function(req, res, path) {
+ var self = this;
+ var file = fs.createReadStream(path);
+ res.writeHead(200, {
+ 'Content-Type': StaticServlet.
+ MimeMap[path.split('.').pop()] || 'text/plain'
+ });
+ if (req.method === 'HEAD') {
+ res.end();
+ } else {
+ file.on('data', res.write.bind(res));
+ file.on('close', function() {
+ res.end();
+ });
+ file.on('error', function(error) {
+ self.sendError_(req, res, error);
+ });
+ }
+};
+
+StaticServlet.prototype.sendDirectory_ = function(req, res, path) {
+ var self = this;
+ if (path.match(/[^\/]$/)) {
+ req.url.pathname += '/';
+ var redirectUrl = url.format(url.parse(url.format(req.url)));
+ return self.sendRedirect_(req, res, redirectUrl);
+ }
+ fs.readdir(path, function(err, files) {
+ if (err)
+ return self.sendError_(req, res, error);
+
+ if (!files.length)
+ return self.writeDirectoryIndex_(req, res, path, []);
+
+ var remaining = files.length;
+ files.forEach(function(fileName, index) {
+ fs.stat(path + '/' + fileName, function(err, stat) {
+ if (err)
+ return self.sendError_(req, res, err);
+ if (stat.isDirectory()) {
+ files[index] = fileName + '/';
+ }
+ if (!(--remaining))
+ return self.writeDirectoryIndex_(req, res, path, files);
+ });
+ });
+ });
+};
+
+StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) {
+ path = path.substring(1);
+ res.writeHead(200, {
+ 'Content-Type': 'text/html'
+ });
+ if (req.method === 'HEAD') {
+ res.end();
+ return;
+ }
+ res.write('<!doctype html>\n');
+ res.write('<title>' + escapeHtml(path) + '</title>\n');
+ res.write('<style>\n');
+ res.write(' ol { list-style-type: none; font-size: 1.2em; }\n');
+ res.write('</style>\n');
+ res.write('<h1>Directory: ' + escapeHtml(path) + '</h1>');
+ res.write('<ol>');
+ files.forEach(function(fileName) {
+ if (fileName.charAt(0) !== '.') {
+ res.write('<li><a href="' +
+ escapeHtml(fileName) + '">' +
+ escapeHtml(fileName) + '</a></li>');
+ }
+ });
+ res.write('</ol>');
+ res.end();
+};
+
+// Must be last,
+main(process.argv);
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Column.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Column.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Column.js
new file mode 100644
index 0000000..bf3ca53
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Column.js
@@ -0,0 +1,52 @@
+/* Column module */
+
+(function (global, angular) {
+ "use strict";
+ var smartTableColumnModule = angular.module('smartTable.column', ['smartTable.templateUrlList']).constant('DefaultColumnConfiguration', {
+ isSortable: true,
+ isEditable: false,
+ type: 'text',
+
+
+ //it is useless to have that empty strings, but it reminds what is available
+ headerTemplateUrl: '',
+ map: '',
+ label: '',
+ sortPredicate: '',
+ formatFunction: '',
+ formatParameter: '',
+ filterPredicate: '',
+ cellTemplateUrl: '',
+ headerClass: '',
+ cellClass: ''
+ });
+
+ function ColumnProvider(DefaultColumnConfiguration, templateUrlList) {
+
+ function Column(config) {
+ if (!(this instanceof Column)) {
+ return new Column(config);
+ }
+ angular.extend(this, config);
+ }
+
+ this.setDefaultOption = function (option) {
+ angular.extend(Column.prototype, option);
+ };
+
+ DefaultColumnConfiguration.headerTemplateUrl = templateUrlList.defaultHeader;
+ this.setDefaultOption(DefaultColumnConfiguration);
+
+ this.$get = function () {
+ return Column;
+ };
+ }
+
+ ColumnProvider.$inject = ['DefaultColumnConfiguration', 'templateUrlList'];
+ smartTableColumnModule.provider('Column', ColumnProvider);
+
+ //make it global so it can be tested
+ global.ColumnProvider = ColumnProvider;
+})(window, angular);
+
+
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Directives.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Directives.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Directives.js
new file mode 100644
index 0000000..82d1a0c
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Directives.js
@@ -0,0 +1,267 @@
+/* Directives */
+(function (angular) {
+ "use strict";
+ angular.module('smartTable.directives', ['smartTable.templateUrlList', 'smartTable.templates'])
+ .directive('smartTable', ['templateUrlList', 'DefaultTableConfiguration', function (templateList, defaultConfig) {
+ return {
+ restrict: 'EA',
+ scope: {
+ columnCollection: '=columns',
+ dataCollection: '=rows',
+ config: '='
+ },
+ replace: 'true',
+ templateUrl: templateList.smartTable,
+ controller: 'TableCtrl',
+ link: function (scope, element, attr, ctrl) {
+
+ var templateObject;
+
+ scope.$watch('config', function (config) {
+ var newConfig = angular.extend({}, defaultConfig, config),
+ length = scope.columns !== undefined ? scope.columns.length : 0;
+
+ ctrl.setGlobalConfig(newConfig);
+
+ //remove the checkbox column if needed
+ if (newConfig.selectionMode !== 'multiple' || newConfig.displaySelectionCheckbox !== true) {
+ for (var i = length - 1; i >= 0; i--) {
+ if (scope.columns[i].isSelectionColumn === true) {
+ ctrl.removeColumn(i);
+ }
+ }
+ } else {
+ //add selection box column if required
+ ctrl.insertColumn({cellTemplateUrl: templateList.selectionCheckbox, headerTemplateUrl: templateList.selectAllCheckbox, isSelectionColumn: true}, 0);
+ }
+ }, true);
+
+ //insert columns from column config
+ scope.$watch('columnCollection', function (oldValue, newValue) {
+
+ ctrl.clearColumns();
+
+ if (scope.columnCollection) {
+ for (var i = 0, l = scope.columnCollection.length; i < l; i++) {
+ ctrl.insertColumn(scope.columnCollection[i]);
+ }
+ } else {
+ //or guess data Structure
+ if (scope.dataCollection && scope.dataCollection.length > 0) {
+ templateObject = scope.dataCollection[0];
+ angular.forEach(templateObject, function (value, key) {
+ if (key[0] != '$') {
+ ctrl.insertColumn({label: key, map: key});
+ }
+ });
+ }
+ }
+ }, true);
+
+ //if item are added or removed into the data model from outside the grid
+ scope.$watch('dataCollection.length', function (oldValue, newValue) {
+ if (oldValue !== newValue) {
+ ctrl.sortBy();//it will trigger the refresh... some hack ?
+ }
+ });
+ }
+ };
+ }])
+ //just to be able to select the row
+ .directive('smartTableDataRow', function () {
+
+ return {
+ require: '^smartTable',
+ restrict: 'C',
+ link: function (scope, element, attr, ctrl) {
+
+ var _config;
+ if ((_config = scope.config) != null) {
+ if (typeof _config.rowFunction === "function") {
+ _config.rowFunction(scope, element, attr, ctrl);
+ }
+ }
+
+ element.bind('click', function () {
+ scope.$apply(function () {
+ ctrl.toggleSelection(scope.dataRow);
+ })
+ });
+ }
+ };
+ })
+ //header cell with sorting functionality or put a checkbox if this column is a selection column
+ .directive('smartTableHeaderCell',function () {
+ return {
+ restrict: 'C',
+ require: '^smartTable',
+ link: function (scope, element, attr, ctrl) {
+ element.bind('click', function () {
+ scope.$apply(function () {
+ ctrl.sortBy(scope.column);
+ });
+ })
+ }
+ };
+ }).directive('smartTableSelectAll', function () {
+ return {
+ restrict: 'C',
+ require: '^smartTable',
+ link: function (scope, element, attr, ctrl) {
+ element.bind('click', function (event) {
+ ctrl.toggleSelectionAll(element[0].checked === true);
+ })
+ }
+ };
+ })
+ //credit to Valentyn shybanov : http://stackoverflow.com/questions/14544741/angularjs-directive-to-stoppropagation
+ .directive('stopEvent', function () {
+ return {
+ restrict: 'A',
+ link: function (scope, element, attr) {
+ element.bind(attr.stopEvent, function (e) {
+ e.stopPropagation();
+ });
+ }
+ }
+ })
+ //the global filter
+ .directive('smartTableGlobalSearch', ['templateUrlList', function (templateList) {
+ return {
+ restrict: 'C',
+ require: '^smartTable',
+ scope: {
+ columnSpan: '@'
+ },
+ templateUrl: templateList.smartTableGlobalSearch,
+ replace: false,
+ link: function (scope, element, attr, ctrl) {
+
+ scope.searchValue = '';
+
+ scope.$watch('searchValue', function (value) {
+ //todo perf improvement only filter on blur ?
+ ctrl.search(value);
+ });
+ }
+ }
+ }])
+ //a customisable cell (see templateUrl) and editable
+ //TODO check with the ng-include strategy
+ .directive('smartTableDataCell', ['$filter', '$http', '$templateCache', '$compile', '$parse', function (filter, http, templateCache, compile, parse) {
+ return {
+ restrict: 'C',
+ link: function (scope, element) {
+ var
+ column = scope.column,
+ isSimpleCell = !column.isEditable,
+ row = scope.dataRow,
+ format = filter('format'),
+ getter = parse(column.map),
+ childScope;
+
+ //can be useful for child directives
+ scope.$watch('dataRow', function (value) {
+ scope.formatedValue = format(getter(row), column.formatFunction, column.formatParameter);
+ if (isSimpleCell === true) {
+ element.html(scope.formatedValue);
+ }
+ }, true);
+
+ function defaultContent() {
+ if (column.isEditable) {
+ element.html('<div editable-cell="" row="dataRow" column="column" type="column.type"></div>');
+ compile(element.contents())(scope);
+ } else {
+ element.html(scope.formatedValue);
+ }
+ }
+
+ scope.$watch('column.cellTemplateUrl', function (value) {
+
+ if (value) {
+ //we have to load the template (and cache it) : a kind of ngInclude
+ http.get(value, {cache: templateCache}).success(function (response) {
+
+ isSimpleCell = false;
+
+ //create a scope
+ childScope = scope.$new();
+ //compile the element with its new content and new scope
+ element.html(response);
+ compile(element.contents())(childScope);
+ }).error(defaultContent);
+
+ } else {
+ defaultContent();
+ }
+ });
+ }
+ };
+ }])
+ //directive that allows type to be bound in input
+ .directive('inputType', function () {
+ return {
+ restrict: 'A',
+ priority: 1,
+ link: function (scope, ielement, iattr) {
+ //force the type to be set before inputDirective is called
+ var type = scope.$eval(iattr.type);
+ iattr.$set('type', type);
+ }
+ };
+ })
+ //an editable content in the context of a cell (see row, column)
+ .directive('editableCell', ['templateUrlList', '$parse', function (templateList, parse) {
+ return {
+ restrict: 'EA',
+ require: '^smartTable',
+ templateUrl: templateList.editableCell,
+ scope: {
+ row: '=',
+ column: '=',
+ type: '='
+ },
+ replace: true,
+ link: function (scope, element, attrs, ctrl) {
+ var form = angular.element(element.children()[1]),
+ input = angular.element(form.children()[0]),
+ getter = parse(scope.column.map);
+
+ //init values
+ scope.isEditMode = false;
+ scope.$watch('row', function () {
+ scope.value = getter(scope.row);
+ }, true);
+
+
+ scope.submit = function () {
+ //update model if valid
+ if (scope.myForm.$valid === true) {
+ ctrl.updateDataRow(scope.row, scope.column.map, scope.value);
+ ctrl.sortBy();//it will trigger the refresh... (ie it will sort, filter, etc with the new value)
+ }
+ scope.toggleEditMode();
+ };
+
+ scope.toggleEditMode = function () {
+ scope.value = getter(scope.row);
+ scope.isEditMode = scope.isEditMode !== true;
+ };
+
+ scope.$watch('isEditMode', function (newValue) {
+ if (newValue === true) {
+ input[0].select();
+ input[0].focus();
+ }
+ });
+
+ input.bind('blur', function () {
+ scope.$apply(function () {
+ scope.submit();
+ });
+ });
+ }
+ };
+ }]);
+})(angular);
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Filters.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Filters.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Filters.js
new file mode 100644
index 0000000..65cdccf
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Filters.js
@@ -0,0 +1,22 @@
+/* Filters */
+(function (angular) {
+ "use strict";
+ angular.module('smartTable.filters', []).
+ constant('DefaultFilters', ['currency', 'date', 'json', 'lowercase', 'number', 'uppercase']).
+ filter('format', ['$filter', 'DefaultFilters', function (filter, defaultfilters) {
+ return function (value, formatFunction, filterParameter) {
+
+ var returnFunction;
+
+ if (formatFunction && angular.isFunction(formatFunction)) {
+ returnFunction = formatFunction;
+ } else {
+ returnFunction = defaultfilters.indexOf(formatFunction) !== -1 ? filter(formatFunction) : function (value) {
+ return value;
+ };
+ }
+ return returnFunction(value, filterParameter);
+ };
+ }]);
+})(angular);
+
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Table.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Table.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Table.js
new file mode 100644
index 0000000..792f61f
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Table.js
@@ -0,0 +1,279 @@
+/*table module */
+
+(function (angular) {
+ "use strict";
+ angular.module('smartTable.table', ['smartTable.column', 'smartTable.utilities', 'smartTable.directives', 'smartTable.filters', 'ui.bootstrap.pagination.smartTable'])
+ .constant('DefaultTableConfiguration', {
+ selectionMode: 'none',
+ isGlobalSearchActivated: false,
+ displaySelectionCheckbox: false,
+ isPaginationEnabled: true,
+ itemsByPage: 10,
+ maxSize: 5,
+
+ //just to remind available option
+ sortAlgorithm: '',
+ filterAlgorithm: ''
+ })
+ .controller('TableCtrl', ['$scope', 'Column', '$filter', '$parse', 'ArrayUtility', 'DefaultTableConfiguration', function (scope, Column, filter, parse, arrayUtility, defaultConfig) {
+
+ scope.columns = [];
+ scope.dataCollection = scope.dataCollection || [];
+ scope.displayedCollection = []; //init empty array so that if pagination is enabled, it does not spoil performances
+ scope.numberOfPages = calculateNumberOfPages(scope.dataCollection);
+ scope.currentPage = 1;
+ scope.holder = {isAllSelected: false};
+
+ var predicate = {},
+ lastColumnSort;
+
+ function isAllSelected() {
+ var i,
+ l = scope.displayedCollection.length;
+ for (i = 0; i < l; i++) {
+ if (scope.displayedCollection[i].isSelected !== true) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ function calculateNumberOfPages(array) {
+
+ if (!angular.isArray(array) || array.length === 0 || scope.itemsByPage < 1) {
+ return 1;
+ }
+ return Math.ceil(array.length / scope.itemsByPage);
+ }
+
+ function sortDataRow(array, column) {
+ var sortAlgo = (scope.sortAlgorithm && angular.isFunction(scope.sortAlgorithm)) === true ? scope.sortAlgorithm : filter('orderBy');
+ if (column && !(column.reverse === undefined)) {
+ return arrayUtility.sort(array, sortAlgo, column.sortPredicate, column.reverse);
+ } else {
+ return array;
+ }
+ }
+
+ function selectDataRow(array, selectionMode, index, select) {
+
+ var dataRow, oldValue;
+
+ if ((!angular.isArray(array)) || (selectionMode !== 'multiple' && selectionMode !== 'single')) {
+ return;
+ }
+
+ if (index >= 0 && index < array.length) {
+ dataRow = array[index];
+ if (selectionMode === 'single') {
+ //unselect all the others
+ for (var i = 0, l = array.length; i < l; i++) {
+ oldValue = array[i].isSelected;
+ array[i].isSelected = false;
+ if (oldValue === true) {
+ scope.$emit('selectionChange', {item: array[i]});
+ }
+ }
+ }
+ dataRow.isSelected = select;
+ scope.holder.isAllSelected = isAllSelected();
+ scope.$emit('selectionChange', {item: dataRow});
+ }
+ }
+
+ /**
+ * set the config (config parameters will be available through scope
+ * @param config
+ */
+ this.setGlobalConfig = function (config) {
+ angular.extend(scope, defaultConfig, config);
+ };
+
+ /**
+ * change the current page displayed
+ * @param page
+ */
+ this.changePage = function (page) {
+ var oldPage = scope.currentPage;
+ if (angular.isNumber(page.page)) {
+ scope.currentPage = page.page;
+ scope.displayedCollection = this.pipe(scope.dataCollection);
+ scope.holder.isAllSelected = isAllSelected();
+ scope.$emit('changePage', {oldValue: oldPage, newValue: scope.currentPage});
+ }
+ };
+
+ /**
+ * set column as the column used to sort the data (if it is already the case, it will change the reverse value)
+ * @method sortBy
+ * @param column
+ */
+ this.sortBy = function (column) {
+ var index = scope.columns.indexOf(column);
+ if (index !== -1) {
+ if (column.isSortable === true) {
+ // reset the last column used
+ if (lastColumnSort && lastColumnSort !== column) {
+ lastColumnSort.reverse = undefined;
+ }
+ column.sortPredicate = column.sortPredicate || column.map;
+
+ if (column.reverse === undefined) {
+ column.reverse = false;
+ }
+ else if (column.reverse === false) {
+ column.reverse = true;
+ }
+ else {
+ column.reverse = undefined;
+ }
+
+ lastColumnSort = column;
+ }
+ }
+
+ scope.displayedCollection = this.pipe(scope.dataCollection);
+ };
+
+ /**
+ * set the filter predicate used for searching
+ * @param input
+ * @param column
+ */
+ this.search = function (input, column) {
+
+ //update column and global predicate
+ if (column && scope.columns.indexOf(column) !== -1) {
+ predicate[column.map] = input;
+ } else {
+ predicate = {$: input};
+ }
+ scope.displayedCollection = this.pipe(scope.dataCollection);
+ };
+
+ /**
+ * combine sort, search and limitTo operations on an array,
+ * @param array
+ * @returns Array, an array result of the operations on input array
+ */
+ this.pipe = function (array) {
+ var filterAlgo = (scope.filterAlgorithm && angular.isFunction(scope.filterAlgorithm)) === true ? scope.filterAlgorithm : filter('filter'),
+ output;
+ //filter and sort are commutative
+ output = sortDataRow(arrayUtility.filter(array, filterAlgo, predicate), lastColumnSort);
+ scope.numberOfPages = calculateNumberOfPages(output);
+ return scope.isPaginationEnabled ? arrayUtility.fromTo(output, (scope.currentPage - 1) * scope.itemsByPage, scope.itemsByPage) : output;
+ };
+
+ /*////////////
+ Column API
+ ///////////*/
+
+
+ /**
+ * insert a new column in scope.collection at index or push at the end if no index
+ * @param columnConfig column configuration used to instantiate the new Column
+ * @param index where to insert the column (at the end if not specified)
+ */
+ this.insertColumn = function (columnConfig, index) {
+ var column = new Column(columnConfig);
+ arrayUtility.insertAt(scope.columns, index, column);
+ };
+
+ /**
+ * remove the column at columnIndex from scope.columns
+ * @param columnIndex index of the column to be removed
+ */
+ this.removeColumn = function (columnIndex) {
+ arrayUtility.removeAt(scope.columns, columnIndex);
+ };
+
+ /**
+ * move column located at oldIndex to the newIndex in scope.columns
+ * @param oldIndex index of the column before it is moved
+ * @param newIndex index of the column after the column is moved
+ */
+ this.moveColumn = function (oldIndex, newIndex) {
+ arrayUtility.moveAt(scope.columns, oldIndex, newIndex);
+ };
+
+ /**
+ * remove all columns
+ */
+ this.clearColumns = function () {
+ scope.columns.length = 0;
+ };
+
+ /*///////////
+ ROW API
+ */
+
+ /**
+ * select or unselect the item of the displayedCollection with the selection mode set in the scope
+ * @param dataRow
+ */
+ this.toggleSelection = function (dataRow) {
+ var index = scope.dataCollection.indexOf(dataRow);
+ if (index !== -1) {
+ selectDataRow(scope.dataCollection, scope.selectionMode, index, dataRow.isSelected !== true);
+ }
+ };
+
+ /**
+ * select/unselect all the currently displayed rows
+ * @param value if true select, else unselect
+ */
+ this.toggleSelectionAll = function (value) {
+ var i = 0,
+ l = scope.displayedCollection.length;
+
+ if (scope.selectionMode !== 'multiple') {
+ return;
+ }
+ for (; i < l; i++) {
+ selectDataRow(scope.displayedCollection, scope.selectionMode, i, value === true);
+ }
+ };
+
+ /**
+ * remove the item at index rowIndex from the displayed collection
+ * @param rowIndex
+ * @returns {*} item just removed or undefined
+ */
+ this.removeDataRow = function (rowIndex) {
+ var toRemove = arrayUtility.removeAt(scope.displayedCollection, rowIndex);
+ arrayUtility.removeAt(scope.dataCollection, scope.dataCollection.indexOf(toRemove));
+ };
+
+ /**
+ * move an item from oldIndex to newIndex in displayedCollection
+ * @param oldIndex
+ * @param newIndex
+ */
+ this.moveDataRow = function (oldIndex, newIndex) {
+ arrayUtility.moveAt(scope.displayedCollection, oldIndex, newIndex);
+ };
+
+ /**
+ * update the model, it can be a non existing yet property
+ * @param dataRow the dataRow to update
+ * @param propertyName the property on the dataRow ojbect to update
+ * @param newValue the value to set
+ */
+ this.updateDataRow = function (dataRow, propertyName, newValue) {
+ var index = scope.displayedCollection.indexOf(dataRow),
+ getter = parse(propertyName),
+ setter = getter.assign,
+ oldValue;
+ if (index !== -1) {
+ oldValue = getter(scope.displayedCollection[index]);
+ if (oldValue !== newValue) {
+ setter(scope.displayedCollection[index], newValue);
+ scope.$emit('updateDataRow', {item: scope.displayedCollection[index]});
+ }
+ }
+ };
+ }]);
+})(angular);
+
+
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Template.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Template.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Template.js
new file mode 100644
index 0000000..34be956
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Template.js
@@ -0,0 +1,81 @@
+angular.module('smartTable.templates', ['partials/defaultCell.html', 'partials/defaultHeader.html', 'partials/editableCell.html', 'partials/globalSearchCell.html', 'partials/pagination.html', 'partials/selectAllCheckbox.html', 'partials/selectionCheckbox.html', 'partials/smartTable.html']);
+
+angular.module("partials/defaultCell.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/defaultCell.html",
+ "{{formatedValue}}");
+}]);
+
+angular.module("partials/defaultHeader.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/defaultHeader.html",
+ "<span class=\"header-content\" ng-class=\"{'sort-ascent':column.reverse==false,'sort-descent':column.reverse==true}\">{{column.label}}</span>");
+}]);
+
+angular.module("partials/editableCell.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/editableCell.html",
+ "<div ng-dblclick=\"isEditMode || toggleEditMode($event)\">\n" +
+ " <span ng-hide=\"isEditMode\">{{value | format:column.formatFunction:column.formatParameter}}</span>\n" +
+ "\n" +
+ " <form ng-submit=\"submit()\" ng-show=\"isEditMode\" name=\"myForm\">\n" +
+ " <input name=\"myInput\" ng-model=\"value\" type=\"type\" input-type/>\n" +
+ " </form>\n" +
+ "</div>");
+}]);
+
+angular.module("partials/globalSearchCell.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/globalSearchCell.html",
+ "<label>Search :</label>\n" +
+ "<input type=\"text\" ng-model=\"searchValue\"/>");
+}]);
+
+angular.module("partials/pagination.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/pagination.html",
+ "<div class=\"pagination\">\n" +
+ " <ul class=\"pagination\">\n" +
+ " <li ng-repeat=\"page in pages\" ng-class=\"{active: page.active, disabled: page.disabled}\"><a\n" +
+ " ng-click=\"selectPage(page.number)\">{{page.text}}</a></li>\n" +
+ " </ul>\n" +
+ "</div> ");
+}]);
+
+angular.module("partials/selectAllCheckbox.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/selectAllCheckbox.html",
+ "<input class=\"smart-table-select-all\" type=\"checkbox\" ng-model=\"holder.isAllSelected\"/>");
+}]);
+
+angular.module("partials/selectionCheckbox.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/selectionCheckbox.html",
+ "<input type=\"checkbox\" ng-model=\"dataRow.isSelected\" stop-event=\"click\"/>");
+}]);
+
+angular.module("partials/smartTable.html", []).run(["$templateCache", function($templateCache) {
+ $templateCache.put("partials/smartTable.html",
+ "<table class=\"smart-table\">\n" +
+ " <thead>\n" +
+ " <tr class=\"smart-table-global-search-row\" ng-show=\"isGlobalSearchActivated\">\n" +
+ " <td class=\"smart-table-global-search\" column-span=\"{{columns.length}}\" colspan=\"{{columnSpan}}\">\n" +
+ " </td>\n" +
+ " </tr>\n" +
+ " <tr class=\"smart-table-header-row\">\n" +
+ " <th ng-repeat=\"column in columns\" ng-include=\"column.headerTemplateUrl\"\n" +
+ " class=\"smart-table-header-cell {{column.headerClass}}\" scope=\"col\">\n" +
+ " </th>\n" +
+ " </tr>\n" +
+ " </thead>\n" +
+ " <tbody>\n" +
+ " <tr ng-repeat=\"dataRow in displayedCollection\" ng-class=\"{selected:dataRow.isSelected}\"\n" +
+ " class=\"smart-table-data-row\">\n" +
+ " <td ng-repeat=\"column in columns\" class=\"smart-table-data-cell {{column.cellClass}}\"></td>\n" +
+ " </tr>\n" +
+ " </tbody>\n" +
+ " <tfoot ng-show=\"isPaginationEnabled\">\n" +
+ " <tr class=\"smart-table-footer-row\">\n" +
+ " <td colspan=\"{{columns.length}}\">\n" +
+ " <div pagination-smart-table=\"\" num-pages=\"numberOfPages\" max-size=\"maxSize\" current-page=\"currentPage\"></div>\n" +
+ " </td>\n" +
+ " </tr>\n" +
+ " </tfoot>\n" +
+ "</table>\n" +
+ "\n" +
+ "\n" +
+ "");
+}]);
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/TemplateUrlList.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/TemplateUrlList.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/TemplateUrlList.js
new file mode 100644
index 0000000..c418e3b
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/TemplateUrlList.js
@@ -0,0 +1,14 @@
+(function (angular) {
+ "use strict";
+ angular.module('smartTable.templateUrlList', [])
+ .constant('templateUrlList', {
+ smartTable: 'partials/smartTable.html',
+ smartTableGlobalSearch: 'partials/globalSearchCell.html',
+ editableCell: 'partials/editableCell.html',
+ selectionCheckbox: 'partials/selectionCheckbox.html',
+ selectAllCheckbox: 'partials/selectAllCheckbox.html',
+ defaultHeader: 'partials/defaultHeader.html',
+ pagination: 'partials/pagination.html'
+ });
+})(angular);
+
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Utilities.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Utilities.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Utilities.js
new file mode 100644
index 0000000..d6f156d
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/Utilities.js
@@ -0,0 +1,120 @@
+(function (angular) {
+ "use strict";
+ angular.module('smartTable.utilities', [])
+
+ .factory('ArrayUtility', function () {
+
+ /**
+ * remove the item at index from arrayRef and return the removed item
+ * @param arrayRef
+ * @param index
+ * @returns {*}
+ */
+ var removeAt = function (arrayRef, index) {
+ if (index >= 0 && index < arrayRef.length) {
+ return arrayRef.splice(index, 1)[0];
+ }
+ },
+
+ /**
+ * insert item in arrayRef at index or a the end if index is wrong
+ * @param arrayRef
+ * @param index
+ * @param item
+ */
+ insertAt = function (arrayRef, index, item) {
+ if (index >= 0 && index < arrayRef.length) {
+ arrayRef.splice(index, 0, item);
+ } else {
+ arrayRef.push(item);
+ }
+ },
+
+ /**
+ * move the item at oldIndex to newIndex in arrayRef
+ * @param arrayRef
+ * @param oldIndex
+ * @param newIndex
+ */
+ moveAt = function (arrayRef, oldIndex, newIndex) {
+ var elementToMove;
+ if (oldIndex >= 0 && oldIndex < arrayRef.length && newIndex >= 0 && newIndex < arrayRef.length) {
+ elementToMove = arrayRef.splice(oldIndex, 1)[0];
+ arrayRef.splice(newIndex, 0, elementToMove);
+ }
+ },
+
+ /**
+ * sort arrayRef according to sortAlgorithm following predicate and reverse
+ * @param arrayRef
+ * @param sortAlgorithm
+ * @param predicate
+ * @param reverse
+ * @returns {*}
+ */
+ sort = function (arrayRef, sortAlgorithm, predicate, reverse) {
+
+ if (!sortAlgorithm || !angular.isFunction(sortAlgorithm)) {
+ return arrayRef;
+ } else {
+ return sortAlgorithm(arrayRef, predicate, reverse === true);//excpet if reverse is true it will take it as false
+ }
+ },
+
+ /**
+ * filter arrayRef according with filterAlgorithm and predicate
+ * @param arrayRef
+ * @param filterAlgorithm
+ * @param predicate
+ * @returns {*}
+ */
+ filter = function (arrayRef, filterAlgorithm, predicate) {
+ if (!filterAlgorithm || !angular.isFunction(filterAlgorithm)) {
+ return arrayRef;
+ } else {
+ return filterAlgorithm(arrayRef, predicate);
+ }
+ },
+
+ /**
+ * return an array, part of array ref starting at min and the size of length
+ * @param arrayRef
+ * @param min
+ * @param length
+ * @returns {*}
+ */
+ fromTo = function (arrayRef, min, length) {
+
+ var out = [],
+ limit,
+ start;
+
+ if (!angular.isArray(arrayRef)) {
+ return arrayRef;
+ }
+
+ start = Math.max(min, 0);
+ start = Math.min(start, (arrayRef.length - 1) > 0 ? arrayRef.length - 1 : 0);
+
+ length = Math.max(0, length);
+ limit = Math.min(start + length, arrayRef.length);
+
+ for (var i = start; i < limit; i++) {
+ out.push(arrayRef[i]);
+ }
+ return out;
+ };
+
+
+ return {
+ removeAt: removeAt,
+ insertAt: insertAt,
+ moveAt: moveAt,
+ sort: sort,
+ filter: filter,
+ fromTo: fromTo
+ };
+ });
+})(angular);
+
+
http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/3a992e2c/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/ui-bootstrap-custom-tpls-0.4.0-SNAPSHOT.js
----------------------------------------------------------------------
diff --git a/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/ui-bootstrap-custom-tpls-0.4.0-SNAPSHOT.js b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/ui-bootstrap-custom-tpls-0.4.0-SNAPSHOT.js
new file mode 100644
index 0000000..ac89dac
--- /dev/null
+++ b/3rdparty/javascript/bower_components/smart-table/smart-table-module/js/ui-bootstrap-custom-tpls-0.4.0-SNAPSHOT.js
@@ -0,0 +1,111 @@
+(function (angular) {
+ angular.module('ui.bootstrap.pagination.smartTable', ['smartTable.templateUrlList'])
+
+ .constant('paginationConfig', {
+ boundaryLinks: false,
+ directionLinks: true,
+ firstText: 'First',
+ previousText: '<',
+ nextText: '>',
+ lastText: 'Last'
+ })
+
+ .directive('paginationSmartTable', ['paginationConfig', 'templateUrlList', function (paginationConfig, templateUrlList) {
+ return {
+ restrict: 'EA',
+ require: '^smartTable',
+ scope: {
+ numPages: '=',
+ currentPage: '=',
+ maxSize: '='
+ },
+ templateUrl: templateUrlList.pagination,
+ replace: true,
+ link: function (scope, element, attrs, ctrl) {
+
+ // Setup configuration parameters
+ var boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks;
+ var directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$eval(attrs.directionLinks) : paginationConfig.directionLinks;
+ var firstText = angular.isDefined(attrs.firstText) ? attrs.firstText : paginationConfig.firstText;
+ var previousText = angular.isDefined(attrs.previousText) ? attrs.previousText : paginationConfig.previousText;
+ var nextText = angular.isDefined(attrs.nextText) ? attrs.nextText : paginationConfig.nextText;
+ var lastText = angular.isDefined(attrs.lastText) ? attrs.lastText : paginationConfig.lastText;
+
+ // Create page object used in template
+ function makePage(number, text, isActive, isDisabled) {
+ return {
+ number: number,
+ text: text,
+ active: isActive,
+ disabled: isDisabled
+ };
+ }
+
+ scope.$watch('numPages + currentPage + maxSize', function () {
+ scope.pages = [];
+
+ // Default page limits
+ var startPage = 1, endPage = scope.numPages;
+
+ // recompute if maxSize
+ if (scope.maxSize && scope.maxSize < scope.numPages) {
+ startPage = Math.max(scope.currentPage - Math.floor(scope.maxSize / 2), 1);
+ endPage = startPage + scope.maxSize - 1;
+
+ // Adjust if limit is exceeded
+ if (endPage > scope.numPages) {
+ endPage = scope.numPages;
+ startPage = endPage - scope.maxSize + 1;
+ }
+ }
+
+ // Add page number links
+ for (var number = startPage; number <= endPage; number++) {
+ var page = makePage(number, number, scope.isActive(number), false);
+ scope.pages.push(page);
+ }
+
+ // Add previous & next links
+ if (directionLinks) {
+ var previousPage = makePage(scope.currentPage - 1, previousText, false, scope.noPrevious());
+ scope.pages.unshift(previousPage);
+
+ var nextPage = makePage(scope.currentPage + 1, nextText, false, scope.noNext());
+ scope.pages.push(nextPage);
+ }
+
+ // Add first & last links
+ if (boundaryLinks) {
+ var firstPage = makePage(1, firstText, false, scope.noPrevious());
+ scope.pages.unshift(firstPage);
+
+ var lastPage = makePage(scope.numPages, lastText, false, scope.noNext());
+ scope.pages.push(lastPage);
+ }
+
+
+ if (scope.currentPage > scope.numPages) {
+ scope.selectPage(scope.numPages);
+ }
+ });
+ scope.noPrevious = function () {
+ return scope.currentPage === 1;
+ };
+ scope.noNext = function () {
+ return scope.currentPage === scope.numPages;
+ };
+ scope.isActive = function (page) {
+ return scope.currentPage === page;
+ };
+
+ scope.selectPage = function (page) {
+ if (!scope.isActive(page) && page > 0 && page <= scope.numPages) {
+ scope.currentPage = page;
+ ctrl.changePage({ page: page });
+ }
+ };
+ }
+ };
+ }]);
+})(angular);
+