pseudo-localization 2.1.0 → 2.3.2
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 +12 -7
- package/bin/pseudo-localize +147 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +5 -3
- package/CHANGELOG.md +0 -46
- package/lib/pseudoLocalizeString.js +0 -2
- package/lib/pseudoLocalizeString.js.map +0 -1
package/README.md
CHANGED
|
@@ -38,8 +38,13 @@ import pseudoLocalization from 'pseudo-localization';
|
|
|
38
38
|
|
|
39
39
|
pseudoLocalization.start();
|
|
40
40
|
|
|
41
|
+
pseudoLocalization.isEnabled // true
|
|
42
|
+
|
|
41
43
|
// Later, if needed
|
|
42
44
|
pseudoLocalization.stop();
|
|
45
|
+
|
|
46
|
+
pseudoLocalization.isEnabled // false
|
|
47
|
+
|
|
43
48
|
```
|
|
44
49
|
|
|
45
50
|
To use `pseudo-localization` in React, Vue, Ember or anything else, hook the `start` and `stop` methods into your libraries
|
|
@@ -202,25 +207,25 @@ The pseudo localization strategy to use when transforming strings. Accepted valu
|
|
|
202
207
|
For easy scripting a CLI interface is exposed. The interface supports raw input, JSON files, and CommonJS modules.
|
|
203
208
|
|
|
204
209
|
```bash
|
|
205
|
-
npx pseudo-
|
|
210
|
+
npx pseudo-localization ./path/to/file.json
|
|
206
211
|
|
|
207
212
|
# pass in a JS transpiled ES module or an exported CJS module
|
|
208
|
-
npx pseudo-
|
|
213
|
+
npx pseudo-localization ./path/to/file
|
|
209
214
|
|
|
210
215
|
# pass in JSON files through STDIN
|
|
211
|
-
cat ./path/to/file.json | npx pseudo-
|
|
216
|
+
cat ./path/to/file.json | npx pseudo-localization --strategy bidi
|
|
212
217
|
|
|
213
218
|
# pass a string via a pipe
|
|
214
|
-
echo hello world | npx pseudo-
|
|
219
|
+
echo hello world | npx pseudo-localization
|
|
215
220
|
|
|
216
221
|
# direct input pseudo-localization
|
|
217
|
-
npx pseudo-
|
|
222
|
+
npx pseudo-localization -i "hello world"
|
|
218
223
|
```
|
|
219
224
|
|
|
220
225
|
CLI Options:
|
|
221
226
|
|
|
222
227
|
```
|
|
223
|
-
pseudo-
|
|
228
|
+
pseudo-localization [src] [options]
|
|
224
229
|
|
|
225
230
|
Pseudo localize a string, JSON file, or a JavaScript object
|
|
226
231
|
|
|
@@ -230,7 +235,7 @@ Positionals:
|
|
|
230
235
|
Options:
|
|
231
236
|
-o, --output Writes output to STDOUT by default. Optionally specify a JSON
|
|
232
237
|
file to write the pseudo-localizations to [string]
|
|
233
|
-
-i, --input Pass in direct input to pseudo-
|
|
238
|
+
-i, --input Pass in direct input to pseudo-localization [string]
|
|
234
239
|
--debug Print out all stack traces and other debug info [boolean]
|
|
235
240
|
--pretty Pretty print JSON output [boolean]
|
|
236
241
|
--strategy Set the strategy for localization
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const getStdin = require('get-stdin');
|
|
6
|
+
const flatten = require('flat');
|
|
7
|
+
const unflatten = require('flat').unflatten;
|
|
8
|
+
|
|
9
|
+
const { localize } = require('../lib/index');
|
|
10
|
+
|
|
11
|
+
const argv = require('yargs')
|
|
12
|
+
.usage(
|
|
13
|
+
'$0 [src] [options]',
|
|
14
|
+
'Pseudo localize a string, JSON file, or a JavaScript object',
|
|
15
|
+
function(yargs) {
|
|
16
|
+
yargs.positional('src', {
|
|
17
|
+
describe: 'The source as a path or from STDIN',
|
|
18
|
+
type: 'string',
|
|
19
|
+
coerce: path.resolve,
|
|
20
|
+
conflicts: 'i',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
.options({
|
|
25
|
+
o: {
|
|
26
|
+
alias: 'output',
|
|
27
|
+
describe:
|
|
28
|
+
'Writes output to STDOUT by default. Optionally specify a JSON file to write the pseudo-localizations to',
|
|
29
|
+
type: 'string',
|
|
30
|
+
coerce: path.resolve,
|
|
31
|
+
},
|
|
32
|
+
i: {
|
|
33
|
+
alias: 'input',
|
|
34
|
+
describe: 'Pass in direct input to pseudo-localize',
|
|
35
|
+
type: 'string',
|
|
36
|
+
conflicts: 'src',
|
|
37
|
+
},
|
|
38
|
+
debug: {
|
|
39
|
+
describe: 'Print out all stack traces and other debug info',
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
},
|
|
42
|
+
pretty: {
|
|
43
|
+
describe: 'Pretty print JSON output',
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
},
|
|
46
|
+
strategy: {
|
|
47
|
+
describe: 'Set the strategy for localization',
|
|
48
|
+
choices: ['accented', 'bidi'],
|
|
49
|
+
default: 'accented',
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
.help()
|
|
53
|
+
.version().argv;
|
|
54
|
+
|
|
55
|
+
const debug = function(e) {
|
|
56
|
+
if (argv.debug) {
|
|
57
|
+
console.error(e);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const write = function(output) {
|
|
62
|
+
argv.output ? fs.writeFileSync(argv.output, output) : fs.writeSync(1, output);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const convert = function(input) {
|
|
66
|
+
const options = { strategy: argv.strategy };
|
|
67
|
+
|
|
68
|
+
if (typeof input === 'string') {
|
|
69
|
+
write(localize(input, options));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Flatten nested translation JSONs
|
|
74
|
+
input = flatten(input, {
|
|
75
|
+
safe: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
for (let key in input) {
|
|
79
|
+
// this will need to be updated if other primitives
|
|
80
|
+
// support pseudo-localization
|
|
81
|
+
if (typeof input[key] === 'string') {
|
|
82
|
+
input[key] = localize(input[key], options);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Retrieve initial JSON structure
|
|
87
|
+
output = unflatten(input, {
|
|
88
|
+
safe: true,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
write(JSON.stringify(output, null, argv.pretty ? 4 : undefined) + '\n');
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
(function() {
|
|
95
|
+
'use strict';
|
|
96
|
+
|
|
97
|
+
let json = null;
|
|
98
|
+
|
|
99
|
+
if (argv.i) {
|
|
100
|
+
convert(argv.i + '\n');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (argv.src) {
|
|
105
|
+
try {
|
|
106
|
+
json = require(argv.src);
|
|
107
|
+
|
|
108
|
+
if (json.default) {
|
|
109
|
+
json = json.default;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
convert(json);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
debug(e);
|
|
115
|
+
|
|
116
|
+
console.error(
|
|
117
|
+
`${e.message}\nUnable to parse input file. Make sure it is in JSON format or is an exported JS module`
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
getStdin()
|
|
124
|
+
.then(function(input) {
|
|
125
|
+
if (!input) {
|
|
126
|
+
console.warn('No input from STDIN detected. Exiting...');
|
|
127
|
+
process.exit(0);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let string = input;
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
string = JSON.parse(input);
|
|
134
|
+
} catch (e) {
|
|
135
|
+
// do nothing
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
convert(string);
|
|
139
|
+
})
|
|
140
|
+
.catch(function(e) {
|
|
141
|
+
debug(e);
|
|
142
|
+
console.error(
|
|
143
|
+
`${e.message}\nUnable to parse source from STDIN. Is it a valid JSON file?`
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
})(argv);
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"localize",{enumerable:true,get:function get(){return _localize.default}});exports.default=void 0;var _localize=_interopRequireDefault(require("./localize.js"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var pseudoLocalization=function(){var opts={blacklistedNodeNames:["STYLE"]};var observer=null;var observerConfig={characterData:true,childList:true,subtree:true};var textNodesUnder=function textNodesUnder(element){var walker=document.createTreeWalker(element,NodeFilter.SHOW_TEXT,function(node){var isAllWhitespace=!/[^\s]/.test(node.nodeValue);if(isAllWhitespace)return NodeFilter.FILTER_REJECT;var isBlacklistedNode=opts.blacklistedNodeNames.includes(node.parentElement.nodeName);if(isBlacklistedNode)return NodeFilter.FILTER_REJECT;return NodeFilter.FILTER_ACCEPT});var currNode;var textNodes=[];while(currNode=walker.nextNode()){textNodes.push(currNode)}return textNodes};var isNonEmptyString=function isNonEmptyString(str){return str&&typeof str==="string"};var pseudoLocalize=function pseudoLocalize(element){var textNodesUnderElement=textNodesUnder(element);var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=textNodesUnderElement[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var textNode=_step.value;var nodeValue=textNode.nodeValue;if(isNonEmptyString(nodeValue)){textNode.nodeValue=(0,_localize.default)(nodeValue,opts)}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}};var domMutationCallback=function domMutationCallback(mutationsList){var _iteratorNormalCompletion2=true;var _didIteratorError2=false;var _iteratorError2=undefined;try{for(var _iterator2=mutationsList[Symbol.iterator](),_step2;!(_iteratorNormalCompletion2=(_step2=_iterator2.next()).done);_iteratorNormalCompletion2=true){var mutation=_step2.value;if(mutation.type==="childList"&&mutation.addedNodes.length>0){observer.disconnect();mutation.addedNodes.forEach(pseudoLocalize);observer.observe(document.body,observerConfig)}else if(mutation.type==="characterData"){var nodeValue=mutation.target.nodeValue;var isBlacklistedNode=opts.blacklistedNodeNames.includes(mutation.target.parentElement.nodeName);if(isNonEmptyString(nodeValue)&&!isBlacklistedNode){observer.disconnect();mutation.target.nodeValue=(0,_localize.default)(nodeValue,opts);observer.observe(document.body,observerConfig)}}}}catch(err){_didIteratorError2=true;_iteratorError2=err}finally{try{if(!_iteratorNormalCompletion2&&_iterator2.return!=null){_iterator2.return()}}finally{if(_didIteratorError2){throw _iteratorError2}}}};var start=function start(){var _ref=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{},_ref$strategy=_ref.strategy,strategy=_ref$strategy===void 0?"accented":_ref$strategy,_ref$blacklistedNodeN=_ref.blacklistedNodeNames,blacklistedNodeNames=_ref$blacklistedNodeN===void 0?opts.blacklistedNodeNames:_ref$blacklistedNodeN;opts.blacklistedNodeNames=blacklistedNodeNames;opts.strategy=strategy;pseudoLocalize(document.body);observer=new MutationObserver(domMutationCallback);observer.observe(document.body,observerConfig)};var stop=function stop(){observer&&observer.disconnect()};return{start:start,stop:stop,localize:_localize.default}}();var _default=pseudoLocalization;exports.default=_default;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"localize",{enumerable:true,get:function get(){return _localize.default}});exports.default=void 0;var _localize=_interopRequireDefault(require("./localize.js"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var pseudoLocalization=function(){var opts={blacklistedNodeNames:["STYLE"]};var isEnabled=false;var observer=null;var observerConfig={characterData:true,childList:true,subtree:true};var textNodesUnder=function textNodesUnder(element){var walker=document.createTreeWalker(element,NodeFilter.SHOW_TEXT,function(node){var isAllWhitespace=!/[^\s]/.test(node.nodeValue);if(isAllWhitespace)return NodeFilter.FILTER_REJECT;var isBlacklistedNode=opts.blacklistedNodeNames.includes(node.parentElement.nodeName);if(isBlacklistedNode)return NodeFilter.FILTER_REJECT;return NodeFilter.FILTER_ACCEPT});var currNode;var textNodes=[];while(currNode=walker.nextNode()){textNodes.push(currNode)}return textNodes};var isNonEmptyString=function isNonEmptyString(str){return str&&typeof str==="string"};var pseudoLocalize=function pseudoLocalize(element){var textNodesUnderElement=textNodesUnder(element);var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=textNodesUnderElement[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var textNode=_step.value;var nodeValue=textNode.nodeValue;if(isNonEmptyString(nodeValue)){textNode.nodeValue=(0,_localize.default)(nodeValue,opts)}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}};var domMutationCallback=function domMutationCallback(mutationsList){var _iteratorNormalCompletion2=true;var _didIteratorError2=false;var _iteratorError2=undefined;try{for(var _iterator2=mutationsList[Symbol.iterator](),_step2;!(_iteratorNormalCompletion2=(_step2=_iterator2.next()).done);_iteratorNormalCompletion2=true){var mutation=_step2.value;if(mutation.type==="childList"&&mutation.addedNodes.length>0){observer.disconnect();mutation.addedNodes.forEach(pseudoLocalize);observer.observe(document.body,observerConfig)}else if(mutation.type==="characterData"){var nodeValue=mutation.target.nodeValue;var isBlacklistedNode=opts.blacklistedNodeNames.includes(mutation.target.parentElement.nodeName);if(isNonEmptyString(nodeValue)&&!isBlacklistedNode){observer.disconnect();mutation.target.nodeValue=(0,_localize.default)(nodeValue,opts);observer.observe(document.body,observerConfig)}}}}catch(err){_didIteratorError2=true;_iteratorError2=err}finally{try{if(!_iteratorNormalCompletion2&&_iterator2.return!=null){_iterator2.return()}}finally{if(_didIteratorError2){throw _iteratorError2}}}};var start=function start(){var _ref=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{},_ref$strategy=_ref.strategy,strategy=_ref$strategy===void 0?"accented":_ref$strategy,_ref$blacklistedNodeN=_ref.blacklistedNodeNames,blacklistedNodeNames=_ref$blacklistedNodeN===void 0?opts.blacklistedNodeNames:_ref$blacklistedNodeN;opts.blacklistedNodeNames=blacklistedNodeNames;opts.strategy=strategy;pseudoLocalize(document.body);observer=new MutationObserver(domMutationCallback);observer.observe(document.body,observerConfig);isEnabled=true};var stop=function stop(){observer&&observer.disconnect();isEnabled=false};return{start:start,stop:stop,isEnabled:isEnabled,localize:_localize.default}}();var _default=pseudoLocalization;exports.default=_default;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["pseudoLocalization","opts","blacklistedNodeNames","observer","observerConfig","characterData","childList","subtree","textNodesUnder","element","walker","document","createTreeWalker","NodeFilter","SHOW_TEXT","node","isAllWhitespace","test","nodeValue","FILTER_REJECT","isBlacklistedNode","includes","parentElement","nodeName","FILTER_ACCEPT","currNode","textNodes","nextNode","push","isNonEmptyString","str","pseudoLocalize","textNodesUnderElement","textNode","domMutationCallback","mutationsList","mutation","type","addedNodes","length","disconnect","forEach","observe","body","target","start","strategy","MutationObserver","stop","localize","pseudoLocalizeString"],"mappings":"sMAAA,+D,kFASA,GAAMA,CAAAA,kBAAkB,CAAI,UAAM,CAChC,GAAMC,CAAAA,IAAI,CAAG,CACXC,oBAAoB,CAAE,CAAC,OAAD,CADX,CAAb,
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["pseudoLocalization","opts","blacklistedNodeNames","isEnabled","observer","observerConfig","characterData","childList","subtree","textNodesUnder","element","walker","document","createTreeWalker","NodeFilter","SHOW_TEXT","node","isAllWhitespace","test","nodeValue","FILTER_REJECT","isBlacklistedNode","includes","parentElement","nodeName","FILTER_ACCEPT","currNode","textNodes","nextNode","push","isNonEmptyString","str","pseudoLocalize","textNodesUnderElement","textNode","domMutationCallback","mutationsList","mutation","type","addedNodes","length","disconnect","forEach","observe","body","target","start","strategy","MutationObserver","stop","localize","pseudoLocalizeString"],"mappings":"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","sourcesContent":["import pseudoLocalizeString from './localize.js';\n\n/**\n * export the underlying pseudo localization function so this import style\n * import { localize } from 'pseudo-localization';\n * can be used.\n */\nexport { default as localize } from './localize.js';\n\nconst pseudoLocalization = (() => {\n const opts = {\n blacklistedNodeNames: ['STYLE'],\n };\n\n // Indicates whether the pseudo-localization is currently enabled.\n let isEnabled = false;\n\n // Observer for dom updates. Initialization is defered to make parts\n // of the API safe to use in non-browser environments like nodejs\n let observer = null;\n const observerConfig = {\n characterData: true,\n childList: true,\n subtree: true,\n };\n\n const textNodesUnder = element => {\n const walker = document.createTreeWalker(\n element,\n NodeFilter.SHOW_TEXT,\n node => {\n const isAllWhitespace = !/[^\\s]/.test(node.nodeValue);\n if (isAllWhitespace) return NodeFilter.FILTER_REJECT;\n\n const isBlacklistedNode = opts.blacklistedNodeNames.includes(\n node.parentElement.nodeName\n );\n if (isBlacklistedNode) return NodeFilter.FILTER_REJECT;\n\n return NodeFilter.FILTER_ACCEPT;\n }\n );\n\n let currNode;\n const textNodes = [];\n while ((currNode = walker.nextNode())) textNodes.push(currNode);\n return textNodes;\n };\n\n const isNonEmptyString = str => str && typeof str === 'string';\n\n const pseudoLocalize = element => {\n const textNodesUnderElement = textNodesUnder(element);\n for (let textNode of textNodesUnderElement) {\n const nodeValue = textNode.nodeValue;\n if (isNonEmptyString(nodeValue)) {\n textNode.nodeValue = pseudoLocalizeString(nodeValue, opts);\n }\n }\n };\n\n const domMutationCallback = mutationsList => {\n for (let mutation of mutationsList) {\n if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {\n // Turn the observer off while performing dom manipulation to prevent\n // infinite dom mutation callback loops\n observer.disconnect();\n // For every node added, recurse down it's subtree and convert\n // all children as well\n mutation.addedNodes.forEach(pseudoLocalize);\n observer.observe(document.body, observerConfig);\n } else if (mutation.type === 'characterData') {\n const nodeValue = mutation.target.nodeValue;\n const isBlacklistedNode = opts.blacklistedNodeNames.includes(\n mutation.target.parentElement.nodeName\n );\n if (isNonEmptyString(nodeValue) && !isBlacklistedNode) {\n // Turn the observer off while performing dom manipulation to prevent\n // infinite dom mutation callback loops\n observer.disconnect();\n // The target will always be a text node so it can be converted\n // directly\n mutation.target.nodeValue = pseudoLocalizeString(nodeValue, opts);\n observer.observe(document.body, observerConfig);\n }\n }\n }\n };\n\n const start = ({\n strategy = 'accented',\n blacklistedNodeNames = opts.blacklistedNodeNames,\n } = {}) => {\n opts.blacklistedNodeNames = blacklistedNodeNames;\n opts.strategy = strategy;\n // Pseudo localize the DOM\n pseudoLocalize(document.body);\n // Start observing the DOM for changes and run\n // pseudo localization on any added text nodes\n observer = new MutationObserver(domMutationCallback);\n observer.observe(document.body, observerConfig);\n isEnabled = true;\n };\n\n const stop = () => {\n observer && observer.disconnect();\n isEnabled = false;\n };\n\n return {\n start,\n stop,\n isEnabled,\n localize: pseudoLocalizeString,\n };\n})();\n\nexport default pseudoLocalization;\n"],"file":"index.js"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pseudo-localization",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Dynamic pseudo-localization in the browser and nodejs",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
7
|
-
"lib"
|
|
7
|
+
"lib",
|
|
8
|
+
"bin"
|
|
8
9
|
],
|
|
9
10
|
"bin": "./bin/pseudo-localize",
|
|
10
11
|
"scripts": {
|
|
@@ -42,7 +43,8 @@
|
|
|
42
43
|
"prettier": "^1.18.2"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
46
|
+
"flat": "^5.0.2",
|
|
45
47
|
"get-stdin": "^7.0.0",
|
|
46
|
-
"yargs": "^
|
|
48
|
+
"yargs": "^17.2.1"
|
|
47
49
|
}
|
|
48
50
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
##2.1.0
|
|
2
|
-
- Adding CLI interface
|
|
3
|
-
|
|
4
|
-
##2.0.2
|
|
5
|
-
- Fix a bug where blacklisted nodes would get pseudo-localized when mutated in the DOM
|
|
6
|
-
|
|
7
|
-
##2.0.1
|
|
8
|
-
- Mention in package.json description that `pseudo-localization` works with nodejs.
|
|
9
|
-
|
|
10
|
-
##2.0.0
|
|
11
|
-
- Safeguard childlist mutations and empty strings https://github.com/tryggvigy/pseudo-localization/pull/12
|
|
12
|
-
- Fixes https://github.com/tryggvigy/pseudo-localization/issues/6 and https://github.com/tryggvigy/pseudo-localization/issues/11
|
|
13
|
-
- Fix a bug where DOM mutation localizations did not respect the strategy specified https://github.com/tryggvigy/pseudo-localization/pull/16
|
|
14
|
-
- Refactor internals to use import/export ES modules https://github.com/tryggvigy/pseudo-localization/pull/16
|
|
15
|
-
- **BREAKING** `require` usage will have to change from
|
|
16
|
-
```js
|
|
17
|
-
const pseudoLocalization = require('pseudo-localization');
|
|
18
|
-
```
|
|
19
|
-
to
|
|
20
|
-
```js
|
|
21
|
-
const pseudoLocalization = require('pseudo-localization').default;
|
|
22
|
-
```
|
|
23
|
-
- Transform to "not dead" browsers through babel https://github.com/tryggvigy/pseudo-localization/pull/16
|
|
24
|
-
- Fixes https://github.com/tryggvigy/pseudo-localization/issues/8
|
|
25
|
-
|
|
26
|
-
##1.3.0
|
|
27
|
-
- Allow blacklisting nodes ([#9](https://github.com/tryggvigy/pseudo-localization/pull/9))
|
|
28
|
-
|
|
29
|
-
## 1.2.0
|
|
30
|
-
- Expose `localize` function
|
|
31
|
-
|
|
32
|
-
## 1.1.5
|
|
33
|
-
- Fix typo in README
|
|
34
|
-
- Set MIT as license in package.json
|
|
35
|
-
|
|
36
|
-
## 1.1.4
|
|
37
|
-
- Update explanatory picture in README.md
|
|
38
|
-
|
|
39
|
-
## 1.1.3
|
|
40
|
-
- Add support for bidirectional text
|
|
41
|
-
- `pseudoLocalization.start({ strategy: 'bidi' });`
|
|
42
|
-
- Changed several things to improve legibility
|
|
43
|
-
- Removed `[]` surrounding each string. horizontal Cutoff should be relatively easy to spot without those.
|
|
44
|
-
- Stop using `one two three ...` to elongagate the string by ~30-40% and instead duplicate letters withing the string itself.
|
|
45
|
-
- Tidy up pseudo language symbols maps to contain more legibile symbols
|
|
46
|
-
- Make pseudo language deterministic. Always use the same pseudo symbol for the same english letter.
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.pseudoLocalizeString=void 0;var ACCENTED_MAP={a:"\u0227",A:"\u0226",b:"\u0180",B:"\u0181",c:"\u0188",C:"\u0187",d:"\u1E13",D:"\u1E12",e:"\u1E17",E:"\u1E16",f:"\u0192",F:"\u0191",g:"\u0260",G:"\u0193",h:"\u0127",H:"\u0126",i:"\u012B",I:"\u012A",j:"\u0135",J:"\u0134",k:"\u0137",K:"\u0136",l:"\u0140",L:"\u013F",m:"\u1E3F",M:"\u1E3E",n:"\u019E",N:"\u0220",o:"\u01FF",O:"\u01FE",p:"\u01A5",P:"\u01A4",q:"\u024B",Q:"\u024A",r:"\u0159",R:"\u0158",s:"\u015F",S:"\u015E",t:"\u0167",T:"\u0166",v:"\u1E7D",V:"\u1E7C",u:"\u016D",U:"\u016C",w:"\u1E87",W:"\u1E86",x:"\u1E8B",X:"\u1E8A",y:"\u1E8F",Y:"\u1E8E",z:"\u1E91",Z:"\u1E90"};var BIDI_MAP={a:"\u0250",A:"\u2200",b:"q",B:"\u0510",c:"\u0254",C:"\u2183",d:"p",D:"\u15E1",e:"\u01DD",E:"\u018E",f:"\u025F",F:"\u2132",g:"\u0183",G:"\u2141",h:"\u0265",H:"H",i:"\u0131",I:"I",j:"\u027E",J:"\u017F",k:"\u029E",K:"\u04FC",l:"\u0285",L:"\u2142",m:"\u026F",M:"W",n:"u",N:"N",o:"o",O:"O",p:"d",P:"\u0500",q:"b",Q:"\xD2",r:"\u0279",R:"\u1D1A",s:"s",S:"S",t:"\u0287",T:"\u22A5",u:"n",U:"\u2229",v:"\u028C",V:"\u0245",w:"\u028D",W:"M",x:"x",X:"X",y:"\u028E",Y:"\u2144",z:"z",Z:"Z"};var strategies={accented:{prefix:"",postfix:"",map:ACCENTED_MAP,elongate:true},bidi:{prefix:"\u202E",postfix:"\u202C",map:BIDI_MAP,elongate:false}};var pseudoLocalizeString=function pseudoLocalizeString(string){var _ref=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{},_ref$strategy=_ref.strategy,strategy=_ref$strategy===void 0?"accented":_ref$strategy;var opts=strategies[strategy];var pseudoLocalizedText="";var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=string[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var character=_step.value;if(opts.map[character]){var cl=character.toLowerCase();if(opts.elongate&&(cl==="a"||cl==="e"||cl==="o"||cl==="u")){pseudoLocalizedText+=opts.map[character]+opts.map[character]}else pseudoLocalizedText+=opts.map[character]}else pseudoLocalizedText+=character}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}if(pseudoLocalizedText.startsWith(opts.prefix)&&pseudoLocalizedText.endsWith(opts.postfix)){return pseudoLocalizedText}return opts.prefix+pseudoLocalizedText+opts.postfix};exports.pseudoLocalizeString=pseudoLocalizeString;
|
|
2
|
-
//# sourceMappingURL=pseudoLocalizeString.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/pseudoLocalizeString.js"],"names":["ACCENTED_MAP","a","A","b","B","c","C","d","D","e","E","f","F","g","G","h","H","i","I","j","J","k","K","l","L","m","M","n","N","o","O","p","P","q","Q","r","R","s","S","t","T","v","V","u","U","w","W","x","X","y","Y","z","Z","BIDI_MAP","strategies","accented","prefix","postfix","map","elongate","bidi","pseudoLocalizeString","string","strategy","opts","pseudoLocalizedText","character","cl","toLowerCase","startsWith","endsWith"],"mappings":"0GAAA,GAAMA,CAAAA,YAAY,CAAG,CACnBC,CAAC,CAAE,QADgB,CAEnBC,CAAC,CAAE,QAFgB,CAGnBC,CAAC,CAAE,QAHgB,CAInBC,CAAC,CAAE,QAJgB,CAKnBC,CAAC,CAAE,QALgB,CAMnBC,CAAC,CAAE,QANgB,CAOnBC,CAAC,CAAE,QAPgB,CAQnBC,CAAC,CAAE,QARgB,CASnBC,CAAC,CAAE,QATgB,CAUnBC,CAAC,CAAE,QAVgB,CAWnBC,CAAC,CAAE,QAXgB,CAYnBC,CAAC,CAAE,QAZgB,CAanBC,CAAC,CAAE,QAbgB,CAcnBC,CAAC,CAAE,QAdgB,CAenBC,CAAC,CAAE,QAfgB,CAgBnBC,CAAC,CAAE,QAhBgB,CAiBnBC,CAAC,CAAE,QAjBgB,CAkBnBC,CAAC,CAAE,QAlBgB,CAmBnBC,CAAC,CAAE,QAnBgB,CAoBnBC,CAAC,CAAE,QApBgB,CAqBnBC,CAAC,CAAE,QArBgB,CAsBnBC,CAAC,CAAE,QAtBgB,CAuBnBC,CAAC,CAAE,QAvBgB,CAwBnBC,CAAC,CAAE,QAxBgB,CAyBnBC,CAAC,CAAE,QAzBgB,CA0BnBC,CAAC,CAAE,QA1BgB,CA2BnBC,CAAC,CAAE,QA3BgB,CA4BnBC,CAAC,CAAE,QA5BgB,CA6BnBC,CAAC,CAAE,QA7BgB,CA8BnBC,CAAC,CAAE,QA9BgB,CA+BnBC,CAAC,CAAE,QA/BgB,CAgCnBC,CAAC,CAAE,QAhCgB,CAiCnBC,CAAC,CAAE,QAjCgB,CAkCnBC,CAAC,CAAE,QAlCgB,CAmCnBC,CAAC,CAAE,QAnCgB,CAoCnBC,CAAC,CAAE,QApCgB,CAqCnBC,CAAC,CAAE,QArCgB,CAsCnBC,CAAC,CAAE,QAtCgB,CAuCnBC,CAAC,CAAE,QAvCgB,CAwCnBC,CAAC,CAAE,QAxCgB,CAyCnBC,CAAC,CAAE,QAzCgB,CA0CnBC,CAAC,CAAE,QA1CgB,CA2CnBC,CAAC,CAAE,QA3CgB,CA4CnBC,CAAC,CAAE,QA5CgB,CA6CnBC,CAAC,CAAE,QA7CgB,CA8CnBC,CAAC,CAAE,QA9CgB,CA+CnBC,CAAC,CAAE,QA/CgB,CAgDnBC,CAAC,CAAE,QAhDgB,CAiDnBC,CAAC,CAAE,QAjDgB,CAkDnBC,CAAC,CAAE,QAlDgB,CAmDnBC,CAAC,CAAE,QAnDgB,CAoDnBC,CAAC,CAAE,QApDgB,CAArB,CAuDA,GAAMC,CAAAA,QAAQ,CAAG,CACfpD,CAAC,CAAE,QADY,CAEfC,CAAC,CAAE,QAFY,CAGfC,CAAC,CAAE,GAHY,CAIfC,CAAC,CAAE,QAJY,CAKfC,CAAC,CAAE,QALY,CAMfC,CAAC,CAAE,QANY,CAOfC,CAAC,CAAE,GAPY,CAQfC,CAAC,CAAE,QARY,CASfC,CAAC,CAAE,QATY,CAUfC,CAAC,CAAE,QAVY,CAWfC,CAAC,CAAE,QAXY,CAYfC,CAAC,CAAE,QAZY,CAafC,CAAC,CAAE,QAbY,CAcfC,CAAC,CAAE,QAdY,CAefC,CAAC,CAAE,QAfY,CAgBfC,CAAC,CAAE,GAhBY,CAiBfC,CAAC,CAAE,QAjBY,CAkBfC,CAAC,CAAE,GAlBY,CAmBfC,CAAC,CAAE,QAnBY,CAoBfC,CAAC,CAAE,QApBY,CAqBfC,CAAC,CAAE,QArBY,CAsBfC,CAAC,CAAE,QAtBY,CAuBfC,CAAC,CAAE,QAvBY,CAwBfC,CAAC,CAAE,QAxBY,CAyBfC,CAAC,CAAE,QAzBY,CA0BfC,CAAC,CAAE,GA1BY,CA2BfC,CAAC,CAAE,GA3BY,CA4BfC,CAAC,CAAE,GA5BY,CA6BfC,CAAC,CAAE,GA7BY,CA8BfC,CAAC,CAAE,GA9BY,CA+BfC,CAAC,CAAE,GA/BY,CAgCfC,CAAC,CAAE,QAhCY,CAiCfC,CAAC,CAAE,GAjCY,CAkCfC,CAAC,CAAE,MAlCY,CAmCfC,CAAC,CAAE,QAnCY,CAoCfC,CAAC,CAAE,QApCY,CAqCfC,CAAC,CAAE,GArCY,CAsCfC,CAAC,CAAE,GAtCY,CAuCfC,CAAC,CAAE,QAvCY,CAwCfC,CAAC,CAAE,QAxCY,CAyCfG,CAAC,CAAE,GAzCY,CA0CfC,CAAC,CAAE,QA1CY,CA2CfH,CAAC,CAAE,QA3CY,CA4CfC,CAAC,CAAE,QA5CY,CA6CfG,CAAC,CAAE,QA7CY,CA8CfC,CAAC,CAAE,GA9CY,CA+CfC,CAAC,CAAE,GA/CY,CAgDfC,CAAC,CAAE,GAhDY,CAiDfC,CAAC,CAAE,QAjDY,CAkDfC,CAAC,CAAE,QAlDY,CAmDfC,CAAC,CAAE,GAnDY,CAoDfC,CAAC,CAAE,GApDY,CAAjB,CAuDA,GAAME,CAAAA,UAAU,CAAG,CACjBC,QAAQ,CAAE,CACRC,MAAM,CAAE,EADA,CAERC,OAAO,CAAE,EAFD,CAGRC,GAAG,CAAE1D,YAHG,CAIR2D,QAAQ,CAAE,IAJF,CADO,CAOjBC,IAAI,CAAE,CAGJJ,MAAM,CAAE,QAHJ,CAIJC,OAAO,CAAE,QAJL,CAKJC,GAAG,CAAEL,QALD,CAMJM,QAAQ,CAAE,KANN,CAPW,CAAnB,CAiBO,GAAME,CAAAA,oBAAoB,CAAG,QAAvBA,CAAAA,oBAAuB,CAACC,MAAD,CAA4C,oEAAP,EAAO,oBAAjCC,QAAiC,CAAjCA,QAAiC,wBAAtB,UAAsB,eAC9E,GAAIC,CAAAA,IAAI,CAAGV,UAAU,CAACS,QAAD,CAArB,CAEA,GAAIE,CAAAA,mBAAmB,CAAG,EAA1B,CAH8E,gGAI9E,kBAAsBH,MAAtB,oHAA8B,IAArBI,CAAAA,SAAqB,aAC5B,GAAIF,IAAI,CAACN,GAAL,CAASQ,SAAT,CAAJ,CAAyB,CACvB,GAAMC,CAAAA,EAAE,CAAGD,SAAS,CAACE,WAAV,EAAX,CAEA,GACEJ,IAAI,CAACL,QAAL,GACCQ,EAAE,GAAK,GAAP,EAAcA,EAAE,GAAK,GAArB,EAA4BA,EAAE,GAAK,GAAnC,EAA0CA,EAAE,GAAK,GADlD,CADF,CAGE,CACAF,mBAAmB,EAAID,IAAI,CAACN,GAAL,CAASQ,SAAT,EAAsBF,IAAI,CAACN,GAAL,CAASQ,SAAT,CAC9C,CALD,IAKOD,CAAAA,mBAAmB,EAAID,IAAI,CAACN,GAAL,CAASQ,SAAT,CAC/B,CATD,IASOD,CAAAA,mBAAmB,EAAIC,SAC/B,CAf6E,kMAkB9E,GACED,mBAAmB,CAACI,UAApB,CAA+BL,IAAI,CAACR,MAApC,GACAS,mBAAmB,CAACK,QAApB,CAA6BN,IAAI,CAACP,OAAlC,CAFF,CAGE,CACA,MAAOQ,CAAAA,mBACR,CACD,MAAOD,CAAAA,IAAI,CAACR,MAAL,CAAcS,mBAAd,CAAoCD,IAAI,CAACP,OACjD,CAzBM,C","sourcesContent":["const ACCENTED_MAP = {\n a: 'ȧ',\n A: 'Ȧ',\n b: 'ƀ',\n B: 'Ɓ',\n c: 'ƈ',\n C: 'Ƈ',\n d: 'ḓ',\n D: 'Ḓ',\n e: 'ḗ',\n E: 'Ḗ',\n f: 'ƒ',\n F: 'Ƒ',\n g: 'ɠ',\n G: 'Ɠ',\n h: 'ħ',\n H: 'Ħ',\n i: 'ī',\n I: 'Ī',\n j: 'ĵ',\n J: 'Ĵ',\n k: 'ķ',\n K: 'Ķ',\n l: 'ŀ',\n L: 'Ŀ',\n m: 'ḿ',\n M: 'Ḿ',\n n: 'ƞ',\n N: 'Ƞ',\n o: 'ǿ',\n O: 'Ǿ',\n p: 'ƥ',\n P: 'Ƥ',\n q: 'ɋ',\n Q: 'Ɋ',\n r: 'ř',\n R: 'Ř',\n s: 'ş',\n S: 'Ş',\n t: 'ŧ',\n T: 'Ŧ',\n v: 'ṽ',\n V: 'Ṽ',\n u: 'ŭ',\n U: 'Ŭ',\n w: 'ẇ',\n W: 'Ẇ',\n x: 'ẋ',\n X: 'Ẋ',\n y: 'ẏ',\n Y: 'Ẏ',\n z: 'ẑ',\n Z: 'Ẑ',\n};\n\nconst BIDI_MAP = {\n a: 'ɐ',\n A: '∀',\n b: 'q',\n B: 'Ԑ',\n c: 'ɔ',\n C: 'Ↄ',\n d: 'p',\n D: 'ᗡ',\n e: 'ǝ',\n E: 'Ǝ',\n f: 'ɟ',\n F: 'Ⅎ',\n g: 'ƃ',\n G: '⅁',\n h: 'ɥ',\n H: 'H',\n i: 'ı',\n I: 'I',\n j: 'ɾ',\n J: 'ſ',\n k: 'ʞ',\n K: 'Ӽ',\n l: 'ʅ',\n L: '⅂',\n m: 'ɯ',\n M: 'W',\n n: 'u',\n N: 'N',\n o: 'o',\n O: 'O',\n p: 'd',\n P: 'Ԁ',\n q: 'b',\n Q: 'Ò',\n r: 'ɹ',\n R: 'ᴚ',\n s: 's',\n S: 'S',\n t: 'ʇ',\n T: '⊥',\n u: 'n',\n U: '∩',\n v: 'ʌ',\n V: 'Ʌ',\n w: 'ʍ',\n W: 'M',\n x: 'x',\n X: 'X',\n y: 'ʎ',\n Y: '⅄',\n z: 'z',\n Z: 'Z',\n};\n\nconst strategies = {\n accented: {\n prefix: '',\n postfix: '',\n map: ACCENTED_MAP,\n elongate: true,\n },\n bidi: {\n // Surround words with Unicode formatting marks forcing\n // right-to-left directionality of characters\n prefix: '\\u202e',\n postfix: '\\u202c',\n map: BIDI_MAP,\n elongate: false,\n },\n};\n\nexport const pseudoLocalizeString = (string, { strategy = 'accented' } = {}) => {\n let opts = strategies[strategy];\n\n let pseudoLocalizedText = '';\n for (let character of string) {\n if (opts.map[character]) {\n const cl = character.toLowerCase();\n // duplicate \"a\", \"e\", \"o\" and \"u\" to emulate ~30% longer text\n if (\n opts.elongate &&\n (cl === 'a' || cl === 'e' || cl === 'o' || cl === 'u')\n ) {\n pseudoLocalizedText += opts.map[character] + opts.map[character];\n } else pseudoLocalizedText += opts.map[character];\n } else pseudoLocalizedText += character;\n }\n\n // If this string is from the DOM, it should already contain the pre- and postfix\n if (\n pseudoLocalizedText.startsWith(opts.prefix) &&\n pseudoLocalizedText.endsWith(opts.postfix)\n ) {\n return pseudoLocalizedText;\n }\n return opts.prefix + pseudoLocalizedText + opts.postfix;\n};\n"],"file":"pseudoLocalizeString.js"}
|