Exemple #1
0
        /// <summary>
        /// The crunch css.
        /// </summary>
        /// <param name="configuration">
        /// The configuration.
        /// </param>
        private static void Crunch(ConsoleConfiguration configuration)
        {
            // Get the currently operating directory.
            // http://stackoverflow.com/questions/52797/how-do-i-get-the-path-of-the-assembly-the-code-is-in
            string directoryName = Path.GetDirectoryName(configuration.InputPath);
            string rootFolder    = Path.IsPathRooted(directoryName) ? directoryName : AppDomain.CurrentDomain.BaseDirectory;
            string fileName      = configuration.InputPath;

            if (!string.IsNullOrWhiteSpace(fileName) && !string.IsNullOrWhiteSpace(rootFolder))
            {
                string actualInputPath = Path.GetFullPath(Path.Combine(rootFolder, fileName));
                string outputPath      = GetOutPutPath(
                    rootFolder,
                    actualInputPath,
                    configuration.OutputPath,
                    configuration.TargetType,
                    configuration.Minify);

                CruncherOptions options = new CruncherOptions
                {
                    Minify           = configuration.Minify,
                    AllowRemoteFiles = true,
                    RootFolder       = Path.GetDirectoryName(actualInputPath)
                };

                string crunched;

                if (configuration.TargetType == CrunchTargetType.CSS)
                {
                    CssCruncher cssCruncher = new CssCruncher(options);
                    crunched = cssCruncher.Crunch(actualInputPath);
                    crunched = cssCruncher.Minify(crunched);
                }
                else
                {
                    JavaScriptCruncher javaScriptCruncher = new JavaScriptCruncher(options);
                    crunched = javaScriptCruncher.Crunch(actualInputPath);
                    crunched = javaScriptCruncher.Minify(crunched);
                }

                FileHelper.WriteFile(outputPath, crunched);
            }
        }
        /// <summary>
        /// Processes the css request using cruncher and returns the result.
        /// </summary>
        /// <param name="context">
        /// The current context.
        /// </param>
        /// <param name="minify">
        /// Whether to minify the output.
        /// </param>
        /// <param name="paths">
        /// The paths to the resources to crunch.
        /// </param>
        /// <returns>
        /// The <see cref="string"/> representing the processed result.
        /// </returns>
        public async Task<string> ProcessCssCrunchAsync(HttpContext context, bool minify, params string[] paths)
        {
            string combinedCSS = string.Empty;

            if (paths != null)
            {
                string key = string.Join(string.Empty, paths).ToMd5Fingerprint();

                using (await Locker.LockAsync(key))
                {
                    combinedCSS = (string)CacheManager.GetItem(key);

                    if (string.IsNullOrWhiteSpace(combinedCSS))
                    {
                        StringBuilder stringBuilder = new StringBuilder();

                        CruncherOptions cruncherOptions = new CruncherOptions
                        {
                            MinifyCacheKey = key,
                            Minify = minify,
                            CacheFiles = true,
                            AllowRemoteFiles = CruncherConfiguration.Instance.AllowRemoteDownloads,
                            RemoteFileMaxBytes = CruncherConfiguration.Instance.MaxBytes,
                            RemoteFileTimeout = CruncherConfiguration.Instance.Timeout
                        };

                        CssCruncher cssCruncher = new CssCruncher(cruncherOptions, context);

                        AutoPrefixerOptions autoPrefixerOptions = CruncherConfiguration.Instance.AutoPrefixerOptions;

                        // Loop through and process each file.
                        foreach (string path in paths)
                        {
                            // Local files.
                            if (PreprocessorManager.Instance.AllowedExtensionsRegex.IsMatch(path))
                            {
                                List<string> files = new List<string>();

                                // Try to get the file by absolute/relative path
                                if (!ResourceHelper.IsResourceFilenameOnly(path))
                                {
                                    string cssFilePath = ResourceHelper.GetFilePath(
                                        path,
                                        cruncherOptions.RootFolder,
                                        context);

                                    if (File.Exists(cssFilePath))
                                    {
                                        files.Add(cssFilePath);
                                    }
                                }
                                else
                                {
                                    // Get the path from the server.
                                    // Loop through each possible directory.
                                    foreach (string cssPath in CruncherConfiguration.Instance.CSSPaths)
                                    {
                                        if (!string.IsNullOrWhiteSpace(cssPath) && cssPath.Trim().StartsWith("~/"))
                                        {
                                            DirectoryInfo directoryInfo = new DirectoryInfo(context.Server.MapPath(cssPath));

                                            if (directoryInfo.Exists)
                                            {
                                                IEnumerable<FileInfo> fileInfos =
                                                    await
                                                    directoryInfo.EnumerateFilesAsync(path, SearchOption.AllDirectories);
                                                    files.AddRange(fileInfos.Select(f => f.FullName));
                                            }
                                        }
                                    }
                                }

                                if (files.Any())
                                {
                                    // We only want the first file.
                                    string first = files.FirstOrDefault();
                                    cruncherOptions.RootFolder = Path.GetDirectoryName(first);
                                    stringBuilder.Append(await cssCruncher.CrunchAsync(first));
                                }
                            }
                            else
                            {
                                // Remote files.
                                string remoteFile = this.GetUrlFromToken(path).ToString();
                                stringBuilder.Append(await cssCruncher.CrunchAsync(remoteFile));
                            }
                        }

                        combinedCSS = stringBuilder.ToString();

                        // Apply autoprefixer
                        combinedCSS = cssCruncher.AutoPrefix(combinedCSS, autoPrefixerOptions);

                        if (minify)
                        {
                            combinedCSS = cssCruncher.Minify(combinedCSS);
                        }

                        this.AddItemToCache(key, combinedCSS, cssCruncher.FileMonitors);
                    }
                }
            }

            return combinedCSS;
        }
