/// <summary> /// Constructor for Script Collection. /// </summary> /// /// <param name="libraryPath"> /// A PathList object containing the libraries to search for dependencies. /// </param> /// <param name="mapPathFunc"> /// The MapPath function, e.g. HttpContext.Current.MapPath /// </param> public ScriptCollection(PathList libraryPath, Func <string, string> mapPathFunc) { MapPath = mapPathFunc; LibraryPath = libraryPath; Scripts = new HashSet <ScriptRef>(); DependenciesOrdered = new List <string>(); //ScriptSources = new HashSet<ScriptRef>(); }
private void Initialize(PathList libraryPath, Func <string, string> mapPathFunc, Func <string, string> resolveUrlFunc) { ScriptEnvironment = new ScriptEnvironment { MapPath = mapPathFunc, LibraryPath = libraryPath, ResolveUrl = resolveUrlFunc }; }
/// <summary> /// Default constructor; creates this ScriptManager for the specified library path & MapPath /// function. /// </summary> /// /// <param name="libraryPath"> /// The paths in the library search path. /// </param> /// <param name="mapPathFunc"> /// The map path function. /// </param> public ScriptManager(PathList libraryPath, Func <string, string> mapPathFunc) { if (mapPathFunc == null) { throw new ArgumentException("The MapPath function cannot be null."); } if (libraryPath == null) { throw new ArgumentException("The LibraryPath cannot be null."); } Initialize(libraryPath, mapPathFunc); }
private void Initialize(PathList libraryPath, Func <string, string> mapPathFunc) { MapPath = mapPathFunc ?? HttpContext.Current.Server.MapPath; LibraryPath = libraryPath ?? new PathList(); }
/// <summary> /// Resolve all script dependencies in the bound CQ document. Scripts that cotain a "data- /// location='head'" attribute will be moved to the head. /// </summary> /// /// <param name="doc"> /// The document to resolve. /// </param> public void ResolveScriptDependencies(CQ doc) { string scriptSelector = "script[src][type='text/javascript'], link[type='text/css']"; //+ (Options.HasFlag(ViewEngineOptions.ProcessAllScripts) ? // "" : ".csquery-script") // + "[src]"; // Filter out non-relative paths (remote URLs) CQ scripts = doc[scriptSelector].Filter(item => { return(!PathList.IsRemoteUrl(item.UrlSource())); }); if (scripts.Length == 0) { return; } // move scripts to head as needed first var toMove = scripts.Filter("[data-location='head']"); var head = doc["head"]; if (toMove.Length > 0) { foreach (var item in toMove) { if (item.ParentNode != head) { head.Append(item); } } } // resolve dependencies ScriptCollection coll = new ScriptCollection(LibraryPath, MapPath); coll.NoCache = Options.HasFlag(ViewEngineOptions.NoCache); coll.IgnoreErrors = Options.HasFlag(ViewEngineOptions.IgnoreMissingScripts); // identify the insertion point for the script bundle var firstScriptEl = coll.AddFromCq(scripts); var firstScript = firstScriptEl == null? head.Children().First() : firstScriptEl.Cq(); string bundleUrl; List <ScriptRef> dependencies = coll.GetDependencies() .Where(item => !coll.Contains(item)) .ToList(); // find the first script with dependencies // Now add scripts directly for depenencies marked as NoCombine. foreach (var item in dependencies.Where(item => item.NoCombine)) { firstScript.Before(GetScriptHtml(item.Path, item.ScriptHash)); } // Before creating the bundle, remove any duplicates of the same script on the page bool hasBundle = Bundles.TryGetValue(coll, out bundleUrl); if (hasBundle) { // when nocache is set, we will regenerate the bundle, but not change the script ID. The v= // flag will be changed by BundleTable. if (Options.HasFlag(ViewEngineOptions.NoCache)) { string removeUrl = "~" + bundleUrl.Before("?"); BundleTable.Bundles.Remove(BundleTable.Bundles.GetBundleFor(removeUrl)); hasBundle = false; ScriptID++; // //var bundleList = BundleTable.Bundles.ToList(); //BundleTable.Bundles.Clear(); //BundleTable.Bundles.ResetAll(); //BundleTable.EnableOptimizations = false; //foreach (var oldBundle in bundleList) //{ // BundleTable.Bundles.Add(oldBundle); //} } } else { ScriptID++; } if (!hasBundle) { string bundleAlias = "~/cqbundle" + ScriptID; var bundle = GetScriptBundle(bundleAlias); var activeDependencies = dependencies.Where(item => !item.NoCombine); foreach (var item in activeDependencies) { bundle.Include(item.Path); } BundleTable.Bundles.Add(bundle); if (HttpContext.Current != null) { bundleUrl = BundleTable.Bundles.ResolveBundleUrl(bundleAlias, true); } else { bundleUrl = bundleAlias + "_no_http_context"; } Bundles[coll] = bundleUrl; } var scriptPlaceholder = scripts.First(); // add bundle after all noncombined scripts firstScript.Before(GetScriptHtml(bundleUrl)); }
/// <summary> /// Gets a script reference given a path. /// </summary> /// /// <exception cref="FileNotFoundException"> /// Thrown when the requested file is not present. /// </exception> /// /// <param name="name"> /// The name to use for this script. /// </param> /// <param name="virtualPath"> /// Virtual path to the script. /// </param> /// /// <returns> /// The script reference. /// </returns> protected ScriptRef GetScriptRef(string name, string virtualPath) { ScriptRef scriptRef; string normalizedPath = PathList.NormalizePath(virtualPath); string normalizedName = PathList.NormalizeName(name); if (ResolvedDependencies.TryGetValue(normalizedName, out scriptRef)) { return(scriptRef); } string fileName; ScriptParser parser = null; try { fileName = MapPath(normalizedPath); parser = new ScriptParser(fileName); } catch (FileNotFoundException e) { if (!IgnoreErrors) { throw e; } } scriptRef = new ScriptRef { Name = normalizedName, Path = normalizedPath }; // Parser can be null if there was an error loading the script, but IgnoreErrors=true. If this // is the case just skip everything, there will be no dependencies. // if (parser != null) { var options = new HashSet <string>(); using (parser) { string line; while ((line = parser.ReadLine()) != null && !parser.AnyCodeYet) { var match = Patterns.Dependency.Match(line); var matchOptions = Patterns.Options.Match(line); if (match.Success) { string depName = match.Groups["dep"].Value; var optGroup = match.Groups["opt"]; scriptRef.Dependencies.Add(new ScriptRef { Name = PathList.NormalizeName(depName), Path = null, NoCombine = optGroup.Captures.Any <Capture>(item => item.Value == "nocombine") }); } else if (matchOptions.Success) { foreach (Group grp in matchOptions.Groups) { options.Add(grp.Value.ToLower()); } } } scriptRef.ScriptHash = parser.FileHash; scriptRef.NoCombine = options.Contains("nocombine"); } } if (!NoCache) { ResolvedDependencies[normalizedName] = scriptRef; } return(scriptRef); }