Beispiel #1
0
        private void RenderScriptReferences()
        {
            // Get scripts that are added by the framework
            var frameworkScriptPaths = GetFrameworkScripts();

            // Construct smart list
            var smartList = new List <string>();

            // Hard-code WebForms.js - it will be rendered here, and not in Page (like by default)
            smartList.Add(GetUrl(new ScriptReference(this.Page.ClientScript.GetWebResourceUrl(typeof(System.Web.UI.Page), "WebForms.js"))));
            // Add scripts needed by the framework
            smartList.AddRange(frameworkScriptPaths);
            // Add scripts previously added to this control
            smartList.AddRange(this.Scripts.Select(s => GetUrl(s)));
            // Add scripts from the smart loader
            smartList.AddRange(SmartLoader.GetScriptsToLoad());

            // Clear previous scripts (they are now part of smartList)
            Scripts.Clear();

            // Initialize bundling
            var allowJsBundling = PortalContext.Current.BundleOptions.AllowJsBundling;
            var bundle          = allowJsBundling ? new JsBundle() : null;

            // Go through all scripts
            foreach (var spath in smartList)
            {
                var lower = spath.ToLower();

                if (lower.EndsWith(".css"))
                {
                    UITools.AddStyleSheetToHeader(UITools.GetHeader(), spath);
                }
                else
                {
                    var isPostponed       = PortalBundleOptions.JsIsBlacklisted(spath);
                    var isFrameworkScript = frameworkScriptPaths.Contains(spath);

                    if (isPostponed)
                    {
                        _postponedList.Add(spath);
                    }
                    if (allowJsBundling && !isPostponed)
                    {
                        bundle.AddPath(spath);
                    }
                    if (!isPostponed && !isFrameworkScript)
                    {
                        Scripts.Add(new ScriptReference(spath));
                    }
                }
            }

            // Go through postponed scripts
            foreach (var spath in _postponedList)
            {
                Scripts.Add(new ScriptReference(spath));
            }

            // NOTE: At this point, script order is the following:
            // 1) scripts added by the framework
            // 2) scripts added directly to this control
            // 3) scripts from SmartLoader (that are not blacklisted from bundling)
            // 4) scripts from SmartLoader (that are blacklisted from bundling)

            // Finalize bundling
            if (allowJsBundling)
            {
                // If bundling is allowed, close the bundle and process it
                bundle.Close();
                BundleHandler.AddBundleIfNotThere(bundle);
                ThreadPool.QueueUserWorkItem(x => BundleHandler.AddBundleToCache(bundle));

                if (BundleHandler.IsBundleInCache(bundle))
                {
                    // If the bundle is complete, use its path to replace the path of all the scripts that are not postponed
                    _bundle = bundle;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Adds a CSS link to the given header using the given order and parameters. If a link with the given order already exists new link is added right after.
        /// </summary>
        /// <param name="header">Page header</param>
        /// <param name="cssPath">Path of CSS file</param>
        /// <param name="order">Desired order of CSS link</param>
        /// <param name="allowBundlingIfEnabled"></param>
        /// <param name="control">Source control, optional. It will be used to find the current CacheablePortlet and the script reference to it too.</param>
        public static void AddStyleSheetToHeader(Control header, string cssPath, int order, string rel, string type, string media, string title, bool allowBundlingIfEnabled = true, Control control = null)
        {
            if (header == null)
            {
                return;
            }

            if (string.IsNullOrEmpty(cssPath))
            {
                return;
            }

            // Take care of folders
            if (ServiceTools.RecurseFilesInVirtualPath(SkinManager.Resolve(cssPath), true, p => AddStyleSheetToHeader(header, p, order, rel, type, media, title, allowBundlingIfEnabled, control)))
            {
                return;
            }

            var resolvedPath = SkinManager.Resolve(cssPath);

            if (allowBundlingIfEnabled && rel == "stylesheet" && type == "text/css" && PortalBundleOptions.Current.AllowCssBundling)
            {
                if (!string.IsNullOrEmpty(title))
                {
                    throw new Exception("The title attribute on link tags is not supported when CSS bundling is enabled.");
                }

                PortalBundleOptions.Current.EnableCssBundling(header);

                // If this is CSS stylesheet and bundling is enabled, add it to the bundle

                // Find the bundle object for the current media
                var bundle = PortalBundleOptions.Current.CssBundles.SingleOrDefault(x => x.Media == media);

                if (bundle == null)
                {
                    bundle = new CssBundle()
                    {
                        Media = media,
                    };
                    PortalBundleOptions.Current.CssBundles.Add(bundle);
                }

                // Add the current resolved path to the bundle
                if (PortalBundleOptions.CssIsBlacklisted(resolvedPath))
                {
                    bundle.AddPostponedPath(resolvedPath);
                }
                else
                {
                    bundle.AddPath(resolvedPath, order);
                }
            }
            else
            {
                // If bundling is disabled, fallback to the old behaviour

                var cssLink = new HtmlLink();
                cssLink.ID = "cssLink_" + resolvedPath.GetHashCode().ToString();

                // link already added to header
                if (header.FindControl(cssLink.ID) != null)
                {
                    return;
                }

                cssLink.Href = resolvedPath;
                cssLink.Attributes["rel"]      = rel;
                cssLink.Attributes["type"]     = type;
                cssLink.Attributes["media"]    = media;
                cssLink.Attributes["title"]    = title;
                cssLink.Attributes["cssorder"] = order.ToString();

                // find next control with higher order
                var  index = -1;
                bool found = false;
                foreach (Control headerControl in header.Controls)
                {
                    index++;

                    var link = headerControl as HtmlLink;
                    if (link == null)
                    {
                        continue;
                    }

                    var orderStr = link.Attributes["cssorder"];
                    if (string.IsNullOrEmpty(orderStr))
                    {
                        continue;
                    }

                    int linkOrder = Int32.MinValue;
                    if (Int32.TryParse(orderStr, out linkOrder) && linkOrder > order)
                    {
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    // add link right before higher order link
                    header.Controls.AddAt(index, cssLink);
                }
                else
                {
                    // add link at end of header's controlcollection
                    header.Controls.Add(cssLink);
                }
            }

            // Add stylesheet reference to cacheable portlet if possible, to
            // be able to add references even if the portlet html is cached.
            var cb = GetCacheablePortlet(control);

            if (cb != null)
            {
                cb.AddStyleSheet(new StyleSheetReference
                {
                    CssPath = cssPath,
                    Media   = media,
                    Order   = order,
                    Rel     = rel,
                    Title   = title,
                    Type    = type,
                    AllowBundlingIfEnabled = allowBundlingIfEnabled
                });
            }
        }
Beispiel #3
0
        private void RenderScriptReferences()
        {
            var           smartList       = SmartLoader.GetScriptsToLoad();
            var           allowJsBundling = PortalContext.Current.BundleOptions.AllowJsBundling;
            JsBundle      bundle          = null;
            List <string> postponedList   = null;

            if (allowJsBundling)
            {
                bundle        = new JsBundle();
                postponedList = new List <string>();
            }

            foreach (var spath in smartList)
            {
                var lower = spath.ToLower();

                if (lower.EndsWith(".css"))
                {
                    UITools.AddStyleSheetToHeader(UITools.GetHeader(), spath);
                }
                else
                {
                    if (allowJsBundling)
                    {
                        // If bundling is allowed, add the path to the bundle - if it is not blacklisted
                        if (PortalBundleOptions.JsIsBlacklisted(spath))
                        {
                            postponedList.Add(spath);
                        }
                        else
                        {
                            bundle.AddPath(spath);
                        }
                    }
                    else
                    {
                        // If bundling is disabled, fall back to the old behaviour
                        var sref = new ScriptReference(spath);
                        Scripts.Add(sref);
                    }
                }
            }

            if (allowJsBundling)
            {
                // If bundling is allowed, closing the bundle and adding it as a single script reference
                bundle.Close();
                BundleHandler.AddBundleIfNotThere(bundle);
                ThreadPool.QueueUserWorkItem(x => BundleHandler.AddBundleToCache(bundle));

                if (BundleHandler.IsBundleInCache(bundle))
                {
                    // If the bundle is complete, add it as a single script reference
                    var sref = new ScriptReference("/sn-bundles/" + bundle.FakeFilename);
                    Scripts.Add(sref);
                }
                else
                {
                    // The bundle will be complete in a few seconds; disallow caching the page until then
                    this.Page.Response.Cache.SetCacheability(HttpCacheability.NoCache);

                    // Fallback to adding every script again as separate script references
                    foreach (var path in bundle.Paths)
                    {
                        var sref = new ScriptReference(path);
                        Scripts.Add(sref);
                    }
                }

                //add blacklisted js path's to the script collection individually
                foreach (var path in postponedList)
                {
                    Scripts.Add(new ScriptReference(path));
                }
            }
        }