示例#1
0
        /// <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>();
        }
示例#2
0
 private void Initialize(PathList libraryPath, Func <string, string> mapPathFunc, Func <string, string> resolveUrlFunc)
 {
     ScriptEnvironment = new ScriptEnvironment
     {
         MapPath     = mapPathFunc,
         LibraryPath = libraryPath,
         ResolveUrl  = resolveUrlFunc
     };
 }
示例#3
0
        /// <summary>
        /// Default constructor; creates this ScriptManager for the specified library path &amp; 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);
        }
示例#4
0
 private void Initialize(PathList libraryPath, Func <string, string> mapPathFunc)
 {
     MapPath     = mapPathFunc ?? HttpContext.Current.Server.MapPath;
     LibraryPath = libraryPath ?? new PathList();
 }
示例#5
0
        /// <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));
        }
示例#6
0
        /// <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);
        }