Skip to content

Commit

Permalink
4.0.0-pre.13 with Fix #75 Preprocess json-data to data property for i…
Browse files Browse the repository at this point in the history
…18n-format
  • Loading branch information
t2ym committed Mar 17, 2019
1 parent 154bbf4 commit 743d6d1
Show file tree
Hide file tree
Showing 13 changed files with 170 additions and 46 deletions.
1 change: 1 addition & 0 deletions demo/clock/clock.js
Expand Up @@ -291,6 +291,7 @@ class WorldClockContainer extends i18n(HTMLElement) {
(item, index) =>
/* no I18N for this template itself */html`<world-clock .timezone=${item}></world-clock>`)}
<i18n-format id="compound-format-text" class="text">
<!-- <json-data> is to be preprocessed as .data property -->
<json-data>{
"0": "No timezones",
"1": "Only 1 timezone for {2} is shown.",
Expand Down
2 changes: 1 addition & 1 deletion demo/clock/xliff/bundle.ja.xlf
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd">
<xliff version="1.0">
<file xml:space="default" source-language="en" target-language="ja" datatype="plaintext" original="messages" date="2019-03-15T04:56:54Z" product-name="messages">
<file xml:space="default" source-language="en" target-language="ja" datatype="plaintext" original="messages" date="2019-03-17T07:01:13Z" product-name="messages">
<header>
<tool tool-id="xliff-conv" tool-name="xliff-conv" tool-version="1.0.12"/>
</header>
Expand Down
40 changes: 34 additions & 6 deletions demo/gulpfile.js
Expand Up @@ -42,6 +42,9 @@ const mergeStream = require('merge-stream');
// Use i18n-core.js
const useI18nCoreJs = true;

// Proprocess to <i18n-format .data=${data}><json-data preprocessed>
const useI18nFormatDataProperty = true;

// Global object to store localizable attributes repository
var attributesRepository = {};

Expand Down Expand Up @@ -291,6 +294,7 @@ function traverseAst(ast, templates) {
"name": "_bind",
}];
let index;
let prefixNextString = '';
//console.log(`${name} stripped=${strippedTemplate} localizable-text=${localizableTextJSON}`);
while ((index = strippedTemplate.indexOf('{{')) >= 0) {
let preprocessedString;
Expand All @@ -301,6 +305,10 @@ function traverseAst(ast, templates) {
else {
preprocessedString = strippedTemplate.substring(0, index);
}
if (prefixNextString) {
preprocessedString = prefixNextString + preprocessedString;
prefixNextString = '';
}
strippedTemplate = strippedTemplate.substring(index);
index = strippedTemplate.indexOf('}}');
if (index < 0) {
Expand All @@ -309,10 +317,6 @@ function traverseAst(ast, templates) {
let part = strippedTemplate.substring(0, index + 2);
strippedTemplate = strippedTemplate.substring(index + 2);
let partMatch = part.match(/^{{parts[.]([0-9]*)}}$/);
strings.push({
"type": "Literal",
"value": preprocessedString,
});
if (partMatch) {
parts.push(ast.quasi.expressions[parseInt(partMatch[1]) + offset]);
}
Expand Down Expand Up @@ -349,7 +353,27 @@ function traverseAst(ast, templates) {
valueExpression += `["${tmpPart}"]`;
}
if (isJSON) {
valueExpression = `JSON.stringify(${valueExpression})`;
if (useI18nFormatDataProperty) {
/*
Before conversion:
<i18n-format lang="{{effectiveLang}}"> <!-- 0 or more whitespaces or comments --><json-data>{{serialize(text.target.0)}}</json-data>
After conversion (equivalent tagged template literal):
<i18n-format lang="${effectiveLang}" .data=${text['target']['0']}> <!-- 0 or more whitespaces or comments --><json-data preprocessed></json-data>
*/
let match = preprocessedString.match(/^(.*[^-]|)>([ \n\t]*|(<!--(.|[\n\t])*-->)?)*<json-data>$/);
if (match) {
let preGt = match[1];
let preJsonData = preprocessedString.substring(preGt.length, preprocessedString.length - '<json-data>'.length);
preprocessedString = `${preGt} .data=`;
prefixNextString = `${preJsonData}<json-data preprocessed>`;
}
else {
valueExpression = `JSON.stringify(${valueExpression})`;
}
}
else {
valueExpression = `JSON.stringify(${valueExpression})`;
}
}
}
valueExpressions.push(valueExpression);
Expand All @@ -372,10 +396,14 @@ function traverseAst(ast, templates) {
}
parts.push(valueExpressionAst);
}
strings.push({
"type": "Literal",
"value": preprocessedString,
});
}
strings.push({
"type": "Literal",
"value": strippedTemplate,
"value": prefixNextString + strippedTemplate,
});

let templateCode = ({
Expand Down
6 changes: 3 additions & 3 deletions demo/preprocess/clock.js
Expand Up @@ -255,8 +255,8 @@ class WorldClockContainer extends i18n(HTMLElement) {
'\n <style>\n :host {\n display: block;\n width: 100%;\n }\n world-clock {\n display: flow;\n max-width: 300px;\n }\n </style>\n <div>',
'</div>\n ',
'\n <i18n-format id="compound-format-text" class="text" lang="',
'">\n <json-data>',
'</json-data>\n <i18n-number offset="1" slot="1" lang="',
'" .data=',
'>\n <!-- <json-data> is preprocessed as .data property -->\n <json-data preprocessed></json-data>\n <i18n-number offset="1" slot="1" lang="',
'">',
'</i18n-number>\n <span slot="2">',
'</span>\n </i18n-format>\n '
Expand All @@ -265,7 +265,7 @@ class WorldClockContainer extends i18n(HTMLElement) {
text['div_1'],
repeat(this.timezones, item => item, (item, index) => html`<world-clock .timezone=${ item }></world-clock>`),
effectiveLang,
JSON.stringify(text['compound-format-text']['0']),
text['compound-format-text']['0'],
effectiveLang,
this.timezones.length,
'GMT' + (this.timezones[0] < 0 ? '' : '+') + this.timezones[0] / 60
Expand Down
1 change: 1 addition & 0 deletions demo/tmp/clock.html
Expand Up @@ -142,6 +142,7 @@
<div>{{text.div_1}}</div>
{{parts.0}}
<i18n-format id="compound-format-text" class="text" lang="{{effectiveLang}}">
<!-- <json-data> is preprocessed as .data property -->
<json-data>{{serialize(text.compound-format-text.0)}}</json-data>
<i18n-number offset="1" slot="1" lang="{{effectiveLang}}">{{parts.1}}</i18n-number>
<span slot="2">{{parts.2}}</span>
Expand Down
4 changes: 0 additions & 4 deletions demo/tmp/i18n-attr-repo.js
Expand Up @@ -212,10 +212,6 @@ Handle and judge JSON object attributes.
@element i18n-attr-repo
*/
export class I18nAttrRepo extends HTMLElement {
static get importMeta() {
return import.meta;
}

static get is() {
return 'i18n-attr-repo';
}
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -21,7 +21,7 @@
},
"homepage": "https://github.com/t2ym/i18n-element#readme",
"name": "i18n-element",
"version": "4.0.0-pre.12",
"version": "4.0.0-pre.13",
"main": "i18n.js",
"directories": {
"test": "test"
Expand Down Expand Up @@ -128,7 +128,7 @@
"type-detect": "1.0.0"
},
"dependencies": {
"i18n-behavior": "^4.0.0-pre.14",
"i18n-behavior": "^4.0.0-pre.15",
"lit-html": "^1.0.0",
"wc-putty": "^0.1.0"
}
Expand Down
86 changes: 78 additions & 8 deletions test/lit-gulpfile.js
Expand Up @@ -13,6 +13,7 @@ const vulcanize = require('gulp-vulcanize');
const debug = require('gulp-debug');
const replace = require('gulp-replace');
const uglify = require('gulp-uglify');
const htmlMinifier = require('html-minifier');
const runSequence = require('run-sequence');
const del = require('del');
const gutil = require('gulp-util');
Expand All @@ -38,6 +39,12 @@ const he = require('he');
//const logging = require('plylog');
const mergeStream = require('merge-stream');

// Use i18n-core.js
const useI18nCoreJs = true;

// Proprocess to <i18n-format .data=${data}><json-data preprocessed>
const useI18nFormatDataProperty = true;

// Global object to store localizable attributes repository
var attributesRepository = {};

Expand Down Expand Up @@ -111,6 +118,13 @@ const escodegenOptionsCompact = {
comment: false
};

const minifyHtmlTemplates = false;
const htmlMinifierOptions = {
// Same options as polymer build minify: true
collapseWhitespace: true,
removeComments: true,
};

function UncamelCase (name) {
return name
// insert a hyphen between lower & upper
Expand All @@ -137,6 +151,32 @@ function traverseAst(ast, templates) {
inClass = true;
}
break;
case 'ImportDeclaration':
if (templates._preprocess &&
useI18nCoreJs &&
ast.source &&
ast.source.type === 'Literal' &&
typeof ast.source.value === 'string') {
let match = ast.source.value.match(/^(.*\/)?(i18n-element|i18n-element\/i18n[.]js|[.][.]\/[.][.]\/[.][.]\/i18n[.]js)$/);
if (match) {
let orig = ast.source.value;
if (match[1]) {
if (match[2].indexOf('i18n-element') === 0) {
ast.source.value = `${match[1]}i18n-element/i18n-core.js`;
}
}
else {
if (match[2].indexOf('i18n-element') === 0) {
ast.source.value = 'i18n-element/i18n-core.js';
}
else {
ast.source.value = '../../../i18n-core.js';
}
}
console.log(`ImportDeclaration: "${orig}" converted to "${ast.source.value}"`);
}
}
break;
case 'TaggedTemplateExpression':
{
let tag;
Expand Down Expand Up @@ -237,9 +277,14 @@ function traverseAst(ast, templates) {
let indexOfLocalizableText = preprocessedTemplate.indexOf(localizableTextPrefix);
let indexOfLocalizableTextPostfix = preprocessedTemplate.indexOf(localizableTextPostfix, indexOfLocalizableText);
let localizableTextJSON = preprocessedTemplate.substring(indexOfLocalizableText + localizableTextPrefix.length, indexOfLocalizableTextPostfix);
localizableTextJSON = localizableTextJSON.replace(/&quot;/g, '\\"').replace(/&#34;/g, '\\"');
localizableTextJSON = he.decode(localizableTextJSON);
localizableTextJSON = JSON.stringify(JSON.parse(localizableTextJSON), ((key, value) => typeof value === 'string' ? he.decode(value) : value), 2)
let strippedTemplate = preprocessedTemplate.substring(0, indexOfLocalizableText);
if (minifyHtmlTemplates) {
//console.log(`${name}: original ${strippedTemplate}`);
strippedTemplate = htmlMinifier.minify(strippedTemplate, htmlMinifierOptions);
//console.log(`${name}: minified ${strippedTemplate}`);
}

let strings = [{
"type": "Literal",
"value": "<!-- localizable -->",
Expand All @@ -249,6 +294,7 @@ function traverseAst(ast, templates) {
"name": "_bind",
}];
let index;
let prefixNextString = '';
//console.log(`${name} stripped=${strippedTemplate} localizable-text=${localizableTextJSON}`);
while ((index = strippedTemplate.indexOf('{{')) >= 0) {
let preprocessedString;
Expand All @@ -259,6 +305,10 @@ function traverseAst(ast, templates) {
else {
preprocessedString = strippedTemplate.substring(0, index);
}
if (prefixNextString) {
preprocessedString = prefixNextString + preprocessedString;
prefixNextString = '';
}
strippedTemplate = strippedTemplate.substring(index);
index = strippedTemplate.indexOf('}}');
if (index < 0) {
Expand All @@ -267,10 +317,6 @@ function traverseAst(ast, templates) {
let part = strippedTemplate.substring(0, index + 2);
strippedTemplate = strippedTemplate.substring(index + 2);
let partMatch = part.match(/^{{parts[.]([0-9]*)}}$/);
strings.push({
"type": "Literal",
"value": preprocessedString,
});
if (partMatch) {
parts.push(ast.quasi.expressions[parseInt(partMatch[1]) + offset]);
}
Expand Down Expand Up @@ -307,7 +353,27 @@ function traverseAst(ast, templates) {
valueExpression += `["${tmpPart}"]`;
}
if (isJSON) {
valueExpression = `JSON.stringify(${valueExpression})`;
if (useI18nFormatDataProperty) {
/*
Before conversion:
<i18n-format lang="{{effectiveLang}}"> <!-- 0 or more whitespaces or comments --><json-data>{{serialize(text.target.0)}}</json-data>
After conversion (equivalent tagged template literal):
<i18n-format lang="${effectiveLang}" .data=${text['target']['0']}> <!-- 0 or more whitespaces or comments --><json-data preprocessed></json-data>
*/
let match = preprocessedString.match(/^(.*[^-]|)>([ \n\t]*|(<!--(.|[\n\t])*-->)?)*<json-data>$/);
if (match) {
let preGt = match[1];
let preJsonData = preprocessedString.substring(preGt.length, preprocessedString.length - '<json-data>'.length);
preprocessedString = `${preGt} .data=`;
prefixNextString = `${preJsonData}<json-data preprocessed>`;
}
else {
valueExpression = `JSON.stringify(${valueExpression})`;
}
}
else {
valueExpression = `JSON.stringify(${valueExpression})`;
}
}
}
valueExpressions.push(valueExpression);
Expand All @@ -330,10 +396,14 @@ function traverseAst(ast, templates) {
}
parts.push(valueExpressionAst);
}
strings.push({
"type": "Literal",
"value": preprocessedString,
});
}
strings.push({
"type": "Literal",
"value": strippedTemplate,
"value": prefixNextString + strippedTemplate,
});

let templateCode = ({
Expand Down

0 comments on commit 743d6d1

Please sign in to comment.