/lib/monomi.js

https://bitbucket.org/jamesgpearce/monomi · JavaScript · 114 lines · 87 code · 27 blank · 0 comment · 13 complexity · 651d2bf49d3c8b314356057ab8c3c3f9 MD5 · raw file

  1. var detectBrowserType = exports.detectBrowserType = function (options) {
  2. var opts = merge({
  3. 'order': ['tablet', 'touch', 'mobile', 'desktop'],
  4. 'default': 'unknown',
  5. 'tablet': {
  6. 'user-agent': new RegExp('ipad', 'i')
  7. },
  8. 'touch': {
  9. 'user-agent': new RegExp('iphone|android', 'i')
  10. },
  11. 'mobile': {
  12. 'order':['x-wap-profile', 'profile', 'accept', 'user-agent'],
  13. 'x-wap-profile': new RegExp('.+'),
  14. 'profile': new RegExp('.+'),
  15. 'accept': new RegExp('wap', 'i'),
  16. 'user-agent': new RegExp('^(' + [
  17. 'w3c ', 'w3c-', 'acs-', 'alav', 'alca', 'amoi', 'audi', 'avan', 'benq', 'bird', 'blac',
  18. 'blaz', 'brew', 'cell', 'cldc', 'cmd-', 'dang', 'doco', 'eric', 'hipt', 'htc_', 'inno',
  19. 'ipaq', 'ipod', 'jigs', 'kddi', 'keji', 'leno', 'lg-c', 'lg-d', 'lg-g', 'lge-', 'lg/u',
  20. 'maui', 'maxo', 'midp', 'mits', 'mmef', 'mobi', 'mot-', 'moto', 'mwbp', 'nec-', 'newt',
  21. 'noki', 'palm', 'pana', 'pant', 'phil', 'play', 'port', 'prox', 'qwap', 'sage', 'sams',
  22. 'sany', 'sch-', 'sec-', 'send', 'seri', 'sgh-', 'shar', 'sie-', 'siem', 'smal', 'smar',
  23. 'sony', 'sph-', 'symb', 't-mo', 'teli', 'tim-', 'tosh', 'tsm-', 'upg1', 'upsi', 'vk-v',
  24. 'voda', 'wap-', 'wapa', 'wapi', 'wapp', 'wapr', 'webc', 'winw', 'winw', 'xda ', 'xda-'
  25. ].join('|') + ')|(' + [
  26. 'android', 'hiptop', 'ipod', 'lge vx', 'midp', 'mmp', 'netfront', 'palm', 'psp',
  27. 'openweb', 'opera mobi', 'opera mini', 'phone', 'smartphone', 'symbian', 'up.browser',
  28. 'up.link', 'wap', 'windows ce'
  29. ].join('|') + ')' , 'i')
  30. },
  31. 'desktop': function () {
  32. return true;
  33. }
  34. }, options);
  35. return function(request, response, next) {
  36. var userAgent = getHeader(request, 'user-agent'); //oft-used
  37. var browserType = opts['default'];
  38. for (var t in opts['order']) {
  39. var type = opts['order'][t];
  40. var options = opts[type];
  41. if (options && (
  42. typeof(options)==='function' && options(request, userAgent))
  43. ||
  44. detect(request, userAgent, options)
  45. ) {
  46. browserType = type;
  47. break;
  48. }
  49. }
  50. request.monomi = {
  51. 'browserType' : browserType
  52. };
  53. next();
  54. }
  55. }
  56. function detect(request, userAgent, options) {
  57. var opts = merge({
  58. 'order':['user-agent']
  59. }, options);
  60. for (var h in opts['order']) {
  61. var header = opts['order'][h].toLowerCase();
  62. if (opts[header]) {
  63. var value = (header==='user-agent') ? userAgent : getHeader(request, header);
  64. if (value.match(opts[header])!=null) {
  65. return true;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71. var getHeader = exports.getHeader = function(request, header, tryPrefix, defaultValue) {
  72. tryPrefix = typeof(tryPrefix) != 'undefined' ? tryPrefix : 'x-device-';
  73. var value = request.headers[tryPrefix + header];
  74. if (value) { return value; }
  75. value = request.headers[header];
  76. if (value) { return value; }
  77. return typeof(defaultValue) != 'undefined' ? defaultValue : '';
  78. }
  79. function merge() {
  80. var merged = {};
  81. for (a in arguments) {
  82. for (f in arguments[a]) {
  83. merged[f] = arguments[a][f];
  84. }
  85. }
  86. return merged;
  87. };