royale-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Harbs <harbs.li...@gmail.com>
Subject Re: Type Selector Approximation (was Re: [DISCUSS] Explanation of the changes)
Date Thu, 17 May 2018 20:39:18 GMT
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
Mime
View raw message