You have a fundamental misunderstanding of @Import, despite the doc being 
rather clear, and that's your only problem (afaict).
http://www.gwtproject.org/doc/latest/DevGuideClientBundle.html#Imported_scopes
You also have a slight misunderstanding of @Shared.

Let's go back to the 
basics: 
http://www.gwtproject.org/doc/latest/DevGuideClientBundle.html#Selector_obfuscation_details

   - each method in a CssResource interface maps to a unique name (let's 
   call it obfuscated class name) based on the type of the interface and the 
   name of the method
   - the basis for the unique name is the interface used as return type of 
   the ClientBundle method, even for methods inherited from other interfaces, 
   except if such an interface is annotated with @Shared, in which case the 
   name will be unique for the @Shared interface (and the same name used for 
   every sub-interface)
   - each class name used in the CSS must map to a method in the interface, 
   unless you use @NotStrict, or the class name has been declared @external, 
   or the class name has been @Import-ed from another interface. In that case, 
   the .*prefix-className* in the CSS (where *prefix* is the prefix 
   declared in @ImportedWithPrefix on the imported interface, and 
   *className* is the original class name from the imported interface) will 
   be replaced with the unique name computed for the method of the imported 
   interface
   - mapping class names to/from methods is based on the method name or a 
   @ClassName annotation (the class name in the CSS file will thus be replaced 
   with the unique name computed for the method)

So, if you want to reuse a class name in a selector, then use @Import or 
@Shared+inheritance. The difference is that with @Shared you're forced to 
declare rules for the inherited/shared class names (to satisfy the 4th rule 
above), and the class name is accessible from outside the CSS file, from 
the CssResource interface (because of inheritance).

@Import is for cases where you want to say "the style rules have to be 
slightly different when used within/in coordination with/in the context of 
some other widget" (e.g. a cell that's slightly different when in a 
CellTree, compared to a CellTable or CellList, or a widget that's slightly 
different when put in some specific container widget, or possibly when 
defining the style of a container or composite widget saying a child widget 
needs to have a slightly different style).
@Shared is generally for cases where you want to say "the style rules have 
to be slightly different depending on some state/situation", where the 
state/situation is toggled/triggered externally by adding/removing a class 
name, and you possibly want a shared/common way to toggle/trigger that 
state/situation independently of the current specific style (e.g. all 
"checkables" have "checked" and "unchecked" states, whether they're 
checkboxes, push buttons, togglable menu items, etc.)
In both cases, the goal is to write compound selectors using a local class 
name and an imported/shared class name, composed directly (both classes 
applied to the same element) or with an operator.

In your case, you'll use either @Import or @Shared, depending on your use 
case. But if you use @Shared, then you MUST NOT use the parent CSS file in 
the @Source for the child interface!

Inline notes below:

On Saturday, February 22, 2014 10:09:48 PM UTC+1, GWTter wrote:
>
>
>
> On Friday, February 21, 2014 5:09:36 PM UTC+1, Thomas Broyer wrote:
>>
>>
>>
>> On Thursday, February 20, 2014 10:51:29 PM UTC+1, GWTter wrote:
>>>
>>> ----Before anything, sorry Thomas, I think I may have just replied to 
>>> you instead of just the topic (buttons bugged on me a bit), no-spam 
>>> intended----
>>>
>>> You're right I guess I did misunderstand if the imported with prefix 
>>> doesn't in fact use a different obfuscation
>>> for the original selectors in the final css. So using the imported with 
>>> prefix method isn't a viable workaround for avoid the
>>> precedence override on injection after all.
>>>
>>> And definitely, anything that will help clear it up. I can try to 
>>> clarify my original example:
>>>
>>> You have the following,
>>>
>>> === Pseudocode ===
>>>
>>> CssResouces:
>>>
>>> SuperCssResource, is injected onModuleLoad (global css) and has the 
>>> following css as its source:
>>> .genButton{
>>> color: black;
>>> }
>>>
>>> and
>>>
>>> LeafCssResource extends SuperCssResource
>>> .... 
>>> css definitions here 
>>> ....
>>>
>>
>> Why are you using an "extends" here? what do you expect from it? and more 
>> importantly what does your ClientBundle(s) looks like?
>>
>
> I'm just setting up viable example when working with Resources. In this 
> case specifically you would expect to be able to reference the styles
> from SuperCssResource via LeafCssResource and be able to use the selectors 
> from SuperCssResource's css to qualify other selectors in LeafCssResource's 
> css.
>
 

> The client bundle would simply look like:
>
> interface LeafClientBundle extends ClientBundle{
>   @Source({"Leaf.css","Super.css"})
>   LeafCssResource leafCss();
> }
>

