[ERROR] Only either css files or gss files are supported on one interface

176 views
Skip to first unread message

Ed

unread,
Mar 3, 2015, 3:01:11 PM3/3/15
to google-we...@googlegroups.com
Why does GSS throw the following error when combining CSS and GSS files? (latest GWT 2.7 version)
---
        [ERROR] Only either css files or gss files are supported on one interface 
---

Why isn't it allowed to combine them ?
Combining it makes it much more friendly/easy to switch to GSS.
In my case it's a blocker to move to GSS. In my general components, that have their own resource bundle, I use adapter/empty css files that only contains the class names without any css rules. They are very handy to use and overcomes to having to add all class names to a css file.
They are empty so I don't see any problem that GSS can't process them.
Currently it's impossible to rename all the css files in general components to gss.

How to solve this ? Can't GSS not process CSS files as welll?
    

Jens

unread,
Mar 3, 2015, 4:32:16 PM3/3/15
to google-we...@googlegroups.com
If you have a mixture of *.css and *.gss files referenced in @Source then you can not convert the css files one by one because a css file might not contain @def rules if they are defined in a different file. As you must also honor css rule ordering the only right thing to do is to merge all these referenced files in the same order they are referenced in the @Source annotation and then convert it.

However when doing so the in-memory css2gss converter would get a mixture of gss and css syntax as input but it only understands normal css as input (it builds a AST from the input and recognizes CssResource features during parsing). So at the end the converter requires pure css input. It does not understand any gss features.

I would create a branch, run the Css2Gss class to convert all css files to gss and then start updating @Source annotations and/or String constants pointing to old css files.

-- J.

Ed Bras

unread,
Mar 3, 2015, 4:58:04 PM3/3/15
to google-we...@googlegroups.com
I am very sorry Jens, but don't really understand your explanation.
Why can't the css file be used as gss file? 
If I look at the examples of gss files, they can contain standard css content.

Jens

unread,
Mar 3, 2015, 7:11:53 PM3/3/15
to google-we...@googlegroups.com
Ok put differently:

When you enable GSS then GWT will use the GssResourceGenerator which accepts valid GSS and hands it over to the closure stylesheets backend to produce the final css output. Your css files could contain CssResource specific extensions like @def, conditionals, sprites, etc. and most of them work a bit differently in GSS. GWT can not assume your css file is a valid gss file, thus the css file must run through the css2gss converter before it will be handed over to the closure stylesheets backend.

-- J.

Ed Bras

unread,
Mar 4, 2015, 3:42:51 AM3/4/15
to google-we...@googlegroups.com
Thanks @Jens, I understand what you mean.
However, I still not see a could reason to force the gss file extension. I think we can assume that the developer knows what he is doing and it's his responsibility to feed the gss engine with the correct files, giving him the freedom to use any extension he wants.

I understand that it's a nice separation, and it's how other css generation tools work.
But Gwt is a bit different and does more then just css generation, so in this case it has some blocking disadvantages.
Advantages of allowing the css extension: shared code use, merging to gss step by step.

Let me explain it through my use case:
I have a gwt code base that exists of many widget having their own resource bundle and css files (empty mostly, following to the adapter pattern). 
New projects want to use css3 features, as such need the gss mechanism. However, these shared resource bundles can't be changed, as it results in breaking other projects using them. Neither do I want to change them as mostly they concern empty css files that aren't gss dependent, which they would look like it if they have the gss extension.

To solve this I see 2 options: duplicating the shared css files and giving them the gss extension -> a lot of work, messy maintainable code.
Patching the gwt gss engine to allow for css files with the css extension.
I think I go for the last option as it seems an easy one looking at the gss code.

I would suggest to allow for the css extension. Optional with a console warning that can be suppressed (like done in other parts of the gwt code).

I understand that the css files might contain some gwt syntax like @def that might result in unwanted results when processed by gss. But isn't that the same as letting Spring eat some hibernate syntax that it understands and results in strange outcome.... It's the responsibility of the developer to overcome that.... So give him that freedom....

What do you think?
Just my 50 cents.


Jens

