/// <summary> /// Deserialize a list of ScriptEntries /// </summary> /// <remarks> /// Serialized list looks like: /// ;Assembly1.dll Version=1:Culture:MVID1:ScriptName1Hash:ScriptName2Hash;Assembly2.dll Version=2:Culture:MVID1:ScriptName3Hash /// </remarks> /// <param name="serializedScriptEntries">serialized list</param> /// <param name="loaded">loaded state of the serialized scripts</param> /// <returns>list of scripts</returns> private static List <ScriptEntry> DeserializeScriptEntries(string serializedScriptEntries, bool loaded) { List <ScriptEntry> scriptEntries = new List <ScriptEntry>(); foreach (string assemblyScripts in serializedScriptEntries.Split(';')) { // Deserialize this assembly's scripts string assembly = null; string culture = null; string mvid = null; Dictionary <string, string> resourceNameHashToResourceName = null; foreach (string script in assemblyScripts.Split(':')) { if (null == assembly) { // Haven't got the assembly name yet; this is it assembly = script; } else if (null == culture) { // Haven't got the culture value yet; this is it culture = script; } else if (null == mvid) { // Haven't got the MVID value yet; this is it mvid = script; } else { if (null == resourceNameHashToResourceName) { // Populate the "resource name hash to resource name" dictionary for this assembly resourceNameHashToResourceName = new Dictionary <string, string>(); foreach (string resourceName in (new ScriptEntry(assembly, null, null)).LoadAssembly().GetManifestResourceNames()) { string hashCode = resourceName.GetHashCode().ToString("x", CultureInfo.InvariantCulture); if (resourceNameHashToResourceName.ContainsKey(hashCode)) { // Hash collisions are exceedingly rare, but possible throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Assembly \"{0}\" contains multiple scripts with hash code \"{1}\".", assembly, hashCode)); } resourceNameHashToResourceName[hashCode] = resourceName; } } // Map the script hash to a script name string scriptName; if (!resourceNameHashToResourceName.TryGetValue(script, out scriptName)) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Assembly \"{0}\" does not contain a script with hash code \"{1}\".", assembly, script)); } // Create a ScriptEntry to represent the script ScriptEntry scriptEntry = new ScriptEntry(assembly, scriptName, culture); scriptEntry.Loaded = loaded; scriptEntries.Add(scriptEntry); } } } return(scriptEntries); }
/// <summary> /// Checks if the specified ScriptEntry is combinable /// </summary> /// <param name="scriptEntry">ScriptEntry to check</param> /// <returns>true iff combinable</returns> private static bool IsScriptCombinable(ScriptEntry scriptEntry) { // Load the script's assembly and look for ScriptCombineAttribute bool combinable = false; Assembly assembly = scriptEntry.LoadAssembly(); foreach (ScriptCombineAttribute scriptCombineAttribute in GetScriptCombineAttributes(assembly)) { if (string.IsNullOrEmpty(scriptCombineAttribute.IncludeScripts)) { // If the IncludeScripts property is empty, all scripts are combinable by default combinable = true; } else { // IncludeScripts specifies the combinable scripts foreach (string includeScript in scriptCombineAttribute.IncludeScripts.Split(',')) { // If this script name matches, it's combinable if (0 == string.Compare(scriptEntry.Name, includeScript.Trim(), StringComparison.OrdinalIgnoreCase)) { combinable = true; break; } } } if (!string.IsNullOrEmpty(scriptCombineAttribute.ExcludeScripts)) { // ExcludeScripts specifies the non-combinable scripts (and overrides IncludeScripts) foreach (string excludeScript in scriptCombineAttribute.ExcludeScripts.Split(',')) { // If the script name matches, it's not combinable if (0 == string.Compare(scriptEntry.Name, excludeScript.Trim(), StringComparison.OrdinalIgnoreCase)) { combinable = false; break; } } } } if (combinable) { // Make sure the script has an associated WebResourceAttribute (else ScriptManager wouldn't have served it) bool correspondingWebResourceAttribute = false; foreach (WebResourceAttribute webResourceAttribute in GetWebResourceAttributes(assembly)) { if (scriptEntry.Name == webResourceAttribute.WebResource) { correspondingWebResourceAttribute = true; break; } } // Don't allow it to be combined if not combinable &= correspondingWebResourceAttribute; } return(combinable); }
/// <summary> /// Register script reference to script entries. /// </summary> /// <param name="scriptReference"></param> public void RegisterScriptReference(ScriptReference scriptReference) { if (_scriptEntries == null) { _scriptEntries = new List <ScriptEntry>(); } var scriptEntry = _scriptEntries.FirstOrDefault( s => s.LoadAssembly().FullName == scriptReference.Assembly && s.Name == scriptReference.Name); if (scriptEntry == null) { scriptEntry = new ScriptEntry(scriptReference); _scriptEntries.Add(scriptEntry); } scriptEntry.Loaded = true; }
protected override void OnResolveScriptReference(ScriptReferenceEventArgs e) { base.OnResolveScriptReference(e); ScriptReference script = e.Script; ScriptEntry item = new ScriptEntry(script); if (this.ScriptsBuckets != null) { foreach (CombinableScripts combinableScripts in this.ScriptsBuckets) { if (combinableScripts.Scripts.Contains(item)) { script.Name = string.Empty; script.Assembly = string.Empty; script.Path = base.ResolveUrl(this.ScriptsPath + combinableScripts.Alias.ToLower() + ".js"); if (combinableScripts.HasScriptResources) { this.AddScriptResourceLink(combinableScripts.Alias); } break; } } } }
/// <summary> /// Equals override to compare two ScriptEntry objects /// </summary> /// <param name="obj">comparison object</param> /// <returns>true iff both ScriptEntries represent the same script</returns> public override bool Equals(object obj) { ScriptEntry other = (ScriptEntry)obj; return((other.Assembly == Assembly) && (other.Name == Name)); }
protected override void OnResolveScriptReference(ScriptReferenceEventArgs e) { #if !NET4 && !NET45 ApplyAssembly(e.Script, false); #endif base.OnResolveScriptReference(e); // If combining scripts and this is a candidate script if (_combineScripts && !String.IsNullOrEmpty(e.Script.Assembly) && !String.IsNullOrEmpty(e.Script.Name)) { // Initialize ScriptReference scriptReference = e.Script; ScriptEntry scriptEntry = new ScriptEntry(scriptReference); if (IsScriptCombinable(scriptEntry)) { if (!_scriptEntries.Contains(scriptEntry)) { // Haven't seen this script yet; add it to the list and invalidate the Url _scriptEntries.Add(scriptEntry); _combinedScriptUrl = null; } if (null == _combinedScriptUrl) { // Url is invalid; update it _combinedScriptUrl = String.Format(CultureInfo.InvariantCulture, "{0}?{1}={2}&{3}={4}", ((null != _combineScriptsHandlerUrl) ? _combineScriptsHandlerUrl.ToString() : Page.Request.Path.Replace(" ", "%20")), HiddenFieldParamName, HiddenFieldName, CombinedScriptsParamName, HttpUtility.UrlEncode(SerializeScriptEntries(_scriptEntries, false))); } // Remove the script from the list and track it scriptReference.Name = ""; scriptReference.Assembly = ""; _disabledScriptReferences.Add(scriptReference); // Update the common (combined) Url for all tracked scripts foreach (ScriptReference disabledScriptReference in _disabledScriptReferences) { disabledScriptReference.Path = _combinedScriptUrl; } } else { // See if we've already seen this uncombinable script reference bool alreadySeen = false; foreach (ScriptReference uncombinableScriptReference in _uncombinableScriptReferences) { if ((uncombinableScriptReference.Assembly == scriptReference.Assembly) && (uncombinableScriptReference.Name == scriptReference.Name)) { alreadySeen = true; } } if (!alreadySeen) { // Haven't seen the script reference yet, so we need to stop building the current combined script // file and let the uncombinable script reference be output so as not to alter the ordering of // scripts (which may have dependencies). Update our state so we'll start building a new combined // script file with the next combinable script. // Note: _combinedScriptUrl was initially cleared here. While that's correct behavior (and was // released without issue), not clearing it means that we can omit an unnecessary <script> tag // for the scenario "CombinableA, Uncombinable?, CombinableA, Uncombinable?" because the second // instance of CombinableA will reuse the URL from the first (vs. an empty one) and ScriptManager // will detect and omit the redundant URL. _uncombinableScriptReferences.Add(scriptReference); _disabledScriptReferences.Clear(); foreach (ScriptEntry se in _scriptEntries) { se.Loaded = true; } } } } }
// Token: 0x06000193 RID: 403 RVA: 0x00005E54 File Offset: 0x00004054 public override bool Equals(object obj) { ScriptEntry scriptEntry = (ScriptEntry)obj; return(scriptEntry.Assembly == this.Assembly && scriptEntry.Name == this.Name); }