@doist/react-interpolate 0.2.0 → 0.3.8
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/README.md +49 -48
- package/dist/react-interpolate.cjs +56 -48
- package/dist/react-interpolate.min.cjs +1 -1
- package/dist/react-interpolate.min.mjs +1 -1
- package/dist/react-interpolate.mjs +33 -32
- package/package.json +73 -62
- package/src/constants.js +10 -10
- package/src/index.js +3 -8
- package/src/interpolate.js +13 -20
- package/src/lexer.js +8 -10
- package/src/node.js +11 -11
- package/src/parser.js +7 -8
- package/src/syntax.js +9 -14
- package/.eslintrc.js +0 -36
- package/.github/workflows/nodejs.yml +0 -32
- package/.prettierrc.json +0 -9
- package/CONTRIBUTING.md +0 -7
- package/__test__/Interpolate.test.js +0 -203
- package/__test__/parser.test.js +0 -45
- package/babel.config.js +0 -18
- package/dist/react-interpolate.min.cjs.gz +0 -0
- package/dist/react-interpolate.min.mjs.gz +0 -0
- package/rollup.config.js +0 -17
|
@@ -4,22 +4,24 @@ import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
|
|
|
4
4
|
import _createClass from '@babel/runtime/helpers/createClass';
|
|
5
5
|
import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
|
|
6
6
|
|
|
7
|
-
var TOKEN_PLACEHOLDER =
|
|
8
|
-
var TOKEN_OPEN_TAG =
|
|
9
|
-
var TOKEN_CLOSE_TAG =
|
|
10
|
-
var TOKEN_SELF_TAG =
|
|
11
|
-
var TOKEN_TEXT =
|
|
12
|
-
var NODE_FRAGMENT =
|
|
13
|
-
var NODE_TAG_ELEMENT =
|
|
14
|
-
var NODE_VOID_ELEMENT =
|
|
15
|
-
var NODE_PLACEHOLDER =
|
|
16
|
-
var NODE_TEXT =
|
|
7
|
+
var TOKEN_PLACEHOLDER = 'TOKEN_PLACEHOLDER';
|
|
8
|
+
var TOKEN_OPEN_TAG = 'TOKEN_OPEN_TAG';
|
|
9
|
+
var TOKEN_CLOSE_TAG = 'TOKEN_CLOSE_TAG';
|
|
10
|
+
var TOKEN_SELF_TAG = 'TOKEN_SELF_TAG';
|
|
11
|
+
var TOKEN_TEXT = 'TOKEN_TEXT';
|
|
12
|
+
var NODE_FRAGMENT = 'NODE_FRAGMENT';
|
|
13
|
+
var NODE_TAG_ELEMENT = 'NODE_TAG_ELEMENT';
|
|
14
|
+
var NODE_VOID_ELEMENT = 'NODE_VOID_ELEMENT';
|
|
15
|
+
var NODE_PLACEHOLDER = 'NODE_PLACEHOLDER';
|
|
16
|
+
var NODE_TEXT = 'NODE_TEXT';
|
|
17
|
+
|
|
18
|
+
var _excluded = ["type", "children"];
|
|
17
19
|
|
|
18
20
|
var Node = /*#__PURE__*/function () {
|
|
19
21
|
function Node(_ref) {
|
|
20
22
|
var type = _ref.type,
|
|
21
23
|
children = _ref.children,
|
|
22
|
-
fields = _objectWithoutProperties(_ref,
|
|
24
|
+
fields = _objectWithoutProperties(_ref, _excluded);
|
|
23
25
|
|
|
24
26
|
_classCallCheck(this, Node);
|
|
25
27
|
|
|
@@ -117,9 +119,9 @@ var SYNTAX_I18NEXT = [{
|
|
|
117
119
|
regex: /<(\w+)\s*\/>/g
|
|
118
120
|
}];
|
|
119
121
|
|
|
120
|
-
function _createForOfIteratorHelper(o) {
|
|
122
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
121
123
|
|
|
122
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(
|
|
124
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
123
125
|
|
|
124
126
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
125
127
|
/*
|
|
@@ -179,7 +181,7 @@ function lexer(string, syntax) {
|
|
|
179
181
|
});
|
|
180
182
|
var text = string.substring(start);
|
|
181
183
|
|
|
182
|
-
if (text !==
|
|
184
|
+
if (text !== '') {
|
|
183
185
|
textTokens.push({
|
|
184
186
|
type: TOKEN_TEXT,
|
|
185
187
|
string: text,
|
|
@@ -203,10 +205,10 @@ function parser(string, syntax) {
|
|
|
203
205
|
var p = new Parser(tokens);
|
|
204
206
|
return p.parse();
|
|
205
207
|
}
|
|
206
|
-
var SYNTAX_ERROR =
|
|
208
|
+
var SYNTAX_ERROR = 'Syntax error. Please check if each open tag is closed correctly'; // A special token representing end of the tream
|
|
207
209
|
|
|
208
210
|
var EPSILON = {
|
|
209
|
-
type:
|
|
211
|
+
type: 'EPSILON'
|
|
210
212
|
};
|
|
211
213
|
/*
|
|
212
214
|
* A recursive descent parser that construct a syntax tree represeting
|
|
@@ -343,6 +345,11 @@ var Parser = /*#__PURE__*/function () {
|
|
|
343
345
|
|
|
344
346
|
this.match(TOKEN_CLOSE_TAG);
|
|
345
347
|
}
|
|
348
|
+
}, {
|
|
349
|
+
key: "lookahead",
|
|
350
|
+
get: function get() {
|
|
351
|
+
return this.tokens.length === 0 ? EPSILON : this.tokens[0];
|
|
352
|
+
}
|
|
346
353
|
}, {
|
|
347
354
|
key: "predict",
|
|
348
355
|
value: function predict() {
|
|
@@ -367,11 +374,6 @@ var Parser = /*#__PURE__*/function () {
|
|
|
367
374
|
value: function pushTag(token) {
|
|
368
375
|
this.tags.push(token);
|
|
369
376
|
}
|
|
370
|
-
}, {
|
|
371
|
-
key: "lookahead",
|
|
372
|
-
get: function get() {
|
|
373
|
-
return this.tokens.length === 0 ? EPSILON : this.tokens[0];
|
|
374
|
-
}
|
|
375
377
|
}]);
|
|
376
378
|
|
|
377
379
|
return Parser;
|
|
@@ -392,18 +394,18 @@ var createElement = function createElement(node, mapping, keyPrefix) {
|
|
|
392
394
|
|
|
393
395
|
case NODE_FRAGMENT:
|
|
394
396
|
{
|
|
395
|
-
return React.createElement(React.Fragment, null, children);
|
|
397
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
396
398
|
}
|
|
397
399
|
|
|
398
400
|
case NODE_VOID_ELEMENT:
|
|
399
401
|
{
|
|
400
402
|
var val = mapping[node.name];
|
|
401
403
|
|
|
402
|
-
if (typeof val ===
|
|
404
|
+
if (typeof val === 'function') {
|
|
403
405
|
return val();
|
|
404
406
|
}
|
|
405
407
|
|
|
406
|
-
return val || React.createElement(node.name, null);
|
|
408
|
+
return val || /*#__PURE__*/React.createElement(node.name, null);
|
|
407
409
|
}
|
|
408
410
|
|
|
409
411
|
case NODE_TAG_ELEMENT:
|
|
@@ -411,19 +413,19 @@ var createElement = function createElement(node, mapping, keyPrefix) {
|
|
|
411
413
|
var _val = mapping[node.name];
|
|
412
414
|
|
|
413
415
|
if (_val === undefined) {
|
|
414
|
-
return React.createElement(node.name, null, children);
|
|
416
|
+
return /*#__PURE__*/React.createElement(node.name, null, children);
|
|
415
417
|
}
|
|
416
418
|
|
|
417
|
-
if (typeof _val ===
|
|
419
|
+
if (typeof _val === 'function') {
|
|
418
420
|
return _val(children);
|
|
419
421
|
}
|
|
420
422
|
|
|
421
|
-
if (React.isValidElement(_val)) {
|
|
423
|
+
if ( /*#__PURE__*/React.isValidElement(_val)) {
|
|
422
424
|
if (React.Children.count(_val.props.children) !== 0) {
|
|
423
|
-
throw new Error(
|
|
425
|
+
throw new Error('when passing an element as value, the element should not contains children');
|
|
424
426
|
}
|
|
425
427
|
|
|
426
|
-
return React.cloneElement(_val, {
|
|
428
|
+
return /*#__PURE__*/React.cloneElement(_val, {
|
|
427
429
|
children: children
|
|
428
430
|
});
|
|
429
431
|
}
|
|
@@ -440,7 +442,7 @@ var createElement = function createElement(node, mapping, keyPrefix) {
|
|
|
440
442
|
return node.string;
|
|
441
443
|
}
|
|
442
444
|
|
|
443
|
-
if (typeof _val2 ===
|
|
445
|
+
if (typeof _val2 === 'function') {
|
|
444
446
|
return _val2();
|
|
445
447
|
}
|
|
446
448
|
|
|
@@ -478,5 +480,4 @@ Interpolate.propTypes = {
|
|
|
478
480
|
graceful: PropTypes.bool
|
|
479
481
|
};
|
|
480
482
|
|
|
481
|
-
export default
|
|
482
|
-
export { SYNTAX_BUILT_IN, SYNTAX_I18NEXT, TOKEN_CLOSE_TAG, TOKEN_OPEN_TAG, TOKEN_PLACEHOLDER, TOKEN_SELF_TAG };
|
|
483
|
+
export { SYNTAX_BUILT_IN, SYNTAX_I18NEXT, TOKEN_CLOSE_TAG, TOKEN_OPEN_TAG, TOKEN_PLACEHOLDER, TOKEN_SELF_TAG, Interpolate as default };
|
package/package.json
CHANGED
|
@@ -1,64 +1,75 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
2
|
+
"name": "@doist/react-interpolate",
|
|
3
|
+
"version": "0.3.8",
|
|
4
|
+
"description": "A string interpolation component that formats and interpolates a template string in a safe way",
|
|
5
|
+
"main": "dist/react-interpolate.cjs",
|
|
6
|
+
"module": "dist/react-interpolate.mjs",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": "16.13",
|
|
9
|
+
"npm": "8.1.0"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"src"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"lint": "eslint ./src ./__test__",
|
|
18
|
+
"build": "del dist && rollup -c && npm run mini-cjs && npm run mini-mjs",
|
|
19
|
+
"mini-cjs": "uglifyjs dist/react-interpolate.cjs --compress --mangle --enclose --output dist/react-interpolate.min.cjs",
|
|
20
|
+
"mini-mjs": "uglifyjs dist/react-interpolate.mjs --compress --mangle --enclose --output dist/react-interpolate.min.mjs",
|
|
21
|
+
"prettify": "prettier --write ."
|
|
22
|
+
},
|
|
23
|
+
"prettier": "@doist/prettier-config",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/Doist/react-interpolate.git"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"react",
|
|
30
|
+
"interpolate",
|
|
31
|
+
"template",
|
|
32
|
+
"format",
|
|
33
|
+
"text",
|
|
34
|
+
"string"
|
|
35
|
+
],
|
|
36
|
+
"author": "Steven Kao",
|
|
37
|
+
"license": "ISC",
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^17.0.2",
|
|
40
|
+
"react-dom": "^17.0.2"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@babel/cli": "^7.16.0",
|
|
44
|
+
"@babel/core": "^7.16.0",
|
|
45
|
+
"@babel/eslint-parser": "^7.16.3",
|
|
46
|
+
"@babel/plugin-transform-runtime": "^7.16.4",
|
|
47
|
+
"@babel/preset-env": "^7.16.4",
|
|
48
|
+
"@babel/preset-react": "^7.16.0",
|
|
49
|
+
"@doist/eslint-config": "^7.0.0",
|
|
50
|
+
"@doist/prettier-config": "^3.0.5",
|
|
51
|
+
"@testing-library/react": "^12.1.2",
|
|
52
|
+
"babel-jest": "^27.4.1",
|
|
53
|
+
"core-js": "^3.19.2",
|
|
54
|
+
"del-cli": "^4.0.1",
|
|
55
|
+
"eslint": "^8.3.0",
|
|
56
|
+
"eslint-config-prettier": "^8.3.0",
|
|
57
|
+
"eslint-plugin-compat": "^4.0.0",
|
|
58
|
+
"eslint-plugin-import": "^2.25.3",
|
|
59
|
+
"eslint-plugin-jest": "^25.3.0",
|
|
60
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
61
|
+
"eslint-plugin-react": "^7.27.1",
|
|
62
|
+
"eslint-plugin-react-hooks": "^4.3.0",
|
|
63
|
+
"gzip-cli": "^1.2.0",
|
|
64
|
+
"jest": "^27.4.1",
|
|
65
|
+
"prettier": "^2.5.0",
|
|
66
|
+
"react": "^17.0.2",
|
|
67
|
+
"react-dom": "^17.0.2",
|
|
68
|
+
"rollup": "^2.60.2",
|
|
69
|
+
"rollup-plugin-babel": "^4.4.0",
|
|
70
|
+
"uglify-es": "^3.3.9"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@babel/runtime": "^7.16.3"
|
|
74
|
+
}
|
|
64
75
|
}
|
package/src/constants.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export const TOKEN_PLACEHOLDER =
|
|
2
|
-
export const TOKEN_OPEN_TAG =
|
|
3
|
-
export const TOKEN_CLOSE_TAG =
|
|
4
|
-
export const TOKEN_SELF_TAG =
|
|
5
|
-
export const TOKEN_TEXT =
|
|
1
|
+
export const TOKEN_PLACEHOLDER = 'TOKEN_PLACEHOLDER'
|
|
2
|
+
export const TOKEN_OPEN_TAG = 'TOKEN_OPEN_TAG'
|
|
3
|
+
export const TOKEN_CLOSE_TAG = 'TOKEN_CLOSE_TAG'
|
|
4
|
+
export const TOKEN_SELF_TAG = 'TOKEN_SELF_TAG'
|
|
5
|
+
export const TOKEN_TEXT = 'TOKEN_TEXT'
|
|
6
6
|
|
|
7
|
-
export const NODE_FRAGMENT =
|
|
8
|
-
export const NODE_TAG_ELEMENT =
|
|
9
|
-
export const NODE_VOID_ELEMENT =
|
|
10
|
-
export const NODE_PLACEHOLDER =
|
|
11
|
-
export const NODE_TEXT =
|
|
7
|
+
export const NODE_FRAGMENT = 'NODE_FRAGMENT'
|
|
8
|
+
export const NODE_TAG_ELEMENT = 'NODE_TAG_ELEMENT'
|
|
9
|
+
export const NODE_VOID_ELEMENT = 'NODE_VOID_ELEMENT'
|
|
10
|
+
export const NODE_PLACEHOLDER = 'NODE_PLACEHOLDER'
|
|
11
|
+
export const NODE_TEXT = 'NODE_TEXT'
|
package/src/index.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import Interpolate from
|
|
1
|
+
import Interpolate from './interpolate'
|
|
2
2
|
export default Interpolate
|
|
3
3
|
|
|
4
|
-
export { SYNTAX_I18NEXT, SYNTAX_BUILT_IN } from
|
|
5
|
-
export {
|
|
6
|
-
TOKEN_PLACEHOLDER,
|
|
7
|
-
TOKEN_OPEN_TAG,
|
|
8
|
-
TOKEN_CLOSE_TAG,
|
|
9
|
-
TOKEN_SELF_TAG
|
|
10
|
-
} from "./constants"
|
|
4
|
+
export { SYNTAX_I18NEXT, SYNTAX_BUILT_IN } from './syntax'
|
|
5
|
+
export { TOKEN_PLACEHOLDER, TOKEN_OPEN_TAG, TOKEN_CLOSE_TAG, TOKEN_SELF_TAG } from './constants'
|
package/src/interpolate.js
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import PropTypes from
|
|
3
|
-
import parser from
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import parser from './parser'
|
|
4
4
|
import {
|
|
5
5
|
NODE_FRAGMENT,
|
|
6
6
|
NODE_TAG_ELEMENT,
|
|
7
7
|
NODE_VOID_ELEMENT,
|
|
8
8
|
NODE_PLACEHOLDER,
|
|
9
|
-
NODE_TEXT
|
|
10
|
-
} from
|
|
9
|
+
NODE_TEXT,
|
|
10
|
+
} from './constants'
|
|
11
11
|
|
|
12
12
|
const createElement = (node, mapping, keyPrefix) => {
|
|
13
13
|
const children = node.children.map((c, i) => (
|
|
14
|
-
<React.Fragment key={keyPrefix + i}>
|
|
15
|
-
{createElement(c, mapping, keyPrefix)}
|
|
16
|
-
</React.Fragment>
|
|
14
|
+
<React.Fragment key={keyPrefix + i}>{createElement(c, mapping, keyPrefix)}</React.Fragment>
|
|
17
15
|
))
|
|
18
16
|
|
|
19
17
|
switch (node.type) {
|
|
@@ -25,7 +23,7 @@ const createElement = (node, mapping, keyPrefix) => {
|
|
|
25
23
|
}
|
|
26
24
|
case NODE_VOID_ELEMENT: {
|
|
27
25
|
const val = mapping[node.name]
|
|
28
|
-
if (typeof val ===
|
|
26
|
+
if (typeof val === 'function') {
|
|
29
27
|
return val()
|
|
30
28
|
}
|
|
31
29
|
|
|
@@ -38,14 +36,14 @@ const createElement = (node, mapping, keyPrefix) => {
|
|
|
38
36
|
return React.createElement(node.name, null, children)
|
|
39
37
|
}
|
|
40
38
|
|
|
41
|
-
if (typeof val ===
|
|
39
|
+
if (typeof val === 'function') {
|
|
42
40
|
return val(children)
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
if (React.isValidElement(val)) {
|
|
46
44
|
if (React.Children.count(val.props.children) !== 0) {
|
|
47
45
|
throw new Error(
|
|
48
|
-
|
|
46
|
+
'when passing an element as value, the element should not contains children',
|
|
49
47
|
)
|
|
50
48
|
}
|
|
51
49
|
|
|
@@ -53,7 +51,7 @@ const createElement = (node, mapping, keyPrefix) => {
|
|
|
53
51
|
}
|
|
54
52
|
|
|
55
53
|
throw new Error(
|
|
56
|
-
`Invalid mapping value for "${node.name}". Only element or render function are accepted
|
|
54
|
+
`Invalid mapping value for "${node.name}". Only element or render function are accepted`,
|
|
57
55
|
)
|
|
58
56
|
}
|
|
59
57
|
case NODE_PLACEHOLDER: {
|
|
@@ -63,7 +61,7 @@ const createElement = (node, mapping, keyPrefix) => {
|
|
|
63
61
|
return node.string
|
|
64
62
|
}
|
|
65
63
|
|
|
66
|
-
if (typeof val ===
|
|
64
|
+
if (typeof val === 'function') {
|
|
67
65
|
return val()
|
|
68
66
|
}
|
|
69
67
|
|
|
@@ -74,12 +72,7 @@ const createElement = (node, mapping, keyPrefix) => {
|
|
|
74
72
|
}
|
|
75
73
|
}
|
|
76
74
|
|
|
77
|
-
export default function Interpolate({
|
|
78
|
-
string,
|
|
79
|
-
syntax,
|
|
80
|
-
mapping = {},
|
|
81
|
-
graceful = true
|
|
82
|
-
}) {
|
|
75
|
+
export default function Interpolate({ string, syntax, mapping = {}, graceful = true }) {
|
|
83
76
|
try {
|
|
84
77
|
const tree = parser(string, syntax)
|
|
85
78
|
return createElement(tree, mapping, string)
|
|
@@ -96,5 +89,5 @@ export default function Interpolate({
|
|
|
96
89
|
Interpolate.propTypes = {
|
|
97
90
|
string: PropTypes.string.isRequired,
|
|
98
91
|
mapping: PropTypes.object,
|
|
99
|
-
graceful: PropTypes.bool
|
|
92
|
+
graceful: PropTypes.bool,
|
|
100
93
|
}
|
package/src/lexer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TOKEN_TEXT } from
|
|
2
|
-
export { SYNTAX_I18NEXT, SYNTAX_BUILT_IN } from
|
|
1
|
+
import { TOKEN_TEXT } from './constants'
|
|
2
|
+
export { SYNTAX_I18NEXT, SYNTAX_BUILT_IN } from './syntax'
|
|
3
3
|
|
|
4
4
|
/*
|
|
5
5
|
* return a array of token object
|
|
@@ -17,7 +17,7 @@ export default function lexer(string, syntax) {
|
|
|
17
17
|
string: res[0],
|
|
18
18
|
name: res[1],
|
|
19
19
|
start: res.index,
|
|
20
|
-
end: res.index + res[0].length
|
|
20
|
+
end: res.index + res[0].length,
|
|
21
21
|
})
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -26,7 +26,7 @@ export default function lexer(string, syntax) {
|
|
|
26
26
|
const textTokens = []
|
|
27
27
|
|
|
28
28
|
let start = 0
|
|
29
|
-
matches.forEach(match => {
|
|
29
|
+
matches.forEach((match) => {
|
|
30
30
|
if (match.start === start) {
|
|
31
31
|
start = match.end
|
|
32
32
|
return
|
|
@@ -40,25 +40,23 @@ export default function lexer(string, syntax) {
|
|
|
40
40
|
string: text,
|
|
41
41
|
text,
|
|
42
42
|
start,
|
|
43
|
-
end
|
|
43
|
+
end,
|
|
44
44
|
})
|
|
45
45
|
|
|
46
46
|
start = match.end
|
|
47
47
|
})
|
|
48
48
|
|
|
49
49
|
const text = string.substring(start)
|
|
50
|
-
if (text !==
|
|
50
|
+
if (text !== '') {
|
|
51
51
|
textTokens.push({
|
|
52
52
|
type: TOKEN_TEXT,
|
|
53
53
|
string: text,
|
|
54
54
|
start,
|
|
55
|
-
end: string.length
|
|
55
|
+
end: string.length,
|
|
56
56
|
})
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
const tokens = []
|
|
60
|
-
.concat(textTokens, matches)
|
|
61
|
-
.sort((a, b) => a.start - b.start)
|
|
59
|
+
const tokens = [].concat(textTokens, matches).sort((a, b) => a.start - b.start)
|
|
62
60
|
|
|
63
61
|
return tokens
|
|
64
62
|
}
|
package/src/node.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
NODE_TAG_ELEMENT,
|
|
4
4
|
NODE_VOID_ELEMENT,
|
|
5
5
|
NODE_PLACEHOLDER,
|
|
6
|
-
NODE_TEXT
|
|
7
|
-
} from
|
|
6
|
+
NODE_TEXT,
|
|
7
|
+
} from './constants'
|
|
8
8
|
|
|
9
9
|
export default class Node {
|
|
10
10
|
constructor({ type, children, ...fields }) {
|
|
@@ -34,32 +34,32 @@ Node.createTagNode = (token, children) =>
|
|
|
34
34
|
type: NODE_TAG_ELEMENT,
|
|
35
35
|
children,
|
|
36
36
|
name: token.name,
|
|
37
|
-
token
|
|
37
|
+
token,
|
|
38
38
|
})
|
|
39
39
|
|
|
40
|
-
Node.createFragmentNode = children =>
|
|
40
|
+
Node.createFragmentNode = (children) =>
|
|
41
41
|
new Node({
|
|
42
42
|
type: NODE_FRAGMENT,
|
|
43
|
-
children
|
|
43
|
+
children,
|
|
44
44
|
})
|
|
45
45
|
|
|
46
|
-
Node.createVoidNode = token =>
|
|
46
|
+
Node.createVoidNode = (token) =>
|
|
47
47
|
new Node({
|
|
48
48
|
type: NODE_VOID_ELEMENT,
|
|
49
49
|
name: token.name,
|
|
50
|
-
token
|
|
50
|
+
token,
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
-
Node.createTextNode = token =>
|
|
53
|
+
Node.createTextNode = (token) =>
|
|
54
54
|
new Node({
|
|
55
55
|
type: NODE_TEXT,
|
|
56
56
|
text: token.string,
|
|
57
|
-
token
|
|
57
|
+
token,
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
-
Node.createPlaceholderNode = token =>
|
|
60
|
+
Node.createPlaceholderNode = (token) =>
|
|
61
61
|
new Node({
|
|
62
62
|
type: NODE_PLACEHOLDER,
|
|
63
63
|
name: token.name,
|
|
64
|
-
token
|
|
64
|
+
token,
|
|
65
65
|
})
|
package/src/parser.js
CHANGED
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
TOKEN_OPEN_TAG,
|
|
4
4
|
TOKEN_CLOSE_TAG,
|
|
5
5
|
TOKEN_SELF_TAG,
|
|
6
|
-
TOKEN_TEXT
|
|
7
|
-
} from
|
|
8
|
-
import Node from
|
|
9
|
-
import lexer from
|
|
10
|
-
import { SYNTAX_BUILT_IN } from
|
|
6
|
+
TOKEN_TEXT,
|
|
7
|
+
} from './constants'
|
|
8
|
+
import Node from './node.js'
|
|
9
|
+
import lexer from './lexer'
|
|
10
|
+
import { SYNTAX_BUILT_IN } from './syntax'
|
|
11
11
|
|
|
12
12
|
export default function parser(string, syntax) {
|
|
13
13
|
if (!syntax) {
|
|
@@ -19,12 +19,11 @@ export default function parser(string, syntax) {
|
|
|
19
19
|
return p.parse()
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const SYNTAX_ERROR =
|
|
23
|
-
"Syntax error. Please check if each open tag is closed correctly"
|
|
22
|
+
const SYNTAX_ERROR = 'Syntax error. Please check if each open tag is closed correctly'
|
|
24
23
|
|
|
25
24
|
// A special token representing end of the tream
|
|
26
25
|
const EPSILON = {
|
|
27
|
-
type:
|
|
26
|
+
type: 'EPSILON',
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
/*
|
package/src/syntax.js
CHANGED
|
@@ -1,38 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
TOKEN_PLACEHOLDER,
|
|
3
|
-
TOKEN_OPEN_TAG,
|
|
4
|
-
TOKEN_CLOSE_TAG,
|
|
5
|
-
TOKEN_SELF_TAG
|
|
6
|
-
} from "./constants"
|
|
1
|
+
import { TOKEN_PLACEHOLDER, TOKEN_OPEN_TAG, TOKEN_CLOSE_TAG, TOKEN_SELF_TAG } from './constants'
|
|
7
2
|
|
|
8
3
|
export const SYNTAX_BUILT_IN = [
|
|
9
4
|
{
|
|
10
5
|
type: TOKEN_PLACEHOLDER,
|
|
11
|
-
regex: /{\s*(\w+)\s*}/g
|
|
6
|
+
regex: /{\s*(\w+)\s*}/g,
|
|
12
7
|
},
|
|
13
8
|
{
|
|
14
9
|
type: TOKEN_OPEN_TAG,
|
|
15
|
-
regex: /<(\w+)>/g
|
|
10
|
+
regex: /<(\w+)>/g,
|
|
16
11
|
},
|
|
17
12
|
{
|
|
18
13
|
type: TOKEN_CLOSE_TAG,
|
|
19
|
-
regex: /<\/(\w+)>/g
|
|
14
|
+
regex: /<\/(\w+)>/g,
|
|
20
15
|
},
|
|
21
|
-
{ type: TOKEN_SELF_TAG, regex: /<(\w+)\s*\/>/g }
|
|
16
|
+
{ type: TOKEN_SELF_TAG, regex: /<(\w+)\s*\/>/g },
|
|
22
17
|
]
|
|
23
18
|
|
|
24
19
|
export const SYNTAX_I18NEXT = [
|
|
25
20
|
{
|
|
26
21
|
type: TOKEN_PLACEHOLDER,
|
|
27
|
-
regex: /{{\s*(\w+)\s*}}/g
|
|
22
|
+
regex: /{{\s*(\w+)\s*}}/g,
|
|
28
23
|
},
|
|
29
24
|
{
|
|
30
25
|
type: TOKEN_OPEN_TAG,
|
|
31
|
-
regex: /<(\w+)>/g
|
|
26
|
+
regex: /<(\w+)>/g,
|
|
32
27
|
},
|
|
33
28
|
{
|
|
34
29
|
type: TOKEN_CLOSE_TAG,
|
|
35
|
-
regex: /<\/(\w+)>/g
|
|
30
|
+
regex: /<\/(\w+)>/g,
|
|
36
31
|
},
|
|
37
|
-
{ type: TOKEN_SELF_TAG, regex: /<(\w+)\s*\/>/g }
|
|
32
|
+
{ type: TOKEN_SELF_TAG, regex: /<(\w+)\s*\/>/g },
|
|
38
33
|
]
|
package/.eslintrc.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
const config = {
|
|
2
|
-
extends: [
|
|
3
|
-
"eslint:recommended",
|
|
4
|
-
"plugin:react/recommended",
|
|
5
|
-
"prettier",
|
|
6
|
-
"prettier/react",
|
|
7
|
-
"plugin:compat/recommended"
|
|
8
|
-
],
|
|
9
|
-
env: {
|
|
10
|
-
browser: true,
|
|
11
|
-
"jest/globals": true
|
|
12
|
-
},
|
|
13
|
-
parserOptions: {
|
|
14
|
-
ecmaFeatures: {
|
|
15
|
-
jsx: true,
|
|
16
|
-
impliedStrict: true
|
|
17
|
-
},
|
|
18
|
-
sourceType: "module"
|
|
19
|
-
},
|
|
20
|
-
plugins: ["react", "prettier", "react-hooks", "jest"],
|
|
21
|
-
parser: "babel-eslint",
|
|
22
|
-
rules: {
|
|
23
|
-
semi: ["error", "never"],
|
|
24
|
-
"arrow-parens": ["error", "as-needed"],
|
|
25
|
-
"prettier/prettier": "error",
|
|
26
|
-
"react-hooks/rules-of-hooks": "error",
|
|
27
|
-
"react-hooks/exhaustive-deps": "error"
|
|
28
|
-
},
|
|
29
|
-
settings: {
|
|
30
|
-
react: {
|
|
31
|
-
version: "16.0"
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
module.exports = config
|