unread,
Mar 4, 2015, 11:18:47 AM3/4/15
to google-we...@googlegroups.com
What you are asking for is simply not possible in a reliable way under the requirement that old css syntax needs to be converted to gss syntax to avoid producing compile errors when activating GSS for a project.

When I give you (which is hopefully similar to your use case):

@Source({ app-constants.gss, library-constants.css, library-mywidget.css, app-mywidget.gss })

Then what should GWT do to produce valid GSS code that can be handed over to closure stylesheets? 

- The ordering of files is important as later files can override CSS rules in previous files (e.g. library-mywidget could produce a red widget by default and app-mywidget overrides it to a blue gradient)
- Any css file might be compatible with GSS as-is but maybe it is not. If you can not use the file extension to decide it you need to try parsing a css file using a GSS parser. If it fails it is incompatible and would need to be converted using the css2gss in-memory converter.
- app-mywidget.gss might reuse constants provided by library-constants.css as well use constants from app-constants.gss.


So what would you do now?

1.) You can not try parsing each file one-by-one to figure out if it is GSS compatible because each file might use constants provided by other files. If the parser does not see the constant definition it would fail even though the file might be GSS compatible. The parser needs complete knowledge.

2.) Because of the previous you need to merge all files before parsing so you have all information available. Parsing the merged data might work if the css files are GSS compatible in which case you would hand over the merge result to closure stylesheet to parse it again and produce the final css output. However if the merged data fails to parse then you know that some files are incompatible but not wich ones. So you don't know if its because of a GSS syntax error in one of the gss files (in which case you would fail the compile) or if its because one of the css files contain legacy syntax that needs to be converted using the in-memory converter.
To figure that out you would need to assume that css files are incompatible, merge just the css files (because of 1. and because the converter does not want gss input)), run them through the css2gss converter and finally merge the conversion result with the remaining gss files. However when doing so you might have changed the ordering of css rules that needs to be avoided as it changes rendering behavior.

So the only way to make it fool proof for GWT is to assume that *.css files must always be converted and that *.gss files can be used as-is and that you can never mix them for a given CssResource. And that is exactly what GWT does.



So in your case you need to provide gss and css files for your widgets. You can generate the gss files from the css files by using the css2gss tool provided in gwt-user.jar. GWT itself does the same for its widgets.



-- J.

Ed Bras

unread,
Mar 4, 2015, 2:00:14 PM3/4/15
to google-we...@googlegroups.com
Thanks for the explanation @Jens. I think I understand why the extension is important. So we can't  let go if that requirement.
But let's go back to the original error (subject of the topic).
If I understand you correctly, I could be able to mix css and gss files by using the correct extension. In case it concerns a css file, the gss mechanism will sue the css2gss converter to create the gss file before passing it to to the closure compiler. But that is what I am doing, so why isn't that allowed?
- Ed

Jens

unread,
Mar 4, 2015, 2:40:38 PM3/4/15
to google-we...@googlegroups.com

If I understand you correctly, I could be able to mix css and gss files by using the correct extension. In case it concerns a css file, the gss mechanism will sue the css2gss converter to create the gss file before passing it to to the closure compiler. But that is what I am doing, so why isn't that allowed?

Because GWT can not convert it on a file-by-file basis. All files need to be merged to get complete information for parsing. So all files need to be of the same type.

-- J.

Ed Bras

unread,
Mar 4, 2015, 5:31:51 PM3/4/15
to google-we...@googlegroups.com
Thanks @Jens.

Because GWT can not convert it on a file-by-file basis. 
Why not ?

Jens

unread,
Mar 4, 2015, 6:17:08 PM3/4/15
to google-we...@googlegroups.com

Because GWT can not convert it on a file-by-file basis. 
Why not ?

I have already said it before: in case of old css a constant might be used in one file but is defined in a different file. In case of gss you might use a @mixin in one file but that @mixin is defined in a different file. 

-- J.

Ed Bras

unread,
Mar 4, 2015, 6:34:44 PM3/4/15
to google-we...@googlegroups.com
Ahhh, yes, you explained that before, sorry for that.
All clear now, I have to think about how to use it.

Reply all
Reply to author
Forward
0 new messages