New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-i18nliner

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-i18nliner - npm Package Compare versions

Comparing version 0.0.6 to 0.0.7

20

__tests__/preprocess.test.js

@@ -43,2 +43,7 @@ jest.autoMockOff();

it('doesn\'t merge leading or trailing standalone elements with keys', function() {
expect(subject('<div translate="yes"><input key="user_1" /> versus <input key="user_2" /></div>'))
.toEqual('<div><I18n.ComponentInterpolator string={I18n.t("%{user_1} versus %{user_2}", { "user_1": "%{user_1}", "user_2": "%{user_2}" })} user_1={<input key="user_1" />} user_2={<input key="user_2" />}>$1</I18n.ComponentInterpolator></div>');
});
it('absorbs wrappers into placeholders if there is no other content', function() {

@@ -49,2 +54,7 @@ expect(subject('<div translate="yes">hello <b>{user}</b></div>'))

it('users the outermost key when absorbing wrappers into placeholders with no text content', function() {
expect(subject('<div translate="yes">hello <b key="name">{user.name}</b></div>'))
.toEqual('<div><I18n.ComponentInterpolator string={I18n.t("hello %{name}", { "name": "%{name}" })} name={<b key="name">{user.name}</b>}>$1</I18n.ComponentInterpolator></div>');
});
it('creates placeholders for expressions', function() {

@@ -60,2 +70,12 @@ expect(subject('<div translate="yes">hello {this.props.userName}</div>'))

it('uses the empty components\'s key as the placeholder name', function() {
expect(subject('<div translate="yes">Create <input key="numAccounts" /> new accounts</div>'))
.toEqual('<div><I18n.ComponentInterpolator string={I18n.t("Create %{num_accounts} new accounts", { "num_accounts": "%{num_accounts}" })} num_accounts={<input key="numAccounts" />}>$1</I18n.ComponentInterpolator></div>');
});
it('doesn\'t use the empty components\'s key as the placeholder name if it\'s not a literal', function() {
expect(subject('<div translate="yes">Create <input key={something} /> new accounts</div>'))
.toEqual('<div><I18n.ComponentInterpolator string={I18n.t("Create %{input_key_something} new accounts", { "input_key_something": "%{input_key_something}" })} input_key_something={<input key={something} />}>$1</I18n.ComponentInterpolator></div>');
});
it('creates placeholders for translate="no" components', function() {

@@ -62,0 +82,0 @@ expect(subject('<div translate="yes">to create an alert, type <code translate="no">alert()</code></div>'))

2

package.json
{
"name": "react-i18nliner",
"version": "0.0.6",
"version": "0.0.7",
"description": "i18n made simple",

@@ -5,0 +5,0 @@ "main": "main.js",

@@ -86,10 +86,13 @@ var recast = require('recast');

if (node.type !== "JSXElement") return;
var attributes = node.openingElement.attributes;
var index = findAttributeIndex(attribute, attributes);
var value;
if (index >= 0) {
value = attributes[index].value.value;
if (shouldSpliceFn && shouldSpliceFn(value)) {
attributes.splice(index, 1);
}
if (index < 0) return;
var value = attributes[index].value;
if (attributes[index].value.type !== "Literal") return;
value = value.value;
if (shouldSpliceFn && shouldSpliceFn(value)) {
attributes.splice(index, 1);
}

@@ -99,3 +102,4 @@ return value;

var extractTranslateAttribute = findAttribute.bind(null, "translate");
var findTranslateAttribute = findAttribute.bind(null, "translate");
var findKeyAttribute = findAttribute.bind(null, "key");

@@ -131,3 +135,3 @@

var tagName = node.openingElement && node.openingElement.name.name;
var translateAttr = extractTranslateAttribute(node, shouldSpliceTranslateAttr);
var translateAttr = findTranslateAttribute(node, shouldSpliceTranslateAttr);
if (translateAttr) {

@@ -247,12 +251,21 @@ return translateAttr === "yes";

var placeholderBaseFor = function(node) {
var source = recast.print(node).code;
var baseString = source.replace(/<\/[^>]+>/g, '')
.replace(/([A-Z]+)?([A-Z])/g, '$1 $2')
.replace(/this\.((state|props)\.)/g, '');
if (node.type === "JSXExpressionContainer")
node = node.expression;
if (hasNonJSXDescendants(node)) {
baseString = baseString.replace(/<\w+[^>]*>/, '');
var baseString;
if (node.type === "JSXElement")
baseString = findKeyAttribute(node);
if (!baseString) {
var source = recast.print(node).code;
baseString = source.replace(/<\/[^>]+>/g, '')
.replace(/this\.((state|props)\.)/g, '');
if (hasNonJSXDescendants(node)) {
baseString = baseString.replace(/<\w+[^>]*>/, '');
}
}
return baseString.toLowerCase()
return baseString.replace(/([A-Z]+)?([A-Z])/g, '$1 $2')
.toLowerCase()
.replace(/[^a-z0-9]/g, ' ')

@@ -284,3 +297,3 @@ .trim()

part = wrappedStringFor(child, wrappers, placeholders);
} else if (findNestedJSXExpressions(child).length === 1 || !translatable) {
} else if (findNestedJSXExpressions(child).length === 1 || !translatable || findKeyAttribute(child)) {
part = placeholderStringFor(child, placeholders);

@@ -287,0 +300,0 @@ } else {

@@ -22,7 +22,10 @@ # react-i18nliner

`translate="yes"` attribute on any element/component that needs to be
localized.
localized. Seriously.
Best of all, you don't need to maintain translation files anymore;
I18nliner will do it for you.
And because the default translation is inline, it will be used as a
fallback if a translation is missing or hasn't happened yet.
Best of all, you don't need to maintain separate translation files
anymore; I18nliner will do it for you.
## How does it work?

@@ -65,7 +68,24 @@

By default, placeholder keys will be inferred from the content, so a
translator would see `"Create %{input} keys"` and `"Welcome back,
%{user_name}"`. For complicated expressions, these placeholder keys can
get a bit long/gnarly. Having to retranslate strings that "changed" just
because you refactored some code is terrible, so you can use keys to
be a bit more explicit:
```html
<label translate="yes">
Create <input key="numAccounts" onChange={this.addAccounts} /> new
accounts
</label>
```
In this case the extracted string would just be `"Create %{num_accounts}
new accounts"`
### Wrappers
Translators won't see any markup; it will be replaced with a simple wrapper
notation. In this example, the extracted string would be `"That is *not*
the right answer"`:
Translators won't see any components or markup; they will be replaced with
a simple wrapper notation. In this example, the extracted string would be
`"That is *not* the right answer"`:

@@ -82,3 +102,4 @@ ```html

`Your Account"` will also be preprocessed, since it is a valid
[translatable attribute](http://www.w3.org/TR/html5/dom.html#the-translate-attribute).
[translatable attribute](http://www.w3.org/TR/html5/dom.html#the-translate-attribute)
within a translated element.

@@ -91,3 +112,2 @@ ```html

## Installation

@@ -94,0 +114,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc