/// <summary>
 /// Creates a path based on the format, fileKey, type and version specified.
 /// </summary>
 /// <param name="pathBasedUrlFormat"></param>
 /// <param name="fileKey"></param>
 /// <param name="type"></param>
 /// <param name="version"></param>
 /// <returns></returns>
 public static string CreatePath(string pathBasedUrlFormat, string fileKey, ClientDependencyType type, int version)
 {            
     var pathUrl = pathBasedUrlFormat;
     var dependencyId = new StringBuilder();
     int pos = 0;
     //split paths at a max of 240 chars to not exceed the max path length of a URL
     while (fileKey.Length > pos)
     {
         if (dependencyId.Length > 0)
         {
             dependencyId.Append('/');
         }
         var len = Math.Min(fileKey.Length - pos, 240);
         dependencyId.Append(fileKey.Substring(pos, len));
         pos += 240;
     }
     pathUrl = pathUrl.Replace("{dependencyId}", dependencyId.ToString());
     pathUrl = pathUrl.Replace("{version}", version.ToString());
     switch (type)
     {
         case ClientDependencyType.Css:
             pathUrl = pathUrl.Replace("{type}", "css");
             break;
         case ClientDependencyType.Javascript:
             pathUrl = pathUrl.Replace("{type}", "js");
             break;
     }
     return pathUrl;
 }
        /// <summary>
        /// Get all dependencies declared on property editors
        /// </summary>
        /// <param name="cdfType"></param>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        protected JArray ScanPropertyEditors(ClientDependencyType cdfType, HttpContextBase httpContext)
        {
            if (httpContext == null) throw new ArgumentNullException("httpContext");
            var cdfAttributes =
                PropertyEditorResolver.Current.PropertyEditors
                                      .SelectMany(x => x.GetType().GetCustomAttributes<PropertyEditorAssetAttribute>(false))
                                      .Where(x => x.AssetType == cdfType)
                                      .Select(x => x.DependencyFile)
                                      .ToList();

            string jsOut;
            string cssOut;
            var renderer = ClientDependencySettings.Instance.MvcRendererCollection["Umbraco.DependencyPathRenderer"];
            renderer.RegisterDependencies(cdfAttributes, new HashSet<IClientDependencyPath>(), out jsOut, out cssOut, httpContext);

            var toParse = cdfType == ClientDependencyType.Javascript ? jsOut : cssOut;

            var result = new JArray();
            //split the result by the delimiter and add to the array
            foreach (var u in toParse.Split(new[] { DependencyPathRenderer.Delimiter }, StringSplitOptions.RemoveEmptyEntries))
            {
                result.Add(u);
            }
            return result;
        }
예제 #3
0
 private void RegisterIncludes(IEnumerable<BasicFile> files, ClientDependencyLoader loader, ClientDependencyType dependencyType)
 {
     foreach (var file in files)
     {
         loader.RegisterDependency(file.Group, file.Priority, file.FilePath, "", dependencyType, file.HtmlAttributes, file.ForceProvider);
     }
 }
예제 #4
0
 /// <summary>
 /// Returns the url for the composite file handler for the filePath specified.
 /// </summary>
 /// <param name="filePaths"></param>
 /// <param name="type"></param>
 /// <param name="http"></param>
 /// <returns></returns>
 public static string GetCompositeFileUrl(string filePaths, ClientDependencyType type, HttpContextBase http)
 {
     //build the combined composite list url
     string handler = "{0}?s={1}&t={2}";
     string combinedurl = string.Format(handler, ClientDependencySettings.Instance.CompositeFileHandlerPath, http.Server.UrlEncode(EncodeTo64(filePaths)), type.ToString());
     return combinedurl;
 }
예제 #5
0
        /// <summary>
        /// Writes the actual contents of a file or request result to the stream and ensures the contents are minified if necessary
        /// </summary>
        /// <param name="provider"></param>
        /// <param name="sw"></param>
        /// <param name="content"></param>
        /// <param name="type"></param>
        /// <param name="context"></param>
        /// <param name="originalUrl">The original Url that the content is related to</param>
        internal static void WriteContentToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, string content, ClientDependencyType type, HttpContextBase context, string originalUrl)
        {
            if (type == ClientDependencyType.Css)
            {
                IEnumerable<string> importedPaths;
                var removedImports = CssHelper.ParseImportStatements(content, out importedPaths);

                //need to write the imported sheets first since these theoretically should *always* be at the top for browser to support them
                foreach (var importPath in importedPaths)
                {
                    var uri = new Uri(originalUrl, UriKind.RelativeOrAbsolute)
                        .MakeAbsoluteUri(context);
                    var absolute = uri.ToAbsolutePath(importPath);
                    provider.WritePathToStream(ClientDependencyType.Css, absolute, context, sw);
                }

                //ensure the Urls in the css are changed to absolute
                var parsedUrls = CssHelper.ReplaceUrlsWithAbsolutePaths(removedImports, originalUrl, context);

                //then we write the css with the removed import statements
                sw.WriteLine(provider.MinifyFile(parsedUrls, ClientDependencyType.Css));
            }
            else
            {
                sw.WriteLine(provider.MinifyFile(content, type));
            }
        }
예제 #6
0
        /// <summary>
        /// Registers the embedded client resource.
        /// </summary>
        /// <param name="page">The page.</param>
        /// <param name="resourceContainer">The type containing the embedded resource</param>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="type">The type.</param>
        public static void RegisterEmbeddedClientResource(this Page page, Type resourceContainer, string resourceName, ClientDependencyType type)
        {
            var target = page.Header;

            // if there's no <head runat="server" /> don't throw an exception.
            if (target != null)
            {
                switch (type)
                {
                    case ClientDependencyType.Css:
                        // get the urls for the embedded resources
                        var resourceUrl = page.ClientScript.GetWebResourceUrl(resourceContainer, resourceName);
                        var link = new HtmlLink();
                        link.Attributes.Add("href", resourceUrl);
                        link.Attributes.Add("type", "text/css");
                        link.Attributes.Add("rel", "stylesheet");
                        target.Controls.Add(link);
                        break;

                    case ClientDependencyType.Javascript:
                        page.ClientScript.RegisterClientScriptResource(resourceContainer, resourceName);
                        break;

                    default:
                        break;
                }
            }
        }
예제 #7
0
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {
                //if it is a file based dependency then read it
                var fileContents = File.ReadAllText(fi.FullName, Encoding.UTF8); //read as utf 8

                //for our custom file reader to work we just need to put the origUrl into the httpcontext items so
                //we can retreive it in the reader to then figure out the 'real' requested path.
                http.Items["Cdf_LessWriter_origUrl"] = origUrl;
                //get the default less config
                var config = DotlessConfiguration.GetDefaultWeb();
                //set the file reader to our custom file reader
                config.LessSource = typeof(CdfFileReader);
                //disable cache for this engine since we are already caching our own, plus enabling this will cause errors because
                // the import paths aren't resolved properly.
                config.CacheEnabled = false;
                //get the engine based on the custom config with our custom file reader
                var lessEngine = LessWeb.GetEngine(config);

                var output = lessEngine.TransformToCss(fileContents, origUrl);

                DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);

                return true;
            }
            catch (Exception ex)
            {
                ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
                return false;
            }
        }
        /// <summary>
        /// Adds an embedded resource to the ClientDependency output by name
        /// </summary>
        /// <param name="ctl">The CTL.</param>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="type">The type.</param>
        public static void AddResourceToClientDependency(this Control ctl, string resourceName, ClientDependencyType type)
        {
            //get the urls for the embedded resources
            //var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(ctl.GetType(), resourceName);
            var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(typeof(AbstractPrevalueEditor), resourceName);

            //This only works in v4 currently or until i release CD version 1.2, so in the meantime, we'll use the below method
            //add the resources to client dependency
            //ClientDependencyLoader.Instance.RegisterDependency(resourceUrl, type);

            switch (type)
            {
                case ClientDependencyType.Css:
                    ctl.Page.Header.Controls.Add(
                        new LiteralControl("<link type='text/css' rel='stylesheet' href='" + resourceUrl + "' />"));
                    break;

                case ClientDependencyType.Javascript:
                    ctl.Page.ClientScript.RegisterClientScriptResource(typeof(ResourceExtensions), resourceName);
                    break;

                default:
                    break;
            }
        }
예제 #9
0
		public BasicFile(ClientDependencyType type)
		{
			DependencyType = type;
		    HtmlAttributes = new Dictionary<string, string>();
		    Priority = Constants.DefaultPriority;
		    Group = Constants.DefaultGroup;
		}
예제 #10
0
 public BundleDefinition(
     ClientDependencyType type,
     string name)
 {
     if (name == null) throw new ArgumentNullException("name");
     Type = type;
     Name = name;
 }
 public PlaceholderReplacementEventArgs(
     HttpContextBase httpContext, 
     ClientDependencyType type, 
     string replacedText,
     Match regexMatch) 
     : base(httpContext, replacedText)
 {
     Type = type;
     RegexMatch = regexMatch;
 }
예제 #12
0
 public BundleDefinition(
     ClientDependencyType type,
     string name, 
     int priority = Constants.DefaultPriority, int group = Constants.DefaultGroup)
 {
     if (name == null) throw new ArgumentNullException("name");
     Type = type;
     Name = name;
     Group = group;
     Priority = priority;
 }
 protected override string MinifyFile(string fileContents, ClientDependencyType type)
 {
     switch (type)
     {
         case ClientDependencyType.Css:
             return MinifyCss ? CssMin.CompressCSS(fileContents) : fileContents;
         case ClientDependencyType.Javascript:
             return MinifyJs ? JSMin.CompressJS(fileContents) : fileContents;
         default:
             return fileContents;
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientDependencyAttribute"/> class.
        /// </summary>
        /// <param name="priority">The priority.</param>
        /// <param name="dependencyType">Type of the dependency.</param>
        /// <param name="filePath">The file path to the dependency.</param>
        /// <param name="appendUmbracoPath">if set to <c>true</c> the current umbraco path will be prefixed to the filePath.</param>
        /// <param name="invokeJavascriptMethodOnLoad">The name of the Javascript method to invoke when the dependency is loaded.</param>
        public ClientDependencyAttribute(int priority, ClientDependencyType dependencyType, string filePath, bool appendUmbracoPath, string invokeJavascriptMethodOnLoad)
        {
            if (String.IsNullOrEmpty(filePath))
                throw new ArgumentException("filePath");

            Priority = priority;
            FilePath = appendUmbracoPath ? GlobalSettings.Path + "/" + filePath : filePath;
            DependencyType = dependencyType;
            InvokeJavascriptMethodOnLoad = invokeJavascriptMethodOnLoad ?? String.Empty;

            ClientDependencyLoader.Instance.RegisterDependency(FilePath, DependencyType == ClientDependencyType.Css ? ClientDependency.Core.ClientDependencyType.Css : ClientDependency.Core.ClientDependencyType.Javascript);
        }
	    /// <summary>
	    /// combines all files to a byte array
	    /// </summary>
	    /// <param name="filePaths"></param>
	    /// <param name="context"></param>
	    /// <param name="type"></param>
	    /// <param name="fileDefs"></param>
	    /// <returns></returns>
	    public override byte[] CombineFiles(string[] filePaths, HttpContextBase context, ClientDependencyType type, out List<CompositeFileDefinition> fileDefs)
		{
	        var ms = new MemoryStream(5000);            
            var sw = new StreamWriter(ms, Encoding.UTF8);

	        var fDefs = filePaths.Select(s => WritePathToStream(type, s, context, sw)).Where(def => def != null).ToList();

	        sw.Flush();
			byte[] outputBytes = ms.ToArray();
			sw.Close();
			ms.Close();
			fileDefs = fDefs;
			return outputBytes;
		}
예제 #16
0
 public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
 {
     try
     {
         //if it is a file based dependency then read it
         var fileContents = File.ReadAllText(fi.FullName, Encoding.UTF8); //read as utf 8
         WriteContentToStream(provider, sw, fileContents, type, http, origUrl);
         return true;
     }
     catch (Exception ex)
     {
         ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
         return false;
     }
 }
        public static bool Parse(string pathBasedUrlFormat, string path, out string fileKey, out ClientDependencyType type, out int version)
        {
            try
            {
                //start parsing from the end
                var typeIndex = pathBasedUrlFormat.IndexOf("{type}");
                var versionIndex = pathBasedUrlFormat.IndexOf("{version}");

                var typeDelimiter = pathBasedUrlFormat.Substring(versionIndex + "{version}".Length, typeIndex - (versionIndex + "{version}".Length));
                var typeAsString = "";
                for (var i = path.Length - 1; i > path.LastIndexOf(typeDelimiter) + (typeDelimiter.Length - 1); i--)
                {
                    typeAsString += path[i];
                }
                typeAsString = typeAsString.ReverseString().ToUpper();

                var versionDelimiter = pathBasedUrlFormat.Substring("{dependencyId}".Length, versionIndex - ("{dependencyId}".Length));
                var versionAsString = "";
                for (var i = path.LastIndexOf(typeDelimiter) - 1;
                    i > path.Substring(0, path.LastIndexOf(typeDelimiter)).LastIndexOf(versionDelimiter) + (typeDelimiter.Length - 1); i--)
                {
                    versionAsString += path[i];
                }
                versionAsString = versionAsString.ReverseString();

				//var p = path.IndexOf(versionDelimiter);
				//fileKey = p > 0 ? path.Substring(0, p) : "";
                fileKey = path.Substring(0, path.Substring(0, path.LastIndexOf(typeDelimiter)).LastIndexOf(versionDelimiter));
                //there may be '/' in the fileKey since we add additional paths when the max path length is exceeded
                fileKey = fileKey.Replace("/", "");

                type = typeAsString == "js".ToUpper() ? ClientDependencyType.Javascript : ClientDependencyType.Css;
                if (!int.TryParse(versionAsString, out version))
                {
                    return false;
                }

                return true;
            }
            catch (ArgumentOutOfRangeException)
            {
                fileKey = "";
                version = -1;
                type = ClientDependencyType.Javascript;
                return false;
            }

        }
예제 #18
0
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {
                //NOTE: We don't want this compressed since CDF will do that ourselves
                var output = Compiler.Compile(fi.FullName, false, new List<string>());

                DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);

                return true;
            }
            catch (Exception ex)
            {
                ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
                return false;
            }
        }