Exemple #3
0
        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler" /> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext" /> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
        public override void ProcessRequest(HttpContext context)
        {
            HttpRequest request = context.Request;
            string      path    = request.QueryString["path"];
            string      key     = path.ToMd5Fingerprint();
            bool        fallback;
            bool        minify = bool.TryParse(request.QueryString["minify"], out fallback);

            if (!string.IsNullOrWhiteSpace(path))
            {
                minify = minify || CruncherConfiguration.Instance.MinifyCSS;
                string combinedCSS = (string)CacheManager.GetItem(key);

                if (string.IsNullOrWhiteSpace(combinedCSS))
                {
                    string[]      cssFiles      = path.Split('|');
                    StringBuilder stringBuilder = new StringBuilder();

                    CruncherOptions cruncherOptions = new CruncherOptions
                    {
                        MinifyCacheKey     = path,
                        Minify             = minify,
                        AllowRemoteFiles   = CruncherConfiguration.Instance.AllowRemoteDownloads,
                        RemoteFileMaxBytes = CruncherConfiguration.Instance.MaxBytes,
                        RemoteFileTimeout  = CruncherConfiguration.Instance.Timeout
                    };

                    cruncherOptions.CacheFiles  = cruncherOptions.Minify;
                    cruncherOptions.CacheLength = cruncherOptions.Minify ? CruncherConfiguration.Instance.MaxCacheDays : 0;
                    minify = cruncherOptions.Minify;

                    this.cssCruncher = new CssCruncher(cruncherOptions);

                    // Loop through and process each file.
                    foreach (string cssFile in cssFiles)
                    {
                        // Local files.
                        if (PreprocessorManager.Instance.AllowedExtensionsRegex.IsMatch(cssFile))
                        {
                            // Get the path from the server.
                            // Loop through each possible directory.
                            List <string> files = new List <string>();

                            foreach (string cssFolder in CruncherConfiguration.Instance.CSSPaths)
                            {
                                if (!string.IsNullOrWhiteSpace(cssFolder) && cssFolder.StartsWith("~/"))
                                {
                                    string actual = HttpContext.Current.Server.MapPath(cssFolder);

                                    if (actual != null)
                                    {
                                        files.AddRange(Directory.GetFiles(actual, cssFile, SearchOption.AllDirectories));
                                    }
                                }
                            }

                            // We only want the first file.
                            string first = files.FirstOrDefault();
                            cruncherOptions.RootFolder = Path.GetDirectoryName(first);
                            stringBuilder.Append(this.cssCruncher.Crunch(first));
                        }
                        else
                        {
                            // Remote files.
                            string remoteFile = this.GetUrlFromToken(cssFile).ToString();
                            stringBuilder.Append(this.cssCruncher.Crunch(remoteFile));
                        }
                    }

                    combinedCSS = this.cssCruncher.Minify(stringBuilder.ToString());
                }

                if (!string.IsNullOrWhiteSpace(combinedCSS))
                {
                    IList <string> fileMonitors;

                    // Configure response headers
                    if (this.cssCruncher == null)
                    {
                        // There should always be a valid list of monitors in the cache.
                        fileMonitors = (List <string>)CacheManager.GetItem(key + "_FILE_MONITORS");
                    }
                    else
                    {
                        fileMonitors = this.cssCruncher.FileMonitors;
                    }

                    // Configure response headers
                    this.SetHeaders(path, context, ResponseType.Css, minify, fileMonitors);
                    context.Response.Write(combinedCSS);

                    // Compress the response if applicable.
                    if (CruncherConfiguration.Instance.CompressResources)
                    {
                        CompressionModule.CompressResponse(context);
                    }
                }
                else
                {
                    context.Response.StatusCode        = (int)HttpStatusCode.NotFound;
                    context.Response.StatusDescription = HttpStatusCode.NotFound.ToString();
                }
            }
        }