uaparser.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // uaparser by lindsey simon,
  2. // ported to node by tobie
  3. // https://github.com/tobie/ua-parser/
  4. // browserized by paul irish
  5. (function(exports){
  6. exports.uaparse = parse;
  7. function parse(ua) {
  8. for (var i=0; i < parsers.length; i++) {
  9. var result = parsers[i](ua);
  10. if (result) { return result; }
  11. }
  12. return new UserAgent();
  13. }
  14. function UserAgent(family) {
  15. this.family = family || 'Other';
  16. }
  17. UserAgent.prototype.toVersionString = function() {
  18. var output = '';
  19. if (this.major != null) {
  20. output += this.major;
  21. if (this.minor != null) {
  22. output += '.' + this.minor;
  23. if (this.patch != null) {
  24. output += '.' + this.patch;
  25. }
  26. }
  27. }
  28. return output;
  29. };
  30. UserAgent.prototype.toString = function() {
  31. var suffix = this.toVersionString();
  32. if (suffix) { suffix = ' ' + suffix; }
  33. return this.family + suffix;
  34. };
  35. var regexes = [
  36. {"pattern":"^(Opera)/(\\d+)\\.(\\d+) \\(Nintendo Wii",
  37. "v1_replacement":null,
  38. "family_replacement":"Wii"},
  39. {"pattern":"(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?)",
  40. "v1_replacement":null,
  41. "family_replacement":"Firefox ($1)"},
  42. {"pattern":"(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)?",
  43. "v1_replacement":null,
  44. "family_replacement":"Firefox ($1)"},
  45. {"pattern":"(SeaMonkey|Fennec|Camino)/(\\d+)\\.(\\d+)([ab]?\\d+[a-z]*)",
  46. "v1_replacement":null,
  47. "family_replacement":null},
  48. {"pattern":"(Flock)/(\\d+)\\.(\\d+)(b\\d+?)",
  49. "v1_replacement":null,
  50. "family_replacement":null},
  51. {"pattern":"(Fennec)/(\\d+)\\.(\\d+)(pre)",
  52. "v1_replacement":null,
  53. "family_replacement":null},
  54. {"pattern":"(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)",
  55. "v1_replacement":null,
  56. "family_replacement":"Netscape"},
  57. {"pattern":"(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)",
  58. "v1_replacement":null,
  59. "family_replacement":"Netscape"},
  60. {"pattern":"(Netscape6)/(\\d+)\\.(\\d+)\\.(\\d+)",
  61. "v1_replacement":null,
  62. "family_replacement":"Netscape"},
  63. {"pattern":"(MyIBrow)/(\\d+)\\.(\\d+)",
  64. "v1_replacement":null,
  65. "family_replacement":"My Internet Browser"},
  66. {"pattern":"(Firefox).*Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)",
  67. "v1_replacement":null,
  68. "family_replacement":"MicroB"},
  69. {"pattern":"(Opera)/9.80.*Version\\/(\\d+)\\.(\\d+)(?:\\.(\\d+))?",
  70. "v1_replacement":null,
  71. "family_replacement":null},
  72. {"pattern":"(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre)?) \\(Swiftfox\\)",
  73. "v1_replacement":null,
  74. "family_replacement":"Swiftfox"},
  75. {"pattern":"(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*)? \\(Swiftfox\\)",
  76. "v1_replacement":null,
  77. "family_replacement":"Swiftfox"},
  78. {"pattern":"(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)",
  79. "v1_replacement":null,
  80. "family_replacement":"Konqueror"},
  81. {"pattern":"(Jasmine|ANTGalio|Midori|Fresco|Lobo|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Vodafone|NetFront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|Iron|Iris)/(\\d+)\\.(\\d+)\\.(\\d+)",
  82. "v1_replacement":null,
  83. "family_replacement":null},
  84. {"pattern":"(Bolt|Jasmine|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|Vodafone|NetFront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca)/(\\d+)\\.(\\d+)",
  85. "v1_replacement":null,
  86. "family_replacement":null},
  87. {"pattern":"(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)",
  88. "v1_replacement":null,
  89. "family_replacement":null},
  90. {"pattern":"(iCab|Lunascape|Opera|Android) (\\d+)\\.(\\d+)",
  91. "v1_replacement":null,
  92. "family_replacement":null},
  93. {"pattern":"(IEMobile) (\\d+)\\.(\\d+)",
  94. "v1_replacement":null,
  95. "family_replacement":"IE Mobile"},
  96. {"pattern":"(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)",
  97. "v1_replacement":null,
  98. "family_replacement":null},
  99. {"pattern":"(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*)?",
  100. "v1_replacement":null,
  101. "family_replacement":null},
  102. {"pattern":"(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+))?",
  103. "v1_replacement":null,
  104. "family_replacement":"Obigo"},
  105. {"pattern":"(MAXTHON|Maxthon) (\\d+)\\.(\\d+)",
  106. "v1_replacement":null,
  107. "family_replacement":"Maxthon"},
  108. {"pattern":"(Maxthon|MyIE2|Uzbl|Shiira)",
  109. "v1_replacement":"0",
  110. "family_replacement":null},
  111. {"pattern":"(PLAYSTATION) (\\d+)",
  112. "v1_replacement":null,
  113. "family_replacement":"PlayStation"},
  114. {"pattern":"(PlayStation Portable)[^\\d]+(\\d+).(\\d+)",
  115. "v1_replacement":null,
  116. "family_replacement":null},
  117. {"pattern":"(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)",
  118. "v1_replacement":null,
  119. "family_replacement":null},
  120. {"pattern":"(Opera)/(\\d+)\\.(\\d+).*Opera Mobi",
  121. "v1_replacement":null,
  122. "family_replacement":"Opera Mobile"},
  123. {"pattern":"(POLARIS)/(\\d+)\\.(\\d+)",
  124. "v1_replacement":null,
  125. "family_replacement":"Polaris"},
  126. {"pattern":"(BonEcho)/(\\d+)\\.(\\d+)\\.(\\d+)",
  127. "v1_replacement":null,
  128. "family_replacement":"Bon Echo"},
  129. {"pattern":"(iPhone) OS (\\d+)_(\\d+)(?:_(\\d+))?",
  130. "v1_replacement":null,
  131. "family_replacement":null},
  132. {"pattern":"(Avant)",
  133. "v1_replacement":"1",
  134. "family_replacement":null},
  135. {"pattern":"(Nokia)[EN]?(\\d+)",
  136. "v1_replacement":null,
  137. "family_replacement":null},
  138. {"pattern":"(Black[bB]erry)(\\d+)",
  139. "v1_replacement":null,
  140. "family_replacement":"Blackberry"},
  141. {"pattern":"(OmniWeb)/v(\\d+)\\.(\\d+)",
  142. "v1_replacement":null,
  143. "family_replacement":null},
  144. {"pattern":"(Blazer)/(\\d+)\\.(\\d+)",
  145. "v1_replacement":null,
  146. "family_replacement":"Palm Blazer"},
  147. {"pattern":"(Pre)/(\\d+)\\.(\\d+)",
  148. "v1_replacement":null,
  149. "family_replacement":"Palm Pre"},
  150. {"pattern":"(Links) \\((\\d+)\\.(\\d+)",
  151. "v1_replacement":null,
  152. "family_replacement":null},
  153. {"pattern":"(QtWeb) Internet Browser/(\\d+)\\.(\\d+)",
  154. "v1_replacement":null,
  155. "family_replacement":null},
  156. {"pattern":"(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari/",
  157. "v1_replacement":null,
  158. "family_replacement":"Safari"},
  159. {"pattern":"(OLPC)/Update(\\d+)\\.(\\d+)",
  160. "v1_replacement":null,
  161. "family_replacement":null},
  162. {"pattern":"(OLPC)/Update()\\.(\\d+)",
  163. "v1_replacement":"0",
  164. "family_replacement":null},
  165. {"pattern":"(SamsungSGHi560)",
  166. "v1_replacement":null,
  167. "family_replacement":"Samsung SGHi560"},
  168. {"pattern":"^(SonyEricssonK800i)",
  169. "v1_replacement":null,
  170. "family_replacement":"Sony Ericsson K800i"},
  171. {"pattern":"(Teleca Q7)",
  172. "v1_replacement":null,
  173. "family_replacement":null},
  174. {"pattern":"(MSIE) (\\d+)\\.(\\d+)",
  175. "v1_replacement":null,
  176. "family_replacement":"IE"}
  177. ];
  178. var parsers = regexes.map(function(obj) {
  179. var regexp = new RegExp(obj.pattern),
  180. famRep = obj.family_replacement,
  181. v1Rep = obj.v1_replacement;
  182. function parser(ua) {
  183. var m = ua.match(regexp);
  184. if (!m) { return null; }
  185. var familly = famRep ? famRep.replace('$1', m[1]) : m[1];
  186. var obj = new UserAgent(familly);
  187. obj.major = parseInt(v1Rep ? v1Rep : m[2]);
  188. obj.minor = m[3] ? parseInt(m[3]) : null;
  189. obj.patch = m[4] ? parseInt(m[4]) : null;
  190. return obj;
  191. }
  192. return parser;
  193. });
  194. })(window);