The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

language.js 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /**
  2. * negotiator
  3. * Copyright(c) 2012 Isaac Z. Schlueter
  4. * Copyright(c) 2014 Federico Romero
  5. * Copyright(c) 2014-2015 Douglas Christopher Wilson
  6. * MIT Licensed
  7. */
  8. 'use strict';
  9. /**
  10. * Module exports.
  11. * @public
  12. */
  13. module.exports = preferredLanguages;
  14. module.exports.preferredLanguages = preferredLanguages;
  15. /**
  16. * Module variables.
  17. * @private
  18. */
  19. var simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/;
  20. /**
  21. * Parse the Accept-Language header.
  22. * @private
  23. */
  24. function parseAcceptLanguage(accept) {
  25. var accepts = accept.split(',');
  26. for (var i = 0, j = 0; i < accepts.length; i++) {
  27. var language = parseLanguage(accepts[i].trim(), i);
  28. if (language) {
  29. accepts[j++] = language;
  30. }
  31. }
  32. // trim accepts
  33. accepts.length = j;
  34. return accepts;
  35. }
  36. /**
  37. * Parse a language from the Accept-Language header.
  38. * @private
  39. */
  40. function parseLanguage(str, i) {
  41. var match = simpleLanguageRegExp.exec(str);
  42. if (!match) return null;
  43. var prefix = match[1],
  44. suffix = match[2],
  45. full = prefix;
  46. if (suffix) full += "-" + suffix;
  47. var q = 1;
  48. if (match[3]) {
  49. var params = match[3].split(';')
  50. for (var j = 0; j < params.length; j++) {
  51. var p = params[j].split('=');
  52. if (p[0] === 'q') q = parseFloat(p[1]);
  53. }
  54. }
  55. return {
  56. prefix: prefix,
  57. suffix: suffix,
  58. q: q,
  59. i: i,
  60. full: full
  61. };
  62. }
  63. /**
  64. * Get the priority of a language.
  65. * @private
  66. */
  67. function getLanguagePriority(language, accepted, index) {
  68. var priority = {o: -1, q: 0, s: 0};
  69. for (var i = 0; i < accepted.length; i++) {
  70. var spec = specify(language, accepted[i], index);
  71. if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) {
  72. priority = spec;
  73. }
  74. }
  75. return priority;
  76. }
  77. /**
  78. * Get the specificity of the language.
  79. * @private
  80. */
  81. function specify(language, spec, index) {
  82. var p = parseLanguage(language)
  83. if (!p) return null;
  84. var s = 0;
  85. if(spec.full.toLowerCase() === p.full.toLowerCase()){
  86. s |= 4;
  87. } else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) {
  88. s |= 2;
  89. } else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) {
  90. s |= 1;
  91. } else if (spec.full !== '*' ) {
  92. return null
  93. }
  94. return {
  95. i: index,
  96. o: spec.i,
  97. q: spec.q,
  98. s: s
  99. }
  100. };
  101. /**
  102. * Get the preferred languages from an Accept-Language header.
  103. * @public
  104. */
  105. function preferredLanguages(accept, provided) {
  106. // RFC 2616 sec 14.4: no header = *
  107. var accepts = parseAcceptLanguage(accept === undefined ? '*' : accept || '');
  108. if (!provided) {
  109. // sorted list of all languages
  110. return accepts
  111. .filter(isQuality)
  112. .sort(compareSpecs)
  113. .map(getFullLanguage);
  114. }
  115. var priorities = provided.map(function getPriority(type, index) {
  116. return getLanguagePriority(type, accepts, index);
  117. });
  118. // sorted list of accepted languages
  119. return priorities.filter(isQuality).sort(compareSpecs).map(function getLanguage(priority) {
  120. return provided[priorities.indexOf(priority)];
  121. });
  122. }
  123. /**
  124. * Compare two specs.
  125. * @private
  126. */
  127. function compareSpecs(a, b) {
  128. return (b.q - a.q) || (b.s - a.s) || (a.o - b.o) || (a.i - b.i) || 0;
  129. }
  130. /**
  131. * Get full language string.
  132. * @private
  133. */
  134. function getFullLanguage(spec) {
  135. return spec.full;
  136. }
  137. /**
  138. * Check if a spec has any quality.
  139. * @private
  140. */
  141. function isQuality(spec) {
  142. return spec.q > 0;
  143. }