UNPKG

@localazy/strapi-plugin

Version:

The official Strapi Plugin by Localazy.

433 lines (432 loc) 16.2 kB
import { createElement, isValidElement, cloneElement, Children, Fragment, useContext } from "react"; import { g as getDefaultExportFromCjs } from "./_commonjsHelpers-DWwsNxpa.mjs"; import { w as warnOnce, i as isString, a as warn, b as isObject, I as I18nContext } from "./useTranslation-CZQ4lU1m.mjs"; import { u } from "./useTranslation-CZQ4lU1m.mjs"; import { g as getI18n, a as getDefaults } from "./initReactI18next-MHHxeg_9.mjs"; import { i, s, b } from "./initReactI18next-MHHxeg_9.mjs"; var voidElements = { "area": true, "base": true, "br": true, "col": true, "embed": true, "hr": true, "img": true, "input": true, "link": true, "meta": true, "param": true, "source": true, "track": true, "wbr": true }; const e = /* @__PURE__ */ getDefaultExportFromCjs(voidElements); var t = /\s([^'"/\s><]+?)[\s/>]|([^\s=]+)=\s?(".*?"|'.*?')/g; function n(n2) { var r2 = { type: "tag", name: "", voidElement: false, attrs: {}, children: [] }, i3 = n2.match(/<\/?([^\s]+?)[/\s>]/); if (i3 && (r2.name = i3[1], (e[i3[1]] || "/" === n2.charAt(n2.length - 2)) && (r2.voidElement = true), r2.name.startsWith("!--"))) { var s3 = n2.indexOf("-->"); return { type: "comment", comment: -1 !== s3 ? n2.slice(4, s3) : "" }; } for (var a2 = new RegExp(t), c2 = null; null !== (c2 = a2.exec(n2)); ) if (c2[0].trim()) if (c2[1]) { var o = c2[1].trim(), l = [o, ""]; o.indexOf("=") > -1 && (l = o.split("=")), r2.attrs[l[0]] = l[1], a2.lastIndex--; } else c2[2] && (r2.attrs[c2[2]] = c2[3].trim().substring(1, c2[3].length - 1)); return r2; } var r = /<[a-zA-Z0-9\-\!\/](?:"[^"]*"|'[^']*'|[^'">])*>/g, i2 = /^\s*$/, s2 = /* @__PURE__ */ Object.create(null); function a(e2, t2) { switch (t2.type) { case "text": return e2 + t2.content; case "tag": return e2 += "<" + t2.name + (t2.attrs ? function(e3) { var t3 = []; for (var n2 in e3) t3.push(n2 + '="' + e3[n2] + '"'); return t3.length ? " " + t3.join(" ") : ""; }(t2.attrs) : "") + (t2.voidElement ? "/>" : ">"), t2.voidElement ? e2 : e2 + t2.children.reduce(a, "") + "</" + t2.name + ">"; case "comment": return e2 + "<!--" + t2.comment + "-->"; } } var c = { parse: function(e2, t2) { t2 || (t2 = {}), t2.components || (t2.components = s2); var a2, c2 = [], o = [], l = -1, m = false; if (0 !== e2.indexOf("<")) { var u2 = e2.indexOf("<"); c2.push({ type: "text", content: -1 === u2 ? e2 : e2.substring(0, u2) }); } return e2.replace(r, function(r2, s3) { if (m) { if (r2 !== "</" + a2.name + ">") return; m = false; } var u3, f = "/" !== r2.charAt(1), h = r2.startsWith("<!--"), p = s3 + r2.length, d = e2.charAt(p); if (h) { var v = n(r2); return l < 0 ? (c2.push(v), c2) : ((u3 = o[l]).children.push(v), c2); } if (f && (l++, "tag" === (a2 = n(r2)).type && t2.components[a2.name] && (a2.type = "component", m = true), a2.voidElement || m || !d || "<" === d || a2.children.push({ type: "text", content: e2.slice(p, e2.indexOf("<", p)) }), 0 === l && c2.push(a2), (u3 = o[l - 1]) && u3.children.push(a2), o[l] = a2), (!f || a2.voidElement) && (l > -1 && (a2.voidElement || a2.name === r2.slice(2, -1)) && (l--, a2 = -1 === l ? c2 : o[l]), !m && "<" !== d && d)) { u3 = -1 === l ? c2 : o[l].children; var x = e2.indexOf("<", p), g = e2.slice(p, -1 === x ? void 0 : x); i2.test(g) && (g = " "), (x > -1 && l + u3.length >= 0 || " " !== g) && u3.push({ type: "text", content: g }); } }), c2; }, stringify: function(e2) { return e2.reduce(function(e3, t2) { return e3 + a("", t2); }, ""); } }; const hasChildren = (node, checkLength) => { if (!node) return false; const base = node.props?.children ?? node.children; if (checkLength) return base.length > 0; return !!base; }; const getChildren = (node) => { if (!node) return []; const children = node.props?.children ?? node.children; return node.props?.i18nIsDynamicList ? getAsArray(children) : children; }; const hasValidReactChildren = (children) => Array.isArray(children) && children.every(isValidElement); const getAsArray = (data) => Array.isArray(data) ? data : [data]; const mergeProps = (source, target) => { const newTarget = { ...target }; newTarget.props = Object.assign(source.props, target.props); return newTarget; }; const nodesToString = (children, i18nOptions, i18n, i18nKey) => { if (!children) return ""; let stringNode = ""; const childrenArray = getAsArray(children); const keepArray = i18nOptions?.transSupportBasicHtmlNodes ? i18nOptions.transKeepBasicHtmlNodesFor ?? [] : []; childrenArray.forEach((child, childIndex) => { if (isString(child)) { stringNode += `${child}`; return; } if (isValidElement(child)) { const { props, type } = child; const childPropsCount = Object.keys(props).length; const shouldKeepChild = keepArray.indexOf(type) > -1; const childChildren = props.children; if (!childChildren && shouldKeepChild && !childPropsCount) { stringNode += `<${type}/>`; return; } if (!childChildren && (!shouldKeepChild || childPropsCount) || props.i18nIsDynamicList) { stringNode += `<${childIndex}></${childIndex}>`; return; } if (shouldKeepChild && childPropsCount === 1 && isString(childChildren)) { stringNode += `<${type}>${childChildren}</${type}>`; return; } const content = nodesToString(childChildren, i18nOptions, i18n, i18nKey); stringNode += `<${childIndex}>${content}</${childIndex}>`; return; } if (child === null) { warn(i18n, "TRANS_NULL_VALUE", `Passed in a null value as child`, { i18nKey }); return; } if (isObject(child)) { const { format, ...clone } = child; const keys = Object.keys(clone); if (keys.length === 1) { const value = format ? `${keys[0]}, ${format}` : keys[0]; stringNode += `{{${value}}}`; return; } warn(i18n, "TRANS_INVALID_OBJ", `Invalid child - Object should only have keys {{ value, format }} (format is optional).`, { i18nKey, child }); return; } warn(i18n, "TRANS_INVALID_VAR", `Passed in a variable like {number} - pass variables for interpolation as full objects like {{number}}.`, { i18nKey, child }); }); return stringNode; }; const renderNodes = (children, targetString, i18n, i18nOptions, combinedTOpts, shouldUnescape) => { if (targetString === "") return []; const keepArray = i18nOptions.transKeepBasicHtmlNodesFor || []; const emptyChildrenButNeedsHandling = targetString && new RegExp(keepArray.map((keep) => `<${keep}`).join("|")).test(targetString); if (!children && !emptyChildrenButNeedsHandling && !shouldUnescape) return [targetString]; const data = {}; const getData = (childs) => { const childrenArray = getAsArray(childs); childrenArray.forEach((child) => { if (isString(child)) return; if (hasChildren(child)) getData(getChildren(child)); else if (isObject(child) && !isValidElement(child)) Object.assign(data, child); }); }; getData(children); const ast = c.parse(`<0>${targetString}</0>`); const opts = { ...data, ...combinedTOpts }; const renderInner = (child, node, rootReactNode) => { const childs = getChildren(child); const mappedChildren = mapAST(childs, node.children, rootReactNode); return hasValidReactChildren(childs) && mappedChildren.length === 0 || child.props?.i18nIsDynamicList ? childs : mappedChildren; }; const pushTranslatedJSX = (child, inner, mem, i3, isVoid) => { if (child.dummy) { child.children = inner; mem.push(cloneElement(child, { key: i3 }, isVoid ? void 0 : inner)); } else { mem.push(...Children.map([child], (c2) => { const props = { ...c2.props }; delete props.i18nIsDynamicList; return createElement(c2.type, { ...props, key: i3, ref: c2.ref }, isVoid ? null : inner); })); } }; const mapAST = (reactNode, astNode, rootReactNode) => { const reactNodes = getAsArray(reactNode); const astNodes = getAsArray(astNode); return astNodes.reduce((mem, node, i3) => { const translationContent = node.children?.[0]?.content && i18n.services.interpolator.interpolate(node.children[0].content, opts, i18n.language); if (node.type === "tag") { let tmp = reactNodes[parseInt(node.name, 10)]; if (rootReactNode.length === 1 && !tmp) tmp = rootReactNode[0][node.name]; if (!tmp) tmp = {}; const child = Object.keys(node.attrs).length !== 0 ? mergeProps({ props: node.attrs }, tmp) : tmp; const isElement = isValidElement(child); const isValidTranslationWithChildren = isElement && hasChildren(node, true) && !node.voidElement; const isEmptyTransWithHTML = emptyChildrenButNeedsHandling && isObject(child) && child.dummy && !isElement; const isKnownComponent = isObject(children) && Object.hasOwnProperty.call(children, node.name); if (isString(child)) { const value = i18n.services.interpolator.interpolate(child, opts, i18n.language); mem.push(value); } else if (hasChildren(child) || isValidTranslationWithChildren) { const inner = renderInner(child, node, rootReactNode); pushTranslatedJSX(child, inner, mem, i3); } else if (isEmptyTransWithHTML) { const inner = mapAST(reactNodes, node.children, rootReactNode); pushTranslatedJSX(child, inner, mem, i3); } else if (Number.isNaN(parseFloat(node.name))) { if (isKnownComponent) { const inner = renderInner(child, node, rootReactNode); pushTranslatedJSX(child, inner, mem, i3, node.voidElement); } else if (i18nOptions.transSupportBasicHtmlNodes && keepArray.indexOf(node.name) > -1) { if (node.voidElement) { mem.push(createElement(node.name, { key: `${node.name}-${i3}` })); } else { const inner = mapAST(reactNodes, node.children, rootReactNode); mem.push(createElement(node.name, { key: `${node.name}-${i3}` }, inner)); } } else if (node.voidElement) { mem.push(`<${node.name} />`); } else { const inner = mapAST(reactNodes, node.children, rootReactNode); mem.push(`<${node.name}>${inner}</${node.name}>`); } } else if (isObject(child) && !isElement) { const content = node.children[0] ? translationContent : null; if (content) mem.push(content); } else { pushTranslatedJSX(child, translationContent, mem, i3, node.children.length !== 1 || !translationContent); } } else if (node.type === "text") { const wrapTextNodes = i18nOptions.transWrapTextNodes; const content = shouldUnescape ? i18nOptions.unescape(i18n.services.interpolator.interpolate(node.content, opts, i18n.language)) : i18n.services.interpolator.interpolate(node.content, opts, i18n.language); if (wrapTextNodes) { mem.push(createElement(wrapTextNodes, { key: `${node.name}-${i3}` }, content)); } else { mem.push(content); } } return mem; }, []); }; const result = mapAST([{ dummy: true, children: children || [] }], ast, getAsArray(children || [])); return getChildren(result[0]); }; const fixComponentProps = (component, index, translation) => { const componentKey = component.key || index; const comp = cloneElement(component, { key: componentKey }); if (!comp.props || !comp.props.children || translation.indexOf(`${index}/>`) < 0 && translation.indexOf(`${index} />`) < 0) { return comp; } function Componentized() { return createElement(Fragment, null, comp); } return createElement(Componentized); }; const generateArrayComponents = (components, translation) => components.map((c2, index) => fixComponentProps(c2, index, translation)); const generateObjectComponents = (components, translation) => { const componentMap = {}; Object.keys(components).forEach((c2) => { Object.assign(componentMap, { [c2]: fixComponentProps(components[c2], c2, translation) }); }); return componentMap; }; const generateComponents = (components, translation, i18n, i18nKey) => { if (!components) return null; if (Array.isArray(components)) { return generateArrayComponents(components, translation); } if (isObject(components)) { return generateObjectComponents(components, translation); } warnOnce(i18n, "TRANS_INVALID_COMPONENTS", `<Trans /> "components" prop expects an object or array`, { i18nKey }); return null; }; function Trans$1({ children, count, parent, i18nKey, context, tOptions = {}, values, defaults, components, ns, i18n: i18nFromProps, t: tFromProps, shouldUnescape, ...additionalProps }) { const i18n = i18nFromProps || getI18n(); if (!i18n) { warnOnce(i18n, "NO_I18NEXT_INSTANCE", `Trans: You need to pass in an i18next instance using i18nextReactModule`, { i18nKey }); return children; } const t2 = tFromProps || i18n.t.bind(i18n) || ((k) => k); const reactI18nextOptions = { ...getDefaults(), ...i18n.options?.react }; let namespaces = ns || t2.ns || i18n.options?.defaultNS; namespaces = isString(namespaces) ? [namespaces] : namespaces || ["translation"]; const nodeAsString = nodesToString(children, reactI18nextOptions, i18n, i18nKey); const defaultValue = defaults || nodeAsString || reactI18nextOptions.transEmptyNodeValue || i18nKey; const { hashTransKey } = reactI18nextOptions; const key = i18nKey || (hashTransKey ? hashTransKey(nodeAsString || defaultValue) : nodeAsString || defaultValue); if (i18n.options?.interpolation?.defaultVariables) { values = values && Object.keys(values).length > 0 ? { ...values, ...i18n.options.interpolation.defaultVariables } : { ...i18n.options.interpolation.defaultVariables }; } const interpolationOverride = values || count !== void 0 && !i18n.options?.interpolation?.alwaysFormat || !children ? tOptions.interpolation : { interpolation: { ...tOptions.interpolation, prefix: "#$?", suffix: "?$#" } }; const combinedTOpts = { ...tOptions, context: context || tOptions.context, count, ...values, ...interpolationOverride, defaultValue, ns: namespaces }; const translation = key ? t2(key, combinedTOpts) : defaultValue; const generatedComponents = generateComponents(components, translation, i18n, i18nKey); const content = renderNodes(generatedComponents || children, translation, i18n, reactI18nextOptions, combinedTOpts, shouldUnescape); const useAsParent = parent ?? reactI18nextOptions.defaultTransParent; return useAsParent ? createElement(useAsParent, additionalProps, content) : content; } function Trans({ children, count, parent, i18nKey, context, tOptions = {}, values, defaults, components, ns, i18n: i18nFromProps, t: tFromProps, shouldUnescape, ...additionalProps }) { const { i18n: i18nFromContext, defaultNS: defaultNSFromContext } = useContext(I18nContext) || {}; const i18n = i18nFromProps || i18nFromContext || getI18n(); const t2 = tFromProps || i18n?.t.bind(i18n); return Trans$1({ children, count, parent, i18nKey, context, tOptions, values, defaults, components, ns: ns || t2?.ns || defaultNSFromContext || i18n?.options?.defaultNS, i18n, t: tFromProps, shouldUnescape, ...additionalProps }); } export { I18nContext, Trans, Trans$1 as TransWithoutContext, getDefaults, getI18n, i as initReactI18next, s as setDefaults, b as setI18n, u as useTranslation };