1 //------------------------------------------------------------------------------ 2 // <copyright file="ScriptReferenceBase.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 namespace System.Web.UI { 8 using System; 9 using System.ComponentModel; 10 using System.Diagnostics.CodeAnalysis; 11 using System.Globalization; 12 using System.Web; 13 using System.Web.Resources; 14 using System.Web.UI.WebControls; 15 using Debug = System.Diagnostics.Debug; 16 17 [ 18 DefaultProperty("Path"), 19 ] 20 public abstract class ScriptReferenceBase { 21 private bool _alwaysLoadBeforeUI; 22 private IClientUrlResolver _clientUrlResolver; 23 private Control _containingControl; 24 private bool _isStaticReference; 25 private bool _notifyScriptLoaded = true; 26 private string _path; 27 private string[] _resourceUICultures; 28 private ScriptMode _scriptMode; 29 ScriptReferenceBase()30 protected ScriptReferenceBase() {} 31 32 internal bool AlwaysLoadBeforeUI { 33 get { 34 return _alwaysLoadBeforeUI; 35 } 36 set { 37 _alwaysLoadBeforeUI = value; 38 } 39 } 40 41 // Used by ScriptManager to associate a ScriptReference with its url resolver 42 // (i.e. ScriptManager or ScriptManagerProxy) 43 internal IClientUrlResolver ClientUrlResolver { 44 get { 45 return _clientUrlResolver; 46 } 47 set { 48 _clientUrlResolver = value; 49 } 50 } 51 52 internal Control ContainingControl { 53 get { 54 return _containingControl; 55 } 56 set { 57 _containingControl = value; 58 } 59 } 60 61 // isStaticReference is true if the reference came from a ScriptManager or ScriptManagerProxy scripts collection, 62 // false if it came from an IScriptControl or ExtenderControl. 63 internal bool IsStaticReference { 64 get { 65 return _isStaticReference; 66 } 67 set { 68 _isStaticReference = value; 69 } 70 } 71 72 // True if this is a reference to a bundle 73 internal bool IsBundleReference { 74 get; 75 set; 76 } 77 78 [ 79 Category("Behavior"), 80 DefaultValue(true), 81 NotifyParentProperty(true), 82 ResourceDescription("ScriptReference_NotifyScriptLoaded"), 83 Obsolete("NotifyScriptLoaded is no longer required in script references.") 84 ] 85 public bool NotifyScriptLoaded { 86 get { 87 return _notifyScriptLoaded; 88 } 89 set { 90 _notifyScriptLoaded = value; 91 } 92 } 93 94 [ 95 Category("Behavior"), 96 DefaultValue(""), 97 NotifyParentProperty(true), 98 ResourceDescription("ScriptReference_Path"), 99 UrlProperty("*.js") 100 ] 101 public string Path { 102 get { 103 return (_path == null) ? String.Empty : _path; 104 } 105 set { 106 _path = value; 107 } 108 } 109 110 [ 111 ResourceDescription("ScriptReference_ResourceUICultures"), 112 DefaultValue(null), 113 Category("Behavior"), 114 MergableProperty(false), 115 NotifyParentProperty(true), 116 TypeConverter(typeof(StringArrayConverter)), 117 SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", 118 Justification = "String[] has existing TypeConverter support, which we don't want to add for List<string> to the assembly just for this property and at this point in the product cycle.") 119 ] 120 public string[] ResourceUICultures { 121 get { 122 return _resourceUICultures; 123 } 124 set { 125 _resourceUICultures = value; 126 } 127 } 128 129 [ 130 Category("Behavior"), 131 DefaultValue(ScriptMode.Auto), 132 NotifyParentProperty(true), 133 ResourceDescription("ScriptReference_ScriptMode") 134 ] 135 public ScriptMode ScriptMode { 136 get { 137 return _scriptMode; 138 } 139 set { 140 if (value < ScriptMode.Auto || value > ScriptMode.Release) { 141 throw new ArgumentOutOfRangeException("value"); 142 } 143 _scriptMode = value; 144 } 145 } 146 147 [Obsolete("Use IsAjaxFrameworkScript(ScriptManager)")] IsFromSystemWebExtensions()148 protected internal abstract bool IsFromSystemWebExtensions(); 149 IsAjaxFrameworkScript(ScriptManager scriptManager)150 protected internal virtual bool IsAjaxFrameworkScript(ScriptManager scriptManager) { 151 return false; 152 } 153 154 internal virtual bool IsDefiningSys { 155 get; 156 set; 157 } 158 159 // Script path may contain a query string, while script name may not 160 // Release: foo.js?key=value 161 // Debug: foo.debug.js?key=value GetDebugPath(string releasePath)162 internal static string GetDebugPath(string releasePath) { 163 // Per RFC 3986, the '?' delimits the query, regardless of the protocol. This overrides 164 // an earlier RFC, which stated that FTP protocol allows '?' as path characters. 165 string pathWithoutQuery; 166 string query; 167 if (releasePath.IndexOf('?') >= 0) { 168 int indexOfQuery = releasePath.IndexOf('?'); 169 pathWithoutQuery = releasePath.Substring(0, indexOfQuery); 170 query = releasePath.Substring(indexOfQuery); 171 } 172 else { 173 pathWithoutQuery = releasePath; 174 query = null; 175 } 176 177 if (!pathWithoutQuery.EndsWith(".js", StringComparison.Ordinal)) { 178 throw new InvalidOperationException( 179 String.Format(CultureInfo.CurrentUICulture, AtlasWeb.ScriptReference_InvalidReleaseScriptPath, pathWithoutQuery)); 180 } 181 182 return ReplaceExtension(pathWithoutQuery) + query; 183 } 184 185 [SuppressMessage("Microsoft.Design", "CA1055", Justification = "Consistent with other URL properties in ASP.NET.")] GetUrl(ScriptManager scriptManager, bool zip)186 protected internal abstract string GetUrl(ScriptManager scriptManager, bool zip); 187 188 // Assumes the input ends with ".js". Replaces the ".js" at the end of the input 189 // with ".debug.js". ReplaceExtension(string pathOrName)190 protected static string ReplaceExtension(string pathOrName) { 191 Debug.Assert(pathOrName.EndsWith(".js", StringComparison.Ordinal)); 192 return (pathOrName.Substring(0, pathOrName.Length - 2) + "debug.js"); 193 } 194 } 195 } 196