From 1a405e56f5aa4442c2bdbb41a233fc13b6a101a3 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Mon, 3 Nov 2014 11:18:52 +0100 Subject: [PATCH] replace moment.js with bower version * fix JS unit tests --- bower.json | 1 + core/js/core.json | 6 +- core/vendor/.gitignore | 8 + core/vendor/moment/LICENSE | 22 +++ .../moment/min/moment-with-locales.js} | 177 +++++++++++++----- lib/base.php | 2 +- tests/karma.config.js | 7 + 7 files changed, 168 insertions(+), 55 deletions(-) create mode 100644 core/vendor/.gitignore create mode 100644 core/vendor/moment/LICENSE rename core/{js/moment.js => vendor/moment/min/moment-with-locales.js} (98%) diff --git a/bower.json b/bower.json index 3a6d8d73663..5476115be1d 100644 --- a/bower.json +++ b/bower.json @@ -13,5 +13,6 @@ "tests" ], "dependencies": { + "moment": "~2.8.3" } } diff --git a/core/js/core.json b/core/js/core.json index e2da1402888..3297b44318d 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -1,4 +1,7 @@ { + "vendor": [ + "moment/min/moment-with-locales.js" + ], "libraries": [ "jquery-1.10.0.min.js", "jquery-migrate-1.2.1.min.js", @@ -19,7 +22,6 @@ "eventsource.js", "config.js", "multiselect.js", - "oc-requesttoken.js", - "moment.js" + "oc-requesttoken.js" ] } diff --git a/core/vendor/.gitignore b/core/vendor/.gitignore new file mode 100644 index 00000000000..8d4f4fbe84d --- /dev/null +++ b/core/vendor/.gitignore @@ -0,0 +1,8 @@ +# momentjs - ignore all files except the two listed below +moment/benchmarks +moment/locale +moment/min/** +moment/*.js* +moment/*.md +!moment/LICENSE +!moment/min/moment-with-locales.js diff --git a/core/vendor/moment/LICENSE b/core/vendor/moment/LICENSE new file mode 100644 index 00000000000..bd172467a6b --- /dev/null +++ b/core/vendor/moment/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2011-2014 Tim Wood, Iskren Chernev, Moment.js contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/core/js/moment.js b/core/vendor/moment/min/moment-with-locales.js similarity index 98% rename from core/js/moment.js rename to core/vendor/moment/min/moment-with-locales.js index 6f1dcc5dfab..23d06ef3551 100644 --- a/core/js/moment.js +++ b/core/vendor/moment/min/moment-with-locales.js @@ -1,5 +1,5 @@ //! moment.js -//! version : 2.8.2 +//! version : 2.8.3 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com @@ -10,7 +10,7 @@ ************************************/ var moment, - VERSION = '2.8.2', + VERSION = '2.8.3', // the global-scope this is NOT the global object in Node.js globalScope = typeof global !== 'undefined' ? global : this, oldGlobalMoment, @@ -1493,6 +1493,9 @@ for (i = 0; i < config._f.length; i++) { currentScore = 0; tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } tempConfig._pf = defaultParsingFlags(); tempConfig._f = config._f[i]; makeDateFromStringAndFormat(tempConfig); @@ -1557,6 +1560,14 @@ } } + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + function makeDateFromInput(config) { var input = config._i, matched; if (input === undefined) { @@ -1568,7 +1579,9 @@ } else if (typeof input === 'string') { makeDateFromString(config); } else if (isArray(input)) { - config._a = input.slice(0); + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); dateFromConfig(config); } else if (typeof(input) === 'object') { dateFromObject(config); @@ -2123,7 +2136,7 @@ this._isUTC = false; if (keepLocalTime) { - this.add(this._d.getTimezoneOffset(), 'm'); + this.add(this._dateTzOffset(), 'm'); } } return this; @@ -2141,7 +2154,7 @@ diff : function (input, units, asFloat) { var that = makeAs(input, this), zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output; + diff, output, daysAdjust; units = normalizeUnits(units); @@ -2152,11 +2165,12 @@ output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); // adjust by taking difference in days, average number of days // and dst in the given months. - output += ((this - moment(this).startOf('month')) - - (that - moment(that).startOf('month'))) / diff; + daysAdjust = (this - moment(this).startOf('month')) - + (that - moment(that).startOf('month')); // same as above but with zones, to negate all dst - output -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; + daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) - + (that.zone() - moment(that).startOf('month').zone())) * 6e4; + output += daysAdjust / diff; if (units === 'year') { output = output / 12; } @@ -2265,18 +2279,33 @@ }, isAfter: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) > +moment(input).startOf(units); + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this > +input; + } else { + return +this.clone().startOf(units) > +moment(input).startOf(units); + } }, isBefore: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) < +moment(input).startOf(units); + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this < +input; + } else { + return +this.clone().startOf(units) < +moment(input).startOf(units); + } }, isSame: function (input, units) { - units = units || 'ms'; - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this === +input; + } else { + return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); + } }, min: deprecate( @@ -2316,7 +2345,7 @@ input = input * 60; } if (!this._isUTC && keepLocalTime) { - localAdjust = this._d.getTimezoneOffset(); + localAdjust = this._dateTzOffset(); } this._offset = input; this._isUTC = true; @@ -2334,7 +2363,7 @@ } } } else { - return this._isUTC ? offset : this._d.getTimezoneOffset(); + return this._isUTC ? offset : this._dateTzOffset(); } return this; }, @@ -2438,10 +2467,15 @@ // instance. Otherwise, it will return the locale configuration // variables for this instance. locale : function (key) { + var newLocaleData; + if (key === undefined) { return this._locale._abbr; } else { - this._locale = moment.localeData(key); + newLocaleData = moment.localeData(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } return this; } }, @@ -2452,14 +2486,19 @@ if (key === undefined) { return this.localeData(); } else { - this._locale = moment.localeData(key); - return this; + return this.locale(key); } } ), localeData : function () { return this._locale; + }, + + _dateTzOffset : function () { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return Math.round(this._d.getTimezoneOffset() / 15) * 15; } }); @@ -2657,19 +2696,21 @@ var days, months; units = normalizeUnits(units); - days = this._days + this._milliseconds / 864e5; if (units === 'month' || units === 'year') { + days = this._days + this._milliseconds / 864e5; months = this._months + daysToYears(days) * 12; return units === 'month' ? months : months / 12; } else { - days += yearsToDays(this._months / 12); + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + yearsToDays(this._months / 12); switch (units) { - case 'week': return days / 7; - case 'day': return days; - case 'hour': return days * 24; - case 'minute': return days * 24 * 60; - case 'second': return days * 24 * 60 * 60; - case 'millisecond': return days * 24 * 60 * 60 * 1000; + case 'week': return days / 7 + this._milliseconds / 6048e5; + case 'day': return days + this._milliseconds / 864e5; + case 'hour': return days * 24 + this._milliseconds / 36e5; + case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; + case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; default: throw new Error('Unknown unit ' + units); } } @@ -2973,9 +3014,10 @@ }); })); // moment.js locale configuration -// locale : Arabic (ar) -// author : Abdel Said : https://github.com/abdelsaid -// changes in months, weekdays : Ahmed Elkhatib +// Locale: Arabic (ar) +// Author: Abdel Said: https://github.com/abdelsaid +// Changes in months, weekdays: Ahmed Elkhatib +// Native plural forms: forabi https://github.com/forabi (function (factory) { factory(moment); @@ -3002,11 +3044,42 @@ '٨': '8', '٩': '9', '٠': '0' - }; + }, pluralForm = function (n) { + return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5; + }, plurals = { + s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'], + m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'], + h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'], + d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'], + M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'], + y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام'] + }, pluralize = function (u) { + return function (number, withoutSuffix, string, isFuture) { + var f = pluralForm(number), + str = plurals[u][pluralForm(number)]; + if (f === 2) { + str = str[withoutSuffix ? 0 : 1]; + } + return str.replace(/%d/i, number); + }; + }, months = [ + 'كانون الثاني يناير', + 'شباط فبراير', + 'آذار مارس', + 'نيسان أبريل', + 'أيار مايو', + 'حزيران يونيو', + 'تموز يوليو', + 'آب أغسطس', + 'أيلول سبتمبر', + 'تشرين الأول أكتوبر', + 'تشرين الثاني نوفمبر', + 'كانون الأول ديسمبر' + ]; return moment.defineLocale('ar', { - months : 'يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول'.split('_'), - monthsShort : 'يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول'.split('_'), + months : months, + monthsShort : months, weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'), weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'), weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'), @@ -3025,27 +3098,27 @@ } }, calendar : { - sameDay: '[اليوم على الساعة] LT', - nextDay: '[غدا على الساعة] LT', - nextWeek: 'dddd [على الساعة] LT', - lastDay: '[أمس على الساعة] LT', - lastWeek: 'dddd [على الساعة] LT', + sameDay: '[اليوم عند الساعة] LT', + nextDay: '[غدًا عند الساعة] LT', + nextWeek: 'dddd [عند الساعة] LT', + lastDay: '[أمس عند الساعة] LT', + lastWeek: 'dddd [عند الساعة] LT', sameElse: 'L' }, relativeTime : { - future : 'في %s', + future : 'بعد %s', past : 'منذ %s', - s : 'ثوان', - m : 'دقيقة', - mm : '%d دقائق', - h : 'ساعة', - hh : '%d ساعات', - d : 'يوم', - dd : '%d أيام', - M : 'شهر', - MM : '%d أشهر', - y : 'سنة', - yy : '%d سنوات' + s : pluralize('s'), + m : pluralize('m'), + mm : pluralize('m'), + h : pluralize('h'), + hh : pluralize('h'), + d : pluralize('d'), + dd : pluralize('d'), + M : pluralize('M'), + MM : pluralize('M'), + y : pluralize('y'), + yy : pluralize('y') }, preparse: function (string) { return string.replace(/[۰-۹]/g, function (match) { @@ -3954,7 +4027,7 @@ weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'), weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'), longDateFormat : { - LT: 'H.mm', + LT: 'H:mm', L : 'DD. MM. YYYY', LL : 'D. MMMM YYYY', LLL : 'D. MMMM YYYY LT', diff --git a/lib/base.php b/lib/base.php index 7fa53c3a074..11c5167786d 100644 --- a/lib/base.php +++ b/lib/base.php @@ -348,7 +348,7 @@ class OC { OC_Util::addScript("oc-requesttoken"); OC_Util::addScript("apps"); OC_Util::addScript("snap"); - OC_Util::addScript("moment"); + OC_Util::addVendorScript('moment/min/moment-with-locales'); // avatars if (\OC_Config::getValue('enable_avatars', true) === true) { diff --git a/tests/karma.config.js b/tests/karma.config.js index 357fcf3f122..f67fa9977c2 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -99,6 +99,7 @@ module.exports = function(config) { // note that the loading order is important that's why they // are specified in a separate file var corePath = 'core/js/'; + var vendorPath = 'core/vendor/'; var coreModule = require('../' + corePath + 'core.json'); var testCore = false; var files = []; @@ -134,6 +135,12 @@ module.exports = function(config) { } } + // add vendor library files + for ( i = 0; i < coreModule.vendor.length; i++ ) { + srcFile = vendorPath + coreModule.vendor[i]; + files.push(srcFile); + } + // TODO: settings pages // need to test the core app as well ? -- 2.39.5