++ Test/mainsoft/ChangeLog (working copy)
[mono.git] / mcs / class / System.Web / System.Web / BrowserCapabilities.cs
1 // 
2 // System.Web.HttpBrowserCapabilities
3 //
4 // Authors:
5 //   Patrik Torstensson (Patrik.Torstensson@labs2.com)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (c) 2003 Novell, Inc. (http://www.novell.com)
9 //
10
11 //
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:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
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.
30 //
31
32 using System.Collections;
33 using System.Globalization;
34 using System.Web.Configuration;
35 using System.Web.UI;
36 using System.Security.Permissions;
37
38 #if NET_2_0
39 namespace System.Web.Configuration {
40         public partial class HttpCapabilitiesBase
41 #else
42
43 namespace System.Web {
44         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
46         public class HttpBrowserCapabilities : HttpCapabilitiesBase
47 #endif
48         {
49                 const int HaveActiveXControls = 1; // 1;
50                 const int HaveAdapters = 2;
51                 const int HaveAOL = 3; // 2;
52                 const int HaveBackGroundSounds = 4; // 3;
53                 const int HaveBeta = 5; // 4;
54                 const int HaveBrowser = 6; // 5;
55                 const int HaveBrowsers = 7;
56                 const int HaveCanCombineFormsInDeck = 8;
57                 const int HaveCanInitiateVoiceCall = 9;
58                 const int HaveCanRenderAfterInputOrSelectElement = 10;
59                 const int HaveCanRenderEmptySelects = 11;
60                 const int HaveCanRenderInputAndSelectElementsTogether = 12;
61                 const int HaveCanRenderMixedSelects = 13;
62                 const int HaveCanRenderOneventAndPrevElementsTogether = 14;
63                 const int HaveCanRenderPostBackCards = 15;
64                 const int HaveCanRenderSetvarZeroWithMultiSelectionList = 16;
65                 const int HaveCanSendMail = 17;
66                 const int HaveCDF = 18; // 6;
67                 //const int HaveClrVersion = 19; // 7;
68                 const int HaveCookies = 20; // 8;
69                 const int HaveCrawler = 21; // 9;
70                 const int HaveDefaultSubmitButtonLimit = 22;
71                 const int HaveEcmaScriptVersion = 23;
72                 const int HaveFrames = 24; // 11;
73                 const int HaveGatewayMajorVersion = 25;
74                 const int HaveGatewayMinorVersion = 26;
75                 const int HaveGatewayVersion = 27;
76                 const int HaveHasBackButton = 28;
77                 const int HaveHidesRightAlignedMultiselectScrollbars = 29;
78                 const int HaveHtmlTextWriter = 30;
79                 const int HaveId = 31;
80                 const int HaveInputType = 32;
81                 const int HaveIsColor = 33;
82                 const int HaveIsMobileDevice = 34;
83                 const int HaveJavaApplets = 35; // 12;
84                 const int HaveJavaScript = 36; // 13;
85                 const int HaveJScriptVersion = 37;
86                 const int HaveMajorVersion = 38; // 14;
87                 const int HaveMaximumHrefLength = 39;
88                 const int HaveMaximumRenderedPageSize = 40;
89                 const int HaveMaximumSoftkeyLabelLength = 41;
90                 const int HaveMinorVersion = 42; // 15;
91                 const int HaveMinorVersionString = 43;
92                 const int HaveMobileDeviceManufacturer = 44;
93                 const int HaveMobileDeviceModel = 45;
94                 const int HaveMSDomVersion = 46; // 16;
95                 const int HaveNumberOfSoftkeys = 47;
96                 const int HavePlatform = 48; // 17;
97                 const int HavePreferredImageMime = 49;
98                 const int HavePreferredRenderingMime = 50;
99                 const int HavePreferredRenderingType = 51;
100                 const int HavePreferredRequestEncoding = 52;
101                 const int HavePreferredResponseEncoding = 53;
102                 const int HaveRendersBreakBeforeWmlSelectAndInput = 54;
103                 const int HaveRendersBreaksAfterHtmlLists = 55;
104                 const int HaveRendersBreaksAfterWmlAnchor = 56;
105                 const int HaveRendersBreaksAfterWmlInput = 57;
106                 const int HaveRendersWmlDoAcceptsInline = 58;
107                 const int HaveRendersWmlSelectsAsMenuCards = 59;
108                 const int HaveRequiredMetaTagNameValue = 60;
109                 const int HaveRequiresAttributeColonSubstitution = 61;
110                 const int HaveRequiresContentTypeMetaTag = 62;
111                 const int HaveRequiresControlStateInSession = 63;
112                 const int HaveRequiresDBCSCharacter = 64;
113                 const int HaveRequiresHtmlAdaptiveErrorReporting = 65;
114                 const int HaveRequiresLeadingPageBreak = 66;
115                 const int HaveRequiresNoBreakInFormatting = 67;
116                 const int HaveRequiresOutputOptimization = 68;
117                 const int HaveRequiresPhoneNumbersAsPlainText = 69;
118                 const int HaveRequiresSpecialViewStateEncoding = 70;
119                 const int HaveRequiresUniqueFilePathSuffix = 71;
120                 const int HaveRequiresUniqueHtmlCheckboxNames = 72;
121                 const int HaveRequiresUniqueHtmlInputNames = 73;
122                 const int HaveRequiresUrlEncodedPostfieldValues = 74;
123                 const int HaveScreenBitDepth = 75;
124                 const int HaveScreenCharactersHeight = 76;
125                 const int HaveScreenCharactersWidth = 77;
126                 const int HaveScreenPixelsHeight = 78;
127                 const int HaveScreenPixelsWidth = 79;
128                 const int HaveSupportsAccesskeyAttribute = 80;
129                 const int HaveSupportsBodyColor = 81;
130                 const int HaveSupportsBold = 82;
131                 const int HaveSupportsCacheControlMetaTag = 83;
132                 const int HaveSupportsCallback = 84;
133                 const int HaveSupportsCss = 85;
134                 const int HaveSupportsDivAlign = 86;
135                 const int HaveSupportsDivNoWrap = 87;
136                 const int HaveSupportsEmptyStringInCookieValue = 88;
137                 const int HaveSupportsFontColor = 89;
138                 const int HaveSupportsFontName = 90;
139                 const int HaveSupportsFontSize = 91;
140                 const int HaveSupportsImageSubmit = 92;
141                 const int HaveSupportsIModeSymbols = 93;
142                 const int HaveSupportsInputIStyle = 94;
143                 const int HaveSupportsInputMode = 95;
144                 const int HaveSupportsItalic = 96;
145                 const int HaveSupportsJPhoneMultiMediaAttributes = 97;
146                 const int HaveSupportsJPhoneSymbols = 98;
147                 const int HaveSupportsQueryStringInFormAction = 99;
148                 const int HaveSupportsRedirectWithCookie = 100;
149                 const int HaveSupportsSelectMultiple = 101;
150                 const int HaveSupportsUncheck = 102;
151                 const int HaveSupportsXmlHttp = 103;
152                 const int HaveTables = 104; // 18;
153                 const int HaveTagWriter = 105; // 19;
154                 const int HaveType = 106;
155                 const int HaveUseOptimizedCacheKey = 107;
156                 const int HaveVBScript = 108; // 20;
157                 const int HaveVersion = 109; // 21;
158                 const int HaveW3CDomVersion = 110; // 22;
159                 const int HaveWin16 = 111; // 23;
160                 const int HaveWin32 = 112; // 24;
161                 const int LastHaveFlag = 113;
162
163                 BitArray flags = new BitArray (LastHaveFlag);
164                 bool activeXControls;
165                 bool aol;
166                 bool backgroundSounds;
167                 bool beta;
168                 string browser;
169                 bool cdf;
170                 Version clrVersion;
171                 bool cookies;
172                 bool crawler;
173                 Version ecmaScriptVersion;
174                 bool frames;
175                 bool javaApplets;
176                 bool javaScript;
177                 int majorVersion;
178                 double minorVersion;
179                 Version msDomVersion;
180                 string platform;
181                 bool tables;
182                 Type tagWriter;
183                 bool vbscript;
184                 string version;
185                 Version w3CDomVersion;
186                 bool win16;
187                 bool win32;
188                 Version [] clrVersions;
189                 internal string useragent;
190
191 #if !NET_2_0
192                 public HttpBrowserCapabilities ()
193                 {
194                 }
195 #endif
196
197                 public bool ActiveXControls {
198                         get {
199                                 if (!Get (HaveActiveXControls)) {
200                                         activeXControls = ReadBoolean ("activexcontrols");
201                                         Set (HaveActiveXControls);
202                                 }
203
204                                 return activeXControls;
205                         }
206                 }
207
208                 public bool AOL {
209                         get {
210                                 if (!Get (HaveAOL)) {
211                                         aol = ReadBoolean ("aol");
212                                         Set (HaveAOL);
213                                 }
214
215                                 return aol;
216                         }
217                 }
218
219                 public bool BackgroundSounds {
220                         get {
221                                 if (!Get (HaveBackGroundSounds)) {
222                                         backgroundSounds = ReadBoolean ("backgroundsounds");
223                                         Set (HaveBackGroundSounds);
224                                 }
225
226                                 return backgroundSounds;
227                         }
228                 }
229
230                 public bool Beta {
231                         get {
232                                 if (!Get (HaveBeta)) {
233                                         beta = ReadBoolean ("beta");
234                                         Set (HaveBeta);
235                                 }
236
237                                 return beta;
238                         }
239                 }
240
241                 public string Browser {
242                         get {
243                                 if (!Get (HaveBrowser)) {
244                                         browser = this ["browser"];
245                                         if (browser == null || browser.Length == 0)
246                                                 browser = "Unknown";
247                                         Set (HaveBrowser);
248                                 }
249
250                                 return browser;
251                         }
252                 }
253 #if NET_2_0
254                 ArrayList browsers = null;
255                 public ArrayList Browsers {
256                         get {
257                                 if (!Get (HaveBrowsers)) {
258                                         browsers = ReadArrayList ("browsers");
259                                         Set (HaveBrowsers);
260                                 }
261
262                                 return browsers;
263                         }
264                 }
265
266                 public bool IsBrowser (string browserName) 
267                 {
268                         foreach (string browser in Browsers) {
269                                 if (0 == String.CompareOrdinal(browser, "Unknown")) {
270                                         continue;
271                                 }
272                                 if (0 == String.CompareOrdinal(browserName, browser)) {
273                                         return true;
274                                 }
275                         }
276                         return false;
277                 }
278 #endif
279                 public bool CDF {
280                         get {
281                                 if (!Get (HaveCDF)) {
282                                         cdf = ReadBoolean ("cdf");
283                                         Set (HaveCDF);
284                                 }
285
286                                 return cdf;
287                         }
288                 }
289
290                 public Version ClrVersion {
291                         get {
292                                 if (clrVersion == null)
293                                         InternalGetClrVersions ();
294
295                                 return clrVersion;
296                         }
297                 }
298
299                 public bool Cookies {
300                         get {
301                                 if (!Get (HaveCookies)) {
302                                         cookies = ReadBoolean ("cookies");
303                                         Set (HaveCookies);
304                                 }
305
306                                 return cookies;
307                         }
308                 }
309
310                 public bool Crawler {
311                         get {
312                                 if (!Get (HaveCrawler)) {
313                                         crawler = ReadBoolean ("crawler");
314                                         Set (HaveCrawler);
315                                 }
316
317                                 return crawler;
318                         }
319                 }
320
321                 public Version EcmaScriptVersion {
322                         get {
323                                 if (!Get (HaveEcmaScriptVersion)) {
324                                         ecmaScriptVersion = ReadVersion ("ecmascriptversion");
325                                         Set (HaveEcmaScriptVersion);
326                                 }
327
328                                 return ecmaScriptVersion;
329                         }
330                 }
331
332                 public bool Frames {
333                         get {
334                                 if (!Get (HaveFrames)) {
335                                         frames = ReadBoolean ("frames");
336                                         Set (HaveFrames);
337                                 }
338
339                                 return frames;
340                         }
341                 }
342
343                 public bool JavaApplets {
344                         get {
345                                 if (!Get (HaveJavaApplets)) {
346                                         javaApplets = ReadBoolean ("javaapplets");
347                                         Set (HaveJavaApplets);
348                                 }
349
350                                 return javaApplets;
351                         }
352                 }
353
354 #if NET_2_0
355                 [Obsolete]
356 #endif
357                 public bool JavaScript {
358                         get {
359                                 if (!Get (HaveJavaScript)) {
360                                         javaScript = ReadBoolean ("javascript");
361                                         Set (HaveJavaScript);
362                                 }
363
364                                 return javaScript;
365                         }
366                 }
367
368                 public int MajorVersion {
369                         get {
370                                 if (!Get (HaveMajorVersion)) {
371                                         majorVersion = ReadInt32 ("majorver");
372                                         Set (HaveMajorVersion);
373                                 }
374
375                                 return majorVersion;
376                         }
377                 }
378
379                 public double MinorVersion {
380                         get {
381                                 if (!Get (HaveMinorVersion)) {
382                                         minorVersion = ReadDouble ("minorver");
383                                         Set (HaveMinorVersion);
384                                 }
385
386                                 return minorVersion;
387                         }
388                 }
389
390                 public Version MSDomVersion {
391                         get {
392                                 if (!Get (HaveMSDomVersion)) {
393                                         msDomVersion = ReadVersion ("msdomversion");
394                                         Set (HaveMSDomVersion);
395                                 }
396
397                                 return msDomVersion;
398                         }
399                 }
400
401                 public string Platform {
402                         get {
403                                 if (!Get (HavePlatform)) {
404                                         platform = ReadString ("platform");
405                                         Set (HavePlatform);
406                                 }
407
408                                 return platform;
409                         }
410                 }
411
412                 public bool Tables {
413                         get {
414                                 if (!Get (HaveTables)) {
415                                         tables = ReadBoolean ("tables");
416                                         Set (HaveTables);
417                                 }
418
419                                 return tables;
420                         }
421                 }
422
423                 public Type TagWriter {
424                         get {
425                                 if (!Get (HaveTagWriter)) {
426                                         tagWriter = GetTagWriter ();
427                                         Set (HaveTagWriter);
428                                 }
429                                 return tagWriter;
430                         }
431                 }
432                 
433                 internal virtual Type GetTagWriter ()
434                 {
435                                 return typeof (HtmlTextWriter);                 
436                 }
437
438                 public string Type {
439                         get {
440                                 return Browser + MajorVersion;
441                         }
442                 }
443
444                 public bool VBScript {
445                         get {
446                                 if (!Get (HaveVBScript)) {
447                                         vbscript = ReadBoolean ("vbscript");
448                                         Set (HaveVBScript);
449                                 }
450
451                                 return vbscript;
452                         }
453                 }
454
455                 public string Version {
456                         get {
457                                 if (!Get (HaveVersion)) {
458                                         version = ReadString ("version");
459                                         Set (HaveVersion);
460                                 }
461
462                                 return version;
463                         }
464                 }
465
466                 public Version W3CDomVersion {
467                         get {
468                                 if (!Get (HaveW3CDomVersion)) {
469                                         w3CDomVersion = ReadVersion ("w3cdomversion");
470                                         Set (HaveW3CDomVersion);
471                                 }
472
473                                 return w3CDomVersion;
474                         }
475                 }
476
477                 public bool Win16 {
478                         get {
479                                 if (!Get (HaveWin16)) {
480                                         win16 = ReadBoolean ("win16");
481                                         Set (HaveWin16);
482                                 }
483
484                                 return win16;
485                         }
486                 }
487
488                 public bool Win32 {
489                         get {
490                                 // This is the list of different windows platforms that browscap.ini has.
491                                 // Win16 Win2000 Win2003 Win32 Win95 Win98 WinME WinNT WinVI WinXP
492                                 if (!Get (HaveWin32)) {
493                                         string platform = Platform;
494                                         win32 = (platform != "Win16" && platform.StartsWith ("Win"));
495                                         Set (HaveWin32);
496                                 }
497                                 return win32;
498                         }
499                 }
500
501 #if NET_1_1
502                 public Version [] GetClrVersions ()
503                 {
504                         if (clrVersions == null)
505                                 InternalGetClrVersions ();
506
507                         return clrVersions;
508                 }
509 #endif
510
511                 void InternalGetClrVersions ()
512                 {
513                         char [] anychars = new char [] { ';', ')' };
514                         string s = useragent;
515                         ArrayList list = null;
516                         int idx;
517                         while ((s != null) && (idx = s.IndexOf (".NET CLR ")) != -1) {
518                                 int end = s.IndexOfAny (anychars, idx + 9);
519                                 if (end == -1)
520                                         break;
521
522                                 string ver = s.Substring (idx + 9, end - idx - 9);
523                                 Version v = null;
524                                 try {
525                                         v = new Version (ver);
526                                         if (clrVersion == null || v > clrVersion)
527                                                 clrVersion = v;
528
529                                         if (list == null)
530                                                 list = new ArrayList (4);
531
532                                         list.Add (v);
533                                 } catch { }
534                                 s = s.Substring (idx + 9);
535                         }
536                         
537                         if (list == null || list.Count == 0) {
538                                 clrVersion = new Version ();
539 #if NET_2_0
540                                 clrVersions = null;
541 #else
542                                 clrVersions = new Version [1] { clrVersion };
543 #endif
544                         } else {
545                                 list.Sort ();
546                                 clrVersions = (Version []) list.ToArray (typeof (Version));
547                         }
548                 }
549
550                 bool ReadBoolean (string key)
551                 {
552                         string v = this [key];
553                         if (v == null) {
554                                 throw CreateCapabilityNotFoundException (key);
555                         }
556
557                         return (String.Compare (v, "True", true, CultureInfo.InvariantCulture) == 0);
558                 }
559
560                 int ReadInt32 (string key)
561                 {
562                         string v = this [key];
563                         if (v == null) {
564                                 throw CreateCapabilityNotFoundException (key);
565                         }
566
567                         try {
568                                 return Int32.Parse (v);
569                         } catch {
570                                 throw CreateCapabilityNotFoundException (key);
571                         }
572                 }
573
574                 double ReadDouble (string key)
575                 {
576                         string v = this [key];
577                         if (v == null) {
578                                 throw CreateCapabilityNotFoundException (key);
579                         }
580
581                         try {
582                                 return Double.Parse (v);
583                         } catch {
584                                 throw CreateCapabilityNotFoundException (key);
585                         }
586                 }
587
588                 private string ReadString (string key) 
589                 {
590                         string v = this [key];
591                         if (v == null) {
592                                 throw CreateCapabilityNotFoundException (key);
593                         }
594
595                         return v;
596                 }
597
598                 Version ReadVersion (string key) 
599                 {
600                         string v = this [key];
601                         if (v == null) {
602                                 throw CreateCapabilityNotFoundException (key);
603                         }
604
605                         try {
606                                 return new Version (v);
607                         }
608                         catch {
609                                 throw CreateCapabilityNotFoundException (key);
610                         }
611                 }
612
613 #if NET_2_0
614                 private ArrayList ReadArrayList (string key) 
615                 {
616                         ArrayList v = (ArrayList)this.capabilities [key];
617                         if (v == null) {
618                                 throw CreateCapabilityNotFoundException (key);
619                         }
620
621                         return v;
622                 }
623 #endif
624                 Exception CreateCapabilityNotFoundException (string key) {
625                         return new ArgumentNullException (String.Format ("browscaps.ini does not contain a definition for capability {0} for userAgent {1}", key, Browser));
626                 }
627
628                 bool Get (int idx)
629                 {
630                         return flags.Get (idx);
631                 }
632
633                 void Set (int idx)
634                 {
635                         flags.Set (idx, true);
636                 }
637         }
638 }