vue-i18n.esm.js 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607
  1. /*!
  2. * vue-i18n v7.8.1
  3. * (c) 2018 kazuya kawaguchi
  4. * Released under the MIT License.
  5. */
  6. /* */
  7. /**
  8. * utilites
  9. */
  10. function warn (msg, err) {
  11. if (typeof console !== 'undefined') {
  12. console.warn('[vue-i18n] ' + msg);
  13. /* istanbul ignore if */
  14. if (err) {
  15. console.warn(err.stack);
  16. }
  17. }
  18. }
  19. function isObject (obj) {
  20. return obj !== null && typeof obj === 'object'
  21. }
  22. var toString = Object.prototype.toString;
  23. var OBJECT_STRING = '[object Object]';
  24. function isPlainObject (obj) {
  25. return toString.call(obj) === OBJECT_STRING
  26. }
  27. function isNull (val) {
  28. return val === null || val === undefined
  29. }
  30. function parseArgs () {
  31. var args = [], len = arguments.length;
  32. while ( len-- ) args[ len ] = arguments[ len ];
  33. var locale = null;
  34. var params = null;
  35. if (args.length === 1) {
  36. if (isObject(args[0]) || Array.isArray(args[0])) {
  37. params = args[0];
  38. } else if (typeof args[0] === 'string') {
  39. locale = args[0];
  40. }
  41. } else if (args.length === 2) {
  42. if (typeof args[0] === 'string') {
  43. locale = args[0];
  44. }
  45. /* istanbul ignore if */
  46. if (isObject(args[1]) || Array.isArray(args[1])) {
  47. params = args[1];
  48. }
  49. }
  50. return { locale: locale, params: params }
  51. }
  52. function getOldChoiceIndexFixed (choice) {
  53. return choice
  54. ? choice > 1
  55. ? 1
  56. : 0
  57. : 1
  58. }
  59. function getChoiceIndex (choice, choicesLength) {
  60. choice = Math.abs(choice);
  61. if (choicesLength === 2) { return getOldChoiceIndexFixed(choice) }
  62. return choice ? Math.min(choice, 2) : 0
  63. }
  64. function fetchChoice (message, choice) {
  65. /* istanbul ignore if */
  66. if (!message && typeof message !== 'string') { return null }
  67. var choices = message.split('|');
  68. choice = getChoiceIndex(choice, choices.length);
  69. if (!choices[choice]) { return message }
  70. return choices[choice].trim()
  71. }
  72. function looseClone (obj) {
  73. return JSON.parse(JSON.stringify(obj))
  74. }
  75. function remove (arr, item) {
  76. if (arr.length) {
  77. var index = arr.indexOf(item);
  78. if (index > -1) {
  79. return arr.splice(index, 1)
  80. }
  81. }
  82. }
  83. var hasOwnProperty = Object.prototype.hasOwnProperty;
  84. function hasOwn (obj, key) {
  85. return hasOwnProperty.call(obj, key)
  86. }
  87. function merge (target) {
  88. var arguments$1 = arguments;
  89. var output = Object(target);
  90. for (var i = 1; i < arguments.length; i++) {
  91. var source = arguments$1[i];
  92. if (source !== undefined && source !== null) {
  93. var key = (void 0);
  94. for (key in source) {
  95. if (hasOwn(source, key)) {
  96. if (isObject(source[key])) {
  97. output[key] = merge(output[key], source[key]);
  98. } else {
  99. output[key] = source[key];
  100. }
  101. }
  102. }
  103. }
  104. }
  105. return output
  106. }
  107. function looseEqual (a, b) {
  108. if (a === b) { return true }
  109. var isObjectA = isObject(a);
  110. var isObjectB = isObject(b);
  111. if (isObjectA && isObjectB) {
  112. try {
  113. var isArrayA = Array.isArray(a);
  114. var isArrayB = Array.isArray(b);
  115. if (isArrayA && isArrayB) {
  116. return a.length === b.length && a.every(function (e, i) {
  117. return looseEqual(e, b[i])
  118. })
  119. } else if (!isArrayA && !isArrayB) {
  120. var keysA = Object.keys(a);
  121. var keysB = Object.keys(b);
  122. return keysA.length === keysB.length && keysA.every(function (key) {
  123. return looseEqual(a[key], b[key])
  124. })
  125. } else {
  126. /* istanbul ignore next */
  127. return false
  128. }
  129. } catch (e) {
  130. /* istanbul ignore next */
  131. return false
  132. }
  133. } else if (!isObjectA && !isObjectB) {
  134. return String(a) === String(b)
  135. } else {
  136. return false
  137. }
  138. }
  139. var canUseDateTimeFormat =
  140. typeof Intl !== 'undefined' && typeof Intl.DateTimeFormat !== 'undefined';
  141. var canUseNumberFormat =
  142. typeof Intl !== 'undefined' && typeof Intl.NumberFormat !== 'undefined';
  143. /* */
  144. function extend (Vue) {
  145. // $FlowFixMe
  146. Object.defineProperty(Vue.prototype, '$t', {
  147. get: function get () {
  148. var this$1 = this;
  149. return function (key) {
  150. var values = [], len = arguments.length - 1;
  151. while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
  152. var i18n = this$1.$i18n;
  153. return i18n._t.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this$1 ].concat( values ))
  154. }
  155. }
  156. });
  157. // $FlowFixMe
  158. Object.defineProperty(Vue.prototype, '$tc', {
  159. get: function get () {
  160. var this$1 = this;
  161. return function (key, choice) {
  162. var values = [], len = arguments.length - 2;
  163. while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
  164. var i18n = this$1.$i18n;
  165. return i18n._tc.apply(i18n, [ key, i18n.locale, i18n._getMessages(), this$1, choice ].concat( values ))
  166. }
  167. }
  168. });
  169. // $FlowFixMe
  170. Object.defineProperty(Vue.prototype, '$te', {
  171. get: function get () {
  172. var this$1 = this;
  173. return function (key, locale) {
  174. var i18n = this$1.$i18n;
  175. return i18n._te(key, i18n.locale, i18n._getMessages(), locale)
  176. }
  177. }
  178. });
  179. // $FlowFixMe
  180. Object.defineProperty(Vue.prototype, '$d', {
  181. get: function get () {
  182. var this$1 = this;
  183. return function (value) {
  184. var ref;
  185. var args = [], len = arguments.length - 1;
  186. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  187. return (ref = this$1.$i18n).d.apply(ref, [ value ].concat( args ))
  188. }
  189. }
  190. });
  191. // $FlowFixMe
  192. Object.defineProperty(Vue.prototype, '$n', {
  193. get: function get () {
  194. var this$1 = this;
  195. return function (value) {
  196. var ref;
  197. var args = [], len = arguments.length - 1;
  198. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  199. return (ref = this$1.$i18n).n.apply(ref, [ value ].concat( args ))
  200. }
  201. }
  202. });
  203. }
  204. /* */
  205. var mixin = {
  206. beforeCreate: function beforeCreate () {
  207. var options = this.$options;
  208. options.i18n = options.i18n || (options.__i18n ? {} : null);
  209. if (options.i18n) {
  210. if (options.i18n instanceof VueI18n) {
  211. // init locale messages via custom blocks
  212. if (options.__i18n) {
  213. try {
  214. var localeMessages = {};
  215. options.__i18n.forEach(function (resource) {
  216. localeMessages = merge(localeMessages, JSON.parse(resource));
  217. });
  218. Object.keys(localeMessages).forEach(function (locale) {
  219. options.i18n.mergeLocaleMessage(locale, localeMessages[locale]);
  220. });
  221. } catch (e) {
  222. if (process.env.NODE_ENV !== 'production') {
  223. warn("Cannot parse locale messages via custom blocks.", e);
  224. }
  225. }
  226. }
  227. this._i18n = options.i18n;
  228. this._i18nWatcher = this._i18n.watchI18nData();
  229. this._i18n.subscribeDataChanging(this);
  230. this._subscribing = true;
  231. } else if (isPlainObject(options.i18n)) {
  232. // component local i18n
  233. if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
  234. options.i18n.root = this.$root.$i18n;
  235. options.i18n.formatter = this.$root.$i18n.formatter;
  236. options.i18n.fallbackLocale = this.$root.$i18n.fallbackLocale;
  237. options.i18n.silentTranslationWarn = this.$root.$i18n.silentTranslationWarn;
  238. }
  239. // init locale messages via custom blocks
  240. if (options.__i18n) {
  241. try {
  242. var localeMessages$1 = {};
  243. options.__i18n.forEach(function (resource) {
  244. localeMessages$1 = merge(localeMessages$1, JSON.parse(resource));
  245. });
  246. options.i18n.messages = localeMessages$1;
  247. } catch (e) {
  248. if (process.env.NODE_ENV !== 'production') {
  249. warn("Cannot parse locale messages via custom blocks.", e);
  250. }
  251. }
  252. }
  253. this._i18n = new VueI18n(options.i18n);
  254. this._i18nWatcher = this._i18n.watchI18nData();
  255. this._i18n.subscribeDataChanging(this);
  256. this._subscribing = true;
  257. if (options.i18n.sync === undefined || !!options.i18n.sync) {
  258. this._localeWatcher = this.$i18n.watchLocale();
  259. }
  260. } else {
  261. if (process.env.NODE_ENV !== 'production') {
  262. warn("Cannot be interpreted 'i18n' option.");
  263. }
  264. }
  265. } else if (this.$root && this.$root.$i18n && this.$root.$i18n instanceof VueI18n) {
  266. // root i18n
  267. this._i18n = this.$root.$i18n;
  268. this._i18n.subscribeDataChanging(this);
  269. this._subscribing = true;
  270. } else if (options.parent && options.parent.$i18n && options.parent.$i18n instanceof VueI18n) {
  271. // parent i18n
  272. this._i18n = options.parent.$i18n;
  273. this._i18n.subscribeDataChanging(this);
  274. this._subscribing = true;
  275. }
  276. },
  277. beforeDestroy: function beforeDestroy () {
  278. if (!this._i18n) { return }
  279. if (this._subscribing) {
  280. this._i18n.unsubscribeDataChanging(this);
  281. delete this._subscribing;
  282. }
  283. if (this._i18nWatcher) {
  284. this._i18nWatcher();
  285. delete this._i18nWatcher;
  286. }
  287. if (this._localeWatcher) {
  288. this._localeWatcher();
  289. delete this._localeWatcher;
  290. }
  291. this._i18n = null;
  292. }
  293. }
  294. /* */
  295. var component = {
  296. name: 'i18n',
  297. functional: true,
  298. props: {
  299. tag: {
  300. type: String,
  301. default: 'span'
  302. },
  303. path: {
  304. type: String,
  305. required: true
  306. },
  307. locale: {
  308. type: String
  309. },
  310. places: {
  311. type: [Array, Object]
  312. }
  313. },
  314. render: function render (h, ref) {
  315. var props = ref.props;
  316. var data = ref.data;
  317. var children = ref.children;
  318. var parent = ref.parent;
  319. var i18n = parent.$i18n;
  320. children = (children || []).filter(function (child) {
  321. return child.tag || (child.text = child.text.trim())
  322. });
  323. if (!i18n) {
  324. if (process.env.NODE_ENV !== 'production') {
  325. warn('Cannot find VueI18n instance!');
  326. }
  327. return children
  328. }
  329. var path = props.path;
  330. var locale = props.locale;
  331. var params = {};
  332. var places = props.places || {};
  333. var hasPlaces = Array.isArray(places)
  334. ? places.length > 0
  335. : Object.keys(places).length > 0;
  336. var everyPlace = children.every(function (child) {
  337. if (child.data && child.data.attrs) {
  338. var place = child.data.attrs.place;
  339. return (typeof place !== 'undefined') && place !== ''
  340. }
  341. });
  342. if (hasPlaces && children.length > 0 && !everyPlace) {
  343. warn('If places prop is set, all child elements must have place prop set.');
  344. }
  345. if (Array.isArray(places)) {
  346. places.forEach(function (el, i) {
  347. params[i] = el;
  348. });
  349. } else {
  350. Object.keys(places).forEach(function (key) {
  351. params[key] = places[key];
  352. });
  353. }
  354. children.forEach(function (child, i) {
  355. var key = everyPlace
  356. ? ("" + (child.data.attrs.place))
  357. : ("" + i);
  358. params[key] = child;
  359. });
  360. return h(props.tag, data, i18n.i(path, locale, params))
  361. }
  362. }
  363. /* */
  364. function bind (el, binding, vnode) {
  365. if (!assert(el, vnode)) { return }
  366. t(el, binding, vnode);
  367. }
  368. function update (el, binding, vnode, oldVNode) {
  369. if (!assert(el, vnode)) { return }
  370. if (localeEqual(el, vnode) && looseEqual(binding.value, binding.oldValue)) { return }
  371. t(el, binding, vnode);
  372. }
  373. function unbind (el, binding, vnode, oldVNode) {
  374. if (!assert(el, vnode)) { return }
  375. el.textContent = '';
  376. el._vt = undefined;
  377. delete el['_vt'];
  378. el._locale = undefined;
  379. delete el['_locale'];
  380. }
  381. function assert (el, vnode) {
  382. var vm = vnode.context;
  383. if (!vm) {
  384. warn('not exist Vue instance in VNode context');
  385. return false
  386. }
  387. if (!vm.$i18n) {
  388. warn('not exist VueI18n instance in Vue instance');
  389. return false
  390. }
  391. return true
  392. }
  393. function localeEqual (el, vnode) {
  394. var vm = vnode.context;
  395. return el._locale === vm.$i18n.locale
  396. }
  397. function t (el, binding, vnode) {
  398. var ref$1, ref$2;
  399. var value = binding.value;
  400. var ref = parseValue(value);
  401. var path = ref.path;
  402. var locale = ref.locale;
  403. var args = ref.args;
  404. var choice = ref.choice;
  405. if (!path && !locale && !args) {
  406. warn('not support value type');
  407. return
  408. }
  409. if (!path) {
  410. warn('required `path` in v-t directive');
  411. return
  412. }
  413. var vm = vnode.context;
  414. if (choice) {
  415. el._vt = el.textContent = (ref$1 = vm.$i18n).tc.apply(ref$1, [ path, choice ].concat( makeParams(locale, args) ));
  416. } else {
  417. el._vt = el.textContent = (ref$2 = vm.$i18n).t.apply(ref$2, [ path ].concat( makeParams(locale, args) ));
  418. }
  419. el._locale = vm.$i18n.locale;
  420. }
  421. function parseValue (value) {
  422. var path;
  423. var locale;
  424. var args;
  425. var choice;
  426. if (typeof value === 'string') {
  427. path = value;
  428. } else if (isPlainObject(value)) {
  429. path = value.path;
  430. locale = value.locale;
  431. args = value.args;
  432. choice = value.choice;
  433. }
  434. return { path: path, locale: locale, args: args, choice: choice }
  435. }
  436. function makeParams (locale, args) {
  437. var params = [];
  438. locale && params.push(locale);
  439. if (args && (Array.isArray(args) || isPlainObject(args))) {
  440. params.push(args);
  441. }
  442. return params
  443. }
  444. var Vue;
  445. function install (_Vue) {
  446. Vue = _Vue;
  447. var version = (Vue.version && Number(Vue.version.split('.')[0])) || -1;
  448. /* istanbul ignore if */
  449. if (process.env.NODE_ENV !== 'production' && install.installed) {
  450. warn('already installed.');
  451. return
  452. }
  453. install.installed = true;
  454. /* istanbul ignore if */
  455. if (process.env.NODE_ENV !== 'production' && version < 2) {
  456. warn(("vue-i18n (" + (install.version) + ") need to use Vue 2.0 or later (Vue: " + (Vue.version) + ")."));
  457. return
  458. }
  459. Object.defineProperty(Vue.prototype, '$i18n', {
  460. get: function get () { return this._i18n }
  461. });
  462. extend(Vue);
  463. Vue.mixin(mixin);
  464. Vue.directive('t', { bind: bind, update: update, unbind: unbind });
  465. Vue.component(component.name, component);
  466. // use object-based merge strategy
  467. var strats = Vue.config.optionMergeStrategies;
  468. strats.i18n = strats.methods;
  469. }
  470. /* */
  471. var BaseFormatter = function BaseFormatter () {
  472. this._caches = Object.create(null);
  473. };
  474. BaseFormatter.prototype.interpolate = function interpolate (message, values) {
  475. if (!values) {
  476. return [message]
  477. }
  478. var tokens = this._caches[message];
  479. if (!tokens) {
  480. tokens = parse(message);
  481. this._caches[message] = tokens;
  482. }
  483. return compile(tokens, values)
  484. };
  485. var RE_TOKEN_LIST_VALUE = /^(\d)+/;
  486. var RE_TOKEN_NAMED_VALUE = /^(\w)+/;
  487. function parse (format) {
  488. var tokens = [];
  489. var position = 0;
  490. var text = '';
  491. while (position < format.length) {
  492. var char = format[position++];
  493. if (char === '{') {
  494. if (text) {
  495. tokens.push({ type: 'text', value: text });
  496. }
  497. text = '';
  498. var sub = '';
  499. char = format[position++];
  500. while (char !== '}') {
  501. sub += char;
  502. char = format[position++];
  503. }
  504. var type = RE_TOKEN_LIST_VALUE.test(sub)
  505. ? 'list'
  506. : RE_TOKEN_NAMED_VALUE.test(sub)
  507. ? 'named'
  508. : 'unknown';
  509. tokens.push({ value: sub, type: type });
  510. } else if (char === '%') {
  511. // when found rails i18n syntax, skip text capture
  512. if (format[(position)] !== '{') {
  513. text += char;
  514. }
  515. } else {
  516. text += char;
  517. }
  518. }
  519. text && tokens.push({ type: 'text', value: text });
  520. return tokens
  521. }
  522. function compile (tokens, values) {
  523. var compiled = [];
  524. var index = 0;
  525. var mode = Array.isArray(values)
  526. ? 'list'
  527. : isObject(values)
  528. ? 'named'
  529. : 'unknown';
  530. if (mode === 'unknown') { return compiled }
  531. while (index < tokens.length) {
  532. var token = tokens[index];
  533. switch (token.type) {
  534. case 'text':
  535. compiled.push(token.value);
  536. break
  537. case 'list':
  538. compiled.push(values[parseInt(token.value, 10)]);
  539. break
  540. case 'named':
  541. if (mode === 'named') {
  542. compiled.push((values)[token.value]);
  543. } else {
  544. if (process.env.NODE_ENV !== 'production') {
  545. warn(("Type of token '" + (token.type) + "' and format of value '" + mode + "' don't match!"));
  546. }
  547. }
  548. break
  549. case 'unknown':
  550. if (process.env.NODE_ENV !== 'production') {
  551. warn("Detect 'unknown' type of token!");
  552. }
  553. break
  554. }
  555. index++;
  556. }
  557. return compiled
  558. }
  559. /* */
  560. /**
  561. * Path paerser
  562. * - Inspired:
  563. * Vue.js Path parser
  564. */
  565. // actions
  566. var APPEND = 0;
  567. var PUSH = 1;
  568. var INC_SUB_PATH_DEPTH = 2;
  569. var PUSH_SUB_PATH = 3;
  570. // states
  571. var BEFORE_PATH = 0;
  572. var IN_PATH = 1;
  573. var BEFORE_IDENT = 2;
  574. var IN_IDENT = 3;
  575. var IN_SUB_PATH = 4;
  576. var IN_SINGLE_QUOTE = 5;
  577. var IN_DOUBLE_QUOTE = 6;
  578. var AFTER_PATH = 7;
  579. var ERROR = 8;
  580. var pathStateMachine = [];
  581. pathStateMachine[BEFORE_PATH] = {
  582. 'ws': [BEFORE_PATH],
  583. 'ident': [IN_IDENT, APPEND],
  584. '[': [IN_SUB_PATH],
  585. 'eof': [AFTER_PATH]
  586. };
  587. pathStateMachine[IN_PATH] = {
  588. 'ws': [IN_PATH],
  589. '.': [BEFORE_IDENT],
  590. '[': [IN_SUB_PATH],
  591. 'eof': [AFTER_PATH]
  592. };
  593. pathStateMachine[BEFORE_IDENT] = {
  594. 'ws': [BEFORE_IDENT],
  595. 'ident': [IN_IDENT, APPEND],
  596. '0': [IN_IDENT, APPEND],
  597. 'number': [IN_IDENT, APPEND]
  598. };
  599. pathStateMachine[IN_IDENT] = {
  600. 'ident': [IN_IDENT, APPEND],
  601. '0': [IN_IDENT, APPEND],
  602. 'number': [IN_IDENT, APPEND],
  603. 'ws': [IN_PATH, PUSH],
  604. '.': [BEFORE_IDENT, PUSH],
  605. '[': [IN_SUB_PATH, PUSH],
  606. 'eof': [AFTER_PATH, PUSH]
  607. };
  608. pathStateMachine[IN_SUB_PATH] = {
  609. "'": [IN_SINGLE_QUOTE, APPEND],
  610. '"': [IN_DOUBLE_QUOTE, APPEND],
  611. '[': [IN_SUB_PATH, INC_SUB_PATH_DEPTH],
  612. ']': [IN_PATH, PUSH_SUB_PATH],
  613. 'eof': ERROR,
  614. 'else': [IN_SUB_PATH, APPEND]
  615. };
  616. pathStateMachine[IN_SINGLE_QUOTE] = {
  617. "'": [IN_SUB_PATH, APPEND],
  618. 'eof': ERROR,
  619. 'else': [IN_SINGLE_QUOTE, APPEND]
  620. };
  621. pathStateMachine[IN_DOUBLE_QUOTE] = {
  622. '"': [IN_SUB_PATH, APPEND],
  623. 'eof': ERROR,
  624. 'else': [IN_DOUBLE_QUOTE, APPEND]
  625. };
  626. /**
  627. * Check if an expression is a literal value.
  628. */
  629. var literalValueRE = /^\s?(true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;
  630. function isLiteral (exp) {
  631. return literalValueRE.test(exp)
  632. }
  633. /**
  634. * Strip quotes from a string
  635. */
  636. function stripQuotes (str) {
  637. var a = str.charCodeAt(0);
  638. var b = str.charCodeAt(str.length - 1);
  639. return a === b && (a === 0x22 || a === 0x27)
  640. ? str.slice(1, -1)
  641. : str
  642. }
  643. /**
  644. * Determine the type of a character in a keypath.
  645. */
  646. function getPathCharType (ch) {
  647. if (ch === undefined || ch === null) { return 'eof' }
  648. var code = ch.charCodeAt(0);
  649. switch (code) {
  650. case 0x5B: // [
  651. case 0x5D: // ]
  652. case 0x2E: // .
  653. case 0x22: // "
  654. case 0x27: // '
  655. case 0x30: // 0
  656. return ch
  657. case 0x5F: // _
  658. case 0x24: // $
  659. case 0x2D: // -
  660. return 'ident'
  661. case 0x20: // Space
  662. case 0x09: // Tab
  663. case 0x0A: // Newline
  664. case 0x0D: // Return
  665. case 0xA0: // No-break space
  666. case 0xFEFF: // Byte Order Mark
  667. case 0x2028: // Line Separator
  668. case 0x2029: // Paragraph Separator
  669. return 'ws'
  670. }
  671. // a-z, A-Z
  672. if ((code >= 0x61 && code <= 0x7A) || (code >= 0x41 && code <= 0x5A)) {
  673. return 'ident'
  674. }
  675. // 1-9
  676. if (code >= 0x31 && code <= 0x39) { return 'number' }
  677. return 'else'
  678. }
  679. /**
  680. * Format a subPath, return its plain form if it is
  681. * a literal string or number. Otherwise prepend the
  682. * dynamic indicator (*).
  683. */
  684. function formatSubPath (path) {
  685. var trimmed = path.trim();
  686. // invalid leading 0
  687. if (path.charAt(0) === '0' && isNaN(path)) { return false }
  688. return isLiteral(trimmed) ? stripQuotes(trimmed) : '*' + trimmed
  689. }
  690. /**
  691. * Parse a string path into an array of segments
  692. */
  693. function parse$1 (path) {
  694. var keys = [];
  695. var index = -1;
  696. var mode = BEFORE_PATH;
  697. var subPathDepth = 0;
  698. var c;
  699. var key;
  700. var newChar;
  701. var type;
  702. var transition;
  703. var action;
  704. var typeMap;
  705. var actions = [];
  706. actions[PUSH] = function () {
  707. if (key !== undefined) {
  708. keys.push(key);
  709. key = undefined;
  710. }
  711. };
  712. actions[APPEND] = function () {
  713. if (key === undefined) {
  714. key = newChar;
  715. } else {
  716. key += newChar;
  717. }
  718. };
  719. actions[INC_SUB_PATH_DEPTH] = function () {
  720. actions[APPEND]();
  721. subPathDepth++;
  722. };
  723. actions[PUSH_SUB_PATH] = function () {
  724. if (subPathDepth > 0) {
  725. subPathDepth--;
  726. mode = IN_SUB_PATH;
  727. actions[APPEND]();
  728. } else {
  729. subPathDepth = 0;
  730. key = formatSubPath(key);
  731. if (key === false) {
  732. return false
  733. } else {
  734. actions[PUSH]();
  735. }
  736. }
  737. };
  738. function maybeUnescapeQuote () {
  739. var nextChar = path[index + 1];
  740. if ((mode === IN_SINGLE_QUOTE && nextChar === "'") ||
  741. (mode === IN_DOUBLE_QUOTE && nextChar === '"')) {
  742. index++;
  743. newChar = '\\' + nextChar;
  744. actions[APPEND]();
  745. return true
  746. }
  747. }
  748. while (mode !== null) {
  749. index++;
  750. c = path[index];
  751. if (c === '\\' && maybeUnescapeQuote()) {
  752. continue
  753. }
  754. type = getPathCharType(c);
  755. typeMap = pathStateMachine[mode];
  756. transition = typeMap[type] || typeMap['else'] || ERROR;
  757. if (transition === ERROR) {
  758. return // parse error
  759. }
  760. mode = transition[0];
  761. action = actions[transition[1]];
  762. if (action) {
  763. newChar = transition[2];
  764. newChar = newChar === undefined
  765. ? c
  766. : newChar;
  767. if (action() === false) {
  768. return
  769. }
  770. }
  771. if (mode === AFTER_PATH) {
  772. return keys
  773. }
  774. }
  775. }
  776. function empty (target) {
  777. /* istanbul ignore else */
  778. if (Array.isArray(target)) {
  779. return target.length === 0
  780. } else {
  781. return false
  782. }
  783. }
  784. var I18nPath = function I18nPath () {
  785. this._cache = Object.create(null);
  786. };
  787. /**
  788. * External parse that check for a cache hit first
  789. */
  790. I18nPath.prototype.parsePath = function parsePath (path) {
  791. var hit = this._cache[path];
  792. if (!hit) {
  793. hit = parse$1(path);
  794. if (hit) {
  795. this._cache[path] = hit;
  796. }
  797. }
  798. return hit || []
  799. };
  800. /**
  801. * Get path value from path string
  802. */
  803. I18nPath.prototype.getPathValue = function getPathValue (obj, path) {
  804. if (!isObject(obj)) { return null }
  805. var paths = this.parsePath(path);
  806. if (empty(paths)) {
  807. return null
  808. } else {
  809. var length = paths.length;
  810. var ret = null;
  811. var last = obj;
  812. var i = 0;
  813. while (i < length) {
  814. var value = last[paths[i]];
  815. if (value === undefined) {
  816. last = null;
  817. break
  818. }
  819. last = value;
  820. i++;
  821. }
  822. ret = last;
  823. return ret
  824. }
  825. };
  826. /* */
  827. var numberFormatKeys = [
  828. 'style',
  829. 'currency',
  830. 'currencyDisplay',
  831. 'useGrouping',
  832. 'minimumIntegerDigits',
  833. 'minimumFractionDigits',
  834. 'maximumFractionDigits',
  835. 'minimumSignificantDigits',
  836. 'maximumSignificantDigits',
  837. 'localeMatcher',
  838. 'formatMatcher'
  839. ];
  840. var VueI18n = function VueI18n (options) {
  841. var this$1 = this;
  842. if ( options === void 0 ) options = {};
  843. // Auto install if it is not done yet and `window` has `Vue`.
  844. // To allow users to avoid auto-installation in some cases,
  845. // this code should be placed here. See #290
  846. /* istanbul ignore if */
  847. if (!Vue && typeof window !== 'undefined' && window.Vue) {
  848. install(window.Vue);
  849. }
  850. var locale = options.locale || 'en-US';
  851. var fallbackLocale = options.fallbackLocale || 'en-US';
  852. var messages = options.messages || {};
  853. var dateTimeFormats = options.dateTimeFormats || {};
  854. var numberFormats = options.numberFormats || {};
  855. this._vm = null;
  856. this._formatter = options.formatter || new BaseFormatter();
  857. this._missing = options.missing || null;
  858. this._root = options.root || null;
  859. this._sync = options.sync === undefined ? true : !!options.sync;
  860. this._fallbackRoot = options.fallbackRoot === undefined
  861. ? true
  862. : !!options.fallbackRoot;
  863. this._silentTranslationWarn = options.silentTranslationWarn === undefined
  864. ? false
  865. : !!options.silentTranslationWarn;
  866. this._dateTimeFormatters = {};
  867. this._numberFormatters = {};
  868. this._path = new I18nPath();
  869. this._dataListeners = [];
  870. this._exist = function (message, key) {
  871. if (!message || !key) { return false }
  872. return !isNull(this$1._path.getPathValue(message, key))
  873. };
  874. this._initVM({
  875. locale: locale,
  876. fallbackLocale: fallbackLocale,
  877. messages: messages,
  878. dateTimeFormats: dateTimeFormats,
  879. numberFormats: numberFormats
  880. });
  881. };
  882. var prototypeAccessors = { vm: { configurable: true },messages: { configurable: true },dateTimeFormats: { configurable: true },numberFormats: { configurable: true },locale: { configurable: true },fallbackLocale: { configurable: true },missing: { configurable: true },formatter: { configurable: true },silentTranslationWarn: { configurable: true } };
  883. VueI18n.prototype._initVM = function _initVM (data) {
  884. var silent = Vue.config.silent;
  885. Vue.config.silent = true;
  886. this._vm = new Vue({ data: data });
  887. Vue.config.silent = silent;
  888. };
  889. VueI18n.prototype.subscribeDataChanging = function subscribeDataChanging (vm) {
  890. this._dataListeners.push(vm);
  891. };
  892. VueI18n.prototype.unsubscribeDataChanging = function unsubscribeDataChanging (vm) {
  893. remove(this._dataListeners, vm);
  894. };
  895. VueI18n.prototype.watchI18nData = function watchI18nData () {
  896. var self = this;
  897. return this._vm.$watch('$data', function () {
  898. var i = self._dataListeners.length;
  899. while (i--) {
  900. Vue.nextTick(function () {
  901. self._dataListeners[i] && self._dataListeners[i].$forceUpdate();
  902. });
  903. }
  904. }, { deep: true })
  905. };
  906. VueI18n.prototype.watchLocale = function watchLocale () {
  907. /* istanbul ignore if */
  908. if (!this._sync || !this._root) { return null }
  909. var target = this._vm;
  910. return this._root.vm.$watch('locale', function (val) {
  911. target.$set(target, 'locale', val);
  912. target.$forceUpdate();
  913. }, { immediate: true })
  914. };
  915. prototypeAccessors.vm.get = function () { return this._vm };
  916. prototypeAccessors.messages.get = function () { return looseClone(this._getMessages()) };
  917. prototypeAccessors.dateTimeFormats.get = function () { return looseClone(this._getDateTimeFormats()) };
  918. prototypeAccessors.numberFormats.get = function () { return looseClone(this._getNumberFormats()) };
  919. prototypeAccessors.locale.get = function () { return this._vm.locale };
  920. prototypeAccessors.locale.set = function (locale) {
  921. this._vm.$set(this._vm, 'locale', locale);
  922. };
  923. prototypeAccessors.fallbackLocale.get = function () { return this._vm.fallbackLocale };
  924. prototypeAccessors.fallbackLocale.set = function (locale) {
  925. this._vm.$set(this._vm, 'fallbackLocale', locale);
  926. };
  927. prototypeAccessors.missing.get = function () { return this._missing };
  928. prototypeAccessors.missing.set = function (handler) { this._missing = handler; };
  929. prototypeAccessors.formatter.get = function () { return this._formatter };
  930. prototypeAccessors.formatter.set = function (formatter) { this._formatter = formatter; };
  931. prototypeAccessors.silentTranslationWarn.get = function () { return this._silentTranslationWarn };
  932. prototypeAccessors.silentTranslationWarn.set = function (silent) { this._silentTranslationWarn = silent; };
  933. VueI18n.prototype._getMessages = function _getMessages () { return this._vm.messages };
  934. VueI18n.prototype._getDateTimeFormats = function _getDateTimeFormats () { return this._vm.dateTimeFormats };
  935. VueI18n.prototype._getNumberFormats = function _getNumberFormats () { return this._vm.numberFormats };
  936. VueI18n.prototype._warnDefault = function _warnDefault (locale, key, result, vm, values) {
  937. if (!isNull(result)) { return result }
  938. if (this._missing) {
  939. var missingRet = this._missing.apply(null, [locale, key, vm, values]);
  940. if (typeof missingRet === 'string') {
  941. return missingRet
  942. }
  943. } else {
  944. if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
  945. warn(
  946. "Cannot translate the value of keypath '" + key + "'. " +
  947. 'Use the value of keypath as default.'
  948. );
  949. }
  950. }
  951. return key
  952. };
  953. VueI18n.prototype._isFallbackRoot = function _isFallbackRoot (val) {
  954. return !val && !isNull(this._root) && this._fallbackRoot
  955. };
  956. VueI18n.prototype._interpolate = function _interpolate (
  957. locale,
  958. message,
  959. key,
  960. host,
  961. interpolateMode,
  962. values
  963. ) {
  964. if (!message) { return null }
  965. var pathRet = this._path.getPathValue(message, key);
  966. if (Array.isArray(pathRet) || isPlainObject(pathRet)) { return pathRet }
  967. var ret;
  968. if (isNull(pathRet)) {
  969. /* istanbul ignore else */
  970. if (isPlainObject(message)) {
  971. ret = message[key];
  972. if (typeof ret !== 'string') {
  973. if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
  974. warn(("Value of key '" + key + "' is not a string!"));
  975. }
  976. return null
  977. }
  978. } else {
  979. return null
  980. }
  981. } else {
  982. /* istanbul ignore else */
  983. if (typeof pathRet === 'string') {
  984. ret = pathRet;
  985. } else {
  986. if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
  987. warn(("Value of key '" + key + "' is not a string!"));
  988. }
  989. return null
  990. }
  991. }
  992. // Check for the existance of links within the translated string
  993. if (ret.indexOf('@:') >= 0) {
  994. ret = this._link(locale, message, ret, host, interpolateMode, values);
  995. }
  996. return this._render(ret, interpolateMode, values)
  997. };
  998. VueI18n.prototype._link = function _link (
  999. locale,
  1000. message,
  1001. str,
  1002. host,
  1003. interpolateMode,
  1004. values
  1005. ) {
  1006. var this$1 = this;
  1007. var ret = str;
  1008. // Match all the links within the local
  1009. // We are going to replace each of
  1010. // them with its translation
  1011. var matches = ret.match(/(@:[\w\-_|.]+)/g);
  1012. for (var idx in matches) {
  1013. // ie compatible: filter custom array
  1014. // prototype method
  1015. if (!matches.hasOwnProperty(idx)) {
  1016. continue
  1017. }
  1018. var link = matches[idx];
  1019. // Remove the leading @:
  1020. var linkPlaceholder = link.substr(2);
  1021. // Translate the link
  1022. var translated = this$1._interpolate(
  1023. locale, message, linkPlaceholder, host,
  1024. interpolateMode === 'raw' ? 'string' : interpolateMode,
  1025. interpolateMode === 'raw' ? undefined : values
  1026. );
  1027. if (this$1._isFallbackRoot(translated)) {
  1028. if (process.env.NODE_ENV !== 'production' && !this$1._silentTranslationWarn) {
  1029. warn(("Fall back to translate the link placeholder '" + linkPlaceholder + "' with root locale."));
  1030. }
  1031. /* istanbul ignore if */
  1032. if (!this$1._root) { throw Error('unexpected error') }
  1033. var root = this$1._root;
  1034. translated = root._translate(
  1035. root._getMessages(), root.locale, root.fallbackLocale,
  1036. linkPlaceholder, host, interpolateMode, values
  1037. );
  1038. }
  1039. translated = this$1._warnDefault(
  1040. locale, linkPlaceholder, translated, host,
  1041. Array.isArray(values) ? values : [values]
  1042. );
  1043. // Replace the link with the translated
  1044. ret = !translated ? ret : ret.replace(link, translated);
  1045. }
  1046. return ret
  1047. };
  1048. VueI18n.prototype._render = function _render (message, interpolateMode, values) {
  1049. var ret = this._formatter.interpolate(message, values);
  1050. // if interpolateMode is **not** 'string' ('row'),
  1051. // return the compiled data (e.g. ['foo', VNode, 'bar']) with formatter
  1052. return interpolateMode === 'string' ? ret.join('') : ret
  1053. };
  1054. VueI18n.prototype._translate = function _translate (
  1055. messages,
  1056. locale,
  1057. fallback,
  1058. key,
  1059. host,
  1060. interpolateMode,
  1061. args
  1062. ) {
  1063. var res =
  1064. this._interpolate(locale, messages[locale], key, host, interpolateMode, args);
  1065. if (!isNull(res)) { return res }
  1066. res = this._interpolate(fallback, messages[fallback], key, host, interpolateMode, args);
  1067. if (!isNull(res)) {
  1068. if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
  1069. warn(("Fall back to translate the keypath '" + key + "' with '" + fallback + "' locale."));
  1070. }
  1071. return res
  1072. } else {
  1073. return null
  1074. }
  1075. };
  1076. VueI18n.prototype._t = function _t (key, _locale, messages, host) {
  1077. var ref;
  1078. var values = [], len = arguments.length - 4;
  1079. while ( len-- > 0 ) values[ len ] = arguments[ len + 4 ];
  1080. if (!key) { return '' }
  1081. var parsedArgs = parseArgs.apply(void 0, values);
  1082. var locale = parsedArgs.locale || _locale;
  1083. var ret = this._translate(
  1084. messages, locale, this.fallbackLocale, key,
  1085. host, 'string', parsedArgs.params
  1086. );
  1087. if (this._isFallbackRoot(ret)) {
  1088. if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
  1089. warn(("Fall back to translate the keypath '" + key + "' with root locale."));
  1090. }
  1091. /* istanbul ignore if */
  1092. if (!this._root) { throw Error('unexpected error') }
  1093. return (ref = this._root).t.apply(ref, [ key ].concat( values ))
  1094. } else {
  1095. return this._warnDefault(locale, key, ret, host, values)
  1096. }
  1097. };
  1098. VueI18n.prototype.t = function t (key) {
  1099. var ref;
  1100. var values = [], len = arguments.length - 1;
  1101. while ( len-- > 0 ) values[ len ] = arguments[ len + 1 ];
  1102. return (ref = this)._t.apply(ref, [ key, this.locale, this._getMessages(), null ].concat( values ))
  1103. };
  1104. VueI18n.prototype._i = function _i (key, locale, messages, host, values) {
  1105. var ret =
  1106. this._translate(messages, locale, this.fallbackLocale, key, host, 'raw', values);
  1107. if (this._isFallbackRoot(ret)) {
  1108. if (process.env.NODE_ENV !== 'production' && !this._silentTranslationWarn) {
  1109. warn(("Fall back to interpolate the keypath '" + key + "' with root locale."));
  1110. }
  1111. if (!this._root) { throw Error('unexpected error') }
  1112. return this._root.i(key, locale, values)
  1113. } else {
  1114. return this._warnDefault(locale, key, ret, host, [values])
  1115. }
  1116. };
  1117. VueI18n.prototype.i = function i (key, locale, values) {
  1118. /* istanbul ignore if */
  1119. if (!key) { return '' }
  1120. if (typeof locale !== 'string') {
  1121. locale = this.locale;
  1122. }
  1123. return this._i(key, locale, this._getMessages(), null, values)
  1124. };
  1125. VueI18n.prototype._tc = function _tc (
  1126. key,
  1127. _locale,
  1128. messages,
  1129. host,
  1130. choice
  1131. ) {
  1132. var ref;
  1133. var values = [], len = arguments.length - 5;
  1134. while ( len-- > 0 ) values[ len ] = arguments[ len + 5 ];
  1135. if (!key) { return '' }
  1136. if (choice === undefined) {
  1137. choice = 1;
  1138. }
  1139. return fetchChoice((ref = this)._t.apply(ref, [ key, _locale, messages, host ].concat( values )), choice)
  1140. };
  1141. VueI18n.prototype.tc = function tc (key, choice) {
  1142. var ref;
  1143. var values = [], len = arguments.length - 2;
  1144. while ( len-- > 0 ) values[ len ] = arguments[ len + 2 ];
  1145. return (ref = this)._tc.apply(ref, [ key, this.locale, this._getMessages(), null, choice ].concat( values ))
  1146. };
  1147. VueI18n.prototype._te = function _te (key, locale, messages) {
  1148. var args = [], len = arguments.length - 3;
  1149. while ( len-- > 0 ) args[ len ] = arguments[ len + 3 ];
  1150. var _locale = parseArgs.apply(void 0, args).locale || locale;
  1151. return this._exist(messages[_locale], key)
  1152. };
  1153. VueI18n.prototype.te = function te (key, locale) {
  1154. return this._te(key, this.locale, this._getMessages(), locale)
  1155. };
  1156. VueI18n.prototype.getLocaleMessage = function getLocaleMessage (locale) {
  1157. return looseClone(this._vm.messages[locale] || {})
  1158. };
  1159. VueI18n.prototype.setLocaleMessage = function setLocaleMessage (locale, message) {
  1160. this._vm.$set(this._vm.messages, locale, message);
  1161. };
  1162. VueI18n.prototype.mergeLocaleMessage = function mergeLocaleMessage (locale, message) {
  1163. this._vm.$set(this._vm.messages, locale, Vue.util.extend(this._vm.messages[locale] || {}, message));
  1164. };
  1165. VueI18n.prototype.getDateTimeFormat = function getDateTimeFormat (locale) {
  1166. return looseClone(this._vm.dateTimeFormats[locale] || {})
  1167. };
  1168. VueI18n.prototype.setDateTimeFormat = function setDateTimeFormat (locale, format) {
  1169. this._vm.$set(this._vm.dateTimeFormats, locale, format);
  1170. };
  1171. VueI18n.prototype.mergeDateTimeFormat = function mergeDateTimeFormat (locale, format) {
  1172. this._vm.$set(this._vm.dateTimeFormats, locale, Vue.util.extend(this._vm.dateTimeFormats[locale] || {}, format));
  1173. };
  1174. VueI18n.prototype._localizeDateTime = function _localizeDateTime (
  1175. value,
  1176. locale,
  1177. fallback,
  1178. dateTimeFormats,
  1179. key
  1180. ) {
  1181. var _locale = locale;
  1182. var formats = dateTimeFormats[_locale];
  1183. // fallback locale
  1184. if (isNull(formats) || isNull(formats[key])) {
  1185. if (process.env.NODE_ENV !== 'production') {
  1186. warn(("Fall back to '" + fallback + "' datetime formats from '" + locale + " datetime formats."));
  1187. }
  1188. _locale = fallback;
  1189. formats = dateTimeFormats[_locale];
  1190. }
  1191. if (isNull(formats) || isNull(formats[key])) {
  1192. return null
  1193. } else {
  1194. var format = formats[key];
  1195. var id = _locale + "__" + key;
  1196. var formatter = this._dateTimeFormatters[id];
  1197. if (!formatter) {
  1198. formatter = this._dateTimeFormatters[id] = new Intl.DateTimeFormat(_locale, format);
  1199. }
  1200. return formatter.format(value)
  1201. }
  1202. };
  1203. VueI18n.prototype._d = function _d (value, locale, key) {
  1204. /* istanbul ignore if */
  1205. if (process.env.NODE_ENV !== 'production' && !VueI18n.availabilities.dateTimeFormat) {
  1206. warn('Cannot format a Date value due to not supported Intl.DateTimeFormat.');
  1207. return ''
  1208. }
  1209. if (!key) {
  1210. return new Intl.DateTimeFormat(locale).format(value)
  1211. }
  1212. var ret =
  1213. this._localizeDateTime(value, locale, this.fallbackLocale, this._getDateTimeFormats(), key);
  1214. if (this._isFallbackRoot(ret)) {
  1215. if (process.env.NODE_ENV !== 'production') {
  1216. warn(("Fall back to datetime localization of root: key '" + key + "' ."));
  1217. }
  1218. /* istanbul ignore if */
  1219. if (!this._root) { throw Error('unexpected error') }
  1220. return this._root.d(value, key, locale)
  1221. } else {
  1222. return ret || ''
  1223. }
  1224. };
  1225. VueI18n.prototype.d = function d (value) {
  1226. var args = [], len = arguments.length - 1;
  1227. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  1228. var locale = this.locale;
  1229. var key = null;
  1230. if (args.length === 1) {
  1231. if (typeof args[0] === 'string') {
  1232. key = args[0];
  1233. } else if (isObject(args[0])) {
  1234. if (args[0].locale) {
  1235. locale = args[0].locale;
  1236. }
  1237. if (args[0].key) {
  1238. key = args[0].key;
  1239. }
  1240. }
  1241. } else if (args.length === 2) {
  1242. if (typeof args[0] === 'string') {
  1243. key = args[0];
  1244. }
  1245. if (typeof args[1] === 'string') {
  1246. locale = args[1];
  1247. }
  1248. }
  1249. return this._d(value, locale, key)
  1250. };
  1251. VueI18n.prototype.getNumberFormat = function getNumberFormat (locale) {
  1252. return looseClone(this._vm.numberFormats[locale] || {})
  1253. };
  1254. VueI18n.prototype.setNumberFormat = function setNumberFormat (locale, format) {
  1255. this._vm.$set(this._vm.numberFormats, locale, format);
  1256. };
  1257. VueI18n.prototype.mergeNumberFormat = function mergeNumberFormat (locale, format) {
  1258. this._vm.$set(this._vm.numberFormats, locale, Vue.util.extend(this._vm.numberFormats[locale] || {}, format));
  1259. };
  1260. VueI18n.prototype._localizeNumber = function _localizeNumber (
  1261. value,
  1262. locale,
  1263. fallback,
  1264. numberFormats,
  1265. key,
  1266. options
  1267. ) {
  1268. var _locale = locale;
  1269. var formats = numberFormats[_locale];
  1270. // fallback locale
  1271. if (isNull(formats) || isNull(formats[key])) {
  1272. if (process.env.NODE_ENV !== 'production') {
  1273. warn(("Fall back to '" + fallback + "' number formats from '" + locale + " number formats."));
  1274. }
  1275. _locale = fallback;
  1276. formats = numberFormats[_locale];
  1277. }
  1278. if (isNull(formats) || isNull(formats[key])) {
  1279. return null
  1280. } else {
  1281. var format = formats[key];
  1282. var formatter;
  1283. if (options) {
  1284. // If options specified - create one time number formatter
  1285. formatter = new Intl.NumberFormat(_locale, Object.assign({}, format, options));
  1286. } else {
  1287. var id = _locale + "__" + key;
  1288. formatter = this._numberFormatters[id];
  1289. if (!formatter) {
  1290. formatter = this._numberFormatters[id] = new Intl.NumberFormat(_locale, format);
  1291. }
  1292. }
  1293. return formatter.format(value)
  1294. }
  1295. };
  1296. VueI18n.prototype._n = function _n (value, locale, key, options) {
  1297. /* istanbul ignore if */
  1298. if (process.env.NODE_ENV !== 'production' && !VueI18n.availabilities.numberFormat) {
  1299. warn('Cannot format a Number value due to not supported Intl.NumberFormat.');
  1300. return ''
  1301. }
  1302. if (!key) {
  1303. var nf = !options ? new Intl.NumberFormat(locale) : new Intl.NumberFormat(locale, options);
  1304. return nf.format(value)
  1305. }
  1306. var ret =
  1307. this._localizeNumber(value, locale, this.fallbackLocale, this._getNumberFormats(), key, options);
  1308. if (this._isFallbackRoot(ret)) {
  1309. if (process.env.NODE_ENV !== 'production') {
  1310. warn(("Fall back to number localization of root: key '" + key + "' ."));
  1311. }
  1312. /* istanbul ignore if */
  1313. if (!this._root) { throw Error('unexpected error') }
  1314. return this._root.n(value, Object.assign({}, { key: key, locale: locale }, options))
  1315. } else {
  1316. return ret || ''
  1317. }
  1318. };
  1319. VueI18n.prototype.n = function n (value) {
  1320. var args = [], len = arguments.length - 1;
  1321. while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
  1322. var locale = this.locale;
  1323. var key = null;
  1324. var options = null;
  1325. if (args.length === 1) {
  1326. if (typeof args[0] === 'string') {
  1327. key = args[0];
  1328. } else if (isObject(args[0])) {
  1329. if (args[0].locale) {
  1330. locale = args[0].locale;
  1331. }
  1332. if (args[0].key) {
  1333. key = args[0].key;
  1334. }
  1335. // Filter out number format options only
  1336. options = Object.keys(args[0]).reduce(function (acc, key) {
  1337. var obj;
  1338. if (numberFormatKeys.includes(key)) {
  1339. return Object.assign({}, acc, ( obj = {}, obj[key] = args[0][key], obj ))
  1340. }
  1341. return acc
  1342. }, null);
  1343. }
  1344. } else if (args.length === 2) {
  1345. if (typeof args[0] === 'string') {
  1346. key = args[0];
  1347. }
  1348. if (typeof args[1] === 'string') {
  1349. locale = args[1];
  1350. }
  1351. }
  1352. return this._n(value, locale, key, options)
  1353. };
  1354. Object.defineProperties( VueI18n.prototype, prototypeAccessors );
  1355. VueI18n.availabilities = {
  1356. dateTimeFormat: canUseDateTimeFormat,
  1357. numberFormat: canUseNumberFormat
  1358. };
  1359. VueI18n.install = install;
  1360. VueI18n.version = '7.8.1';
  1361. export default VueI18n;