@@ -10,6 +10,50 @@ import {
1010 getZoneNameForLocale
1111} from './lookup-utill.js' ;
1212
13+ // Used to get the value of a super function without class syntax
14+ // This is taken (and slightly modified) from Babel's output for
15+ // ES6 class syntax
16+ function _get ( object , property , receiver ) {
17+ if ( object === null )
18+ object = Function . prototype ;
19+ let desc = Object . getOwnPropertyDescriptor ( object , property ) ;
20+ if ( desc === undefined ) {
21+ let parent = Object . getPrototypeOf ( object ) ;
22+ if ( parent === null ) {
23+ return undefined ;
24+ }
25+ return _get ( parent , property , receiver ) ;
26+ }
27+ if ( "value" in desc ) {
28+ return desc . value ;
29+ }
30+ let getter = desc . get ;
31+ if ( getter === undefined ) {
32+ return undefined ;
33+ }
34+ return getter . call ( receiver ) ;
35+ }
36+
37+ // Also from Babel, minimal subclassing utility function
38+ function _inherits ( subClass , superClass ) {
39+ if ( typeof superClass !== "function" && superClass !== null ) {
40+ throw new TypeError ( "Super expression must either be null or a function, not " + typeof superClass ) ;
41+ }
42+ subClass . prototype = Object . create ( superClass && superClass . prototype , {
43+ constructor : {
44+ value : subClass ,
45+ enumerable : false ,
46+ writable : true ,
47+ configurable : true
48+ }
49+ } ) ;
50+ if ( superClass ) {
51+ Object . setPrototypeOf
52+ ? Object . setPrototypeOf ( subClass , superClass )
53+ : subClass . __proto__ = superClass ;
54+ }
55+ }
56+
1357/**
1458* Pollyfill ECMA402 DateTimeFormat
1559* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/format
@@ -26,74 +70,93 @@ export default function polyfill(globalSpace) {
2670 const jsonClone = function ( o ) {
2771 return JSON . parse ( JSON . stringify ( o ) ) ;
2872 } ;
73+ const _DateTimeFormat = gIntl . DateTimeFormat ;
2974
30- gIntl . _DateTimeFormat = gIntl . DateTimeFormat ;
75+ gIntl . _DateTimeFormat = _DateTimeFormat ;
3176
3277 gIntl . _DateTimeFormatTimeZone = {
3378 checkTimeZoneSupport : checkTimeZoneSupport
3479 } ;
3580
36- class DateTimeFormatPolyfill extends gIntl . _DateTimeFormat {
37-
38- constructor ( locale , options ) {
39- const timeZone = ( options && options . timeZone ) || 'UTC' ;
40-
41- if ( options === undefined ) {
42- // options is not provided. this means
43- // we don't need to format arbitrary timezone
44- super ( locale , options ) ;
81+ function DateTimeFormatPolyfill ( locale , options ) {
82+ if ( ! ( this instanceof DateTimeFormatPolyfill ) ) {
83+ return new DateTimeFormatPolyfill ( locale , options ) ;
84+ }
4585
46- return ;
47- }
86+ const timeZone = ( options && options . timeZone ) || 'UTC' ;
4887
49- if ( checkTimeZoneSupport ( timeZone ) ) {
50- // native method has support for timezone. no polyfill logic needed.
51- super ( locale , options ) ;
88+ if ( options === undefined ) {
89+ // options is not provided. this means
90+ // we don't need to format arbitrary timezone
91+ _DateTimeFormat . call ( this , locale , options ) ;
5292
53- return ;
54- }
93+ return ;
94+ }
5595
56- const timeZoneData = gIntl . _timeZoneData . get ( timeZone ) ;
96+ if ( checkTimeZoneSupport ( timeZone ) ) {
97+ // native method has support for timezone. no polyfill logic needed.
98+ _DateTimeFormat . call ( this , locale , options ) ;
5799
58- // check if we have timezone data for this timezone
59- if ( ! timeZoneData ) {
60- throw new RangeError ( `invalid time zone in DateTimeFormat(): ${ timeZone } ` ) ;
61- }
100+ return ;
101+ }
62102
63- // Do a timeshift to UTC to avoid explosion due to unsupprted timezone.
64- const tsOption = jsonClone ( options ) ;
65- tsOption . timeZone = 'UTC' ;
66- super ( locale , tsOption ) ;
103+ const timeZoneData = gIntl . _timeZoneData . get ( timeZone ) ;
67104
68- const resolvedLocale = super . resolvedOptions ( ) . locale ;
105+ // check if we have timezone data for this timezone
106+ if ( ! timeZoneData ) {
107+ throw new RangeError ( `invalid time zone in DateTimeFormat(): ${ timeZone } ` ) ;
108+ }
69109
70- if ( options . timeZoneName !== undefined ) {
71- // We need to include timeZoneName in date format.
72- // Check if we have locale data to able to do that.
73- if ( ! ( gIntl . _localeData . get ( resolvedLocale ) && // availability of localedata
74- Intl . _metaZoneData . get ( timeZone ) ) ) { // availability of metaZone for this timeZone
75- throw new RangeError ( `unsupported value "${ options . timeZoneName } " for timeZone ${ timeZone } . requires locale data for ${ resolvedLocale } ` ) ;
76- }
110+ // Do a timeshift to UTC to avoid explosion due to unsupprted timezone.
111+ const tsOption = jsonClone ( options ) ;
112+ tsOption . timeZone = 'UTC' ;
113+ _DateTimeFormat . call ( this , locale , tsOption ) ;
114+
115+ const _resolvedOptions = _get (
116+ DateTimeFormatPolyfill . prototype . __proto__ ||
117+ Object . getPrototypeOf ( DateTimeFormatPolyfill . prototype ) ,
118+ 'resolvedOptions' ,
119+ this
120+ ) ;
121+
122+ const resolvedLocale = _resolvedOptions . call ( this ) . locale ;
123+
124+ if ( options . timeZoneName !== undefined ) {
125+ // We need to include timeZoneName in date format.
126+ // Check if we have locale data to able to do that.
127+ if ( ! ( gIntl . _localeData . get ( resolvedLocale ) && // availability of localedata
128+ Intl . _metaZoneData . get ( timeZone ) ) ) { // availability of metaZone for this timeZone
129+ throw new RangeError ( `unsupported value "${ options . timeZoneName } " for timeZone ${ timeZone } . requires locale data for ${ resolvedLocale } ` ) ;
77130 }
78-
79- // to minimize pollution everything we need to perform polyfill is wrapped under one object.
80- this . _dateTimeFormatPolyfill = {
81- optionTimeZone : timeZone ,
82- optionTimeZoneName : options . timeZoneName ,
83- timeZoneData : timeZoneData
84- } ;
85-
86- return this ;
87131 }
88132
89- supportedLocalesOf ( ) {
90- // there is no need to modify behaviour of this function.
91- return super . supportedLocalesOf ( ) ;
92- }
133+ // to minimize pollution everything we need to perform polyfill is wrapped under one object.
134+ this . _dateTimeFormatPolyfill = {
135+ optionTimeZone : timeZone ,
136+ optionTimeZoneName : options . timeZoneName ,
137+ timeZoneData : timeZoneData
138+ } ;
139+ }
140+ _inherits ( DateTimeFormatPolyfill , _DateTimeFormat ) ;
141+
142+ Object . defineProperty ( DateTimeFormatPolyfill . prototype , 'format' , {
143+ configurable : true ,
144+ value : function ( date ) {
145+ const _format = _get (
146+ DateTimeFormatPolyfill . prototype . __proto__ ||
147+ Object . getPrototypeOf ( DateTimeFormatPolyfill . prototype ) ,
148+ 'format' ,
149+ this
150+ ) ;
151+ const _resolvedOptions = _get (
152+ DateTimeFormatPolyfill . prototype . __proto__ ||
153+ Object . getPrototypeOf ( DateTimeFormatPolyfill . prototype ) ,
154+ 'resolvedOptions' ,
155+ this
156+ ) ;
93157
94- format ( date ) {
95158 if ( ! this . _dateTimeFormatPolyfill ) {
96- return super . format ( date ) ;
159+ return _format . call ( this , date ) ;
97160 }
98161
99162 if ( date === null || date === undefined ) {
@@ -108,8 +171,8 @@ export default function polyfill(globalSpace) {
108171 const timeZoneOffsetInfo = getTimeZoneOffsetInfo ( polyfill . timeZoneData , date ) ;
109172 const timeZoneOffset = timeZoneOffsetInfo . offset * 60000 ;
110173 const shiftedDate = new Date ( date . getTime ( ) + timeZoneOffset ) ; // We need to format time by offseting it
111- const shiftedFormat = super . format ( shiftedDate ) ; // offseted or shifted format
112- const resolvedLocale = super . resolvedOptions ( ) . locale ;
174+ const shiftedFormat = _format . call ( this , shiftedDate ) ; // offseted or shifted format
175+ const resolvedLocale = _resolvedOptions . call ( this ) . locale ;
113176 const doNeedToReplaceTimeZoneName = ( polyfill . optionTimeZoneName !== undefined ) ;
114177
115178 if ( doNeedToReplaceTimeZoneName ) {
@@ -145,20 +208,31 @@ export default function polyfill(globalSpace) {
145208
146209 return shiftedFormat ;
147210 }
211+ } ) ;
212+
213+ Object . defineProperty ( DateTimeFormatPolyfill . prototype , 'resolvedOptions' , {
214+ writable : true ,
215+ configurable : true ,
216+ value : function ( ) {
217+ const _resolvedOptions = _get (
218+ DateTimeFormatPolyfill . prototype . __proto__ ||
219+ Object . getPrototypeOf ( DateTimeFormatPolyfill . prototype ) ,
220+ 'resolvedOptions' ,
221+ this
222+ ) ;
148223
149- resolvedOptions ( ) {
150224 if ( this . _dateTimeFormatPolyfill ) {
151- // since we have altered timezone option for super .
225+ // since we have altered timezone option for _DateTimeFormat .
152226 // we need to correct that before returing.
153- const options = jsonClone ( super . resolvedOptions ( ) ) ;
227+ const options = jsonClone ( _resolvedOptions . call ( this ) ) ;
154228 options . timeZone = this . _dateTimeFormatPolyfill . optionTimeZone ;
155229
156230 return options ;
157231 }
158232
159- return super . resolvedOptions ( ) ;
233+ return _resolvedOptions . call ( this ) ;
160234 }
161- }
235+ } ) ;
162236
163237 gIntl . DateTimeFormat = DateTimeFormatPolyfill ;
164238
0 commit comments