예제 #19
0
 public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
 {
     try
     {
         //if it is a file based dependency then read it
         using (var fileStream = fi.OpenRead())
         {
             WriteContentToStream(provider, sw, fileStream, type, http, origUrl);
         }
         return true;
     }
     catch (Exception ex)
     {
         ClientDependencySettings.Instance.Logger.Error($"Could not write file {fi.FullName} contents to stream. EXCEPTION: {ex.Message}", ex);
         return false;
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ClientDependencyAttribute"/> class.
        /// </summary>
        /// <param name="group"></param>
        /// <param name="priority">The priority.</param>
        /// <param name="dependencyType">Type of the dependency.</param>
        /// <param name="fileName"></param>
        /// <param name="pathNameAlias"></param>
        public ClientDependencyAttribute(int group, int priority, ClientDependencyType dependencyType, string fileName, string pathNameAlias, bool forceBundle)
        {
            if (String.IsNullOrEmpty(fileName))
                throw new ArgumentNullException("fileName");

            Priority = priority;

            Group = group;

            FilePath = fileName;
            PathNameAlias = pathNameAlias;

            DependencyType = dependencyType;
			ForceBundle = forceBundle;

            HtmlAttributes = new Dictionary<string, string>();
        }
		/// <summary>
		/// Saves the file's bytes to disk with a hash of the byte array
		/// </summary>
		/// <param name="fileContents"></param>
		/// <param name="type"></param>
		/// <returns>The new file path</returns>
		/// <remarks>
		/// the extension will be: .cdj for JavaScript and .cdc for CSS
		/// </remarks>
		public static string SaveCompositeFile(byte[] fileContents, ClientDependencyType type)
		{
            //don't save the file if composite files are disabled.
            if (!ClientDependencySettings.Instance.EnableCompositeFiles)
                return string.Empty;

			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;
		}
예제 #22
0
 /// <summary>
 /// The write to stream.
 /// </summary>
 /// <param name="provider">
 /// The provider.
 /// </param>
 /// <param name="sw">
 /// The sw.
 /// </param>
 /// <param name="vf">
 /// The vf.
 /// </param>
 /// <param name="type">
 /// The type.
 /// </param>
 /// <param name="origUrl">
 /// The orig url.
 /// </param>
 /// <param name="http">
 /// The http.
 /// </param>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, IVirtualFile vf, ClientDependencyType type, string origUrl, HttpContextBase http)
 {
     try
     {
         using (var readStream = vf.Open())
         using (var streamReader = new StreamReader(readStream))
         {
             var output = streamReader.ReadToEnd();
             DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);
             return true;
         }
     }
     catch (Exception)
     {
         // the file must have failed to open
         return false;
     }
 }
        /// <summary>
        /// Adds an embedded resource to the ClientDependency output by name
        /// </summary>
        /// <param name="ctl">The control.</param>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="type">The type of resource.</param>
        public static void AddResourceToClientDependency(this Control ctl, string resourceName, ClientDependencyType type)
        {
            // get the urls for the embedded resources
            var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(ctl.GetType(), resourceName);

            switch (type)
            {
                case ClientDependencyType.Css:
                    ctl.Page.Header.Controls.Add(new LiteralControl("<link type='text/css' rel='stylesheet' href='" + resourceUrl + "'/>"));
                    break;

                case ClientDependencyType.Javascript:
                    ctl.Page.ClientScript.RegisterClientScriptResource(typeof(ResourceExtensions), resourceName);
                    break;

                default:
                    break;
            }
        }
예제 #24
0
        /// <summary>
        /// Returns a URL used to return a compbined/compressed/optimized version of all dependencies.
        /// <remarks>
        /// The full url with the encoded query strings for the handler which will process the composite list
        /// of dependencies. The handler will compbine, compress, minify, and output cache the results
        /// on the base64 encoded string.
        /// </remarks>        
        /// </summary>
        /// <param name="dependencies"></param>
        /// <param name="type"></param>
        /// <param name="http"></param>
        /// <returns>An array containing the list of composite file URLs. This will generally only contain 1 value unless
        /// the number of files registered exceeds the maximum length, then it will return more than one file.</returns>
        public string[] ProcessCompositeList(List<IClientDependencyFile> dependencies, ClientDependencyType type, HttpContextBase http)
        {
            if (dependencies.Count == 0)
                return new string[] { };

            //build the combined composite list urls
            var files = new List<string>();
            var currBuilder = new StringBuilder();
            var builderCount = 1;
            var stringType = type.ToString();
            foreach (var a in dependencies)
            {
                //if the addition of this file is going to exceed 75% of the max length (since we'll be base64 encoding), we'll need to split
                if ((currBuilder.Length +
                    a.FilePath.Length +
                    ClientDependencySettings.Instance.CompositeFileHandlerPath.Length +
                    stringType.Length + 10) >= (CompositeDependencyHandler.MaxHandlerUrlLength * 0.75))
                {
                    //add the current output to the array
                    files.Add(currBuilder.ToString());
                    //create some new output
                    currBuilder = new StringBuilder();
                    builderCount++;
                }

                currBuilder.Append(a.FilePath + ";");
            }

            if (builderCount > files.Count)
            {
                files.Add(currBuilder.ToString());
            }

            //now, compress each url
            for (var i = 0; i < files.Count; i++)
            {
                //append our version to the combined url
                files[i] = AppendVersionQueryString(GetCompositeFileUrl(files[i], type, http));
            }

            return files.ToArray();
        }
        /// <summary>
        ///   Adds an embedded resource to the ClientDependency output by name
        /// </summary>
        /// <param name = "page">The Page to add the resource to</param>
        /// <param name = "resourceContainer">The type containing the embedded resourcre</param>
        /// <param name = "resourceName">Name of the resource.</param>
        /// <param name = "type">The type.</param>
        /// <param name = "priority">The priority.</param>
        public static void AddResourceToClientDependency(this Page page, Type resourceContainer, string resourceName, ClientDependencyType type, int priority)
        {
            // get the urls for the embedded resources
            var resourceUrl = page.ClientScript.GetWebResourceUrl(resourceContainer, resourceName);

            switch (type)
            {
                case ClientDependencyType.Css:
                    page.Header.Controls.Add(
                        new LiteralControl(string.Format("<link type='text/css' rel='stylesheet' href='{0}' />", page.Server.HtmlEncode(resourceUrl))));
                    break;

                case ClientDependencyType.Javascript:
                    page.Header.Controls.Add(
                        new LiteralControl(string.Format("<script type='text/javascript' src='{0}'></script>", page.Server.HtmlEncode(resourceUrl))));
                    break;

                default:
                    break;
            }
        }
예제 #26
0
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {

                //if it is a file based dependency then read it
                var fileContents = File.ReadAllText(fi.FullName, Encoding.UTF8); //read as utf 8

                //NOTE: passing in null will automatically for the web configuration section to be loaded in!
                var output = LessWeb.Parse(fileContents, null);

                DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);

                return true;
            }
            catch (Exception ex)
            {
                ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
                return false;
            }
        }
	    /// <summary>
	    /// Saves the file's bytes to disk with a hash of the byte array
	    /// </summary>
	    /// <param name="fileContents"></param>
	    /// <param name="type"></param>
	    /// <param name="server"></param>
	    /// <returns>The new file path</returns>
	    /// <remarks>
	    /// the extension will be: .cdj for JavaScript and .cdc for CSS
	    /// </remarks>
	    public override FileInfo SaveCompositeFile(byte[] fileContents, ClientDependencyType type, HttpServerUtilityBase server, int version)
		{
            //don't save the file if composite files are disabled.
            if (!PersistCompositeFiles)
                return null;

            if (!CompositeFilePath.Exists)
                CompositeFilePath.Create();
			
            var fi = new FileInfo(
                Path.Combine(CompositeFilePath.FullName,
					version + "_" + Guid.NewGuid().ToString("N") + ".cd" + type.ToString().Substring(0, 1).ToUpper()));
			
            if (fi.Exists)
				fi.Delete();
			
            var fs = fi.Create();
			fs.Write(fileContents, 0, fileContents.Length);
			fs.Close();
			return fi;
		}
        /// <summary>Minifies the given <paramref name="fileContents"/>.</summary>
        /// <param name="fileContents">The contents of the file.</param>
        /// <param name="type">The type of the resource.</param>
        /// <returns>The minified or full contents of <paramref name="fileContents"/>, based on the minification configuration.</returns>
        protected override string MinifyFile(string fileContents, ClientDependencyType type)
        {
            if (type == ClientDependencyType.Css && this.MinifyCss)
            {
                var minifiedCss = this.minifier.MinifyStyleSheet(fileContents, CssSettings);
                if (!this.minifier.ErrorList.Any(error => error.IsError))
                {
                    return minifiedCss;
                }
            }

            if (type == ClientDependencyType.Javascript && this.MinifyJs)
            {
                var minifiedScript = this.minifier.MinifyJavaScript(fileContents, JsSettings);
                if (!this.minifier.ErrorList.Any(error => error.IsError))
                {
                    return minifiedScript;
                }
            }

            return fileContents;
        }
		/// <summary>
		/// Adds an embedded resource to the ClientDependency output by name
		/// </summary>
		/// <param name="page">The Page to add the resource to</param>
		/// <param name="resourceContainer">The type containing the embedded resourcre</param>
		/// <param name="resourceName">Name of the resource.</param>
		/// <param name="type">The type.</param>
		/// <param name="priority">The priority.</param>
		public static void AddResourceToClientDependency(this Page page, Type resourceContainer, string resourceName, ClientDependencyType type, int priority)
		{
			// get the urls for the embedded resources
			var resourceUrl = page.ClientScript.GetWebResourceUrl(resourceContainer, resourceName);


            Control target = page.Header;
            if (target != null) //if there's no <head runat="server" /> don't throw an exception.
            {                

                ////// check the Umbraco version, v4.6.0 shipped with ClientDependency 1.2
                ////if (GlobalSettings.VersionMajor >= 4 && GlobalSettings.VersionMinor >= 6)
                ////{
                ////    // add the resources to client dependency
                ////    ClientDependencyLoader.Instance.RegisterDependency(resourceUrl, type);
                ////}
                ////else
                ////{
                // Umbraco v4.5.x shipped with earlier version of ClientDependency - which had an issue with querystrings in virtual paths.
                switch (type)
                {
                    case ClientDependencyType.Css:
                        target.Controls.Add(
                            new LiteralControl("<link type='text/css' rel='stylesheet' href='" + page.Server.HtmlEncode(resourceUrl) + "' />"));
                        break;

                    case ClientDependencyType.Javascript:
                        target.Controls.Add(
                            new LiteralControl("<script type='text/javascript' src='" + page.Server.HtmlEncode(resourceUrl) + "'></script>"));
                        break;

                    default:
                        break;
                }
            }
			////}
		}
        /// <summary>
        /// Adds an embedded resource to the ClientDependency output by name
        /// </summary>
        /// <param name="page">The Page to add the resource to</param>
        /// <param name="resourceContainer">The type containing the embedded resourcre</param>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="type">The type.</param>
        /// <param name="priority">The priority.</param>
        public static void AddResourceToClientDependency(this Page page, Type resourceContainer, string resourceName, ClientDependencyType type, int priority)
        {
            // get the urls for the embedded resources           
            var resourceUrl = page.ClientScript.GetWebResourceUrl(resourceContainer, resourceName);

            Control target = page.Header;
            // if there's no <head runat="server" /> don't throw an exception.
            if (target != null)
            {
                // Umbraco v4.5.x shipped with earlier version of ClientDependency - which had an issue with querystrings in virtual paths.
                switch (type)
                {
                    case ClientDependencyType.Css:
                        target.Controls.Add(
                            new LiteralControl("<link type='text/css' rel='stylesheet' href='" + page.Server.HtmlEncode(resourceUrl) + "' />"));
                        break;

                    case ClientDependencyType.Javascript:
                        target.Controls.Add(
                            new LiteralControl("<script type='text/javascript' src='" + page.Server.HtmlEncode(resourceUrl) + "'></script>"));
                        break;
                }
            }
        }
 public abstract FileInfo SaveCompositeFile(byte[] fileContents, ClientDependencyType type, HttpServerUtilityBase server);
        /// <summary>
        /// When the path type is one of the base64 paths, this will create the composite file urls for all of the dependencies.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="dependencies"></param>
        /// <param name="compositeFileHandlerPath"></param>
        /// <param name="http"></param>
        /// <param name="maxLength">the max length each url can be</param>
        /// <param name="version">the current cdf version</param>
        /// <returns></returns>
        /// <remarks>
        /// Generally there will only be one path returned but his depends on how many dependencies there are and whether the base64 created path will exceed the max url length parameter.
        /// If the string length exceeds it, then we need to creaet multiple paths all of which must be less length than the maximum provided.
        /// </remarks>
        internal IEnumerable <string> GetCompositeFileUrls(
            ClientDependencyType type,
            IClientDependencyFile[] dependencies,
            string compositeFileHandlerPath,
            HttpContextBase http,
            int maxLength,
            int version)
        {
            var files         = new List <string>();
            var currBuilder   = new StringBuilder();
            var base64Builder = new StringBuilder();
            var builderCount  = 1;
            var stringType    = type.ToString();

            var remaining = new Queue <IClientDependencyFile>(dependencies);

            while (remaining.Any())
            {
                var current = remaining.Peek();

                //update the base64 output to get the length
                base64Builder.Append(current.FilePath.EncodeTo64());

                //test if the current base64 string exceeds the max length, if so we need to split
                if ((base64Builder.Length
                     + compositeFileHandlerPath.Length
                     + stringType.Length
                     + version.ToString(CultureInfo.InvariantCulture).Length
                     //this number deals with the ampersands, etc...
                     + 10)
                    >= (maxLength))
                {
                    //we need to do a check here, this is the first one and it's already exceeded the max length we cannot continue
                    if (currBuilder.Length == 0)
                    {
                        throw new InvalidOperationException("The path for the single dependency: '" + current.FilePath + "' exceeds the max length (" + maxLength + "), either reduce the single dependency's path length or increase the CompositeDependencyHandler.MaxHandlerUrlLength value");
                    }

                    //flush the current output to the array
                    files.Add(currBuilder.ToString());
                    //create some new output
                    currBuilder   = new StringBuilder();
                    base64Builder = new StringBuilder();
                    builderCount++;
                }
                else
                {
                    //update the normal builder
                    currBuilder.Append(current.FilePath + ";");
                    //remove from the queue
                    remaining.Dequeue();
                }
            }

            //foreach (var a in dependencies)
            //{
            //    //update the base64 output to get the length
            //    base64Builder.Append(a.FilePath.EncodeTo64());

            //    //test if the current base64 string exceeds the max length, if so we need to split
            //    if ((base64Builder.Length
            //        + compositeFileHandlerPath.Length
            //        + stringType.Length
            //        + version.Length
            //        + 10)
            //        >= (maxLength))
            //    {
            //        //add the current output to the array
            //        files.Add(currBuilder.ToString());
            //        //create some new output
            //        currBuilder = new StringBuilder();
            //        base64Builder = new StringBuilder();
            //        builderCount++;
            //    }

            //    //update the normal builder
            //    currBuilder.Append(a.FilePath + ";");
            //}

            if (builderCount > files.Count)
            {
                files.Add(currBuilder.ToString());
            }

            //now, compress each url
            for (var i = 0; i < files.Count; i++)
            {
                //append our version to the combined url
                var encodedFile = files[i].EncodeTo64Url();
                files[i] = GetCompositeFileUrl(encodedFile, type, http, UrlType, compositeFileHandlerPath, version);
            }

            return(files.ToArray());
        }
