What about Step A - requirements? We should list out the requirements we have so we can make sure we aren't missing anything. There's been a lot of work in getting the skinning to work with portals, so we'll need that to still work and we will probably want to redesign it since it's kind of lame the way it works right now.

From my experience coming up with a good API takes a lot of time. I'll try to find some time to read your proposal at least.

Jeanne

Simon Lessard wrote, On 12/8/2008 6:16 AM PT:
I would prefer a roadmap like:

   1. Design a modular API that fits Trinidad's needs with minimal
      compatibility loss.
   2. In parallel
         1. Start implementing the API defined in 1. as a myfaces
extension, possibily along with a ResourceHandler for JSF 1.2 2. Propose the API to JSF 2.0 EG
   3. If the API make it the the spec then
         1. Convert the extension to fit the new API (even if target
            is 1.2 it should be possible but in a different package)
         2. Integrate the API with the corect package naming to the
            2.0 branch (obviously)
   4. In the API doesn't get in the spec, then create a 2.0 branch of
      the skin extension
   5. Convert Trinidad to the new extension
   6. Integrate the extension in Tomahawk and Tobago


So, for now, I would really really like to get comments from the community on the API I proposed as well as potential solutions for the pendings. Otherwise I'll have to propose it in its current form and that would prevent the API to be reviewed by the MyFaces community and that would be a shame imho. As I mentioned before, time is running really short and the fact that 2.0 is in public review phase alone might prevent the addition of such core API in the spec so the faster we can design a great API, the more chances there is to see it standardized.


Regards,

~ Simon

On Mon, Dec 8, 2008 at 4:22 AM, Gerhard Petracek <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:

    hello paul,

    ok - let's continue with the case you mentioned.

    we could:
     - use the same approach of the myfaces shared module also for the
    shared skinning code
     - provide skinning as an independent jar file (it's easier for
    other projects/custom components to re-use it)

    regards,
    gerhard



    2008/12/8 Paul Rivera <[EMAIL PROTECTED]
    <mailto:[EMAIL PROTECTED]>>

        Hi,

        It's good to hear that there's effort done to make skinning
        standardized and part of JSF by Simon.  Is there anything that
        the current skinning project we have at
        http://code.google.com/p/myfaces-csi/ can contribute to this?

        In the event that Simon's ideas don't get integrated into JSF
        2.0, I'd like to bring back the discussion to the skinning
        project that we now have in the link mentioned above.

        Overall, I think the community agrees with the idea of having
        an independent skinning project that is basically derived from
        trinidad code.  I'd like to hear your opinion on the project
        layout described in
        http://code.google.com/p/myfaces-csi/wiki/MyfacesSkinsProposal.

        What concerns me most here is that the skins project and
        trinidad share a lot of classes that it is hard to get a clean
        separation.  You can check shared-impl for those classes.

        Our current layout has a shared module (shared-api,
        shared-impl).  This module contains code shared by both
        skinning and trinidad-core.  We can probably move some of the
        utility classes into myfaces-commons-utils.  But other classes
        there might not be such a good fit into myfaces-commons-utils.

        We started this project with the most immediate goal of giving
        tomahawk skinning support and eventually have trinidad use
        this project.  We've taken trinidad skinning code and now it
        works with tomahawk and trinidad-core.  In the event that this
        project gets accepted into myfaces, integration with tomahawk
        is not a big problem.  I am actually more worried with the
        changes we have to make in trinidad-core.  This is why I'd
        like to propose as a roadmap:
          - finish the skinning project and make the necessary changes
        in trinidad-core without adding new features yet to the
        current set that trinidad has.  There will be big changes in
        trinidad-core that need to be done at the same time.
          - once we verify that everything is working, we can then add
        the desired new features/changes to the skinning api.  In this
        phase, we can implement the new features/changes to the api in
        small and more manageable increments.

        While Simon is in the process of submitting his proposal, I'd
        like to work on these issues and anything else you think might
        be a problem for the skinning project or the transition with
        trinidad.

        Best Regards,
        Paul Rivera


        --- On *Sat, 12/6/08, Gerhard Petracek
        /<[EMAIL PROTECTED]
        <mailto:[EMAIL PROTECTED]>>/* wrote:

            From: Gerhard Petracek <[EMAIL PROTECTED]
            <mailto:[EMAIL PROTECTED]>>
            Subject: Re: [Skinning] Independent skinning myfaces
            subproject
            To: "MyFaces Development" <[email protected]
            <mailto:[email protected]>>
            Date: Saturday, December 6, 2008, 12:42 PM


            hello simon,

            no it's just because of ie version < 7 like it is
            mentioned in the trinidad skinning documentation.

            regards,
            gerhard



            2008/12/6 Simon Lessard <[EMAIL PROTECTED]
            <mailto:[EMAIL PROTECTED]>>

                Hi Gerhard,

                Trinidad already has this and it would be the same
                with what I propose. Assume: <tr:tree
                styleClass="MyClass"/>

                Then switch the selectors to: tr|tree.MyClass

                As far as I can tell this is enough to cover every
                possibilities without burdening the framework with an
                extra attribute. Unless you can come up with a counter
                example not involving IE6's shitty CSS support.


                ~ Simon


                On Sat, Dec 6, 2008 at 2:19 PM, Gerhard Petracek
                <[EMAIL PROTECTED]
                <mailto:[EMAIL PROTECTED]>> wrote:

                    hello simon,

                    in my opinion andrew brought up an interesting
                    question. have you also thought about multiple
                    selectors for the same component?

                    i repeat the example i mentioned before:


                    <tr:tree/> ... uses default selector
                    <tr:tree selectorId="myId"/> ... uses selector
                    with "myId" to use a different selector

                    regards,
                    gerhard



                    2008/12/6 Simon Lessard <[EMAIL PROTECTED]
                    <mailto:[EMAIL PROTECTED]>>

                        Hi all,

                        Since I completed the proposition by memory
                        yesterday I forgot some important parts. Also,
                        I thought more about some possibilities I
                        rejected during the night and reconsidered my
                        those. So here is v2. Among other thing I
                        integrated skin extends, removed selector
                        redirection, removed some other PENDING and
                        simplified 3.1 suggestion since I discarded
                        redirection:

                        *Modified classes*

                        public abstract class Application
                        {
                            public String getDefaultSkinFamily();
                            public void setDefaultSkinFamily(String
                        skinFamily);
                        }

                        public final class FactoryFinder
                        {
                            public static final String SKIN_FACTORY;
                        }

                        public class UIViewRoot
                        {
                            public String getSkinFamily();
                            public void setSkinFamily(String skinFamily);
                        }


                        *Modified methods*

                        public abstract class ViewHandler
                        {
                            /**
                             * Same as before but also copy skin family.
                             */
                            public abstract UIViewRoot
                        createView(FacesContext context, String viewId);
                        }


                        *New classes*

                        public abstract class Icon extends Resource
                        {
                            /**
                             * Gets the key within the skin's
                        ResourceBundle to the description of this
                        icon. The description can be used
                             * as an alternate text for the icon to
                        improve accessibility for example.
                             */
                            public abstract String getDescriptionKey();
/**
                             * Gets the name of this icon.
                             */
                            public abstract String getName();

                            /**
                             * Gets the effective style class of this
                        icon within the skin.
                             */
                            public abstract String getStyleClass();
                        }

                        public abstract class Skin
                        {
                            public abstract Resource
                        getContentResource(FacesContext context);

                            public abstract Icon getIcon(FacesContext
                        context, String iconName);

                            public abstract Object
                        getProperty(FacesContext context, String
                        propertyName);

                            /**
                             * Get the ResourceBundle for this skin in
                        the current locale.
                             */
                            public abstract ResourceBundle
                        getResourceBundle(FacesContext context);

                            public abstract SkinNode
                        getSkinNode(FacesContext context, SkinSelector
                        selector);

                            public String getStyleClass(FacesContext
                        context, SkinSelector selector)
                            {
                                SkinNode node = getSkinNode(context,
                        selector);
                                return node == null ? null :
                        node.getStyleClass();
                            }
                        }

                        public class SkinException extends FacesException
                        {
                            // Provides all 4 common Exception
                        constructors
                        }

                        public abstract class SkinFactory implements
                        FacesWrapper<SkinFactory>
                        {
                            public abstract void addSkin(String
                        skinFamily, String renderKitId, Skin skin);
                            public abstract Skin getSkin(String
                        skinFamily, String renderKitId);
                            public abstract Collection<String>
                        getSkinFamilies();
                            public SkinFactory getWrapped()
                            {
                                return null;
                            }
                        }

                        public class SkinInitializationException
                        extends SkinException
                        {
                            // Provides all 4 common Exception
                        constructors
                        }

                        /**
                         * Implementations of this interface are in
                        charge of creating Skin instances in an
                        implementation specific manner.
                         */
                        public interface SkinLoader
                        {
                            /**
                             * Creates a new <code>Skin</code>
                        instance the specified skinFamily and
                        parameters. There's no garanteed as of what
                             * parameters will be present in the Map
                        argument and the creation should fails if
                        those parameters are not correct
                             * for the specific implementation.
                             *
                             * @throws SkinInitializationException if
                        the provided parameters are not sufficient to
                        create the new <code>Skin</code>
                             *         instance
                             */
                            public Skin loadSkin(Skin parentSkin,
                        String resourceBundle, Map<String, String>
                        parameters);
                        }

                        public abstract class SkinNode
                        {
                            public abstract String getStyleClass();

                            public abstract Map<String, Object>
                        getProperties();

                            /**
                             * Gets a server side property of this
                        node. Server side properties are not visible
                        by the client.
                             */
                            public Object getProperty(String propertyName)
                            {
                                return getProperties().get(propertyName);
                            }

                            /**
                             * Gets a read-only version of the
                        client-side properties of this node. In HTML,
                        those represent CSS properties.
                             *
                             * It's valid to place those properties in
                        a SoftRenderece for memory footprint safety.
                        However, this
                             * method must be able to reload them if
                        needed
                             * those properties should be placed in
                        memory-aware renference
                             */
                            public abstract Map<String, Object>
                        getStyleProperties();

                            public Object getStyleProperty(String
                        propertyName)
                            {
                                return
                        getStyleProperties().get(propertyName);
                            }
                        }

                        public class SkinSelector implements
                        Comparable<SkinSelector>
                        {
                            /**
                             * Finds the SkinSelector with the
                        specified name or return <code>null</code> if
                        it doesn't exists. This
                             * method should be called by Renderers
                        during their initialization in order to cache
                        the SkinSelector instances
                             * they'll be using to increase overall
                        performance of the Skin module.
                             */
                            public static SkinSelector
                        getInstance(String selectorName);

                            /**
                             * Finds the SkinSelector with the
                        specified name or create a new one if it
                        doesn't exists and <code>create</code>
                             * argument is <code>true</code>. This
                        method should be used mainly by SkinLoader in
                        order to register a new
                             * selector.
                             */
                            public static SkinSelector
                        getInstance(String selectorName, boolean create);

                            private static int nextOrdinal = 0;

                            private int ordinal;
                            private String name;
private SkinSelector(String name)
                            {
                                assert name != null;
synchronized (SkinSelector.class)
                                {
                                    ordinal = nextOrdinal++;
                                }

                                this.name <http://this.name> = name;
                            }

                            public boolean equals(Object obj)
                            {
                                // Sufficient because ordinal is unique
                                return o == this;
                            }
public int hashCode()
                            {
                                return ordinal();
                            }

                            public String name()
                            {
                                return name;
                            }

                            public int ordinal()
                            {
                                return ordinal;
                            }
                        }

                        *New config
                        *
                        <application>
                          <default-skin-family/>
                        </application>
                        <skin>
                          <skin-family/>
                          <render-kit-id/>
                          <description/>
                          <extends>
                            <skin-family/>
                            <render-kit-id/>
                          </extends>
                          <skin-loader-class/>
                          <resource-bundle/>
                          <skin-loader-parameters>
                            <map-entries/>
                          </skin-loader-parameters>
                        </skin>
                        *
                        *
                        PENDING: Should it instead be a
                        getTranslatedResource instead of
                        getResourceBundle within the Skin class?

                        PENDING: Should the skin family and render kit
                        id passed to the loader or is that irrelevant?

                        PENDING: With the proposed API, Trinidad
                        aliases wouldn't be able to be used across
                        skin additions as it would be aggregated in a
                        CompositeSkin instance and thus in multiple
                        different documents, anyone has a better idea
                        than CompositeSkin for this? Maybe stardadize
                        aliases somehow and have CompositeSkin
                        aggregate the content in a single document
                        instead of delegating to its fragments?

                        PENDING: Should Skin.getIcon uses an optimized
                        key as well? Doesn't seem required since there
                        are much less icons in a page than HTML
                        elements, thus the gain wouldn't worth the
                        trouble imho.

                        PENDING: The Resource API might have to be
                        revisited in order to recognize the Resource
                        returned by Skin.getContentResource so that
                        ResourceHandler can identify Resource requests
                        for the skin content and thus locate the given
                        skin, get its Resource insteance and return
                        the content with the standard algorithm. I
                        believe a reserved library name could be used
                        for that, the resource name is an harder issue
                        though since the skin identifier is a tuple
                        atm and defining a reserved separator
                        character would bring limitation to the render
                        kit ids and skin family values. Someone could
                        come up with a better suggestion for that maybe?

                        PENDING: Skin.getStyleProperties could maybe
                        offer the option to return a mutable Map as an
                        optional feature, but then would requires the
                        Skin to
                        regenerate the style document (CSS). However
                        this can get hellish with composite skin. The
                        node would need to have access to its
                        container Skin and there should be a
                        SkinModificationEvent/Listener capability
                        added to the Skin class.


                        Regards,

                        ~ Simon


                        On Fri, Dec 5, 2008 at 1:21 PM, Simon Lessard
                        <[EMAIL PROTECTED]
                        <mailto:[EMAIL PROTECTED]>> wrote:

                            I agree with most of these statements, but
                            I would start even higher than that, like
                            defining the base interfaces and access
                            classes.

                            For instance, I think it's safe to assume
                            that a Skin class or interface should
                            exists. Let assume all interfaces for now
                            as it takes less characters. Now, from
                            where and how should the Skin be available
                            for a given FacesContext. Personally I
                            believe a Skin should be linked to a
                            RenderKit (or a common base RenderKit
                            class for all MyFaces extensions if not in
                            the standard), but let assume work on the
                            API for now for the sake of the discussion.

                            So for now we have:

                            public interface Skin
                            {
                                public String getResourceBundle();
                            }

                            public abstract class RenderKit
                            {
                                public abstract Skin
                            getSkin(FacesContext context);
                            }

                            So far so good, but now that opens some
                            issues that will themselves explode into more:

                               1. Should the way the RenderKit locates
                                  the current Skin standardized?
                               2. How do we define the contract
                                  ensuring that the Skin get rendered
                                  on the page?
                               3. What other functionalities should be
                                  standarized in the Skin interface?

                            *Issue 1: Current skin localization*
                            Personally I chose yes to that question
                            since it allow a standardized way to
                            define skins. Let use Trinidad's
                            skin-family notion here, but with the way
                            renderKitId is defined, that's the view
                            root and a factory implementing decorator
                            pattern. So we add

                            public class UIViewRoot
                            {
                                public String getSkinFamily();
                                public void setSkinFamily(String
                            skinFamily);
                            }

                            public abstract class SkinFactory
                            implements FacesWrapper<SkinFactory>
                            {
                                public abstract void addSkin(String
                            skinFamily, String renderKitId, Skin skin);
                                public abstract Skin getSkin(String
                            skinFamily, String renderKitId);
                                public abstract Collection<String>
                            getSkinFamilies();
                                public SkinFactory getWrapped()
                                {
                                    return null;
                                }
                            }

                            *Sub-issue 1.1: Default SkinFactory
                            implementation behavior*
                            Additional Exceptions
                            public class SkinException extends
                            FacesException
                            {
                                // Provides all 4 common Exception
                            constructors
                            }

                            public class SkinInitializationException
                            extends SkinException
                            {
                                // Provides all 4 common Exception
                            constructors
                            }

                            Additional interface
                            /**
                             * Implementations of this interface are
                            in charge of creating Skin instances in an
                            implementation specific manner.
                             */
                            public interface SkinLoader
                            {
                                /**
                                 * Creates a new <code>Skin</code>
                            instance the specified skinFamily and
                            parameters. There's no garanteed as of what
                                 * parameters will be present in the
                            Map argument and the creation should fails
                            if those parameters are not correct
                                 * for the specific implementation.
                                 *
                                 * @throws SkinInitializationException
                            if the provided parameter are not enough
                            to create the <code>Skin</code> instance
                                 */
                                public Skin loadSkin(String
                            skinFamily, String resourceBundle,
                            Map<String, String> parameters);
                            }

                            Addition to faces-config.xml:
                            <application>
                              <default-skin-family/>
                            </application>
                            <skin>
                              <skin-family/>
                              <render-kit-id/>
                              <description/>
                              <skin-loader-class/>
                              <resource-bundle/>
                              <skin-loader-parameters>
                                <map-entries/>
                              </skin-loader-parameters>
                            </skin>

                            Note that this solution makes
                            RenderKit.getSkin more an utility method
                            than anything, except if an extension
                            decides to override it (would probably be
                            the casew ith Trinidad, at least to start
                            to use trinidad-config.xml, or later to
                            add .pda or .desktop to the current
                            skinFamily).

                            Also, the framework should probably
                            provide some implementations of SkinLoader
                            out-of-the-box, most likely
                            ClassSkinLoader expecting a skinClass
                            parameter and a CSSSkinLoader receiving a
                            cssResourcePath parameter. (Trinidad would
                            mostl ikely provide an XSSSkinLoader for
                            example)

                            *Issue 2: Skin content rendering*
                            How should rendering be handled? Should it
                            be handled as an added ResourceDependency
                            just before rendering or as an additional
                            contract for the default HtmlRenderer for
                            HtmlHead? The latter sounds better, but
                            how should it be implemented? target would
                            obviously be "head", but then a public
                            Resource Skin.getContentResource() method
                            could be required and this might imply
                            some changes to the ResourceHandler
                            specification so that it can locate the
                            Skin instance in order to be able to serve
                            the Resource's content (effective CSS
                            content) to the agent. I like the Resource
                            version, but I have more thinking to do
                            about how to implement this, maybe
                            involving a reserved resourceIdentifier
                            structure/syntax

                            *Issue 3: Skin features*
                            Additional class
                            public abstract class Icon extends Resource
                            {
                                /**
                                 * Gets the key within the skin's
                            ResourceBundle to the description of this
                            icon. The description can be used
                                 * as an alternate text for the icon
                            to improve accessibility for example.
                                 */
                                public abstract String
                            getDescriptionKey();
/**
                                 * Gets the name of this icon.
                                 */
                                public abstract String getName();

                                /**
                                 * Gets the effective style class of
                            this icon within the skin.
                                 */
                                public abstract String getStyleClass();
                            }

                            public interface Skin
                            {
                                public Icon getIcon(String iconName);

                                public String getProperty(String
                            propertyKey);

                                public String getResourceBundle();

                                public String getStyleClass(String
                            selectorKey);
                            }

                            *Sub-issue 3.1: style class / property /
                            icon access strategy*
                            Trinidad uses String keys to access style
                            classes within the skin. That strategy is
                            very flexible, but alas very slow, thanks
                            to String.hashCode() being linear and
                            uncached. So, even if String.intern() is
                            called on all selectors within a given
                            skin, the gain will only be on
                            String.equals, making it O(1) instead of
                            O(n). Even if this is better than nothing,
                            especially it there's a collision, the
                            overall complexity of looking up a
                            selector remains O(n) with the length of
                            the key. So, the overall cost of skinning
                            with this strategy is averageLengthOfKey *
                            averageAmountOfComponentPerPage *
                            averageAmountOfHtmlElementPerComponent
                            (assuming each element gets its own style
                            class which is required for maximum
                            customizability). Another, but a little
                            bit more complex, solution is also
                            possible using a "dynamic enum" alike to
                            PropertyKey in Trinidad. So I'd like
                            something like:

                            public abstract class SkinKeyPart
                            {
                                public String name();

                                public int ordinal();
                            }

                            public class Namespace extends SkinKeyPart
                            {
                                /**
                                 * Find or create the Namespace
                            instance with the specified name.
                                 */
                                public static Namespace
                            getInstance(String name);
                            }

                            public class ComponentKey extends SkinKeyPart
                            {
                                /**
                                 * Find or create the ComponentKey
                            instance with the specified name.
                                 */
                                public static ComponentKey
                            getInstance(String name);
                            }

                            public class ComponentPartKey extends
                            SkinKeyPart
                            {
                                /**
                                 * Find or create the ComponentPartKey
                            instance with the specified name.
                                 */
                                public static ComponentPartKey
                            getInstance(String name);
                            }

                            public class ComponentStateKey extends
                            SkinKeyPart
                            {
                                /**
                                 * Find or create the
                            ComponentStateKey instance with the
                            specified name.
                                 */
                                public static ComponentPartKey
                            getInstance(String name);
                            }

                            public abstract class SkinNode
                            {
                                public abstract String[]
                            getStyleClasses();
                                public abstract String
                            getProperty(String propertyName);
                                public abstract Icon getIcon(String
                            iconName);
                                public abstract SkinNode
                            getSubPart(ComponentPartKey partKey);
                            }

                            public interface Skin
                            {
                                /**
                                 * Still exists to get properties
                            global to the whole skin if someone ever
                            need that feature
                                 */
                                public String getProperty(String
                            propertyName);

                                /**
                                 * No change here
                                 */
                                public String getResourceBundle();

                                public String getSkinNode(Namespace
                            ns, ComponentKey component);

                                public String getSkinNode(Namespace
                            ns, ComponentKey component,
                            ComponentStateKey state);

                                public String getSkinNode(Namespace
                            ns, ComponentKey component,
                            ComponentStateKey... states);
                            }

                            That solution has the advantage of being
                            very fast, actually a real O(1) for every
                            node access assuming the Renderer gathers
                            the keys it needs during instanciation.
                            Then the "root" SkinNode could probably be
                            located using a base Renderer class and
                            passed to a custom encoding method
                            (Trinidad's encodeAll for example). Of
                            course, the skin loaders would have to
                            create skin instances structuring the
                            selectors accordingly. A base class for
                            Skin with such feature should probably be
                            provided if this solution is wanted in
                            order to make new implementation of Skin
                            easier to create.

                            *PENDIND issues:*
                            PENDING: Should the path leverage the
                            Resource API instead and receive a
                            library-name, library-version,
                            resource-name and resource-version instead?

                            PENDING: A CompositeSkin class should
                            probably be provided and most likely
                            usable from the configuration, should it
                            be using a specific loader with parameters
                            or have a fully-fledged tag like
                            <composite-skin> for example? The use of
                            such skin implementation would be for
                            users using multiple libraries, each with
                            very different RenderKit implementations.
                            A composite RenderKit class could also be
                            useful here.

                            PENDING: Should Trinidad's SkinAddition
                            notion be considered? SkinAddition
                            provides a way to add skin elements to an
                            existing skin based on its id. It would be
                            possible to leverage that by using the
                            skin-family/render-kit-id tuple instead.
                            Another option would be to simply have the
                            default SkinFactory implementation to
                            automatically agreggate the Skin instances
                            with the same skin-family and
                            render-kit-id into a CompositeSkin instance.

                            PENDING: Should additional metadata be
                            added to <renderer> tag to define the
                            supported skin selector for tooling
                            purpose? This point is dependant on the
                            content of the Skin interface and the
                            strategy chosen to access the
                            properties/style class of a given
                            component and/or one of its sub-element.

                            PENDING: Should the effective CSS
                            properties stay accessible in memory or
                            otherwise from the Skin instance? If so,
                            should they be modifiable? I tend toward
                            no for both for performance issues. Of
                            course this could be also left as an
                            optional operation of the interface,
                            throwing UnsupportedOperationException in
                            most case but at least leaving the
                            possibility for special implementations
                            requiring it. This point also impact issue
                            2 in some ways.

                            PENDING: About Icon, it should probably
                            also leverage the Resource API, how should
                            that be implemented?

                            PENDING: Icon's styleClass, should the
                            instance directly return an effective
                            class or should it rather return a
                            selector that would then be looked up from
                            the Skin? I prefer the latter, but then
                            there's the Stirng issue so maybe the icon
                            would have to return an optimized selector
                            key as mentioned in 3.1

                            PENDING: Solution to issue 3.1, although
                            very fast and flexible, can be an linkage
                            nightmare. For example, a node for
                            component "inputText" with states
                            "disabled" and "required" should be able
                            to link to the component part node for
                            part "label" of "inputText" without any
                            state defined if needed. The performance
                            gain of 3.1 is great, the implementation
                            complexity isn't. Still, personally I
                            don't have any problem throwing complexity
                            at implementor's head if the users can
                            feel the difference. Another option would
                            be to remove the "state" complexity part
                            and have a predefined style class syntax
                            for those. That solution is what Trinidad
                            does. However, this solution is not as
                            flexible as it doesn't allow to switch
                            Icon dynamically depending on the
                            component's state.

                            PENDING: Solution 3.1 don't allow state to
                            be applied on the component's sub parts.
                            Most of the time it's not an issue, but we
                            have one such use case with Trinidad's
                            train component where the train itself
                            doesn't have a state, but each of its
                            station (sub-part) can be
                            visited/unvisited and/or selected and/or
                            disabled. If 3.1 is kept, should it be
                            tweaked even more to allow a sub-part
                            state on a per part basis as well? This
                            makes the linkage a nightmare on Elm
                            Street candidate, althoguh adding more
                            potential to the Skin

                            PENDING: Trinidad supports a "selector
                            redirect" feature that is used with the
                            delegate renderer architecture to have
                            specified selectorKeys transformed into a
                            different one. This is implemented as a
                            Map<String oldName, String newName>
                            redirection map. Should such feature be
                            standardized? If so and 3.1 is adressed
                            then it will have to be well thought
                            about. Also, trinidad support a single of
                            those map applied as a set on the skin
                            instance, I believe it should be a push /
                            pop instead if standardized.

                            PENDING: Should there be any
                            inheritance/cascading behavior defined by
                            default? I tend toward no here.

                            PENDING: Should the skin have a
                            getTranslatedResource(FacesContext
                            context, String resourceKey) instead of
                            the getResourceBundle method?


                            That's about it for now. My main blocker
                            is 3.1 and I'd like to come up with
                            something better for it before presenting
                            it to the EG, same holds true with various
                            links to the Resource API (icons, the skin
                            itself, etc)


                            Regards,

                            ~ Simon



                            On Fri, Dec 5, 2008 at 10:33 AM, Andrew
                            Robinson <[EMAIL PROTECTED]
                            <mailto:[EMAIL PROTECTED]>> wrote:

                                > All other frameworks use
                                > component attributes for this, but
                                Trinidad puts it in these
                                > non-intuitive skinning keys.

                                Sorry, had one more comment right
                                after I hit send again. Maybe just
                                having default component attributes
                                for a web app would satisfy the
                                need. Like a way to say
                                'partialSumbit' should be defaulted to
                                true on
                                all tr:commandLink. Then all the skin
                                properties could be converted to
                                attributes and have their defaults set
                                in a common location (like what
                                the skin does).

                                This would be much more useful and
                                flexible as then page developers
                                can make exceptions to the rule.






--
                    http://www.irian.at

                    Your JSF powerhouse -
                    JSF Consulting, Development and
                    Courses in English and German

                    Professional Support for Apache MyFaces





--
            http://www.irian.at

            Your JSF powerhouse -
            JSF Consulting, Development and
            Courses in English and German

            Professional Support for Apache MyFaces





--
    http://www.irian.at

    Your JSF powerhouse -
    JSF Consulting, Development and
    Courses in English and German

    Professional Support for Apache MyFaces


Reply via email to