1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2024-12-11 22:24:21 +01:00
fab-manager/vendor/assets/components/angular-moment/angular-moment.js
2016-03-23 18:39:41 +01:00

633 lines
19 KiB
JavaScript

/* angular-moment.js / v0.10.3 / (c) 2013, 2014, 2015 Uri Shaked / MIT Licence */
'format amd';
/* global define */
(function () {
'use strict';
function angularMoment(angular, moment) {
/**
* @ngdoc overview
* @name angularMoment
*
* @description
* angularMoment module provides moment.js functionality for angular.js apps.
*/
return angular.module('angularMoment', [])
/**
* @ngdoc object
* @name angularMoment.config:angularMomentConfig
*
* @description
* Common configuration of the angularMoment module
*/
.constant('angularMomentConfig', {
/**
* @ngdoc property
* @name angularMoment.config.angularMomentConfig#preprocess
* @propertyOf angularMoment.config:angularMomentConfig
* @returns {string} The default preprocessor to apply
*
* @description
* Defines a default preprocessor to apply (e.g. 'unix', 'etc', ...). The default value is null,
* i.e. no preprocessor will be applied.
*/
preprocess: null, // e.g. 'unix', 'utc', ...
/**
* @ngdoc property
* @name angularMoment.config.angularMomentConfig#timezone
* @propertyOf angularMoment.config:angularMomentConfig
* @returns {string} The default timezone
*
* @description
* The default timezone (e.g. 'Europe/London'). Empty string by default (does not apply
* any timezone shift).
*/
timezone: '',
/**
* @ngdoc property
* @name angularMoment.config.angularMomentConfig#format
* @propertyOf angularMoment.config:angularMomentConfig
* @returns {string} The pre-conversion format of the date
*
* @description
* Specify the format of the input date. Essentially it's a
* default and saves you from specifying a format in every
* element. Overridden by element attr. Null by default.
*/
format: null,
/**
* @ngdoc property
* @name angularMoment.config.angularMomentConfig#statefulFilters
* @propertyOf angularMoment.config:angularMomentConfig
* @returns {boolean} Whether angular-moment filters should be stateless (or not)
*
* @description
* Specifies whether the filters included with angular-moment are stateful.
* Stateful filters will automatically re-evaluate whenever you change the timezone
* or language settings, but may negatively impact performance. true by default.
*/
statefulFilters: true
})
/**
* @ngdoc object
* @name angularMoment.object:moment
*
* @description
* moment global (as provided by the moment.js library)
*/
.constant('moment', moment)
/**
* @ngdoc object
* @name angularMoment.config:amTimeAgoConfig
* @module angularMoment
*
* @description
* configuration specific to the amTimeAgo directive
*/
.constant('amTimeAgoConfig', {
/**
* @ngdoc property
* @name angularMoment.config.amTimeAgoConfig#withoutSuffix
* @propertyOf angularMoment.config:amTimeAgoConfig
* @returns {boolean} Whether to include a suffix in am-time-ago directive
*
* @description
* Defaults to false.
*/
withoutSuffix: false,
/**
* @ngdoc property
* @name angularMoment.config.amTimeAgoConfig#serverTime
* @propertyOf angularMoment.config:amTimeAgoConfig
* @returns {number} Server time in milliseconds since the epoch
*
* @description
* If set, time ago will be calculated relative to the given value.
* If null, local time will be used. Defaults to null.
*/
serverTime: null,
/**
* @ngdoc property
* @name angularMoment.config.amTimeAgoConfig#titleFormat
* @propertyOf angularMoment.config:amTimeAgoConfig
* @returns {string} The format of the date to be displayed in the title of the element. If null,
* the directive set the title of the element.
*
* @description
* The format of the date used for the title of the element. null by default.
*/
titleFormat: null,
/**
* @ngdoc property
* @name angularMoment.config.amTimeAgoConfig#fullDateThreshold
* @propertyOf angularMoment.config:amTimeAgoConfig
* @returns {number} The minimum number of days for showing a full date instead of relative time
*
* @description
* The threshold for displaying a full date. The default is null, which means the date will always
* be relative, and full date will never be displayed.
*/
fullDateThreshold: null,
/**
* @ngdoc property
* @name angularMoment.config.amTimeAgoConfig#fullDateFormat
* @propertyOf angularMoment.config:amTimeAgoConfig
* @returns {string} The format to use when displaying a full date.
*
* @description
* Specify the format of the date when displayed as full date. null by default.
*/
fullDateFormat: null
})
/**
* @ngdoc directive
* @name angularMoment.directive:amTimeAgo
* @module angularMoment
*
* @restrict A
*/
.directive('amTimeAgo', ['$window', 'moment', 'amMoment', 'amTimeAgoConfig', 'angularMomentConfig', function ($window, moment, amMoment, amTimeAgoConfig, angularMomentConfig) {
return function (scope, element, attr) {
var activeTimeout = null;
var currentValue;
var currentFormat = angularMomentConfig.format;
var withoutSuffix = amTimeAgoConfig.withoutSuffix;
var titleFormat = amTimeAgoConfig.titleFormat;
var fullDateThreshold = amTimeAgoConfig.fullDateThreshold;
var fullDateFormat = amTimeAgoConfig.fullDateFormat;
var localDate = new Date().getTime();
var preprocess = angularMomentConfig.preprocess;
var modelName = attr.amTimeAgo;
var currentFrom;
var isTimeElement = ('TIME' === element[0].nodeName.toUpperCase());
function getNow() {
var now;
if (currentFrom) {
now = currentFrom;
} else if (amTimeAgoConfig.serverTime) {
var localNow = new Date().getTime();
var nowMillis = localNow - localDate + amTimeAgoConfig.serverTime;
now = moment(nowMillis);
}
else {
now = moment();
}
return now;
}
function cancelTimer() {
if (activeTimeout) {
$window.clearTimeout(activeTimeout);
activeTimeout = null;
}
}
function updateTime(momentInstance) {
var daysAgo = getNow().diff(momentInstance, 'day');
var showFullDate = fullDateThreshold && daysAgo >= fullDateThreshold;
if (showFullDate) {
element.text(momentInstance.format(fullDateFormat));
} else {
element.text(momentInstance.from(getNow(), withoutSuffix));
}
if (titleFormat && !element.attr('title')) {
element.attr('title', momentInstance.local().format(titleFormat));
}
if (!showFullDate) {
var howOld = Math.abs(getNow().diff(momentInstance, 'minute'));
var secondsUntilUpdate = 3600;
if (howOld < 1) {
secondsUntilUpdate = 1;
} else if (howOld < 60) {
secondsUntilUpdate = 30;
} else if (howOld < 180) {
secondsUntilUpdate = 300;
}
activeTimeout = $window.setTimeout(function () {
updateTime(momentInstance);
}, secondsUntilUpdate * 1000);
}
}
function updateDateTimeAttr(value) {
if (isTimeElement) {
element.attr('datetime', value);
}
}
function updateMoment() {
cancelTimer();
if (currentValue) {
var momentValue = amMoment.preprocessDate(currentValue, preprocess, currentFormat);
updateTime(momentValue);
updateDateTimeAttr(momentValue.toISOString());
}
}
scope.$watch(modelName, function (value) {
if ((typeof value === 'undefined') || (value === null) || (value === '')) {
cancelTimer();
if (currentValue) {
element.text('');
updateDateTimeAttr('');
currentValue = null;
}
return;
}
currentValue = value;
updateMoment();
});
if (angular.isDefined(attr.amFrom)) {
scope.$watch(attr.amFrom, function (value) {
if ((typeof value === 'undefined') || (value === null) || (value === '')) {
currentFrom = null;
} else {
currentFrom = moment(value);
}
updateMoment();
});
}
if (angular.isDefined(attr.amWithoutSuffix)) {
scope.$watch(attr.amWithoutSuffix, function (value) {
if (typeof value === 'boolean') {
withoutSuffix = value;
updateMoment();
} else {
withoutSuffix = amTimeAgoConfig.withoutSuffix;
}
});
}
attr.$observe('amFormat', function (format) {
if (typeof format !== 'undefined') {
currentFormat = format;
updateMoment();
}
});
attr.$observe('amPreprocess', function (newValue) {
preprocess = newValue;
updateMoment();
});
attr.$observe('amFullDateThreshold', function (newValue) {
fullDateThreshold = newValue;
updateMoment();
});
attr.$observe('amFullDateFormat', function (newValue) {
fullDateFormat = newValue;
updateMoment();
});
scope.$on('$destroy', function () {
cancelTimer();
});
scope.$on('amMoment:localeChanged', function () {
updateMoment();
});
};
}])
/**
* @ngdoc service
* @name angularMoment.service.amMoment
* @module angularMoment
*/
.service('amMoment', ['moment', '$rootScope', '$log', 'angularMomentConfig', function (moment, $rootScope, $log, angularMomentConfig) {
/**
* @ngdoc property
* @name angularMoment:amMoment#preprocessors
* @module angularMoment
*
* @description
* Defines the preprocessors for the preprocessDate method. By default, the following preprocessors
* are defined: utc, unix.
*/
this.preprocessors = {
utc: moment.utc,
unix: moment.unix
};
/**
* @ngdoc function
* @name angularMoment.service.amMoment#changeLocale
* @methodOf angularMoment.service.amMoment
*
* @description
* Changes the locale for moment.js and updates all the am-time-ago directive instances
* with the new locale. Also broadcasts an `amMoment:localeChanged` event on $rootScope.
*
* @param {string} locale Locale code (e.g. en, es, ru, pt-br, etc.)
* @param {object} customization object of locale strings to override
*/
this.changeLocale = function (locale, customization) {
var result = moment.locale(locale, customization);
if (angular.isDefined(locale)) {
$rootScope.$broadcast('amMoment:localeChanged');
}
return result;
};
/**
* @ngdoc function
* @name angularMoment.service.amMoment#changeTimezone
* @methodOf angularMoment.service.amMoment
*
* @description
* Changes the default timezone for amCalendar, amDateFormat and amTimeAgo. Also broadcasts an
* `amMoment:timezoneChanged` event on $rootScope.
*
* @param {string} timezone Timezone name (e.g. UTC)
*/
this.changeTimezone = function (timezone) {
angularMomentConfig.timezone = timezone;
$rootScope.$broadcast('amMoment:timezoneChanged');
};
/**
* @ngdoc function
* @name angularMoment.service.amMoment#preprocessDate
* @methodOf angularMoment.service.amMoment
*
* @description
* Preprocess a given value and convert it into a Moment instance appropriate for use in the
* am-time-ago directive and the filters.
*
* @param {*} value The value to be preprocessed
* @param {string} preprocess The name of the preprocessor the apply (e.g. utc, unix)
* @param {string=} format Specifies how to parse the value (see {@link http://momentjs.com/docs/#/parsing/string-format/})
* @return {Moment} A value that can be parsed by the moment library
*/
this.preprocessDate = function (value, preprocess, format) {
if (angular.isUndefined(preprocess)) {
preprocess = angularMomentConfig.preprocess;
}
if (this.preprocessors[preprocess]) {
return this.preprocessors[preprocess](value, format);
}
if (preprocess) {
$log.warn('angular-moment: Ignoring unsupported value for preprocess: ' + preprocess);
}
if (!isNaN(parseFloat(value)) && isFinite(value)) {
// Milliseconds since the epoch
return moment(parseInt(value, 10));
}
// else just returns the value as-is.
return moment(value, format);
};
/**
* @ngdoc function
* @name angularMoment.service.amMoment#applyTimezone
* @methodOf angularMoment.service.amMoment
*
* @description
* Apply a timezone onto a given moment object. It can be a named timezone (e.g. 'America/Phoenix') or an offset from UTC (e.g. '+0300')
* moment-timezone.js is needed when a named timezone is used, otherwise, it'll not apply any timezone shift.
*
* @param {Moment} aMoment a moment() instance to apply the timezone shift to
* @param {string=} timezone The timezone to apply. If none given, will apply the timezone
* configured in angularMomentConfig.timezone. It can be a named timezone (e.g. 'America/Phoenix') or an offset from UTC (e.g. '+0300')
*
* @returns {Moment} The given moment with the timezone shift applied
*/
this.applyTimezone = function (aMoment, timezone) {
timezone = timezone || angularMomentConfig.timezone;
if (!timezone) {
return aMoment;
}
if (timezone.match(/^Z|[+-]\d\d:?\d\d$/i)) {
aMoment = aMoment.utcOffset(timezone);
} else if (aMoment.tz) {
aMoment = aMoment.tz(timezone);
} else {
$log.warn('angular-moment: named timezone specified but moment.tz() is undefined. Did you forget to include moment-timezone.js?');
}
return aMoment;
};
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amCalendar
* @module angularMoment
*/
.filter('amCalendar', ['moment', 'amMoment', 'angularMomentConfig', function (moment, amMoment, angularMomentConfig) {
function amCalendarFilter(value, preprocess, timezone) {
if (typeof value === 'undefined' || value === null) {
return '';
}
value = amMoment.preprocessDate(value, preprocess);
var date = moment(value);
if (!date.isValid()) {
return '';
}
return amMoment.applyTimezone(date, timezone).calendar();
}
// Since AngularJS 1.3, filters have to explicitly define being stateful
// (this is no longer the default).
amCalendarFilter.$stateful = angularMomentConfig.statefulFilters;
return amCalendarFilter;
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amDifference
* @module angularMoment
*/
.filter('amDifference', ['moment', 'amMoment', 'angularMomentConfig', function (moment, amMoment, angularMomentConfig) {
function amDifferenceFilter(value, otherValue, unit, usePrecision, preprocessValue, preprocessOtherValue) {
if (typeof value === 'undefined' || value === null) {
return '';
}
value = amMoment.preprocessDate(value, preprocessValue);
var date = moment(value);
if (!date.isValid()) {
return '';
}
var date2;
if (typeof otherValue === 'undefined' || otherValue === null) {
date2 = moment();
} else {
otherValue = amMoment.preprocessDate(otherValue, preprocessOtherValue);
date2 = moment(otherValue);
if (!date2.isValid()) {
return '';
}
}
return amMoment.applyTimezone(date).diff(amMoment.applyTimezone(date2), unit, usePrecision);
}
amDifferenceFilter.$stateful = angularMomentConfig.statefulFilters;
return amDifferenceFilter;
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amDateFormat
* @module angularMoment
* @function
*/
.filter('amDateFormat', ['moment', 'amMoment', 'angularMomentConfig', function (moment, amMoment, angularMomentConfig) {
function amDateFormatFilter(value, format, preprocess, timezone, inputFormat) {
var currentFormat = inputFormat || angularMomentConfig.format;
if (typeof value === 'undefined' || value === null) {
return '';
}
value = amMoment.preprocessDate(value, preprocess, currentFormat);
var date = moment(value);
if (!date.isValid()) {
return '';
}
return amMoment.applyTimezone(date, timezone).format(format);
}
amDateFormatFilter.$stateful = angularMomentConfig.statefulFilters;
return amDateFormatFilter;
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amDurationFormat
* @module angularMoment
* @function
*/
.filter('amDurationFormat', ['moment', 'angularMomentConfig', function (moment, angularMomentConfig) {
function amDurationFormatFilter(value, format, suffix) {
if (typeof value === 'undefined' || value === null) {
return '';
}
return moment.duration(value, format).humanize(suffix);
}
amDurationFormatFilter.$stateful = angularMomentConfig.statefulFilters;
return amDurationFormatFilter;
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amTimeAgo
* @module angularMoment
* @function
*/
.filter('amTimeAgo', ['moment', 'amMoment', 'angularMomentConfig', function (moment, amMoment, angularMomentConfig) {
function amTimeAgoFilter(value, preprocess, suffix, from) {
var date, dateFrom;
if (typeof value === 'undefined' || value === null) {
return '';
}
value = amMoment.preprocessDate(value, preprocess);
date = moment(value);
if (!date.isValid()) {
return '';
}
dateFrom = moment(from);
if (typeof from !== 'undefined' && dateFrom.isValid()) {
return amMoment.applyTimezone(date).from(dateFrom, suffix);
}
return amMoment.applyTimezone(date).fromNow(suffix);
}
amTimeAgoFilter.$stateful = angularMomentConfig.statefulFilters;
return amTimeAgoFilter;
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amSubtract
* @module angularMoment
* @function
*/
.filter('amSubtract', ['moment', 'angularMomentConfig', function (moment, angularMomentConfig) {
function amSubtractFilter(value, amount, type) {
if (typeof value === 'undefined' || value === null) {
return '';
}
return moment(value).subtract(parseInt(amount, 10), type);
}
amSubtractFilter.$stateful = angularMomentConfig.statefulFilters;
return amSubtractFilter;
}])
/**
* @ngdoc filter
* @name angularMoment.filter:amAdd
* @module angularMoment
* @function
*/
.filter('amAdd', ['moment', 'angularMomentConfig', function (moment, angularMomentConfig) {
function amAddFilter(value, amount, type) {
if (typeof value === 'undefined' || value === null) {
return '';
}
return moment(value).add(parseInt(amount, 10), type);
}
amAddFilter.$stateful = angularMomentConfig.statefulFilters;
return amAddFilter;
}]);
}
if (typeof define === 'function' && define.amd) {
define(['angular', 'moment'], angularMoment);
} else if (typeof module !== 'undefined' && module && module.exports) {
angularMoment(angular, require('moment'));
module.exports = 'angularMoment';
} else {
angularMoment(angular, (typeof global !== 'undefined' ? global : window).moment);
}
})();