Skip to content

Commit fa20132

Browse files
committed
fix(dateParser): support literals inside date format string
'format` string can contain literal values. These need to be escaped by surrounding with single quotes (e.g. `"h 'in the morning'"`).
1 parent fac071e commit fa20132

File tree

2 files changed

+68
-14
lines changed

2 files changed

+68
-14
lines changed

src/helpers/date-parser.js

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -251,27 +251,64 @@ angular.module('mgcrea.ngStrap.helpers.dateParser', [])
251251
return sortedMap;
252252
}
253253

254-
function escapeReservedSymbols(text) {
255-
return text.replace(/\//g, '[\\/]').replace('/-/g', '[-]').replace(/\./g, '[.]').replace(/\\s/g, '[\\s]');
254+
function regExpForFormat(format) {
255+
// `format` string can contain literal values.
256+
// These need to be escaped by surrounding with
257+
// single quotes (e.g. `"h 'in the morning'"`).
258+
// In order to output a single quote, escape it - i.e.,
259+
// two single quotes in a sequence (e.g. `"h 'o''clock'"`).
260+
261+
var re = buildDateAbstractRegex(format);
262+
return buildDateParseRegex(re);
256263
}
257264

258-
function regExpForFormat(format) {
259-
var keys = Object.keys(regExpMap), i;
265+
function buildDateAbstractRegex(format) {
266+
var literalRegex = /('.*?')/;
267+
var formatParts = format.split(literalRegex);
268+
var dateElements = Object.keys(regExpMap);
269+
var dateRegexParts = [];
270+
271+
angular.forEach(formatParts, function (part) {
272+
if (isFormatStringLiteral(part)) {
273+
part = removeLiteralEscapeChars(part);
274+
}
275+
else {
276+
// Abstract replaces to avoid collisions
277+
for(var i = 0; i < dateElements.length; i++) {
278+
part = part.split(dateElements[i]).join('${' + i + '}');
279+
}
280+
}
281+
dateRegexParts.push(part);
282+
});
283+
284+
return dateRegexParts.join('');
285+
}
286+
287+
function isFormatStringLiteral(text) {
288+
return text.indexOf('\'') == 0;
289+
}
290+
291+
function removeLiteralEscapeChars(text) {
292+
return text.replace(/'/g, '');
293+
}
294+
295+
function buildDateParseRegex(abstractRegex) {
296+
var dateElements = Object.keys(regExpMap);
297+
var re = abstractRegex;
260298

261-
var re = format;
262-
// Abstract replaces to avoid collisions
263-
for(i = 0; i < keys.length; i++) {
264-
re = re.split(keys[i]).join('${' + i + '}');
265-
}
266299
// Replace abstracted values
267-
for(i = 0; i < keys.length; i++) {
268-
re = re.split('${' + i + '}').join('(' + regExpMap[keys[i]] + ')');
300+
for(var i = 0; i < dateElements.length; i++) {
301+
re = re.split('${' + i + '}').join('(' + regExpMap[dateElements[i]] + ')');
269302
}
270-
format = escapeReservedSymbols(format);
303+
re = escapeReservedSymbols(re);
271304

272305
return new RegExp('^' + re + '$', ['i']);
273306
}
274307

308+
function escapeReservedSymbols(text) {
309+
return text.replace(/\//g, '[\\/]').replace('/-/g', '[-]').replace(/\./g, '[.]').replace(/\\s/g, '[\\s]');
310+
}
311+
275312
$dateParser.init();
276313
return $dateParser;
277314

src/helpers/test/date-parser.spec.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ describe('dateParser', function () {
44

55
var $compile, scope, $dateParser, parser, $locale;
66

7-
var lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur non velit nulla. Suspendisse sit amet tempus diam. Sed at ultricies neque. Suspendisse id felis a sem placerat ornare. Donec auctor, purus at molestie tempor, arcu enim molestie lacus, ac imperdiet massa urna eu massa. Praesent velit tellus, scelerisque a fermentum ut, ornare in diam. Phasellus egestas molestie feugiat. Vivamus sit amet viverra metus.';
8-
97
beforeEach(module('mgcrea.ngStrap.helpers.dateParser'));
108

119
beforeEach(inject(function (_$rootScope_, _$compile_, _$dateParser_, _$locale_) {
@@ -391,5 +389,24 @@ describe('dateParser', function () {
391389
]);
392390
});
393391

392+
describe('fullDate format "EEEE, d MMMM y"', function() {
393+
beforeEach(function() {
394+
parser = $dateParser({ format: "EEEE, d MMMM y" });
395+
});
396+
generateTestCasesForParsing([
397+
{val:'Wednesday, 01 January 2014', expect: new Date(2014,0,1), reason:'full date'}
398+
]);
399+
});
400+
401+
describe('fullDate format "EEEE, d \'de\' MMMM \'de\' y" with literals', function() {
402+
beforeEach(function() {
403+
parser = $dateParser({ format: "EEEE, d 'de' MMMM 'de' y" });
404+
});
405+
generateTestCasesForParsing([
406+
{val:'Wednesday, 01 de January de 2014', expect: new Date(2014,0,1), reason:'full date with literals'},
407+
{val:'Wednesday, 01 January 2014', expect: false, reason:'full date does not include literals'}
408+
]);
409+
});
410+
394411
});
395412
});

0 commit comments

Comments
 (0)