From a75e9b931fe6b28306be02274bac2a83e1f457ca Mon Sep 17 00:00:00 2001 From: Martin Filo Date: Thu, 17 Jun 2021 15:34:39 +0200 Subject: [PATCH] 0.2.0-alpha - extract parser to @annotation/ng-parse, allow configurable parser methods see NgDatepickerConf --- README.md | 2 + ng-a-date-picker/package.json | 1 + .../projects/ng-datepicker/ng-package.json | 1 - .../projects/ng-datepicker/package.json | 5 +- .../lib/components/popup/popup.component.ts | 32 +- .../src/lib/conf/has-ng-date-conf.ts | 8 +- .../src/lib/conf/ng-date.config.util.ts | 2 +- .../src/lib/conf/ng-datepicker.conf.ts | 11 +- .../DefaultDateModelValueConverter.ts | 19 +- .../DefaultFormattedModelValueConverter.ts | 22 +- .../DefaultIsoStringModelValueConverter.ts | 19 +- .../DefaultNumberModelValueConverter.ts | 19 +- .../directives/ng-date/ng-date.directive.ts | 13 +- .../validators/max-date.directive.ts | 8 +- .../validators/min-date.directive.ts | 8 +- .../src/lib/model/ng-date-public.model.ts | 122 +-- .../src/lib/ng-datepicker.module.ts | 9 +- .../src/lib/parsers/format-date.ts | 163 ---- .../src/lib/parsers/parse-date.spec.ts | 287 ------- .../src/lib/parsers/parse-date.ts | 738 ------------------ .../src/lib/services/parse.service.ts | 35 + .../src/lib/services/service-locator.ts | 7 + .../projects/ng-datepicker/src/public-api.ts | 3 +- ng-a-date-picker/yarn.lock | 7 + 24 files changed, 169 insertions(+), 1372 deletions(-) delete mode 100644 ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/format-date.ts delete mode 100644 ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.spec.ts delete mode 100644 ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.ts create mode 100644 ng-a-date-picker/projects/ng-datepicker/src/lib/services/parse.service.ts create mode 100644 ng-a-date-picker/projects/ng-datepicker/src/lib/services/service-locator.ts diff --git a/README.md b/README.md index fab4a20..815789c 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,10 @@ ## Install ```sh +yarn add @annotation/ng-parser ## peer dependency yarn add @annotation/ng-datepicker ## OR ## +npm install @annotation/ng-parser --save ## peer dependency npm install @annotation/ng-datepicker --save ``` diff --git a/ng-a-date-picker/package.json b/ng-a-date-picker/package.json index 6ae86fa..81bb7a6 100644 --- a/ng-a-date-picker/package.json +++ b/ng-a-date-picker/package.json @@ -22,6 +22,7 @@ "@angular/platform-browser": "~11.0.1", "@angular/platform-browser-dynamic": "~11.0.1", "@angular/router": "~11.0.1", + "@annotation/ng-parse": "^1.0.0", "rxjs": "~6.6.3", "tslib": "^2.0.0", "zone.js": "~0.10.2" diff --git a/ng-a-date-picker/projects/ng-datepicker/ng-package.json b/ng-a-date-picker/projects/ng-datepicker/ng-package.json index 150d488..5c6cbab 100644 --- a/ng-a-date-picker/projects/ng-datepicker/ng-package.json +++ b/ng-a-date-picker/projects/ng-datepicker/ng-package.json @@ -5,6 +5,5 @@ "entryFile": "src/public-api.ts" }, "whitelistedNonPeerDependencies": [ - ] } diff --git a/ng-a-date-picker/projects/ng-datepicker/package.json b/ng-a-date-picker/projects/ng-datepicker/package.json index 4d8a27e..b2f7a24 100644 --- a/ng-a-date-picker/projects/ng-datepicker/package.json +++ b/ng-a-date-picker/projects/ng-datepicker/package.json @@ -1,6 +1,6 @@ { "name": "@annotation/ng-datepicker", - "version": "0.1.20-alpha", + "version": "0.2.0-alpha", "description": "Angular datepicker - work in progress", "scripts": { "release": "dotenv release-it" @@ -10,7 +10,8 @@ "@angular/core": "^11.0.5", "@angular/forms": "^11.0.5", "@angular/localize": "^11.0.5", - "rxjs": "^6.6.3" + "rxjs": "^6.6.3", + "@annotation/ng-parse": "^1.0.0" }, "repository": { "type": "git", diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/components/popup/popup.component.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/components/popup/popup.component.ts index aaea902..247c838 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/components/popup/popup.component.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/components/popup/popup.component.ts @@ -1,17 +1,11 @@ -import {Component, ElementRef, Input, OnDestroy, OnInit, ViewEncapsulation} from '@angular/core'; -import { - formatDate, - FormStyle, - getLocaleDayNames, - getLocaleFirstDayOfWeek, - TranslationWidth, - WeekDay -} from '@angular/common'; -import {NgModel} from '@angular/forms'; -import {NgDateDirectiveApi} from '../../directives/ng-date/ng-date.directive.api'; -import {NgDateConfigUtil} from '../../conf/ng-date.config.util'; -import {BasicDateFormat, HtmlValueConfig} from '../../model/ng-date-public.model'; -import {DateType, getDateFormatParser} from '../../parsers/parse-date'; +import { Component, ElementRef, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; +import { formatDate, FormStyle, getLocaleDayNames, getLocaleFirstDayOfWeek, TranslationWidth, WeekDay } from '@angular/common'; +import { NgModel } from '@angular/forms'; +import { BasicDateFormat, DateType } from '@annotation/ng-parse'; +import { NgDateDirectiveApi } from '../../directives/ng-date/ng-date.directive.api'; +import { NgDateConfigUtil } from '../../conf/ng-date.config.util'; +import { HtmlValueConfig } from '../../model/ng-date-public.model'; +import { ParseService } from '../../services/parse.service'; @Component({ selector: 'ng-date-popup', @@ -59,7 +53,7 @@ export class PopupComponent implements OnInit, OnDestroy { return this._val; } - constructor(private _elementRef: ElementRef) { + constructor(private _elementRef: ElementRef, private parse: ParseService) { const myDate = new Date(); const timePortion = (myDate.getTime() - myDate.getTimezoneOffset() * 60 * 1000) % (3600 * 1000 * 24); this._today = new Date(+myDate - timePortion); @@ -111,7 +105,7 @@ export class PopupComponent implements OnInit, OnDestroy { }; private configureCalendarContent(conf: HtmlValueConfig) { - const {types} = getDateFormatParser(this.locale, conf.displayFormat as BasicDateFormat); + const { types } = this.parse.getDateFormatParser(this.locale, conf.displayFormat as BasicDateFormat); if (!this.config) { // TODO - mfilo - 27.01.2021 - typings!!! @@ -342,19 +336,19 @@ const utils = { const day = prevMonthStart + i; const date = new Date(prevYearNumber, prevMonthNumber, day); const dayOfWeek = utils.getDayOfWeek(date, firstDayOfWeek); - days.push({day, currentMonth: false, date, dayOfWeek}); + days.push({ day, currentMonth: false, date, dayOfWeek }); } for (let j = 1; j <= currMonthDays; j++) { const date = new Date(year, month, j); const dayOfWeek = utils.getDayOfWeek(date, firstDayOfWeek); - days.push({day: j, currentMonth: true, date, dayOfWeek}); + days.push({ day: j, currentMonth: true, date, dayOfWeek }); } for (let k = 1; k <= lastDayOfMonth; k++) { const date = new Date(nexyYearNumber, nextMonthNumber, k); const dayOfWeek = utils.getDayOfWeek(date, firstDayOfWeek); - days.push({day: k, currentMonth: false, date, dayOfWeek}); + days.push({ day: k, currentMonth: false, date, dayOfWeek }); } return days; diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/has-ng-date-conf.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/has-ng-date-conf.ts index ff5b269..edb241f 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/has-ng-date-conf.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/has-ng-date-conf.ts @@ -1,10 +1,6 @@ +import { BasicDateFormat } from '@annotation/ng-parse'; import { NgDatepickerConf } from './ng-datepicker.conf'; -import { - ApiNgDateModelValueConverter, - BasicDateFormat, - NgDateConfig, - StandardModelValueConverters, -} from '../model/ng-date-public.model'; +import { ApiNgDateModelValueConverter, NgDateConfig, StandardModelValueConverters } from '../model/ng-date-public.model'; export interface HasNgDateConf { ngDateConfig?: BasicDateFormat | NgDateConfig; diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-date.config.util.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-date.config.util.ts index 8170234..fa45ec0 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-date.config.util.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-date.config.util.ts @@ -1,3 +1,4 @@ +import { BasicDateFormat } from '@annotation/ng-parse'; import { DefaultFormattedModelValueConverter } from '../converters/DefaultFormattedModelValueConverter'; import { DefaultDateModelValueConverter } from '../converters/DefaultDateModelValueConverter'; import { DefaultNumberModelValueConverter } from '../converters/DefaultNumberModelValueConverter'; @@ -6,7 +7,6 @@ import { NgDatepickerConf } from './ng-datepicker.conf'; import { HasNgDateConf } from './has-ng-date-conf'; import { ApiNgDateModelValueConverter, - BasicDateFormat, HtmlValueConfig, NgDateConfig, StandardModelValueConverters, diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-datepicker.conf.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-datepicker.conf.ts index bc973e1..878d7c0 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-datepicker.conf.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/conf/ng-datepicker.conf.ts @@ -1,10 +1,19 @@ // https://www.usefuldev.com/post/Angular:%20Creating%20configurable%20libraries%20with%20angular%20cli -import { BasicDateFormat, NgDateConfig } from '../model/ng-date-public.model'; +import { BasicDateFormat, DateParser } from '@annotation/ng-parse'; +import { NgDateConfig } from '../model/ng-date-public.model'; type DateFormatConfig = { [key in BasicDateFormat]?: NgDateConfig }; +type DateParserConfig = { + parseDate: (value: string, format: BasicDateFormat | string, locale: string, oldValue?: Date) => Date; + getDateFormatParser: (locale: string, format: BasicDateFormat | string) => DateParser; + toDate: (value: string | number | Date) => Date; +}; export interface NgDatepickerConf extends DateFormatConfig { + // custom date parsing + parser?: DateParserConfig; + // common default config all?: NgDateConfig; diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultDateModelValueConverter.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultDateModelValueConverter.ts index b21312a..6dc9bfe 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultDateModelValueConverter.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultDateModelValueConverter.ts @@ -1,11 +1,26 @@ -import { toDate } from '../parsers/format-date'; import { ApiNgDateModelValueConverter } from '../model/ng-date-public.model'; +import { ParseService } from '../services/parse.service'; +import { ServiceLocator } from '../services/service-locator'; export class DefaultDateModelValueConverter implements ApiNgDateModelValueConverter { static readonly INSTANCE = new DefaultDateModelValueConverter(); + private parse: ParseService; + constructor() { + const isReady = ServiceLocator.onReady.getValue(); + if (!isReady) { + ServiceLocator.onReady.subscribe((value) => { + if (value) { + this.parse = ServiceLocator.injector.get(ParseService); + } + }); + } else { + this.parse = ServiceLocator.injector.get(ParseService); + } + } + fromModel(value: string | number | Date): Date { - return toDate(value); + return this.parse.toDate(value); } toModel(value: Date): Date { diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultFormattedModelValueConverter.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultFormattedModelValueConverter.ts index 7daba40..1816779 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultFormattedModelValueConverter.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultFormattedModelValueConverter.ts @@ -1,8 +1,8 @@ import { formatDate } from '@angular/common'; -import { parseDate } from '../parsers/parse-date'; -import { toDate } from '../parsers/format-date'; import { NgDateConfigUtil } from '../conf/ng-date.config.util'; import { ApiNgDateModelValueConverter, ApiNgDateModelValueConverterConf } from '../model/ng-date-public.model'; +import { ParseService } from '../services/parse.service'; +import { ServiceLocator } from '../services/service-locator'; const localeIso = 'en-US'; @@ -33,7 +33,19 @@ export class DefaultFormattedModelValueConverter implements ApiNgDateModelValueC localeIso ); - constructor(private dateFormat: string, private locale?: string, private timezone?: string) {} + private parse: ParseService; + constructor(private dateFormat: string, private locale?: string, private timezone?: string) { + const isReady = ServiceLocator.onReady.getValue(); + if (!isReady) { + ServiceLocator.onReady.subscribe((value) => { + if (value) { + this.parse = ServiceLocator.injector.get(ParseService); + } + }); + } else { + this.parse = ServiceLocator.injector.get(ParseService); + } + } fromModel(value: any, oldValue: Date, opts: ApiNgDateModelValueConverterConf): Date { if (NgDateConfigUtil.isStringConstant(value)) { @@ -42,9 +54,9 @@ export class DefaultFormattedModelValueConverter implements ApiNgDateModelValueC if (!locale && opts) locale = opts.locale; // tuto je defaultne definovane 'en-US' a teda ignoruje locale z conf if (!locale) locale = localeIso; - return parseDate(value, this.dateFormat, locale); + return this.parse.parseDate(value, this.dateFormat, locale); } - return toDate(value); + return this.parse.toDate(value); } toModel(value: Date, oldModel: string, opts: ApiNgDateModelValueConverterConf): string { diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultIsoStringModelValueConverter.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultIsoStringModelValueConverter.ts index d67a818..995b180 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultIsoStringModelValueConverter.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultIsoStringModelValueConverter.ts @@ -1,12 +1,27 @@ -import { toDate } from '../parsers/format-date'; import { ApiNgDateModelValueConverter } from '../model/ng-date-public.model'; +import { ParseService } from '../services/parse.service'; +import { ServiceLocator } from '../services/service-locator'; export class DefaultIsoStringModelValueConverter implements ApiNgDateModelValueConverter { static readonly INSTANCE = new DefaultIsoStringModelValueConverter(); + private parse: ParseService; + constructor() { + const isReady = ServiceLocator.onReady.getValue(); + if (!isReady) { + ServiceLocator.onReady.subscribe((value) => { + if (value) { + this.parse = ServiceLocator.injector.get(ParseService); + } + }); + } else { + this.parse = ServiceLocator.injector.get(ParseService); + } + } + fromModel(value: string): Date { if (!value || !value?.trim()?.length) return null; - return toDate(value); + return this.parse.toDate(value); } toModel(value: Date): string { diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultNumberModelValueConverter.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultNumberModelValueConverter.ts index ed620d4..0ea7ded 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultNumberModelValueConverter.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/converters/DefaultNumberModelValueConverter.ts @@ -1,11 +1,26 @@ import { ApiNgDateModelValueConverter } from '../model/ng-date-public.model'; -import { toDate } from '../parsers/format-date'; +import { ParseService } from '../services/parse.service'; +import { ServiceLocator } from '../services/service-locator'; export class DefaultNumberModelValueConverter implements ApiNgDateModelValueConverter { static readonly INSTANCE = new DefaultNumberModelValueConverter(); + private parse: ParseService; + constructor() { + const isReady = ServiceLocator.onReady.getValue(); + if (!isReady) { + ServiceLocator.onReady.subscribe((value) => { + if (value) { + this.parse = ServiceLocator.injector.get(ParseService); + } + }); + } else { + this.parse = ServiceLocator.injector.get(ParseService); + } + } + fromModel(value: string | number | Date): Date { - return toDate(value); + return this.parse.toDate(value); } toModel(value: Date): number { diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/ng-date/ng-date.directive.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/ng-date/ng-date.directive.ts index 80e9a40..c3cb324 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/ng-date/ng-date.directive.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/ng-date/ng-date.directive.ts @@ -16,19 +16,15 @@ import { ViewContainerRef, } from '@angular/core'; import { COMPOSITION_BUFFER_MODE, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { parseDate } from '../../parsers/parse-date'; +import { BasicDateFormat } from '@annotation/ng-parse'; import { NG_DATEPICKER_CONF } from '../../conf/ng-datepicker.conf.token'; import { NgDatepickerConf } from '../../conf/ng-datepicker.conf'; -import { - ApiNgDateModelValueConverter, - BasicDateFormat, - NgDateConfig, - StandardModelValueConverters, -} from '../../model/ng-date-public.model'; +import { ApiNgDateModelValueConverter, NgDateConfig, StandardModelValueConverters } from '../../model/ng-date-public.model'; import { PopupComponent } from '../../components/popup/popup.component'; import { NgDateConfigUtil } from '../../conf/ng-date.config.util'; import { HasNgDateConf } from '../../conf/has-ng-date-conf'; import { NgDateDirectiveApi, NgDateValue } from './ng-date.directive.api'; +import { ParseService } from '../../services/parse.service'; /** * We must check whether the agent is Android because composition events @@ -127,6 +123,7 @@ export class NgDateDirective implements ControlValueAccessor, HasNgDateConf, NgD private elementRef: ElementRef, private _viewContainerRef: ViewContainerRef, private _componentFactoryResolver: ComponentFactoryResolver, + private parse: ParseService, @Optional() @Inject(NG_DATEPICKER_CONF) public ngDatepickerConf: NgDatepickerConf, @Inject(LOCALE_ID) public locale: string, @Optional() @Inject(COMPOSITION_BUFFER_MODE) private _compositionMode: boolean @@ -300,7 +297,7 @@ export class NgDateDirective implements ControlValueAccessor, HasNgDateConf, NgD // 3) convert(htmlValue, dtValue/old) => dtValue/new private convertHtmlValueToDtValue(htmlValue: string, dtValue: Date): Date | null { const htmlValueConfig = NgDateConfigUtil.resolveHtmlValueConfig(this); - return parseDate(htmlValue, htmlValueConfig.displayFormat, htmlValueConfig.locale, dtValue); + return this.parse.parseDate(htmlValue, htmlValueConfig.displayFormat, htmlValueConfig.locale, dtValue); } // 4) convert(dtValue, ngValue/old) => ngValue/new diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/max-date.directive.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/max-date.directive.ts index 3137c2b..ec74b88 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/max-date.directive.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/max-date.directive.ts @@ -1,12 +1,8 @@ import { Directive, forwardRef, Inject, Input, LOCALE_ID, Optional } from '@angular/core'; import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms'; +import { BasicDateFormat } from '@annotation/ng-parse'; import { NgDateValidators } from './validate.conf'; -import { - ApiNgDateModelValueConverter, - BasicDateFormat, - NgDateConfig, - StandardModelValueConverters, -} from '../../model/ng-date-public.model'; +import { ApiNgDateModelValueConverter, NgDateConfig, StandardModelValueConverters } from '../../model/ng-date-public.model'; import { NG_DATEPICKER_CONF } from '../../conf/ng-datepicker.conf.token'; import { NgDatepickerConf } from '../../conf/ng-datepicker.conf'; import { HasNgDateConf } from '../../conf/has-ng-date-conf'; diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/min-date.directive.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/min-date.directive.ts index 1f7c5de..0ed79c6 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/min-date.directive.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/directives/validators/min-date.directive.ts @@ -1,15 +1,11 @@ import { Directive, forwardRef, Inject, Input, LOCALE_ID, Optional } from '@angular/core'; import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms'; +import { BasicDateFormat } from '@annotation/ng-parse'; import { NG_DATEPICKER_CONF } from '../../conf/ng-datepicker.conf.token'; import { NgDatepickerConf } from '../../conf/ng-datepicker.conf'; import { NgDateValidators } from './validate.conf'; import { HasNgDateConf } from '../../conf/has-ng-date-conf'; -import { - ApiNgDateModelValueConverter, - BasicDateFormat, - NgDateConfig, - StandardModelValueConverters, -} from '../../model/ng-date-public.model'; +import { ApiNgDateModelValueConverter, NgDateConfig, StandardModelValueConverters } from '../../model/ng-date-public.model'; @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/model/ng-date-public.model.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/model/ng-date-public.model.ts index d1c2b4b..4f48fdf 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/model/ng-date-public.model.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/model/ng-date-public.model.ts @@ -1,3 +1,5 @@ +import { BasicDateFormat } from '@annotation/ng-parse'; + // converting HTML value <=> Date value (working with std. Date parser&formatter) export interface HtmlValueConfig { @@ -48,123 +50,3 @@ export type StandardModelValueConverters = | 'string-iso-time' | 'string-iso-time-short' | 'string-iso-date'; - -// List of known angular DatePipe formats, not all are implemented, more info: https://angular.io/api/common/DatePipe#pre-defined-format-options -export type BasicDateFormat = - | 'short' - | 'medium' - | 'long' - | 'full' - | 'shortDate' - | 'mediumDate' - | 'longDate' - | 'fullDate' - | 'shortTime' - | 'mediumTime' - | 'longTime' - | 'fullTime'; - -// List of known DatePart formats, not all are implemented, more info: https://angular.io/api/common/DatePipe#custom-format-options -export type DatePartFormat = - // Era name (AD/BC) - | 'G' - | 'GG' - | 'GGG' - | 'GGGG' - | 'GGGGG' - // 1 digit representation of the year, e.g. (AD 1 => 1, AD 199 => 199) - | 'y' - // 2 digit representation of the year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) - | 'yy' - // 3 digit representation of the year, padded (000-999). (e.g. AD 2001 => 01, AD 2010 => 10) - | 'yyy' - // 4 digit representation of the year (e.g. AD 1 => 0001, AD 2010 => 2010) - | 'yyyy' - // 1 digit representation of the week-numbering year, e.g. (AD 1 => 1, AD 199 => 199) - | 'Y' - // 2 digit representation of the week-numbering year, padded (00-99). (e.g. AD 2001 => 01, AD - // 2010 => 10) - | 'YY' - // 3 digit representation of the week-numbering year, padded (000-999). (e.g. AD 1 => 001, AD - // 2010 => 2010) - | 'YYY' - | 'YYYY' - // Month of the year (1-12), numeric - | 'M' - | 'L' - | 'MM' - | 'LL' - // Month of the year (January, ...), string, format - | 'MMM' - | 'MMMM' - | 'MMMMM' - // Month of the year (January, ...), string, standalone - | 'LLL' - | 'LLLL' - | 'LLLLL' - // Week of the year (1, ... 52) - | 'w' - | 'ww' - // Week of the month (1, ...) - | 'W' - // Day of the month (1-31) - | 'd' - | 'dd' - // Day of the Week - | 'E' - | 'EE' - | 'EEE' - | 'EEEE' - | 'EEEEE' - | 'EEEEEE' - // Generic period of the day (am-pm) - | 'a' - | 'aa' - | 'aaa' - | 'aaaa' - | 'aaaaa' - // Extended period of the day (midnight, at night, ...), standalone - | 'b' - | 'bb' - | 'bbb' - | 'bbbb' - | 'bbbbb' - // Extended period of the day (midnight, night, ...), standalone - | 'B' - | 'BB' - | 'BBB' - | 'BBBB' - | 'BBBBB' - // Hour in AM/PM, (1-12) - | 'h' - | 'hh' - // Hour of the day (0-23) - | 'H' - | 'HH' - // Minute of the hour (0-59) - | 'm' - | 'mm' - // Second of the minute (0-59) - | 's' - | 'ss' - // Fractional second - | 'S' - | 'SS' - | 'SSS' - // Timezone ISO8601 short format (-0430) - | 'Z' - | 'ZZ' - | 'ZZZ' - // Timezone ISO8601 extended format (-0430) - | 'ZZZZZ' - // Timezone GMT short format (GMT+4) - | 'O' - | 'OO' - | 'OOO' - | 'z' - | 'zz' - | 'zzz' - // Timezone GMT long format (GMT+0430) - | 'OOOO' - | 'ZZZZ' - | 'zzzz'; diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/ng-datepicker.module.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/ng-datepicker.module.ts index 3d40732..9f9e2d0 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/ng-datepicker.module.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/ng-datepicker.module.ts @@ -1,4 +1,4 @@ -import { ModuleWithProviders, NgModule } from '@angular/core'; +import { Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { NgDatepickerConf } from './conf/ng-datepicker.conf'; @@ -7,6 +7,7 @@ import { NgDateDirective } from './directives/ng-date/ng-date.directive'; import { MinDateDirective } from './directives/validators/min-date.directive'; import { MaxDateDirective } from './directives/validators/max-date.directive'; import { PopupComponent } from './components/popup/popup.component'; +import { ServiceLocator } from './services/service-locator'; @NgModule({ declarations: [NgDateDirective, MinDateDirective, MaxDateDirective, PopupComponent], @@ -14,6 +15,12 @@ import { PopupComponent } from './components/popup/popup.component'; exports: [NgDateDirective, MinDateDirective, MaxDateDirective, PopupComponent], }) export class NgDatepickerModule { + // https://stackoverflow.com/a/42462579/5011810 + constructor(private injector: Injector) { + ServiceLocator.injector = this.injector; + ServiceLocator.onReady.next(true); + } + static forRoot(ngDatepickerConf: NgDatepickerConf): ModuleWithProviders { return { ngModule: NgDatepickerModule, diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/format-date.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/format-date.ts deleted file mode 100644 index 23cb1b3..0000000 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/format-date.ts +++ /dev/null @@ -1,163 +0,0 @@ -/* eslint-disable no-case-declarations */ -/** - * copy from https://github.com/angular/angular/blob/master/packages/common/src/i18n/format_date.ts - */ -import { FormatWidth, getLocaleDateFormat, getLocaleDateTimeFormat, getLocaleId, getLocaleTimeFormat } from '@angular/common'; -import { BasicDateFormat } from '../model/ng-date-public.model'; - -export const DATE_FORMATS_SPLIT = /((?:[^GyYMLwWdEabBhHmsSzZO']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/; - -const NAMED_FORMATS: { [localeId: string]: { [format in BasicDateFormat]: string } } = {}; - -function formatDateTime(str: string, opt_values: string[]) { - if (opt_values) { - str = str.replace(/\{([^}]+)}/g, function (match, key) { - return opt_values != null && key in opt_values ? opt_values[key] : match; - }); - } - return str; -} - -export function getNamedFormat(locale: string, format: BasicDateFormat): string { - const localeId = getLocaleId(locale); - NAMED_FORMATS[localeId] = NAMED_FORMATS[localeId] || ({} as any); - - if (NAMED_FORMATS[localeId][format]) { - return NAMED_FORMATS[localeId][format]; - } - - let formatValue = ''; - switch (format) { - case 'shortDate': - formatValue = getLocaleDateFormat(locale, FormatWidth.Short); - break; - case 'mediumDate': - formatValue = getLocaleDateFormat(locale, FormatWidth.Medium); - break; - case 'longDate': - formatValue = getLocaleDateFormat(locale, FormatWidth.Long); - break; - case 'fullDate': - formatValue = getLocaleDateFormat(locale, FormatWidth.Full); - break; - case 'shortTime': - formatValue = getLocaleTimeFormat(locale, FormatWidth.Short); - break; - case 'mediumTime': - formatValue = getLocaleTimeFormat(locale, FormatWidth.Medium); - break; - case 'longTime': - formatValue = getLocaleTimeFormat(locale, FormatWidth.Long); - break; - case 'fullTime': - formatValue = getLocaleTimeFormat(locale, FormatWidth.Full); - break; - case 'short': - const shortTime = getNamedFormat(locale, 'shortTime'); - const shortDate = getNamedFormat(locale, 'shortDate'); - formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Short), [shortTime, shortDate]); - break; - case 'medium': - const mediumTime = getNamedFormat(locale, 'mediumTime'); - const mediumDate = getNamedFormat(locale, 'mediumDate'); - formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Medium), [mediumTime, mediumDate]); - break; - case 'long': - const longTime = getNamedFormat(locale, 'longTime'); - const longDate = getNamedFormat(locale, 'longDate'); - formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Long), [longTime, longDate]); - break; - case 'full': - const fullTime = getNamedFormat(locale, 'fullTime'); - const fullDate = getNamedFormat(locale, 'fullDate'); - formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Full), [fullTime, fullDate]); - break; - default: - return null; - } - if (formatValue) { - NAMED_FORMATS[localeId][format] = formatValue; - } - return formatValue; -} - -export const ISO8601_DATE_REGEX = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; - -export function toDate(value: string | number | Date): Date { - if (isDate(value)) { - return value; - } - - if (typeof value === 'number' && !isNaN(value)) { - return new Date(value); - } - - if (typeof value === 'string') { - value = value.trim(); - - const parsedNb = parseFloat(value); - - // any string that only contains numbers, like "1234" but not like "1234hello" - if (!isNaN((value as any) - parsedNb)) { - return new Date(parsedNb); - } - - if (/^(\d{4}-\d{1,2}-\d{1,2})$/.test(value)) { - /* For ISO Strings without time the day, month and year must be extracted from the ISO String - before Date creation to avoid time offset and errors in the new Date. - If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new - date, some browsers (e.g. IE 9) will throw an invalid Date error. - If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset - is applied. - Note: ISO months are 0 for January, 1 for February, ... */ - const [y, m, d] = value.split('-').map((val: string) => +val); - return new Date(y, m - 1, d); - } - - const match: RegExpMatchArray | null = value.match(ISO8601_DATE_REGEX); - if (match) { - return isoStringToDate(match); - } - } - - const date = new Date(value as any); - if (!isDate(date)) { - throw new Error(`Unable to convert "${value}" into a date`); - } - return date; -} - -/** - * Converts a date in ISO8601 to a Date. - * Used instead of `Date.parse` because of browser discrepancies. - */ - -export function isoStringToDate(match: RegExpMatchArray): Date { - const date = new Date(0); - let tzHour = 0; - let tzMin = 0; - - // match[8] means that the string contains "Z" (UTC) or a timezone like "+01:00" or "+0100" - const dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear; - const timeSetter = match[8] ? date.setUTCHours : date.setHours; - - // if there is a timezone defined like "+01:00" or "+0100" - if (match[9]) { - tzHour = Number(match[9] + match[10]); - tzMin = Number(match[9] + match[11]); - } - dateSetter.call(date, Number(match[1]), Number(match[2]) - 1, Number(match[3])); - const h = Number(match[4] || 0) - tzHour; - const m = Number(match[5] || 0) - tzMin; - const s = Number(match[6] || 0); - // The ECMAScript specification (https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.11) - // defines that `DateTime` milliseconds should always be rounded down, so that `999.9ms` - // becomes `999ms`. - const ms = Math.floor(parseFloat(`0.${match[7] || 0}`) * 1000); - timeSetter.call(date, h, m, s, ms); - return date; -} - -export function isDate(value: any): value is Date { - return value instanceof Date && !isNaN(value.valueOf()); -} diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.spec.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.spec.ts deleted file mode 100644 index d1b8859..0000000 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.spec.ts +++ /dev/null @@ -1,287 +0,0 @@ -import { formatDate } from '@angular/common'; -import { getNamedFormat } from './format-date'; -import { getDateFormatParser } from './parse-date'; - -const localeEn = 'en'; -// const localeDe = 'de'; -// const localeSk = 'sk'; -// -// getTestBed().configureTestingModule({ -// providers: [{ provide: LOCALE_ID, useValue: locale }], -// }); - -describe('DateParserService', () => { - var strValues = [ - '2021-01-27T20:37:44Z', - '2021-01-27T20:37:44+00:00', - '2021-01-27T21:37:44+01:00', - '2021-01-27T22:07:44+01:30', - '2021-01-27T22:37:44+02:00', - '2021-01-28T00:37:44+04:00', - '2021-01-27T20:37:44-00:00', - '2021-01-27T19:37:44-01:00', - '2021-01-27T19:07:44-01:30', - '2021-01-27T18:37:44-02:00', - '2021-01-27T16:37:44-04:00', - ]; - for (let i = 0; i < strValues.length; i++) { - it(`test parsing timezone ${strValues[i]} == ${strValues[0]}`, () => { - let isoDateTimeWithTimeZone: string = 'yyyy-MM-ddTHH:mm:ssZZZZZ'; - const parser = getDateFormatParser(localeEn, isoDateTimeWithTimeZone); - expect(parser.errorMsg).toBe(null); - - const d0 = new Date(strValues[0]); - const d1 = new Date(strValues[i]); - const d2 = parser.parseDate(strValues[i]); - expect(d2).not.toBeNull(); - expect(d1).not.toBe(d0); - expect(d2).not.toBe(d0); - expect(d2).not.toBe(d1); - expect(d1.getTime()).toBe(d0.getTime()); - expect(d2.getTime()).toBe(d1.getTime()); - - var zone = strValues[i]; - zone = zone.substring(zone.length-6); - const strValue2 = formatDate(d2, isoDateTimeWithTimeZone, localeEn, zone); - expect(strValue2).not.toBeNull(); - expect(strValue2).toBe(strValues[i].replace('+00:00', 'Z').replace('-00:00', 'Z')); - console.log(zone, strValue2, d0.getTime(), d1.getTime(), d2.getTime()); - }); - } - - - - it('test getNamedFormat', () => { - const directive = getNamedFormat(localeEn, 'shortDate'); - console.log('test the cat api ', directive); - expect(directive).toBe('M/d/yy'); - }); - getDateFormatParser['run_in_tests'] = true; - - const unsupportedFormats = [ - 'G', - 'GG', - 'GGG', - 'GGGG', - 'GGGGG', - 'b', - 'bb', - 'bbb', - 'bbbb', - 'bbbbb', - 'B', - 'BB', - 'BBB', - 'BBBB', - 'BBBBB', - ]; - - for (const unsupportedFormat of unsupportedFormats) { - it(`test unsupported format: ${unsupportedFormat}`, () => { - const parser = getDateFormatParser(localeEn, unsupportedFormat); - // console.log(parser.errorMsg); - expect(parser.errorMsg).toEqual(`Error: Unsupported parsing format '${unsupportedFormat}'`); - }); - } - - const ignoredFormats = ['w', 'ww', 'W', 'E', 'EE', 'EEE']; - for (const ignoredFormat of ignoredFormats) { - it(`test ignored format: ${ignoredFormat}`, () => { - const parser = getDateFormatParser(localeEn, ignoredFormat); - expect(parser.errorMsg).toBe(null); - - const d1 = new Date(); - const s1 = formatDate(d1, ignoredFormat, localeEn); - - const d2 = parser.parseDate(s1); - - const lineRegexp = `${parser['lineRegexp']}`; - console.log('lineRegexp', lineRegexp, s1); - - expect(d2).toBeNull(); - - const d3 = parser.parseDate(s1, d1); - expect(d3).toBe(d1); - }); - } - - const supportedFormats = [ - 'y', - 'yy', - 'yyy', - 'yyyy', - 'Y', - 'YY', - 'YYY', - 'YYYY', - 'M', - 'L', - 'MM', - 'LL', - 'MMM', - 'MMMM', - 'MMMMM', - 'LLL', - 'LLLL', - 'LLLLL', - 'd', - 'dd', - 'a', - 'aa', - 'aaa', - 'aaaa', - 'aaaaa', - 'h', - 'hh', - 'H', - 'HH', - 'm', - 'mm', - 's', - 'ss', - 'S', - 'SS', - 'SSS', - - // timezone ... - 'Z', - 'ZZ', - 'ZZZ', - 'ZZZZZ', - 'O', - 'OO', - 'OOO', - 'z', - 'zz', - 'zzz', - 'OOOO', - 'ZZZZ', - 'zzzz', - ]; - for (const supportedFormat of supportedFormats) { - it(`test format: ${supportedFormat}`, () => { - const parser = getDateFormatParser(localeEn, supportedFormat); - expect(parser.errorMsg).toBe(null); - debugger; - - const d1 = new Date('1999-12-31T23:59:57'); // some formats can lost any information (e.g.: MMMMM) - const s1 = formatDate(d1, supportedFormat, localeEn); - const d2 = parser.parseDate(s1); - - const lineRegexp = `${parser['lineRegexp']}`; - console.log('lineRegexp', lineRegexp, s1); - - expect(d2).not.toBeNull(); - expect(formatDate(d2, supportedFormat, localeEn)).toBe(s1); - - const d3 = parser.parseDate(s1, d1); - expect(d3).not.toBeNull(); - expect(d3).not.toBe(d1); - expect(d3.getTime()).toBe(d1.getTime()); - }); - } - - const createYearTest = ( - supportedFormat: string, - strValue: string, - fullYearBefore: number, - fullYearExpected: number, - runFormatedTest: boolean = true - ) => { - it(`test year format: ${supportedFormat} = '${strValue}' => ${fullYearExpected}`, () => { - const parser = getDateFormatParser(localeEn, supportedFormat); - const dIn = new Date(); - dIn.setMonth(5); - dIn.setFullYear(fullYearBefore); - - const dOut = parser.parseDate(strValue, dIn); - expect(dOut).not.toBeNull(); - expect(dOut).not.toBeUndefined(); - expect(dOut).not.toBe(dIn); - expect(dOut.getFullYear()).toBe(fullYearExpected); - - if (runFormatedTest) { - const strValue2 = formatDate(dOut, supportedFormat, localeEn); - expect(strValue2).toBe(strValue); - } - }); - }; - // y | Y - createYearTest('y', '1', 2, 1); - createYearTest('y', '12', 11, 12); - createYearTest('y', '1299', 11, 1299); - createYearTest('y', '120', 1, 120); - - /* - createYearTest('Y', '1', 2, 1); // Bug in @angular/common - createYearTest('Y', '12', 11, 12); // Bug in @angular/common - */ - createYearTest('Y', '1299', 11, 1299); - createYearTest('Y', '120', 1, 120); - - // yy = 2 digit representation of the year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) - createYearTest('yy', '03', 2, 3); - createYearTest('yy', '33', 2, 33); - createYearTest('yy', '33', 22, 33); - createYearTest('yy', '33', 222, 233); - createYearTest('yy', '33', 2222, 2233); - - // YY = 2 digit representation of the week-numbering year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) - createYearTest('YY', '03', 2, 3); - createYearTest('YY', '33', 2, 33); - createYearTest('YY', '33', 22, 33); - createYearTest('YY', '33', 222, 233); - createYearTest('YY', '33', 2222, 2233); - - // yyy = 3 digit representation of the year, padded (000-999). (e.g. AD 2001 => 01, AD 2010 => 10) - createYearTest('yyy', '333', 2, 333); - createYearTest('YYY', '333', 2, 333); - createYearTest('yyy', '3334', 2, 3334); - createYearTest('YYY', '3334', 2, 3334); - createYearTest('yyyy', '3334', 2, 3334); - createYearTest('YYYY', '3334', 2, 3334); - - const createCustomTest = ( - format: string, - strValue: string, - dIn: Date, - lineRegexpExpected: string, - expFormatedStrValue: string = null - ) => { - it(`createCustomTest: ${format} = '${strValue}' => ${dIn.toISOString()}, parsed with regexp: lineRegexpExpected`, () => { - const parser = getDateFormatParser(localeEn, format); - - // test line regexp - const lineRegexp = `${parser['lineRegexp']}`; - expect(lineRegexp).not.toBeNull(); - expect(lineRegexp).not.toBeUndefined(); - expect(lineRegexp).toBe(lineRegexpExpected); - - const strValueTest1 = formatDate(dIn, format, localeEn); - if (!expFormatedStrValue) expFormatedStrValue = strValue.replace(/\s+/g, ''); - expect(strValueTest1).toBe(expFormatedStrValue); - - const dOut = parser.parseDate(strValue, dIn); - expect(dOut).not.toBeNull(); - expect(dOut).not.toBeUndefined(); - expect(dOut).not.toBe(dIn); - - const strValueTest2 = formatDate(dOut, format, localeEn); - expect(strValueTest2).toBe(strValueTest1); - }); - }; - const dtTest = new Date('2131-10-20T13:14:15.167'); // - - createCustomTest('yyyy', '2131', dtTest, '^(\\d{4,5})$'); - createCustomTest('yyyy-dd', '2131-20', dtTest, '^(\\d{4,5})\\s*-\\s*(\\d{1,2})$'); - createCustomTest('yyyy-dd', ' 2131 - 20 ', dtTest, '^(\\d{4,5})\\s*-\\s*(\\d{1,2})$'); - createCustomTest('yyyy-MM', '2131-10', dtTest, '^(\\d{4,5})\\s*-\\s*(\\d{1,2})$'); - createCustomTest('yyyy-MM-dd', '2131 - 10 -20', dtTest, '^(\\d{4,5})\\s*-\\s*(\\d{1,2})\\s*-\\s*(\\d{1,2})$'); - createCustomTest( - 'yyyy-MM-dd HH:mm:ss', - '2131 - 10 -20 13 :14 : 15', - dtTest, - '^(\\d{4,5})\\s*-\\s*(\\d{1,2})\\s*-\\s*(\\d{1,2})\\s*(\\d{1,2})\\s*:\\s*(\\d{1,2})\\s*:\\s*(\\d{1,2})$', - '2131-10-20 13:14:15' - ); -}); diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.ts deleted file mode 100644 index c7a4980..0000000 --- a/ng-a-date-picker/projects/ng-datepicker/src/lib/parsers/parse-date.ts +++ /dev/null @@ -1,738 +0,0 @@ -import { - FormStyle, - getLocaleDayNames, - getLocaleDayPeriods, - getLocaleEraNames, - getLocaleMonthNames, - getLocaleNumberSymbol, - NumberSymbol, - TranslationWidth, -} from '@angular/common'; -import { isDevMode } from '@angular/core'; -import { DATE_FORMATS_SPLIT, getNamedFormat } from './format-date'; -import { BasicDateFormat, DatePartFormat } from '../model/ng-date-public.model'; - -/* -export function parseDate(value: string, format: string, locale: string, oldValue: Date = null): Date { - return getDateFormatParser(locale, format).parseDate(value, oldValue); -} -*/ - -export enum DateType { - FullYear, - Month, - Date, - Hours_24, - Hours_12, - Minutes, - Seconds, - FractionalSeconds, - DayOfWeek, - - DayPeriods, - Eras, - TimeZoneOffset, -} - -function valueToNumber(value: number | string): number { - if (typeof value === 'string') return parseInt(value, 10); - return value; -} - -interface DateParser { - errorMsg: string; - types: DateType[]; - - parseDate(text: string, oldValue?: Date): Date; -} - -function createErrorParser(format: BasicDateFormat | string, msg: string) { - return { - errorMsg: `${msg}`, - types: undefined, - parseDate: (text: string, oldValue: Date = null): Date => { - try { - console.error(`DateParser for format '${format}' has error: ${msg}`); - // eslint-disable-next-line no-empty - } catch (e) {} - - return oldValue; - }, - }; -} - -function normalizeString(text: string): string { - if (!text) return ''; - - // remove diacritical chars - text = text - .normalize('NFD') - .replace(/[\u0300-\u036f]/g, '') - .trim(); - - return text; -} - -function normalizeStringForRegexp(text: string): string { - if (!text) return ''; - - text = normalizeString(text); - - // regexp escape + space replace with - return ( - text - - // $& means the whole matched string - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - // replace white space with '\s+ regexp part' - .replace(/\s+/, '\\s+') - ); -} - -interface StrPartStructure { - regexp: string; - mapRegexpPerValue: { [locale: string]: number }; -} - -const REGEXP_STR_NAMES: { [locale: string]: StrPartStructure } = {}; - -function getStrPartStructure( - locale: string, - type: DateType, - width: TranslationWidth, - form: FormStyle = FormStyle.Format, - extended = false -): StrPartStructure { - if (!locale) locale = 'en_US'; - const key = `${locale || ''}:${type}:${width}:${form}:${extended}`; - if (!REGEXP_STR_NAMES[key]) { - const ret = { - mapRegexpPerValue: {}, - } as StrPartStructure; - REGEXP_STR_NAMES[key] = ret; - switch (type) { - case DateType.Month: - getLocaleMonthNames(locale, form, width).forEach((name, value) => { - const regexp = normalizeStringForRegexp(name); - ret.mapRegexpPerValue[regexp] = value + 1; - }); - break; - case DateType.DayOfWeek: - getLocaleDayNames(locale, form, width).forEach((name, value) => { - const regexp = normalizeStringForRegexp(name); - ret.mapRegexpPerValue[regexp] = value; - }); - break; - case DateType.DayPeriods: - getLocaleDayPeriods(locale, form, width).forEach((name, value) => { - const regexp = normalizeStringForRegexp(name); - ret.mapRegexpPerValue[regexp] = value; - }); - break; - case DateType.Eras: - getLocaleEraNames(locale, width).forEach((name, value) => { - const regexp = normalizeStringForRegexp(name); - ret.mapRegexpPerValue[regexp] = value; - }); - break; - default: - throw new Error('Unknown names !!!'); - } - ret.regexp = `(${Object.keys(ret.mapRegexpPerValue).join('|')})`; - } - return REGEXP_STR_NAMES[key]; -} - -class DatePart { - private constructor( - public regexp: string, - public regexpGroup: number, - public type: DateType = null, - public parseValue: (parsedArray: RegExpExecArray, arrayIndex: number, dtValue: Date) => number | string = null - ) {} - - static ignoreText(text: string): DatePart { - return new DatePart(normalizeStringForRegexp(text), null, null); - } - - private static defaultParseValueAsString: ( - parsedArray: RegExpExecArray, - arrayIndex: number, - dtValue: Date - ) => number | string = (parsedArray: RegExpExecArray, arrayIndex: number, dtValue: Date) => { - const strValue = parsedArray[arrayIndex + 1]; - return (strValue || '').trim(); // vrati to ako string - aby sme vedeli pocet znakov - }; - - public static defaultParseValueAsNumber: ( - parsedArray: RegExpExecArray, - arrayIndex: number, - dtValue: Date - ) => number | string = (parsedArray: RegExpExecArray, arrayIndex: number, dtValue: Date) => { - const strValue = parsedArray[arrayIndex + 1]; - return valueToNumber(strValue); // vrati to ako string - aby sme vedeli pocet znakov - }; - - static parsePartSimple( - regexp: string, - type: DateType, - parseValue: ( - parsedArray: RegExpExecArray, - arrayIndex: number, - dtValue: Date - ) => number | string = DatePart.defaultParseValueAsString - ): DatePart { - return new DatePart(`(${regexp})`, 1, type, parseValue); - } - - static parsePartRegexp( - regexp: string, - regexpGroups: number, - type: DateType, - parseValue: ( - parsedArray: RegExpExecArray, - arrayIndex: number, - dtValue: Date - ) => number | string = DatePart.defaultParseValueAsString - ): DatePart { - return new DatePart(regexp, regexpGroups, type, parseValue); - } - - /* - * ([+-])(\d\d)(\d\d) - * ([+-])(\d\d):(\d\d) - * GMT([+-])(d+) - * GMT([+-])(\d\d)(\d\d) - * (Z|([+-])(\\d\\d):(\\d\\d)) - */ - static parsePartTimeZone(locale: string, regexp: string, regexpGroups: number): DatePart { - regexp = normalizeString(regexp); - const plus = normalizeString(getLocaleNumberSymbol(locale, NumberSymbol.PlusSign)); - const minus = normalizeString(getLocaleNumberSymbol(locale, NumberSymbol.MinusSign)); - - if (plus !== '+' || minus !== '-') { - regexp = regexp.replace('([+-])', `(${normalizeStringForRegexp(plus)}|${normalizeStringForRegexp(minus)}|\\+|\\-)`); - } // todo: dokoncit sposoby parsovania - return new DatePart(regexp, regexpGroups, DateType.TimeZoneOffset, (parsedArray: RegExpExecArray, arrayIndex: number) => { - if (regexpGroups == 4) { - // (Z|([+-])(\\d\\d):(\\d\\d)) - if (parsedArray[arrayIndex + 1] === 'Z') return 0; - arrayIndex++; - } - - const sign = parsedArray[arrayIndex + 1]; - const h = parsedArray[arrayIndex + 2]; - const m = regexpGroups > 2 ? parsedArray[arrayIndex + 3] : '0'; - - const ret = parseInt(h, 10) * 60 + parseInt(m, 10); - if (sign == '-' || sign == minus) { - return ret; - } - return -ret; - }); - } - - static ignorePart(regexp: string): DatePart { - return new DatePart(regexp, null, null); - } - - static parseStrPart( - locale: string, - type: DateType, - /* name: TranslationType, */ width: TranslationWidth, - form: FormStyle = FormStyle.Format, - extended = false - ): DatePart { - const structure = getStrPartStructure(locale, type, width, form, extended); - return new DatePart(structure.regexp, 1, type, (parsedArray: RegExpExecArray, arrayIndex: number, dtValue: Date) => { - const strValue = parsedArray[arrayIndex + 1]; - if (!strValue) return null; - - // eslint-disable-next-line no-restricted-syntax - for (const regexp in structure.mapRegexpPerValue) { - if (strValue.match(new RegExp(regexp))) { - return structure.mapRegexpPerValue[regexp]; - } - } - return null; - }); - } - - static ignoreStrPart( - locale: string, - type: DateType, - width: TranslationWidth, - form: FormStyle = FormStyle.Format, - extended = false - ): DatePart { - const structure = getStrPartStructure(locale, type, width, form, extended); - return new DatePart(structure.regexp, 0, null, () => null); // ignored - } -} - -// if (DATE_PARSERS[format]) { -// return DATE_PARSERS[format]; -// } - -// type DateParser = (value: string, updateValue: Date, locale: string) => string; -// const DATE_PARSERS: { [format: string]: DateParser } = {}; -function getDatePartParser(locale: string, format: DatePartFormat): DatePart | null { - // if (DATE_PARSERS[format]) { - // return DATE_PARSERS[format]; - // } - let formatter = null; - switch (format) { - // Era name (AD/BC) - case 'G': - case 'GG': - case 'GGG': - throw Error(`Unsupported parsing format '${format}'`); - // formatter = dateStrGetter(DateType.Eras, TranslationWidth.Abbreviated); - break; - case 'GGGG': - // formatter = dateStrGetter(DateType.Eras, TranslationWidth.Wide); - throw Error(`Unsupported parsing format '${format}'`); - break; - case 'GGGGG': - // formatter = dateStrGetter(DateType.Eras, TranslationWidth.Narrow); - throw Error(`Unsupported parsing format '${format}'`); - break; - - // 1 digit representation of the year, e.g. (AD 1 => 1, AD 199 => 199) - case 'y': - formatter = DatePart.parsePartRegexp('(\\d{1,4})', 1, DateType.FullYear, DatePart.defaultParseValueAsNumber); - break; - - // 2 digit representation of the year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10) - case 'yy': - formatter = DatePart.parsePartRegexp( - '(\\d{2})', - 1, - DateType.FullYear, - (parsedArray: RegExpExecArray, arrayIndex: number, dtValue: Date) => { - const value = parsedArray[arrayIndex + 1]; - const strFullYear = `${dtValue.getFullYear()}`; - if (strFullYear.length <= value.length) { - return valueToNumber(value); - } - const newFullYear = strFullYear.substr(0, strFullYear.length - value.length) + value; - return valueToNumber(newFullYear); - } - ); - break; - - // 3 digit representation of the year, padded (000-999). (e.g. AD 2001 => 01, AD 2010 => 10) - case 'yyy': - // formatter = DatePart.parsePart('\\d{3}', DateType.FullYear, (value:string, dtValue: Date) => { - // var strFullYear = dtValue.getFullYear() + ""; - // if (strFullYear.length<=value.length) { - // return valueToNumber(value); - // } - // const newFullYear = strFullYear.substr(0, strFullYear.length-value.length)+value; - // return valueToNumber(newFullYear); - // }); - formatter = DatePart.parsePartRegexp('(\\d{3,5})', 1, DateType.FullYear); - break; - // 4 digit representation of the year (e.g. AD 1 => 0001, AD 2010 => 2010) - case 'yyyy': - formatter = DatePart.parsePartRegexp('(\\d{4,5})', 1, DateType.FullYear); - break; - - // 1 digit representation of the week-numbering year, e.g. (AD 1 => 1, AD 199 => 199) - case 'Y': - formatter = DatePart.parsePartRegexp('(\\d{1,5})', 1, DateType.FullYear); - break; - // 2 digit representation of the week-numbering year, padded (00-99). (e.g. AD 2001 => 01, AD - // 2010 => 10) - case 'YY': - formatter = DatePart.parsePartRegexp( - '(\\d{2})', - 1, - DateType.FullYear, - (parsedArray: RegExpExecArray, arrayIndex: number, dtValue: Date) => { - let value = parsedArray[arrayIndex + 1]; - - const strFullYear = `${dtValue.getFullYear()}`; - if (value.length < 2) value = `0${value}`; - if (strFullYear.length <= value.length) { - return valueToNumber(value); - } - const newFullYear = strFullYear.substr(0, strFullYear.length - value.length) + value; - return valueToNumber(newFullYear); - } - ); - break; - // 3 digit representation of the week-numbering year, padded (000-999). (e.g. AD 1 => 001, AD - // 2010 => 2010) - case 'YYY': - // 4 digit representation of the week-numbering year (e.g. AD 1 => 0001, AD 2010 => 2010) - formatter = DatePart.parsePartRegexp('(\\d{3,5})', 1, DateType.FullYear); - break; - case 'YYYY': - // throw Error("Unsupported parsing format: " + format); - formatter = DatePart.parsePartRegexp('(\\d{4,5})', 1, DateType.FullYear); - break; - - // Month of the year (1-12), numeric - case 'M': - case 'L': - case 'MM': - case 'LL': - formatter = DatePart.parsePartRegexp('(\\d{1,2})', 1, DateType.Month); - break; - - // Month of the year (January, ...), string, format - case 'MMM': - formatter = DatePart.parseStrPart(locale, DateType.Month, TranslationWidth.Abbreviated); - break; - case 'MMMM': - formatter = DatePart.parseStrPart(locale, DateType.Month, TranslationWidth.Wide); - break; - case 'MMMMM': - formatter = DatePart.parseStrPart(locale, DateType.Month, TranslationWidth.Narrow); - break; - - // Month of the year (January, ...), string, standalone - case 'LLL': - formatter = DatePart.parseStrPart(locale, DateType.Month, TranslationWidth.Abbreviated, FormStyle.Standalone); - break; - case 'LLLL': - formatter = DatePart.parseStrPart(locale, DateType.Month, TranslationWidth.Wide, FormStyle.Standalone); - break; - case 'LLLLL': - formatter = DatePart.parseStrPart(locale, DateType.Month, TranslationWidth.Narrow, FormStyle.Standalone); - break; - - // Week of the year (1, ... 52) - case 'w': - case 'ww': - formatter = DatePart.ignorePart('\\d{1,2}'); - // formatter = weekParser(2); - break; - - // Week of the month (1, ...) - case 'W': - formatter = DatePart.ignorePart('\\d{1}'); - // formatter = weekParser(1, true); - break; - - // Day of the month (1-31) - case 'd': - case 'dd': - formatter = DatePart.parsePartRegexp('(\\d{1,2})', 1, DateType.Date); - break; - - // Day of the Week - case 'E': - case 'EE': - case 'EEE': - formatter = DatePart.ignoreStrPart(locale, DateType.DayOfWeek, TranslationWidth.Abbreviated); - break; - case 'EEEE': - formatter = DatePart.ignoreStrPart(locale, DateType.DayOfWeek, TranslationWidth.Wide); - break; - case 'EEEEE': - formatter = DatePart.ignoreStrPart(locale, DateType.DayOfWeek, TranslationWidth.Narrow); - break; - case 'EEEEEE': - formatter = DatePart.ignoreStrPart(locale, DateType.DayOfWeek, TranslationWidth.Short); - break; - - // Generic period of the day (am-pm) - case 'a': - case 'aa': - case 'aaa': - formatter = DatePart.parseStrPart(locale, DateType.DayPeriods, TranslationWidth.Abbreviated); - break; - case 'aaaa': - formatter = DatePart.parseStrPart(locale, DateType.DayPeriods, TranslationWidth.Wide); - break; - case 'aaaaa': - formatter = DatePart.parseStrPart(locale, DateType.DayPeriods, TranslationWidth.Narrow); - break; - - // Extended period of the day (midnight, at night, ...), standalone - case 'b': - case 'bb': - case 'bbb': - case 'bbbb': - case 'bbbbb': - // formatter = DatePart.ignoreStrPart(locale, DateType.DayPeriods, TranslationWidth.Narrow, FormStyle.Standalone, true); - // break; - throw Error(`Unsupported parsing format '${format}'`); - - // Extended period of the day (midnight, night, ...), standalone - case 'B': - case 'BB': - case 'BBB': - case 'BBBB': - case 'BBBBB': - throw Error(`Unsupported parsing format '${format}'`); - - // Hour in AM/PM, (1-12) - case 'h': - case 'hh': - formatter = DatePart.parsePartRegexp('(\\d{1,2})', 1, DateType.Hours_12); - break; - - // Hour of the day (0-23) - case 'H': - case 'HH': - formatter = DatePart.parsePartRegexp('(\\d{1,2})', 1, DateType.Hours_24); - break; - - // Minute of the hour (0-59) - case 'm': - case 'mm': - formatter = DatePart.parsePartRegexp('(\\d{1,2})', 1, DateType.Minutes); - break; - - // Second of the minute (0-59) - case 's': - case 'ss': - formatter = DatePart.parsePartRegexp('(\\d{1,2})', 1, DateType.Seconds); - break; - - // Fractional second - case 'S': - case 'SS': - case 'SSS': - formatter = DatePart.parsePartRegexp('(\\d{1,3})', 1, DateType.FractionalSeconds); - break; - - // Timezone ISO8601 short format (-0430) - case 'Z': - case 'ZZ': - case 'ZZZ': - formatter = DatePart.parsePartTimeZone(locale, `([+-])(\\d\\d)(\\d\\d)`, 3); - break; - // Timezone ISO8601 extended format (-04:30) - case 'ZZZZZ': - formatter = DatePart.parsePartTimeZone(locale, `(Z|([+-])(\\d\\d):(\\d\\d))`, 4); - break; - - // Timezone GMT short format (GMT+4) - case 'O': - case 'OO': - case 'OOO': - case 'z': - case 'zz': - case 'zzz': - formatter = DatePart.parsePartTimeZone(locale, 'GMT([+-])(\\d+)', 2); - // formatter = timeZoneGetter(ZoneWidth.ShortGMT); - // throw Error(`Unsupported parsing format '${format}'`); - break; - // Timezone GMT long format (GMT+0430) - case 'OOOO': - case 'ZZZZ': - case 'zzzz': - // formatter = timeZoneGetter(ZoneWidth.Long); - // throw Error(`Unsupported parsing format '${format}'`); - formatter = DatePart.parsePartTimeZone(locale, `GMT([+-])(\\d\\d):?(\\d\\d)`, 3); - break; - default: - // ignored text part - formatter = DatePart.ignoreText(format); - } - if (!formatter) { - throw Error(`Unsupported part '${format}'`); - } - // DATE_PARSERS[format] = formatter; - return formatter; -} - -const DateParserMaps: { [key: string]: DateParser } = {}; - -export function getDateFormatParser(locale: string, format: BasicDateFormat | string): DateParser | null { - const namedFormat = getNamedFormat(locale, format as BasicDateFormat); - format = namedFormat || format; - const originalFormat = format; - if (!format) return createErrorParser(format, 'bad format'); - if (!locale) locale = 'en_US'; - const key = `${locale}:${format}`; - if (DateParserMaps[key]) return DateParserMaps[key]; - - try { - const parsers: DatePart[] = []; - - let match; - while (format) { - if (!format || format.trim().length === 0) break; - - match = DATE_FORMATS_SPLIT.exec(format); - if (match) { - const formatParts = match.splice(1); - const part = formatParts.pop(); - - if (formatParts && formatParts.length) { - formatParts.forEach((formatPart) => { - if (!formatPart || formatPart.trim().length === 0) return; - parsers.push(getDatePartParser(locale, formatPart)); - }); - } - - format = part; - } else { - parsers.push(getDatePartParser(locale, format as DatePartFormat)); - break; - } - } - - let lineRegexp = null; - // eslint-disable-next-line no-restricted-syntax - for (const parser of parsers) { - if (!parser.regexp || parser.regexp.trim().length === 0) continue; - if (lineRegexp) lineRegexp += '\\s*'; - else lineRegexp = '^'; - lineRegexp += parser.regexp; - } - lineRegexp += '$'; - const strValueRegexp = new RegExp(lineRegexp, 'i'); - - const ret = { - types: parsers.map((p) => p.type).filter((t) => t != null), - parseDate(text: string, dtValue: Date = null): Date { - try { - dtValue = dtValue || null; - // empty date - if (!text || text.trim().length === 0) return null; - - // parse string - const matchedInput = strValueRegexp.exec(normalizeString(text)); - if (!matchedInput) { - if (isDevMode()) { - console.error(`DateParser with format '${originalFormat}' cannot parse date from '${text}'`); - } - return null; - } - - // value updates ... - // let retValue = null; - // if (dtValue) retValue = new Date(dtValue.getTime()); - // if (!retValue) { - // retValue = new Date(0); - // retValue.setMilliseconds(0); - // retValue.setSeconds(0); - // } - - // TODO - mfilo - 31.01.2021 - tmp fix - const retValue = new Date(0); - retValue.setHours(0); - retValue.setMinutes(0); - retValue.setSeconds(0); - retValue.setMilliseconds(0); - - // reading part values - const values = new Map(); - let groupInx = 0; - // eslint-disable-next-line no-restricted-syntax - for (const parser of parsers) { - // if function for value parsing missing => part of string is not in group and it is ignored - if (!parser.regexpGroup || !parser.parseValue) continue; - - // if valueType is null => value is ignored - if (!parser.type && parser.type !== 0) { - groupInx += parser.regexpGroup; - continue; - } // ak nema typ, ignorujeme hodnotu tiez - - const value = parser.parseValue(matchedInput, groupInx, retValue); - groupInx += parser.regexpGroup; - - // if value == null, value is ignored - if (value === null || value === undefined) continue; - values.set(parser.type, value); - } - - if (!values.size) { - if (isDevMode()) { - console.info(`DateParser with format '${originalFormat}' cannot parse date from '${text}'`); - } - return dtValue; - } - - if (values.has(DateType.FullYear)) { - retValue.setFullYear(valueToNumber(values.get(DateType.FullYear))); - } - if (values.has(DateType.Month)) { - retValue.setMonth(valueToNumber(values.get(DateType.Month)) - 1); - } - if (values.has(DateType.Date)) { - retValue.setDate(valueToNumber(values.get(DateType.Date))); - } - if (values.has(DateType.Hours_24)) { - retValue.setHours(valueToNumber(values.get(DateType.Hours_24))); - } - if (values.has(DateType.Hours_12)) { - const hours12 = valueToNumber(values.get(DateType.Hours_12)); - if (hours12 > 12) { - console.error(`DateParser with format '${originalFormat}' cannot parse date from '${text}'`); - return null; - } - const inAM = retValue.getHours() < 12; - retValue.setHours((hours12 % 12) + (inAM ? 0 : 12)); - } - if (values.has(DateType.DayPeriods)) { - const period = valueToNumber(values.get(DateType.DayPeriods)) || 0; - const currentPeriod = retValue.getHours() < 12 ? 0 : 1; - if (currentPeriod !== period) { - if (period) { - retValue.setHours(retValue.getHours() + 12); - } else { - retValue.setHours(retValue.getHours() - 12); - } - } - } - if (values.has(DateType.Minutes)) { - retValue.setMinutes(valueToNumber(values.get(DateType.Minutes))); - } - if (values.has(DateType.Seconds)) { - retValue.setSeconds(valueToNumber(values.get(DateType.Seconds))); - } - if (values.has(DateType.FractionalSeconds)) { - retValue.setMilliseconds(valueToNumber(values.get(DateType.FractionalSeconds)) % 1000); - } - - if (values.has(DateType.TimeZoneOffset)) { - const v = valueToNumber(values.get(DateType.TimeZoneOffset)); - if (v != retValue.getTimezoneOffset()) { - const move = -retValue.getTimezoneOffset() + v; - retValue.setMinutes(retValue.getMinutes() + move); - } - } - - return retValue; - } catch (e) { - try { - if (isDevMode()) { - console.error('DateParser throw error', e); - } - // eslint-disable-next-line no-empty - } catch (eee) {} - return null; - } - }, - errorMsg: null, - } as DateParser; - - DateParserMaps[key] = ret; - - // for tests - if (getDateFormatParser['run_in_tests']) { - ret['lineRegexp'] = lineRegexp; - ret['parsers'] = parsers; - } - } catch (e) { - if (isDevMode()) { - console.error(e); - } - DateParserMaps[key] = createErrorParser(format, e || 'unsupported format!'); - return DateParserMaps[key]; - } - - return DateParserMaps[key]; -} - -export function parseDate(value: string, format: BasicDateFormat | string, locale: string, oldValue: Date = null): Date | null{ - return getDateFormatParser(locale, format).parseDate(value, oldValue); -} diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/services/parse.service.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/services/parse.service.ts new file mode 100644 index 0000000..1b78650 --- /dev/null +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/services/parse.service.ts @@ -0,0 +1,35 @@ +import { Inject, Injectable, Optional } from '@angular/core'; +import { parseDate, toDate, getDateFormatParser, DateParser, BasicDateFormat } from '@annotation/ng-parse'; +import { NG_DATEPICKER_CONF } from '../conf/ng-datepicker.conf.token'; +import { NgDatepickerConf } from '../conf/ng-datepicker.conf'; + +@Injectable({ + providedIn: 'root', +}) +export class ParseService { + constructor(@Optional() @Inject(NG_DATEPICKER_CONF) private ngDatepickerConf: NgDatepickerConf) {} + + parseDate(value: string, format: BasicDateFormat | string, locale: string, oldValue?: Date): Date { + if (this.ngDatepickerConf?.parser?.parseDate) { + return this.ngDatepickerConf.parser.parseDate.call(this, value, format, locale, oldValue); + } + + return parseDate(value, format, locale, oldValue); + } + + getDateFormatParser(locale: string, format: BasicDateFormat): DateParser { + if (this.ngDatepickerConf?.parser?.getDateFormatParser) { + return this.ngDatepickerConf.parser.getDateFormatParser.call(this, locale, format); + } + + return getDateFormatParser(locale, format); + } + + toDate(value: string | number | Date): Date { + if (this.ngDatepickerConf?.parser?.toDate) { + return this.ngDatepickerConf.parser.toDate.call(this, value); + } + + return toDate(value); + } +} diff --git a/ng-a-date-picker/projects/ng-datepicker/src/lib/services/service-locator.ts b/ng-a-date-picker/projects/ng-datepicker/src/lib/services/service-locator.ts new file mode 100644 index 0000000..36d89ce --- /dev/null +++ b/ng-a-date-picker/projects/ng-datepicker/src/lib/services/service-locator.ts @@ -0,0 +1,7 @@ +import { Injector } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +export class ServiceLocator { + public static injector: Injector = null; + public static onReady: BehaviorSubject = new BehaviorSubject(false); +} diff --git a/ng-a-date-picker/projects/ng-datepicker/src/public-api.ts b/ng-a-date-picker/projects/ng-datepicker/src/public-api.ts index 04e3501..182921f 100644 --- a/ng-a-date-picker/projects/ng-datepicker/src/public-api.ts +++ b/ng-a-date-picker/projects/ng-datepicker/src/public-api.ts @@ -3,8 +3,6 @@ export * from './lib/directives/ng-date/ng-date.directive'; export * from './lib/directives/ng-date/ng-date.directive.api'; export * from './lib/model/ng-date-public.model'; -export * from './lib/parsers/format-date'; -export * from './lib/parsers/parse-date'; export * from './lib/converters/converter-api'; export * from './lib/directives/validators/max-date.directive'; @@ -12,3 +10,4 @@ export * from './lib/directives/validators/min-date.directive'; export * from './lib/directives/validators/validate.conf'; export * from './lib/components/popup/popup.component'; +export * from '@annotation/ng-parse'; diff --git a/ng-a-date-picker/yarn.lock b/ng-a-date-picker/yarn.lock index db957a6..6f5475c 100644 --- a/ng-a-date-picker/yarn.lock +++ b/ng-a-date-picker/yarn.lock @@ -276,6 +276,13 @@ dependencies: tslib "^2.0.0" +"@annotation/ng-parse@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@annotation/ng-parse/-/ng-parse-1.0.0.tgz#27e59f0cc6829cdafcb60413007a997fa45b784d" + integrity sha512-ZBjleIqjDwY9PkkTKjNrhRfwZN73QRkrFCZjRbGo/95FahiFKTqQGJm+6BzGS4TCuRUq1I5KKr1JR9pK4x8+kw== + dependencies: + tslib "^2.0.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"