@Import
and @ImportedWithPrefix
A CSS Resource can import other CSS resources. GWT supplies two annotations
for this: @Import
and @ImportedWithPrefix
.
Unfortunately, the online examples and tutorials that I have found for this are woefully incomplete. They all suffer from what I have found to be an ever-increasing approach to programming discussions and documentation: they have either been written hypothetically (i.e., the code they list was never actually run), or, if they did come from a working example, the small details crucial to understanding and implementing the concept have been left out.
Plus, to make things even more confusing, the @Import
annotation
does not produce the same effect as using @import
within a CSS
file. When used in a CSS file associated with a CssResource
, @import
doesn't
seem to do anything.
So, below is my attempt at describing these two annotations and how they are used.
A CssResource
sub-interface can have a prefix automatically prepended
to its style class names by annotating it with the @ImportedWithPrefix("prefix")
annotation.
As a result, all the style class names
will have the prefix prepended, regardless of whether the CSS resource is imported
into another, of just used without importing it anywhere (a better name for
the annotation might have been @PrefixedWith
). In the associated
CSS file, however, you should write the class names without the prefix (which
would match the method names in the interface).
It's worth noting that above (and below), when I say "class names will have the prefix prepended", that will for the most part mean "behave as if they had the prefix prepended". You won't ever see the prefix in the resulting compiled app, or in a debugger like Firebug, you'll see just an obfuscated name. The only place you would use the prefix would be in a CSS resource that imported another resource.
Another CSS resource can import one or more additional CssResource
classes
by creating a method that returns a CssResource
, annotated with @Import
.
The value supplied for the annotation can be a single class object for another CssResource
,
or an array of those class objects. Given that the imported class names will
have the prefix regardless of whether they're imported anywhere, the real
benefit of this is that the associated stylesheet can modify the rules involving
the imported class name (but, they would now use the prefix).
For any class names that the importing CSS does want to use, there must be an associated method in the interface (but, without any prefix). It appears that the GWT compiler, as of GWT 2.5, will allow the CSS file to have any prefixed class names as long as the end part of the name is declared as a method in the interface, even if the specific prefix applied doesn't match anything that was imported.
Within the associated CSS file, all the style class names used in the interface must be defined, but without the prefix. When the resource is imported into another, the resulting class definitions will have the prefix (of course, you won't be able to tell, since they will be obfuscated).
Note that by doing this, you are locking this resource into always using the specified prefix.
The CSS file associated with the new CSS resource can also contain rules involving the imported classes, but now those rules must include the prefix.
But, to use the prefixed rules, your client bundle must have an instance
of the CSS resource that originally defined them, not just the one that
imported them. So, the client bundle containing the code snippet above, you
must also define a method to retrieve the original CSS resource (the one
with @ImportedWithPrefix
). In fact, a CSS resource that uses the @ImportedWithPrefix
annotation
doesn't even have to be imported into any other - you can just invoke the accessor
methods to retrieve the obfuscated name, which will be different from the same
name defined in a different CSS resource with a different prefix or no prefix.
But, if this resource is imported into another, any rules added by the importing resource's CSS file will be applied also, since that caused the CSS to be generated and injected.
Note that in order to minimize the file size, the gwt-servlet.jar
file
is not included. After unzipping and importing into an Eclipse workspace, you
can usually reinstate it by going to the project's properties, under the
Google ... Web Toolkit sections, removing the check from Use Google Web Toolkit,
then OK. Then go back through the same process to put the check back and OK
again. (Or just copy the jar file from another project.)
You can try the code below to see all three CSS resources in action. There
are embedded notes regarding code to comment out to try it without any instance
of the
Styles
resource - they must be done as a group.
In the code below, the lines marked with /**/
are to be commented
out to try it without any instance of the Styles
class.
The comments after each added panel show the class that actually got added in one test run of the application.