@enact/i18n
Version:
Internationalization support for Enact using iLib
218 lines (210 loc) • 9.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.I18n = void 0;
var _dispatcher = require("@enact/core/dispatcher");
var _util = require("@enact/core/util");
var _locale = require("../locale");
var _resBundle = require("../src/resBundle");
var _wrapIlibCallback = _interopRequireDefault(require("../src/wrapIlibCallback"));
var _getI18nClasses = _interopRequireDefault(require("./getI18nClasses"));
var _windowFocus = require("./windowFocus");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _toArray(r) { return _arrayWithHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
* Manages i18n resource loading.
*
* @class I18n
* @private
*/
var I18n = exports.I18n = /*#__PURE__*/function () {
function I18n(_ref) {
var _this = this;
var latinLanguageOverrides = _ref.latinLanguageOverrides,
nonLatinLanguageOverrides = _ref.nonLatinLanguageOverrides,
resources = _ref.resources,
_ref$sync = _ref.sync,
sync = _ref$sync === void 0 ? true : _ref$sync;
_classCallCheck(this, I18n);
/**
* Called when the `languagechange` event fires.
*/
this.handleLocaleChange = function () {
(0, _windowFocus.onWindowFocus)(_this.updateLocale);
};
/**
* Updates the locale for the application.
*
* If `newLocale` is omitted, the locale will be reset to the device's default locale.
*
* @param {String} newLocale Locale identifier string
*
* @returns {undefined}
* @public
*/
this.updateLocale = function (newLocale) {
_this.loadResources(newLocale);
};
this._locale = null;
this._ready = sync;
this._onLoadResources = function () {};
this.loadResourceJob = null;
this.latinLanguageOverrides = latinLanguageOverrides;
this.nonLatinLanguageOverrides = nonLatinLanguageOverrides;
this.resources = this.normalizeResources(resources);
this.sync = sync;
}
/**
* Sets the current locale and load callback.
*
* Changing the locale will request new resource files for that locale.
*
* @type {String}
* @public
*/
return _createClass(I18n, [{
key: "setContext",
value: function setContext(locale, onLoadResources) {
this.loadResourceJob = new _util.Job(onLoadResources);
this._onLoadResources = onLoadResources;
if (this._locale !== locale) {
this._locale = locale;
this.loadResources(locale);
}
}
/**
* Normalize the structure of the external resources to be an array of resource/onLoad pairs.
*
* @private
*/
}, {
key: "normalizeResources",
value: function normalizeResources(resources) {
return Array.isArray(resources) ? resources.map(function (res) {
if (!res) return;
var fn = res.resource || res;
var onLoad = res.onLoad;
if (typeof fn !== 'function') return;
return {
resource: fn,
onLoad: onLoad
};
}).filter(Boolean) : [];
}
/**
* Adds the `languagechange` event listener and initiates async resource retrieval.
*
* Should only be called after `window` is available and the DOM is ready.
*
* @public
*/
}, {
key: "load",
value: function load() {
this._ready = true;
if (typeof window === 'object') {
(0, _dispatcher.on)('languagechange', this.handleLocaleChange, window);
}
// When async, we defer loading resources until DOM is ready
if (!this.sync) {
this.loadResources(this._locale);
}
}
/**
* Cleans up resource retrieval and event listeners.
*
* @public
*/
}, {
key: "unload",
value: function unload() {
this._ready = false;
this.loadResourceJob.stop();
if (typeof window === 'object') {
(0, _dispatcher.off)('languagechange', this.handleLocaleChange, window);
}
}
/**
* Loads the resources for the given locale.
*
* @private
*/
}, {
key: "loadResources",
value: function loadResources(spec) {
var _this2 = this;
if (!this._ready) return;
var locale = (0, _locale.updateLocale)(spec);
var options = {
sync: this.sync,
locale: locale
};
var rtl = (0, _wrapIlibCallback["default"])(_locale.isRtlLocale, options);
var className = (0, _wrapIlibCallback["default"])(_getI18nClasses["default"], _objectSpread(_objectSpread({}, options), {}, {
latinLanguageOverrides: this.latinLanguageOverrides,
nonLatinLanguageOverrides: this.nonLatinLanguageOverrides
}));
var bundle = (0, _wrapIlibCallback["default"])(_resBundle.createResBundle, options);
if (this.sync) {
var state = {
className: className,
loaded: true,
locale: locale,
rtl: rtl
};
(0, _resBundle.setResBundle)(bundle);
this.resources.forEach(function (_ref2) {
var resource = _ref2.resource,
onLoad = _ref2.onLoad;
var result = resource(options);
if (onLoad) onLoad(result);
});
this._onLoadResources(state);
} else {
var resources = Promise.all([rtl, className,
// move updating into a new method with call to setState
bundle].concat(_toConsumableArray(this.resources.map(function (res) {
return (0, _wrapIlibCallback["default"])(res.resource, options);
})))).then(function (_ref3) {
var _ref4 = _toArray(_ref3),
rtlResult = _ref4[0],
classNameResult = _ref4[1],
bundleResult = _ref4[2],
userResources = _arrayLikeToArray(_ref4).slice(3);
(0, _resBundle.setResBundle)(bundleResult);
_this2.resources.forEach(function (_ref5, i) {
var onLoad = _ref5.onLoad;
return onLoad && onLoad(userResources[i]);
});
return {
className: classNameResult,
loaded: true,
locale: locale,
rtl: rtlResult
};
});
// TODO: Resolve how to handle failed resource requests
// .catch(...);
this.loadResourceJob.promise(resources);
}
}
}]);
}();
var _default = exports["default"] = I18n;