UNPKG

@enact/ui

Version:

A collection of simplified unstyled cross-platform UI components for Enact

243 lines (231 loc) 9.03 kB
"use strict"; function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _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 _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 _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 _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } var fontMap = {}; var currentLocale = null; // Generate a single font-face rule var buildFont = function buildFont(config) { if (!config && !config.name) { return ''; } var strOut = '@font-face { \n' + " font-family: \"".concat(config.name, "\";\n"); if (config.weight) { strOut += " font-weight: ".concat(config.weight, ";\n"); } if (config.localName) { // Accept a string or an array. If it's a string convert it into an array if (typeof config.localName === 'string') { config.localName = [config.localName]; } // Take our array and update each of its elements to be CSS "local()" strings config.localName = config.localName.map(function (f) { return "local(\"".concat(f, "\")"); }); // Join all our strings together with a comma, so it's a valid CSS `src` rule strOut += " src: ".concat(config.localName.join(', '), ";\n"); } if (config.unicodeRange) { strOut += " unicode-range: ".concat(config.unicodeRange, ";\n"); } strOut += '} \n'; return strOut; }; // Generate a collection of font-face rules, in multiple font-variants var buildFontSet = function buildFontSet(fontName, fonts, strLang, bitDefault) { var strOut = '', name = bitDefault ? fontName : fontName + ' ' + strLang; if (fonts[strLang].regular) { // Build Regular strOut += buildFont({ name: name, localName: fonts[strLang].regular, unicodeRange: fonts[strLang].unicodeRange }); // Build Light strOut += buildFont({ name: name, localName: fonts[strLang].light || fonts[strLang].regular, weight: 300, unicodeRange: fonts[strLang].unicodeRange }); // Build SemiBold strOut += buildFont({ name: name, localName: fonts[strLang].semibold || fonts[strLang].bold || fonts[strLang].regular, weight: 600, unicodeRange: fonts[strLang].unicodeRange }); // Build Bold strOut += buildFont({ name: name, localName: fonts[strLang].bold || fonts[strLang].regular, weight: 700, unicodeRange: fonts[strLang].unicodeRange }); } return strOut; }; var buildFontDefinitionCss = function buildFontDefinitionCss(locale, buildOverrides) { var matchLang = locale.match(/\b([a-z]{2})\b/), language = matchLang && matchLang[1], matchScript = locale.match(/\b([a-z]{4})\b/i), script = matchScript && matchScript[1], matchReg = locale.match(/\b([A-Z]{2}|[0-9]{3})\b/), region = matchReg && matchReg[1]; var fontDefinitionCss = ''; // Build all the fonts so they could be explicitly called for (var fontName in fontMap) { var fonts = fontMap[fontName]; for (var lang in fonts) { if (!buildOverrides) { fontDefinitionCss += buildFontSet(fontName, fonts, lang); } else { // Set up the override for locale-specific font. // la = language, sc = script, re = region; `la-RE` or `zh-Hans-HK` var _lang$split = lang.split('-'), _lang$split2 = _slicedToArray(_lang$split, 3), la = _lang$split2[0], sc = _lang$split2[1], re = _lang$split2[2]; // if script is not specified, fall back to second part representing region if (!re && sc && sc.length === 2) { re = sc; sc = null; } var matchesRegion = re ? re === region : true; var matchesScript = sc ? sc === script : true; if (la === language && matchesRegion && matchesScript) { fontDefinitionCss += buildFontSet(fontName, fonts, lang, true); } } } } return fontDefinitionCss; }; var insertFontDefinitionCss = function insertFontDefinitionCss(styleId, fontDefinitionCss) { if (typeof document !== 'undefined') { // Normal execution in a browser window var styleElem = document.getElementById(styleId); if (!styleElem) { styleElem = document.createElement('style'); styleElem.setAttribute('id', styleId); styleElem.setAttribute('type', 'text/css'); document.head.appendChild(styleElem); } styleElem.innerHTML = fontDefinitionCss; } else { var tag = "<style type=\"text/css\" id=\"".concat(styleId, "\">").concat(fontDefinitionCss, "</style>"); // We're rendering without the DOM; return the font definition stylesheet element string. return tag; } }; function fontGenerator(locale) { var styleId = 'localized-fonts'; if (typeof document !== 'undefined' && document.getElementById(styleId)) { return; } return insertFontDefinitionCss(styleId, buildFontDefinitionCss(locale)); } function fontOverrideGenerator(locale) { return insertFontDefinitionCss('localized-fonts-override', buildFontDefinitionCss(locale, true)); } /** * Generates locale-specific font rules allowing any locale to have its own custom font. Each * locale-font from the configuration block (defined in this file) is generated at run-time. If the * locale you're currently in is in the locale-font list an additional `@font-face` rule will be * generated that will override the standard font. * * In addition to the standard override-font being generated, named region-specific fonts are also * generated. This lets you incorporate language specific fonts when you're outside of one of those * regions; useful in a language list context where you want the name of each language to be * represented by that language's designated font. * * Below is example genarated-output of the Urdu ("ur") locale-font. * * ```css * &#64;font-face { * font-family: 'Custom Font ur'; * font-weight: 500; * src: local('CustomFont_Urdu'); * unicode-range: U+0600-U+06FF, U+FE70-U+FEFE, U+FB50-U+FDFF; * } * &#64;font-face { * font-family: 'Custom Font ur Bold'; * font-weight: 700; * src: local('CustomFont_Urdu'); * unicode-range: U+0600-U+06FF, U+FE70-U+FEFE, U+FB50-U+FDFF; * } * &#64;font-face { * font-family: 'Custom Font ur Light'; * font-weight: 300; * src: local('CustomFont_Urdu'); * unicode-range: U+0600-U+06FF, U+FE70-U+FEFE, U+FB50-U+FDFF; * } * ``` * * @param {String} locale Locale string in the format * @returns {String} An HTML fragment of the `<style>` when prerendering * * @public */ function generateFontRules(locale) { if (!locale || locale === currentLocale) { return; } currentLocale = locale; return fontGenerator(locale); } function generateFontOverrideRules(locale) { if (!locale) { return; } return fontOverrideGenerator(locale); } /** * Adds a localed font to the font map * * ``` * addLocalizedFont('My Theme Font', { * 'ur': { * regular: 'My Theme Urdu', * unicodeRange: * 'U+600-6FF,' + * 'U+FE70-FEFE,' + * 'U+FB50-FDFF' * } * }) * ``` * * @param {String} name Name of the font * @param {Object} fonts Object mapping font names and unicode ranges to locales * * @public */ function addLocalizedFont(name, fonts) { fontMap[name] = fonts; if (currentLocale) { fontGenerator(currentLocale); } } /** * Removes a localized font from the font map * * @param {String} name Name of the font * * @public */ function removeLocalizedFont(name) { delete fontMap[name]; if (currentLocale) { fontGenerator(currentLocale); } } module.exports = generateFontRules; module.exports.generateFontRules = generateFontRules; module.exports.generateFontOverrideRules = generateFontOverrideRules; module.exports.addLocalizedFont = addLocalizedFont; module.exports.removeLocalizedFont = removeLocalizedFont;