Created
November 6, 2018 20:55
-
-
Save lightoze/04a115e4331f6cbee9e875d192a7cd46 to your computer and use it in GitHub Desktop.
Vaadin Polymer component i18n
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For the record: this code have a problem, details with problem description and possible solution here