@reykjavik/webtools 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  - ... <!-- Add new lines here. -->
6
6
 
7
+ ## 0.1.16
8
+
9
+ _2024-03-09_
10
+
11
+ - `@reykjavik/webtools/fixIcelandicLocale`:
12
+ - fix: Add missing `DateTimeFormat.format*ToParts` methods, fix bugs
13
+ - refctor: Reduce code-size and simplify logic by dog-fooding `*ToParts`
14
+ methods internally
15
+
7
16
  ## 0.1.15
8
17
 
9
18
  _2024-03-08_
package/README.md CHANGED
@@ -437,7 +437,7 @@ substituting the `is` locale with `da` (Danish) and apply a few post-hoc fixes
437
437
  to their return values.
438
438
 
439
439
  - `Intl.Collator` and `String.prototype.localeCompare`
440
- - `Intl.NumzberFormat` and `Number.prototype.toLocaleString`
440
+ - `Intl.NumberFormat` and `Number.prototype.toLocaleString`
441
441
  - `Intl.DateTimeFormat` and `Date.prototype.toLocaleDateString`
442
442
 
443
443
  This provides usable (but not perfect) results, with some caveats listed
@@ -475,13 +475,11 @@ detection test.)
475
475
  **`Intl.DateTimeFormat` and `toLocaleDateString`:**
476
476
 
477
477
  - The `month: 'narrow'` and `weekday: 'narrow'` options are not supported, and
478
- print the corresponding Danish initials
478
+ print the corresponding Danish initials.
479
479
  - For `timeZoneName` the values `"long"`, `"shortGeneric"` and `"longGeneric"`
480
480
  will appear in Danish.
481
- - The `timeStyle: 'full'` option prints timezone will appear in Danish
481
+ - The `timeStyle: 'full'` option prints the timezone names in Danish
482
482
  - The `dayPeriod` option is not supported and prints the day-period in Danish.
483
- - Custom formatted `DD.MM.YY` (2-digit year) dates turn into time-like
484
- `DD:MM:YY` strings.
485
483
 
486
484
  ---
487
485
 
@@ -19,6 +19,7 @@ const mapLocales = (locales) => {
19
19
  }
20
20
  }
21
21
  };
22
+ const combineParts = (parts) => parts.map(({ value }) => value).join('');
22
23
  // ===========================================================================
23
24
  // Collator
24
25
  // ===========================================================================
@@ -43,21 +44,6 @@ _patchedLocaleCompare.$original = _localeCompare;
43
44
  // ===========================================================================
44
45
  // NumberFormat
45
46
  // ===========================================================================
46
- const reformatNumber = function (result) {
47
- if (!this.mapped) {
48
- return result;
49
- }
50
- const options = this.super.resolvedOptions();
51
- if (options.style === 'currency' && options.currencyDisplay === 'symbol') {
52
- if (options.currency === 'DKK') {
53
- return result.replace(/kr\./g, 'DKK');
54
- }
55
- if (options.currency === 'ISK') {
56
- return result.replace(/ISK/g, 'kr.');
57
- }
58
- }
59
- return result;
60
- };
61
47
  const reformatNumberParts = function (parts) {
62
48
  if (!this.mapped) {
63
49
  return parts;
@@ -90,10 +76,10 @@ const PatchedNumberFormat = function NumberFormat(locales, options) {
90
76
  const numberFormatProto = {
91
77
  constructor: PatchedNumberFormat,
92
78
  format(value) {
93
- return reformatNumber.call(this, this.super.format(value));
79
+ return combineParts(this.formatToParts(value));
94
80
  },
95
81
  formatRange(value1, value2) {
96
- return reformatNumber.call(this, this.super.formatRange(value1, value2));
82
+ return combineParts(this.formatRangeToParts(value1, value2));
97
83
  },
98
84
  formatToParts(value) {
99
85
  return reformatNumberParts.call(this, this.super.formatToParts(value));
@@ -119,83 +105,75 @@ _patchedToLocaleString.$original = _toLocaleString;
119
105
  // ===========================================================================
120
106
  // DateTimeFormat
121
107
  // ===========================================================================
122
- const months = [
123
- ['januar', 'janúar', true],
124
- ['februar', 'febrúar'],
125
- ['marts', 'mars'],
126
- ['april', 'apríl'],
127
- ['maj', 'maí'],
128
- ['juni', 'júní', true],
129
- ['juli', 'júlí', true],
130
- ['august', 'ágúst', true],
131
- // ['september', 'september'],
132
- ['oktober', 'október'],
133
- ['november', 'nóvember', true],
134
- ['december', 'desember', true],
135
- ];
136
- const weekdays = [
137
- ['mandag', 'mánudagur'],
138
- ['tirsdag', 'þriðjudagur', 4],
139
- ['onsdag', 'miðvikudagur'],
140
- ['torsdag', 'fimmtudagur', 4],
141
- ['fredag', 'föstudagur'],
142
- ['lørdag', 'laugardagur'],
143
- ['søndag', 'sunnudagur'],
144
- ];
145
- const reformatDateTime = function (result) {
146
- if (!this.mapped) {
147
- return result;
148
- }
149
- const options = this.super.resolvedOptions();
150
- let mappedResult = result;
151
- let monthMatches = 0;
152
- for (let i = 0, month; (month = months[i]); i++) {
153
- const [da, is, checkShort] = month;
154
- mappedResult = mappedResult.replace(da, is);
155
- if (checkShort && mappedResult === result) {
156
- mappedResult = mappedResult.replace(da.slice(0, 3), is.slice(0, 3));
108
+ const months = {
109
+ jan: 'janúar',
110
+ feb: 'febrúar',
111
+ mar: 'mars',
112
+ apr: 'apríl',
113
+ maj: 'maí',
114
+ jun: 'júní',
115
+ jul: 'júlí',
116
+ aug: 'ágúst',
117
+ // sep: 'september', // is the same
118
+ okt: 'október',
119
+ nov: 'nóvember',
120
+ dec: 'desember',
121
+ };
122
+ const weekdays = {
123
+ man: 'mánudagur',
124
+ tir: 'þriðjudagur',
125
+ ons: 'miðvikudagur',
126
+ tor: 'fimmtudagur',
127
+ fre: 'föstudagur',
128
+ lør: 'laugardagur',
129
+ søn: 'sunnudagur',
130
+ };
131
+ const partMappers = {
132
+ month: (value) => {
133
+ const islMonth = months[value.slice(0, 3)];
134
+ if (islMonth) {
135
+ return value.endsWith('.') ? `${islMonth.slice(0, 3)}.` : islMonth;
157
136
  }
158
- if (mappedResult !== result) {
159
- monthMatches++;
160
- if (monthMatches >= 2) {
161
- break;
162
- }
137
+ },
138
+ weekday: (value) => {
139
+ const isl = weekdays[value.slice(0, 3)];
140
+ if (isl) {
141
+ return value.endsWith('.') ? `${isl.slice(0, 3)}.` : isl;
163
142
  }
164
- }
165
- result = mappedResult; // reset result
166
- let weekdayMatches = 0;
167
- for (let i = 0, weekday; (weekday = weekdays[i]); i++) {
168
- const [da, is, shortLength] = weekday;
169
- mappedResult = mappedResult.replace(da, is);
170
- if (mappedResult === result) {
171
- mappedResult = mappedResult.replace(da.slice(0, shortLength || 3), is.slice(0, 3));
143
+ },
144
+ era: (value) => {
145
+ if (!value.endsWith('.')) {
146
+ return value.length === 3
147
+ ? `${value[0]}.k.`
148
+ : value[0] === 'f'
149
+ ? 'fyrir Krist'
150
+ : 'eftir Krist';
151
+ }
152
+ },
153
+ dayPeriod: (value) => {
154
+ return { AM: 'f.h.', PM: 'e.h.' }[value] || value;
155
+ },
156
+ literal: (value, lastType) => {
157
+ if (value === ' den ') {
158
+ return 'inn ';
172
159
  }
173
- if (mappedResult !== result) {
174
- weekdayMatches++;
175
- if (weekdayMatches >= 2) {
176
- break;
177
- }
160
+ else if (value === '.' && (lastType === 'hour' || lastType === 'minute')) {
161
+ return ':';
178
162
  }
179
- }
180
- result = mappedResult;
181
- if (/Kristus/.test(result)) {
182
- result = result.replace(/før Kristus/g, 'fyrir Krist');
183
- result = result.replace(/efter Kristus/g, 'eftir Krist');
184
- }
185
- result = result.replace(/(f|e)Kr/g, '$1.k.');
186
- result = result.replace(/AM/g, 'f.h.');
187
- result = result.replace(/PM/g, 'e.h.');
188
- // convert timestamps from `00.00` to `00:00`
189
- result = result.replace(/(?:^|\s)\d\d\.\d\d(?:\.\d\d)?(?:,|\s|$)/g, (match) => match.replace(/\./g, ':'));
190
- result = result.replace(/ den/g, 'inn');
191
- return result;
163
+ },
192
164
  };
193
165
  const reformatDateTimeParts = function (parts) {
194
166
  if (!this.mapped) {
195
167
  return parts;
196
168
  }
197
- const options = this.super.resolvedOptions();
198
- // reformat
169
+ parts.forEach((part, idx) => {
170
+ var _a;
171
+ const mapper = partMappers[part.type];
172
+ const newValue = mapper && mapper(part.value, (_a = parts[idx - 1]) === null || _a === void 0 ? void 0 : _a.type);
173
+ if (newValue != null) {
174
+ part.value = newValue;
175
+ }
176
+ });
199
177
  return parts;
200
178
  };
201
179
  const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
@@ -220,10 +198,10 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
220
198
  const dateTimeFormatProto = {
221
199
  constructor: PatchedDateTimeFormat,
222
200
  format(value) {
223
- return reformatDateTime.call(this, this.super.format(value));
201
+ return combineParts(this.formatToParts(value));
224
202
  },
225
203
  formatRange(value1, value2) {
226
- return reformatDateTime.call(this, this.super.formatRange(value1, value2));
204
+ return combineParts(this.formatRangeToParts(value1, value2));
227
205
  },
228
206
  formatToParts(value) {
229
207
  return reformatDateTimeParts.call(this, this.super.formatToParts(value));
@@ -22,6 +22,7 @@ const mapLocales = (locales) => {
22
22
  }
23
23
  }
24
24
  };
25
+ const combineParts = (parts) => parts.map(({ value }) => value).join('');
25
26
  // ===========================================================================
26
27
  // Collator
27
28
  // ===========================================================================
@@ -47,21 +48,6 @@ exports._patchedLocaleCompare.$original = _localeCompare;
47
48
  // ===========================================================================
48
49
  // NumberFormat
49
50
  // ===========================================================================
50
- const reformatNumber = function (result) {
51
- if (!this.mapped) {
52
- return result;
53
- }
54
- const options = this.super.resolvedOptions();
55
- if (options.style === 'currency' && options.currencyDisplay === 'symbol') {
56
- if (options.currency === 'DKK') {
57
- return result.replace(/kr\./g, 'DKK');
58
- }
59
- if (options.currency === 'ISK') {
60
- return result.replace(/ISK/g, 'kr.');
61
- }
62
- }
63
- return result;
64
- };
65
51
  const reformatNumberParts = function (parts) {
66
52
  if (!this.mapped) {
67
53
  return parts;
@@ -94,10 +80,10 @@ const PatchedNumberFormat = function NumberFormat(locales, options) {
94
80
  const numberFormatProto = {
95
81
  constructor: PatchedNumberFormat,
96
82
  format(value) {
97
- return reformatNumber.call(this, this.super.format(value));
83
+ return combineParts(this.formatToParts(value));
98
84
  },
99
85
  formatRange(value1, value2) {
100
- return reformatNumber.call(this, this.super.formatRange(value1, value2));
86
+ return combineParts(this.formatRangeToParts(value1, value2));
101
87
  },
102
88
  formatToParts(value) {
103
89
  return reformatNumberParts.call(this, this.super.formatToParts(value));
@@ -124,83 +110,75 @@ exports._patchedToLocaleString.$original = _toLocaleString;
124
110
  // ===========================================================================
125
111
  // DateTimeFormat
126
112
  // ===========================================================================
127
- const months = [
128
- ['januar', 'janúar', true],
129
- ['februar', 'febrúar'],
130
- ['marts', 'mars'],
131
- ['april', 'apríl'],
132
- ['maj', 'maí'],
133
- ['juni', 'júní', true],
134
- ['juli', 'júlí', true],
135
- ['august', 'ágúst', true],
136
- // ['september', 'september'],
137
- ['oktober', 'október'],
138
- ['november', 'nóvember', true],
139
- ['december', 'desember', true],
140
- ];
141
- const weekdays = [
142
- ['mandag', 'mánudagur'],
143
- ['tirsdag', 'þriðjudagur', 4],
144
- ['onsdag', 'miðvikudagur'],
145
- ['torsdag', 'fimmtudagur', 4],
146
- ['fredag', 'föstudagur'],
147
- ['lørdag', 'laugardagur'],
148
- ['søndag', 'sunnudagur'],
149
- ];
150
- const reformatDateTime = function (result) {
151
- if (!this.mapped) {
152
- return result;
153
- }
154
- const options = this.super.resolvedOptions();
155
- let mappedResult = result;
156
- let monthMatches = 0;
157
- for (let i = 0, month; (month = months[i]); i++) {
158
- const [da, is, checkShort] = month;
159
- mappedResult = mappedResult.replace(da, is);
160
- if (checkShort && mappedResult === result) {
161
- mappedResult = mappedResult.replace(da.slice(0, 3), is.slice(0, 3));
113
+ const months = {
114
+ jan: 'janúar',
115
+ feb: 'febrúar',
116
+ mar: 'mars',
117
+ apr: 'apríl',
118
+ maj: 'maí',
119
+ jun: 'júní',
120
+ jul: 'júlí',
121
+ aug: 'ágúst',
122
+ // sep: 'september', // is the same
123
+ okt: 'október',
124
+ nov: 'nóvember',
125
+ dec: 'desember',
126
+ };
127
+ const weekdays = {
128
+ man: 'mánudagur',
129
+ tir: 'þriðjudagur',
130
+ ons: 'miðvikudagur',
131
+ tor: 'fimmtudagur',
132
+ fre: 'föstudagur',
133
+ lør: 'laugardagur',
134
+ søn: 'sunnudagur',
135
+ };
136
+ const partMappers = {
137
+ month: (value) => {
138
+ const islMonth = months[value.slice(0, 3)];
139
+ if (islMonth) {
140
+ return value.endsWith('.') ? `${islMonth.slice(0, 3)}.` : islMonth;
162
141
  }
163
- if (mappedResult !== result) {
164
- monthMatches++;
165
- if (monthMatches >= 2) {
166
- break;
167
- }
142
+ },
143
+ weekday: (value) => {
144
+ const isl = weekdays[value.slice(0, 3)];
145
+ if (isl) {
146
+ return value.endsWith('.') ? `${isl.slice(0, 3)}.` : isl;
168
147
  }
169
- }
170
- result = mappedResult; // reset result
171
- let weekdayMatches = 0;
172
- for (let i = 0, weekday; (weekday = weekdays[i]); i++) {
173
- const [da, is, shortLength] = weekday;
174
- mappedResult = mappedResult.replace(da, is);
175
- if (mappedResult === result) {
176
- mappedResult = mappedResult.replace(da.slice(0, shortLength || 3), is.slice(0, 3));
148
+ },
149
+ era: (value) => {
150
+ if (!value.endsWith('.')) {
151
+ return value.length === 3
152
+ ? `${value[0]}.k.`
153
+ : value[0] === 'f'
154
+ ? 'fyrir Krist'
155
+ : 'eftir Krist';
156
+ }
157
+ },
158
+ dayPeriod: (value) => {
159
+ return { AM: 'f.h.', PM: 'e.h.' }[value] || value;
160
+ },
161
+ literal: (value, lastType) => {
162
+ if (value === ' den ') {
163
+ return 'inn ';
177
164
  }
178
- if (mappedResult !== result) {
179
- weekdayMatches++;
180
- if (weekdayMatches >= 2) {
181
- break;
182
- }
165
+ else if (value === '.' && (lastType === 'hour' || lastType === 'minute')) {
166
+ return ':';
183
167
  }
184
- }
185
- result = mappedResult;
186
- if (/Kristus/.test(result)) {
187
- result = result.replace(/før Kristus/g, 'fyrir Krist');
188
- result = result.replace(/efter Kristus/g, 'eftir Krist');
189
- }
190
- result = result.replace(/(f|e)Kr/g, '$1.k.');
191
- result = result.replace(/AM/g, 'f.h.');
192
- result = result.replace(/PM/g, 'e.h.');
193
- // convert timestamps from `00.00` to `00:00`
194
- result = result.replace(/(?:^|\s)\d\d\.\d\d(?:\.\d\d)?(?:,|\s|$)/g, (match) => match.replace(/\./g, ':'));
195
- result = result.replace(/ den/g, 'inn');
196
- return result;
168
+ },
197
169
  };
198
170
  const reformatDateTimeParts = function (parts) {
199
171
  if (!this.mapped) {
200
172
  return parts;
201
173
  }
202
- const options = this.super.resolvedOptions();
203
- // reformat
174
+ parts.forEach((part, idx) => {
175
+ var _a;
176
+ const mapper = partMappers[part.type];
177
+ const newValue = mapper && mapper(part.value, (_a = parts[idx - 1]) === null || _a === void 0 ? void 0 : _a.type);
178
+ if (newValue != null) {
179
+ part.value = newValue;
180
+ }
181
+ });
204
182
  return parts;
205
183
  };
206
184
  const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
@@ -225,10 +203,10 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
225
203
  const dateTimeFormatProto = {
226
204
  constructor: PatchedDateTimeFormat,
227
205
  format(value) {
228
- return reformatDateTime.call(this, this.super.format(value));
206
+ return combineParts(this.formatToParts(value));
229
207
  },
230
208
  formatRange(value1, value2) {
231
- return reformatDateTime.call(this, this.super.formatRange(value1, value2));
209
+ return combineParts(this.formatRangeToParts(value1, value2));
232
210
  },
233
211
  formatToParts(value) {
234
212
  return reformatDateTimeParts.call(this, this.super.formatToParts(value));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reykjavik/webtools",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Misc. JS/TS helpers used by Reykjavík City's web dev teams.",
5
5
  "main": "index.js",
6
6
  "repository": "ssh://git@github.com:reykjavikcity/webtools.git",