CSS Resources are not set in Panels in an iframe

167 views
Skip to first unread message

confile

unread,
Jan 4, 2016, 2:31:56 PM1/4/16
to GWT Contributors
I want to insert GWT Widgets like FlowPanel, HTMLPanel inside and iframe using GWT. I find out how to insert GWT Widgets and Panels programmatically into GWT. Here is how I do it:


  public interface Resources extends ClientBundle {

    @Source({Css.DEFAULT_CSS})
    Css css();

  }

  public interface Css extends CssResource {

    String DEFAULT_CSS = "test/client/app/start/StartView.gss";

    String outerBox();
    String iframe();
    String test();

  }

  @UiField(provided = true)
  Resources resources;

  @UiField(provided = true)
  Messages messages;

  @Inject
  public StartView(final Binder binder, Resources resources, Messages messages)    
  {
    this.resources = resources;
    resources.css().ensureInjected();
    this.messages = messages;
    initWidget(binder.createAndBindUi(this));

    final IFrameElement iframe = Document.get().createIFrameElement();
    FlowPanel innerBox = new FlowPanel() {
       @Override
       protected void onLoad() {
         super.onLoad();

         FlowPanel p1 = new FlowPanel();
         p1.addStyleName(resources.css().test());

         HTMLPanel panel = new HTMLPanel("Hello World!");
         panel.setStyleName(resources.css().test());  // does not work
         p1.add(panel);

         final Document doc = iframe.getContentDocument();
         BodyElement body = doc.getBody();

         body.appendChild(p1.getElement());
         panel.setStyleName(resources.css().test());  // does not work
         p1.getElement().addClassName(resources.css().test()); // does not work

       }
    };
  }

The former code inserts GWT Panels into an iframe. The problem is that I cannot set any css style. Even if I set the style with:

panel.setStyleName(resources.css().test());  // does not work
p1.getElement().addClassName(resources.css().test()); // does not work

both variants do not work. I know I can inject a general css file in the head of the iframe document, but I want to use the GWT resources.

How can I set the styles using CSS/GSS Resources for the Panels inside the iframe?

Grzegorz Nowak

unread,
Jan 5, 2016, 4:03:01 AM1/5/16
to GWT Contributors
According to this 'ensureInjected' uses StyleInjector.injectStylesheet(String) to inject the text of the style into head of $doc. You would have to manually inject it (Use CssResource.getText()) into your iframe's head to be able to use it. Unfortunately StyleInjector does not permit to specify the document to which the style should be injected in similar manner ScriptInjector does, so you will have to implement it yourself based on both ScriptInjector and StyleInjector. After successful injection you can assign styles to elements from Css/Gss resources.

Thomas Broyer

unread,
Jan 5, 2016, 4:16:39 AM1/5/16
to GWT Contributors


On Monday, January 4, 2016 at 8:31:56 PM UTC+1, confile wrote:
I want to insert GWT Widgets like FlowPanel, HTMLPanel inside and iframe using GWT.

TL;DR: you can't.
When doing this, you're neutralizing event handling on the widgets, making many of them unusable.

What you need to do is either:
  • load a GWT app into the iframe and communicate with it to make it build the UI you're expecting
  • or only "inject" elements into the frame, not widgets.
But one has to wonder why you want to use an iframe to begin with…

 

         panel.setStyleName(resources.css().test());  // does not work
         p1.getElement().addClassName(resources.css().test()); // does not work

       }
    };
  }

The former code inserts GWT Panels into an iframe. The problem is that I cannot set any css style. Even if I set the style with:

panel.setStyleName(resources.css().test());  // does not work
p1.getElement().addClassName(resources.css().test()); // does not work

both variants do not work. I know I can inject a general css file in the head of the iframe document, but I want to use the GWT resources.

How can I set the styles using CSS/GSS Resources for the Panels inside the iframe?

As Grzegorz Nowak said, you need to inject your stylesheet into the iframe first; it's as easy as creating a <style> element and setting its content to resources.css().getText() (which is basically what ensureInjected() does in $doc / Document.get()) 

confile

unread,
Jan 5, 2016, 10:47:07 AM1/5/16
to GWT Contributors
Hi Thomas, 

the reason why I want to use an iframe is the following. I want to create a JavaScript widget which is integrated into another third party page. Have a look at this: https://www.livechatinc.com/ They have a chat widget which has the following structure: 

<div class="some-outer-div-stype">
  <iframe>
   // widget content
  </iframe>
</div>

I guess they use the iframe such that the page containing the widget does not change the css or html tree of the widget. 

Do you see how such a technique can be used with GWT?

Thomas Broyer

unread,
Jan 5, 2016, 12:40:28 PM1/5/16
to GWT Contributors
Ideally, probably use a custom linker that makes it so that $wnd and $doc point to an iframe created during "bootstrap" of the app.
Or as I said before, don't use widgets.

confile

unread,
Jan 5, 2016, 12:42:19 PM1/5/16
to GWT Contributors
Do you have an example for a custom linker?

confile

unread,
Jan 8, 2016, 12:35:51 PM1/8/16
to GWT Contributors
Here is what I want to do with GWT. https://perishablepress.com/embed-external-content-via-iframe-and-div/

Any idea how to do that?


Am Dienstag, 5. Januar 2016 18:40:28 UTC+1 schrieb Thomas Broyer:

confile

unread,
Jan 8, 2016, 12:44:08 PM1/8/16
to GWT Contributors
I could extend the CrossSiteIframeLinker and change: 

L413:   out.print("var $wnd = $wnd || window.parent;"); 

to 

 out.print("var $wnd = $wnd ||  document.getElementById("myiframe");");


But what do you mean by "an iframe created during "bootstrap"? Where do I create the iframe?




Am Dienstag, 5. Januar 2016 18:40:28 UTC+1 schrieb Thomas Broyer:

Colin Alworth

unread,
Jan 8, 2016, 2:28:50 PM1/8/16
to GWT Contributors
As long as both $wnd and $doc exist in the frame where you plan on creating/rendering widgets, it shouldn't matter how you create or find the iframe. This should only mean that your frame must be created when that line of bootstrap code executes, either because you created it there, or because you found it.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/2bf5cdc5-9108-45ac-911b-44995474f518%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

confile

unread,
Jan 8, 2016, 4:34:09 PM1/8/16
to GWT Contributors
@Colin, I did not get your point how would you generate a GWT app inside: 

<div>
   <iframe>
     // GWT app
  </iframe>
</div>


Am Freitag, 8. Januar 2016 20:28:50 UTC+1 schrieb Colin Alworth:
As long as both $wnd and $doc exist in the frame where you plan on creating/rendering widgets, it shouldn't matter how you create or find the iframe. This should only mean that your frame must be created when that line of bootstrap code executes, either because you created it there, or because you found it.

On Fri, Jan 8, 2016 at 11:44 AM confile <michael....@googlemail.com> wrote:
I could extend the CrossSiteIframeLinker and change: 

L413:   out.print("var $wnd = $wnd || window.parent;"); 

to 

 out.print("var $wnd = $wnd ||  document.getElementById("myiframe");");


But what do you mean by "an iframe created during "bootstrap"? Where do I create the iframe?




Am Dienstag, 5. Januar 2016 18:40:28 UTC+1 schrieb Thomas Broyer:
Ideally, probably use a custom linker that makes it so that $wnd and $doc point to an iframe created during "bootstrap" of the app.
Or as I said before, don't use widgets.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages