This repository was archived by the owner on Sep 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Expand file tree
/
Copy pathdateLocaleProvider.js
More file actions
331 lines (299 loc) · 12.9 KB
/
dateLocaleProvider.js
File metadata and controls
331 lines (299 loc) · 12.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
(function() {
'use strict';
/**
* @ngdoc service
* @name $mdDateLocaleProvider
* @module material.components.datepicker
*
* @description
* The `$mdDateLocaleProvider` is the provider that creates the `$mdDateLocale` service.
* This provider that allows the user to specify messages, formatters, and parsers for date
* internationalization. The `$mdDateLocale` service itself is consumed by AngularJS Material
* components that deal with dates
* (i.e. <a ng-href="api/directive/mdDatepicker">mdDatepicker</a>).
*
* @property {Array<string>} months Array of month names (in order).
* @property {Array<string>} shortMonths Array of abbreviated month names.
* @property {Array<string>} days Array of the days of the week (in order).
* @property {Array<string>} shortDays Array of abbreviated days of the week.
* @property {Array<string>} dates Array of dates of the month. Only necessary for locales
* using a numeral system other than [1, 2, 3...].
* @property {Array<string>} firstDayOfWeek The first day of the week. Sunday = 0, Monday = 1,
* etc.
* @property {function(string): Date} parseDate Function that converts a date string to a Date
* object (the date portion).
* @property {function(Date, string): string} formatDate Function to format a date object to a
* string. The datepicker directive also provides the time zone, if it was specified.
* @property {function(Date): string} monthHeaderFormatter Function that returns the label for
* a month given a date.
* @property {function(Date): string} monthFormatter Function that returns the full name of a month
* for a given date.
* @property {function(number): string} weekNumberFormatter Function that returns a label for
* a week given the week number.
* @property {function(Date): string} longDateFormatter Function that formats a date into a long
* `aria-label` that is read by the screen reader when the focused date changes.
* @property {string} msgCalendar Translation of the label "Calendar" for the current locale.
* @property {string} msgOpenCalendar Translation of the button label "Open calendar" for the
* current locale.
* @property {Date} firstRenderableDate The date from which the datepicker calendar will begin
* rendering. Note that this will be ignored if a minimum date is set.
* Defaults to January 1st 1880.
* @property {Date} lastRenderableDate The last date that will be rendered by the datepicker
* calendar. Note that this will be ignored if a maximum date is set.
* Defaults to January 1st 2130.
* @property {function(string): boolean} isDateComplete Function to determine whether a string
* makes sense to be parsed to a `Date` object. Returns `true` if the date appears to be complete
* and parsing should occur. By default, this checks for 3 groups of text or numbers separated
* by delimiters. This means that by default, date strings must include a month, day, and year
* to be parsed and for the model to be updated.
*
* @usage
* <hljs lang="js">
* myAppModule.config(function($mdDateLocaleProvider) {
*
* // Example of a French localization.
* $mdDateLocaleProvider.months = ['janvier', 'février', 'mars', ...];
* $mdDateLocaleProvider.shortMonths = ['janv', 'févr', 'mars', ...];
* $mdDateLocaleProvider.days = ['dimanche', 'lundi', 'mardi', ...];
* $mdDateLocaleProvider.shortDays = ['Di', 'Lu', 'Ma', ...];
*
* // Can change week display to start on Monday.
* $mdDateLocaleProvider.firstDayOfWeek = 1;
*
* // Optional.
* $mdDateLocaleProvider.dates = [1, 2, 3, 4, 5, 6, ...];
*
* // Example uses moment.js to parse and format dates.
* $mdDateLocaleProvider.parseDate = function(dateString) {
* var m = moment(dateString, 'L', true);
* return m.isValid() ? m.toDate() : new Date(NaN);
* };
*
* $mdDateLocaleProvider.formatDate = function(date) {
* var m = moment(date);
* return m.isValid() ? m.format('L') : '';
* };
*
* // Allow only a day and month to be specified.
* // This is required if using the 'M/D' format with moment.js.
* $mdDateLocaleProvider.isDateComplete = function(dateString) {
* dateString = dateString.trim();
*
* // Look for two chunks of content (either numbers or text) separated by delimiters.
* var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ .,]+|[/-]))([a-zA-Z]{3,}|[0-9]{1,4})/;
* return re.test(dateString);
* };
*
* $mdDateLocaleProvider.monthHeaderFormatter = function(date) {
* return myShortMonths[date.getMonth()] + ' ' + date.getFullYear();
* };
*
* // In addition to date display, date components also need localized messages
* // for aria-labels for screen-reader users.
*
* $mdDateLocaleProvider.weekNumberFormatter = function(weekNumber) {
* return 'Semaine ' + weekNumber;
* };
*
* $mdDateLocaleProvider.msgCalendar = 'Calendrier';
* $mdDateLocaleProvider.msgOpenCalendar = 'Ouvrir le calendrier';
*
* // You can also set when your calendar begins and ends.
* $mdDateLocaleProvider.firstRenderableDate = new Date(1776, 6, 4);
* $mdDateLocaleProvider.lastRenderableDate = new Date(2012, 11, 21);
* });
* </hljs>
*
*/
angular.module('material.components.datepicker').config(function($provide) {
// TODO(jelbourn): Assert provided values are correctly formatted. Need assertions.
/** @constructor */
function DateLocaleProvider() {
/** Array of full month names. E.g., ['January', 'February', ...] */
this.months = null;
/** Array of abbreviated month names. E.g., ['Jan', 'Feb', ...] */
this.shortMonths = null;
/** Array of full day of the week names. E.g., ['Monday', 'Tuesday', ...] */
this.days = null;
/** Array of abbreviated dat of the week names. E.g., ['M', 'T', ...] */
this.shortDays = null;
/** Array of dates of a month (1 - 31). Characters might be different in some locales. */
this.dates = null;
/** Index of the first day of the week. 0 = Sunday, 1 = Monday, etc. */
this.firstDayOfWeek = 0;
/**
* Function that converts the date portion of a Date to a string.
* @type {(function(Date): string)}
*/
this.formatDate = null;
/**
* Function that converts a date string to a Date object (the date portion)
* @type {function(string): Date}
*/
this.parseDate = null;
/**
* Function that formats a Date into a month header string.
* @type {function(Date): string}
*/
this.monthHeaderFormatter = null;
/**
* Function that formats a week number into a label for the week.
* @type {function(number): string}
*/
this.weekNumberFormatter = null;
/**
* Function that formats a date into a long aria-label that is read
* when the focused date changes.
* @type {function(Date): string}
*/
this.longDateFormatter = null;
/**
* Function to determine whether a string makes sense to be
* parsed to a Date object.
* @type {function(string): boolean}
*/
this.isDateComplete = null;
/**
* ARIA label for the calendar "dialog" used in the datepicker.
* @type {string}
*/
this.msgCalendar = '';
/**
* ARIA label for the datepicker's "Open calendar" buttons.
* @type {string}
*/
this.msgOpenCalendar = '';
}
/**
* Factory function that returns an instance of the dateLocale service.
* @ngInject
* @param $locale
* @param $filter
* @returns {DateLocale}
*/
DateLocaleProvider.prototype.$get = function($locale, $filter) {
/**
* Default date-to-string formatting function.
* @param {!Date} date
* @param {string=} timezone
* @returns {string}
*/
function defaultFormatDate(date, timezone) {
if (!date) {
return '';
}
// All of the dates created through ng-material *should* be set to midnight.
// If we encounter a date where the localeTime shows at 11pm instead of midnight,
// we have run into an issue with DST where we need to increment the hour by one:
// var d = new Date(1992, 9, 8, 0, 0, 0);
// d.toLocaleString(); // == "10/7/1992, 11:00:00 PM"
var localeTime = date.toLocaleTimeString();
var formatDate = date;
if (date.getHours() === 0 &&
(localeTime.indexOf('11:') !== -1 || localeTime.indexOf('23:') !== -1)) {
formatDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), 1, 0, 0);
}
return $filter('date')(formatDate, 'M/d/yyyy', timezone);
}
/**
* Default string-to-date parsing function.
* @param {string|number} dateString
* @returns {!Date}
*/
function defaultParseDate(dateString) {
return new Date(dateString);
}
/**
* Default function to determine whether a string makes sense to be
* parsed to a Date object.
*
* This is very permissive and is just a basic sanity check to ensure that
* things like single integers aren't able to be parsed into dates.
* @param {string} dateString
* @returns {boolean}
*/
function defaultIsDateComplete(dateString) {
dateString = dateString.trim();
// Looks for three chunks of content (either numbers or text) separated
// by delimiters.
var re = /^(([a-zA-Z]{3,}|[0-9]{1,4})([ .,]+|[/-])){2}([a-zA-Z]{3,}|[0-9]{1,4})$/;
return re.test(dateString);
}
/**
* Default date-to-string formatter to get a month header.
* @param {!Date} date
* @returns {string}
*/
function defaultMonthHeaderFormatter(date) {
return service.shortMonths[date.getMonth()] + ' ' + date.getFullYear();
}
/**
* Default formatter for a month.
* @param {!Date} date
* @returns {string}
*/
function defaultMonthFormatter(date) {
return service.months[date.getMonth()] + ' ' + date.getFullYear();
}
/**
* Default week number formatter.
* @param number
* @returns {string}
*/
function defaultWeekNumberFormatter(number) {
return 'Week ' + number;
}
/**
* Default formatter for date cell aria-labels.
* @param {!Date} date
* @returns {string}
*/
function defaultLongDateFormatter(date) {
// Example: 'Thursday June 18 2015'
return [
service.days[date.getDay()],
service.months[date.getMonth()],
service.dates[date.getDate()],
date.getFullYear()
].join(' ');
}
// The default "short" day strings are the first character of each day,
// e.g., "Monday" => "M".
var defaultShortDays = $locale.DATETIME_FORMATS.SHORTDAY.map(function(day) {
return day.substring(0, 1);
});
// The default dates are simply the numbers 1 through 31.
var defaultDates = Array(32);
for (var i = 1; i <= 31; i++) {
defaultDates[i] = i;
}
// Default ARIA messages are in English (US).
var defaultMsgCalendar = 'Calendar';
var defaultMsgOpenCalendar = 'Open calendar';
// Default start/end dates that are rendered in the calendar.
var defaultFirstRenderableDate = new Date(1880, 0, 1);
var defaultLastRendereableDate = new Date(defaultFirstRenderableDate.getFullYear() + 250, 0, 1);
var service = {
months: this.months || $locale.DATETIME_FORMATS.MONTH,
shortMonths: this.shortMonths || $locale.DATETIME_FORMATS.SHORTMONTH,
days: this.days || $locale.DATETIME_FORMATS.DAY,
shortDays: this.shortDays || defaultShortDays,
dates: this.dates || defaultDates,
firstDayOfWeek: this.firstDayOfWeek || 0,
formatDate: this.formatDate || defaultFormatDate,
parseDate: this.parseDate || defaultParseDate,
isDateComplete: this.isDateComplete || defaultIsDateComplete,
monthHeaderFormatter: this.monthHeaderFormatter || defaultMonthHeaderFormatter,
monthFormatter: this.monthFormatter || defaultMonthFormatter,
weekNumberFormatter: this.weekNumberFormatter || defaultWeekNumberFormatter,
longDateFormatter: this.longDateFormatter || defaultLongDateFormatter,
msgCalendar: this.msgCalendar || defaultMsgCalendar,
msgOpenCalendar: this.msgOpenCalendar || defaultMsgOpenCalendar,
firstRenderableDate: this.firstRenderableDate || defaultFirstRenderableDate,
lastRenderableDate: this.lastRenderableDate || defaultLastRendereableDate
};
return service;
};
$provide.provider('$mdDateLocale', new DateLocaleProvider());
});
})();