javacssjawr

How do I stop Jawr processing some parts of CSS files?


I am currently using Jawr to compress and bundle my css, javascript and image files.

Jawr is currently converting all of the url() links in my css files, regardless whether they are images or not. For example:

@font-face {
    font-family: 'NothingYouCouldSay';
    src: url('../fonts/NothingYouCouldSay.eot') format('eot');
    src: local("☺"), url('../fonts/NothingYouCouldSay.woff') format('woff'), url("../fonts/NothingYouCouldSay.otf") format("opentype"), url('../fonts/NothingYouCouldSay.ttf') format('truetype'), url('../fonts/NothingYouCouldSay.svg') format('svg');
    font-weight: normal;
    font-style: normal;
}

Jawr is converting all of the url() values, but then the resources cannot be found when the webserver is running, as I have configured the image servlet to listen only for *.png & *.jpg.

@font-face {
    font-family: 'NothingYouCouldSay';
    src: url('../../../cb1130234589/resources/fonts/NothingYouCouldSay.eot') format('eot');
    src: local("☺"), url('../../../cb1130234589/resources/fonts/NothingYouCouldSay.woff') format('woff'), url("../../../cb1130234589/resources/fonts/NothingYouCouldSay.otf") format("opentype"), url('../../../cb1130234589/resources/fonts/NothingYouCouldSay.ttf') format('truetype'), url('../../../cb1130234589/resources/fonts/NothingYouCouldSay.svg') format('svg');
    font-weight: normal;
    font-style: normal;
}

If I add *.woff to the image servlet mapping, then the servlet complains that the mime type of the file is not understood.

Is there any way I can get Jawr to not process these particular particular URLs?


Solution

  • So, after trying a few different ideas, I ended up writing my own custom post processor to handle this. I reuse as much of the existing Jawr code as possible, which means it may be quite brittle if Jawr changes it's underlying code.

    Anyway, here's what I wrote:

    package com.bullethq.jawr.postprocessor;
    
    import net.jawr.web.resource.FileNameUtils;
    import net.jawr.web.resource.bundle.factory.util.PathNormalizer;
    import net.jawr.web.resource.bundle.postprocess.BundleProcessingStatus;
    import net.jawr.web.resource.bundle.postprocess.impl.CSSURLPathRewriterPostProcessor;
    import net.jawr.web.resource.bundle.postprocess.impl.PostProcessorCssImageUrlRewriter;
    
    import java.io.IOException;
    
    public class CustomCssUrlPathRewriterPostProcessor extends CSSURLPathRewriterPostProcessor {
    
        public static final String CUSTOM_URL_PATH_REWRITER = "customcsspathrewriter";
    
        public CustomCssUrlPathRewriterPostProcessor() {
            super(CUSTOM_URL_PATH_REWRITER);
        }
    
        // ========================================================================
        // ========================================================================
        // ========================================================================
        @Override
        protected PostProcessorCssImageUrlRewriter createImageUrlRewriter(BundleProcessingStatus status) {
            return new CustomPostProcessorCssImageUrlRewriter(status);
        }
    
        // ========================================================================
        // ========================================================================
        // ========================================================================
        public class CustomPostProcessorCssImageUrlRewriter extends PostProcessorCssImageUrlRewriter {
    
            public CustomPostProcessorCssImageUrlRewriter(BundleProcessingStatus status) {
                super(status);
            }
    
            // ========================================================================
            // ========================================================================
            // ========================================================================
            @Override
            protected String getUrlPath(String match, String originalPath, String newCssPath) throws IOException {
                String url = match.substring(match.indexOf('(') + 1, match.lastIndexOf(')')).trim();
    
                // Remove any quotes if necessary.
                String quoteStr = "";
                if (url.startsWith("'") || url.startsWith("\"")) {
                    quoteStr = String.valueOf(url.charAt(0));
                    url = url.substring(1, url.length() - 1);
                }
    
                // We now check if the url ends in a known image file extension
                // If not, the url is ignored.
                if (FileNameUtils.hasImageExtension(url)) {
                    return super.getUrlPath(match, originalPath, newCssPath);
                } else {
                    // We need to rewrite the path, as any relative URLs will
                    // not resolve correctly if Jawr has changed the CSS path.
                    url = PathNormalizer.concatWebPath(originalPath, url);
                    url = PathNormalizer.getRelativeWebPath(PathNormalizer.getParentPath(newCssPath), url);
                    return "url(" + quoteStr + url + quoteStr + ")";
                }
            }
        }
    }
    

    And then, you need to configure Jawr to use this custom post processor in jawr.properties:

    jawr.custom.postprocessors.customcsspathrewriter.class=com.bullethq.jawr.postprocessor.CustomCssUrlPathRewriterPostProcessor
    jawr.css.bundle.factory.filepostprocessors=customcsspathrewriter