On Tue, Dec 9, 2008 at 2:23 PM, Gerhard Petracek
<[EMAIL PROTECTED]> wrote:
> hello,
>
> concerning the accessibility mode: is trinidad tested with real
> screen-readers?

we use jaws

> furthermore, we should specify if we are talking about skinning or theming.
>
> regards,
> gerhard
>
>
>
> 2008/12/9 Paul Rivera <[EMAIL PROTECTED]>
>>
>> Hi,
>>
>> I agree with Jeanne as well regarding the requirements.  This has been the
>> list of requirements we've used as a guide in building the skinning
>> project.  Maybe we can use this as a starting point.  Feel free to modify
>> the list.
>>
>> from trinidad:
>> * basic css style skinning
>> * global styles/aliases
>> * skin extensions
>> * skin additions for custom component developers
>> * properties skinning
>> * icon skinning
>> * text skinning / translations
>>   - using bundle-name
>>   - using translation-source
>> * skin variants based on:
>>   - agent name
>>   - agent version
>>   - platform name
>>   - accessibility-profile
>>   - direction (:rtl)
>>   - locale (@locale, :lang) -> Accdg to the skinning guide, this is not
>> yet implemented in trinidad
>> * dynamically changing skins at runtime
>> * compressed styleclass names feature
>> * CHECK_FILE_MODIFICATION feature
>> * And as Jeanne mentioned, compatibility with portals.  I don't have much
>> experience with portals.  I will probably need to look more into this.
>>
>> added requirements:
>> * tomahawk-support: make use of AddResource and ExtensionsFilter
>> * generic-support
>>
>> As for simon's issue on style class / property / icon access strategy
>> (sub-issue 3.1), I've read somewhere that hashcode is already cached in
>> String since java 1.3.  I've not really verified this on java 1.3.  But I
>> did check on jdk 1.6 and confirmed that it does cache hashcode.  Here's the
>> snippet fro java.lang.String:
>>
>>     public int hashCode() {
>>     int h = hash;
>>     if (h == 0) {
>>         int off = offset;
>>         char val[] = value;
>>         int len = count;
>>
>>             for (int i = 0; i < len; i++) {
>>                 h = 31*h + val[off++];
>>             }
>>             hash = h;
>>         }
>>         return h;
>>     }
>>
>> Best Regards,
>> Paul Rivera
>>
>> --- On Tue, 12/9/08, Matthias Wessendorf <[EMAIL PROTECTED]> wrote:
>>
>> From: Matthias Wessendorf <[EMAIL PROTECTED]>
>> Subject: Re: [Skinning] Independent skinning myfaces subproject
>> To: "MyFaces Development" <[email protected]>
>> Date: Tuesday, December 9, 2008, 12:52 AM
>>
>> On Tue, Dec 9, 2008 at 1:03 AM, Jeanne Waldman
>> <[EMAIL PROTECTED]> wrote:
>> >
>>  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.
>>
>> +1
>> good point, Jeanne, we don't want to see that work destroyed.
>>
>> -M
>>
>>
>> >
>> > 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 nightma
>>
>> >
>> > ...
>> >
>> > [Message
>>  clipped]
>>
>>
>>
>> --
>> Matthias Wessendorf
>>
>> blog: http://matthiaswessendorf.wordpress.com/
>> sessions: http://www.slideshare.net/mwessendorf
>>
>> twitter: http://twitter.com/mwessendorf
>>
>
>
>
> --
>
> http://www.irian.at
>
> Your JSF powerhouse -
> JSF Consulting, Development and
> Courses in English and German
>
> Professional Support for Apache MyFaces
>



-- 
Matthias Wessendorf

blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf

Reply via email to