Users would expect to have events with source from where event was fired. That was source field in GWT events. In your implementation we will need to intercept DOM event and fire new event with source field of custom element. (e.g re-fire through EventHandler). This is kind of double work.
Another thing that we need to care about is if add and then remove some custom element from DOM like element.removeChild(customElement.asElement()) we also need to remove reference to custom element to be garbage collected? Since only asElement() is removed from DOM not custom element object itself. If I'm right...
This is why it would be good if custom element can extends Element and wrap inner element like Widget Composite.
When I say "custom element" I mean:
public class CustomElement implements IsElement {
// private HandlerManager handlerManager; ?
List<String> someUserObject; //state object of CustomElement
HTMLElement root = Js.cast(DomGlobal.document.createElement("div"));
@Override
public HTMLElement asElement() {
return root;
}
public static void test() {
CustomElement customElement = new CustomElement();
customElement.asElement().addEventListener("click", evt -> {
//evt.target is not CustomElement so we can't access e.g someUserObject
//We can map DOM events to custom events fired through HandlerManager with source field set to CustomElement (double work.. )
});
}
//
}
Also when working with custom elements constructed as above we need some discipline to remove objects both logically and from DOM (as you said we need to keep them in sync)..
We are coming to something that looks like a Panel
class Panel implements IsElement {
List<IsElement> componentList;
HTMLElement root;
@Override
public HTMLElement asElement() {
return root;
}
public void add(IsElement component) {
// add to componentList
// add to DOM
}
public void remove(IsElement component) {
//remove from componentList
//remove from DOM
}
}
So it would be good to have something like this :
public abstract class CustomElementComposite extends HTMLElement implements IsElement {
List<String> someUserObject;
protected void initComposite(HTMLElement element) {
//If we could encapsulate element to become actually CustomElementComposite like Widget Composite
}
@Override
public HTMLElement asElement() {
return this;
}
public static void test() {
CustomElementComposite element = new CustomElementComposite() {};
element.addEventListener("click", evt -> {
// evt.target is CustomElementComposite
});
// we don't need any additional mapping for adding and removing
HTMLElement parent = Js.cast(DomGlobal.document.createElement("div"));
parent.appendChild(element);
parent.removeChild(element);
}
}
This way we are adding events directly and there is no additional synchronization with DOM when adding and removing components.
I must inspect but I'm not sure if Web Component can solve this (in the way widget's composite did).. I'd rather have web component as a option.