intl-messageformat 7.8.4 → 8.2.1

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
@@ -3,6 +3,71 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [8.2.1](https://github.com/formatjs/formatjs/compare/intl-messageformat@8.2.0...intl-messageformat@8.2.1) (2020-03-05)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **intl-messageformat:** export Error obj ([614debb](https://github.com/formatjs/formatjs/commit/614debb80f654966bc3ba832d6e5603be88da3d9))
12
+
13
+
14
+
15
+
16
+
17
+ # [8.2.0](https://github.com/formatjs/formatjs/compare/intl-messageformat@8.1.0...intl-messageformat@8.2.0) (2020-03-05)
18
+
19
+
20
+ ### Features
21
+
22
+ * **intl-messageformat:** Add error type for better debugging ([6200573](https://github.com/formatjs/formatjs/commit/6200573c9f88b23f157bede7305fcc5da64b842b))
23
+
24
+
25
+
26
+
27
+
28
+ # [8.1.0](https://github.com/formatjs/formatjs/compare/intl-messageformat@8.0.0...intl-messageformat@8.1.0) (2020-03-05)
29
+
30
+
31
+ ### Features
32
+
33
+ * **intl-messageformat-parser:** Allow - in embedded HTML tag ([43aa6a7](https://github.com/formatjs/formatjs/commit/43aa6a727ab6fd5eb3fb4d8c4035039a2c27b6c5)), closes [#545](https://github.com/formatjs/formatjs/issues/545)
34
+
35
+
36
+
37
+
38
+
39
+ # [8.0.0](https://github.com/formatjs/formatjs/compare/intl-messageformat@7.8.3...intl-messageformat@8.0.0) (2020-03-04)
40
+
41
+
42
+ ### Features
43
+
44
+ * **intl-messageformat:** combine formatHTMLMessage into format ([d59fbf1](https://github.com/formatjs/formatjs/commit/d59fbf1a4a017a3a023254cb9947575eef9cf803))
45
+
46
+
47
+ ### BREAKING CHANGES
48
+
49
+ * **intl-messageformat:** We've modified the way we parse and format embedded
50
+ XML/HTML as follow:
51
+
52
+ 1. `formatHTMLMessage` has been combined with `format`
53
+ 2. All tags specified must have corresponding values and will throw
54
+ error if it's missing, e.g: `new IntlMessageFormat("a
55
+ <b>strong</b>").format({ b: (...chunks) => <strong>chunks</strong> })`
56
+ 3. Self-closing tags are treated as string literal by default. We don't
57
+ allow formatting self-closing tags because we already use ICU
58
+ `{placeholder}` syntax for that.
59
+ 4. XML/HTML tags are escaped using apostrophe just like other ICU
60
+ constructs.
61
+ 5. Remove dependency on DOMParser and restrictions on void element like
62
+ `<link>`. This effectively means you don't need to polyfill DOMParser in
63
+ Node anymore
64
+
65
+ fix(intl-messageformat-parser): fix escaping for XML tag
66
+
67
+
68
+
69
+
70
+
6
71
  ## [7.8.4](https://github.com/formatjs/formatjs/compare/intl-messageformat@7.8.3...intl-messageformat@7.8.4) (2020-01-27)
7
72
 
8
73
  **Note:** Version bump only for package intl-messageformat
package/README.md CHANGED
@@ -164,32 +164,35 @@ console.log(output); // => "My name is Eric."
164
164
 
165
165
  _Note: A value **must** be supplied for every argument in the message pattern the instance was constructed with._
166
166
 
167
- ### `getAst` Method
168
-
169
- Return the underlying AST for the compiled message
170
-
171
- ### `formatHTMLMessage` method
172
-
173
- Formats message containing HTML tags & can be used to embed rich text formatters such as React. For example:
167
+ #### Rich Text support
174
168
 
175
169
  ```tsx
176
170
  const mf = new IntlMessageFormat('hello <b>world</b>', 'en');
177
- mf.formatHTMLMessage({b: str => <span>{str}</span>});
171
+ mf.format({b: str => <span>{str}</span>});
178
172
  // returns ['hello ', React element rendered as <span>world</span>]
179
173
  ```
180
174
 
181
- #### Caveats
182
-
183
- This is not meant to be a full-fledged method to embed HTML, but rather to tag specific text chunk so translation can be more contextual. Therefore, the following restrictions apply:
175
+ We support embedded XML tag in the message, e.g `this is a <b>strong</b> tag`. This is not meant to be a full-fledged method to embed HTML, but rather to tag specific text chunk so translation can be more contextual. Therefore, the following restrictions apply:
184
176
 
185
177
  1. Any attributes on the HTML tag are also ignored.
186
- 2. Self-closing tags are not supported, please use regular ICU placeholder like `{placeholder}`.
187
- 3. HTML tags must be all lowercased since it's case-insensitive.
188
- 4. Self-closing tags can not be used as HTML tag placeholder. For e.g. `"Please click this <link>link</link>"` will not work because `<link/>` is a self-closing tag, and it can not be parsed correctly by browser `DOMParser`.
178
+ 2. Self-closing tags are treated as string literal and not supported, please use regular ICU placeholder like `{placeholder}`.
179
+ 3. All tags specified must have corresponding values and will throw
180
+ error if it's missing, e.g: `new IntlMessageFormat("a<b>strong</b>").format({ b: (...chunks) => <strong>chunks</strong> })`.
181
+ 4. XML/HTML tags are escaped using apostrophe just like other ICU constructs. In order to escape you can do things like:
189
182
 
190
- - List of self-closing tags is defined [here](https://html.spec.whatwg.org/multipage/syntax.html#void-elements).
183
+ ```tsx
184
+ new IntlMessageFormat("I '<'3 cats").format(); // "I <3 cats"
185
+ new IntlMessageFormat("raw '<b>HTML</b>'").format(); // "raw <b>HTML</b>"
186
+ new IntlMessageFormat(
187
+ "raw '<b>HTML</b>' with '<a>'{placeholder}'</a>'"
188
+ ).format({placeholder: 'some word'}); // "raw <b>HTML</b> with <a>some word</a>"
189
+ ```
190
+
191
+ 5. Embedded valid HTML tag is a bit of a grey area right now since we're not supporting the full HTML/XHTML/XML spec.
192
+
193
+ ### `getAst` Method
191
194
 
192
- If you don't have `DOMParser` available in your environment (e.g. Node.js), you need to add a polyfill. One of the packages that provides such a polyfill is [jsdom](https://www.npmjs.com/package/jsdom).
195
+ Return the underlying AST for the compiled message.
193
196
 
194
197
  ### User Defined Formats
195
198
 
package/dist/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { parse, MessageFormatElement } from 'intl-messageformat-parser';
2
- import { FormatterCache, Formatters, Formats, FormatXMLElementFn, PrimitiveType, MessageFormatPart } from './formatters';
2
+ import { FormatterCache, Formatters, Formats, FormatXMLElementFn, MessageFormatPart } from './formatters';
3
3
  export interface Options {
4
4
  formatters?: Formatters;
5
5
  }
@@ -12,9 +12,8 @@ export declare class IntlMessageFormat {
12
12
  private readonly message;
13
13
  private readonly formatterCache;
14
14
  constructor(message: string | MessageFormatElement[], locales?: string | string[], overrideFormats?: Partial<Formats>, opts?: Options);
15
- format: (values?: Record<string, PrimitiveType> | undefined) => string;
16
- formatToParts: (values?: Record<string, any> | undefined) => MessageFormatPart[];
17
- formatHTMLMessage: (values?: Record<string, string | number | boolean | object | Date | FormatXMLElementFn | null | undefined> | undefined) => (string | object)[];
15
+ format: <T = void>(values?: Record<string, string | number | boolean | Date | T | FormatXMLElementFn<T> | null | undefined> | undefined) => string | T | (string | T)[];
16
+ formatToParts: <T>(values?: Record<string, string | number | boolean | Date | T | FormatXMLElementFn<T> | null | undefined> | undefined) => MessageFormatPart<T>[];
18
17
  resolvedOptions: () => {
19
18
  locale: string;
20
19
  };
package/dist/core.js CHANGED
@@ -61,14 +61,30 @@ var IntlMessageFormat = /** @class */ (function () {
61
61
  pluralRules: {},
62
62
  };
63
63
  this.format = function (values) {
64
- return formatters_1.formatToString(_this.ast, _this.locales, _this.formatters, _this.formats, values, _this.message);
64
+ var parts = _this.formatToParts(values);
65
+ // Hot path for straight simple msg translations
66
+ if (parts.length === 1) {
67
+ return parts[0].value;
68
+ }
69
+ var result = parts.reduce(function (all, part) {
70
+ if (!all.length ||
71
+ part.type !== 0 /* literal */ ||
72
+ typeof all[all.length - 1] !== 'string') {
73
+ all.push(part.value);
74
+ }
75
+ else {
76
+ all[all.length - 1] += part.value;
77
+ }
78
+ return all;
79
+ }, []);
80
+ if (result.length <= 1) {
81
+ return result[0] || '';
82
+ }
83
+ return result;
65
84
  };
66
85
  this.formatToParts = function (values) {
67
86
  return formatters_1.formatToParts(_this.ast, _this.locales, _this.formatters, _this.formats, values, undefined, _this.message);
68
87
  };
69
- this.formatHTMLMessage = function (values) {
70
- return formatters_1.formatHTMLMessage(_this.ast, _this.locales, _this.formatters, _this.formats, values, _this.message);
71
- };
72
88
  this.resolvedOptions = function () { return ({
73
89
  locale: Intl.NumberFormat.supportedLocalesOf(_this.locales)[0],
74
90
  }); };
@@ -0,0 +1,16 @@
1
+ export declare const enum ErrorCode {
2
+ MISSING_VALUE = 0,
3
+ INVALID_VALUE = 1,
4
+ MISSING_INTL_API = 2
5
+ }
6
+ export declare class FormatError extends Error {
7
+ readonly code: ErrorCode;
8
+ constructor(msg: string, code: ErrorCode);
9
+ toString(): string;
10
+ }
11
+ export declare class InvalidValueError extends FormatError {
12
+ constructor(variableId: string, value: any, options: string[]);
13
+ }
14
+ export declare class MissingValueError extends FormatError {
15
+ constructor(variableId: string, originalMessage?: string);
16
+ }
package/dist/error.js ADDED
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ extendStatics(d, b);
11
+ function __() { this.constructor = d; }
12
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13
+ };
14
+ })();
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ var FormatError = /** @class */ (function (_super) {
17
+ __extends(FormatError, _super);
18
+ function FormatError(msg, code) {
19
+ var _this = _super.call(this, msg) || this;
20
+ _this.code = code;
21
+ return _this;
22
+ }
23
+ FormatError.prototype.toString = function () {
24
+ return "[formatjs Error: " + this.code + "] " + this.message;
25
+ };
26
+ return FormatError;
27
+ }(Error));
28
+ exports.FormatError = FormatError;
29
+ var InvalidValueError = /** @class */ (function (_super) {
30
+ __extends(InvalidValueError, _super);
31
+ function InvalidValueError(variableId, value, options) {
32
+ return _super.call(this, "Invalid values for \"" + variableId + "\": \"" + value + "\". Options are \"" + Object.keys(options).join('", "') + "\"", 1 /* INVALID_VALUE */) || this;
33
+ }
34
+ return InvalidValueError;
35
+ }(FormatError));
36
+ exports.InvalidValueError = InvalidValueError;
37
+ var MissingValueError = /** @class */ (function (_super) {
38
+ __extends(MissingValueError, _super);
39
+ function MissingValueError(variableId, originalMessage) {
40
+ return _super.call(this, "The intl string context variable \"" + variableId + "\" was not provided to the string \"" + originalMessage + "\"", 0 /* MISSING_VALUE */) || this;
41
+ }
42
+ return MissingValueError;
43
+ }(FormatError));
44
+ exports.MissingValueError = MissingValueError;
@@ -16,19 +16,17 @@ export interface Formatters {
16
16
  }
17
17
  export declare const enum PART_TYPE {
18
18
  literal = 0,
19
- argument = 1
19
+ object = 1
20
20
  }
21
21
  export interface LiteralPart {
22
22
  type: PART_TYPE.literal;
23
23
  value: string;
24
24
  }
25
- export interface ArgumentPart {
26
- type: PART_TYPE.argument;
27
- value: any;
25
+ export interface ObjectPart<T = any> {
26
+ type: PART_TYPE.object;
27
+ value: T;
28
28
  }
29
- export declare type MessageFormatPart = LiteralPart | ArgumentPart;
29
+ export declare type MessageFormatPart<T> = LiteralPart | ObjectPart<T>;
30
30
  export declare type PrimitiveType = string | number | boolean | null | undefined | Date;
31
- export declare function formatToParts(els: MessageFormatElement[], locales: string | string[], formatters: Formatters, formats: Formats, values?: Record<string, any>, currentPluralValue?: number, originalMessage?: string): MessageFormatPart[];
32
- export declare function formatToString(els: MessageFormatElement[], locales: string | string[], formatters: Formatters, formats: Formats, values?: Record<string, PrimitiveType>, originalMessage?: string): string;
33
- export declare type FormatXMLElementFn = (...args: any[]) => string | object;
34
- export declare function formatHTMLMessage(els: MessageFormatElement[], locales: string | string[], formatters: Formatters, formats: Formats, values?: Record<string, PrimitiveType | object | FormatXMLElementFn>, originalMessage?: string): Array<string | object>;
31
+ export declare function formatToParts<T>(els: MessageFormatElement[], locales: string | string[], formatters: Formatters, formats: Formats, values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T>>, currentPluralValue?: number, originalMessage?: string): MessageFormatPart<T>[];
32
+ export declare type FormatXMLElementFn<T> = (...args: Array<string | T>) => string | Array<string | T>;
@@ -1,35 +1,7 @@
1
1
  "use strict";
2
- var __extends = (this && this.__extends) || (function () {
3
- var extendStatics = function (d, b) {
4
- extendStatics = Object.setPrototypeOf ||
5
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7
- return extendStatics(d, b);
8
- };
9
- return function (d, b) {
10
- extendStatics(d, b);
11
- function __() { this.constructor = d; }
12
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13
- };
14
- })();
15
- var __spreadArrays = (this && this.__spreadArrays) || function () {
16
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
17
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
18
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
19
- r[k] = a[j];
20
- return r;
21
- };
22
2
  Object.defineProperty(exports, "__esModule", { value: true });
23
3
  var intl_messageformat_parser_1 = require("intl-messageformat-parser");
24
- var FormatError = /** @class */ (function (_super) {
25
- __extends(FormatError, _super);
26
- function FormatError(msg, variableId) {
27
- var _this = _super.call(this, msg) || this;
28
- _this.variableId = variableId;
29
- return _this;
30
- }
31
- return FormatError;
32
- }(Error));
4
+ var error_1 = require("./error");
33
5
  function mergeLiteral(parts) {
34
6
  if (parts.length < 2) {
35
7
  return parts;
@@ -47,6 +19,9 @@ function mergeLiteral(parts) {
47
19
  return all;
48
20
  }, []);
49
21
  }
22
+ function isFormatXMLElementFn(el) {
23
+ return typeof el === 'function';
24
+ }
50
25
  // TODO(skeleton): add skeleton support
51
26
  function formatToParts(els, locales, formatters, formats, values, currentPluralValue,
52
27
  // For debugging
@@ -85,7 +60,7 @@ originalMessage) {
85
60
  var varName = el.value;
86
61
  // Enforce that all required values are provided by the caller.
87
62
  if (!(values && varName in values)) {
88
- throw new FormatError("The intl string context variable \"" + varName + "\" was not provided to the string \"" + originalMessage + "\"");
63
+ throw new error_1.MissingValueError(varName, originalMessage);
89
64
  }
90
65
  var value = values[varName];
91
66
  if (intl_messageformat_parser_1.isArgumentElement(el)) {
@@ -96,7 +71,7 @@ originalMessage) {
96
71
  : '';
97
72
  }
98
73
  result.push({
99
- type: 1 /* argument */,
74
+ type: typeof value === 'string' ? 0 /* literal */ : 1 /* object */,
100
75
  value: value,
101
76
  });
102
77
  continue;
@@ -142,10 +117,28 @@ originalMessage) {
142
117
  });
143
118
  continue;
144
119
  }
120
+ if (intl_messageformat_parser_1.isTagElement(el)) {
121
+ var children = el.children, value_1 = el.value;
122
+ var formatFn = values[value_1];
123
+ if (!isFormatXMLElementFn(formatFn)) {
124
+ throw new TypeError("Value for \"" + value_1 + "\" must be a function");
125
+ }
126
+ var parts = formatToParts(children, locales, formatters, formats, values);
127
+ var chunks = formatFn.apply(void 0, parts.map(function (p) { return p.value; }));
128
+ if (!Array.isArray(chunks)) {
129
+ chunks = [chunks];
130
+ }
131
+ result.push.apply(result, chunks.map(function (c) {
132
+ return {
133
+ type: typeof c === 'string' ? 0 /* literal */ : 1 /* object */,
134
+ value: c,
135
+ };
136
+ }));
137
+ }
145
138
  if (intl_messageformat_parser_1.isSelectElement(el)) {
146
139
  var opt = el.options[value] || el.options.other;
147
140
  if (!opt) {
148
- throw new RangeError("Invalid values for \"" + el.value + "\": \"" + value + "\". Options are \"" + Object.keys(el.options).join('", "') + "\"");
141
+ throw new error_1.InvalidValueError(el.value, value, Object.keys(el.options));
149
142
  }
150
143
  result.push.apply(result, formatToParts(opt.value, locales, formatters, formats, values));
151
144
  continue;
@@ -154,7 +147,7 @@ originalMessage) {
154
147
  var opt = el.options["=" + value];
155
148
  if (!opt) {
156
149
  if (!Intl.PluralRules) {
157
- throw new FormatError("Intl.PluralRules is not available in this environment.\nTry polyfilling it using \"@formatjs/intl-pluralrules\"\n");
150
+ throw new error_1.FormatError("Intl.PluralRules is not available in this environment.\nTry polyfilling it using \"@formatjs/intl-pluralrules\"\n", 2 /* MISSING_INTL_API */);
158
151
  }
159
152
  var rule = formatters
160
153
  .getPluralRules(locales, { type: el.pluralType })
@@ -162,7 +155,7 @@ originalMessage) {
162
155
  opt = el.options[rule] || el.options.other;
163
156
  }
164
157
  if (!opt) {
165
- throw new RangeError("Invalid values for \"" + el.value + "\": \"" + value + "\". Options are \"" + Object.keys(el.options).join('", "') + "\"");
158
+ throw new error_1.InvalidValueError(el.value, value, Object.keys(el.options));
166
159
  }
167
160
  result.push.apply(result, formatToParts(opt.value, locales, formatters, formats, values, value - (el.offset || 0)));
168
161
  continue;
@@ -171,138 +164,3 @@ originalMessage) {
171
164
  return mergeLiteral(result);
172
165
  }
173
166
  exports.formatToParts = formatToParts;
174
- function formatToString(els, locales, formatters, formats, values,
175
- // For debugging
176
- originalMessage) {
177
- var parts = formatToParts(els, locales, formatters, formats, values, undefined, originalMessage);
178
- // Hot path for straight simple msg translations
179
- if (parts.length === 1) {
180
- return parts[0].value;
181
- }
182
- return parts.reduce(function (all, part) { return (all += part.value); }, '');
183
- }
184
- exports.formatToString = formatToString;
185
- // Singleton
186
- var domParser;
187
- var TOKEN_DELIMITER = '@@';
188
- var TOKEN_REGEX = /@@(\d+_\d+)@@/g;
189
- var counter = 0;
190
- function generateId() {
191
- return Date.now() + "_" + ++counter;
192
- }
193
- function restoreRichPlaceholderMessage(text, objectParts) {
194
- return text
195
- .split(TOKEN_REGEX)
196
- .filter(Boolean)
197
- .map(function (c) { return (objectParts[c] != null ? objectParts[c] : c); })
198
- .reduce(function (all, c) {
199
- if (!all.length) {
200
- all.push(c);
201
- }
202
- else if (typeof c === 'string' &&
203
- typeof all[all.length - 1] === 'string') {
204
- all[all.length - 1] += c;
205
- }
206
- else {
207
- all.push(c);
208
- }
209
- return all;
210
- }, []);
211
- }
212
- /**
213
- * Not exhaustive, just for sanity check
214
- */
215
- var SIMPLE_XML_REGEX = /(<([0-9a-zA-Z-_]*?)>(.*?)<\/([0-9a-zA-Z-_]*?)>)|(<[0-9a-zA-Z-_]*?\/>)/;
216
- var TEMPLATE_ID = Date.now() + '@@';
217
- var VOID_ELEMENTS = [
218
- 'area',
219
- 'base',
220
- 'br',
221
- 'col',
222
- 'embed',
223
- 'hr',
224
- 'img',
225
- 'input',
226
- 'link',
227
- 'meta',
228
- 'param',
229
- 'source',
230
- 'track',
231
- 'wbr',
232
- ];
233
- function formatHTMLElement(el, objectParts, values) {
234
- var tagName = el.tagName;
235
- var outerHTML = el.outerHTML, textContent = el.textContent, childNodes = el.childNodes;
236
- // Regular text
237
- if (!tagName) {
238
- return restoreRichPlaceholderMessage(textContent || '', objectParts);
239
- }
240
- tagName = tagName.toLowerCase();
241
- var isVoidElement = ~VOID_ELEMENTS.indexOf(tagName);
242
- var formatFnOrValue = values[tagName];
243
- if (formatFnOrValue && isVoidElement) {
244
- throw new FormatError(tagName + " is a self-closing tag and can not be used, please use another tag name.");
245
- }
246
- if (!childNodes.length) {
247
- return [outerHTML];
248
- }
249
- var chunks = Array.prototype.slice.call(childNodes).reduce(function (all, child) {
250
- return all.concat(formatHTMLElement(child, objectParts, values));
251
- }, []);
252
- // Legacy HTML
253
- if (!formatFnOrValue) {
254
- return __spreadArrays(["<" + tagName + ">"], chunks, ["</" + tagName + ">"]);
255
- }
256
- // HTML Tag replacement
257
- if (typeof formatFnOrValue === 'function') {
258
- return [formatFnOrValue.apply(void 0, chunks)];
259
- }
260
- return [formatFnOrValue];
261
- }
262
- function formatHTMLMessage(els, locales, formatters, formats, values,
263
- // For debugging
264
- originalMessage) {
265
- var parts = formatToParts(els, locales, formatters, formats, values, undefined, originalMessage);
266
- var objectParts = {};
267
- var formattedMessage = parts.reduce(function (all, part) {
268
- if (part.type === 0 /* literal */) {
269
- return (all += part.value);
270
- }
271
- var id = generateId();
272
- objectParts[id] = part.value;
273
- return (all += "" + TOKEN_DELIMITER + id + TOKEN_DELIMITER);
274
- }, '');
275
- // Not designed to filter out aggressively
276
- if (!SIMPLE_XML_REGEX.test(formattedMessage)) {
277
- return restoreRichPlaceholderMessage(formattedMessage, objectParts);
278
- }
279
- if (!values) {
280
- throw new FormatError('Message has placeholders but no values was given');
281
- }
282
- if (typeof DOMParser === 'undefined') {
283
- throw new FormatError('Cannot format XML message without DOMParser');
284
- }
285
- if (!domParser) {
286
- domParser = new DOMParser();
287
- }
288
- var content = domParser
289
- .parseFromString("<formatted-message id=\"" + TEMPLATE_ID + "\">" + formattedMessage + "</formatted-message>", 'text/html')
290
- .getElementById(TEMPLATE_ID);
291
- if (!content) {
292
- throw new FormatError("Malformed HTML message " + formattedMessage);
293
- }
294
- var tagsToFormat = Object.keys(values).filter(function (varName) { return !!content.getElementsByTagName(varName).length; });
295
- // No tags to format
296
- if (!tagsToFormat.length) {
297
- return restoreRichPlaceholderMessage(formattedMessage, objectParts);
298
- }
299
- var caseSensitiveTags = tagsToFormat.filter(function (tagName) { return tagName !== tagName.toLowerCase(); });
300
- if (caseSensitiveTags.length) {
301
- throw new FormatError("HTML tag must be lowercased but the following tags are not: " + caseSensitiveTags.join(', '));
302
- }
303
- // We're doing this since top node is `<formatted-message/>` which does not have a formatter
304
- return Array.prototype.slice
305
- .call(content.childNodes)
306
- .reduce(function (all, child) { return all.concat(formatHTMLElement(child, objectParts, values)); }, []);
307
- }
308
- exports.formatHTMLMessage = formatHTMLMessage;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import IntlMessageFormat from './core';
2
2
  export * from './formatters';
3
3
  export * from './core';
4
+ export * from './error';
4
5
  export default IntlMessageFormat;
package/dist/index.js CHANGED
@@ -11,4 +11,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
11
11
  var core_1 = require("./core");
12
12
  __export(require("./formatters"));
13
13
  __export(require("./core"));
14
+ __export(require("./error"));
14
15
  exports.default = core_1.default;