internal MinifyCssResult Process(ContentItem contentItem, FileHasherActivity imageHasher = null) { if (imageHasher != null) { this.availableSourceImages = this.context.GetAvailableFiles(this.context.Configuration.SourceDirectory, this.ImageDirectories, this.ImageExtensions, FileTypes.Image); } var cssContent = contentItem.Content; var minifiedContentItems = new BlockingCollection <ContentItem>(); var hashedImageContentItems = new BlockingCollection <ContentItem>(); var spritedImageContentItems = new BlockingCollection <ContentItem>(); var mergedResources = ResourcePivotActivity.GetUsedGroupedResources(cssContent, this.MergedResources); var dpiValues = this.Dpi; if (dpiValues == null || !dpiValues.Any()) { dpiValues = new HashSet <float>(new[] { 1f }); } var pivots = GetMinifyCssPivots(contentItem, dpiValues, mergedResources, this.DpiResources).ToArray(); var nonIgnoredPivots = pivots.Where(p => !this.context.TemporaryIgnore(p.NewContentResourcePivotKeys)).ToArray(); var parsedStylesheetNode = CssParser.Parse(this.context, cssContent, false); this.context.ParallelForEach( item => new[] { SectionIdParts.MinifyCssActivity }, nonIgnoredPivots, (threadContext, pivot, parallelLoopState) => { ContentItem minifiedContentItem = null; var resourceContentItem = ContentItem.FromContent(contentItem.Content, pivot.NewContentResourcePivotKeys); var result = threadContext .SectionedAction(SectionIdParts.MinifyCssActivity, SectionIdParts.Process) .MakeCachable(resourceContentItem, this.GetVarBySettings(imageHasher, pivot.NewContentResourcePivotKeys, pivot.MergedResource)) .RestoreFromCacheAction(cacheSection => { minifiedContentItem = cacheSection.GetCachedContentItem(CacheFileCategories.MinifiedCssResult, contentItem.RelativeContentPath, contentItem.AbsoluteDiskPath, pivot.NewContentResourcePivotKeys); hashedImageContentItems.AddRange(cacheSection.GetCachedContentItems(CacheFileCategories.HashedImage)); spritedImageContentItems.AddRange(cacheSection.GetCachedContentItems(CacheFileCategories.HashedSpriteImage)); if (minifiedContentItem == null) { context.Log.Error("Css minify cache result is null"); return(false); } if (spritedImageContentItems.Any(hi => hi == null)) { context.Log.Error("Sprited image cache result is null"); return(false); } if (hashedImageContentItems.Any(hi => hi == null)) { context.Log.Error("Hashed image cache result is null"); return(false); } return(true); }) .Execute(cacheSection => { try { // Apply all configured visitors, including, validating, optimizing, minifying and spriting. // Applying of resources var stylesheetNode = ApplyResources(parsedStylesheetNode, pivot.MergedResource, threadContext) as StyleSheetNode; // Validation stylesheetNode = this.ApplyValidation(stylesheetNode, threadContext) as StyleSheetNode; // Optimization stylesheetNode = this.ApplyOptimization(stylesheetNode, threadContext) as StyleSheetNode; // Spriting stylesheetNode = this.ApplySpriting(stylesheetNode, pivot.Dpi, spritedImageContentItems, threadContext) as StyleSheetNode; // Output css as string var processedCssContent = threadContext.SectionedAction(SectionIdParts.MinifyCssActivity, SectionIdParts.PrintCss).Execute(() => this.ShouldMinify ? stylesheetNode.MinifyPrint() : stylesheetNode.PrettyPrint()); // TODO: Hash the images on the styielsheetnode not on the css result. // Hash images on the result css if (imageHasher != null) { var hashResult = HashImages(processedCssContent, imageHasher, cacheSection, threadContext, this.availableSourceImages, this.MissingImageUrl); processedCssContent = hashResult.Item1; hashedImageContentItems.AddRange(hashResult.Item2); } minifiedContentItem = ContentItem.FromContent(processedCssContent, this.DestinationFile, null, pivot.NewContentResourcePivotKeys); cacheSection.AddResult(minifiedContentItem, CacheFileCategories.MinifiedCssResult); } catch (Exception ex) { context.Log.Error(ex, ex.ToString()); return(false); } return(true); }); Safe.Lock(minifiedContentItems, () => minifiedContentItems.Add(minifiedContentItem)); if (!result) { context.Log.Error("An errror occurred while minifying '{0}' with resources '{1}'".InvariantFormat(contentItem.RelativeContentPath, pivot)); } return(result); }); return(new MinifyCssResult( minifiedContentItems, spritedImageContentItems.DistinctBy(hi => hi.RelativeContentPath).ToArray(), hashedImageContentItems.DistinctBy(hi => hi.RelativeContentPath).ToArray())); }