Click here to Skip to main content
15,884,836 members
Articles / Web Development / CSS

Combres - WebForm & MVC Client-side Resource Combine Library

Rate me:
Please Sign up or sign in to vote.
4.50/5 (8 votes)
1 Nov 2009Apache13 min read 52.1K   3.1K   22  
A .NET library which enables minification, compression, combination, and caching of JavaScript and CSS resources for ASP.NET and ASP.NET MVC web applications. Simply put, it helps your applications rank better with YSlow and PageSpeed.
#region License
// Copyright 2009 Buu Nguyen (http://www.buunguyen.net/blog)
// 
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
// 
// http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License.
// 
// The latest version of this file can be found at http://combres.codeplex.com
#endregion

using System;
using System.Text.RegularExpressions;
using log4net;

namespace Combres.Filters
{
    /// <summary>
    /// Filter which modifies relative urls to absolute urls (works for both virtual directory 
    /// as well as website).
    /// 
    /// Assume the path of the CSS file is ~/content/site.css, then the following transformations
    /// are done to each url reference in the CSS file:
    /// 1. Absolute path                ->      keep as-is
    ///       /path/to/image.gif        ->      /path/to/image.gif
    /// 2. Relative from CSS location   ->      make relative to application root
    ///       path/to/image.gif         ->      /content/path/to/imag2.gif 
    ///       ../path/to/style1.css     ->      /path/to/style1.css
    /// 3. Starting from application root
    ///     * ~/path/to/style2.css      ->      /content/path/to/style2.css
    /// 
    /// See http://combres.codeplex.com/Thread/View.aspx?ThreadId=64366 for error  description.
    /// </summary>
    public class FixUrlsInCssFilter : ICombresFilter
    {
        private static readonly ILog Log = LogManager.GetLogger(
                       System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public string TransformSingleContent(Settings settings, Resource resource, string content)
        {
            if (resource.ParentSet.Type == ResourceType.CSS)
                return Regex.Replace(content, @"url\((?<url>.*?)\)", 
                    match => FixUrl(resource.Path, match),
                    RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture);
            return content;
        }

        private static string FixUrl(string cssPath, Match match)
        {
            try
            {
                const string template = "url(\"{0}\")";
                var url = match.Groups["url"].Value.Trim('\"', '\'');
                if (url.StartsWith("/"))
                    return string.Format(template, url);
                if (url.StartsWith("~"))
                    return string.Format(template, url.ResolveUrl());

                var cssFolder = cssPath.Substring(0, cssPath.LastIndexOf("/"));
                var backFolderCount = Regex.Matches(url, @"\.\./").Count;
                for (int i = 0; i < backFolderCount; i++)
                {
                    url = url.Substring(3); // skip 1 '../'
                    cssFolder = cssFolder.Substring(0, cssFolder.LastIndexOf("/")); // move back 1 folder
                }
                return string.Format(template, (cssFolder + "/" + url).ResolveUrl());
            }
            catch (Exception ex)
            {
                // Be lenient here, only log.  After all, this is just an image in the CSS file
                // and it should't be the reason to stop loading that CSS file.
                if (Log.IsWarnEnabled) 
                    Log.Warn("Cannot fix url " + match.Value, ex);
                return match.Value;
            }
        }

        public string TransformCombinedContent(Settings settings, ResourceSet set, string content)
        {
            return content;
        }

        public string TransformMinifiedContent(Settings settings, ResourceSet set, string content)
        {
            return content;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0


Written By
Chief Technology Officer KMS Technology
Vietnam Vietnam
You can visit Buu's blog at http://www.buunguyen.net/blog to read about his thoughts on software development.

Comments and Discussions