PDA

View Full Version : Conditional CSS in XTemplate



Olaus
3 Feb 2012, 1:40 PM
In an XTemplate I have a boolean that determince if a css name should be present in a div or not.
But I get the following error message

[ERROR] [gxt3test] - SafeHtml used in a non-text context. Did you mean to use java.lang.String or SafeStyles instead?

Java:


public class TemplTest { public interface Renderer extends XTemplates {
@XTemplate(source = "template.html")
public SafeHtml render(boolean css,Style style);
}

interface Resources extends ClientBundle {
@Source("Test.css")
Style css();
}
interface Style extends CssResource {
String test();
}

@SuppressWarnings("unused")
public TemplTest() {
Renderer renderer = GWT.create(Renderer.class);
final Resources resources = GWT.create(Resources.class);
resources.css().ensureInjected();
Style style = resources.css();
SafeHtml html = renderer.render(true,style);
}
}


template.html


<div class='<tpl if='css'>{style.test}</tpl>'></div>

Test.css


.test {
position: relative;
}

twisted_pear
2 May 2012, 5:51 AM
I was having this issue with GWT this morning. Here is the deal:


"<div style=\"{0}\" class=\"{2}\"><label debugId=\"{3}\">{1}</label></div>"

* {0} is a style, so must be a SafeStyles type
* {1} is the content of an HTML element, so must be SafeHtml type
* {2} is the a class name, not HTML or a style, so must be String type
* {3} is the a non-standard attribute, not HTML or a style, so must be String? type

Your error is being caused by the 2/3 cases. It is not documented well but should fix your issue.

Seems odd to me, since you could do an injection attack here like {2}=' " /><evilHtml/><div ' Not sure why the don't let you escape the classnames.


Sincerely,
Joe

Colin Alworth
2 May 2012, 6:26 AM
Olaus: This is one part a limitation with XTemplates, stemming from the fact that we build on GWT's SafeHtmlTemplates, and one part 'not valid xml' - you can't put a template tag within the body of another tag.

Instead, a few other options:
* Make the String parameter to your template optionally blank to leave out the class name
* Make two divs, each with its own <tpl> parent, one for the positive case, one for the negative.
* (not always possible) Add the css class after the template has rendered.



twisted_pear: I think you'll find that won't actually work - If it is a String being inserted, GWT will make the necessary changes to prevent this from escaping the attribute.

Along these same lines, I don't believe it will allow SafeHtml to be inserted within the tag body of another tag, only between two existing tags. Additionally, if there is a SafeHtml object with the contents

" /><evilHtml/><div
then your app has escaped something that shouldn't be escaped, or GWT's SafeHtml tools have a major bug in them.