@reykjavik/webtools 0.1.15 → 0.1.17
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 +16 -0
- package/README.md +5 -6
- package/esm/fixIcelandicLocale.privates.js +80 -86
- package/fixIcelandicLocale.privates.js +80 -86
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
- ... <!-- Add new lines here. -->
|
|
6
6
|
|
|
7
|
+
## 0.1.17
|
|
8
|
+
|
|
9
|
+
_2024-03-09_
|
|
10
|
+
|
|
11
|
+
- `@reykjavik/webtools/fixIcelandicLocale`:
|
|
12
|
+
- feat: Add support for `DateTimeFormat`'s `dayPeriod` option
|
|
13
|
+
|
|
14
|
+
## 0.1.16
|
|
15
|
+
|
|
16
|
+
_2024-03-09_
|
|
17
|
+
|
|
18
|
+
- `@reykjavik/webtools/fixIcelandicLocale`:
|
|
19
|
+
- fix: Add missing `DateTimeFormat.format*ToParts` methods, fix bugs
|
|
20
|
+
- refctor: Reduce code-size and simplify logic by dog-fooding `*ToParts`
|
|
21
|
+
methods internally
|
|
22
|
+
|
|
7
23
|
## 0.1.15
|
|
8
24
|
|
|
9
25
|
_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.
|
|
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,12 @@ 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
|
|
482
|
-
- The `dayPeriod` option
|
|
483
|
-
|
|
484
|
-
`DD:MM:YY` strings.
|
|
481
|
+
- The `timeStyle: 'full'` option prints the timezone names in Danish
|
|
482
|
+
- The `dayPeriod` option has a couple of slight mismatches, at 5 am and 12
|
|
483
|
+
noon.
|
|
485
484
|
|
|
486
485
|
---
|
|
487
486
|
|
|
@@ -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
|
|
79
|
+
return combineParts(this.formatToParts(value));
|
|
94
80
|
},
|
|
95
81
|
formatRange(value1, value2) {
|
|
96
|
-
return
|
|
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,91 @@ _patchedToLocaleString.$original = _toLocaleString;
|
|
|
119
105
|
// ===========================================================================
|
|
120
106
|
// DateTimeFormat
|
|
121
107
|
// ===========================================================================
|
|
122
|
-
const months =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const weekdays =
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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 dayPeriods = {
|
|
132
|
+
AM: ['f.h.'],
|
|
133
|
+
PM: ['e.h.'],
|
|
134
|
+
'om natten': ['að nóttu', 'n.'],
|
|
135
|
+
// Mismatch at 05:00 — da: 'om morgenen', is: 'að nóttu'
|
|
136
|
+
'om morgenen': ['að morgni', 'mrg.'],
|
|
137
|
+
'om formiddagen': ['að morgni', 'mrg.'],
|
|
138
|
+
// Mismatch at 12:00 — da: 'om eftermiddagen', is: 'hádegi'
|
|
139
|
+
'om eftermiddagen': ['síðdegis', 'sd.'],
|
|
140
|
+
'om aftenen': ['að kvöldi', 'kv.'],
|
|
141
|
+
};
|
|
142
|
+
const partMappers = {
|
|
143
|
+
month: (value) => {
|
|
144
|
+
const isl = months[value.slice(0, 3)];
|
|
145
|
+
if (isl) {
|
|
146
|
+
return value.endsWith('.') ? `${isl.slice(0, 3)}.` : isl;
|
|
157
147
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
148
|
+
},
|
|
149
|
+
weekday: (value) => {
|
|
150
|
+
const isl = weekdays[value.slice(0, 3)];
|
|
151
|
+
if (isl) {
|
|
152
|
+
return value.endsWith('.') ? `${isl.slice(0, 3)}.` : isl;
|
|
163
153
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
154
|
+
},
|
|
155
|
+
era: (value) => {
|
|
156
|
+
if (!value.endsWith('.')) {
|
|
157
|
+
return value.length === 3
|
|
158
|
+
? `${value[0]}.k.`
|
|
159
|
+
: value[0] === 'f'
|
|
160
|
+
? 'fyrir Krist'
|
|
161
|
+
: 'eftir Krist';
|
|
172
162
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
163
|
+
},
|
|
164
|
+
dayPeriod: (value, _, options) => {
|
|
165
|
+
const isl = dayPeriods[value];
|
|
166
|
+
if (isl) {
|
|
167
|
+
const [long, narrow] = isl;
|
|
168
|
+
return options.dayPeriod === 'narrow' ? narrow : long;
|
|
178
169
|
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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;
|
|
170
|
+
},
|
|
171
|
+
literal: (value, lastType) => {
|
|
172
|
+
if (value === ' den ') {
|
|
173
|
+
return 'inn ';
|
|
174
|
+
}
|
|
175
|
+
else if (value === '.' && (lastType === 'hour' || lastType === 'minute')) {
|
|
176
|
+
return ':';
|
|
177
|
+
}
|
|
178
|
+
},
|
|
192
179
|
};
|
|
193
180
|
const reformatDateTimeParts = function (parts) {
|
|
194
181
|
if (!this.mapped) {
|
|
195
182
|
return parts;
|
|
196
183
|
}
|
|
197
184
|
const options = this.super.resolvedOptions();
|
|
198
|
-
|
|
185
|
+
parts.forEach((part, idx) => {
|
|
186
|
+
var _a;
|
|
187
|
+
const mapper = partMappers[part.type];
|
|
188
|
+
const newValue = mapper && mapper(part.value, (_a = parts[idx - 1]) === null || _a === void 0 ? void 0 : _a.type, options);
|
|
189
|
+
if (newValue != null) {
|
|
190
|
+
part.value = newValue;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
199
193
|
return parts;
|
|
200
194
|
};
|
|
201
195
|
const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
@@ -220,10 +214,10 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
|
220
214
|
const dateTimeFormatProto = {
|
|
221
215
|
constructor: PatchedDateTimeFormat,
|
|
222
216
|
format(value) {
|
|
223
|
-
return
|
|
217
|
+
return combineParts(this.formatToParts(value));
|
|
224
218
|
},
|
|
225
219
|
formatRange(value1, value2) {
|
|
226
|
-
return
|
|
220
|
+
return combineParts(this.formatRangeToParts(value1, value2));
|
|
227
221
|
},
|
|
228
222
|
formatToParts(value) {
|
|
229
223
|
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
|
|
83
|
+
return combineParts(this.formatToParts(value));
|
|
98
84
|
},
|
|
99
85
|
formatRange(value1, value2) {
|
|
100
|
-
return
|
|
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,91 @@ exports._patchedToLocaleString.$original = _toLocaleString;
|
|
|
124
110
|
// ===========================================================================
|
|
125
111
|
// DateTimeFormat
|
|
126
112
|
// ===========================================================================
|
|
127
|
-
const months =
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const weekdays =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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 dayPeriods = {
|
|
137
|
+
AM: ['f.h.'],
|
|
138
|
+
PM: ['e.h.'],
|
|
139
|
+
'om natten': ['að nóttu', 'n.'],
|
|
140
|
+
// Mismatch at 05:00 — da: 'om morgenen', is: 'að nóttu'
|
|
141
|
+
'om morgenen': ['að morgni', 'mrg.'],
|
|
142
|
+
'om formiddagen': ['að morgni', 'mrg.'],
|
|
143
|
+
// Mismatch at 12:00 — da: 'om eftermiddagen', is: 'hádegi'
|
|
144
|
+
'om eftermiddagen': ['síðdegis', 'sd.'],
|
|
145
|
+
'om aftenen': ['að kvöldi', 'kv.'],
|
|
146
|
+
};
|
|
147
|
+
const partMappers = {
|
|
148
|
+
month: (value) => {
|
|
149
|
+
const isl = months[value.slice(0, 3)];
|
|
150
|
+
if (isl) {
|
|
151
|
+
return value.endsWith('.') ? `${isl.slice(0, 3)}.` : isl;
|
|
162
152
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
153
|
+
},
|
|
154
|
+
weekday: (value) => {
|
|
155
|
+
const isl = weekdays[value.slice(0, 3)];
|
|
156
|
+
if (isl) {
|
|
157
|
+
return value.endsWith('.') ? `${isl.slice(0, 3)}.` : isl;
|
|
168
158
|
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
159
|
+
},
|
|
160
|
+
era: (value) => {
|
|
161
|
+
if (!value.endsWith('.')) {
|
|
162
|
+
return value.length === 3
|
|
163
|
+
? `${value[0]}.k.`
|
|
164
|
+
: value[0] === 'f'
|
|
165
|
+
? 'fyrir Krist'
|
|
166
|
+
: 'eftir Krist';
|
|
177
167
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
168
|
+
},
|
|
169
|
+
dayPeriod: (value, _, options) => {
|
|
170
|
+
const isl = dayPeriods[value];
|
|
171
|
+
if (isl) {
|
|
172
|
+
const [long, narrow] = isl;
|
|
173
|
+
return options.dayPeriod === 'narrow' ? narrow : long;
|
|
183
174
|
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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;
|
|
175
|
+
},
|
|
176
|
+
literal: (value, lastType) => {
|
|
177
|
+
if (value === ' den ') {
|
|
178
|
+
return 'inn ';
|
|
179
|
+
}
|
|
180
|
+
else if (value === '.' && (lastType === 'hour' || lastType === 'minute')) {
|
|
181
|
+
return ':';
|
|
182
|
+
}
|
|
183
|
+
},
|
|
197
184
|
};
|
|
198
185
|
const reformatDateTimeParts = function (parts) {
|
|
199
186
|
if (!this.mapped) {
|
|
200
187
|
return parts;
|
|
201
188
|
}
|
|
202
189
|
const options = this.super.resolvedOptions();
|
|
203
|
-
|
|
190
|
+
parts.forEach((part, idx) => {
|
|
191
|
+
var _a;
|
|
192
|
+
const mapper = partMappers[part.type];
|
|
193
|
+
const newValue = mapper && mapper(part.value, (_a = parts[idx - 1]) === null || _a === void 0 ? void 0 : _a.type, options);
|
|
194
|
+
if (newValue != null) {
|
|
195
|
+
part.value = newValue;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
204
198
|
return parts;
|
|
205
199
|
};
|
|
206
200
|
const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
@@ -225,10 +219,10 @@ const PatchedDateTimeFormat = function DateTimeFormat(locales, options) {
|
|
|
225
219
|
const dateTimeFormatProto = {
|
|
226
220
|
constructor: PatchedDateTimeFormat,
|
|
227
221
|
format(value) {
|
|
228
|
-
return
|
|
222
|
+
return combineParts(this.formatToParts(value));
|
|
229
223
|
},
|
|
230
224
|
formatRange(value1, value2) {
|
|
231
|
-
return
|
|
225
|
+
return combineParts(this.formatRangeToParts(value1, value2));
|
|
232
226
|
},
|
|
233
227
|
formatToParts(value) {
|
|
234
228
|
return reformatDateTimeParts.call(this, this.super.formatToParts(value));
|
package/package.json
CHANGED