예제 #33
0
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {
                //if it is a file based dependency then read it
                var fileContents = File.ReadAllText(fi.FullName, Encoding.UTF8); //read as utf 8

                var output = GetOutput(fileContents);

                DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);

                return(true);
            }
            catch (Exception ex)
            {
                ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
                return(false);
            }
        }
예제 #34
0
 public void RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type, string provider)
 {
     RegisterDependency(group, priority, filePath, pathNameAlias, type, provider, false);
 }
예제 #35
0
 public void RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type, object htmlAttributes, string provider)
 {
     RegisterDependency(group, priority, filePath, pathNameAlias, type, htmlAttributes, null, false);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ClientResourceAttribute"/> class.
 /// </summary>
 /// <param name="path">The path.</param>
 /// <param name="priority">The priority.</param>
 /// <param name="targets">The targets.</param>
 /// <param name="type">The type.</param>
 public ClientResourceAttribute(string path, int priority, string targets, ClientDependencyType type)
 {
     this.ClientResource = new ClientResource(path, priority, targets, type);
 }
예제 #37
0
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {
                //if it is a file based dependency then read it
                var fileContents = File.ReadAllText(fi.FullName, Encoding.UTF8); //read as utf 8

                //for our custom file reader to work we just need to put the origUrl into the httpcontext items so
                //we can retreive it in the reader to then figure out the 'real' requested path.
                http.Items["Cdf_LessWriter_origUrl"] = origUrl;
                //get the default less config
                var config = DotlessConfiguration.GetDefaultWeb();
                //set the file reader to our custom file reader
                config.LessSource = typeof(CdfFileReader);
                //disable cache for this engine since we are already caching our own, plus enabling this will cause errors because
                // the import paths aren't resolved properly.
                config.CacheEnabled = false;
                //get the engine based on the custom config with our custom file reader
                var lessEngine = LessWeb.GetEngine(config);

                var output = lessEngine.TransformToCss(fileContents, origUrl);

                DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);

                return(true);
            }
            catch (Exception ex)
            {
                ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
                return(false);
            }
        }
