示例#1
0
		protected override void Render (HtmlTextWriter writer)
		{
			ConfigSection cs = ConfigSection.CurrentConfigSection ();

			// If we are not active, render the head section to the writer as is.
			if (!ConfigSection.OptionIsActive (cs.Active)) {
				base.Render (writer);
				return;
			}

			// --------------

			UrlProcessor urlProcessor =
                new UrlProcessor (
                    cs.CookielessDomains, cs.MakeImageUrlsLowercase, cs.InsertVersionIdInImageUrls,
                    ConfigSection.OptionIsActive (cs.EnableCookielessDomains), cs.PreloadAllImages,
                    ConfigSection.OptionIsActive (cs.ExceptionOnMissingFile));

			// --------------

			// headHtml holds the html on the page making up the 
			// head element, including the <head> tag itself.
			StringBuilder headHtmlSb = new StringBuilder ();
			base.Render (new HtmlTextWriter (new StringWriter (headHtmlSb)));

			// ------------

			HeadAnalysis headAnalysis = null;
			if (cs.HeadCaching == ConfigSection.HeadCachingOption.None) {
				headAnalysis = new HeadAnalysis (
                            headHtmlSb.ToString (), null, cs.CombineCSSFiles, cs.CombineJavaScriptFiles,
                            cs.MinifyCSS, cs.MinifyJavaScript,
                            urlProcessor);
			} else {
				string headCacheKey = HeadCacheKey (HttpContext.Current.Request.Url, cs.HeadCaching);
				headAnalysis = (HeadAnalysis)HttpContext.Current.Cache [headCacheKey];
				if (headAnalysis == null) {
					// The urls of the combined CSS and JavaScript files in the new head
					// are dependent on the versions of the actual files (because they contain the version
					// ids).

					// totalFileNames will be filled with a list of the names of all
					// CSS and JavaScript files loaded in the head (that is, those
					// that get combined and/or minified).
					List<string> totalFileNames = new List<string> ();
					headAnalysis = new HeadAnalysis (
                            headHtmlSb.ToString (), totalFileNames, cs.CombineCSSFiles, cs.CombineJavaScriptFiles,
                            cs.MinifyCSS, cs.MinifyJavaScript,
                            urlProcessor);

					AddPageFilePaths (totalFileNames);

					CacheDependency cd = new CacheDependency (totalFileNames.ToArray ());
					HttpContext.Current.Cache.Insert (headCacheKey, headAnalysis, cd);
				}
			}

			// ------------
			// Do all replacements in the head specified in headAnalysis

			foreach (HeadAnalysis.Replacement r in headAnalysis.Replacements) {
				headHtmlSb.Replace (r.original, r.replacement);
			}

			// ------------
			// Process all images in the page if needed. 

			if (cs.RemoveWhitespace || urlProcessor.ImagesNeedProcessing ()) {
				ProcessAllImages (Control.Page.Controls, urlProcessor, cs.RemoveWhitespace);
			}

			// ------------

			string headHtml = headHtmlSb.ToString ();

			// At this point, urlProcessor and headAnalysis contains all image urls.
			// Build the JavaScript to preload any images that need to be preloaded,
			// and insert it at the start of the head, just after the initial head tag.

			string preloadJS1 = PreloadJS (cs.PreloadAllImages, cs.PrioritizedImages, headAnalysis.ProcessedImageUrls);
			string preloadJS2 = PreloadJS (cs.PreloadAllImages, cs.PrioritizedImages, urlProcessor.ProcessedImageUrls);
			string preloadJS = preloadJS1 + preloadJS2;

			// If any urls need to be preloaded, insert the JavaScript block after the first > (that is, after the
			// head tag).
			if (!string.IsNullOrEmpty (preloadJS)) {
				headHtml = InsertedAfterFirstTag (headHtml, preloadJS);
			}

			writer.Write (headHtml);
		}
示例#2
0
		private void ProcessAllImages (ControlCollection cc, UrlProcessor urlProcessor, bool removeWhitespace)
		{
			bool imagesNeedProcessing = urlProcessor.ImagesNeedProcessing ();

			foreach (Control c in cc) {
				if (c is LiteralControl) {
					LiteralControl lit = (LiteralControl)c;
					string literalContent = lit.Text;
					string newLiteralContent = literalContent;

					if (imagesNeedProcessing) {
						// The "src" group in this regexp doesn't just contain the image url, but also the src= and the quotes.
						// That allows us to replace the entire src="...", instead of the url. 
						// If you only replace the old url with the new url, than if you have a tag with url "images/ball3.png" after a tag with "/images/ball3.png"
						// when the second url ("images/ball3.png") gets replaced, it alsos replace part of the first tag "/images/ball3.png" (because the first tag
						// contains the second tag). 
						const string regexpImgGroup =
                            @"<img[^>]*?(?<src>src[^=]*?=[^""']*?(?:""|')(?<url>[^""']*?)(?:""|'))[^>]*?>";

						Regex r = new Regex (regexpImgGroup, RegexOptions.IgnoreCase);
						Match m = r.Match (literalContent);

						while (m.Success) {
							string oldSrc = m.Groups ["src"].Value;

							string oldUrl = m.Groups ["url"].Value;
							string newUrl = urlProcessor.ProcessedUrl (oldUrl, true, false, Control.Page.Request.Url, null);
                            
							string newSrc = @"src=""" + newUrl + @"""";
                            
							newLiteralContent = newLiteralContent.Replace (oldSrc, newSrc);

							m = m.NextMatch ();
						}
					}

					if (removeWhitespace) {
						newLiteralContent = CollapsedWhitespace (newLiteralContent);
					}


					lit.Text = newLiteralContent;
				} else if ((c is HtmlImage) && imagesNeedProcessing) {
					HtmlImage hi = (HtmlImage)c;
					string versionId = LastUpdateTimeImageControl (hi.Src, hi, urlProcessor.ThrowExceptionOnMissingFile);
					hi.Src = urlProcessor.ProcessedUrl (hi.Src, true, false, Control.Page.Request.Url, versionId);
				} else if ((c is HyperLink) && imagesNeedProcessing) {
					HyperLink hl = (HyperLink)c;
					string versionId = LastUpdateTimeImageControl (hl.ImageUrl, hl, urlProcessor.ThrowExceptionOnMissingFile);
					hl.ImageUrl = urlProcessor.ProcessedUrl (hl.ImageUrl, true, false, Control.Page.Request.Url, versionId);
				} else if ((c is Image) && imagesNeedProcessing) {
					Image i = (Image)c;
					string versionId = LastUpdateTimeImageControl (i.ImageUrl, i, urlProcessor.ThrowExceptionOnMissingFile);
					i.ImageUrl = urlProcessor.ProcessedUrl (i.ImageUrl, true, false, Control.Page.Request.Url, versionId);
				} else {
					ProcessAllImages (c.Controls, urlProcessor, removeWhitespace);
				}
			}
		}