b4b7356e5a0bf32fa4596f4cd4755676ff00353d00b697c8429ed8a408d2bd8ef62a0ea27c724aa4a8fe7d766897b646cdc46168dc9fcf6fd7d65a68e7d5eb 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import isArray from '../utils/is-array';
  2. import hasOwnProp from '../utils/has-own-prop';
  3. import isUndefined from '../utils/is-undefined';
  4. import compareArrays from '../utils/compare-arrays';
  5. import { deprecateSimple } from '../utils/deprecate';
  6. import { mergeConfigs } from './set';
  7. import { Locale } from './constructor';
  8. import keys from '../utils/keys';
  9. import { baseConfig } from './base-config';
  10. // internal storage for locale config files
  11. var locales = {};
  12. var globalLocale;
  13. function normalizeLocale(key) {
  14. return key ? key.toLowerCase().replace('_', '-') : key;
  15. }
  16. // pick the locale from the array
  17. // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
  18. // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
  19. function chooseLocale(names) {
  20. var i = 0, j, next, locale, split;
  21. while (i < names.length) {
  22. split = normalizeLocale(names[i]).split('-');
  23. j = split.length;
  24. next = normalizeLocale(names[i + 1]);
  25. next = next ? next.split('-') : null;
  26. while (j > 0) {
  27. locale = loadLocale(split.slice(0, j).join('-'));
  28. if (locale) {
  29. return locale;
  30. }
  31. if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
  32. //the next array item is better than a shallower substring of this one
  33. break;
  34. }
  35. j--;
  36. }
  37. i++;
  38. }
  39. return null;
  40. }
  41. function loadLocale(name) {
  42. var oldLocale = null;
  43. // TODO: Find a better way to register and load all the locales in Node
  44. if (!locales[name] && (typeof module !== 'undefined') &&
  45. module && module.exports) {
  46. try {
  47. oldLocale = globalLocale._abbr;
  48. require('./locale/' + name);
  49. // because defineLocale currently also sets the global locale, we
  50. // want to undo that for lazy loaded locales
  51. getSetGlobalLocale(oldLocale);
  52. } catch (e) { }
  53. }
  54. return locales[name];
  55. }
  56. // This function will load locale and then set the global locale. If
  57. // no arguments are passed in, it will simply return the current global
  58. // locale key.
  59. export function getSetGlobalLocale (key, values) {
  60. var data;
  61. if (key) {
  62. if (isUndefined(values)) {
  63. data = getLocale(key);
  64. }
  65. else {
  66. data = defineLocale(key, values);
  67. }
  68. if (data) {
  69. // moment.duration._locale = moment._locale = data;
  70. globalLocale = data;
  71. }
  72. }
  73. return globalLocale._abbr;
  74. }
  75. export function defineLocale (name, config) {
  76. if (config !== null) {
  77. var parentConfig = baseConfig;
  78. config.abbr = name;
  79. if (locales[name] != null) {
  80. deprecateSimple('defineLocaleOverride',
  81. 'use moment.updateLocale(localeName, config) to change ' +
  82. 'an existing locale. moment.defineLocale(localeName, ' +
  83. 'config) should only be used for creating a new locale ' +
  84. 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.');
  85. parentConfig = locales[name]._config;
  86. } else if (config.parentLocale != null) {
  87. if (locales[config.parentLocale] != null) {
  88. parentConfig = locales[config.parentLocale]._config;
  89. } else {
  90. // treat as if there is no base config
  91. deprecateSimple('parentLocaleUndefined',
  92. 'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/');
  93. }
  94. }
  95. locales[name] = new Locale(mergeConfigs(parentConfig, config));
  96. // backwards compat for now: also set the locale
  97. getSetGlobalLocale(name);
  98. return locales[name];
  99. } else {
  100. // useful for testing
  101. delete locales[name];
  102. return null;
  103. }
  104. }
  105. export function updateLocale(name, config) {
  106. if (config != null) {
  107. var locale, parentConfig = baseConfig;
  108. // MERGE
  109. if (locales[name] != null) {
  110. parentConfig = locales[name]._config;
  111. }
  112. config = mergeConfigs(parentConfig, config);
  113. locale = new Locale(config);
  114. locale.parentLocale = locales[name];
  115. locales[name] = locale;
  116. // backwards compat for now: also set the locale
  117. getSetGlobalLocale(name);
  118. } else {
  119. // pass null for config to unupdate, useful for tests
  120. if (locales[name] != null) {
  121. if (locales[name].parentLocale != null) {
  122. locales[name] = locales[name].parentLocale;
  123. } else if (locales[name] != null) {
  124. delete locales[name];
  125. }
  126. }
  127. }
  128. return locales[name];
  129. }
  130. // returns locale data
  131. export function getLocale (key) {
  132. var locale;
  133. if (key && key._locale && key._locale._abbr) {
  134. key = key._locale._abbr;
  135. }
  136. if (!key) {
  137. return globalLocale;
  138. }
  139. if (!isArray(key)) {
  140. //short-circuit everything else
  141. locale = loadLocale(key);
  142. if (locale) {
  143. return locale;
  144. }
  145. key = [key];
  146. }
  147. return chooseLocale(key);
  148. }
  149. export function listLocales() {
  150. return keys(locales);
  151. }