Snipping relevant pieces to make it more legible…

> 
> I agree #1 and #2 are creating problems, but they are not bugs in the 
> compiler.  I believe the compiler correctly prunes out any Type Selectors 
> that are not used.  The compiler must carry over any class and id selectors 
> since there is no way to determine if they are used or not (and it must bring 
> in any ClassReferences in selectors).  If you have a strategy for a feature 
> enhancement by which the compiler can know to prune more stuff, we should 
> discuss that.  Just remember that any strategy must apply to user-supplied 
> CSS in fx:Style blocks.  I implemented one such strategy already.  If you 
> give a class selector a name that uses a fully qualified classname (with 
> hyphens instead of dots, so org_apache_royale_html_TextInput_SomeClass) then 
> the compiler will prune that class selector if TextInput is not in the 
> output.  IMO, the changes required here are in the framework to use that 
> naming scheme on any class selectors used in the framework, and/or stop using 
> class selectors in the framework.  We could create subclasses for just about 
> every class selector currently in the defaults.css for our SWCs.
> 
> Also note what I wrote in the wiki about "kinds" of CSS.  I believe that the 
> framework code is not fully conforming to the recommended practices in that 
> wiki article.  If it did, I think there would be far less extra CSS being 
> added to the output. As Carlos mentioned, maybe we should work on a test case 
> so we have specific code to talk about.

Let me use a concrete example to illustrate what I mean: Try compiling the 
DateControlsExample. The example does not use ButtonBar in any manner, shape or 
form. Being so, ButtonBar and all related classes should not be included in the 
output. However, both the ButtonBar CSS and ButtonBar and associated classes 
are included in both debug and release code. I think this can only be 
classified as a bug and this is what we need to fix.

I don’t understand why the compiler cannot build a list of used classes and 
drop any CSS references not used.

> 
>    #3 has a few different ways it can be resolved. The way that Carlos and I 
> both like is by using composite class names such as “basic Button” and using 
> a selector .basic.Button{} which requires the element to have *both* class 
> names applied.
> 
>    The solution above requires that class selectors are used and not type 
> selectors. (The same for other solutions which use fully qualified names).
> 
> That is an appealing solution.  In fact, it might be worth adding a name like 
> "basic" or "jewel" to the className list of TLCs so users can control styles 
> for individual component sets, but that isn't quite PAYG.  It is making 
> everyone pay the price for multiple component sets even if they only use one. 
>  Also I'm trying to figure out how the compiler will know to prune out 
> selectors that are not used.
> 
> The Type Selectors in defaults.css for SWCs are using fully qualified names 
> already.  When you specify the namespace in the defaults.css then just having:
> 
>   @namespace foo
>   Application {}
> 
> really means that selector is foo.Application.  But if you have multiple 
> namespaces open, then what would you write?  I'm not sure .basic.s|Button is 
> allowed.  Needs more investigation.

I’m not sure we’re talking the same language. The class selector for 
ImageButton will always be (in HTML css) .ImageButton. So if you have a basic 
ImageButton and a Jewel ImageButton, there will be CSS conflicts in the 
compiled HTML CSS.

> 
> Sounds like you are saying we shouldn't support extending Type Selectors in 
> Royale for non-HTML components.  I think we can approximate it well enough to 
> do it.  I think customers will want it and expect it and it will be an 
> attractive feature for Royale.  Royale is all about Types, and we should 
> leverage it to help optimize the users output.  It is much easier to prune 
> based on type selectors than class selectors. 

I’m not sure what you mean here. I definitely think we should support things 
like js|ImageButton{background:none}. The question is what that will ultimately 
output in the final css file.

>    Some additional points:
>    * Unless we can figure out a way for the compiler to know which typenames 
> are *actually* used, to prevent css of superclasses from being imported (i.e. 
> basic Button), other components cannot subclass it. (i.e. Jewel should not 
> subclass basic Button to prevent basic Button CSS from being unnecessarily 
> included.0
> 
> Interesting question.  However, a "workaround" might be to make sure the 
> Application developer can manually prune out unused ClassReferences.  Often, 
> optimization has to be left to the app dev.  There is no easy way for the 
> framework and tool chain to really know.  And I think an app dev can prune 
> class references by declaring the Type Selector in custom CSS and setting 
> properties to null:
> 
> Button { iBeadModel: null }
> 
>    * We will need a lookup of “standard” prefixes for the compiler to use so 
> it knows what typenames to use for different packages.
> 
> I'm not understanding what you mean here.

If the typenames are always fully qualified, then the compiler knows what CSS 
to output. If we want to go the prefix route (i.e. j|ImageButton would output 
.jewel.ImageButton), the compiler needs some way to know that the prefix for 
the Jewel namespace is “jewel”.

While discussing this I actually came up with a new idea which I think would be 
better all-around:
We could support metadata in classes for Typename and TypenamePrefix. That 
would allow each class to specify exactly what css classes the compiler should 
use when compiling the CSS for that class.

For example:
    [Typename(name="Button", prefix="basic")]
    public class Button extends ButtonBase

would tell the compiler that the selector for this class should look like:
.basic.Button{
}

    [Typename(name="org_apache_royale_html_Button")]
    public class Button extends ButtonBase

would tell the compiler that the selector for this class should look like:
.org_apache_royale_html_Button{
}

If there’s no meta-tag at all, the behavior would stay as it is today and you’d 
get:

.ImageButton{
}

and 

Button{
}

This feels like the smallest change to the compiler and leaves the component 
sets to decide for themselves how to best handle possible conflicts.

Thoughts?

Harbs

Reply via email to