Skip to content

Instantly share code, notes, and snippets.

@lightoze
Created November 6, 2018 20:55
Show Gist options
  • Save lightoze/04a115e4331f6cbee9e875d192a7cd46 to your computer and use it in GitHub Desktop.
Save lightoze/04a115e4331f6cbee9e875d192a7cd46 to your computer and use it in GitHub Desktop.
Vaadin Polymer component i18n
import com.vaadin.flow.component.Component;
import com.vaadin.flow.dom.DisabledUpdateMode;
import elemental.json.Json;
import elemental.json.JsonArray;
import elemental.json.JsonObject;
import elemental.json.JsonValue;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public class I18nBinding {
private final Component component;
private boolean loaded = false;
public static I18nBinding create(Component component) {
return new I18nBinding(component);
}
private I18nBinding(Component component) {
this.component = component;
init();
}
private void init() {
component.getElement().addEventListener("translation-requested", event -> {
JsonArray keys = event.getEventData().getArray("event.detail.keys");
List<String> list = new ArrayList<>(keys.length());
for (int i = 0; i < keys.length(); i++) {
list.add(keys.getString(i));
}
load(list);
}).addEventData("event.detail.keys").setDisabledUpdateMode(DisabledUpdateMode.ALWAYS);
component.addAttachListener(event -> {
if (event.isInitialAttach()) {
event.getUI().beforeClientResponse(component, context -> initialLoad());
} else if (loaded) {
reload();
}
});
}
private void initialLoad() {
loaded = true;
Set<String> keys = I18nModelCache.getTranslationKeys(component.getClass());
load(keys);
}
private void load(Collection<String> keys) {
if (keys.isEmpty()) {
return;
}
I18nModelCache.notifyKeys(component.getClass(), keys);
JsonObject translation = Json.createObject();
{
Serializable existing = component.getElement().getPropertyRaw("translation");
if (existing instanceof JsonObject) {
for (String key : ((JsonObject) existing).keys()) {
translation.put(key, ((JsonObject) existing).<JsonValue>get(key));
}
}
}
for (String key : keys) {
translation.put(key, component.getTranslation(key));
}
component.getElement().setPropertyJson("translation", translation);
}
public void reload() {
Serializable existing = component.getElement().getPropertyRaw("translation");
if (existing instanceof JsonObject) {
JsonObject translation = Json.createObject();
for (String key : ((JsonObject) existing).keys()) {
translation.put(key, component.getTranslation(key));
}
component.getElement().setPropertyJson("translation", translation);
}
}
}
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
class I18nModelCache {
private static Map<Class<?>, Set<String>> cache = Collections.synchronizedMap(new WeakHashMap<>());
private I18nModelCache() {
}
static Set<String> getTranslationKeys(Class<?> type) {
return cache.getOrDefault(type, Collections.emptySet());
}
static void notifyKeys(Class<?> type, Collection<String> keys) {
Set<String> set = cache.computeIfAbsent(type, key -> ConcurrentHashMap.newKeySet());
set.addAll(keys);
}
}
<script>
/**
* @namespace Vaadin
*/
window.Vaadin = window.Vaadin || {};
Vaadin.TranslateMixin = subclass => class TranslateMixinElement extends subclass {
static get properties() {
return {
translation: {
type: Object,
value: () => {
return {};
}
},
translate: {
type: Function,
computed: '_createTranslator(translation)'
},
_requested: {
type: Array,
value: () => {
return [];
}
},
_requestedSent: {
type: Number,
value: 0
}
}
}
connectedCallback() {
super.connectedCallback();
this._requestTranslationEvent();
}
_createTranslator(translation) {
return key => {
let value = translation[key];
if (value) {
return value;
} else {
this._requestTranslation(key);
return key;
}
};
}
_requestTranslation(key) {
if (this._requested.indexOf(key) < 0) {
this._requested.push(key);
setTimeout(() => this._requestTranslationEvent());
}
}
_requestTranslationEvent() {
if (this._requestedSent < this._requested.length) {
let keys = this._requested.slice(this._requestedSent, this._requested.length);
this._requestedSent = this._requested.length;
this.dispatchEvent(new CustomEvent('translation-requested', {detail: {keys: keys}}));
}
}
};
</script>
@greenhost87
Copy link

For the record: this code have a problem, details with problem description and possible solution here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment