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.

Reply via email to