2 // System.Web.HttpBrowserCapabilities
5 // Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (c) 2003-2009 Novell, Inc. (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Globalization;
34 using System.Web.Configuration;
36 using System.Security.Permissions;
37 using System.Web.Util;
39 namespace System.Web.Configuration
41 public partial class HttpCapabilitiesBase
43 const int HaveActiveXControls = 1; // 1;
44 const int HaveAdapters = 2;
45 const int HaveAOL = 3; // 2;
46 const int HaveBackGroundSounds = 4; // 3;
47 const int HaveBeta = 5; // 4;
48 const int HaveBrowser = 6; // 5;
49 const int HaveBrowsers = 7;
50 const int HaveCanCombineFormsInDeck = 8;
51 const int HaveCanInitiateVoiceCall = 9;
52 const int HaveCanRenderAfterInputOrSelectElement = 10;
53 const int HaveCanRenderEmptySelects = 11;
54 const int HaveCanRenderInputAndSelectElementsTogether = 12;
55 const int HaveCanRenderMixedSelects = 13;
56 const int HaveCanRenderOneventAndPrevElementsTogether = 14;
57 const int HaveCanRenderPostBackCards = 15;
58 const int HaveCanRenderSetvarZeroWithMultiSelectionList = 16;
59 const int HaveCanSendMail = 17;
60 const int HaveCDF = 18; // 6;
61 //const int HaveClrVersion = 19; // 7;
62 const int HaveCookies = 20; // 8;
63 const int HaveCrawler = 21; // 9;
64 const int HaveDefaultSubmitButtonLimit = 22;
65 const int HaveEcmaScriptVersion = 23;
66 const int HaveFrames = 24; // 11;
67 const int HaveGatewayMajorVersion = 25;
68 const int HaveGatewayMinorVersion = 26;
69 const int HaveGatewayVersion = 27;
70 const int HaveHasBackButton = 28;
71 const int HaveHidesRightAlignedMultiselectScrollbars = 29;
72 const int HaveHtmlTextWriter = 30;
73 const int HaveId = 31;
74 const int HaveInputType = 32;
75 const int HaveIsColor = 33;
76 const int HaveIsMobileDevice = 34;
77 const int HaveJavaApplets = 35; // 12;
78 const int HaveJavaScript = 36; // 13;
79 const int HaveJScriptVersion = 37;
80 const int HaveMajorVersion = 38; // 14;
81 const int HaveMaximumHrefLength = 39;
82 const int HaveMaximumRenderedPageSize = 40;
83 const int HaveMaximumSoftkeyLabelLength = 41;
84 const int HaveMinorVersion = 42; // 15;
85 const int HaveMinorVersionString = 43;
86 const int HaveMobileDeviceManufacturer = 44;
87 const int HaveMobileDeviceModel = 45;
88 const int HaveMSDomVersion = 46; // 16;
89 const int HaveNumberOfSoftkeys = 47;
90 const int HavePlatform = 48; // 17;
91 const int HavePreferredImageMime = 49;
92 const int HavePreferredRenderingMime = 50;
93 const int HavePreferredRenderingType = 51;
94 const int HavePreferredRequestEncoding = 52;
95 const int HavePreferredResponseEncoding = 53;
96 const int HaveRendersBreakBeforeWmlSelectAndInput = 54;
97 const int HaveRendersBreaksAfterHtmlLists = 55;
98 const int HaveRendersBreaksAfterWmlAnchor = 56;
99 const int HaveRendersBreaksAfterWmlInput = 57;
100 const int HaveRendersWmlDoAcceptsInline = 58;
101 const int HaveRendersWmlSelectsAsMenuCards = 59;
102 const int HaveRequiredMetaTagNameValue = 60;
103 const int HaveRequiresAttributeColonSubstitution = 61;
104 const int HaveRequiresContentTypeMetaTag = 62;
105 const int HaveRequiresControlStateInSession = 63;
106 const int HaveRequiresDBCSCharacter = 64;
107 const int HaveRequiresHtmlAdaptiveErrorReporting = 65;
108 const int HaveRequiresLeadingPageBreak = 66;
109 const int HaveRequiresNoBreakInFormatting = 67;
110 const int HaveRequiresOutputOptimization = 68;
111 const int HaveRequiresPhoneNumbersAsPlainText = 69;
112 const int HaveRequiresSpecialViewStateEncoding = 70;
113 const int HaveRequiresUniqueFilePathSuffix = 71;
114 const int HaveRequiresUniqueHtmlCheckboxNames = 72;
115 const int HaveRequiresUniqueHtmlInputNames = 73;
116 const int HaveRequiresUrlEncodedPostfieldValues = 74;
117 const int HaveScreenBitDepth = 75;
118 const int HaveScreenCharactersHeight = 76;
119 const int HaveScreenCharactersWidth = 77;
120 const int HaveScreenPixelsHeight = 78;
121 const int HaveScreenPixelsWidth = 79;
122 const int HaveSupportsAccesskeyAttribute = 80;
123 const int HaveSupportsBodyColor = 81;
124 const int HaveSupportsBold = 82;
125 const int HaveSupportsCacheControlMetaTag = 83;
126 const int HaveSupportsCallback = 84;
127 const int HaveSupportsCss = 85;
128 const int HaveSupportsDivAlign = 86;
129 const int HaveSupportsDivNoWrap = 87;
130 const int HaveSupportsEmptyStringInCookieValue = 88;
131 const int HaveSupportsFontColor = 89;
132 const int HaveSupportsFontName = 90;
133 const int HaveSupportsFontSize = 91;
134 const int HaveSupportsImageSubmit = 92;
135 const int HaveSupportsIModeSymbols = 93;
136 const int HaveSupportsInputIStyle = 94;
137 const int HaveSupportsInputMode = 95;
138 const int HaveSupportsItalic = 96;
139 const int HaveSupportsJPhoneMultiMediaAttributes = 97;
140 const int HaveSupportsJPhoneSymbols = 98;
141 const int HaveSupportsQueryStringInFormAction = 99;
142 const int HaveSupportsRedirectWithCookie = 100;
143 const int HaveSupportsSelectMultiple = 101;
144 const int HaveSupportsUncheck = 102;
145 const int HaveSupportsXmlHttp = 103;
146 const int HaveTables = 104; // 18;
147 const int HaveTagWriter = 105; // 19;
148 const int HaveType = 106;
149 const int HaveUseOptimizedCacheKey = 107;
150 const int HaveVBScript = 108; // 20;
151 const int HaveVersion = 109; // 21;
152 const int HaveW3CDomVersion = 110; // 22;
153 const int HaveWin16 = 111; // 23;
154 const int HaveWin32 = 112; // 24;
155 const int LastHaveFlag = 113;
157 BitArray flags = new BitArray (LastHaveFlag);
158 bool activeXControls;
160 bool backgroundSounds;
167 Version ecmaScriptVersion;
173 Version msDomVersion;
179 Version w3CDomVersion;
182 Version [] clrVersions;
183 internal string useragent;
185 public bool ActiveXControls {
187 if (!Get (HaveActiveXControls)) {
188 activeXControls = ReadBoolean ("activexcontrols");
189 Set (HaveActiveXControls);
192 return activeXControls;
198 if (!Get (HaveAOL)) {
199 aol = ReadBoolean ("aol");
207 public bool BackgroundSounds {
209 if (!Get (HaveBackGroundSounds)) {
210 backgroundSounds = ReadBoolean ("backgroundsounds");
211 Set (HaveBackGroundSounds);
214 return backgroundSounds;
220 if (!Get (HaveBeta)) {
221 beta = ReadBoolean ("beta");
229 public string Browser {
231 if (!Get (HaveBrowser)) {
232 browser = this ["browser"];
233 if (browser == null || browser.Length == 0)
242 ArrayList browsers = null;
243 public ArrayList Browsers {
245 if (!Get (HaveBrowsers)) {
246 browsers = ReadArrayList ("browsers");
254 public bool IsBrowser (string browserName)
256 foreach (string browser in Browsers) {
257 if (0 == String.Compare (browser, "Unknown", StringComparison.OrdinalIgnoreCase)) {
260 if (0 == String.Compare (browserName, browser, StringComparison.OrdinalIgnoreCase)) {
269 if (!Get (HaveCDF)) {
270 cdf = ReadBoolean ("cdf");
278 public Version ClrVersion {
280 if (clrVersion == null)
281 InternalGetClrVersions ();
287 public bool Cookies {
289 if (!Get (HaveCookies)) {
290 cookies = ReadBoolean ("cookies");
298 public bool Crawler {
300 if (!Get (HaveCrawler)) {
301 crawler = ReadBoolean ("crawler");
309 public Version EcmaScriptVersion {
311 if (!Get (HaveEcmaScriptVersion)) {
312 ecmaScriptVersion = ReadVersion ("ecmascriptversion");
313 Set (HaveEcmaScriptVersion);
316 return ecmaScriptVersion;
322 if (!Get (HaveFrames)) {
323 frames = ReadBoolean ("frames");
331 public bool JavaApplets {
333 if (!Get (HaveJavaApplets)) {
334 javaApplets = ReadBoolean ("javaapplets");
335 Set (HaveJavaApplets);
343 [Obsolete ("The recommended alternative is the EcmaScriptVersion property. A Major version value greater than or equal to 1 implies JavaScript support. http://go.microsoft.com/fwlink/?linkid=14202")]
344 public bool JavaScript {
346 if (!Get (HaveJavaScript)) {
347 javaScript = ReadBoolean ("javascript");
348 Set (HaveJavaScript);
355 public int MajorVersion {
357 if (!Get (HaveMajorVersion)) {
358 // Try with MS.NET's property name.
359 // See: https://bugzilla.xamarin.com/show_bug.cgi?id=4108
360 if (this["majorversion"] != null)
361 majorVersion = ReadInt32 ("majorversion");
363 majorVersion = ReadInt32 ("majorver");
364 Set (HaveMajorVersion);
371 public double MinorVersion {
373 if (!Get (HaveMinorVersion)) {
374 // Try with MS.NET's property name.
375 // See: https://bugzilla.xamarin.com/show_bug.cgi?id=4108
376 if (this["minorversion"] != null)
377 minorVersion = ReadDouble ("minorversion");
379 minorVersion = ReadDouble ("minorver");
380 Set (HaveMinorVersion);
387 public Version MSDomVersion {
389 if (!Get (HaveMSDomVersion)) {
390 msDomVersion = ReadVersion ("msdomversion");
391 Set (HaveMSDomVersion);
398 public string Platform {
400 if (!Get (HavePlatform)) {
401 platform = ReadString ("platform");
411 if (!Get (HaveTables)) {
412 tables = ReadBoolean ("tables");
420 public Type TagWriter {
422 if (!Get (HaveTagWriter)) {
423 tagWriter = GetTagWriter ();
430 internal virtual Type GetTagWriter ()
432 return typeof (HtmlTextWriter);
437 return Browser + MajorVersion;
441 public bool VBScript {
443 if (!Get (HaveVBScript)) {
444 vbscript = ReadBoolean ("vbscript");
452 public string Version {
454 if (!Get (HaveVersion)) {
455 version = ReadString ("version");
463 public Version W3CDomVersion {
465 if (!Get (HaveW3CDomVersion)) {
466 w3CDomVersion = ReadVersion ("w3cdomversion");
467 Set (HaveW3CDomVersion);
470 return w3CDomVersion;
476 if (!Get (HaveWin16)) {
477 win16 = ReadBoolean ("win16");
487 // This is the list of different windows platforms that browscap.ini has.
488 // Win16 Win2000 Win2003 Win32 Win95 Win98 WinME WinNT WinVI WinXP
489 if (!Get (HaveWin32)) {
490 string platform = Platform;
491 win32 = (platform != "Win16" && platform.StartsWith ("Win"));
498 public Version [] GetClrVersions ()
500 if (clrVersions == null)
501 InternalGetClrVersions ();
506 void InternalGetClrVersions ()
508 char [] anychars = new char [] { ';', ')' };
509 string s = useragent;
510 ArrayList list = null;
512 while ((s != null) && (idx = s.IndexOf (".NET CLR ")) != -1) {
513 int end = s.IndexOfAny (anychars, idx + 9);
517 string ver = s.Substring (idx + 9, end - idx - 9);
520 v = new Version (ver);
521 if (clrVersion == null || v > clrVersion)
525 list = new ArrayList (4);
529 s = s.Substring (idx + 9);
532 if (list == null || list.Count == 0) {
533 clrVersion = new Version ();
537 clrVersions = (Version []) list.ToArray (typeof (Version));
541 bool ReadBoolean (string key)
543 string v = this [key];
545 throw CreateCapabilityNotFoundException (key);
548 return (String.Compare (v, "True", true, Helpers.InvariantCulture) == 0);
551 int ReadInt32 (string key)
553 string v = this [key];
555 throw CreateCapabilityNotFoundException (key);
559 return Int32.Parse (v);
561 throw CreateCapabilityNotFoundException (key);
565 double ReadDouble (string key)
567 string v = this [key];
569 throw CreateCapabilityNotFoundException (key);
573 return Double.Parse (v);
575 throw CreateCapabilityNotFoundException (key);
579 string ReadString (string key)
581 string v = this [key];
583 throw CreateCapabilityNotFoundException (key);
589 Version ReadVersion (string key)
591 string v = this [key];
593 throw CreateCapabilityNotFoundException (key);
597 return new Version (v);
600 throw CreateCapabilityNotFoundException (key);
604 ArrayList ReadArrayList (string key)
606 ArrayList v = (ArrayList)this.capabilities [key];
608 throw CreateCapabilityNotFoundException (key);
614 Exception CreateCapabilityNotFoundException (string key) {
615 return new ArgumentNullException (String.Format ("browscaps.ini does not contain a definition for capability {0} for userAgent {1}", key, Browser));
620 return flags.Get (idx);
625 flags.Set (idx, true);