(js) Fix sgTimePicker parsing of input field

pull/214/head
Francis Lachapelle 2016-06-10 11:38:35 -04:00
parent ccbce4fa1d
commit 684c32ee95
4 changed files with 45 additions and 37 deletions

1
NEWS
View File

@ -7,6 +7,7 @@ Bug fixes
- [web] properly encode rawsource of events and tasks to avoid XSS issues (#3718) - [web] properly encode rawsource of events and tasks to avoid XSS issues (#3718)
- [web] properly encode rawsource of cards to avoid XSS issues - [web] properly encode rawsource of cards to avoid XSS issues
- [web] fixed all-day events covering a timezone change (#3457) - [web] fixed all-day events covering a timezone change (#3457)
- [web] sgTimePicker parser now respects the user's time format and language
- [core] properly handle sorted/deleted calendars (#3723) - [core] properly handle sorted/deleted calendars (#3723)
- [core] properly handle flattened timezone definitions (#2690) - [core] properly handle flattened timezone definitions (#2690)

View File

@ -711,38 +711,22 @@
*/ */
TimePickerCtrl.prototype.handleInputEvent = function(self) { TimePickerCtrl.prototype.handleInputEvent = function(self) {
var inputString = this.inputElement.value; var inputString = this.inputElement.value;
var arr = inputString.split(/[\.:]/); var parsedTime = inputString ? this.dateLocale.parseTime(inputString) : null;
if (inputString === '') { // An input string is valid if it is either empty (representing no date)
this.ngModelCtrl.$setViewValue(null); // or if it parses to a valid time that the user is allowed to select.
this.time = null; var isValidInput = inputString === '' || this.dateUtil.isValidDate(parsedTime);
this.inputContainer.classList.remove(INVALID_CLASS);
} // The datepicker's model is only updated when there is a valid input.
else if (arr.length < 2) { if (isValidInput) {
arr = /(\d{1,2})(\d{2})/i.exec(inputString); var updated = new Date(this.time);
if (arr) updated.setHours(parsedTime.getHours());
arr.splice(0, 1); // only keep text captured by parenthesis updated.setMinutes(parsedTime.getMinutes());
this.ngModelCtrl.$setViewValue(updated);
this.time = updated;
} }
if (!arr || arr.length < 2) { this.updateErrorState(parsedTime);
this.inputContainer.classList.toggle(INVALID_CLASS, inputString);
}
else {
var h = Number(arr[0]);
var m = Number(arr[1]);
var newVal = new Date(this.time);
if (h && h >= 0 && h <= 23 && m && m >= 0 && m <= 59 && angular.isDate(newVal)) {
newVal.setHours(h);
newVal.setMinutes(m);
this.ngModelCtrl.$setViewValue(newVal);
this.time = newVal;
this.inputElement.value = this.dateLocale.formatTime(newVal);
this.inputContainer.classList.remove(INVALID_CLASS);
}
else {
this.inputContainer.classList.toggle(INVALID_CLASS, inputString);
}
}
}; };
/** Position and attach the floating calendar to the document. */ /** Position and attach the floating calendar to the document. */

View File

@ -152,12 +152,14 @@ String.prototype.parseDate = function(localeProvider, format) {
var string, formattingTokens, tokens, token, now, date, regexes, i, parsedInput, matchesCount; var string, formattingTokens, tokens, token, now, date, regexes, i, parsedInput, matchesCount;
string = '' + this; string = '' + this;
formattingTokens = /%[dembByY]/g; formattingTokens = /%[dembByYHIMp]/g;
now = new Date(); now = new Date();
date = { date = {
year: -1, year: now.getYear() + 1900,
month: -1, month: now.getMonth(),
day: -1 day: now.getDate(),
hour: 0,
minute: 0
}; };
regexes = { regexes = {
'%d': [/\d\d/, function(input) { '%d': [/\d\d/, function(input) {
@ -173,13 +175,13 @@ String.prototype.parseDate = function(localeProvider, format) {
return (date.month < 12); return (date.month < 12);
}], }],
'%b': [/[^\d\s\.\/\-]{2,}/, function(input) { '%b': [/[^\d\s\.\/\-]{2,}/, function(input) {
var i = _.indexOf(localeProvider.shortMonths, input); var i = _.indexOf(_.map(localeProvider.shortMonths, _.toLower), _.toLower(input));
if (i >= 0) if (i >= 0)
date.month = i; date.month = i;
return (i >= 0); return (i >= 0);
}], }],
'%B': [/[^\d\s\.\/\-]{2,}/, function(input) { '%B': [/[^\d\s\.\/\-]{2,}/, function(input) {
var i = _.indexOf(localeProvider.months, input); var i = _.indexOf(_.map(localeProvider.months, _.toLower), _.toLower(input));
if (i >= 0) if (i >= 0)
date.month = i; date.month = i;
return (i >= 0); return (i >= 0);
@ -194,7 +196,25 @@ String.prototype.parseDate = function(localeProvider, format) {
'%Y': [/[12]\d\d\d/, function(input) { '%Y': [/[12]\d\d\d/, function(input) {
date.year = parseInt(input); date.year = parseInt(input);
return true; return true;
}] }],
'%H': [/\d{1,2}/, function(input) {
date.hour = parseInt(input);
return (date.hour < 24);
}],
'%I': [/\d{1,2}/, function(input) {
date.hour = parseInt(input);
return (date.hour <= 12);
}],
'%M': [/[0-5]\d/, function(input) {
date.minute = parseInt(input);
return (date.minute < 60 );
}],
'%p': [/[^\d\s\/\-]+/, function(input) {
var linput = _.toLower(input), am = _.toLower(l('AM')), pm = _.toLower(l('PM'));
if (linput == pm)
date.hour += 12;
return (linput == am || linput == pm);
}],
}; };
tokens = format.match(formattingTokens) || []; tokens = format.match(formattingTokens) || [];
matchesCount = 0; matchesCount = 0;
@ -211,7 +231,7 @@ String.prototype.parseDate = function(localeProvider, format) {
if (tokens.length === matchesCount) { if (tokens.length === matchesCount) {
// console.debug(this + ' + ' + format + ' = ' + JSON.stringify(date)); // console.debug(this + ' + ' + format + ' = ' + JSON.stringify(date));
return new Date(date.year, date.month, date.day); return new Date(date.year, date.month, date.day, date.hour, date.minute);
} }
else else
return new Date(NaN); return new Date(NaN);

View File

@ -92,6 +92,9 @@
_this.$mdDateLocaleProvider.formatDate = function(date) { _this.$mdDateLocaleProvider.formatDate = function(date) {
return date? date.format(_this.$mdDateLocaleProvider, data.SOGoShortDateFormat) : ''; return date? date.format(_this.$mdDateLocaleProvider, data.SOGoShortDateFormat) : '';
}; };
_this.$mdDateLocaleProvider.parseTime = function(timeString) {
return timeString? timeString.parseDate(_this.$mdDateLocaleProvider, data.SOGoTimeFormat) : new Date(NaN);
};
_this.$mdDateLocaleProvider.formatTime = function(date) { _this.$mdDateLocaleProvider.formatTime = function(date) {
return date? date.format(_this.$mdDateLocaleProvider, data.SOGoTimeFormat) : ''; return date? date.format(_this.$mdDateLocaleProvider, data.SOGoTimeFormat) : '';
}; };