예제 #38
0
        internal byte[] ProcessRequestInternal(HttpContextBase context, string fileset, ClientDependencyType type, int version, byte[] outputBytes)
        {
            //get the compression type supported
            var clientCompression = context.GetClientCompression();

            //get the map to the composite file for this file set, if it exists.
            var map = ClientDependencySettings.Instance.DefaultFileMapProvider.GetCompositeFile(fileset, version, clientCompression.ToString());

            string compositeFileName = "";

            if (map != null && map.HasFileBytes)
            {
                ProcessFromFile(context, map, out compositeFileName, out outputBytes);
            }
            else
            {
                lock (Lock)
                {
                    //check again...
                    if (map != null && map.HasFileBytes)
                    {
                        //there's files there now, so process them
                        ProcessFromFile(context, map, out compositeFileName, out outputBytes);
                    }
                    else
                    {
                        List <CompositeFileDefinition> fileDefinitions;
                        byte[] fileBytes;

                        if (ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.UrlType == CompositeUrlType.MappedId)
                        {
                            //need to try to find the map by it's id/version (not compression)
                            var filePaths = ClientDependencySettings.Instance.DefaultFileMapProvider.GetDependentFiles(fileset, version);

                            if (filePaths == null)
                            {
                                throw new KeyNotFoundException("no map was found for the dependency key: " + fileset +
                                                               " ,CompositeUrlType.MappedId requires that a map is found");
                            }

                            //combine files and get the definition types of them (internal vs external resources)
                            fileBytes = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider
                                        .CombineFiles(filePaths.ToArray(), context, type, out fileDefinitions);
                        }
                        else
                        {
                            //need to do the combining, etc... and save the file map
                            fileBytes = GetCombinedFiles(context, fileset, type, out fileDefinitions);
                        }

                        //compress data
                        outputBytes = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.CompressBytes(clientCompression, fileBytes);
                        context.AddCompressionResponseHeader(clientCompression);

                        //save combined file
                        var compositeFile = ClientDependencySettings.Instance
                                            .DefaultCompositeFileProcessingProvider
                                            .SaveCompositeFile(outputBytes, type, context.Server, version);

                        if (compositeFile != null)
                        {
                            compositeFileName = compositeFile.FullName;
                            if (!string.IsNullOrEmpty(compositeFileName))
                            {
                                //Update the XML file map
                                ClientDependencySettings.Instance.DefaultFileMapProvider.CreateUpdateMap(fileset, clientCompression.ToString(),
                                                                                                         fileDefinitions.Select(x => new BasicFile(type)
                                {
                                    FilePath = x.Uri
                                }).Cast <IClientDependencyFile>(),
                                                                                                         compositeFileName,
                                                                                                         version);
                            }
                        }
                    }
                }
            }

            SetCaching(context, compositeFileName, fileset, clientCompression);
            return(outputBytes);
        }
 public abstract byte[] CombineFiles(string[] filePaths, HttpContextBase context, ClientDependencyType type, out List <CompositeFileDefinition> fileDefs);
