diff --git a/umbraco/presentation.ClientDependency/ClientDependencyHelper.cs b/umbraco/presentation.ClientDependency/ClientDependencyHelper.cs index 005749b8c7..3d92932fcc 100644 --- a/umbraco/presentation.ClientDependency/ClientDependencyHelper.cs +++ b/umbraco/presentation.ClientDependency/ClientDependencyHelper.cs @@ -7,6 +7,7 @@ using umbraco.presentation.ClientDependency.Providers; using System.Web.Configuration; using System.Configuration.Provider; using umbraco.presentation.ClientDependency.Config; +using umbraco.presentation.ClientDependency.Controls; namespace umbraco.presentation.ClientDependency { @@ -106,11 +107,12 @@ namespace umbraco.presentation.ClientDependency } // add child dependencies + Type iClientDependency = typeof(IClientDependencyFile); foreach (Control child in control.Controls) { - if (child.GetType().Equals(typeof(ClientDependencyInclude))) + if (iClientDependency.IsAssignableFrom(child.GetType())) { - ClientDependencyInclude include = (ClientDependencyInclude)child; + IClientDependencyFile include = (IClientDependencyFile)child; dependencies.Add(include); } else diff --git a/umbraco/presentation.ClientDependency/CompositeDependencyHandler.cs b/umbraco/presentation.ClientDependency/CompositeDependencyHandler.cs index f3539d653b..687be12233 100644 --- a/umbraco/presentation.ClientDependency/CompositeDependencyHandler.cs +++ b/umbraco/presentation.ClientDependency/CompositeDependencyHandler.cs @@ -16,12 +16,14 @@ namespace umbraco.presentation.ClientDependency static CompositeDependencyHandler() { HandlerFileName = DefaultHandlerFileName; - MaxHandlerUrlLength = DefaultMaxHandlerUrlLength; + //MaxHandlerUrlLength = DefaultMaxHandlerUrlLength; } private static readonly string _versionNo = string.Empty; private const string DefaultHandlerFileName = "DependencyHandler.axd"; - private const int DefaultMaxHandlerUrlLength = 2000; + //private const int DefaultMaxHandlerUrlLength = 2000; + + private object m_Lock = new object(); /// /// The handler file name, by default this is DependencyHandler.axd. @@ -66,34 +68,54 @@ namespace umbraco.presentation.ClientDependency if (string.IsNullOrEmpty(fileset)) throw new ArgumentException("Must specify a fileset in the request"); - string compositeFileName; - byte[] outputBytes; - CompositeFileMap map = CompositeFileXmlMapper.Instance.GetCompositeFile(fileset); - if (map == null || !map.HasFileBytes) + string compositeFileName = ""; + byte[] outputBytes = null; + + //get the map to the composite file for this file set, if it exists. + CompositeFileMap map = CompositeFileXmlMapper.Instance.GetCompositeFile(fileset); + + if (map != null && map.HasFileBytes) { - //get the file list - string[] strFiles = DecodeFrom64(fileset).Split(';'); - //combine files - byte[] fileBytes = CombineFiles(strFiles, context, type); - //compress data - CompressionType cType = CompressBytes(context, fileBytes, out outputBytes); - SetContentEncodingHeaders(context, cType); - //save combined file - compositeFileName = SaveCompositeFile(outputBytes, type); - - //Update the XML file map - CompositeFileXmlMapper.Instance.CreateMap(fileset, cType.ToString(), - strFiles.Select(x => new FileInfo(context.Server.MapPath(x))).ToList(), - compositeFileName); - + ProcessFromFile(context, map, out compositeFileName, out outputBytes); } else { - //the saved file's bytes are already compressed. - outputBytes = map.GetCompositeFileBytes(); - compositeFileName = map.CompositeFileName; - CompressionType cType = (CompressionType)Enum.Parse(typeof(CompressionType), map.CompressionType); - SetContentEncodingHeaders(context, cType); + bool fromFile = false; + + lock (m_Lock) + { + //check again... + if (map == null || !map.HasFileBytes) + { + //need to do the combining, etc... and save the file map + + //get the file list + string[] strFiles = DecodeFrom64(fileset).Split(';'); + //combine files + byte[] fileBytes = CompositeFileProcessor.CombineFiles(strFiles, context, type); + //compress data + CompressionType cType = GetCompression(context); + outputBytes = CompositeFileProcessor.CompressBytes(cType, fileBytes); + SetContentEncodingHeaders(context, cType); + //save combined file + compositeFileName = CompositeFileProcessor.SaveCompositeFile(outputBytes, type); + + //Update the XML file map + CompositeFileXmlMapper.Instance.CreateMap(fileset, cType.ToString(), + strFiles.Select(x => new FileInfo(context.Server.MapPath(x))).ToList(), + compositeFileName); + } + else + { + //files are there now, process from file. + fromFile = true; + } + } + + if (fromFile) + { + ProcessFromFile(context, map, out compositeFileName, out outputBytes); + } } SetCaching(context, compositeFileName); @@ -102,168 +124,13 @@ namespace umbraco.presentation.ClientDependency context.Response.OutputStream.Write(outputBytes, 0, outputBytes.Length); } - private enum CompressionType + private void ProcessFromFile(HttpContext context, CompositeFileMap map, out string compositeFileName, out byte[] outputBytes) { - deflate, gzip, none - } - - /// - /// Saves the file's bytes to disk with a hash of the byte array - /// - /// - /// - /// The new file path - /// - /// the extension will be: .cdj for JavaScript and .cdc for CSS - /// - private string SaveCompositeFile(byte[] fileContents, ClientDependencyType type) - { - if (!ClientDependencySettings.Instance.CompositeFilePath.Exists) - ClientDependencySettings.Instance.CompositeFilePath.Create(); - FileInfo fi = new FileInfo( - Path.Combine(ClientDependencySettings.Instance.CompositeFilePath.FullName, - fileContents.GetHashCode().ToString() + ".cd" + type.ToString().Substring(0, 1).ToLower())); - if (fi.Exists) - fi.Delete(); - FileStream fs = fi.Create(); - fs.Write(fileContents, 0, fileContents.Length); - fs.Close(); - return fi.FullName; - } - - /// - /// combines all files to a byte array - /// - /// - /// - /// - private byte[] CombineFiles(string[] strFiles, HttpContext context, ClientDependencyType type) - { - MemoryStream ms = new MemoryStream(5000); - StreamWriter sw = new StreamWriter(ms); - foreach (string s in strFiles) - { - if (!string.IsNullOrEmpty(s)) - { - try - { - FileInfo fi = new FileInfo(context.Server.MapPath(s)); - if (ClientDependencySettings.Instance.FileBasedDependencyExtensionList.Contains(fi.Extension.ToLower().Replace(".", ""))) - { - //if the file doesn't exist, then we'll assume it is a URI external request - if (!fi.Exists) - { - WriteRequestToStream(ref sw, s); - } - else - { - //if it is a file based dependency then read it - string fileContents = File.ReadAllText(fi.FullName); - sw.WriteLine(fileContents); - } - } - else - { - //if it's not a file based dependency, try to get the request output. - WriteRequestToStream(ref sw, s); - } - } - catch (Exception ex) - { - Type exType = ex.GetType(); - if (exType.Equals(typeof(NotSupportedException)) || exType.Equals(typeof(ArgumentException))) - { - //could not parse the string into a fileinfo, so we assume it is a URI - WriteRequestToStream(ref sw, s); - } - else - { - //if this fails, log the exception in trace, but continue - HttpContext.Current.Trace.Warn("ClientDependency", "Could not load file contents from " + s, ex); - System.Diagnostics.Debug.Assert(false, "Could not load file contents from " + s, ex.Message); - } - } - } - - if (type == ClientDependencyType.Javascript) - { - sw.Write(";;;"); //write semicolons in case the js isn't formatted correctly. This also helps for debugging. - } - - } - sw.Flush(); - byte[] outputBytes = ms.ToArray(); - sw.Close(); - ms.Close(); - return outputBytes; - } - - /// - /// Writes the output of an external request to the stream. Returns true/false if succesful or not. - /// - /// - /// - /// - private bool WriteRequestToStream(ref StreamWriter sw, string url) - { - string requestOutput; - bool rVal = false; - rVal = TryReadUri(url, out requestOutput); - if (rVal) - { - //write the contents of the external request. - sw.WriteLine(requestOutput); - } - return rVal; - } - - /// - /// Tries to convert the url to a uri, then read the request into a string and return it. - /// This takes into account relative vs absolute URI's - /// - /// - /// - /// - private bool TryReadUri(string url, out string requestContents) - { - Uri uri; - if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) - { - if (uri.IsAbsoluteUri) - { - WebClient client = new WebClient(); - try - { - requestContents = client.DownloadString(uri.AbsoluteUri); - return true; - } - catch (Exception ex) - { - HttpContext.Current.Trace.Warn("ClientDependency", "Could not load file contents from " + url, ex); - System.Diagnostics.Debug.Assert(false, "Could not load file contents from " + url, ex.Message); - } - } - else - { - //its a relative path so use the execute method - StringWriter sw = new StringWriter(); - try - { - HttpContext.Current.Server.Execute(url, sw); - requestContents = sw.ToString(); - sw.Close(); - return true; - } - catch (Exception ex) - { - HttpContext.Current.Trace.Warn("ClientDependency", "Could not load file contents from " + url, ex); - System.Diagnostics.Debug.Assert(false, "Could not load file contents from " + url, ex.Message); - } - } - - } - requestContents = ""; - return false; + //the saved file's bytes are already compressed. + outputBytes = map.GetCompositeFileBytes(); + compositeFileName = map.CompositeFileName; + CompressionType cType = (CompressionType)Enum.Parse(typeof(CompressionType), map.CompressionType); + SetContentEncodingHeaders(context, cType); } /// @@ -315,42 +182,24 @@ namespace umbraco.presentation.ClientDependency } /// - /// Compresses the bytes if the browser supports it + /// Check what kind of compression to use /// - private CompressionType CompressBytes(HttpContext context, byte[] fileBytes, out byte[] outputBytes) + private CompressionType GetCompression(HttpContext context) { CompressionType type = CompressionType.none; string acceptEncoding = context.Request.Headers["Accept-Encoding"]; - //not compressed initially - outputBytes = fileBytes; if (!string.IsNullOrEmpty(acceptEncoding)) - { - MemoryStream ms = new MemoryStream(); - Stream compressedStream = null; - acceptEncoding = acceptEncoding.ToLowerInvariant(); - + { //deflate is faster in .Net according to Mads Kristensen (blogengine.net) if (acceptEncoding.Contains("deflate")) - { - compressedStream = new DeflateStream(ms, CompressionMode.Compress, true); + { type = CompressionType.deflate; } else if (acceptEncoding.Contains("gzip")) { - compressedStream = new GZipStream(ms, CompressionMode.Compress, true); type = CompressionType.gzip; } - - if (type != CompressionType.none) - { - //write the bytes to the compressed stream - compressedStream.Write(fileBytes, 0, fileBytes.Length); - compressedStream.Close(); - byte[] output = ms.ToArray(); - ms.Close(); - outputBytes = output; - } } return type; diff --git a/umbraco/presentation.ClientDependency/CompositeFileProcessor.cs b/umbraco/presentation.ClientDependency/CompositeFileProcessor.cs new file mode 100644 index 0000000000..a68c0d299a --- /dev/null +++ b/umbraco/presentation.ClientDependency/CompositeFileProcessor.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using umbraco.presentation.ClientDependency.Config; +using System.IO; +using System.Web; +using System.Net; +using System.IO.Compression; + +namespace umbraco.presentation.ClientDependency +{ + public enum CompressionType + { + deflate, gzip, none + } + + /// + /// A utility class for combining, compressing and saving composite scripts/css files + /// + public static class CompositeFileProcessor + { + + /// + /// Saves the file's bytes to disk with a hash of the byte array + /// + /// + /// + /// The new file path + /// + /// the extension will be: .cdj for JavaScript and .cdc for CSS + /// + public static string SaveCompositeFile(byte[] fileContents, ClientDependencyType type) + { + if (!ClientDependencySettings.Instance.CompositeFilePath.Exists) + ClientDependencySettings.Instance.CompositeFilePath.Create(); + FileInfo fi = new FileInfo( + Path.Combine(ClientDependencySettings.Instance.CompositeFilePath.FullName, + fileContents.GetHashCode().ToString() + ".cd" + type.ToString().Substring(0, 1).ToLower())); + if (fi.Exists) + fi.Delete(); + FileStream fs = fi.Create(); + fs.Write(fileContents, 0, fileContents.Length); + fs.Close(); + return fi.FullName; + } + + + /// + /// combines all files to a byte array + /// + /// + /// + /// + public static byte[] CombineFiles(string[] strFiles, HttpContext context, ClientDependencyType type) + { + MemoryStream ms = new MemoryStream(5000); + StreamWriter sw = new StreamWriter(ms); + foreach (string s in strFiles) + { + if (!string.IsNullOrEmpty(s)) + { + try + { + FileInfo fi = new FileInfo(context.Server.MapPath(s)); + if (ClientDependencySettings.Instance.FileBasedDependencyExtensionList.Contains(fi.Extension.ToLower().Replace(".", ""))) + { + //if the file doesn't exist, then we'll assume it is a URI external request + if (!fi.Exists) + { + WriteFileToStream(ref sw, s, type); + } + else + { + WriteFileToStream(ref sw, fi, type, s); + } + } + else + { + //if it's not a file based dependency, try to get the request output. + WriteFileToStream(ref sw, s, type); + } + } + catch (Exception ex) + { + Type exType = ex.GetType(); + if (exType.Equals(typeof(NotSupportedException)) || exType.Equals(typeof(ArgumentException))) + { + //could not parse the string into a fileinfo, so we assume it is a URI + WriteFileToStream(ref sw, s, type); + } + else + { + //if this fails, log the exception in trace, but continue + HttpContext.Current.Trace.Warn("ClientDependency", "Could not load file contents from " + s, ex); + System.Diagnostics.Debug.Assert(false, "Could not load file contents from " + s, ex.Message); + } + } + } + + if (type == ClientDependencyType.Javascript) + { + sw.Write(";;;"); //write semicolons in case the js isn't formatted correctly. This also helps for debugging. + } + + } + sw.Flush(); + byte[] outputBytes = ms.ToArray(); + sw.Close(); + ms.Close(); + return outputBytes; + } + + /// + /// Writes the output of an external request to the stream. Returns true/false if succesful or not. + /// + /// + /// + /// + private static bool WriteFileToStream(ref StreamWriter sw, string url, ClientDependencyType type) + { + string requestOutput; + bool rVal = false; + rVal = TryReadUri(url, out requestOutput); + if (rVal) + { + //write the contents of the external request. + sw.WriteLine(ParseFileContents(requestOutput, type, url)); + } + return rVal; + } + + private static bool WriteFileToStream(ref StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl) + { + try + { + //if it is a file based dependency then read it + string fileContents = File.ReadAllText(fi.FullName); + sw.WriteLine(ParseFileContents(fileContents, type, origUrl)); + return true; + } + catch (Exception ex) + { + HttpContext.Current.Trace.Warn("ClientDependency", "Could not write file " + fi.FullName + " contents to stream", ex); + System.Diagnostics.Debug.Assert(false, "Could not write file " + fi.FullName + " contents to stream", ex.Message); + return false; + } + } + + /// + /// Currently this only parses CSS files, but potentially could have other uses. + /// This is the final process before writing to the stream. + /// + /// + /// + /// + private static string ParseFileContents(string fileContents, ClientDependencyType type, string url) + { + //if it is a CSS file we need to parse the URLs + if (type == ClientDependencyType.Css) + { + + fileContents = CssFileUrlFormatter.TransformCssFile(fileContents, MakeUri(url)); + } + return fileContents; + } + + /// + /// Checks if the url is a local/relative uri, if it is, it makes it absolute based on the + /// current request uri. + /// + /// + /// + private static Uri MakeUri(string url) + { + Uri uri = new Uri(url, UriKind.RelativeOrAbsolute); + if (!uri.IsAbsoluteUri) + { + string http = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); + Uri absoluteUrl = new Uri(new Uri(http), uri); + return absoluteUrl; + } + return uri; + } + + /// + /// Tries to convert the url to a uri, then read the request into a string and return it. + /// This takes into account relative vs absolute URI's + /// + /// + /// + /// + private static bool TryReadUri(string url, out string requestContents) + { + Uri uri; + if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out uri)) + { + if (uri.IsAbsoluteUri) + { + WebClient client = new WebClient(); + try + { + requestContents = client.DownloadString(uri.AbsoluteUri); + return true; + } + catch (Exception ex) + { + HttpContext.Current.Trace.Warn("ClientDependency", "Could not load file contents from " + url, ex); + System.Diagnostics.Debug.Assert(false, "Could not load file contents from " + url, ex.Message); + } + } + else + { + //its a relative path so use the execute method + StringWriter sw = new StringWriter(); + try + { + HttpContext.Current.Server.Execute(url, sw); + requestContents = sw.ToString(); + sw.Close(); + return true; + } + catch (Exception ex) + { + HttpContext.Current.Trace.Warn("ClientDependency", "Could not load file contents from " + url, ex); + System.Diagnostics.Debug.Assert(false, "Could not load file contents from " + url, ex.Message); + } + } + + } + requestContents = ""; + return false; + } + + /// + /// Compresses the bytes if the browser supports it + /// + public static byte[] CompressBytes(CompressionType type, byte[] fileBytes) + { + MemoryStream ms = new MemoryStream(); + Stream compressedStream = null; + + //deflate is faster in .Net according to Mads Kristensen (blogengine.net) + if (type == CompressionType.deflate) + { + compressedStream = new DeflateStream(ms, CompressionMode.Compress, true); + } + else if (type == CompressionType.gzip) + { + compressedStream = new GZipStream(ms, CompressionMode.Compress, true); + } + + if (type != CompressionType.none) + { + //write the bytes to the compressed stream + compressedStream.Write(fileBytes, 0, fileBytes.Length); + compressedStream.Close(); + byte[] output = ms.ToArray(); + ms.Close(); + return output; + } + + //not compressed + return fileBytes; + } + } +} diff --git a/umbraco/presentation.ClientDependency/CompositeFileXmlMapper.cs b/umbraco/presentation.ClientDependency/CompositeFileXmlMapper.cs index ca643a7ce1..8f44f451f5 100644 --- a/umbraco/presentation.ClientDependency/CompositeFileXmlMapper.cs +++ b/umbraco/presentation.ClientDependency/CompositeFileXmlMapper.cs @@ -50,7 +50,6 @@ namespace umbraco.presentation.ClientDependency /// private void Initialize() { - m_XmlFile = new FileInfo( Path.Combine(ClientDependencySettings.Instance.CompositeFilePath.FullName, MapFileName)); @@ -90,6 +89,8 @@ namespace umbraco.presentation.ClientDependency //double check if (!m_XmlFile.Exists) { + if (!ClientDependencySettings.Instance.CompositeFilePath.Exists) + ClientDependencySettings.Instance.CompositeFilePath.Create(); CreateNewXmlFile(); } } @@ -105,19 +106,19 @@ namespace umbraco.presentation.ClientDependency public CompositeFileMap GetCompositeFile(string base64Key) { XElement x = FindItem(base64Key); - //try - //{ + try + { return (x == null ? null : new CompositeFileMap(base64Key, x.Attribute("compression").Value, x.Attribute("file").Value, x.Descendants("file") .Select(f => new FileInfo(f.Attribute("name").Value)) .ToList())); - //} - //catch - //{ - // return null; - //} + } + catch + { + return null; + } } /// diff --git a/umbraco/presentation.ClientDependency/ClientDependencyInclude.cs b/umbraco/presentation.ClientDependency/Controls/ClientDependencyInclude.cs similarity index 82% rename from umbraco/presentation.ClientDependency/ClientDependencyInclude.cs rename to umbraco/presentation.ClientDependency/Controls/ClientDependencyInclude.cs index 76aba91f6c..e7a5894b54 100644 --- a/umbraco/presentation.ClientDependency/ClientDependencyInclude.cs +++ b/umbraco/presentation.ClientDependency/Controls/ClientDependencyInclude.cs @@ -3,14 +3,13 @@ using System.Collections.Generic; using System.Text; using System.Web.UI; -namespace umbraco.presentation.ClientDependency +namespace umbraco.presentation.ClientDependency.Controls { - public class ClientDependencyInclude : Control, IClientDependencyFile + public abstract class ClientDependencyInclude : Control, IClientDependencyFile { public ClientDependencyInclude() - { - DependencyType = ClientDependencyType.Javascript; + { Priority = DefaultPriority; DoNotOptimize = false; } @@ -34,7 +33,8 @@ namespace umbraco.presentation.ClientDependency /// public bool DoNotOptimize { get; set; } - public ClientDependencyType DependencyType { get; set; } + public ClientDependencyType DependencyType { get; internal set; } + public string FilePath { get; set; } public string PathNameAlias { get; set; } public string CompositeGroupName { get; set; } diff --git a/umbraco/presentation.ClientDependency/ClientDependencyLoader.cs b/umbraco/presentation.ClientDependency/Controls/ClientDependencyLoader.cs similarity index 94% rename from umbraco/presentation.ClientDependency/ClientDependencyLoader.cs rename to umbraco/presentation.ClientDependency/Controls/ClientDependencyLoader.cs index 306b1488ce..2ae7aab659 100644 --- a/umbraco/presentation.ClientDependency/ClientDependencyLoader.cs +++ b/umbraco/presentation.ClientDependency/Controls/ClientDependencyLoader.cs @@ -6,7 +6,7 @@ using System.Web; using umbraco.presentation.ClientDependency.Providers; using umbraco.presentation.ClientDependency.Config; -namespace umbraco.presentation.ClientDependency +namespace umbraco.presentation.ClientDependency.Controls { [ParseChildren(typeof(ClientDependencyPath), ChildrenAsProperties = true)] public class ClientDependencyLoader : Control diff --git a/umbraco/presentation.ClientDependency/ClientDependencyPath.cs b/umbraco/presentation.ClientDependency/Controls/ClientDependencyPath.cs similarity index 92% rename from umbraco/presentation.ClientDependency/ClientDependencyPath.cs rename to umbraco/presentation.ClientDependency/Controls/ClientDependencyPath.cs index 0f2d9c8894..0c75cac3d0 100644 --- a/umbraco/presentation.ClientDependency/ClientDependencyPath.cs +++ b/umbraco/presentation.ClientDependency/Controls/ClientDependencyPath.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Text; using System.Web.UI; -namespace umbraco.presentation.ClientDependency +namespace umbraco.presentation.ClientDependency.Controls { /// diff --git a/umbraco/presentation.ClientDependency/ClientDependencyPathCollection.cs b/umbraco/presentation.ClientDependency/Controls/ClientDependencyPathCollection.cs similarity index 69% rename from umbraco/presentation.ClientDependency/ClientDependencyPathCollection.cs rename to umbraco/presentation.ClientDependency/Controls/ClientDependencyPathCollection.cs index a097796cf8..3c945809ba 100644 --- a/umbraco/presentation.ClientDependency/ClientDependencyPathCollection.cs +++ b/umbraco/presentation.ClientDependency/Controls/ClientDependencyPathCollection.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace umbraco.presentation.ClientDependency +namespace umbraco.presentation.ClientDependency.Controls { public class ClientDependencyPathCollection : List { diff --git a/umbraco/presentation.ClientDependency/Controls/CssInclude.cs b/umbraco/presentation.ClientDependency/Controls/CssInclude.cs new file mode 100644 index 0000000000..d85cfd804b --- /dev/null +++ b/umbraco/presentation.ClientDependency/Controls/CssInclude.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace umbraco.presentation.ClientDependency.Controls +{ + public class CssInclude : ClientDependencyInclude + { + + public CssInclude() + { + DependencyType = ClientDependencyType.Css; + } + } +} diff --git a/umbraco/presentation.ClientDependency/Controls/JsInclude.cs b/umbraco/presentation.ClientDependency/Controls/JsInclude.cs new file mode 100644 index 0000000000..fa2c45f5e6 --- /dev/null +++ b/umbraco/presentation.ClientDependency/Controls/JsInclude.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace umbraco.presentation.ClientDependency.Controls +{ + public class JsInclude : ClientDependencyInclude + { + + public JsInclude() + { + DependencyType = ClientDependencyType.Javascript; + } + + } +} diff --git a/umbraco/presentation.ClientDependency/CssFileUrlFormatter.cs b/umbraco/presentation.ClientDependency/CssFileUrlFormatter.cs new file mode 100644 index 0000000000..9d4a0dcc1c --- /dev/null +++ b/umbraco/presentation.ClientDependency/CssFileUrlFormatter.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace umbraco.presentation.ClientDependency +{ + public class CssFileUrlFormatter + { + + /// + /// Returns the CSS file with all of the url's formatted to be absolute locations + /// + /// content of the css file + /// the uri location of the css file + /// + public static string TransformCssFile(string fileContent, Uri cssLocation) + { + string str = Regex.Replace( + fileContent, + @"url\((.+)\)", + new MatchEvaluator( + delegate(Match m) + { + if (m.Groups.Count == 2) + { + string match = m.Groups[1].Value.Trim('\'', '"'); + return string.Format(@"url(""{0}"")", + match.StartsWith("http") ? match : new Uri(cssLocation, match).ToString()); + } + return m.Value; + }) + ); + + return str; + } + + } +} diff --git a/umbraco/presentation.ClientDependency/IClientDependencyFile.cs b/umbraco/presentation.ClientDependency/IClientDependencyFile.cs index 4d24fc4122..8368f49e3e 100644 --- a/umbraco/presentation.ClientDependency/IClientDependencyFile.cs +++ b/umbraco/presentation.ClientDependency/IClientDependencyFile.cs @@ -7,7 +7,7 @@ namespace umbraco.presentation.ClientDependency public interface IClientDependencyFile { string FilePath { get; set; } - ClientDependencyType DependencyType { get; set; } + ClientDependencyType DependencyType { get; } string InvokeJavascriptMethodOnLoad { get; set; } int Priority { get; set; } //string CompositeGroupName { get; set; } diff --git a/umbraco/presentation.ClientDependency/Providers/ClientDependencyProvider.cs b/umbraco/presentation.ClientDependency/Providers/ClientDependencyProvider.cs index 5ee86b861a..14cbc1234a 100644 --- a/umbraco/presentation.ClientDependency/Providers/ClientDependencyProvider.cs +++ b/umbraco/presentation.ClientDependency/Providers/ClientDependencyProvider.cs @@ -5,6 +5,7 @@ using System.Web.UI; using System.Configuration.Provider; using System.Web; using System.Linq; +using umbraco.presentation.ClientDependency.Controls; namespace umbraco.presentation.ClientDependency.Providers { diff --git a/umbraco/presentation.ClientDependency/umbraco.presentation.ClientDependency.csproj b/umbraco/presentation.ClientDependency/umbraco.presentation.ClientDependency.csproj index ba66187cca..6f00a71ea6 100644 --- a/umbraco/presentation.ClientDependency/umbraco.presentation.ClientDependency.csproj +++ b/umbraco/presentation.ClientDependency/umbraco.presentation.ClientDependency.csproj @@ -51,21 +51,25 @@ - + + + + + - - - + + + diff --git a/umbraco/presentation/umbraco/ClientDependencyTest.aspx b/umbraco/presentation/umbraco/ClientDependencyTest.aspx index f3ae66f02e..c2716e87dc 100644 --- a/umbraco/presentation/umbraco/ClientDependencyTest.aspx +++ b/umbraco/presentation/umbraco/ClientDependencyTest.aspx @@ -1,5 +1,5 @@ <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ClientDependencyTest.aspx.cs" Inherits="umbraco.presentation.umbraco.ClientDependencyTest" Trace="true" %> -<%@ Register TagPrefix="umb" Namespace="umbraco.presentation.ClientDependency" Assembly="umbraco.presentation.ClientDependency" %> +<%@ Register TagPrefix="umb" Namespace="umbraco.presentation.ClientDependency.Controls" Assembly="umbraco.presentation.ClientDependency" %> @@ -14,7 +14,7 @@ - +
diff --git a/umbraco/presentation/umbraco/ClientDependencyTest.aspx.designer.cs b/umbraco/presentation/umbraco/ClientDependencyTest.aspx.designer.cs index 33bc810996..78fb4553f5 100644 --- a/umbraco/presentation/umbraco/ClientDependencyTest.aspx.designer.cs +++ b/umbraco/presentation/umbraco/ClientDependencyTest.aspx.designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.3074 +// Runtime Version:2.0.50727.3082 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -20,16 +20,7 @@ namespace umbraco.presentation.umbraco { /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::umbraco.presentation.ClientDependency.ClientDependencyLoader ClientLoader; - - /// - /// Dependency1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.presentation.ClientDependency.ClientDependencyInclude Dependency1; + protected global::umbraco.presentation.ClientDependency.Controls.ClientDependencyLoader ClientLoader; /// /// form1 control. diff --git a/umbraco/presentation/umbraco/controls/ContentPicker.cs b/umbraco/presentation/umbraco/controls/ContentPicker.cs index 1acf593c76..cc5d7e7f96 100644 --- a/umbraco/presentation/umbraco/controls/ContentPicker.cs +++ b/umbraco/presentation/umbraco/controls/ContentPicker.cs @@ -13,14 +13,6 @@ using umbraco.presentation.ClientDependency; namespace umbraco.controls { - //""); - //"" - //""); - //" - //" - //""); - - [ClientDependency(ClientDependencyType.Javascript, "js/xmlextras.js", "UmbracoRoot")] [ClientDependency(ClientDependencyType.Javascript, "js/xmlRequest.js", "UmbracoRoot")] [ClientDependency(ClientDependencyType.Javascript, "webservices/ajax.js", "UmbracoRoot")] @@ -86,10 +78,7 @@ namespace umbraco.controls protected override void OnInit(EventArgs e) { base.OnInit(e); - //base.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ajax", ""); - //base.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ajax1", ""); - //base.Page.ClientScript.RegisterClientScriptBlock(GetType(), "subModal", ""); - + // We need to make sure we have a reference to the legacy ajax calls in the scriptmanager presentation.webservices.ajaxHelpers.EnsureLegacyCalls(base.Page); } diff --git a/umbraco/presentation/umbraco/controls/TreeControl.ascx b/umbraco/presentation/umbraco/controls/TreeControl.ascx index 3de24ace00..43c9bc141f 100644 --- a/umbraco/presentation/umbraco/controls/TreeControl.ascx +++ b/umbraco/presentation/umbraco/controls/TreeControl.ascx @@ -1,18 +1,18 @@ <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TreeControl.ascx.cs" Inherits="umbraco.presentation.umbraco.controls.TreeControl" %> -<%@ Register TagPrefix="umb" Namespace="umbraco.presentation.ClientDependency" Assembly="umbraco.presentation.ClientDependency" %> +<%@ Register TagPrefix="umb" Namespace="umbraco.presentation.ClientDependency.Controls" Assembly="umbraco.presentation.ClientDependency" %> - + - - - - - - - - - - + + + + + + + + + + -
+ " /> + \ No newline at end of file diff --git a/umbraco/presentation/umbraco/dashboard/quickEdit.ascx.designer.cs b/umbraco/presentation/umbraco/dashboard/quickEdit.ascx.designer.cs index 0153c9bfa0..9c58d58e7c 100644 --- a/umbraco/presentation/umbraco/dashboard/quickEdit.ascx.designer.cs +++ b/umbraco/presentation/umbraco/dashboard/quickEdit.ascx.designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.3074 +// Runtime Version:2.0.50727.3082 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +14,21 @@ namespace umbraco.presentation.dashboard { public partial class quickEdit { /// - /// ClientDependencyInclude3 control. + /// JsInclude1 control. /// /// /// Auto-generated field. /// To modify move field declaration from designer file to code-behind file. /// - protected global::umbraco.presentation.ClientDependency.ClientDependencyInclude ClientDependencyInclude3; + protected global::umbraco.presentation.ClientDependency.Controls.JsInclude JsInclude1; + + /// + /// JsInclude2 control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::umbraco.presentation.ClientDependency.Controls.JsInclude JsInclude2; } } diff --git a/umbraco/presentation/umbraco/developer/Xslt/editXslt.aspx b/umbraco/presentation/umbraco/developer/Xslt/editXslt.aspx index f2540b9901..ad9d5b3dd7 100644 --- a/umbraco/presentation/umbraco/developer/Xslt/editXslt.aspx +++ b/umbraco/presentation/umbraco/developer/Xslt/editXslt.aspx @@ -3,6 +3,7 @@ Inherits="umbraco.cms.presentation.developer.editXslt" %> <%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> +<%@ Register TagPrefix="umb" Namespace="umbraco.presentation.ClientDependency.Controls" Assembly="umbraco.presentation.ClientDependency" %>