The mistake here is using Super.css. Because (as you say below) the 
SuperCssResource is @Shared, then LeafCssResource will indeed contain the 
exact same Super.css as SuperCssResource (you duplicate it with @Source, 
and it's renamed/obfuscated to the same because of @Shared).

If your Leaf.css selectors use class names from SuperCssResource in 
compound selectors, but only some of them, then you could instead have 
@Import-ed SuperCssResource (rather than declare it @Shared and extend it). 
I must say I have no idea what would happen if you declared an accessor 
method for an imported class name (I suppose you'd have to use @ClassName 
anyway, with the prefixed class name as value); in case you'd like 
LeafCssResource to have accessors for class names from SuperCssResource.

 
>>
>>> ----------------------------------------
>>>
>>> Finally, we have the following 2 widgets:
>>>
>>> WidgetDisplayedFirst, 
>>> has the following css via uibinder:
>>> MyCssResource:
>>> .myButton{
>>> color: red;
>>> }
>>>
>>> And this button element:
>>> <button class="genButton myButton" />
>>>
>>
>> Using this, it means you have to ensure SuperCssResource is always 
>> injected *before* you createAndBindUi for the widget.
>> Using .genButton.myButton (higher specificity) in the CSS would fix it.
>>
>
> Yes, and in this example I would make sure to inject LeafCssResource which 
> would thereby inject SuperCssResource.
>

Because you misused @Shared/@Source.
 

> And adding .genButton to further the specificity of .myButton would indeed 
> fix, however the point I'm trying to make is that I think it's
> unreasonable to either overqualify every selector for fear of having your 
> styles be overridden because of precedence or that developers
> need to be aware of all the other styles they would be affecting when 
> creating their own widget trying to qualify their selectors with a global 
> cssresource.
>
>  
>>
>>> and WidgetDisplayedSecond which uses LeafCssResource
>>>
>>> ------------------------------------------
>>>
>>> Now if while my app is running I just display WidgetDisplayedFirst then 
>>> it will display its button
>>> with the correct color: red because the .myButton was declared last and 
>>> thus overrides the .genButton which
>>> has the same specificity.
>>>
>>> The issue comes into play if I then display WidgetDisplayedSecond. Since 
>>> WidgetDisplayedSecond uses LeafCssResource
>>> this will cause SuperCssResource and its css to be injected when 
>>> LeafCssResource is injected.
>>>
>>
>> No. Unless you have a @Shared annotation on SuperCssResource, the names 
>> from LeafCssResource will be different from those of SuperCssResource (so 
>> even if you referenced the same CSS file in @Source of your 2 ClientBundle 
>> methods, you'd have duplicated rules with different selectors, in no way 
>> would SuperCssResource be "reinjected").
>> See http://www.gwtproject.org/doc/latest/DevGuideClientBundle.html#Scope
>>
>
> Yes, and I should have actually put the @Shared in the example. I didn't 
> remember to add it because I was talking about reusing selectors in the 
> leaf css to qualify in which case you would need to have the same names or 
> else the qualifying would not work at all since the names would be 
> different. So in this case I am talking about using the @Shared on the 
> SuperCssResource and that you do see the selectors from SuperCssResource's 
> css reinjected when you inject LeafCssResource.
>  
>
>>  
>>
>>> At this point because
>>> SuperCssResource has now been reinjected and thus is now the last one 
>>> declared between it and MyCssResource, its
>>> .genButton rule now wins and causes WidgetDisplayedFirst's button to now 
>>> have a color of black.
>>>
>>
>> With the code above, it shouldn't (now there could be bugs).
>>
>
> So you're saying that SuperCssResource's css should not be included in 
> with the css generated for LeafCssResource to be injected? If that's the 
> case then I think there is a bug.
>

The bug is in your @Source.
 

>  
>
>>  
>>
>>> Now, granted, this is how Css is intended to work in terms of the 
>>> cascade. However, what I'm trying to say is that this
>>> is an example of a case where that is not the desired outcome if you 
>>> want the button to keep the color of red as defined
>>> in its MyCssResource.
>>>
>>> You really only have 3 options in order to prevent this currently as far 
>>> as I can see:
>>> 1) You over-qualify all of your selectors to ensure that they always 
>>> have the most specifity and nothing
>>> will override them
>>> =>CON: over-qualifying is not great for performance and is not as 
>>> maintainable/cascadeable
>>>
>>> 2) You architect the app taking into account every single inheriting 
>>> resource that is injected dynamically/on-demand to make sure
>>> that the injection of the extended resource does not cause an override 
>>> in widgets who are using its classes.
>>> =>CON: extremely unrealistic for non-trivial apps much less a real 
>>> web-app
>>>
>>
>> Except that inheritance of CssResource interfaces does not work that way 
>> (and if it does in practice –I doubt it, there are unit tests–, then that's 
>> a bug).
>>
>
> I'm starting to think that a bug is the issue because you would see the 
> css from SuperCssResource in the css of LeafCssResource when the 
> LeafCssResource is injected which is why this precedence override is 
> happening.
>

…again because that's what you said in your @Source.
 

>  
>>
>>> 3)Do not extend CssResources, this way you can ensure that all resources 
>>> and their associated styles are ONLY injected
>>> once in the lifetime of the app so there are no worries of unintended 
>>> precedence overrides.
>>> =>CON: greatly restricts selector qualifying especially when trying to 
>>> localize css and reuse widgets
>>>
>>
>> I don't get your CON here. If you need to use the class name from another 
>> CssResource in your CSS in a compound selector, then just @Import the other 
>> CssResource. As long as you're not changing the styles from the imported 
>> class names (same as if you had several CSS files without using 
>> ClientBundle), there's no need to worry. 
>>
>  
>>
>
> My CON is assuming that if you do not extend the CssResource then you 
> cannot reference the selectors in the leaf css because I though that 
> @Import and extending worked together. However, I may be wrong about this 
> as I've never tried to use @Import without the accompanying extends on the 
> respective CssResources. Are you saying that using the @Import without the 
> extends would work in terms of being able to reference the super selectors
>

Yes.
 

> and that you wouldn't have this reinjecting issue too?
>

Well, if you'd keep your @Source the same, you'd have issues (probably 
wouldn't compile, because of strict scoping).

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to