예제 #40
0
 /// <summary>
 /// Registers a file dependency
 /// </summary>
 /// <param name="group"></param>
 /// <param name="priority"></param>
 /// <param name="filePath"></param>
 /// <param name="pathNameAlias"></param>
 /// <param name="type"></param>
 /// <param name="htmlAttributes"></param>
 /// <param name="provider"></param>
 /// <returns></returns>
 public ClientDependencyLoader RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type, object htmlAttributes, string provider)
 {
     _base.RegisterDependency(group, priority, filePath, pathNameAlias, type, htmlAttributes, provider);
     return(this);
 }
예제 #41
0
 /// <summary>
 /// Registers a file dependency
 /// </summary>
 /// <param name="filePath"></param>
 /// <param name="pathNameAlias"></param>
 /// <param name="type"></param>
 public ClientDependencyLoader RegisterDependency(string filePath, string pathNameAlias, ClientDependencyType type)
 {
     _base.RegisterDependency(Constants.DefaultGroup, Constants.DefaultPriority, filePath, pathNameAlias, type);
     return(this);
 }
예제 #42
0
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {
                //NOTE: We don't want this compressed since CDF will do that ourselves
                var output = Compiler.Compile(fi.FullName, false, new List <string>());

                DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);

                return(true);
            }
            catch (Exception ex)
            {
                ClientDependencySettings.Instance.Logger.Error(string.Format("Could not write file {0} contents to stream. EXCEPTION: {1}", fi.FullName, ex.Message), ex);
                return(false);
            }
        }
예제 #43
0
 /// <summary>
 /// Renders the HTML markup placeholder with the default provider name
 /// </summary>
 /// <param name="type"></param>
 /// <param name="paths"></param>
 /// <returns></returns>
 internal string RenderPlaceholder(ClientDependencyType type, IEnumerable <IClientDependencyPath> paths)
 {
     return(RenderPlaceholder(type, Provider.Name, paths));
 }
        /// <summary>
        /// combines all files to a byte array
        /// </summary>
        /// <param name="filePaths"></param>
        /// <param name="context"></param>
        /// <param name="type"></param>
        /// <param name="fileDefs"></param>
        /// <returns></returns>
        public override byte[] CombineFiles(string[] filePaths, HttpContextBase context, ClientDependencyType type, out List <CompositeFileDefinition> fileDefs)
        {
            var fDefs = new List <CompositeFileDefinition>();

            var ms = new MemoryStream(5000);
            var sw = new StreamWriter(ms, Encoding.UTF8);

            foreach (string s in filePaths)
            {
                if (!string.IsNullOrEmpty(s))
                {
                    try
                    {
                        var fi = new FileInfo(context.Server.MapPath(s));
                        if (ClientDependencySettings.Instance.FileBasedDependencyExtensionList.Contains(fi.Extension.ToUpper()))
                        {
                            //if the file doesn't exist, then we'll assume it is a URI external request
                            if (!fi.Exists)
                            {
                                WriteFileToStream(ref sw, s, type, ref fDefs, context);
                            }
                            else
                            {
                                WriteFileToStream(ref sw, fi, type, s, ref fDefs, context);
                            }
                        }
                        else
                        {
                            //if it's not a file based dependency, try to get the request output.
                            WriteFileToStream(ref sw, s, type, ref fDefs, context);
                        }
                    }
                    catch (Exception ex)
                    {
                        Type exType = ex.GetType();
                        if (exType.Equals(typeof(NotSupportedException)) ||
                            exType.Equals(typeof(ArgumentException)) ||
                            exType.Equals(typeof(HttpException)))
                        {
                            //could not parse the string into a fileinfo or couldn't mappath, so we assume it is a URI
                            WriteFileToStream(ref sw, s, type, ref fDefs, context);
                        }
                        else
                        {
                            //if this fails, log the exception in trace, but continue
                            ClientDependencySettings.Instance.Logger.Error(string.Format("Could not load file contents from {0}. EXCEPTION: {1}", s, ex.Message), ex);
                        }
                    }
                }

                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();
            fileDefs = fDefs;
            return(outputBytes);
        }
예제 #45
0
 /// <summary>
 /// Registers a file dependency
 /// </summary>
 public ClientDependencyLoader RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type)
 {
     _base.RegisterDependency(group, priority, filePath, pathNameAlias, type);
     return(this);
 }
        public bool WriteToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, IVirtualFile vf, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            try
            {
                using (var readStream = vf.Open())
                    using (var streamReader = new StreamReader(readStream))
                    {
                        var output = streamReader.ReadToEnd();
                        DefaultFileWriter.WriteContentToStream(provider, sw, output, type, http, origUrl);
                        return(true);
                    }
            }
            catch (Exception exception)
            {
                LogHelper.Warn(typeof(EmbeddedResourceVirtualFileWriter), exception.Message);

                return(false);
            }
        }
