Also, feel free to ignore the bit of insanity around virtual shadow roots.
That's just something I built because an older version of webcomponentjs
was severely borked, and I needed to... make my own virtual shadow DOM
implementation. I have allowed it to survive after upstream bug was fixed
because I also added V0-like behavior for slotting elements in shadow DOM
that was (wrongly, imho) replaced in V1 spec with ugly manual slotting.
To make a long story short, in V0, you can do this (note, #shadow-root is
not a real tag name, it's just there to say there is a shadow root with
elements in it):
<my-element>
<#shadow-root>
<content select="div.cls" />
</#shadow-root>
<div class="cls"> I am rendered in shadow root because I match
selector</div>
<div>I am not rendered because I do not match selector</div>
</my-element>
In V1, you have to do this:
<my-element>
<#shadow-root>
<slot name="myslot" />
</#shadow-root>
<div slot="myslot"> I am rendered in shadow root because my slot
attribute matches slot name</div>
<div slot="notfound">I am not rendered because I do not match slot</div>
<div>I am also not rendered</div>
</my-element>
In both cases, a content without a select attribute and a slot without a
name will render all unslotted elements, but even that gets... hairy with
the polyfill, when you are nesting components inside each other.
Anyway, once again: I would strongly recommend avoiding all use of shadow
root unless you really enjoy debugging bleeding edge bugs. :D
On Tuesday, October 17, 2017 at 7:48:25 PM UTC-7, James Nelson wrote:
>
> It is possible to create web components with "fake" ES2015 classes built
> out of raw javascript.
>
>
> https://github.com/WeTheInternet/xapi/blob/master/gwt/components/src/main/java/xapi/components/impl/WebComponentBuilder.java#L108
>
> Note that the library above depends on a custom fork of Gwt that is not
> being released until after 2.8.2 goes out, however, the code for assembling
> custom web components does not actually depend on any of the magic I've
> added to the Gwt compiler (official release will not be dependent on my
> fork; I hope to deprecate / upstream everything I've had to do to it over
> the years).
>
> I also intend to remove all the ugly jsni to make it compatible with j2cl
> / gwt3... But, that bit I've linked to is the secret sauce for assembling a
> correct "extension" of HTMLElement. In theory, you can define your custom
> element using a builder that attaches your lifecycle callbacks (created /
> attached / detached / attributeChanged), plus any extra methods / fields
> you want, and then the rest of your code can use a @JsType(isNative=true,
> name="MyCustomElement", namespace = JsPackage.GLOBAL) interface that
> defines how you want to access the custom element and/or cast directly to
> an Element. This work is very imperative and copy-pasta, so I've also
> created a nice DSL for defining custom elements using... an xml-like,
> json-like, css-like extension of the java language (totally optional
> though; you can still use the builder directly).
>
> The end goal (very near to completion) is that you can define your custom
> component with a bit of xml-like syntax, plugging in java methods wherever
> you please, and it will generate all the builder-y boilerplate and Element
> interface for you. It is likely that I can actually make it extend
> HTMLElement directly as a class, and just define trampoline methods in the
> builder to call into the java code, but I have not had time to explore this
> option yet.
>
> I have not "officially" released this library, but it will be making an
> official debut soon. You should be able to use it earlier, if you are
> interested in some beta testing :-) (message me @ [email protected] so
> I can add you to my beta testers label).
>
> The result is a custom element that has widget-like lifecycle callbacks
> (we are toying with the idea of actually making widget use something like
> this under the hood to survive in Gwt 3). The one *big* gotcha is how
> the createdCallback works. Per the web component spec, you may *not* write
> or *read* any elements attributes or children to a custom element in its
> constructor. I have worked up a... slightly scary "RunSoon"
> implementation which will ensure that the callback is fired as soon as
> possible after construction (but this can be hard, since setting innerHTML
> from plain javascript is an important part of interopability with JS/HTML).
> I won't go into many details here, but, in practice, this ugliness can be
> hidden behind some cleverly generated code (which will lazy-init either at
> your command, whenever attached, or at the end of the current javascript
> event loop).
>
> The very first iteration of these custom components actually took a js
> type interface, directly bound all default methods to the custom element
> definition (via code generator), and allowed you to use that interface in
> both java and javascript. It actually worked quite well, but,
> unfortunately, that was for V0 of web component spec, and the ES2015 class
> syntax requirement (and other, imho, design mistakes) made it untenable for
> V1 (current version of web components).
>
>
>
> To use web components with GWT, you do have to install a polyfill
> (webcomponentjs, with only a couple slight mods I had to make) for older
> browsers / browsers that do not have web components enabled by default.
> The fact GWT runs in an iframe makes instanceof fail spectacularly, so I
> had to change usage of it to typeofs.
>
>
> Shameless plug: Myself, Colin Alworth and Justin Hickman have started a
> company based on selling GWT support contracts called Vertispan. While I
> am happy to share open source code and some pointers with you for free at
> any time, if you are interested in hiring any expertise to help you
> directly, you should email my aforementioned work account. :-)
>
>
> Final note: Shadow DOM is completely optional, and you should likely avoid
> it unless you really need it (for encapsulation and css barriers mostly).
> It... gets a bit hinky especially with polyfills and sane event bubbling,
> so if you are new to web components, only move on to shadow DOM if you've
> tried something without it, and actually need it (for example, to isolate
> component internals, or to avoid re-rendering piles of layout logic when
> all you want is your server to send elements with semantic significance).
>
>
> On Friday, October 13, 2017 at 6:25:00 AM UTC-7, Thomas Broyer wrote:
>>
>> Web Components require using ES2015 class syntax, so you would need some
>> trickery make them work from GWT (see
>> https://github.com/webcomponents/custom-elements#es5-vs-es2015 or
>> https://github.com/webcomponents/webcomponentsjs#custom-elements-es5-adapterjs
>> )
>> At least this is the theory…
>>
>> On Friday, October 13, 2017 at 11:58:14 AM UTC+2, nikola wrote:
>>>
>>> Thanks for the link.. But I can't see what I was looking for..
>>>
>>> Can someone please create and register custom web component using only
>>> elemental 2. e.g that says "hello from shadow DOM!".
>>> Cause I'm not able to do it or find working example .. at least without
>>> losing whole week on it...
>>> Thanks in advance
>>>
>>> On Thursday, October 12, 2017 at 4:04:16 PM UTC+2, harshyadav wrote:
>>>>
>>>> You can try the GWT polymer (web components) wrapper:
>>>> https://github.com/manolo/gwt-polymer-elements
>>>>
>>>> Wither you can use built-in polymer components; or create your own
>>>> (just look at the source code)
>>>>
>>>> Also take a look at:
>>>> https://github.com/manolo/gwt-api-generator
>>>>
>>>> which auto generates GWT api for polymer elements, so no need to be out
>>>> of Java world for most cases.
>>>>
>>>>
>>>> On Thursday, October 12, 2017 at 7:08:05 AM UTC-4, nikola wrote:
>>>>>
>>>>> Ok, Thanks! I'll try with web components. As a java programer I'v been
>>>>> trying to avoid digging too much in javascript but it's inevitable it
>>>>> seems
>>>>> :)
>>>>>
>>>>> On Thursday, October 12, 2017 at 12:43:56 PM UTC+2, Thomas Broyer
>>>>> wrote:
>>>>>>
>>>>>> This is not how the DOM works I'm afraid. How would your proposed
>>>>>> code would translate to JS? (feel free to use ES2015 classes for clarity)
>>>>>> (btw, I really do think Web Components would solve your issues, as I
>>>>>> see them)
>>>>>>
>>>>>> On Thursday, October 12, 2017 at 12:21:11 PM UTC+2, nikola wrote:
>>>>>>>
>>>>>>>
>>>>>>> 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.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Thursday, October 12, 2017 at 10:48:05 AM UTC+2, Thomas Broyer
>>>>>>> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wednesday, October 11, 2017 at 4:12:14 PM UTC+2, nikola wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>
>>>>>>>> I'm really not clear about what you want to do, and what you
>>>>>>>> actually mean by "custom element".
>>>>>>>> Do you mean Web Components? In this case, they'd have to extend
>>>>>>>> HTMLElement and, at least with elemental2-dom 1.0.0-beta-1, set the
>>>>>>>> connectedCallback, attachedCalback, etc. Encapsulation is then
>>>>>>>> provided by
>>>>>>>> the shadow DOM.
>>>>>>>> Or do you mean "kind of widgets, that just happen to map one-to-one
>>>>>>>> with a DOM element and its subtree"? In this case, you're indeed
>>>>>>>> *wrapping*
>>>>>>>> an element, and that means you're going to have parallel hierarchies
>>>>>>>> or
>>>>>>>> such widgets/components on one hand, and DOM elements on the other
>>>>>>>> hand,
>>>>>>>> and will need to maintain both in sync (this is what GWT Widgets do,
>>>>>>>> and I
>>>>>>>> believe more or less how React works too).
>>>>>>>>
>>>>>>>
--
You received this message because you are subscribed to the Google Groups "GWT
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.