Merge pull request #11916 from owncloud/introduce-bower

Introduce bower dependency managment for frontend libraries
This commit is contained in:
Morris Jobke 2014-11-04 11:59:33 +01:00
commit fde8ef0655
10 changed files with 264 additions and 73 deletions

3
.bowerrc Normal file
View File

@ -0,0 +1,3 @@
{
"directory": "core/vendor"
}

18
bower.json Normal file
View File

@ -0,0 +1,18 @@
{
"name": "ownCloud",
"version": "8.0 pre alpha",
"homepage": "https://www.owncloud.org",
"license": "AGPL",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"core/vendor",
"test",
"tests"
],
"dependencies": {
"moment": "~2.8.3"
}
}

View File

@ -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"
]
}

8
core/vendor/.gitignore vendored Normal file
View File

@ -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

22
core/vendor/moment/LICENSE vendored Normal file
View File

@ -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.

View File

@ -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',

View File

@ -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) {

View File

@ -39,6 +39,22 @@ function script($app, $file) {
}
}
/**
* Shortcut for adding vendor scripts to a page
* @param string $app the appname
* @param string|string[] $file the filename,
* if an array is given it will add all scripts
*/
function vendorScript($app, $file) {
if(is_array($file)) {
foreach($file as $f) {
OC_Util::addVendorScript($app, $f);
}
} else {
OC_Util::addVendorScript($app, $file);
}
}
/**
* Shortcut for adding styles to a page
* @param string $app the appname
@ -55,6 +71,22 @@ function style($app, $file) {
}
}
/**
* Shortcut for adding vendor styles to a page
* @param string $app the appname
* @param string|string[] $file the filename,
* if an array is given it will add all styles
*/
function vendorStyle($app, $file) {
if(is_array($file)) {
foreach($file as $f) {
OC_Util::addVendorStyle($app, $f);
}
} else {
OC_Util::addVendorStyle($app, $file);
}
}
/**
* Shortcut for adding translations to a page
* @param string $app the appname

View File

@ -330,6 +330,26 @@ class OC_Util {
}
}
/**
* generates a path for JS/CSS files. If no application is provided it will create the path for core.
*
* @param $application application to get the files from
* @param $directory directory withing this application (css, js, vendor, etc)
* @param $file the file inside of the above folder
* @return string the path
*/
private static function generatePath($application, $directory, $file) {
if (is_null($file)) {
$file = $application;
$application = "";
}
if (!empty($application)) {
return "$application/$directory/$file";
} else {
return "$directory/$file";
}
}
/**
* add a javascript file
*
@ -338,15 +358,18 @@ class OC_Util {
* @return void
*/
public static function addScript($application, $file = null) {
if (is_null($file)) {
$file = $application;
$application = "";
}
if (!empty($application)) {
self::$scripts[] = "$application/js/$file";
} else {
self::$scripts[] = "js/$file";
}
self::$scripts[] = OC_Util::generatePath($application, 'js', $file);
}
/**
* add a javascript file from the vendor sub folder
*
* @param string $application application id
* @param string|null $file filename
* @return void
*/
public static function addVendorScript($application, $file = null) {
self::$scripts[] = OC_Util::generatePath($application, 'vendor', $file);
}
/**
@ -375,15 +398,18 @@ class OC_Util {
* @return void
*/
public static function addStyle($application, $file = null) {
if (is_null($file)) {
$file = $application;
$application = "";
}
if (!empty($application)) {
self::$styles[] = "$application/css/$file";
} else {
self::$styles[] = "css/$file";
}
self::$styles[] = OC_Util::generatePath($application, 'css', $file);
}
/**
* add a css file from the vendor sub folder
*
* @param string $application application id
* @param string|null $file filename
* @return void
*/
public static function addVendorStyle($application, $file = null) {
self::$styles[] = OC_Util::generatePath($application, 'vendor', $file);
}
/**

View File

@ -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 ?