예제 #47
0
        /// <summary>
        /// Writes a given path to the stream
        /// </summary>
        /// <param name="type"></param>
        /// <param name="path">The path could be a local url or an absolute url</param>
        /// <param name="context"></param>
        /// <param name="sw"></param>
        /// <returns>If successful returns a CompositeFileDefinition, otherwise returns null</returns>
        public CompositeFileDefinition WritePathToStream(ClientDependencyType type, string path, HttpContextBase context, StreamWriter sw)
        {
            CompositeFileDefinition def = null;

            if (!string.IsNullOrEmpty(path))
            {
                try
                {
                    //var fi = new FileInfo(context.Server.MapPath(path));

                    var extension = Path.GetExtension(path);

                    //all config based extensions and all extensions registered by file writers
                    var fileBasedExtensions = ClientDependencySettings.Instance.FileBasedDependencyExtensionList
                                              .Union(FileWriters.GetRegisteredExtensions());

                    if (fileBasedExtensions.Contains(extension.ToUpper()))
                    {
                        IVirtualFileWriter virtualWriter;
                        if (CanProcessLocally(context, path, out virtualWriter))
                        {
                            //internal request
                            if (virtualWriter != null)
                            {
                                var vf = virtualWriter.FileProvider.GetFile(path);
                                WriteVirtualFileToStream(sw, vf, virtualWriter, type, context);
                            }
                            else
                            {
                                var fi = new FileInfo(context.Server.MapPath(path));
                                WriteFileToStream(sw, fi, type, path, context);
                            }
                        }
                        else
                        {
                            //external request
                            def = WriteFileToStream(sw, path, type, context);
                        }
                    }
                    else
                    {
                        //if it's not a file based dependency, try to get the request output.
                        def = WriteFileToStream(sw, path, type, context);
                    }
                }
                catch (Exception ex)
                {
                    if (ex is NotSupportedException ||
                        ex is ArgumentException ||
                        ex is HttpException)
                    {
                        //could not parse the string into a fileinfo or couldn't mappath, so we assume it is a URI

                        //before we try to load it by URI, we want to check if the URI is a local request, we'll try to detect if it is and
                        // then try to load it from the file system, if the file isn't there then we'll continue trying to load it via the URI.
                        Uri uri;
                        if (Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out uri) && uri.IsLocalUri(context))
                        {
                            var localPath = uri.PathAndQuery;
                            var fi        = new FileInfo(context.Server.MapPath(localPath));
                            if (fi.Exists)
                            {
                                try
                                {
                                    WriteFileToStream(sw, fi, type, path, context); //internal request
                                }
                                catch (Exception ex1)
                                {
                                    ClientDependencySettings.Instance.Logger.Error($"Could not load file contents from {path}. EXCEPTION: {ex1.Message}", ex1);
                                }
                            }
                        }

                        def = WriteFileToStream(sw, path, type, context);
                    }
                    else
                    {
                        //if this fails, log the exception, but continue
                        ClientDependencySettings.Instance.Logger.Error($"Could not load file contents from {path}. EXCEPTION: {ex.Message}", ex);
                    }
                }
            }

            if (type == ClientDependencyType.Javascript)
            {
                sw.Write(";;;"); //write semicolons in case the js isn't formatted correctly. This also helps for debugging.
            }

            return(def);
        }
        /// <summary>
        /// combines all files to a byte array
        /// </summary>
        /// <param name="fileList"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public static byte[] CombineFiles(string[] strFiles, HttpContext context, ClientDependencyType type, out List <CompositeFileDefinition> fileDefs)
        {
            List <CompositeFileDefinition> fDefs = new List <CompositeFileDefinition>();

            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, ref fDefs);
                            }
                            else
                            {
                                WriteFileToStream(ref sw, fi, type, s, ref fDefs);
                            }
                        }
                        else
                        {
                            //if it's not a file based dependency, try to get the request output.
                            WriteFileToStream(ref sw, s, type, ref fDefs);
                        }
                    }
                    catch (Exception ex)
                    {
                        Type exType = ex.GetType();
                        if (exType.Equals(typeof(NotSupportedException)) ||
                            exType.Equals(typeof(ArgumentException)) ||
                            exType.Equals(typeof(HttpException)))
                        {
                            //could not parse the string into a fileinfo or couldn't mappath, so we assume it is a URI
                            WriteFileToStream(ref sw, s, type, ref fDefs);
                        }
                        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();
            fileDefs = fDefs;
            return(outputBytes);
        }
예제 #49
0
 /// <summary>
 /// Registers a file dependency
 /// </summary>
 public ClientDependencyLoader RegisterDependency(int priority, string filePath, ClientDependencyType type)
 {
     _base.RegisterDependency(priority, filePath, type);
     return(this);
 }
예제 #50
0
        internal static IEnumerable <string> OptimizeAssetCollection(IEnumerable <string> assets, ClientDependencyType assetType, HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            var requestUrl = httpContext.Request.Url;

            if (requestUrl == null)
            {
                throw new ArgumentException("HttpContext.Request.Url is null.", nameof(httpContext));
            }

            var dependencies = assets.Select(x =>
            {
                // most declarations with be made relative to the /umbraco folder, so things
                // ike lib/blah/blah.js so we need to turn them into absolutes here
                if (x.StartsWith("/") == false && Uri.IsWellFormedUriString(x, UriKind.Relative))
                {
                    return(new BasicFile(assetType)
                    {
                        FilePath = new Uri(requestUrl, x).AbsolutePath
                    });
                }

                return(assetType == ClientDependencyType.Javascript
                    ? new JavascriptFile(x)
                    : (IClientDependencyFile) new CssFile(x));
            }).ToList();

            // get the output string for these registrations which will be processed by CDF correctly to stagger the output based
            // on internal vs external resources. The output will be delimited based on our custom Umbraco.Web.UI.JavaScript.DependencyPathRenderer
            var renderer = ClientDependencySettings.Instance.MvcRendererCollection["Umbraco.DependencyPathRenderer"];

            renderer.RegisterDependencies(dependencies, new HashSet <IClientDependencyPath>(), out var scripts, out var stylesheets, httpContext);

            var urls = assetType == ClientDependencyType.Javascript
                ? scripts.Split(new[] { DependencyPathRenderer.Delimiter }, StringSplitOptions.RemoveEmptyEntries)
                : stylesheets.Split(new[] { DependencyPathRenderer.Delimiter }, StringSplitOptions.RemoveEmptyEntries);

            return(urls);
        }
예제 #51
0
 /// <inheritdoc />
 /// <summary>
 ///
 /// </summary>
 /// <param name="assetType"></param>
 /// <param name="filePath"></param>
 public AppAssetAttribute(ClientDependencyType assetType, string filePath)
 {
     AssetType = assetType;
     FilePath  = filePath;
 }
예제 #52
0
 /// <summary>
 /// Registers a file dependency
 /// </summary>
 /// <param name="filePath"></param>
 /// <param name="type"></param>
 public ClientDependencyLoader RegisterDependency(string filePath, ClientDependencyType type)
 {
     _base.RegisterDependency(filePath, type);
     return(this);
 }
