@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 +9 -0
- package/README.md +3 -5
- package/esm/fixIcelandicLocale.privates.js +65 -87
- package/fixIcelandicLocale.privates.js +65 -87
- package/package.json +1 -1
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.
|
|
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
|
|
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
|
|
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,75 @@ _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
|
-
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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 (
|
|
174
|
-
|
|
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
|
-
|
|
198
|
-
|
|
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
|
|
201
|
+
return combineParts(this.formatToParts(value));
|
|
224
202
|
},
|
|
225
203
|
formatRange(value1, value2) {
|
|
226
|
-
return
|
|
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
|
|
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,75 @@ 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
|
-
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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 (
|
|
179
|
-
|
|
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
|
-
|
|
203
|
-
|
|
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
|
|
206
|
+
return combineParts(this.formatToParts(value));
|
|
229
207
|
},
|
|
230
208
|
formatRange(value1, value2) {
|
|
231
|
-
return
|
|
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