----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 
....
----------------------------------------

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" />


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. 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.

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

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 think you can see why these 3 options are unappealing. I'd argue that 
this isn't an issue for static web pages
and the non-webapp era since you could relegate css to a page and count on 
the browser refresh to always provide
a clean slate. However, in the web-app era this seems to be a big issue 
maintainability-wise if nothing else.

This is why I was suggesting the @required functionality so the developer 
can have some assurance that styles won't be
injected more than once and thus be assured that if someone displays their 
widget anywhere then it won't break something else.

Hope that somewhat clears up what I'm trying to say.

Thanks again for the discussion.

On Thursday, February 20, 2014 1:15:48 PM UTC+1, Thomas Broyer wrote:
>
>
>
> On Thursday, February 20, 2014 12:08:28 AM UTC+1, GWTter wrote:
>>
>>
>>
>> On Wednesday, February 19, 2014 10:59:51 AM UTC+1, Thomas Broyer wrote:
>>>
>>>
>>>
>>> On Tuesday, February 18, 2014 6:38:36 PM UTC+1, GWTter wrote:
>>>>
>>>> Hi all,
>>>>
>>>> Let me just go with an example right off the bat.
>>>>
>>>> Let's say I have the following:
>>>>
>>>> === Pseudocode ===
>>>>
>>>> SuperCssResource: This is injected onModuleLoad before anything else
>>>> .genButton{
>>>> color: black;
>>>> }
>>>>
>>>> Widget1 consists of:
>>>> --- css ---
>>>> MyCssResource:
>>>> .myButton{
>>>> color: red;
>>>> }
>>>>
>>>> --- html ---
>>>> <button class="genButton myButton" />
>>>>
>>>> Widget2 consists of:
>>>> --- css ---
>>>> XCssResource extends SuperCssResource:
>>>> ... rules that use classes from SuperCssResource
>>>>
>>>> --- html ---
>>>> ...elements
>>>>
>>>> My problem is that if I display Widget1 first and then display Widget2 
>>>> then the button in Widget1 will have a color of black instead of red.
>>>>
>>>> I know that this is expected behavior (GWT will merge the stylesheets 
>>>> together) since inheritance is basically the cssresource equivalent of CSS 
>>>> @import <http://www.w3.org/TR/css3-cascade/#at-import>
>>>>
>>>
>>> Er, no.
>>>
>>> Inheritance of CssResource interfaces only deals with that: inheriting 
>>> methods. The actual CSS backing the resource is given by the @Source 
>>> annotation on your ClientBundle method, and if you use the same CSS file 
>>> for 2 different CssResource interfaces, the CSS will be duplicated, because 
>>> obfuscation of the class names is based on the interface fully-qualified 
>>> name: 
>>> http://www.gwtproject.org/doc/latest/DevGuideClientBundle.html#Scope (the 
>>> order of the files in @Source will impact merging, just as they'd impact 
>>> precedence in CSS).
>>>
>>
>> Hi Thomas,
>>
>> I guess I should have specified that it is inheritance along with 
>> specifying the source css that for all intents and purposes acts like CSS 
>> @import. I know that GWT will error if you extend the super resource and 
>> don't include it's source to match the classes, unless you're 
>> reimplementing them in the extending css resource which is not what I'm 
>> after and not the best idea IMHO. 
>>
>>>  
>>>
>>>> but I thought since this was GWT maybe there was a way to use 
>>>> inheritance in the sense that the inherited stylesheet would only be 
>>>> injected if
>>>> not injected already. Is this currently possible? or could it be done 
>>>> with like a @Require annotation on the extending interface which would 
>>>> indicate
>>>> that merging of the super stylesheet should not be done but rather a 
>>>> check would be made to see if it already exists and if not to inject it.
>>>> This would easily resolve the specificity overriding issue in the 
>>>> example when it's not the desired behavior.
>>>>
>>>> I know I could also get around this by importing with a prefix, however 
>>>> I still don't like the idea of essentially reinjecting the same styles.
>>>>
>>>
>>> If you don't want duplication, then you need a "shared scope" or 
>>> "imported scope". In any case, that means you should only use the 
>>> shared/imported class names in more complex selectors, you shouldn't change 
>>> the styles attached to the selector by itself.
>>>
>>> None of this applies if you use "@external" though, then it just works 
>>> like standard CSS.
>>>
>>
>> I know, like you mentioned, that I could avoid the precedence override by 
>> importing with prefix for example. And my use case is only to increase 
>> specificity on the extending css resource, definitely not to change the 
>> super's rule def by redefining the super selector in the extending 
>> resource. But I'm not thrilled with essentially reinjecting all the same 
>> rules with just different prefixes and @external does really fit my need as 
>> I don't want to forgo the obfuscation.
>>
>
> I don't understand that "reinjecting all the same rules with just 
> different prefixes" bit; sounds like a misunderstanding of how @Import and 
> @ImportedWithPrefix work.
> Obfuscation is based on the FQCN of the interface, so @Import()ing such an 
> interface is only about importing the *names*, not the source (which is not 
> defined in the interface anyway), and @ImportedWithPrefix is only there to 
> prevent conflicts (it also helps visually distinguishing those names that 
> have been imported and those that are "defined" in the stylesheet). The 
> gwt-CellTree-cellTreeItem you'd get by @Import(CellTree.Style.class) will 
> be replaced with the same obfuscated name as the cellTreeItem from the 
> CellTree stylesheet, so you can match something in a CellTree, but nothing 
> is "injected with just different prefixes", the prefixes are gone after 
> compilation.
>
> Either that, or I'm not understanding your use-case, and a simple example 
> would really help! (in any case, if you could share a simple example, I 
> think everyone could benefit from a discussion around it, or maybe just 
> using it as a basis for their own work, maybe even a "best practice")
>

-- 
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