예제 #53
0
        public void RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type, object htmlAttributes, string provider, bool forceBundle)
        {
            var file = new BasicFile(type)
            {
                Group         = group,
                Priority      = priority,
                FilePath      = filePath,
                PathNameAlias = pathNameAlias,
                ForceProvider = provider,
                ForceBundle   = forceBundle
            };

            //now add the attributes to the list
            foreach (var d in htmlAttributes.ToDictionary())
            {
                file.HtmlAttributes.Add(d.Key, d.Value.ToString());
            }

            RegisterClientDependencies(new List <IClientDependencyFile> {
                file
            }, new List <IClientDependencyPath>());                                                                  //send an empty paths collection
        }
        /// <summary>
        /// Writes a given path to the stream
        /// </summary>
        /// <param name="type"></param>
        /// <param name="path">The path could be a local url or an absolute url</param>
        /// <param name="context"></param>
        /// <param name="sw"></param>
        /// <returns>If successful returns a CompositeFileDefinition, otherwise returns null</returns>
        public CompositeFileDefinition WritePathToStream(ClientDependencyType type, string path, HttpContextBase context, StreamWriter sw)
        {
            path = path.Trim();

            if (string.IsNullOrEmpty(path) || !PathHelper.TryGetFileExtension(path, out var extension))
            {
                return(null);
            }

            CompositeFileDefinition def = null;

            //all config based extensions and all extensions registered by file writers
            var fileBasedExtensions = ClientDependencySettings.Instance.FileBasedDependencyExtensionList
                                      .Union(FileWriters.GetRegisteredExtensions());

            try
            {
                if (fileBasedExtensions.Contains(extension, StringComparer.InvariantCultureIgnoreCase))
                {
                    if (CanProcessLocally(context, path, out IVirtualFileWriter virtualWriter))
                    {
                        //internal request
                        if (virtualWriter != null)
                        {
                            var vf = virtualWriter.FileProvider.GetFile(path);
                            def = WriteVirtualFileToStream(sw, vf, virtualWriter, type, context);
                        }
                        else
                        {
                            if (PathHelper.TryGetFileInfo(path, context, out var fi))
                            {
                                def = WriteFileToStream(sw, fi, type, path, context);
                            }
                        }
                    }
                    else
                    {
                        //Before we try to load it by URI, we want to check if the URI is a local file request.
                        //We can try to detect if it is and try to load it from the file system.
                        //If the file isn't local and doesn't exist then we'll continue trying to load it via the URI.
                        //NOTE: At this stage we've already validated that the file type is based on the file types registered with CDF.
                        if (Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out Uri uri) &&
                            uri.IsLocalUri(context)
                            //extract the path/query of the request and ensure it starts with the virtual path marker (~/) so that the file
                            //can only be looked up local to this website.
                            && PathHelper.TryGetFileInfo(uri.PathAndQuery.EnsureStartsWith("/").EnsureStartsWith("~"), context, out var fi))
                        {
                            def = WriteFileToStream(sw, fi, type, path, context);
                        }
                        else
                        {
                            //external request to a file based dependency
                            def = WriteFileToStream(sw, path, type, context);
                        }
                    }
                }
                else
                {
                    //if it's not a file based dependency, try to get the request output.
                    def = WriteFileToStream(sw, path, type, context);
                }
            }
            catch (Exception ex)
            {
                //if this fails, log the exception, but continue
                ClientDependencySettings.Instance.Logger.Error($"Could not load file contents from {path}. EXCEPTION: {ex.Message}", ex);
            }

            if (def == null)
            {
                return(null);
            }

            if (type == ClientDependencyType.Javascript)
            {
                sw.Write(";;;"); //write semicolons in case the js isn't formatted correctly. This also helps for debugging.
            }

            return(def);
        }
        /// <summary>
        /// Writes the output of an external request to the stream
        /// </summary>
        /// <param name="sw"></param>
        /// <param name="url"></param>
        /// <param name="type"></param>
        /// <param name="http"></param>
        protected virtual CompositeFileDefinition WriteFileToStream(StreamWriter sw, string url, ClientDependencyType type, HttpContextBase http)
        {
            var rVal = RequestHelper.TryReadUri(url, http, BundleDomains, out string requestOutput, out Uri resultUri);

            if (!rVal)
            {
                return(null);
            }

            //write the contents of the external request.
            DefaultFileWriter.WriteContentToStream(this, sw, requestOutput, type, http, url);
            return(new CompositeFileDefinition(url, false));
        }
        /// <summary>
        /// Writes the output of a local file to the stream
        /// </summary>
        /// <param name="sw"></param>
        /// <param name="fi"></param>
        /// <param name="type"></param>
        /// <param name="origUrl"></param>
        /// <param name="http"></param>
        protected virtual CompositeFileDefinition WriteFileToStream(StreamWriter sw, FileInfo fi, ClientDependencyType type, string origUrl, HttpContextBase http)
        {
            //get a writer for the file, first check if there's a specific file writer
            //then check for an extension writer.
            var writer = FileWriters.GetWriterForFile(origUrl);

            if (writer is DefaultFileWriter)
            {
                writer = FileWriters.GetWriterForExtension(fi.Extension);
                if (writer == null)
                {
                    return(null);
                }
            }
            return(writer.WriteToStream(this, sw, fi, type, origUrl, http)
                ? new CompositeFileDefinition(origUrl, true)
                : null);
        }
예제 #57
0
 public void RegisterDependency(int group, int priority, string filePath, string pathNameAlias, ClientDependencyType type, string provider, bool forceBundle)
 {
     RegisterDependency(group, priority, filePath, pathNameAlias, type, null, provider, forceBundle);
 }
        /// <summary>
        /// Writes the output of a local file to the stream
        /// </summary>
        /// <param name="sw"></param>
        /// <param name="vf"></param>
        /// <param name="virtualWriter"></param>
        /// <param name="type"></param>
        /// <param name="http"></param>
        protected virtual CompositeFileDefinition WriteVirtualFileToStream(StreamWriter sw, IVirtualFile vf, IVirtualFileWriter virtualWriter, ClientDependencyType type, HttpContextBase http)
        {
            if (virtualWriter == null)
            {
                throw new ArgumentNullException("virtualWriter");
            }
            if (vf == null)
            {
                return(null);
            }

            return(virtualWriter.WriteToStream(this, sw, vf, type, vf.Path, http)
                ? new CompositeFileDefinition(vf.Path, true)
                : null);
        }
        /// <summary>
        /// Adds an embedded resource to the ClientDependency output by name
        /// </summary>
        /// <param name="ctl">The control.</param>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="type">The type of resource.</param>
        public static void AddResourceToClientDependency(this Control ctl, string resourceName, ClientDependencyType type)
        {
            switch (type)
            {
            case ClientDependencyType.Css:
                // get the urls for the embedded resources
                var resourceUrl = GetWebResourceUrl(ctl, resourceName);
                ctl.Page.Header.Controls.Add(new LiteralControl("<link type='text/css' rel='stylesheet' href='" + resourceUrl + "'/>"));
                break;

            case ClientDependencyType.Javascript:
                ctl.Page.ClientScript.RegisterClientScriptResource(typeof(ResourceExtensions), resourceName);
                break;

            default:
                break;
            }
        }
        /// <summary>
        /// Adds an embedded resource to the ClientDependency output by name
        /// </summary>
        /// <param name="ctl">The CTL.</param>
        /// <param name="resourceName">Name of the resource.</param>
        /// <param name="type">The type.</param>
        public static void AddResourceToClientDependency(this Control ctl, string resourceName, ClientDependencyType type)
        {
            //get the urls for the embedded resources
            //var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(ctl.GetType(), resourceName);
            var resourceUrl = ctl.Page.ClientScript.GetWebResourceUrl(typeof(AbstractPrevalueEditor), resourceName);

            //This only works in v4 currently or until i release CD version 1.2, so in the meantime, we'll use the below method
            //add the resources to client dependency
            //ClientDependencyLoader.Instance.RegisterDependency(resourceUrl, type);

            switch (type)
            {
            case ClientDependencyType.Css:
                ctl.Page.Header.Controls.Add(
                    new LiteralControl("<link type='text/css' rel='stylesheet' href='" + resourceUrl + "' />"));
                break;

            case ClientDependencyType.Javascript:
                ctl.Page.ClientScript.RegisterClientScriptResource(typeof(ResourceExtensions), resourceName);
                break;

            default:
                break;
            }
        }