lingo.dev 0.125.2 → 0.125.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cli.cjs +288 -360
- package/build/cli.cjs.map +1 -1
- package/build/cli.mjs +289 -361
- package/build/cli.mjs.map +1 -1
- package/package.json +4 -4
package/build/cli.mjs
CHANGED
|
@@ -3639,8 +3639,8 @@ function serializeElement(node) {
|
|
|
3639
3639
|
const attrString = Object.entries(attributes).map(([key, value]) => ` ${key}="${escapeAttributeValue(String(value))}"`).join("");
|
|
3640
3640
|
const children = Array.isArray(node.$$) ? node.$$ : [];
|
|
3641
3641
|
if (children.length === 0) {
|
|
3642
|
-
const
|
|
3643
|
-
return `<${name}${attrString}>${
|
|
3642
|
+
const textContent2 = node._ ?? "";
|
|
3643
|
+
return `<${name}${attrString}>${textContent2}</${name}>`;
|
|
3644
3644
|
}
|
|
3645
3645
|
const childContent = children.map(serializeElement).join("");
|
|
3646
3646
|
return `<${name}${attrString}>${childContent}</${name}>`;
|
|
@@ -3731,119 +3731,241 @@ function createPullOutputCleaner() {
|
|
|
3731
3731
|
// src/cli/loaders/html.ts
|
|
3732
3732
|
import * as htmlparser2 from "htmlparser2";
|
|
3733
3733
|
import { DomHandler } from "domhandler";
|
|
3734
|
-
import * as
|
|
3734
|
+
import * as domutils2 from "domutils";
|
|
3735
3735
|
import * as DomSerializer from "dom-serializer";
|
|
3736
|
+
|
|
3737
|
+
// src/cli/utils/element-extraction.ts
|
|
3738
|
+
import * as domutils from "domutils";
|
|
3739
|
+
var SVG_TRANSLATABLE_TAGS = /* @__PURE__ */ new Set([
|
|
3740
|
+
"title",
|
|
3741
|
+
"text",
|
|
3742
|
+
"desc"
|
|
3743
|
+
]);
|
|
3744
|
+
var PHRASING_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3745
|
+
// Text-level semantics
|
|
3746
|
+
"a",
|
|
3747
|
+
"abbr",
|
|
3748
|
+
"b",
|
|
3749
|
+
"bdi",
|
|
3750
|
+
"bdo",
|
|
3751
|
+
"br",
|
|
3752
|
+
"cite",
|
|
3753
|
+
"code",
|
|
3754
|
+
"data",
|
|
3755
|
+
"dfn",
|
|
3756
|
+
"em",
|
|
3757
|
+
"i",
|
|
3758
|
+
"kbd",
|
|
3759
|
+
"mark",
|
|
3760
|
+
"q",
|
|
3761
|
+
"ruby",
|
|
3762
|
+
"s",
|
|
3763
|
+
"samp",
|
|
3764
|
+
"small",
|
|
3765
|
+
"span",
|
|
3766
|
+
"strong",
|
|
3767
|
+
"sub",
|
|
3768
|
+
"sup",
|
|
3769
|
+
"time",
|
|
3770
|
+
"u",
|
|
3771
|
+
"var",
|
|
3772
|
+
"wbr",
|
|
3773
|
+
// Media
|
|
3774
|
+
"audio",
|
|
3775
|
+
"img",
|
|
3776
|
+
"video",
|
|
3777
|
+
"picture",
|
|
3778
|
+
// Interactive
|
|
3779
|
+
"button",
|
|
3780
|
+
"input",
|
|
3781
|
+
"label",
|
|
3782
|
+
"select",
|
|
3783
|
+
"textarea",
|
|
3784
|
+
// Embedded
|
|
3785
|
+
"canvas",
|
|
3786
|
+
"iframe",
|
|
3787
|
+
"object",
|
|
3788
|
+
"svg",
|
|
3789
|
+
"math",
|
|
3790
|
+
// Other
|
|
3791
|
+
"del",
|
|
3792
|
+
"ins",
|
|
3793
|
+
"map",
|
|
3794
|
+
"area"
|
|
3795
|
+
]);
|
|
3796
|
+
var BLOCK_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3797
|
+
"div",
|
|
3798
|
+
"p",
|
|
3799
|
+
"h1",
|
|
3800
|
+
"h2",
|
|
3801
|
+
"h3",
|
|
3802
|
+
"h4",
|
|
3803
|
+
"h5",
|
|
3804
|
+
"h6",
|
|
3805
|
+
"ul",
|
|
3806
|
+
"ol",
|
|
3807
|
+
"li",
|
|
3808
|
+
"dl",
|
|
3809
|
+
"dt",
|
|
3810
|
+
"dd",
|
|
3811
|
+
"blockquote",
|
|
3812
|
+
"pre",
|
|
3813
|
+
"article",
|
|
3814
|
+
"aside",
|
|
3815
|
+
"nav",
|
|
3816
|
+
"section",
|
|
3817
|
+
"header",
|
|
3818
|
+
"footer",
|
|
3819
|
+
"main",
|
|
3820
|
+
"figure",
|
|
3821
|
+
"figcaption",
|
|
3822
|
+
"table",
|
|
3823
|
+
"thead",
|
|
3824
|
+
"tbody",
|
|
3825
|
+
"tfoot",
|
|
3826
|
+
"tr",
|
|
3827
|
+
"td",
|
|
3828
|
+
"th",
|
|
3829
|
+
"caption",
|
|
3830
|
+
"form",
|
|
3831
|
+
"fieldset",
|
|
3832
|
+
"legend",
|
|
3833
|
+
"details",
|
|
3834
|
+
"summary",
|
|
3835
|
+
"address",
|
|
3836
|
+
"hr",
|
|
3837
|
+
"search",
|
|
3838
|
+
"dialog",
|
|
3839
|
+
"noscript",
|
|
3840
|
+
"title"
|
|
3841
|
+
]);
|
|
3842
|
+
var UNLOCALIZABLE_TAGS = /* @__PURE__ */ new Set([
|
|
3843
|
+
"script",
|
|
3844
|
+
"style"
|
|
3845
|
+
]);
|
|
3846
|
+
var BASE_LOCALIZABLE_ATTRIBUTES = {
|
|
3847
|
+
meta: ["content"],
|
|
3848
|
+
img: ["alt", "title"],
|
|
3849
|
+
input: ["placeholder", "title"],
|
|
3850
|
+
textarea: ["placeholder", "title"],
|
|
3851
|
+
a: ["title"],
|
|
3852
|
+
abbr: ["title"],
|
|
3853
|
+
button: ["title"],
|
|
3854
|
+
link: ["title"]
|
|
3855
|
+
};
|
|
3856
|
+
function isInsideUnlocalizableTag(element, unlocalizableTags = UNLOCALIZABLE_TAGS) {
|
|
3857
|
+
let current = element.parent;
|
|
3858
|
+
while (current && current.type === "tag") {
|
|
3859
|
+
if (unlocalizableTags.has(current.name.toLowerCase())) {
|
|
3860
|
+
return true;
|
|
3861
|
+
}
|
|
3862
|
+
current = current.parent;
|
|
3863
|
+
}
|
|
3864
|
+
return false;
|
|
3865
|
+
}
|
|
3866
|
+
function hasTranslatableContent(element) {
|
|
3867
|
+
const text = domutils.textContent(element);
|
|
3868
|
+
return text.trim().length > 0;
|
|
3869
|
+
}
|
|
3870
|
+
function isLeafBlock(element, blockElements = BLOCK_ELEMENTS) {
|
|
3871
|
+
const childElements = element.children.filter(
|
|
3872
|
+
(child) => child.type === "tag"
|
|
3873
|
+
);
|
|
3874
|
+
for (const child of childElements) {
|
|
3875
|
+
if (blockElements.has(child.name.toLowerCase())) {
|
|
3876
|
+
return false;
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
return hasTranslatableContent(element);
|
|
3880
|
+
}
|
|
3881
|
+
function isInsideSvg(element) {
|
|
3882
|
+
let current = element.parent;
|
|
3883
|
+
while (current && current.type === "tag") {
|
|
3884
|
+
if (current.name.toLowerCase() === "svg") {
|
|
3885
|
+
return true;
|
|
3886
|
+
}
|
|
3887
|
+
current = current.parent;
|
|
3888
|
+
}
|
|
3889
|
+
return false;
|
|
3890
|
+
}
|
|
3891
|
+
function containsSvgDescendant(element) {
|
|
3892
|
+
const childElements = element.children.filter(
|
|
3893
|
+
(child) => child.type === "tag"
|
|
3894
|
+
);
|
|
3895
|
+
for (const child of childElements) {
|
|
3896
|
+
if (child.name.toLowerCase() === "svg") {
|
|
3897
|
+
return true;
|
|
3898
|
+
}
|
|
3899
|
+
if (containsSvgDescendant(child)) {
|
|
3900
|
+
return true;
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
return false;
|
|
3904
|
+
}
|
|
3905
|
+
function getSvgExtractionStrategy(element) {
|
|
3906
|
+
const tagName = element.name.toLowerCase();
|
|
3907
|
+
if (tagName === "svg") {
|
|
3908
|
+
return "skip-recurse";
|
|
3909
|
+
}
|
|
3910
|
+
const inSvg = isInsideSvg(element);
|
|
3911
|
+
if (!inSvg) {
|
|
3912
|
+
return "process-normal";
|
|
3913
|
+
}
|
|
3914
|
+
return SVG_TRANSLATABLE_TAGS.has(tagName) ? "extract" : "skip-recurse";
|
|
3915
|
+
}
|
|
3916
|
+
function createElementExtractor(context, result) {
|
|
3917
|
+
function extractFromElement(element, pathParts) {
|
|
3918
|
+
const path20 = pathParts.join("/");
|
|
3919
|
+
const tagName = element.name.toLowerCase();
|
|
3920
|
+
if (isInsideUnlocalizableTag(element)) {
|
|
3921
|
+
return;
|
|
3922
|
+
}
|
|
3923
|
+
context.extractAttributes(element, path20);
|
|
3924
|
+
const svgStrategy = getSvgExtractionStrategy(element);
|
|
3925
|
+
if (svgStrategy === "extract") {
|
|
3926
|
+
const content = context.getInnerHTML(element).trim();
|
|
3927
|
+
if (content) {
|
|
3928
|
+
result[path20] = content;
|
|
3929
|
+
}
|
|
3930
|
+
return;
|
|
3931
|
+
}
|
|
3932
|
+
if (svgStrategy === "skip-recurse") {
|
|
3933
|
+
let childIndex2 = 0;
|
|
3934
|
+
const childElements2 = element.children.filter(
|
|
3935
|
+
(child) => child.type === "tag"
|
|
3936
|
+
);
|
|
3937
|
+
for (const child of childElements2) {
|
|
3938
|
+
extractFromElement(child, [...pathParts, childIndex2++]);
|
|
3939
|
+
}
|
|
3940
|
+
return;
|
|
3941
|
+
}
|
|
3942
|
+
if (BLOCK_ELEMENTS.has(tagName) && isLeafBlock(element) && !containsSvgDescendant(element)) {
|
|
3943
|
+
const content = context.getInnerHTML(element).trim();
|
|
3944
|
+
if (content) {
|
|
3945
|
+
result[path20] = content;
|
|
3946
|
+
}
|
|
3947
|
+
return;
|
|
3948
|
+
}
|
|
3949
|
+
if (PHRASING_ELEMENTS.has(tagName) && hasTranslatableContent(element) && !containsSvgDescendant(element)) {
|
|
3950
|
+
const content = context.getInnerHTML(element).trim();
|
|
3951
|
+
if (content) {
|
|
3952
|
+
result[path20] = content;
|
|
3953
|
+
}
|
|
3954
|
+
return;
|
|
3955
|
+
}
|
|
3956
|
+
let childIndex = 0;
|
|
3957
|
+
const childElements = element.children.filter(
|
|
3958
|
+
(child) => child.type === "tag"
|
|
3959
|
+
);
|
|
3960
|
+
for (const child of childElements) {
|
|
3961
|
+
extractFromElement(child, [...pathParts, childIndex++]);
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
return extractFromElement;
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3967
|
+
// src/cli/loaders/html.ts
|
|
3736
3968
|
function createHtmlLoader() {
|
|
3737
|
-
const PHRASING_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3738
|
-
// Text-level semantics
|
|
3739
|
-
"a",
|
|
3740
|
-
"abbr",
|
|
3741
|
-
"b",
|
|
3742
|
-
"bdi",
|
|
3743
|
-
"bdo",
|
|
3744
|
-
"br",
|
|
3745
|
-
"cite",
|
|
3746
|
-
"code",
|
|
3747
|
-
"data",
|
|
3748
|
-
"dfn",
|
|
3749
|
-
"em",
|
|
3750
|
-
"i",
|
|
3751
|
-
"kbd",
|
|
3752
|
-
"mark",
|
|
3753
|
-
"q",
|
|
3754
|
-
"ruby",
|
|
3755
|
-
"s",
|
|
3756
|
-
"samp",
|
|
3757
|
-
"small",
|
|
3758
|
-
"span",
|
|
3759
|
-
"strong",
|
|
3760
|
-
"sub",
|
|
3761
|
-
"sup",
|
|
3762
|
-
"time",
|
|
3763
|
-
"u",
|
|
3764
|
-
"var",
|
|
3765
|
-
"wbr",
|
|
3766
|
-
// Media
|
|
3767
|
-
"audio",
|
|
3768
|
-
"img",
|
|
3769
|
-
"video",
|
|
3770
|
-
"picture",
|
|
3771
|
-
// Interactive
|
|
3772
|
-
"button",
|
|
3773
|
-
"input",
|
|
3774
|
-
"label",
|
|
3775
|
-
"select",
|
|
3776
|
-
"textarea",
|
|
3777
|
-
// Embedded
|
|
3778
|
-
"canvas",
|
|
3779
|
-
"iframe",
|
|
3780
|
-
"object",
|
|
3781
|
-
"svg",
|
|
3782
|
-
"math",
|
|
3783
|
-
// Other
|
|
3784
|
-
"del",
|
|
3785
|
-
"ins",
|
|
3786
|
-
"map",
|
|
3787
|
-
"area"
|
|
3788
|
-
]);
|
|
3789
|
-
const BLOCK_ELEMENTS = /* @__PURE__ */ new Set([
|
|
3790
|
-
"div",
|
|
3791
|
-
"p",
|
|
3792
|
-
"h1",
|
|
3793
|
-
"h2",
|
|
3794
|
-
"h3",
|
|
3795
|
-
"h4",
|
|
3796
|
-
"h5",
|
|
3797
|
-
"h6",
|
|
3798
|
-
"ul",
|
|
3799
|
-
"ol",
|
|
3800
|
-
"li",
|
|
3801
|
-
"dl",
|
|
3802
|
-
"dt",
|
|
3803
|
-
"dd",
|
|
3804
|
-
"blockquote",
|
|
3805
|
-
"pre",
|
|
3806
|
-
"article",
|
|
3807
|
-
"aside",
|
|
3808
|
-
"nav",
|
|
3809
|
-
"section",
|
|
3810
|
-
"header",
|
|
3811
|
-
"footer",
|
|
3812
|
-
"main",
|
|
3813
|
-
"figure",
|
|
3814
|
-
"figcaption",
|
|
3815
|
-
"table",
|
|
3816
|
-
"thead",
|
|
3817
|
-
"tbody",
|
|
3818
|
-
"tfoot",
|
|
3819
|
-
"tr",
|
|
3820
|
-
"td",
|
|
3821
|
-
"th",
|
|
3822
|
-
"caption",
|
|
3823
|
-
"form",
|
|
3824
|
-
"fieldset",
|
|
3825
|
-
"legend",
|
|
3826
|
-
"details",
|
|
3827
|
-
"summary",
|
|
3828
|
-
"address",
|
|
3829
|
-
"hr",
|
|
3830
|
-
"search",
|
|
3831
|
-
"dialog",
|
|
3832
|
-
"noscript",
|
|
3833
|
-
"title"
|
|
3834
|
-
// <title> should be treated as a block element for translation
|
|
3835
|
-
]);
|
|
3836
|
-
const UNLOCALIZABLE_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
|
|
3837
|
-
const LOCALIZABLE_ATTRIBUTES2 = {
|
|
3838
|
-
meta: ["content"],
|
|
3839
|
-
img: ["alt", "title"],
|
|
3840
|
-
input: ["placeholder", "title"],
|
|
3841
|
-
textarea: ["placeholder", "title"],
|
|
3842
|
-
a: ["title"],
|
|
3843
|
-
abbr: ["title"],
|
|
3844
|
-
button: ["title"],
|
|
3845
|
-
link: ["title"]
|
|
3846
|
-
};
|
|
3847
3969
|
return createLoader({
|
|
3848
3970
|
async pull(locale, input2) {
|
|
3849
3971
|
const result = {};
|
|
@@ -3855,37 +3977,14 @@ function createHtmlLoader() {
|
|
|
3855
3977
|
parser.write(input2);
|
|
3856
3978
|
parser.end();
|
|
3857
3979
|
const dom = handler.dom;
|
|
3858
|
-
function isInsideUnlocalizableTag(element) {
|
|
3859
|
-
let current = element.parent;
|
|
3860
|
-
while (current && current.type === "tag") {
|
|
3861
|
-
if (UNLOCALIZABLE_TAGS.has(current.name.toLowerCase())) {
|
|
3862
|
-
return true;
|
|
3863
|
-
}
|
|
3864
|
-
current = current.parent;
|
|
3865
|
-
}
|
|
3866
|
-
return false;
|
|
3867
|
-
}
|
|
3868
|
-
function hasTranslatableContent(element) {
|
|
3869
|
-
const text = domutils.textContent(element);
|
|
3870
|
-
return text.trim().length > 0;
|
|
3871
|
-
}
|
|
3872
|
-
function isLeafBlock(element) {
|
|
3873
|
-
const childElements = element.children.filter(
|
|
3874
|
-
(child) => child.type === "tag"
|
|
3875
|
-
);
|
|
3876
|
-
for (const child of childElements) {
|
|
3877
|
-
if (BLOCK_ELEMENTS.has(child.name.toLowerCase())) {
|
|
3878
|
-
return false;
|
|
3879
|
-
}
|
|
3880
|
-
}
|
|
3881
|
-
return hasTranslatableContent(element);
|
|
3882
|
-
}
|
|
3883
3980
|
function getInnerHTML2(element) {
|
|
3884
|
-
return element.children.map(
|
|
3981
|
+
return element.children.map(
|
|
3982
|
+
(child) => DomSerializer.default(child, { encodeEntities: false })
|
|
3983
|
+
).join("");
|
|
3885
3984
|
}
|
|
3886
3985
|
function extractAttributes(element, path20) {
|
|
3887
3986
|
const tagName = element.name.toLowerCase();
|
|
3888
|
-
const attrs =
|
|
3987
|
+
const attrs = BASE_LOCALIZABLE_ATTRIBUTES[tagName];
|
|
3889
3988
|
if (!attrs) return;
|
|
3890
3989
|
for (const attr of attrs) {
|
|
3891
3990
|
const value = element.attribs?.[attr];
|
|
@@ -3894,47 +3993,22 @@ function createHtmlLoader() {
|
|
|
3894
3993
|
}
|
|
3895
3994
|
}
|
|
3896
3995
|
}
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
extractAttributes(element, path20);
|
|
3903
|
-
const tagName = element.name.toLowerCase();
|
|
3904
|
-
if (BLOCK_ELEMENTS.has(tagName) && isLeafBlock(element)) {
|
|
3905
|
-
const content = getInnerHTML2(element).trim();
|
|
3906
|
-
if (content) {
|
|
3907
|
-
result[path20] = content;
|
|
3908
|
-
}
|
|
3909
|
-
return;
|
|
3910
|
-
}
|
|
3911
|
-
if (PHRASING_ELEMENTS.has(tagName) && hasTranslatableContent(element)) {
|
|
3912
|
-
const content = getInnerHTML2(element).trim();
|
|
3913
|
-
if (content) {
|
|
3914
|
-
result[path20] = content;
|
|
3915
|
-
}
|
|
3916
|
-
return;
|
|
3917
|
-
}
|
|
3918
|
-
let childIndex = 0;
|
|
3919
|
-
const childElements = element.children.filter(
|
|
3920
|
-
(child) => child.type === "tag"
|
|
3921
|
-
);
|
|
3922
|
-
for (const child of childElements) {
|
|
3923
|
-
extractFromElement(child, [...pathParts, childIndex++]);
|
|
3924
|
-
}
|
|
3925
|
-
}
|
|
3926
|
-
const html = domutils.findOne(
|
|
3996
|
+
const extractFromElement = createElementExtractor(
|
|
3997
|
+
{ getInnerHTML: getInnerHTML2, extractAttributes },
|
|
3998
|
+
result
|
|
3999
|
+
);
|
|
4000
|
+
const html = domutils2.findOne(
|
|
3927
4001
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "html",
|
|
3928
4002
|
dom,
|
|
3929
4003
|
true
|
|
3930
4004
|
);
|
|
3931
4005
|
if (html) {
|
|
3932
|
-
const head =
|
|
4006
|
+
const head = domutils2.findOne(
|
|
3933
4007
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "head",
|
|
3934
4008
|
html.children,
|
|
3935
4009
|
true
|
|
3936
4010
|
);
|
|
3937
|
-
const body =
|
|
4011
|
+
const body = domutils2.findOne(
|
|
3938
4012
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "body",
|
|
3939
4013
|
html.children,
|
|
3940
4014
|
true
|
|
@@ -3979,7 +4053,7 @@ function createHtmlLoader() {
|
|
|
3979
4053
|
);
|
|
3980
4054
|
parser.end();
|
|
3981
4055
|
const dom = handler.dom;
|
|
3982
|
-
const html =
|
|
4056
|
+
const html = domutils2.findOne(
|
|
3983
4057
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "html",
|
|
3984
4058
|
dom,
|
|
3985
4059
|
true
|
|
@@ -4009,13 +4083,13 @@ function createHtmlLoader() {
|
|
|
4009
4083
|
let current = null;
|
|
4010
4084
|
if (html) {
|
|
4011
4085
|
if (rootTag === "head") {
|
|
4012
|
-
current =
|
|
4086
|
+
current = domutils2.findOne(
|
|
4013
4087
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "head",
|
|
4014
4088
|
html.children,
|
|
4015
4089
|
true
|
|
4016
4090
|
);
|
|
4017
4091
|
} else if (rootTag === "body") {
|
|
4018
|
-
current =
|
|
4092
|
+
current = domutils2.findOne(
|
|
4019
4093
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "body",
|
|
4020
4094
|
html.children,
|
|
4021
4095
|
true
|
|
@@ -4432,9 +4506,9 @@ function serializeXmlNode(node) {
|
|
|
4432
4506
|
const attrString = Object.entries(attrs).map(([key, value]) => ` ${key}="${escapeAttributeValue2(String(value))}"`).join("");
|
|
4433
4507
|
const children = node.$$ || [];
|
|
4434
4508
|
if (children.length === 0) {
|
|
4435
|
-
const
|
|
4436
|
-
if (
|
|
4437
|
-
return `<${name}${attrString}>${
|
|
4509
|
+
const textContent2 = node._ || "";
|
|
4510
|
+
if (textContent2) {
|
|
4511
|
+
return `<${name}${attrString}>${textContent2}</${name}>`;
|
|
4438
4512
|
}
|
|
4439
4513
|
return `<${name}${attrString} />`;
|
|
4440
4514
|
}
|
|
@@ -4490,9 +4564,9 @@ function serializeElement2(node, indent2 = "") {
|
|
|
4490
4564
|
const attrString = Object.entries(attributes).map(([key, value]) => ` ${key}="${escapeAttributeValue2(String(value))}"`).join("");
|
|
4491
4565
|
const children = Array.isArray(node.$$) ? node.$$ : [];
|
|
4492
4566
|
if (children.length === 0) {
|
|
4493
|
-
const
|
|
4494
|
-
if (
|
|
4495
|
-
return `${indent2}<${name}${attrString}>${
|
|
4567
|
+
const textContent2 = node._ ?? "";
|
|
4568
|
+
if (textContent2) {
|
|
4569
|
+
return `${indent2}<${name}${attrString}>${textContent2}</${name}>`;
|
|
4496
4570
|
}
|
|
4497
4571
|
return `${indent2}<${name}${attrString} />`;
|
|
4498
4572
|
}
|
|
@@ -6053,10 +6127,10 @@ function formatXml(xml) {
|
|
|
6053
6127
|
if (cdataNode) {
|
|
6054
6128
|
return `${indent2}${openTag}<![CDATA[${cdataNode.nodeValue}]]></${tagName}>`;
|
|
6055
6129
|
}
|
|
6056
|
-
const
|
|
6130
|
+
const textContent2 = element.textContent?.trim() || "";
|
|
6057
6131
|
const hasOnlyText = element.childNodes.length === 1 && element.childNodes[0].nodeType === 3;
|
|
6058
|
-
if (hasOnlyText &&
|
|
6059
|
-
return `${indent2}${openTag}${
|
|
6132
|
+
if (hasOnlyText && textContent2) {
|
|
6133
|
+
return `${indent2}${openTag}${textContent2}</${tagName}>`;
|
|
6060
6134
|
}
|
|
6061
6135
|
const children = Array.from(element.children);
|
|
6062
6136
|
if (children.length === 0) {
|
|
@@ -9376,14 +9450,14 @@ function parseEjsForTranslation(input2) {
|
|
|
9376
9450
|
if (part.type === "ejs") {
|
|
9377
9451
|
template += part.content;
|
|
9378
9452
|
} else {
|
|
9379
|
-
const
|
|
9453
|
+
const textContent2 = part.content;
|
|
9380
9454
|
const htmlTagRegex = /<[^>]+>/g;
|
|
9381
9455
|
const textParts = [];
|
|
9382
9456
|
let lastTextIndex = 0;
|
|
9383
9457
|
let htmlMatch;
|
|
9384
|
-
while ((htmlMatch = htmlTagRegex.exec(
|
|
9458
|
+
while ((htmlMatch = htmlTagRegex.exec(textContent2)) !== null) {
|
|
9385
9459
|
if (htmlMatch.index > lastTextIndex) {
|
|
9386
|
-
const textBefore =
|
|
9460
|
+
const textBefore = textContent2.slice(lastTextIndex, htmlMatch.index);
|
|
9387
9461
|
if (textBefore.trim()) {
|
|
9388
9462
|
textParts.push({ type: "text", content: textBefore });
|
|
9389
9463
|
} else {
|
|
@@ -9393,8 +9467,8 @@ function parseEjsForTranslation(input2) {
|
|
|
9393
9467
|
textParts.push({ type: "html", content: htmlMatch[0] });
|
|
9394
9468
|
lastTextIndex = htmlMatch.index + htmlMatch[0].length;
|
|
9395
9469
|
}
|
|
9396
|
-
if (lastTextIndex <
|
|
9397
|
-
const remainingText =
|
|
9470
|
+
if (lastTextIndex < textContent2.length) {
|
|
9471
|
+
const remainingText = textContent2.slice(lastTextIndex);
|
|
9398
9472
|
if (remainingText.trim()) {
|
|
9399
9473
|
textParts.push({ type: "text", content: remainingText });
|
|
9400
9474
|
} else {
|
|
@@ -9402,11 +9476,11 @@ function parseEjsForTranslation(input2) {
|
|
|
9402
9476
|
}
|
|
9403
9477
|
}
|
|
9404
9478
|
if (textParts.length === 0) {
|
|
9405
|
-
const trimmedContent =
|
|
9479
|
+
const trimmedContent = textContent2.trim();
|
|
9406
9480
|
if (trimmedContent) {
|
|
9407
|
-
textParts.push({ type: "text", content:
|
|
9481
|
+
textParts.push({ type: "text", content: textContent2 });
|
|
9408
9482
|
} else {
|
|
9409
|
-
textParts.push({ type: "html", content:
|
|
9483
|
+
textParts.push({ type: "html", content: textContent2 });
|
|
9410
9484
|
}
|
|
9411
9485
|
}
|
|
9412
9486
|
for (const textPart of textParts) {
|
|
@@ -9478,117 +9552,15 @@ function createEjsLoader() {
|
|
|
9478
9552
|
// src/cli/loaders/twig.ts
|
|
9479
9553
|
import * as htmlparser23 from "htmlparser2";
|
|
9480
9554
|
import { DomHandler as DomHandler3 } from "domhandler";
|
|
9481
|
-
import * as
|
|
9555
|
+
import * as domutils3 from "domutils";
|
|
9482
9556
|
import * as DomSerializer2 from "dom-serializer";
|
|
9483
9557
|
function createTwigLoader() {
|
|
9484
|
-
const PHRASING_ELEMENTS = /* @__PURE__ */ new Set([
|
|
9485
|
-
// Text-level semantics
|
|
9486
|
-
"a",
|
|
9487
|
-
"abbr",
|
|
9488
|
-
"b",
|
|
9489
|
-
"bdi",
|
|
9490
|
-
"bdo",
|
|
9491
|
-
"br",
|
|
9492
|
-
"cite",
|
|
9493
|
-
"code",
|
|
9494
|
-
"data",
|
|
9495
|
-
"dfn",
|
|
9496
|
-
"em",
|
|
9497
|
-
"i",
|
|
9498
|
-
"kbd",
|
|
9499
|
-
"mark",
|
|
9500
|
-
"q",
|
|
9501
|
-
"ruby",
|
|
9502
|
-
"s",
|
|
9503
|
-
"samp",
|
|
9504
|
-
"small",
|
|
9505
|
-
"span",
|
|
9506
|
-
"strong",
|
|
9507
|
-
"sub",
|
|
9508
|
-
"sup",
|
|
9509
|
-
"time",
|
|
9510
|
-
"u",
|
|
9511
|
-
"var",
|
|
9512
|
-
"wbr",
|
|
9513
|
-
// Media
|
|
9514
|
-
"audio",
|
|
9515
|
-
"img",
|
|
9516
|
-
"video",
|
|
9517
|
-
"picture",
|
|
9518
|
-
// Interactive
|
|
9519
|
-
"button",
|
|
9520
|
-
"input",
|
|
9521
|
-
"label",
|
|
9522
|
-
"select",
|
|
9523
|
-
"textarea",
|
|
9524
|
-
// Embedded
|
|
9525
|
-
"canvas",
|
|
9526
|
-
"iframe",
|
|
9527
|
-
"object",
|
|
9528
|
-
"svg",
|
|
9529
|
-
"math",
|
|
9530
|
-
// Other
|
|
9531
|
-
"del",
|
|
9532
|
-
"ins",
|
|
9533
|
-
"map",
|
|
9534
|
-
"area"
|
|
9535
|
-
]);
|
|
9536
|
-
const BLOCK_ELEMENTS = /* @__PURE__ */ new Set([
|
|
9537
|
-
"div",
|
|
9538
|
-
"p",
|
|
9539
|
-
"h1",
|
|
9540
|
-
"h2",
|
|
9541
|
-
"h3",
|
|
9542
|
-
"h4",
|
|
9543
|
-
"h5",
|
|
9544
|
-
"h6",
|
|
9545
|
-
"ul",
|
|
9546
|
-
"ol",
|
|
9547
|
-
"li",
|
|
9548
|
-
"dl",
|
|
9549
|
-
"dt",
|
|
9550
|
-
"dd",
|
|
9551
|
-
"blockquote",
|
|
9552
|
-
"pre",
|
|
9553
|
-
"article",
|
|
9554
|
-
"aside",
|
|
9555
|
-
"nav",
|
|
9556
|
-
"section",
|
|
9557
|
-
"header",
|
|
9558
|
-
"footer",
|
|
9559
|
-
"main",
|
|
9560
|
-
"figure",
|
|
9561
|
-
"figcaption",
|
|
9562
|
-
"table",
|
|
9563
|
-
"thead",
|
|
9564
|
-
"tbody",
|
|
9565
|
-
"tfoot",
|
|
9566
|
-
"tr",
|
|
9567
|
-
"td",
|
|
9568
|
-
"th",
|
|
9569
|
-
"caption",
|
|
9570
|
-
"form",
|
|
9571
|
-
"fieldset",
|
|
9572
|
-
"legend",
|
|
9573
|
-
"details",
|
|
9574
|
-
"summary",
|
|
9575
|
-
"address",
|
|
9576
|
-
"hr",
|
|
9577
|
-
"search",
|
|
9578
|
-
"dialog",
|
|
9579
|
-
"noscript",
|
|
9580
|
-
"title"
|
|
9581
|
-
]);
|
|
9582
|
-
const UNLOCALIZABLE_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
|
|
9583
9558
|
const LOCALIZABLE_ATTRIBUTES2 = {
|
|
9584
|
-
|
|
9585
|
-
img: ["alt", "title"],
|
|
9559
|
+
...BASE_LOCALIZABLE_ATTRIBUTES,
|
|
9586
9560
|
input: ["placeholder", "title", "aria-label"],
|
|
9587
9561
|
textarea: ["placeholder", "title", "aria-label"],
|
|
9588
9562
|
button: ["title", "aria-label"],
|
|
9589
|
-
a: ["title", "aria-label"]
|
|
9590
|
-
abbr: ["title"],
|
|
9591
|
-
link: ["title"]
|
|
9563
|
+
a: ["title", "aria-label"]
|
|
9592
9564
|
};
|
|
9593
9565
|
function preprocessTwig(input2) {
|
|
9594
9566
|
const twigBlocks = [];
|
|
@@ -9622,33 +9594,10 @@ function createTwigLoader() {
|
|
|
9622
9594
|
parser.write(processed);
|
|
9623
9595
|
parser.end();
|
|
9624
9596
|
const dom = handler.dom;
|
|
9625
|
-
function isInsideUnlocalizableTag(element) {
|
|
9626
|
-
let current = element.parent;
|
|
9627
|
-
while (current && current.type === "tag") {
|
|
9628
|
-
if (UNLOCALIZABLE_TAGS.has(current.name.toLowerCase())) {
|
|
9629
|
-
return true;
|
|
9630
|
-
}
|
|
9631
|
-
current = current.parent;
|
|
9632
|
-
}
|
|
9633
|
-
return false;
|
|
9634
|
-
}
|
|
9635
|
-
function hasTranslatableContent(element) {
|
|
9636
|
-
const text = domutils2.textContent(element);
|
|
9637
|
-
return text.trim().length > 0;
|
|
9638
|
-
}
|
|
9639
|
-
function isLeafBlock(element) {
|
|
9640
|
-
const childElements = element.children.filter(
|
|
9641
|
-
(child) => child.type === "tag"
|
|
9642
|
-
);
|
|
9643
|
-
for (const child of childElements) {
|
|
9644
|
-
if (BLOCK_ELEMENTS.has(child.name.toLowerCase())) {
|
|
9645
|
-
return false;
|
|
9646
|
-
}
|
|
9647
|
-
}
|
|
9648
|
-
return hasTranslatableContent(element);
|
|
9649
|
-
}
|
|
9650
9597
|
function getInnerHTML2(element) {
|
|
9651
|
-
const html2 = element.children.map(
|
|
9598
|
+
const html2 = element.children.map(
|
|
9599
|
+
(child) => DomSerializer2.default(child, { encodeEntities: false })
|
|
9600
|
+
).join("");
|
|
9652
9601
|
return postprocessTwig(html2, twigBlocks);
|
|
9653
9602
|
}
|
|
9654
9603
|
function extractAttributes(element, path20) {
|
|
@@ -9663,47 +9612,22 @@ function createTwigLoader() {
|
|
|
9663
9612
|
}
|
|
9664
9613
|
}
|
|
9665
9614
|
}
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
extractAttributes(element, path20);
|
|
9672
|
-
const tagName = element.name.toLowerCase();
|
|
9673
|
-
if (BLOCK_ELEMENTS.has(tagName) && isLeafBlock(element)) {
|
|
9674
|
-
const content = getInnerHTML2(element).trim();
|
|
9675
|
-
if (content) {
|
|
9676
|
-
result[path20] = content;
|
|
9677
|
-
}
|
|
9678
|
-
return;
|
|
9679
|
-
}
|
|
9680
|
-
if (PHRASING_ELEMENTS.has(tagName) && hasTranslatableContent(element)) {
|
|
9681
|
-
const content = getInnerHTML2(element).trim();
|
|
9682
|
-
if (content) {
|
|
9683
|
-
result[path20] = content;
|
|
9684
|
-
}
|
|
9685
|
-
return;
|
|
9686
|
-
}
|
|
9687
|
-
let childIndex = 0;
|
|
9688
|
-
const childElements = element.children.filter(
|
|
9689
|
-
(child) => child.type === "tag"
|
|
9690
|
-
);
|
|
9691
|
-
for (const child of childElements) {
|
|
9692
|
-
extractFromElement(child, [...pathParts, childIndex++]);
|
|
9693
|
-
}
|
|
9694
|
-
}
|
|
9695
|
-
const html = domutils2.findOne(
|
|
9615
|
+
const extractFromElement = createElementExtractor(
|
|
9616
|
+
{ getInnerHTML: getInnerHTML2, extractAttributes },
|
|
9617
|
+
result
|
|
9618
|
+
);
|
|
9619
|
+
const html = domutils3.findOne(
|
|
9696
9620
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "html",
|
|
9697
9621
|
dom,
|
|
9698
9622
|
true
|
|
9699
9623
|
);
|
|
9700
9624
|
if (html) {
|
|
9701
|
-
const head =
|
|
9625
|
+
const head = domutils3.findOne(
|
|
9702
9626
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "head",
|
|
9703
9627
|
html.children,
|
|
9704
9628
|
true
|
|
9705
9629
|
);
|
|
9706
|
-
const body =
|
|
9630
|
+
const body = domutils3.findOne(
|
|
9707
9631
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "body",
|
|
9708
9632
|
html.children,
|
|
9709
9633
|
true
|
|
@@ -9744,10 +9668,12 @@ function createTwigLoader() {
|
|
|
9744
9668
|
lowerCaseTags: false,
|
|
9745
9669
|
lowerCaseAttributeNames: false
|
|
9746
9670
|
});
|
|
9747
|
-
parser.write(
|
|
9671
|
+
parser.write(
|
|
9672
|
+
processed || "<!DOCTYPE html><html><head></head><body></body></html>"
|
|
9673
|
+
);
|
|
9748
9674
|
parser.end();
|
|
9749
9675
|
const dom = handler.dom;
|
|
9750
|
-
const html =
|
|
9676
|
+
const html = domutils3.findOne(
|
|
9751
9677
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "html",
|
|
9752
9678
|
dom,
|
|
9753
9679
|
true
|
|
@@ -9777,13 +9703,13 @@ function createTwigLoader() {
|
|
|
9777
9703
|
let current = null;
|
|
9778
9704
|
if (html) {
|
|
9779
9705
|
if (rootTag === "head") {
|
|
9780
|
-
current =
|
|
9706
|
+
current = domutils3.findOne(
|
|
9781
9707
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "head",
|
|
9782
9708
|
html.children,
|
|
9783
9709
|
true
|
|
9784
9710
|
);
|
|
9785
9711
|
} else if (rootTag === "body") {
|
|
9786
|
-
current =
|
|
9712
|
+
current = domutils3.findOne(
|
|
9787
9713
|
(elem) => elem.type === "tag" && elem.name.toLowerCase() === "body",
|
|
9788
9714
|
html.children,
|
|
9789
9715
|
true
|
|
@@ -9831,7 +9757,9 @@ function createTwigLoader() {
|
|
|
9831
9757
|
}
|
|
9832
9758
|
}
|
|
9833
9759
|
}
|
|
9834
|
-
const serialized = DomSerializer2.default(dom, {
|
|
9760
|
+
const serialized = DomSerializer2.default(dom, {
|
|
9761
|
+
encodeEntities: false
|
|
9762
|
+
});
|
|
9835
9763
|
return postprocessTwig(serialized, twigBlocks);
|
|
9836
9764
|
}
|
|
9837
9765
|
});
|
|
@@ -15246,7 +15174,7 @@ async function renderHero2() {
|
|
|
15246
15174
|
// package.json
|
|
15247
15175
|
var package_default = {
|
|
15248
15176
|
name: "lingo.dev",
|
|
15249
|
-
version: "0.125.
|
|
15177
|
+
version: "0.125.4",
|
|
15250
15178
|
description: "Lingo.dev CLI",
|
|
15251
15179
|
private: false,
|
|
15252
15180
|
repository: {
|