ICEfaces
  1. ICEfaces
  2. ICE-5749

Sparkle: Require CSS resource loading solution with better alignment with std. YUI resource URLs

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0-Alpha3
    • Fix Version/s: 2.0-Beta2, 2.0.0
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      ICEfaces 2.0 Glimmer with Sparkle YUI components.
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.), Sample App./Tutorial

      Description

      The Sparkle components will identify (and load) their resources via the @ResourceDependency annotation.

      This is working as expected for .js files, and they are downloaded from the local library.

      However, there's an issue with the CSS files: the problem is that all local CSS files from the YUI library don't have it's image URLs in the JSF format. For example, slider.css has something like this:

         background-image:url(rail-x.png);

      Instead of something like this:

         background-image:url(rail-x.png.jsf?ln=yui/3_1_1);

      So the actual image file cannot be reached. I think we will have to parse all CSS files to add this suffix, so that all URLs are in JSF format, but doing so will add a cumbersome step to our ongoing maintenance of the YUI-based code in Sparkle.

      We should identify a better solution that does not require modifying all the std. YUI CSS files, if possible.

        Activity

        Hide
        Ted Goddard added a comment -

        CSS can be preprocessed at the component generation stage. Note that it is also useful to concatenate and minify CSS at this stage as well.

        Show
        Ted Goddard added a comment - CSS can be preprocessed at the component generation stage. Note that it is also useful to concatenate and minify CSS at this stage as well.
        Hide
        Ted Goddard added a comment -

        Looks like the JSF-recommended solution is relying on EL expansion in CSS:

        http://forums.java.net/jive/thread.jspa?messageID=374172

        Show
        Ted Goddard added a comment - Looks like the JSF-recommended solution is relying on EL expansion in CSS: http://forums.java.net/jive/thread.jspa?messageID=374172
        Hide
        Ken Fyten added a comment -

        As the actual extension mapping in use is configurable (.jsf, .iface, etc.) it is not possible to pre-generate the correct URLs in the CSS files.

        After much discussion it appeared that using just the FacesServlet mapping to serve CSS resources would be difficult given the URLs embedded within the CSS files themselves.

        Apparently, the JSF 2.0 solution to this is to evaluate EL as the CSS is being served:

        http://forums.java.net/jive/thread.jspa?messageID=374172

        For instance:

        background: #ccccff url(#

        {resource['components/img/table_sort_none.gif']}

        ) no-repeat center left;

        Given that this is the intended approach in JSF 2.0, we should attempt to apply this before developing a proprietary resource handling mechanism.

        The natural objection to the above approach is that performance will suffer due to extensive EL evaluation. It's likely that this can be resolved via a caching strategy within JSF (cache the processed output of certain resource requests) together with caching within the browser (CSS files do not change frequently), but if we are concerned, we should first gather profiling data. (Performing string replacement on the CSS adds very little overhead to the byte copying that needs to take place anyway, so if EL evaluation for #

        {resource}

        is optimized, it's possible that there is no need for concern here.)

        Ted.

        Show
        Ken Fyten added a comment - As the actual extension mapping in use is configurable (.jsf, .iface, etc.) it is not possible to pre-generate the correct URLs in the CSS files. After much discussion it appeared that using just the FacesServlet mapping to serve CSS resources would be difficult given the URLs embedded within the CSS files themselves. Apparently, the JSF 2.0 solution to this is to evaluate EL as the CSS is being served: http://forums.java.net/jive/thread.jspa?messageID=374172 For instance: background: #ccccff url(# {resource['components/img/table_sort_none.gif']} ) no-repeat center left; Given that this is the intended approach in JSF 2.0, we should attempt to apply this before developing a proprietary resource handling mechanism. The natural objection to the above approach is that performance will suffer due to extensive EL evaluation. It's likely that this can be resolved via a caching strategy within JSF (cache the processed output of certain resource requests) together with caching within the browser (CSS files do not change frequently), but if we are concerned, we should first gather profiling data. (Performing string replacement on the CSS adds very little overhead to the byte copying that needs to take place anyway, so if EL evaluation for # {resource} is optimized, it's possible that there is no need for concern here.) Ted.
        Hide
        Ken Fyten added a comment -

        Hopefully it's a straightforward mod to smart sprites code, to get it to see
        url(#

        {resource['components/img/table_sort_none.gif']}

        )

        and then ignore the parts between the brackets and the quotes

        #

        {resource[' ']}

        )

        and just use what's inside the quotes

        components/img/table_sort_none.gif

        and then output the new path, but together with the stuff it stripped out before

        #

        {resource[' components/img/sprite-x.gif ']}

        )

        all back together

        url(#

        {resource['components/img/sprite-x.gif']}

        )

        • Mark
        Show
        Ken Fyten added a comment - Hopefully it's a straightforward mod to smart sprites code, to get it to see url(# {resource['components/img/table_sort_none.gif']} ) and then ignore the parts between the brackets and the quotes # {resource[' ']} ) and just use what's inside the quotes components/img/table_sort_none.gif and then output the new path, but together with the stuff it stripped out before # {resource[' components/img/sprite-x.gif ']} ) all back together url(# {resource['components/img/sprite-x.gif']} ) Mark
        Hide
        Ken Fyten added a comment -

        Ok, I think we're closer to a good solution. I'm going to paraphrase what I understand from the meeting conclusions and "fill in the blanks" the parts that were left open/pending for analysis.

        • We will only commit CSS and image files inside each component source directory, using non-JSF URL formats.
        • We will add @ResourceDependency annotations in the component Java source files for the required CSS files, which will be under the /resource directory (so that they can be served by the JSF resource handling system).
          This CSS file will have the same name and path whether it uses sprites or individual images.

        For example,
        @ResourceDependency(name="skins/sam/button.css", library="org.icefaces.component.button")

        By accessing this resource from a browser, a CSS file will be served that will be making use of either sprites or individual images DEPENDING on what was done at build-time.

        • We will modify the build tool to either generate sprites OR use individual images AND then run the URL tool on the resulting CSS files (i.e. the ones generated by SmartSprites or just the ones in the source directories) AND the output of this process will be placed in the respective component library and will have the same name and relative path, regardless of whether sprites are used or not.
        • * *

        I analyzed what can be done with Ant, and concluded that this is feasible.

        We could add a property called 'use.sprites' to the 'build.properties' file. If it is set, we will generate sprites and run the URL tool on the output of SmartSprites, otherwise we will simply run the tool directly on the source files.

        Right now, all the output of SmartSprites is placed inside the same directory, but it could be possible to separate this output to different component resource libraries by adding a few more declarations in the build script.

        Show
        Ken Fyten added a comment - Ok, I think we're closer to a good solution. I'm going to paraphrase what I understand from the meeting conclusions and "fill in the blanks" the parts that were left open/pending for analysis. We will only commit CSS and image files inside each component source directory, using non-JSF URL formats. We will add @ResourceDependency annotations in the component Java source files for the required CSS files, which will be under the /resource directory (so that they can be served by the JSF resource handling system). This CSS file will have the same name and path whether it uses sprites or individual images. For example, @ResourceDependency(name="skins/sam/button.css", library="org.icefaces.component.button") By accessing this resource from a browser, a CSS file will be served that will be making use of either sprites or individual images DEPENDING on what was done at build-time. We will modify the build tool to either generate sprites OR use individual images AND then run the URL tool on the resulting CSS files (i.e. the ones generated by SmartSprites or just the ones in the source directories) AND the output of this process will be placed in the respective component library and will have the same name and relative path, regardless of whether sprites are used or not. * * I analyzed what can be done with Ant, and concluded that this is feasible. We could add a property called 'use.sprites' to the 'build.properties' file. If it is set, we will generate sprites and run the URL tool on the output of SmartSprites, otherwise we will simply run the tool directly on the source files. Right now, all the output of SmartSprites is placed inside the same directory, but it could be possible to separate this output to different component resource libraries by adding a few more declarations in the build script.
        Hide
        Arturo Zambrano added a comment -

        this was solved with the creation of the cssurlmapper utility, and its integration in the build script.

        Show
        Arturo Zambrano added a comment - this was solved with the creation of the cssurlmapper utility, and its integration in the build script.

          People

          • Assignee:
            Arturo Zambrano
            Reporter:
            Ken Fyten
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: