vue-i18n.common.js 41 KB

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