@reteps/tree-sitter-htmlmustache 0.7.3 → 0.8.0
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/README.md +52 -22
- package/cli/out/main.js +915 -426
- package/package.json +2 -1
package/cli/out/main.js
CHANGED
|
@@ -542,8 +542,8 @@ function parseDocument(source) {
|
|
|
542
542
|
}
|
|
543
543
|
|
|
544
544
|
// lsp/server/src/configFile.ts
|
|
545
|
-
var fs = __toESM(require("fs"));
|
|
546
|
-
var path2 = __toESM(require("path"));
|
|
545
|
+
var fs = __toESM(require("fs"), 1);
|
|
546
|
+
var path2 = __toESM(require("path"), 1);
|
|
547
547
|
|
|
548
548
|
// lsp/server/src/ruleMetadata.ts
|
|
549
549
|
var RULES = [
|
|
@@ -586,11 +586,16 @@ var RULES = [
|
|
|
586
586
|
name: "unrecognizedHtmlTags",
|
|
587
587
|
defaultSeverity: "error",
|
|
588
588
|
description: "Flags HTML tags that are not standard HTML elements or valid custom elements"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
name: "elementContentTooLong",
|
|
592
|
+
defaultSeverity: "off",
|
|
593
|
+
description: "Flags configured elements whose inner content exceeds a byte-length threshold (opt-in; requires `elements: [{ tag, maxBytes }]` option)"
|
|
589
594
|
}
|
|
590
595
|
];
|
|
591
|
-
var KNOWN_RULE_NAMES = new Set(RULES.map((
|
|
596
|
+
var KNOWN_RULE_NAMES = new Set(RULES.map((r2) => r2.name));
|
|
592
597
|
var RULE_DEFAULTS = Object.fromEntries(
|
|
593
|
-
RULES.map((
|
|
598
|
+
RULES.map((r2) => [r2.name, r2.defaultSeverity])
|
|
594
599
|
);
|
|
595
600
|
|
|
596
601
|
// lsp/server/src/configFile.ts
|
|
@@ -614,41 +619,70 @@ var VALID_CSS_DISPLAY_VALUES = /* @__PURE__ */ new Set([
|
|
|
614
619
|
"none"
|
|
615
620
|
]);
|
|
616
621
|
var VALID_RULE_SEVERITIES = /* @__PURE__ */ new Set(["error", "warning", "off"]);
|
|
622
|
+
function parseElementContentTooLongOptions(raw) {
|
|
623
|
+
if (!Array.isArray(raw.elements)) return null;
|
|
624
|
+
const elements = [];
|
|
625
|
+
for (const entry of raw.elements) {
|
|
626
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
627
|
+
const e2 = entry;
|
|
628
|
+
if (typeof e2.tag !== "string" || e2.tag.length === 0) continue;
|
|
629
|
+
if (typeof e2.maxBytes !== "number" || !Number.isFinite(e2.maxBytes) || e2.maxBytes < 0) continue;
|
|
630
|
+
elements.push({ tag: e2.tag, maxBytes: e2.maxBytes });
|
|
631
|
+
}
|
|
632
|
+
return { elements };
|
|
633
|
+
}
|
|
634
|
+
var OPTION_PARSERS = {
|
|
635
|
+
elementContentTooLong: parseElementContentTooLongOptions
|
|
636
|
+
};
|
|
637
|
+
function parseRuleEntry(key, value) {
|
|
638
|
+
if (typeof value === "string") {
|
|
639
|
+
return VALID_RULE_SEVERITIES.has(value) ? value : null;
|
|
640
|
+
}
|
|
641
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
642
|
+
const obj = value;
|
|
643
|
+
if (typeof obj.severity !== "string" || !VALID_RULE_SEVERITIES.has(obj.severity)) return null;
|
|
644
|
+
const severity = obj.severity;
|
|
645
|
+
const parser2 = OPTION_PARSERS[key];
|
|
646
|
+
if (!parser2) return { severity };
|
|
647
|
+
const options = parser2(obj);
|
|
648
|
+
if (!options) return { severity };
|
|
649
|
+
return { severity, ...options };
|
|
650
|
+
}
|
|
617
651
|
var CONFIG_FILENAME = ".htmlmustache.jsonc";
|
|
618
652
|
function parseJsonc(text2) {
|
|
619
653
|
let result = "";
|
|
620
|
-
let
|
|
621
|
-
while (
|
|
622
|
-
if (text2[
|
|
654
|
+
let i2 = 0;
|
|
655
|
+
while (i2 < text2.length) {
|
|
656
|
+
if (text2[i2] === '"') {
|
|
623
657
|
result += '"';
|
|
624
|
-
|
|
625
|
-
while (
|
|
626
|
-
if (text2[
|
|
627
|
-
result += text2[
|
|
628
|
-
|
|
658
|
+
i2++;
|
|
659
|
+
while (i2 < text2.length && text2[i2] !== '"') {
|
|
660
|
+
if (text2[i2] === "\\") {
|
|
661
|
+
result += text2[i2] + (text2[i2 + 1] ?? "");
|
|
662
|
+
i2 += 2;
|
|
629
663
|
} else {
|
|
630
|
-
result += text2[
|
|
631
|
-
|
|
664
|
+
result += text2[i2];
|
|
665
|
+
i2++;
|
|
632
666
|
}
|
|
633
667
|
}
|
|
634
|
-
if (
|
|
668
|
+
if (i2 < text2.length) {
|
|
635
669
|
result += '"';
|
|
636
|
-
|
|
670
|
+
i2++;
|
|
637
671
|
}
|
|
638
672
|
continue;
|
|
639
673
|
}
|
|
640
|
-
if (text2[
|
|
641
|
-
while (
|
|
674
|
+
if (text2[i2] === "/" && text2[i2 + 1] === "/") {
|
|
675
|
+
while (i2 < text2.length && text2[i2] !== "\n") i2++;
|
|
642
676
|
continue;
|
|
643
677
|
}
|
|
644
|
-
if (text2[
|
|
645
|
-
|
|
646
|
-
while (
|
|
647
|
-
|
|
678
|
+
if (text2[i2] === "/" && text2[i2 + 1] === "*") {
|
|
679
|
+
i2 += 2;
|
|
680
|
+
while (i2 < text2.length && !(text2[i2] === "*" && text2[i2 + 1] === "/")) i2++;
|
|
681
|
+
i2 += 2;
|
|
648
682
|
continue;
|
|
649
683
|
}
|
|
650
|
-
result += text2[
|
|
651
|
-
|
|
684
|
+
result += text2[i2];
|
|
685
|
+
i2++;
|
|
652
686
|
}
|
|
653
687
|
result = result.replace(/,\s*([}\]])/g, "$1");
|
|
654
688
|
return JSON.parse(result);
|
|
@@ -674,21 +708,21 @@ function parseCustomTagArray(arr) {
|
|
|
674
708
|
const tags = [];
|
|
675
709
|
for (const entry of arr) {
|
|
676
710
|
if (entry && typeof entry === "object" && "name" in entry) {
|
|
677
|
-
const
|
|
678
|
-
if (typeof
|
|
679
|
-
const tag = { name:
|
|
680
|
-
if (typeof
|
|
681
|
-
tag.display =
|
|
711
|
+
const e2 = entry;
|
|
712
|
+
if (typeof e2.name !== "string" || e2.name.length === 0) continue;
|
|
713
|
+
const tag = { name: e2.name };
|
|
714
|
+
if (typeof e2.display === "string" && VALID_CSS_DISPLAY_VALUES.has(e2.display)) {
|
|
715
|
+
tag.display = e2.display;
|
|
682
716
|
}
|
|
683
|
-
if (typeof
|
|
684
|
-
if (
|
|
685
|
-
tag.languageMap =
|
|
717
|
+
if (typeof e2.languageAttribute === "string") tag.languageAttribute = e2.languageAttribute;
|
|
718
|
+
if (e2.languageMap && typeof e2.languageMap === "object" && !Array.isArray(e2.languageMap)) {
|
|
719
|
+
tag.languageMap = e2.languageMap;
|
|
686
720
|
}
|
|
687
|
-
if (typeof
|
|
688
|
-
if (typeof
|
|
689
|
-
tag.indent =
|
|
721
|
+
if (typeof e2.languageDefault === "string") tag.languageDefault = e2.languageDefault;
|
|
722
|
+
if (typeof e2.indent === "string" && VALID_INDENT_MODES.has(e2.indent)) {
|
|
723
|
+
tag.indent = e2.indent;
|
|
690
724
|
}
|
|
691
|
-
if (typeof
|
|
725
|
+
if (typeof e2.indentAttribute === "string") tag.indentAttribute = e2.indentAttribute;
|
|
692
726
|
tags.push(tag);
|
|
693
727
|
}
|
|
694
728
|
}
|
|
@@ -717,11 +751,11 @@ function validateConfig(raw) {
|
|
|
717
751
|
if (items.length > 0) config.noBreakDelimiters = items;
|
|
718
752
|
}
|
|
719
753
|
if (Array.isArray(obj.include)) {
|
|
720
|
-
const items = obj.include.filter((
|
|
754
|
+
const items = obj.include.filter((s2) => typeof s2 === "string" && s2.length > 0);
|
|
721
755
|
if (items.length > 0) config.include = items;
|
|
722
756
|
}
|
|
723
757
|
if (Array.isArray(obj.exclude)) {
|
|
724
|
-
const items = obj.exclude.filter((
|
|
758
|
+
const items = obj.exclude.filter((s2) => typeof s2 === "string" && s2.length > 0);
|
|
725
759
|
if (items.length > 0) config.exclude = items;
|
|
726
760
|
}
|
|
727
761
|
const parsedCodeTags = parseCustomTagArray(obj.customCodeTags);
|
|
@@ -741,10 +775,11 @@ function validateConfig(raw) {
|
|
|
741
775
|
const rules = {};
|
|
742
776
|
let hasRules = false;
|
|
743
777
|
for (const [key, value] of Object.entries(rawRules)) {
|
|
744
|
-
if (KNOWN_RULE_NAMES.has(key)
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
778
|
+
if (!KNOWN_RULE_NAMES.has(key)) continue;
|
|
779
|
+
const entry = parseRuleEntry(key, value);
|
|
780
|
+
if (entry === null) continue;
|
|
781
|
+
rules[key] = entry;
|
|
782
|
+
hasRules = true;
|
|
748
783
|
}
|
|
749
784
|
if (hasRules) config.rules = rules;
|
|
750
785
|
}
|
|
@@ -752,13 +787,13 @@ function validateConfig(raw) {
|
|
|
752
787
|
const rules = [];
|
|
753
788
|
for (const entry of obj.customRules) {
|
|
754
789
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
755
|
-
const
|
|
756
|
-
if (typeof
|
|
757
|
-
if (typeof
|
|
758
|
-
if (typeof
|
|
759
|
-
const rule = { id:
|
|
760
|
-
if (typeof
|
|
761
|
-
rule.severity =
|
|
790
|
+
const e2 = entry;
|
|
791
|
+
if (typeof e2.id !== "string" || e2.id.length === 0) continue;
|
|
792
|
+
if (typeof e2.selector !== "string" || e2.selector.length === 0) continue;
|
|
793
|
+
if (typeof e2.message !== "string" || e2.message.length === 0) continue;
|
|
794
|
+
const rule = { id: e2.id, selector: e2.selector, message: e2.message };
|
|
795
|
+
if (typeof e2.severity === "string" && VALID_RULE_SEVERITIES.has(e2.severity)) {
|
|
796
|
+
rule.severity = e2.severity;
|
|
762
797
|
}
|
|
763
798
|
rules.push(rule);
|
|
764
799
|
}
|
|
@@ -807,7 +842,7 @@ function isHtmlElementType(node) {
|
|
|
807
842
|
function getTagName(node) {
|
|
808
843
|
for (const child of node.children) {
|
|
809
844
|
if (child.type === "html_start_tag" || child.type === "html_self_closing_tag") {
|
|
810
|
-
const tagNameNode = child.children.find((
|
|
845
|
+
const tagNameNode = child.children.find((c2) => c2.type === "html_tag_name");
|
|
811
846
|
if (tagNameNode) return tagNameNode.text;
|
|
812
847
|
}
|
|
813
848
|
}
|
|
@@ -815,16 +850,33 @@ function getTagName(node) {
|
|
|
815
850
|
}
|
|
816
851
|
function getSectionName(node) {
|
|
817
852
|
const beginNode = node.children.find(
|
|
818
|
-
(
|
|
853
|
+
(c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
|
|
819
854
|
);
|
|
820
855
|
if (!beginNode) return null;
|
|
821
|
-
const tagNameNode = beginNode.children.find((
|
|
856
|
+
const tagNameNode = beginNode.children.find((c2) => c2.type === "mustache_tag_name");
|
|
822
857
|
return tagNameNode?.text ?? null;
|
|
823
858
|
}
|
|
824
859
|
function getErroneousEndTagName(node) {
|
|
825
|
-
const nameNode = node.children.find((
|
|
860
|
+
const nameNode = node.children.find((c2) => c2.type === "html_erroneous_end_tag_name");
|
|
826
861
|
return nameNode?.text?.toLowerCase() ?? null;
|
|
827
862
|
}
|
|
863
|
+
function getInterpolationPath(node) {
|
|
864
|
+
for (const child of node.children) {
|
|
865
|
+
if (child.type === "mustache_path_expression" || child.type === "mustache_identifier") {
|
|
866
|
+
return child.text;
|
|
867
|
+
}
|
|
868
|
+
if (child.type === ".") return ".";
|
|
869
|
+
}
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
function getCommentContent(node) {
|
|
873
|
+
const child = node.children.find((c2) => c2.type === "mustache_comment_content");
|
|
874
|
+
return child ? child.text.trim() : null;
|
|
875
|
+
}
|
|
876
|
+
function getPartialName(node) {
|
|
877
|
+
const child = node.children.find((c2) => c2.type === "mustache_partial_content");
|
|
878
|
+
return child ? child.text.trim() : null;
|
|
879
|
+
}
|
|
828
880
|
|
|
829
881
|
// lsp/server/src/htmlBalanceChecker.ts
|
|
830
882
|
function getTagNameLower(element) {
|
|
@@ -834,7 +886,7 @@ function getErroneousEndTagNameLower(node) {
|
|
|
834
886
|
return getErroneousEndTagName(node)?.toLowerCase() ?? null;
|
|
835
887
|
}
|
|
836
888
|
function hasForcedEndTag(element) {
|
|
837
|
-
return element.children.some((
|
|
889
|
+
return element.children.some((c2) => c2.type === "html_forced_end_tag");
|
|
838
890
|
}
|
|
839
891
|
function extractFromNodes(nodes) {
|
|
840
892
|
const items = [];
|
|
@@ -846,13 +898,13 @@ function extractFromNodes(nodes) {
|
|
|
846
898
|
function extractFromNode(node) {
|
|
847
899
|
if (node.type === "html_element") {
|
|
848
900
|
const contentChildren = node.children.filter(
|
|
849
|
-
(
|
|
901
|
+
(c2) => c2.type !== "html_start_tag" && c2.type !== "html_end_tag" && c2.type !== "html_forced_end_tag"
|
|
850
902
|
);
|
|
851
903
|
if (hasForcedEndTag(node)) {
|
|
852
904
|
const tagName = getTagNameLower(node);
|
|
853
905
|
const items = [];
|
|
854
906
|
if (tagName) {
|
|
855
|
-
const startTag = node.children.find((
|
|
907
|
+
const startTag = node.children.find((c2) => c2.type === "html_start_tag");
|
|
856
908
|
items.push({ type: "open", tagName, node: startTag ?? node });
|
|
857
909
|
}
|
|
858
910
|
items.push(...extractFromNodes(contentChildren));
|
|
@@ -874,7 +926,7 @@ function extractFromNode(node) {
|
|
|
874
926
|
const sectionName = getSectionName(node);
|
|
875
927
|
if (sectionName) {
|
|
876
928
|
const contentChildren = node.children.filter(
|
|
877
|
-
(
|
|
929
|
+
(c2) => c2.type !== "mustache_section_begin" && c2.type !== "mustache_section_end" && c2.type !== "mustache_erroneous_section_end"
|
|
878
930
|
);
|
|
879
931
|
return [
|
|
880
932
|
{
|
|
@@ -891,7 +943,7 @@ function extractFromNode(node) {
|
|
|
891
943
|
const sectionName = getSectionName(node);
|
|
892
944
|
if (sectionName) {
|
|
893
945
|
const contentChildren = node.children.filter(
|
|
894
|
-
(
|
|
946
|
+
(c2) => c2.type !== "mustache_inverted_section_begin" && c2.type !== "mustache_inverted_section_end" && c2.type !== "mustache_erroneous_inverted_section_end"
|
|
895
947
|
);
|
|
896
948
|
return [
|
|
897
949
|
{
|
|
@@ -909,17 +961,17 @@ function extractFromNode(node) {
|
|
|
909
961
|
function mergeAdjacentForks(items) {
|
|
910
962
|
if (items.length === 0) return items;
|
|
911
963
|
const result = [];
|
|
912
|
-
let
|
|
913
|
-
while (
|
|
914
|
-
const item = items[
|
|
964
|
+
let i2 = 0;
|
|
965
|
+
while (i2 < items.length) {
|
|
966
|
+
const item = items[i2];
|
|
915
967
|
if (item.type !== "fork") {
|
|
916
968
|
result.push(item);
|
|
917
|
-
|
|
969
|
+
i2++;
|
|
918
970
|
continue;
|
|
919
971
|
}
|
|
920
972
|
const truthy = [...item.truthy];
|
|
921
973
|
const falsy = [...item.falsy];
|
|
922
|
-
let j =
|
|
974
|
+
let j = i2 + 1;
|
|
923
975
|
while (j < items.length) {
|
|
924
976
|
const next = items[j];
|
|
925
977
|
if (next.type !== "fork" || next.sectionName !== item.sectionName) break;
|
|
@@ -933,7 +985,7 @@ function mergeAdjacentForks(items) {
|
|
|
933
985
|
truthy: mergeAdjacentForks(truthy),
|
|
934
986
|
falsy: mergeAdjacentForks(falsy)
|
|
935
987
|
});
|
|
936
|
-
|
|
988
|
+
i2 = j;
|
|
937
989
|
}
|
|
938
990
|
return result;
|
|
939
991
|
}
|
|
@@ -1074,12 +1126,12 @@ function checkUnclosedTags(rootNode) {
|
|
|
1074
1126
|
const errors = [];
|
|
1075
1127
|
function visit(node) {
|
|
1076
1128
|
if (node.type === "html_element") {
|
|
1077
|
-
const hasEndTag = node.children.some((
|
|
1078
|
-
const hasForcedEnd = node.children.some((
|
|
1129
|
+
const hasEndTag = node.children.some((c2) => c2.type === "html_end_tag");
|
|
1130
|
+
const hasForcedEnd = node.children.some((c2) => c2.type === "html_forced_end_tag");
|
|
1079
1131
|
if (!hasEndTag && !hasForcedEnd) {
|
|
1080
1132
|
const tagName = getTagNameLower(node);
|
|
1081
1133
|
if (tagName && !VOID_ELEMENTS.has(tagName) && !OPTIONAL_END_TAG_ELEMENTS.has(tagName)) {
|
|
1082
|
-
const startTag = node.children.find((
|
|
1134
|
+
const startTag = node.children.find((c2) => c2.type === "html_start_tag");
|
|
1083
1135
|
errors.push({
|
|
1084
1136
|
node: startTag ?? node,
|
|
1085
1137
|
message: `Unclosed HTML tag: <${tagName}>`
|
|
@@ -1107,8 +1159,8 @@ function checkHtmlBalance(rootNode) {
|
|
|
1107
1159
|
const totalPaths = 1 << sectionNames.length;
|
|
1108
1160
|
for (let mask = 0; mask < totalPaths; mask++) {
|
|
1109
1161
|
const assignment = /* @__PURE__ */ new Map();
|
|
1110
|
-
for (let
|
|
1111
|
-
assignment.set(sectionNames[
|
|
1162
|
+
for (let i2 = 0; i2 < sectionNames.length; i2++) {
|
|
1163
|
+
assignment.set(sectionNames[i2], (mask & 1 << i2) !== 0);
|
|
1112
1164
|
}
|
|
1113
1165
|
const events = flattenPath(items, assignment);
|
|
1114
1166
|
const condition = formatCondition(assignment);
|
|
@@ -1132,7 +1184,7 @@ function checkNestedSameNameSections(rootNode) {
|
|
|
1132
1184
|
if (name) {
|
|
1133
1185
|
if (ancestors.has(name)) {
|
|
1134
1186
|
const beginNode = node.children.find(
|
|
1135
|
-
(
|
|
1187
|
+
(c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
|
|
1136
1188
|
);
|
|
1137
1189
|
errors.push({
|
|
1138
1190
|
node: beginNode ?? node,
|
|
@@ -1158,7 +1210,7 @@ function checkUnquotedMustacheAttributes(rootNode) {
|
|
|
1158
1210
|
const errors = [];
|
|
1159
1211
|
function visit(node) {
|
|
1160
1212
|
if (node.type === "html_attribute") {
|
|
1161
|
-
const mustacheNode = node.children.find((
|
|
1213
|
+
const mustacheNode = node.children.find((c2) => c2.type === "mustache_interpolation");
|
|
1162
1214
|
if (mustacheNode) {
|
|
1163
1215
|
errors.push({
|
|
1164
1216
|
node: mustacheNode,
|
|
@@ -1184,9 +1236,9 @@ function checkConsecutiveSameNameSections(rootNode, sourceText) {
|
|
|
1184
1236
|
const errors = [];
|
|
1185
1237
|
function visit(node) {
|
|
1186
1238
|
const children = node.children;
|
|
1187
|
-
for (let
|
|
1188
|
-
const current = children[
|
|
1189
|
-
const next = children[
|
|
1239
|
+
for (let i2 = 0; i2 < children.length - 1; i2++) {
|
|
1240
|
+
const current = children[i2];
|
|
1241
|
+
const next = children[i2 + 1];
|
|
1190
1242
|
if (!isMustacheSection(current) || current.type !== next.type) {
|
|
1191
1243
|
continue;
|
|
1192
1244
|
}
|
|
@@ -1197,12 +1249,12 @@ function checkConsecutiveSameNameSections(rootNode, sourceText) {
|
|
|
1197
1249
|
if (gap.length > 0 && !/^\s*$/.test(gap)) continue;
|
|
1198
1250
|
const endTagType = current.type === "mustache_section" ? "mustache_section_end" : "mustache_inverted_section_end";
|
|
1199
1251
|
const beginTagType = next.type === "mustache_section" ? "mustache_section_begin" : "mustache_inverted_section_begin";
|
|
1200
|
-
const currentEndTag = current.children.find((
|
|
1201
|
-
const nextBeginTag = next.children.find((
|
|
1252
|
+
const currentEndTag = current.children.find((c2) => c2.type === endTagType);
|
|
1253
|
+
const nextBeginTag = next.children.find((c2) => c2.type === beginTagType);
|
|
1202
1254
|
if (!currentEndTag || !nextBeginTag) continue;
|
|
1203
1255
|
const sectionTypeStr = current.type === "mustache_section" ? "#" : "^";
|
|
1204
1256
|
const nextBeginNode = next.children.find(
|
|
1205
|
-
(
|
|
1257
|
+
(c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
|
|
1206
1258
|
);
|
|
1207
1259
|
errors.push({
|
|
1208
1260
|
node: nextBeginNode ?? next,
|
|
@@ -1252,7 +1304,7 @@ function checkSelfClosingNonVoidTags(rootNode) {
|
|
|
1252
1304
|
const errors = [];
|
|
1253
1305
|
function visit(node) {
|
|
1254
1306
|
if (node.type === "html_self_closing_tag") {
|
|
1255
|
-
const tagNameNode = node.children.find((
|
|
1307
|
+
const tagNameNode = node.children.find((c2) => c2.type === "html_tag_name");
|
|
1256
1308
|
const tagName = tagNameNode?.text.toLowerCase();
|
|
1257
1309
|
if (tagName && !VOID_ELEMENTS2.has(tagName)) {
|
|
1258
1310
|
errors.push({
|
|
@@ -1275,8 +1327,8 @@ function checkSelfClosingNonVoidTags(rootNode) {
|
|
|
1275
1327
|
visit(rootNode);
|
|
1276
1328
|
return errors;
|
|
1277
1329
|
}
|
|
1278
|
-
function areMutuallyExclusive(
|
|
1279
|
-
for (const ac of
|
|
1330
|
+
function areMutuallyExclusive(a2, b) {
|
|
1331
|
+
for (const ac of a2) {
|
|
1280
1332
|
for (const bc of b) {
|
|
1281
1333
|
if (ac.name === bc.name && ac.inverted !== bc.inverted) {
|
|
1282
1334
|
return true;
|
|
@@ -1285,11 +1337,11 @@ function areMutuallyExclusive(a, b) {
|
|
|
1285
1337
|
}
|
|
1286
1338
|
return false;
|
|
1287
1339
|
}
|
|
1288
|
-
function formatConditionClause(
|
|
1340
|
+
function formatConditionClause(a2, b) {
|
|
1289
1341
|
const seen = /* @__PURE__ */ new Map();
|
|
1290
|
-
for (const
|
|
1291
|
-
if (!seen.has(
|
|
1292
|
-
seen.set(
|
|
1342
|
+
for (const c2 of [...a2, ...b]) {
|
|
1343
|
+
if (!seen.has(c2.name)) {
|
|
1344
|
+
seen.set(c2.name, c2.inverted);
|
|
1293
1345
|
}
|
|
1294
1346
|
}
|
|
1295
1347
|
if (seen.size === 0) return "";
|
|
@@ -1302,12 +1354,12 @@ function formatConditionClause(a, b) {
|
|
|
1302
1354
|
function collectAttributes(node, conditions, out) {
|
|
1303
1355
|
for (const child of node.children) {
|
|
1304
1356
|
if (child.type === "html_attribute") {
|
|
1305
|
-
const nameNode = child.children.find((
|
|
1357
|
+
const nameNode = child.children.find((c2) => c2.type === "html_attribute_name");
|
|
1306
1358
|
if (nameNode) {
|
|
1307
1359
|
out.push({ nameNode, conditions: [...conditions] });
|
|
1308
1360
|
}
|
|
1309
1361
|
} else if (child.type === "mustache_attribute") {
|
|
1310
|
-
const section = child.children.find((
|
|
1362
|
+
const section = child.children.find((c2) => isMustacheSection(c2));
|
|
1311
1363
|
if (section) {
|
|
1312
1364
|
const name = getSectionName(section);
|
|
1313
1365
|
if (name) {
|
|
@@ -1528,15 +1580,15 @@ var KNOWN_HTML_TAGS = /* @__PURE__ */ new Set([
|
|
|
1528
1580
|
]);
|
|
1529
1581
|
function checkUnrecognizedHtmlTags(rootNode, customTagNames) {
|
|
1530
1582
|
const errors = [];
|
|
1531
|
-
const customSet = customTagNames ? new Set(customTagNames.map((
|
|
1583
|
+
const customSet = customTagNames ? new Set(customTagNames.map((n2) => n2.toLowerCase())) : void 0;
|
|
1532
1584
|
function visit(node) {
|
|
1533
1585
|
if (node.type === "html_element" || node.type === "html_self_closing_tag") {
|
|
1534
|
-
const tagNameNode = node.type === "html_self_closing_tag" ? node.children.find((
|
|
1586
|
+
const tagNameNode = node.type === "html_self_closing_tag" ? node.children.find((c2) => c2.type === "html_tag_name") : node.children.find((c2) => c2.type === "html_start_tag")?.children.find((c2) => c2.type === "html_tag_name");
|
|
1535
1587
|
const tagName = tagNameNode?.text.toLowerCase();
|
|
1536
1588
|
if (tagName === "svg" || tagName === "math") return;
|
|
1537
1589
|
}
|
|
1538
1590
|
if (node.type === "html_start_tag" || node.type === "html_self_closing_tag") {
|
|
1539
|
-
const tagNameNode = node.children.find((
|
|
1591
|
+
const tagNameNode = node.children.find((c2) => c2.type === "html_tag_name");
|
|
1540
1592
|
if (tagNameNode) {
|
|
1541
1593
|
const tagName = tagNameNode.text.toLowerCase();
|
|
1542
1594
|
if (!KNOWN_HTML_TAGS.has(tagName) && !customSet?.has(tagName)) {
|
|
@@ -1573,19 +1625,19 @@ function checkDuplicateAttributes(rootNode) {
|
|
|
1573
1625
|
}
|
|
1574
1626
|
for (const [, group2] of groups) {
|
|
1575
1627
|
if (group2.length < 2) continue;
|
|
1576
|
-
for (let
|
|
1628
|
+
for (let i2 = 1; i2 < group2.length; i2++) {
|
|
1577
1629
|
let conflictIdx = -1;
|
|
1578
|
-
for (let j = 0; j <
|
|
1579
|
-
if (!areMutuallyExclusive(group2[
|
|
1630
|
+
for (let j = 0; j < i2; j++) {
|
|
1631
|
+
if (!areMutuallyExclusive(group2[i2].conditions, group2[j].conditions)) {
|
|
1580
1632
|
conflictIdx = j;
|
|
1581
1633
|
break;
|
|
1582
1634
|
}
|
|
1583
1635
|
}
|
|
1584
1636
|
if (conflictIdx >= 0) {
|
|
1585
|
-
const clause = formatConditionClause(group2[conflictIdx].conditions, group2[
|
|
1637
|
+
const clause = formatConditionClause(group2[conflictIdx].conditions, group2[i2].conditions);
|
|
1586
1638
|
errors.push({
|
|
1587
|
-
node: group2[
|
|
1588
|
-
message: `Duplicate attribute "${group2[
|
|
1639
|
+
node: group2[i2].nameNode,
|
|
1640
|
+
message: `Duplicate attribute "${group2[i2].nameNode.text}"${clause}`
|
|
1589
1641
|
});
|
|
1590
1642
|
}
|
|
1591
1643
|
}
|
|
@@ -1599,264 +1651,685 @@ function checkDuplicateAttributes(rootNode) {
|
|
|
1599
1651
|
visit(rootNode);
|
|
1600
1652
|
return errors;
|
|
1601
1653
|
}
|
|
1654
|
+
function checkElementContentTooLong(rootNode, elements) {
|
|
1655
|
+
const errors = [];
|
|
1656
|
+
if (elements.length === 0) return errors;
|
|
1657
|
+
const thresholds = /* @__PURE__ */ new Map();
|
|
1658
|
+
for (const { tag, maxBytes } of elements) {
|
|
1659
|
+
const key = tag.toLowerCase();
|
|
1660
|
+
const existing = thresholds.get(key);
|
|
1661
|
+
if (existing === void 0 || maxBytes < existing) thresholds.set(key, maxBytes);
|
|
1662
|
+
}
|
|
1663
|
+
function visit(node) {
|
|
1664
|
+
if (node.type === "html_element") {
|
|
1665
|
+
const startTag = node.children.find((c2) => c2.type === "html_start_tag");
|
|
1666
|
+
const endTag = node.children.find((c2) => c2.type === "html_end_tag");
|
|
1667
|
+
const tagNameNode = startTag?.children.find((c2) => c2.type === "html_tag_name");
|
|
1668
|
+
const tagName = tagNameNode?.text.toLowerCase();
|
|
1669
|
+
if (tagName && startTag && endTag) {
|
|
1670
|
+
const maxBytes = thresholds.get(tagName);
|
|
1671
|
+
if (maxBytes !== void 0) {
|
|
1672
|
+
const innerBytes = endTag.startIndex - startTag.endIndex;
|
|
1673
|
+
if (innerBytes > maxBytes) {
|
|
1674
|
+
errors.push({
|
|
1675
|
+
node: startTag,
|
|
1676
|
+
message: `<${tagName}> content is ${innerBytes} bytes, exceeds limit of ${maxBytes}`
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
for (const child of node.children) {
|
|
1683
|
+
visit(child);
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
visit(rootNode);
|
|
1687
|
+
return errors;
|
|
1688
|
+
}
|
|
1602
1689
|
|
|
1603
|
-
//
|
|
1604
|
-
|
|
1605
|
-
|
|
1690
|
+
// node_modules/parsel-js/dist/parsel.min.js
|
|
1691
|
+
var e = { attribute: /\[\s*(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?(?<name>[-\w\P{ASCII}]+)\s*(?:(?<operator>\W?=)\s*(?<value>.+?)\s*(\s(?<caseSensitive>[iIsS]))?\s*)?\]/gu, id: /#(?<name>[-\w\P{ASCII}]+)/gu, class: /\.(?<name>[-\w\P{ASCII}]+)/gu, comma: /\s*,\s*/g, combinator: /\s*[\s>+~]\s*/g, "pseudo-element": /::(?<name>[-\w\P{ASCII}]+)(?:\((?<argument>¶*)\))?/gu, "pseudo-class": /:(?<name>[-\w\P{ASCII}]+)(?:\((?<argument>¶*)\))?/gu, universal: /(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?\*/gu, type: /(?:(?<namespace>\*|[-\w\P{ASCII}]*)\|)?(?<name>[-\w\P{ASCII}]+)/gu };
|
|
1692
|
+
var t = /* @__PURE__ */ new Set(["combinator", "comma"]);
|
|
1693
|
+
var n = /* @__PURE__ */ new Set(["not", "is", "where", "has", "matches", "-moz-any", "-webkit-any", "nth-child", "nth-last-child"]);
|
|
1694
|
+
var s = /(?<index>[\dn+-]+)\s+of\s+(?<subtree>.+)/;
|
|
1695
|
+
var r = { "nth-child": s, "nth-last-child": s };
|
|
1696
|
+
var o = (t2) => {
|
|
1697
|
+
switch (t2) {
|
|
1698
|
+
case "pseudo-element":
|
|
1699
|
+
case "pseudo-class":
|
|
1700
|
+
return new RegExp(e[t2].source.replace("(?<argument>\xB6*)", "(?<argument>.*)"), "gu");
|
|
1701
|
+
default:
|
|
1702
|
+
return e[t2];
|
|
1703
|
+
}
|
|
1704
|
+
};
|
|
1705
|
+
function c(e2, t2) {
|
|
1706
|
+
let n2 = 0, s2 = "";
|
|
1707
|
+
for (; t2 < e2.length; t2++) {
|
|
1708
|
+
const r2 = e2[t2];
|
|
1709
|
+
switch (r2) {
|
|
1710
|
+
case "(":
|
|
1711
|
+
++n2;
|
|
1712
|
+
break;
|
|
1713
|
+
case ")":
|
|
1714
|
+
--n2;
|
|
1715
|
+
}
|
|
1716
|
+
if (s2 += r2, 0 === n2) return s2;
|
|
1717
|
+
}
|
|
1718
|
+
return s2;
|
|
1719
|
+
}
|
|
1720
|
+
function i(n2, s2 = e) {
|
|
1721
|
+
if (!n2) return [];
|
|
1722
|
+
const r2 = [n2];
|
|
1723
|
+
for (const [e2, t2] of Object.entries(s2)) for (let n3 = 0; n3 < r2.length; n3++) {
|
|
1724
|
+
const s3 = r2[n3];
|
|
1725
|
+
if ("string" != typeof s3) continue;
|
|
1726
|
+
t2.lastIndex = 0;
|
|
1727
|
+
const o3 = t2.exec(s3);
|
|
1728
|
+
if (!o3) continue;
|
|
1729
|
+
const c2 = o3.index - 1, i2 = [], a2 = o3[0], l2 = s3.slice(0, c2 + 1);
|
|
1730
|
+
l2 && i2.push(l2), i2.push({ ...o3.groups, type: e2, content: a2 });
|
|
1731
|
+
const u2 = s3.slice(c2 + a2.length + 1);
|
|
1732
|
+
u2 && i2.push(u2), r2.splice(n3, 1, ...i2);
|
|
1733
|
+
}
|
|
1734
|
+
let o2 = 0;
|
|
1735
|
+
for (const e2 of r2) switch (typeof e2) {
|
|
1736
|
+
case "string":
|
|
1737
|
+
throw new Error(`Unexpected sequence ${e2} found at index ${o2}`);
|
|
1738
|
+
case "object":
|
|
1739
|
+
o2 += e2.content.length, e2.pos = [o2 - e2.content.length, o2], t.has(e2.type) && (e2.content = e2.content.trim() || " ");
|
|
1740
|
+
}
|
|
1741
|
+
return r2;
|
|
1742
|
+
}
|
|
1743
|
+
var a = /(['"])([^\\\n]*?)\1/g;
|
|
1744
|
+
var l = /\\./g;
|
|
1745
|
+
function u(t2, n2 = e) {
|
|
1746
|
+
if ("" === (t2 = t2.trim())) return [];
|
|
1747
|
+
const s2 = [];
|
|
1748
|
+
t2 = (t2 = t2.replace(l, ((e2, t3) => (s2.push({ value: e2, offset: t3 }), "\uE000".repeat(e2.length))))).replace(a, ((e2, t3, n3, r3) => (s2.push({ value: e2, offset: r3 }), `${t3}${"\uE001".repeat(n3.length)}${t3}`)));
|
|
1749
|
+
{
|
|
1750
|
+
let e2, n3 = 0;
|
|
1751
|
+
for (; (e2 = t2.indexOf("(", n3)) > -1; ) {
|
|
1752
|
+
const r3 = c(t2, e2);
|
|
1753
|
+
s2.push({ value: r3, offset: e2 }), t2 = `${t2.substring(0, e2)}(${"\xB6".repeat(r3.length - 2)})${t2.substring(e2 + r3.length)}`, n3 = e2 + r3.length;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
const r2 = i(t2, n2), u2 = /* @__PURE__ */ new Set();
|
|
1757
|
+
for (const e2 of s2.reverse()) for (const t3 of r2) {
|
|
1758
|
+
const { offset: n3, value: s3 } = e2;
|
|
1759
|
+
if (!(t3.pos[0] <= n3 && n3 + s3.length <= t3.pos[1])) continue;
|
|
1760
|
+
const { content: r3 } = t3, o2 = n3 - t3.pos[0];
|
|
1761
|
+
t3.content = r3.slice(0, o2) + s3 + r3.slice(o2 + s3.length), t3.content !== r3 && u2.add(t3);
|
|
1762
|
+
}
|
|
1763
|
+
for (const e2 of u2) {
|
|
1764
|
+
const t3 = o(e2.type);
|
|
1765
|
+
if (!t3) throw new Error(`Unknown token type: ${e2.type}`);
|
|
1766
|
+
t3.lastIndex = 0;
|
|
1767
|
+
const n3 = t3.exec(e2.content);
|
|
1768
|
+
if (!n3) throw new Error(`Unable to parse content for ${e2.type}: ${e2.content}`);
|
|
1769
|
+
Object.assign(e2, n3.groups);
|
|
1770
|
+
}
|
|
1771
|
+
return r2;
|
|
1772
|
+
}
|
|
1773
|
+
function f(e2, { list: t2 = true } = {}) {
|
|
1774
|
+
if (t2 && e2.find(((e3) => "comma" === e3.type))) {
|
|
1775
|
+
const t3 = [], n2 = [];
|
|
1776
|
+
for (let s2 = 0; s2 < e2.length; s2++) if ("comma" === e2[s2].type) {
|
|
1777
|
+
if (0 === n2.length) throw new Error("Incorrect comma at " + s2);
|
|
1778
|
+
t3.push(f(n2, { list: false })), n2.length = 0;
|
|
1779
|
+
} else n2.push(e2[s2]);
|
|
1780
|
+
if (0 === n2.length) throw new Error("Trailing comma");
|
|
1781
|
+
return t3.push(f(n2, { list: false })), { type: "list", list: t3 };
|
|
1782
|
+
}
|
|
1783
|
+
for (let t3 = e2.length - 1; t3 >= 0; t3--) {
|
|
1784
|
+
let n2 = e2[t3];
|
|
1785
|
+
if ("combinator" === n2.type) {
|
|
1786
|
+
let s2 = e2.slice(0, t3), r2 = e2.slice(t3 + 1);
|
|
1787
|
+
return 0 === s2.length ? { type: "relative", combinator: n2.content, right: f(r2) } : { type: "complex", combinator: n2.content, left: f(s2), right: f(r2) };
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
switch (e2.length) {
|
|
1791
|
+
case 0:
|
|
1792
|
+
throw new Error("Could not build AST.");
|
|
1793
|
+
case 1:
|
|
1794
|
+
return e2[0];
|
|
1795
|
+
default:
|
|
1796
|
+
return { type: "compound", list: [...e2] };
|
|
1797
|
+
}
|
|
1606
1798
|
}
|
|
1607
|
-
function
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
const attr = parseOneAttribute(raw, pos, false);
|
|
1621
|
-
if (!attr) return attrs;
|
|
1622
|
-
if (raw[pos.i] !== "]") return attrs;
|
|
1623
|
-
pos.i++;
|
|
1624
|
-
attrs.push(attr);
|
|
1625
|
-
} else {
|
|
1799
|
+
function* p(e2, t2) {
|
|
1800
|
+
switch (e2.type) {
|
|
1801
|
+
case "list":
|
|
1802
|
+
for (let t3 of e2.list) yield* p(t3, e2);
|
|
1803
|
+
break;
|
|
1804
|
+
case "complex":
|
|
1805
|
+
yield* p(e2.left, e2), yield* p(e2.right, e2);
|
|
1806
|
+
break;
|
|
1807
|
+
case "relative":
|
|
1808
|
+
yield* p(e2.right, e2);
|
|
1809
|
+
break;
|
|
1810
|
+
case "compound":
|
|
1811
|
+
yield* e2.list.map(((t3) => [t3, e2]));
|
|
1626
1812
|
break;
|
|
1813
|
+
default:
|
|
1814
|
+
yield [e2, t2];
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
function m(e2, { recursive: t2 = true, list: s2 = true } = {}) {
|
|
1818
|
+
const o2 = u(e2);
|
|
1819
|
+
if (!o2) return;
|
|
1820
|
+
const c2 = f(o2, { list: s2 });
|
|
1821
|
+
if (!t2) return c2;
|
|
1822
|
+
for (const [e3] of p(c2)) {
|
|
1823
|
+
if ("pseudo-class" !== e3.type || !e3.argument) continue;
|
|
1824
|
+
if (!n.has(e3.name)) continue;
|
|
1825
|
+
let t3 = e3.argument;
|
|
1826
|
+
const s3 = r[e3.name];
|
|
1827
|
+
if (s3) {
|
|
1828
|
+
const n2 = s3.exec(t3);
|
|
1829
|
+
if (!n2) continue;
|
|
1830
|
+
Object.assign(e3, n2.groups), t3 = n2.groups.subtree;
|
|
1627
1831
|
}
|
|
1832
|
+
t3 && Object.assign(e3, { subtree: m(t3, { recursive: true, list: true }) });
|
|
1628
1833
|
}
|
|
1629
|
-
return
|
|
1834
|
+
return c2;
|
|
1630
1835
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1836
|
+
|
|
1837
|
+
// lsp/server/src/selectorMatcher.ts
|
|
1838
|
+
var MUSTACHE_KIND_PSEUDO = /* @__PURE__ */ new Set([
|
|
1839
|
+
"m-section",
|
|
1840
|
+
"m-inverted",
|
|
1841
|
+
"m-variable",
|
|
1842
|
+
"m-raw",
|
|
1843
|
+
"m-comment",
|
|
1844
|
+
"m-partial"
|
|
1845
|
+
]);
|
|
1846
|
+
function preprocessMustacheLiterals(raw) {
|
|
1847
|
+
let out = "";
|
|
1848
|
+
let i2 = 0;
|
|
1849
|
+
const len = raw.length;
|
|
1850
|
+
while (i2 < len) {
|
|
1851
|
+
const ch = raw[i2];
|
|
1852
|
+
if (ch === '"' || ch === "'") {
|
|
1853
|
+
out += ch;
|
|
1854
|
+
i2++;
|
|
1855
|
+
while (i2 < len && raw[i2] !== ch) {
|
|
1856
|
+
if (raw[i2] === "\\" && i2 + 1 < len) {
|
|
1857
|
+
out += raw[i2] + raw[i2 + 1];
|
|
1858
|
+
i2 += 2;
|
|
1859
|
+
} else {
|
|
1860
|
+
out += raw[i2];
|
|
1861
|
+
i2++;
|
|
1862
|
+
}
|
|
1648
1863
|
}
|
|
1649
|
-
if (
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1864
|
+
if (i2 < len) {
|
|
1865
|
+
out += raw[i2];
|
|
1866
|
+
i2++;
|
|
1867
|
+
}
|
|
1868
|
+
continue;
|
|
1869
|
+
}
|
|
1870
|
+
if (ch !== "{" || raw[i2 + 1] !== "{") {
|
|
1871
|
+
out += ch;
|
|
1872
|
+
i2++;
|
|
1873
|
+
continue;
|
|
1874
|
+
}
|
|
1875
|
+
if (raw[i2 + 2] === "{") {
|
|
1876
|
+
const end2 = raw.indexOf("}}}", i2 + 3);
|
|
1877
|
+
if (end2 < 0) return null;
|
|
1878
|
+
const inner = raw.slice(i2 + 3, end2).trim();
|
|
1879
|
+
if (inner.length === 0) return null;
|
|
1880
|
+
out += `:m-raw(${inner})`;
|
|
1881
|
+
i2 = end2 + 3;
|
|
1882
|
+
continue;
|
|
1883
|
+
}
|
|
1884
|
+
const end = raw.indexOf("}}", i2 + 2);
|
|
1885
|
+
if (end < 0) return null;
|
|
1886
|
+
const body = raw.slice(i2 + 2, end);
|
|
1887
|
+
i2 = end + 2;
|
|
1888
|
+
const sigil = body.trimStart()[0];
|
|
1889
|
+
const content = body.replace(/^\s*[#^!>/]\s*/, "").replace(/^\s+|\s+$/g, "");
|
|
1890
|
+
switch (sigil) {
|
|
1891
|
+
case "#":
|
|
1892
|
+
if (content.length === 0) return null;
|
|
1893
|
+
out += `:m-section(${content})`;
|
|
1894
|
+
break;
|
|
1895
|
+
case "^":
|
|
1896
|
+
if (content.length === 0) return null;
|
|
1897
|
+
out += `:m-inverted(${content})`;
|
|
1898
|
+
break;
|
|
1899
|
+
case "!":
|
|
1900
|
+
if (content.length === 0) return null;
|
|
1901
|
+
out += `:m-comment(${content})`;
|
|
1902
|
+
break;
|
|
1903
|
+
case ">":
|
|
1904
|
+
if (content.length === 0) return null;
|
|
1905
|
+
out += `:m-partial(${content})`;
|
|
1906
|
+
break;
|
|
1907
|
+
case "/":
|
|
1908
|
+
return null;
|
|
1909
|
+
case "=":
|
|
1910
|
+
return null;
|
|
1911
|
+
default: {
|
|
1912
|
+
const path5 = body.trim();
|
|
1913
|
+
if (path5.length === 0) return null;
|
|
1914
|
+
out += `:m-variable(${path5})`;
|
|
1915
|
+
break;
|
|
1654
1916
|
}
|
|
1655
1917
|
}
|
|
1656
1918
|
}
|
|
1657
|
-
return
|
|
1919
|
+
return out;
|
|
1658
1920
|
}
|
|
1659
1921
|
function parseSelector(raw) {
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
alternatives.push(alt);
|
|
1669
|
-
}
|
|
1670
|
-
return { alternatives };
|
|
1671
|
-
}
|
|
1672
|
-
function parseSingleSelector(raw) {
|
|
1673
|
-
const segments = [];
|
|
1674
|
-
let i = 0;
|
|
1675
|
-
let nextCombinator = "descendant";
|
|
1676
|
-
while (i < raw.length) {
|
|
1677
|
-
while (i < raw.length && raw[i] === " ") i++;
|
|
1678
|
-
if (i >= raw.length) break;
|
|
1679
|
-
if (raw[i] === ">") {
|
|
1680
|
-
if (segments.length === 0) return null;
|
|
1681
|
-
nextCombinator = "child";
|
|
1682
|
-
i++;
|
|
1683
|
-
while (i < raw.length && raw[i] === " ") i++;
|
|
1684
|
-
if (i >= raw.length) return null;
|
|
1685
|
-
continue;
|
|
1686
|
-
}
|
|
1687
|
-
const pos = { i };
|
|
1688
|
-
const segment = parseOneSegment(raw, pos);
|
|
1689
|
-
if (!segment) return null;
|
|
1690
|
-
i = pos.i;
|
|
1691
|
-
segment.combinator = nextCombinator;
|
|
1692
|
-
nextCombinator = "descendant";
|
|
1693
|
-
segments.push(segment);
|
|
1922
|
+
if (typeof raw !== "string" || raw.trim() === "") return null;
|
|
1923
|
+
const preprocessed = preprocessMustacheLiterals(raw);
|
|
1924
|
+
if (preprocessed === null) return null;
|
|
1925
|
+
let ast;
|
|
1926
|
+
try {
|
|
1927
|
+
ast = m(preprocessed);
|
|
1928
|
+
} catch {
|
|
1929
|
+
return null;
|
|
1694
1930
|
}
|
|
1695
|
-
if (
|
|
1696
|
-
|
|
1931
|
+
if (!ast) return null;
|
|
1932
|
+
const tops = ast.type === "list" ? ast.list : [ast];
|
|
1933
|
+
const alts = [];
|
|
1934
|
+
for (const top of tops) {
|
|
1935
|
+
const segments = [];
|
|
1936
|
+
if (!collectSegments(top, "descendant", segments)) return null;
|
|
1937
|
+
if (segments.length === 0) return null;
|
|
1938
|
+
alts.push(segments);
|
|
1939
|
+
}
|
|
1940
|
+
return alts.length > 0 ? alts : null;
|
|
1941
|
+
}
|
|
1942
|
+
function collectSegments(ast, combinator, out) {
|
|
1943
|
+
if (ast.type === "complex") {
|
|
1944
|
+
const mapped = mapCombinator(ast.combinator);
|
|
1945
|
+
if (!mapped) return false;
|
|
1946
|
+
return collectSegments(ast.left, "descendant", out) && collectSegments(ast.right, mapped, out);
|
|
1947
|
+
}
|
|
1948
|
+
if (ast.type === "list" || ast.type === "relative") return false;
|
|
1949
|
+
const segment = segmentFromCompound(ast);
|
|
1950
|
+
if (!segment) return false;
|
|
1951
|
+
segment.combinator = combinator;
|
|
1952
|
+
out.push(segment);
|
|
1953
|
+
return true;
|
|
1697
1954
|
}
|
|
1698
|
-
function
|
|
1955
|
+
function mapCombinator(c2) {
|
|
1956
|
+
const trimmed = c2.trim();
|
|
1957
|
+
if (trimmed === "") return "descendant";
|
|
1958
|
+
if (trimmed === ">") return "child";
|
|
1959
|
+
return null;
|
|
1960
|
+
}
|
|
1961
|
+
function segmentFromCompound(ast) {
|
|
1962
|
+
const tokens = ast.type === "compound" ? ast.list : [ast];
|
|
1699
1963
|
let kind;
|
|
1700
|
-
let name;
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1964
|
+
let name = null;
|
|
1965
|
+
let pathRegex;
|
|
1966
|
+
const attributes = [];
|
|
1967
|
+
const descendantChecks = [];
|
|
1968
|
+
const forbidChange = (requested) => {
|
|
1969
|
+
if (kind === void 0) return false;
|
|
1970
|
+
if (kind === requested) return false;
|
|
1971
|
+
return true;
|
|
1972
|
+
};
|
|
1973
|
+
for (const token of tokens) {
|
|
1974
|
+
switch (token.type) {
|
|
1975
|
+
case "type":
|
|
1976
|
+
if (forbidChange("html")) return null;
|
|
1977
|
+
kind = "html";
|
|
1978
|
+
name = token.name.toLowerCase();
|
|
1979
|
+
break;
|
|
1980
|
+
case "universal":
|
|
1981
|
+
if (forbidChange("html")) return null;
|
|
1982
|
+
kind = "html";
|
|
1983
|
+
name = null;
|
|
1984
|
+
break;
|
|
1985
|
+
case "class":
|
|
1986
|
+
if (forbidChange("html")) return null;
|
|
1987
|
+
kind = "html";
|
|
1988
|
+
attributes.push(classConstraint(token, false));
|
|
1989
|
+
break;
|
|
1990
|
+
case "id":
|
|
1991
|
+
if (forbidChange("html")) return null;
|
|
1992
|
+
kind = "html";
|
|
1993
|
+
attributes.push(idConstraint(token, false));
|
|
1994
|
+
break;
|
|
1995
|
+
case "attribute": {
|
|
1996
|
+
if (forbidChange("html")) return null;
|
|
1997
|
+
if (kind === void 0) kind = "html";
|
|
1998
|
+
const c2 = attributeConstraint(token, false);
|
|
1999
|
+
if (!c2) return null;
|
|
2000
|
+
attributes.push(c2);
|
|
2001
|
+
break;
|
|
2002
|
+
}
|
|
2003
|
+
case "pseudo-class": {
|
|
2004
|
+
if (MUSTACHE_KIND_PSEUDO.has(token.name)) {
|
|
2005
|
+
const mustacheKind = mustacheKindFromMarker(token.name);
|
|
2006
|
+
if (mustacheKind === null) return null;
|
|
2007
|
+
if (forbidChange(mustacheKind)) return null;
|
|
2008
|
+
kind = mustacheKind;
|
|
2009
|
+
const glob = parseGlob(token.argument ?? "");
|
|
2010
|
+
name = glob.name;
|
|
2011
|
+
pathRegex = glob.pathRegex;
|
|
2012
|
+
break;
|
|
2013
|
+
}
|
|
2014
|
+
if (token.name === "has") {
|
|
2015
|
+
const sel = subtreeToSelector(token.subtree);
|
|
2016
|
+
if (!sel) return null;
|
|
2017
|
+
descendantChecks.push({ selector: sel, negated: false });
|
|
2018
|
+
break;
|
|
2019
|
+
}
|
|
2020
|
+
if (token.name === "not") {
|
|
2021
|
+
if (!applyNegatedSubtree(token.subtree, attributes, descendantChecks)) return null;
|
|
2022
|
+
break;
|
|
2023
|
+
}
|
|
2024
|
+
return null;
|
|
2025
|
+
}
|
|
2026
|
+
default:
|
|
2027
|
+
return null;
|
|
2028
|
+
}
|
|
1719
2029
|
}
|
|
1720
|
-
if (
|
|
2030
|
+
if (kind === void 0) {
|
|
1721
2031
|
kind = "html";
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
2032
|
+
}
|
|
2033
|
+
const isHtml = kind === "html";
|
|
2034
|
+
const finalAttrs = isHtml ? attributes : [];
|
|
2035
|
+
return { kind, name, pathRegex, attributes: finalAttrs, descendantChecks, combinator: "descendant" };
|
|
2036
|
+
}
|
|
2037
|
+
function mustacheKindFromMarker(name) {
|
|
2038
|
+
switch (name) {
|
|
2039
|
+
case "m-section":
|
|
2040
|
+
return "section";
|
|
2041
|
+
case "m-inverted":
|
|
2042
|
+
return "inverted";
|
|
2043
|
+
case "m-variable":
|
|
2044
|
+
return "variable";
|
|
2045
|
+
case "m-raw":
|
|
2046
|
+
return "raw";
|
|
2047
|
+
case "m-comment":
|
|
2048
|
+
return "comment";
|
|
2049
|
+
case "m-partial":
|
|
2050
|
+
return "partial";
|
|
2051
|
+
default:
|
|
2052
|
+
return null;
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
function parseGlob(arg) {
|
|
2056
|
+
const trimmed = arg.trim();
|
|
2057
|
+
if (trimmed === "" || trimmed === "*") {
|
|
2058
|
+
return { name: null };
|
|
2059
|
+
}
|
|
2060
|
+
if (!trimmed.includes("*")) {
|
|
2061
|
+
return { name: trimmed.toLowerCase() };
|
|
2062
|
+
}
|
|
2063
|
+
const escaped = trimmed.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
2064
|
+
const pathRegex = new RegExp(`^${escaped}$`, "i");
|
|
2065
|
+
return { name: trimmed.toLowerCase(), pathRegex };
|
|
2066
|
+
}
|
|
2067
|
+
function attributeConstraint(token, negated) {
|
|
2068
|
+
const name = token.name.toLowerCase();
|
|
2069
|
+
if (token.operator === void 0) {
|
|
2070
|
+
return { name, op: "=", value: void 0, negated };
|
|
2071
|
+
}
|
|
2072
|
+
let op;
|
|
2073
|
+
switch (token.operator) {
|
|
2074
|
+
case "=":
|
|
2075
|
+
op = "=";
|
|
2076
|
+
break;
|
|
2077
|
+
case "^=":
|
|
2078
|
+
op = "^=";
|
|
2079
|
+
break;
|
|
2080
|
+
case "*=":
|
|
2081
|
+
op = "*=";
|
|
2082
|
+
break;
|
|
2083
|
+
case "$=":
|
|
2084
|
+
op = "$=";
|
|
2085
|
+
break;
|
|
2086
|
+
case "~=":
|
|
2087
|
+
op = "~=";
|
|
2088
|
+
break;
|
|
2089
|
+
default:
|
|
2090
|
+
return null;
|
|
2091
|
+
}
|
|
2092
|
+
return { name, op, value: stripQuotes(token.value ?? ""), negated };
|
|
2093
|
+
}
|
|
2094
|
+
function classConstraint(token, negated) {
|
|
2095
|
+
return { name: "class", op: "~=", value: token.name, negated };
|
|
2096
|
+
}
|
|
2097
|
+
function idConstraint(token, negated) {
|
|
2098
|
+
return { name: "id", op: "=", value: token.name, negated };
|
|
2099
|
+
}
|
|
2100
|
+
function applyNegatedSubtree(subtree, attributes, descendantChecks) {
|
|
2101
|
+
if (!subtree) return false;
|
|
2102
|
+
if (subtree.type === "attribute") {
|
|
2103
|
+
const c2 = attributeConstraint(subtree, true);
|
|
2104
|
+
if (!c2) return false;
|
|
2105
|
+
attributes.push(c2);
|
|
2106
|
+
return true;
|
|
2107
|
+
}
|
|
2108
|
+
if (subtree.type === "class") {
|
|
2109
|
+
attributes.push(classConstraint(subtree, true));
|
|
2110
|
+
return true;
|
|
2111
|
+
}
|
|
2112
|
+
if (subtree.type === "id") {
|
|
2113
|
+
attributes.push(idConstraint(subtree, true));
|
|
2114
|
+
return true;
|
|
2115
|
+
}
|
|
2116
|
+
if (subtree.type === "pseudo-class" && subtree.name === "has") {
|
|
2117
|
+
const sel = subtreeToSelector(subtree.subtree);
|
|
2118
|
+
if (!sel) return false;
|
|
2119
|
+
descendantChecks.push({ selector: sel, negated: true });
|
|
2120
|
+
return true;
|
|
2121
|
+
}
|
|
2122
|
+
return false;
|
|
2123
|
+
}
|
|
2124
|
+
function subtreeToSelector(subtree) {
|
|
2125
|
+
if (!subtree) return null;
|
|
2126
|
+
const tops = subtree.type === "list" ? subtree.list : [subtree];
|
|
2127
|
+
const alts = [];
|
|
2128
|
+
for (const top of tops) {
|
|
2129
|
+
const segments = [];
|
|
2130
|
+
if (!collectSegments(top, "descendant", segments)) return null;
|
|
2131
|
+
if (segments.length === 0) return null;
|
|
2132
|
+
alts.push(segments);
|
|
2133
|
+
}
|
|
2134
|
+
return alts.length > 0 ? alts : null;
|
|
2135
|
+
}
|
|
2136
|
+
function stripQuotes(raw) {
|
|
2137
|
+
if (raw.length < 2) return raw;
|
|
2138
|
+
const first = raw[0];
|
|
2139
|
+
const last = raw[raw.length - 1];
|
|
2140
|
+
if ((first === '"' || first === "'") && first === last) {
|
|
2141
|
+
return raw.slice(1, -1);
|
|
2142
|
+
}
|
|
2143
|
+
return raw;
|
|
2144
|
+
}
|
|
2145
|
+
function ancestorKindForNode(node) {
|
|
2146
|
+
if (HTML_ELEMENT_TYPES.has(node.type)) return "html";
|
|
2147
|
+
if (node.type === "mustache_section") return "section";
|
|
2148
|
+
if (node.type === "mustache_inverted_section") return "inverted";
|
|
2149
|
+
return null;
|
|
2150
|
+
}
|
|
2151
|
+
function getHtmlAttributes(node) {
|
|
1739
2152
|
const startTag = node.children.find(
|
|
1740
|
-
(
|
|
2153
|
+
(c2) => c2.type === "html_start_tag" || c2.type === "html_self_closing_tag"
|
|
1741
2154
|
);
|
|
1742
2155
|
if (!startTag) return [];
|
|
1743
2156
|
const attrs = [];
|
|
1744
2157
|
for (const child of startTag.children) {
|
|
1745
|
-
if (child.type
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
}
|
|
2158
|
+
if (child.type !== "html_attribute") continue;
|
|
2159
|
+
let attrName = "";
|
|
2160
|
+
let attrValue;
|
|
2161
|
+
for (const part of child.children) {
|
|
2162
|
+
if (part.type === "html_attribute_name") {
|
|
2163
|
+
attrName = part.text.toLowerCase();
|
|
2164
|
+
} else if (part.type === "html_quoted_attribute_value") {
|
|
2165
|
+
attrValue = part.text.replace(/^["']|["']$/g, "");
|
|
2166
|
+
} else if (part.type === "html_attribute_value") {
|
|
2167
|
+
attrValue = part.text;
|
|
1756
2168
|
}
|
|
1757
|
-
if (attrName) attrs.push({ name: attrName, value: attrValue });
|
|
1758
2169
|
}
|
|
2170
|
+
if (attrName) attrs.push({ name: attrName, value: attrValue });
|
|
1759
2171
|
}
|
|
1760
2172
|
return attrs;
|
|
1761
2173
|
}
|
|
2174
|
+
function matchesAttributeValue(has, c2) {
|
|
2175
|
+
if (has === void 0 || c2.value === void 0) return false;
|
|
2176
|
+
const v = c2.value;
|
|
2177
|
+
if (v === "") return false;
|
|
2178
|
+
switch (c2.op) {
|
|
2179
|
+
case "=":
|
|
2180
|
+
return has === v;
|
|
2181
|
+
case "^=":
|
|
2182
|
+
return has.startsWith(v);
|
|
2183
|
+
case "*=":
|
|
2184
|
+
return has.includes(v);
|
|
2185
|
+
case "$=":
|
|
2186
|
+
return has.endsWith(v);
|
|
2187
|
+
case "~=":
|
|
2188
|
+
return has.split(/\s+/).includes(v);
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
1762
2191
|
function checkAttributes(node, constraints) {
|
|
1763
2192
|
if (constraints.length === 0) return true;
|
|
1764
|
-
const nodeAttrs =
|
|
1765
|
-
for (const
|
|
1766
|
-
const found = nodeAttrs.find((
|
|
1767
|
-
if (
|
|
1768
|
-
if (found)
|
|
1769
|
-
|
|
1770
|
-
if (
|
|
1771
|
-
|
|
2193
|
+
const nodeAttrs = getHtmlAttributes(node);
|
|
2194
|
+
for (const c2 of constraints) {
|
|
2195
|
+
const found = nodeAttrs.find((a2) => a2.name === c2.name);
|
|
2196
|
+
if (c2.negated) {
|
|
2197
|
+
if (!found) continue;
|
|
2198
|
+
if (c2.value === void 0) return false;
|
|
2199
|
+
if (matchesAttributeValue(found.value, c2)) return false;
|
|
2200
|
+
continue;
|
|
2201
|
+
}
|
|
2202
|
+
if (c2.value === void 0) {
|
|
1772
2203
|
if (!found) return false;
|
|
2204
|
+
continue;
|
|
1773
2205
|
}
|
|
2206
|
+
if (!found || !matchesAttributeValue(found.value, c2)) return false;
|
|
1774
2207
|
}
|
|
1775
2208
|
return true;
|
|
1776
2209
|
}
|
|
1777
|
-
function
|
|
1778
|
-
if (
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
if (tagName !== segment.name) return false;
|
|
1783
|
-
}
|
|
1784
|
-
return checkAttributes(node, segment.attributes);
|
|
1785
|
-
}
|
|
1786
|
-
if (!MUSTACHE_SECTION_TYPES.has(node.type)) return false;
|
|
1787
|
-
if (segment.name !== null) {
|
|
1788
|
-
const sectionName = getSectionName(node)?.toLowerCase();
|
|
1789
|
-
if (sectionName !== segment.name) return false;
|
|
2210
|
+
function checkDescendants(node, checks) {
|
|
2211
|
+
if (checks.length === 0) return true;
|
|
2212
|
+
for (const check of checks) {
|
|
2213
|
+
const present = hasDescendantMatch(node, check.selector);
|
|
2214
|
+
if (check.negated ? present : !present) return false;
|
|
1790
2215
|
}
|
|
1791
2216
|
return true;
|
|
1792
2217
|
}
|
|
2218
|
+
function hasDescendantMatch(node, selector) {
|
|
2219
|
+
for (const child of node.children) {
|
|
2220
|
+
if (matchSelector(child, selector).length > 0) return true;
|
|
2221
|
+
}
|
|
2222
|
+
return false;
|
|
2223
|
+
}
|
|
2224
|
+
function matchesName(actual, segment) {
|
|
2225
|
+
if (segment.name === null) return true;
|
|
2226
|
+
if (actual === null) return false;
|
|
2227
|
+
if (segment.pathRegex) return segment.pathRegex.test(actual);
|
|
2228
|
+
return actual === segment.name;
|
|
2229
|
+
}
|
|
2230
|
+
function nodeMatchesSegment(node, segment) {
|
|
2231
|
+
switch (segment.kind) {
|
|
2232
|
+
case "html": {
|
|
2233
|
+
if (!HTML_ELEMENT_TYPES.has(node.type)) return false;
|
|
2234
|
+
if (segment.name !== null) {
|
|
2235
|
+
const tagName = getTagName(node)?.toLowerCase();
|
|
2236
|
+
if (tagName !== segment.name) return false;
|
|
2237
|
+
}
|
|
2238
|
+
return checkAttributes(node, segment.attributes) && checkDescendants(node, segment.descendantChecks);
|
|
2239
|
+
}
|
|
2240
|
+
case "section":
|
|
2241
|
+
if (node.type !== "mustache_section") return false;
|
|
2242
|
+
if (!matchesName(getSectionName(node)?.toLowerCase() ?? null, segment)) return false;
|
|
2243
|
+
return checkDescendants(node, segment.descendantChecks);
|
|
2244
|
+
case "inverted":
|
|
2245
|
+
if (node.type !== "mustache_inverted_section") return false;
|
|
2246
|
+
if (!matchesName(getSectionName(node)?.toLowerCase() ?? null, segment)) return false;
|
|
2247
|
+
return checkDescendants(node, segment.descendantChecks);
|
|
2248
|
+
case "variable":
|
|
2249
|
+
if (node.type !== "mustache_interpolation") return false;
|
|
2250
|
+
if (!matchesName(getInterpolationPath(node)?.toLowerCase() ?? null, segment)) return false;
|
|
2251
|
+
return checkDescendants(node, segment.descendantChecks);
|
|
2252
|
+
case "raw":
|
|
2253
|
+
if (node.type !== "mustache_triple") return false;
|
|
2254
|
+
if (!matchesName(getInterpolationPath(node)?.toLowerCase() ?? null, segment)) return false;
|
|
2255
|
+
return checkDescendants(node, segment.descendantChecks);
|
|
2256
|
+
case "comment":
|
|
2257
|
+
if (node.type !== "mustache_comment") return false;
|
|
2258
|
+
if (!matchesName(getCommentContent(node)?.toLowerCase() ?? null, segment)) return false;
|
|
2259
|
+
return checkDescendants(node, segment.descendantChecks);
|
|
2260
|
+
case "partial":
|
|
2261
|
+
if (node.type !== "mustache_partial") return false;
|
|
2262
|
+
if (!matchesName(getPartialName(node)?.toLowerCase() ?? null, segment)) return false;
|
|
2263
|
+
return checkDescendants(node, segment.descendantChecks);
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
1793
2266
|
function checkAncestors(ancestors, segments, segIdx, childCombinator) {
|
|
1794
2267
|
if (segIdx < 0) return true;
|
|
1795
2268
|
const segment = segments[segIdx];
|
|
2269
|
+
const ancestorKind = ancestorKindForSegment(segment);
|
|
2270
|
+
if (ancestorKind === null) return false;
|
|
1796
2271
|
if (childCombinator === "child") {
|
|
1797
|
-
for (let
|
|
1798
|
-
const entry = ancestors[
|
|
1799
|
-
if (entry.kind !==
|
|
1800
|
-
if (
|
|
1801
|
-
if (segment.kind === "html" && segment.attributes
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
return checkAncestors(ancestors.slice(0, a), segments, segIdx - 1, segment.combinator);
|
|
2272
|
+
for (let a2 = ancestors.length - 1; a2 >= 0; a2--) {
|
|
2273
|
+
const entry = ancestors[a2];
|
|
2274
|
+
if (entry.kind !== ancestorKind) continue;
|
|
2275
|
+
if (!matchesName(entry.name, segment)) return false;
|
|
2276
|
+
if (segment.kind === "html" && !checkAttributes(entry.node, segment.attributes)) return false;
|
|
2277
|
+
if (!checkDescendants(entry.node, segment.descendantChecks)) return false;
|
|
2278
|
+
return checkAncestors(ancestors.slice(0, a2), segments, segIdx - 1, segment.combinator);
|
|
1805
2279
|
}
|
|
1806
2280
|
return false;
|
|
1807
2281
|
}
|
|
1808
|
-
for (let
|
|
1809
|
-
const entry = ancestors[
|
|
1810
|
-
if (entry.kind !==
|
|
1811
|
-
if (
|
|
1812
|
-
if (segment.kind === "html" && segment.attributes
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
if (checkAncestors(ancestors.slice(0, a), segments, segIdx - 1, segment.combinator)) {
|
|
2282
|
+
for (let a2 = ancestors.length - 1; a2 >= 0; a2--) {
|
|
2283
|
+
const entry = ancestors[a2];
|
|
2284
|
+
if (entry.kind !== ancestorKind) continue;
|
|
2285
|
+
if (!matchesName(entry.name, segment)) continue;
|
|
2286
|
+
if (segment.kind === "html" && !checkAttributes(entry.node, segment.attributes)) continue;
|
|
2287
|
+
if (!checkDescendants(entry.node, segment.descendantChecks)) continue;
|
|
2288
|
+
if (checkAncestors(ancestors.slice(0, a2), segments, segIdx - 1, segment.combinator)) {
|
|
1816
2289
|
return true;
|
|
1817
2290
|
}
|
|
1818
2291
|
}
|
|
1819
2292
|
return false;
|
|
1820
2293
|
}
|
|
2294
|
+
function ancestorKindForSegment(segment) {
|
|
2295
|
+
if (segment.kind === "html") return "html";
|
|
2296
|
+
if (segment.kind === "section") return "section";
|
|
2297
|
+
if (segment.kind === "inverted") return "inverted";
|
|
2298
|
+
return null;
|
|
2299
|
+
}
|
|
1821
2300
|
function getReportNode(node) {
|
|
1822
2301
|
if (HTML_ELEMENT_TYPES.has(node.type)) {
|
|
1823
2302
|
const startTag = node.children.find(
|
|
1824
|
-
(
|
|
2303
|
+
(c2) => c2.type === "html_start_tag" || c2.type === "html_self_closing_tag"
|
|
1825
2304
|
);
|
|
1826
2305
|
return startTag ?? node;
|
|
1827
2306
|
}
|
|
1828
|
-
if (
|
|
2307
|
+
if (node.type === "mustache_section" || node.type === "mustache_inverted_section") {
|
|
1829
2308
|
const begin = node.children.find(
|
|
1830
|
-
(
|
|
2309
|
+
(c2) => c2.type === "mustache_section_begin" || c2.type === "mustache_inverted_section_begin"
|
|
1831
2310
|
);
|
|
1832
2311
|
return begin ?? node;
|
|
1833
2312
|
}
|
|
1834
2313
|
return node;
|
|
1835
2314
|
}
|
|
1836
|
-
function matchAlternative(rootNode,
|
|
2315
|
+
function matchAlternative(rootNode, segments) {
|
|
1837
2316
|
const results = [];
|
|
1838
|
-
const lastSegment =
|
|
2317
|
+
const lastSegment = segments[segments.length - 1];
|
|
1839
2318
|
function walk(node, ancestors) {
|
|
1840
2319
|
if (nodeMatchesSegment(node, lastSegment)) {
|
|
1841
|
-
if (
|
|
2320
|
+
if (segments.length === 1 || checkAncestors(ancestors, segments, segments.length - 2, lastSegment.combinator)) {
|
|
1842
2321
|
results.push(getReportNode(node));
|
|
1843
2322
|
}
|
|
1844
2323
|
}
|
|
1845
2324
|
let newAncestors = ancestors;
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
} else if (MUSTACHE_SECTION_TYPES.has(node.type)) {
|
|
1852
|
-
const sectionName = getSectionName(node)?.toLowerCase();
|
|
1853
|
-
if (sectionName) {
|
|
1854
|
-
newAncestors = [...ancestors, { kind: "mustache", name: sectionName, node }];
|
|
2325
|
+
const ancestorKind = ancestorKindForNode(node);
|
|
2326
|
+
if (ancestorKind !== null) {
|
|
2327
|
+
const name = ancestorKind === "html" ? getTagName(node)?.toLowerCase() : getSectionName(node)?.toLowerCase();
|
|
2328
|
+
if (name) {
|
|
2329
|
+
newAncestors = [...ancestors, { kind: ancestorKind, name, node }];
|
|
1855
2330
|
}
|
|
1856
2331
|
}
|
|
1857
|
-
for (const child of node.children)
|
|
1858
|
-
walk(child, newAncestors);
|
|
1859
|
-
}
|
|
2332
|
+
for (const child of node.children) walk(child, newAncestors);
|
|
1860
2333
|
}
|
|
1861
2334
|
walk(rootNode, []);
|
|
1862
2335
|
return results;
|
|
@@ -1864,7 +2337,7 @@ function matchAlternative(rootNode, alt) {
|
|
|
1864
2337
|
function matchSelector(rootNode, selector) {
|
|
1865
2338
|
const allResults = [];
|
|
1866
2339
|
const seen = /* @__PURE__ */ new Set();
|
|
1867
|
-
for (const alt of selector
|
|
2340
|
+
for (const alt of selector) {
|
|
1868
2341
|
for (const node of matchAlternative(rootNode, alt)) {
|
|
1869
2342
|
if (!seen.has(node)) {
|
|
1870
2343
|
seen.add(node);
|
|
@@ -1883,7 +2356,7 @@ var ERROR_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
|
1883
2356
|
]);
|
|
1884
2357
|
function errorMessageForNode(nodeType, node) {
|
|
1885
2358
|
if (nodeType === "mustache_erroneous_section_end" || nodeType === "mustache_erroneous_inverted_section_end") {
|
|
1886
|
-
const tagNameNode = node.children.find((
|
|
2359
|
+
const tagNameNode = node.children.find((c2) => c2.type === "mustache_erroneous_tag_name");
|
|
1887
2360
|
return `Mismatched mustache section: {{/${tagNameNode?.text || "?"}}}`;
|
|
1888
2361
|
}
|
|
1889
2362
|
if (nodeType === "ERROR") {
|
|
@@ -1891,8 +2364,17 @@ function errorMessageForNode(nodeType, node) {
|
|
|
1891
2364
|
}
|
|
1892
2365
|
return `Missing ${nodeType}`;
|
|
1893
2366
|
}
|
|
1894
|
-
function
|
|
1895
|
-
|
|
2367
|
+
function resolveRuleConfig(rules, ruleName) {
|
|
2368
|
+
const entry = rules?.[ruleName];
|
|
2369
|
+
let severity;
|
|
2370
|
+
if (entry === void 0) {
|
|
2371
|
+
severity = RULE_DEFAULTS[ruleName] ?? "off";
|
|
2372
|
+
} else if (typeof entry === "string") {
|
|
2373
|
+
severity = entry;
|
|
2374
|
+
} else {
|
|
2375
|
+
severity = entry.severity;
|
|
2376
|
+
}
|
|
2377
|
+
return { severity, entry };
|
|
1896
2378
|
}
|
|
1897
2379
|
function parseDisableDirective(node, customRuleIds) {
|
|
1898
2380
|
if (node.type !== "html_comment" && node.type !== "mustache_comment") return null;
|
|
@@ -1954,7 +2436,7 @@ function collectErrors(tree, rules, customTagNames, customRules) {
|
|
|
1954
2436
|
for (const error of unclosedErrors) {
|
|
1955
2437
|
errors.push({ node: error.node, message: error.message });
|
|
1956
2438
|
}
|
|
1957
|
-
const customRuleIds = customRules ? new Set(customRules.map((
|
|
2439
|
+
const customRuleIds = customRules ? new Set(customRules.map((r2) => r2.id)) : void 0;
|
|
1958
2440
|
const disabledRules = collectDisabledRules(tree.rootNode, customRuleIds);
|
|
1959
2441
|
const effectiveRules = { ...rules };
|
|
1960
2442
|
for (const rule of disabledRules) {
|
|
@@ -1969,12 +2451,19 @@ function collectErrors(tree, rules, customTagNames, customRules) {
|
|
|
1969
2451
|
{ rule: "duplicateAttributes", errors: () => checkDuplicateAttributes(tree.rootNode) },
|
|
1970
2452
|
{ rule: "unescapedEntities", errors: () => checkUnescapedEntities(tree.rootNode) },
|
|
1971
2453
|
{ rule: "preferMustacheComments", errors: () => checkHtmlComments(tree.rootNode) },
|
|
1972
|
-
{ rule: "unrecognizedHtmlTags", errors: () => checkUnrecognizedHtmlTags(tree.rootNode, customTagNames) }
|
|
2454
|
+
{ rule: "unrecognizedHtmlTags", errors: () => checkUnrecognizedHtmlTags(tree.rootNode, customTagNames) },
|
|
2455
|
+
{
|
|
2456
|
+
rule: "elementContentTooLong",
|
|
2457
|
+
errors: (entry) => {
|
|
2458
|
+
const elements = (entry && typeof entry === "object" ? entry.elements : void 0) ?? [];
|
|
2459
|
+
return checkElementContentTooLong(tree.rootNode, elements);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
1973
2462
|
];
|
|
1974
2463
|
for (const { rule, errors: getErrors } of ruleChecks) {
|
|
1975
|
-
const severity =
|
|
2464
|
+
const { severity, entry } = resolveRuleConfig(effectiveRules, rule);
|
|
1976
2465
|
if (severity === "off") continue;
|
|
1977
|
-
for (const error of getErrors()) {
|
|
2466
|
+
for (const error of getErrors(entry)) {
|
|
1978
2467
|
errors.push({
|
|
1979
2468
|
node: error.node,
|
|
1980
2469
|
message: error.message,
|
|
@@ -1999,7 +2488,7 @@ function collectErrors(tree, rules, customTagNames, customRules) {
|
|
|
1999
2488
|
}
|
|
2000
2489
|
}
|
|
2001
2490
|
return errors.filter(
|
|
2002
|
-
(
|
|
2491
|
+
(e2) => !(e2.message.includes("HTML comment found") && parseDisableDirective(e2.node, customRuleIds) !== null)
|
|
2003
2492
|
);
|
|
2004
2493
|
}
|
|
2005
2494
|
|
|
@@ -2029,12 +2518,12 @@ function formatError(error, source) {
|
|
|
2029
2518
|
const contextStart = Math.max(0, errorLine - 2);
|
|
2030
2519
|
const contextEnd = Math.min(lines.length - 1, error.endLine - 1);
|
|
2031
2520
|
const gutterWidth = String(contextEnd + 1).length;
|
|
2032
|
-
const pad = (
|
|
2521
|
+
const pad = (n2) => String(n2).padStart(gutterWidth);
|
|
2033
2522
|
const outputLines = [header];
|
|
2034
2523
|
outputLines.push(source_default.dim(" ".repeat(gutterWidth) + " |"));
|
|
2035
|
-
for (let
|
|
2036
|
-
const lineNum =
|
|
2037
|
-
outputLines.push(source_default.dim(`${pad(lineNum)} |`) + " " + lines[
|
|
2524
|
+
for (let i2 = contextStart; i2 <= contextEnd; i2++) {
|
|
2525
|
+
const lineNum = i2 + 1;
|
|
2526
|
+
outputLines.push(source_default.dim(`${pad(lineNum)} |`) + " " + lines[i2]);
|
|
2038
2527
|
}
|
|
2039
2528
|
const lastErrorLineIdx = error.endLine - 1;
|
|
2040
2529
|
const lastLine = lines[lastErrorLineIdx] || "";
|
|
@@ -2108,7 +2597,7 @@ function resolveFiles(cliPatterns) {
|
|
|
2108
2597
|
return { files: [], config };
|
|
2109
2598
|
}
|
|
2110
2599
|
let files = expandGlobs(patterns);
|
|
2111
|
-
files = files.filter((
|
|
2600
|
+
files = files.filter((f2) => !DEFAULT_EXCLUDE_SEGMENTS.some((seg) => f2.includes(seg)));
|
|
2112
2601
|
if (config?.exclude && config.exclude.length > 0) {
|
|
2113
2602
|
const cwd = process.cwd();
|
|
2114
2603
|
const excludeSet = /* @__PURE__ */ new Set();
|
|
@@ -2121,7 +2610,7 @@ function resolveFiles(cliPatterns) {
|
|
|
2121
2610
|
}
|
|
2122
2611
|
}
|
|
2123
2612
|
}
|
|
2124
|
-
files = files.filter((
|
|
2613
|
+
files = files.filter((f2) => !excludeSet.has(f2));
|
|
2125
2614
|
}
|
|
2126
2615
|
return { files, config };
|
|
2127
2616
|
}
|
|
@@ -2133,13 +2622,13 @@ function applyFixes(source, errors) {
|
|
|
2133
2622
|
}
|
|
2134
2623
|
}
|
|
2135
2624
|
if (replacements.length === 0) return source;
|
|
2136
|
-
replacements.sort((
|
|
2625
|
+
replacements.sort((a2, b) => b.startIndex - a2.startIndex);
|
|
2137
2626
|
let result = source;
|
|
2138
2627
|
let minIndex = Infinity;
|
|
2139
|
-
for (const
|
|
2140
|
-
if (
|
|
2141
|
-
result = result.slice(0,
|
|
2142
|
-
minIndex =
|
|
2628
|
+
for (const r2 of replacements) {
|
|
2629
|
+
if (r2.endIndex > minIndex) continue;
|
|
2630
|
+
result = result.slice(0, r2.startIndex) + r2.newText + result.slice(r2.endIndex);
|
|
2631
|
+
minIndex = r2.startIndex;
|
|
2143
2632
|
}
|
|
2144
2633
|
return result;
|
|
2145
2634
|
}
|
|
@@ -2168,7 +2657,7 @@ async function run(args) {
|
|
|
2168
2657
|
return 0;
|
|
2169
2658
|
}
|
|
2170
2659
|
const fixMode = args.includes("--fix");
|
|
2171
|
-
const patterns = args.filter((
|
|
2660
|
+
const patterns = args.filter((a2) => a2 !== "--fix");
|
|
2172
2661
|
const { files, config } = resolveFiles(patterns);
|
|
2173
2662
|
if (files.length === 0) {
|
|
2174
2663
|
if (patterns.length === 0 && (!config?.include || config.include.length === 0)) {
|
|
@@ -2177,8 +2666,8 @@ async function run(args) {
|
|
|
2177
2666
|
}
|
|
2178
2667
|
const displayPatterns = patterns.length > 0 ? patterns : config?.include ?? [];
|
|
2179
2668
|
console.error(source_default.yellow("No files matched the given patterns:"));
|
|
2180
|
-
for (const
|
|
2181
|
-
console.error(source_default.yellow(` ${
|
|
2669
|
+
for (const p2 of displayPatterns) {
|
|
2670
|
+
console.error(source_default.yellow(` ${p2}`));
|
|
2182
2671
|
}
|
|
2183
2672
|
return 1;
|
|
2184
2673
|
}
|
|
@@ -2189,7 +2678,7 @@ async function run(args) {
|
|
|
2189
2678
|
const cwd = process.cwd();
|
|
2190
2679
|
const errorOutput = [];
|
|
2191
2680
|
const rules = config?.rules;
|
|
2192
|
-
const customTagNames = config?.customTags?.map((
|
|
2681
|
+
const customTagNames = config?.customTags?.map((t2) => t2.name);
|
|
2193
2682
|
const customRules = config?.customRules;
|
|
2194
2683
|
for (const file of files) {
|
|
2195
2684
|
const displayPath = import_node_path.default.relative(cwd, file) || file;
|
|
@@ -2205,8 +2694,8 @@ async function run(args) {
|
|
|
2205
2694
|
}
|
|
2206
2695
|
const tree = parseDocument(source);
|
|
2207
2696
|
const errors = collectErrors2(tree, displayPath, rules, customTagNames, customRules);
|
|
2208
|
-
const fileErrors = errors.filter((
|
|
2209
|
-
const fileWarnings = errors.filter((
|
|
2697
|
+
const fileErrors = errors.filter((e2) => e2.severity !== "warning");
|
|
2698
|
+
const fileWarnings = errors.filter((e2) => e2.severity === "warning");
|
|
2210
2699
|
if (errors.length > 0) {
|
|
2211
2700
|
filesWithErrors++;
|
|
2212
2701
|
totalErrors += fileErrors.length;
|
|
@@ -2271,8 +2760,8 @@ var FullTextDocument = class _FullTextDocument {
|
|
|
2271
2760
|
let lineOffsets = this._lineOffsets;
|
|
2272
2761
|
const addedLineOffsets = computeLineOffsets(change.text, false, startOffset);
|
|
2273
2762
|
if (endLine - startLine === addedLineOffsets.length) {
|
|
2274
|
-
for (let
|
|
2275
|
-
lineOffsets[
|
|
2763
|
+
for (let i2 = 0, len = addedLineOffsets.length; i2 < len; i2++) {
|
|
2764
|
+
lineOffsets[i2 + startLine + 1] = addedLineOffsets[i2];
|
|
2276
2765
|
}
|
|
2277
2766
|
} else {
|
|
2278
2767
|
if (addedLineOffsets.length < 1e4) {
|
|
@@ -2283,8 +2772,8 @@ var FullTextDocument = class _FullTextDocument {
|
|
|
2283
2772
|
}
|
|
2284
2773
|
const diff = change.text.length - (endOffset - startOffset);
|
|
2285
2774
|
if (diff !== 0) {
|
|
2286
|
-
for (let
|
|
2287
|
-
lineOffsets[
|
|
2775
|
+
for (let i2 = startLine + 1 + addedLineOffsets.length, len = lineOffsets.length; i2 < len; i2++) {
|
|
2776
|
+
lineOffsets[i2] = lineOffsets[i2] + diff;
|
|
2288
2777
|
}
|
|
2289
2778
|
}
|
|
2290
2779
|
} else if (_FullTextDocument.isFull(change)) {
|
|
@@ -2371,26 +2860,26 @@ var TextDocument;
|
|
|
2371
2860
|
TextDocument2.update = update;
|
|
2372
2861
|
function applyEdits(document, edits) {
|
|
2373
2862
|
const text2 = document.getText();
|
|
2374
|
-
const sortedEdits = mergeSort(edits.map(getWellformedEdit), (
|
|
2375
|
-
const diff =
|
|
2863
|
+
const sortedEdits = mergeSort(edits.map(getWellformedEdit), (a2, b) => {
|
|
2864
|
+
const diff = a2.range.start.line - b.range.start.line;
|
|
2376
2865
|
if (diff === 0) {
|
|
2377
|
-
return
|
|
2866
|
+
return a2.range.start.character - b.range.start.character;
|
|
2378
2867
|
}
|
|
2379
2868
|
return diff;
|
|
2380
2869
|
});
|
|
2381
2870
|
let lastModifiedOffset = 0;
|
|
2382
2871
|
const spans = [];
|
|
2383
|
-
for (const
|
|
2384
|
-
const startOffset = document.offsetAt(
|
|
2872
|
+
for (const e2 of sortedEdits) {
|
|
2873
|
+
const startOffset = document.offsetAt(e2.range.start);
|
|
2385
2874
|
if (startOffset < lastModifiedOffset) {
|
|
2386
2875
|
throw new Error("Overlapping edit");
|
|
2387
2876
|
} else if (startOffset > lastModifiedOffset) {
|
|
2388
2877
|
spans.push(text2.substring(lastModifiedOffset, startOffset));
|
|
2389
2878
|
}
|
|
2390
|
-
if (
|
|
2391
|
-
spans.push(
|
|
2879
|
+
if (e2.newText.length) {
|
|
2880
|
+
spans.push(e2.newText);
|
|
2392
2881
|
}
|
|
2393
|
-
lastModifiedOffset = document.offsetAt(
|
|
2882
|
+
lastModifiedOffset = document.offsetAt(e2.range.end);
|
|
2394
2883
|
}
|
|
2395
2884
|
spans.push(text2.substr(lastModifiedOffset));
|
|
2396
2885
|
return spans.join("");
|
|
@@ -2401,39 +2890,39 @@ function mergeSort(data, compare) {
|
|
|
2401
2890
|
if (data.length <= 1) {
|
|
2402
2891
|
return data;
|
|
2403
2892
|
}
|
|
2404
|
-
const
|
|
2405
|
-
const left = data.slice(0,
|
|
2406
|
-
const right = data.slice(
|
|
2893
|
+
const p2 = data.length / 2 | 0;
|
|
2894
|
+
const left = data.slice(0, p2);
|
|
2895
|
+
const right = data.slice(p2);
|
|
2407
2896
|
mergeSort(left, compare);
|
|
2408
2897
|
mergeSort(right, compare);
|
|
2409
2898
|
let leftIdx = 0;
|
|
2410
2899
|
let rightIdx = 0;
|
|
2411
|
-
let
|
|
2900
|
+
let i2 = 0;
|
|
2412
2901
|
while (leftIdx < left.length && rightIdx < right.length) {
|
|
2413
2902
|
const ret = compare(left[leftIdx], right[rightIdx]);
|
|
2414
2903
|
if (ret <= 0) {
|
|
2415
|
-
data[
|
|
2904
|
+
data[i2++] = left[leftIdx++];
|
|
2416
2905
|
} else {
|
|
2417
|
-
data[
|
|
2906
|
+
data[i2++] = right[rightIdx++];
|
|
2418
2907
|
}
|
|
2419
2908
|
}
|
|
2420
2909
|
while (leftIdx < left.length) {
|
|
2421
|
-
data[
|
|
2910
|
+
data[i2++] = left[leftIdx++];
|
|
2422
2911
|
}
|
|
2423
2912
|
while (rightIdx < right.length) {
|
|
2424
|
-
data[
|
|
2913
|
+
data[i2++] = right[rightIdx++];
|
|
2425
2914
|
}
|
|
2426
2915
|
return data;
|
|
2427
2916
|
}
|
|
2428
2917
|
function computeLineOffsets(text2, isAtLineStart, textOffset = 0) {
|
|
2429
2918
|
const result = isAtLineStart ? [textOffset] : [];
|
|
2430
|
-
for (let
|
|
2431
|
-
const ch = text2.charCodeAt(
|
|
2919
|
+
for (let i2 = 0; i2 < text2.length; i2++) {
|
|
2920
|
+
const ch = text2.charCodeAt(i2);
|
|
2432
2921
|
if (isEOL(ch)) {
|
|
2433
|
-
if (ch === 13 &&
|
|
2434
|
-
|
|
2922
|
+
if (ch === 13 && i2 + 1 < text2.length && text2.charCodeAt(i2 + 1) === 10) {
|
|
2923
|
+
i2++;
|
|
2435
2924
|
}
|
|
2436
|
-
result.push(textOffset +
|
|
2925
|
+
result.push(textOffset + i2 + 1);
|
|
2437
2926
|
}
|
|
2438
2927
|
}
|
|
2439
2928
|
return result;
|
|
@@ -2466,8 +2955,8 @@ function print(doc, options) {
|
|
|
2466
2955
|
}
|
|
2467
2956
|
function currentColumn(output) {
|
|
2468
2957
|
let col = 0;
|
|
2469
|
-
for (let
|
|
2470
|
-
const chunk = output[
|
|
2958
|
+
for (let i2 = output.length - 1; i2 >= 0; i2--) {
|
|
2959
|
+
const chunk = output[i2];
|
|
2471
2960
|
const nlIndex = chunk.lastIndexOf("\n");
|
|
2472
2961
|
if (nlIndex !== -1) {
|
|
2473
2962
|
col += chunk.length - nlIndex - 1;
|
|
@@ -2577,12 +3066,12 @@ function printDoc(doc, state, output, options) {
|
|
|
2577
3066
|
function printFill(parts, state, output, options) {
|
|
2578
3067
|
if (parts.length === 0) return;
|
|
2579
3068
|
const printWidth = options.printWidth ?? 80;
|
|
2580
|
-
for (let
|
|
2581
|
-
const content = parts[
|
|
2582
|
-
const separator =
|
|
3069
|
+
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
3070
|
+
const content = parts[i2];
|
|
3071
|
+
const separator = i2 + 1 < parts.length ? parts[i2 + 1] : null;
|
|
2583
3072
|
printDoc(content, state, output, options);
|
|
2584
3073
|
if (separator === null) break;
|
|
2585
|
-
const nextContent =
|
|
3074
|
+
const nextContent = i2 + 2 < parts.length ? parts[i2 + 2] : null;
|
|
2586
3075
|
if (nextContent !== null) {
|
|
2587
3076
|
const testOutput = [];
|
|
2588
3077
|
const flatState = { ...state, mode: "flat" };
|
|
@@ -2600,7 +3089,7 @@ function printFill(parts, state, output, options) {
|
|
|
2600
3089
|
} else {
|
|
2601
3090
|
printDoc(separator, state, output, options);
|
|
2602
3091
|
}
|
|
2603
|
-
|
|
3092
|
+
i2++;
|
|
2604
3093
|
}
|
|
2605
3094
|
}
|
|
2606
3095
|
function makeIndent(level, options) {
|
|
@@ -2633,10 +3122,10 @@ function indent(contents) {
|
|
|
2633
3122
|
if (contents === "") return "";
|
|
2634
3123
|
return { type: "indent", contents };
|
|
2635
3124
|
}
|
|
2636
|
-
function indentN(contents,
|
|
2637
|
-
if (
|
|
3125
|
+
function indentN(contents, n2) {
|
|
3126
|
+
if (n2 <= 0 || contents === "") return contents;
|
|
2638
3127
|
let result = contents;
|
|
2639
|
-
for (let
|
|
3128
|
+
for (let i2 = 0; i2 < n2; i2++) {
|
|
2640
3129
|
result = indent(result);
|
|
2641
3130
|
}
|
|
2642
3131
|
return result;
|
|
@@ -2650,7 +3139,7 @@ function ifBreak(breakContents, flatContents, options) {
|
|
|
2650
3139
|
return { type: "ifBreak", breakContents, flatContents, groupId: options?.groupId };
|
|
2651
3140
|
}
|
|
2652
3141
|
function fill(parts) {
|
|
2653
|
-
const filtered = parts.filter((
|
|
3142
|
+
const filtered = parts.filter((p2) => p2 !== "");
|
|
2654
3143
|
if (filtered.length === 0) return "";
|
|
2655
3144
|
if (filtered.length === 1) return filtered[0];
|
|
2656
3145
|
return { type: "fill", parts: filtered };
|
|
@@ -2661,12 +3150,12 @@ function isLine(doc) {
|
|
|
2661
3150
|
|
|
2662
3151
|
// lsp/server/src/formatting/utils.ts
|
|
2663
3152
|
function normalizeText(text2) {
|
|
2664
|
-
return text2.split("\n").map((line2) => line2.replace(/[ \t]+/g, " ").trim()).filter((line2,
|
|
3153
|
+
return text2.split("\n").map((line2) => line2.replace(/[ \t]+/g, " ").trim()).filter((line2, i2, arr) => line2 || i2 > 0 && i2 < arr.length - 1).join("\n");
|
|
2665
3154
|
}
|
|
2666
3155
|
function getVisibleChildren(node) {
|
|
2667
3156
|
const children = [];
|
|
2668
|
-
for (let
|
|
2669
|
-
const child = node.child(
|
|
3157
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3158
|
+
const child = node.child(i2);
|
|
2670
3159
|
if (child && !child.type.startsWith("_")) {
|
|
2671
3160
|
children.push(child);
|
|
2672
3161
|
}
|
|
@@ -2697,8 +3186,8 @@ ${middle.join("\n")}
|
|
|
2697
3186
|
${last} }}`;
|
|
2698
3187
|
}
|
|
2699
3188
|
const trimmed = inner.trim();
|
|
2700
|
-
const
|
|
2701
|
-
return `{{${prefix}${
|
|
3189
|
+
const s2 = prefix === "!" ? " " : space;
|
|
3190
|
+
return `{{${prefix}${s2}${trimmed}${s2}}}`;
|
|
2702
3191
|
}
|
|
2703
3192
|
const plainMatch = raw.match(/^\{\{([\s\S]*)\}\}$/);
|
|
2704
3193
|
if (plainMatch) {
|
|
@@ -2740,8 +3229,8 @@ function isCodeTag(config) {
|
|
|
2740
3229
|
return !!(config.languageAttribute || config.languageDefault);
|
|
2741
3230
|
}
|
|
2742
3231
|
function getAttributeValue(node, attrName) {
|
|
2743
|
-
for (let
|
|
2744
|
-
const child = node.child(
|
|
3232
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3233
|
+
const child = node.child(i2);
|
|
2745
3234
|
if (child?.type === "html_start_tag") {
|
|
2746
3235
|
for (let j = 0; j < child.childCount; j++) {
|
|
2747
3236
|
const attr = child.child(j);
|
|
@@ -2958,8 +3447,8 @@ function getContentNodes(sectionNode) {
|
|
|
2958
3447
|
const beginType = isInverted ? "mustache_inverted_section_begin" : "mustache_section_begin";
|
|
2959
3448
|
const endType = isInverted ? "mustache_inverted_section_end" : "mustache_section_end";
|
|
2960
3449
|
const contentNodes = [];
|
|
2961
|
-
for (let
|
|
2962
|
-
const child = sectionNode.child(
|
|
3450
|
+
for (let i2 = 0; i2 < sectionNode.childCount; i2++) {
|
|
3451
|
+
const child = sectionNode.child(i2);
|
|
2963
3452
|
if (!child) continue;
|
|
2964
3453
|
if (child.type !== beginType && child.type !== endType && child.type !== "mustache_erroneous_section_end" && child.type !== "mustache_erroneous_inverted_section_end" && !child.type.startsWith("_")) {
|
|
2965
3454
|
contentNodes.push(child);
|
|
@@ -2980,8 +3469,8 @@ function hasImplicitEndTagsRecursive(node) {
|
|
|
2980
3469
|
let hasStartTag = false;
|
|
2981
3470
|
let hasEndTag = false;
|
|
2982
3471
|
let hasContentChildren = false;
|
|
2983
|
-
for (let
|
|
2984
|
-
const child = node.child(
|
|
3472
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3473
|
+
const child = node.child(i2);
|
|
2985
3474
|
if (!child) continue;
|
|
2986
3475
|
if (child.type === "html_start_tag") hasStartTag = true;
|
|
2987
3476
|
else if (child.type === "html_end_tag") hasEndTag = true;
|
|
@@ -2990,8 +3479,8 @@ function hasImplicitEndTagsRecursive(node) {
|
|
|
2990
3479
|
}
|
|
2991
3480
|
if (hasStartTag && !hasEndTag && hasContentChildren) return true;
|
|
2992
3481
|
}
|
|
2993
|
-
for (let
|
|
2994
|
-
const child = node.child(
|
|
3482
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3483
|
+
const child = node.child(i2);
|
|
2995
3484
|
if (child && hasImplicitEndTagsRecursive(child)) {
|
|
2996
3485
|
return true;
|
|
2997
3486
|
}
|
|
@@ -3018,16 +3507,16 @@ function isInTextFlow(node, index, nodes) {
|
|
|
3018
3507
|
return false;
|
|
3019
3508
|
}
|
|
3020
3509
|
function hasAdjacentInlineContent(index, nodes) {
|
|
3021
|
-
for (let
|
|
3022
|
-
const
|
|
3023
|
-
if (
|
|
3024
|
-
if (isInlineContentNode(
|
|
3510
|
+
for (let i2 = index - 1; i2 >= 0; i2--) {
|
|
3511
|
+
const n2 = nodes[i2];
|
|
3512
|
+
if (n2.type === "text" && n2.text.trim().length === 0) continue;
|
|
3513
|
+
if (isInlineContentNode(n2)) return true;
|
|
3025
3514
|
break;
|
|
3026
3515
|
}
|
|
3027
|
-
for (let
|
|
3028
|
-
const
|
|
3029
|
-
if (
|
|
3030
|
-
if (isInlineContentNode(
|
|
3516
|
+
for (let i2 = index + 1; i2 < nodes.length; i2++) {
|
|
3517
|
+
const n2 = nodes[i2];
|
|
3518
|
+
if (n2.type === "text" && n2.text.trim().length === 0) continue;
|
|
3519
|
+
if (isInlineContentNode(n2)) return true;
|
|
3031
3520
|
break;
|
|
3032
3521
|
}
|
|
3033
3522
|
return false;
|
|
@@ -3083,15 +3572,15 @@ function dedentContent(rawContent) {
|
|
|
3083
3572
|
}
|
|
3084
3573
|
if (lines.length === 0) return "";
|
|
3085
3574
|
let minIndent = Infinity;
|
|
3086
|
-
for (const
|
|
3087
|
-
if (
|
|
3088
|
-
const match =
|
|
3575
|
+
for (const l2 of lines) {
|
|
3576
|
+
if (l2.trim() === "") continue;
|
|
3577
|
+
const match = l2.match(/^(\s*)/);
|
|
3089
3578
|
if (match && match[1].length < minIndent) {
|
|
3090
3579
|
minIndent = match[1].length;
|
|
3091
3580
|
}
|
|
3092
3581
|
}
|
|
3093
3582
|
if (minIndent === Infinity) minIndent = 0;
|
|
3094
|
-
return lines.map((
|
|
3583
|
+
return lines.map((l2) => l2.trim() === "" ? "" : l2.slice(minIndent)).join("\n");
|
|
3095
3584
|
}
|
|
3096
3585
|
function resolveIndentMode(node, config) {
|
|
3097
3586
|
const mode = config.indent ?? "never";
|
|
@@ -3102,8 +3591,8 @@ function resolveIndentMode(node, config) {
|
|
|
3102
3591
|
return isAttributeTruthy(value);
|
|
3103
3592
|
}
|
|
3104
3593
|
function getTagNameFromStartTag(startTag) {
|
|
3105
|
-
for (let
|
|
3106
|
-
const child = startTag.child(
|
|
3594
|
+
for (let i2 = 0; i2 < startTag.childCount; i2++) {
|
|
3595
|
+
const child = startTag.child(i2);
|
|
3107
3596
|
if (child?.type === "html_tag_name") return child.text.toLowerCase();
|
|
3108
3597
|
}
|
|
3109
3598
|
return null;
|
|
@@ -3172,8 +3661,8 @@ function formatHtmlElement(node, context, forceInline = false) {
|
|
|
3172
3661
|
let endTag = null;
|
|
3173
3662
|
let hasRealEndTag = false;
|
|
3174
3663
|
const contentNodes = [];
|
|
3175
|
-
for (let
|
|
3176
|
-
const child = node.child(
|
|
3664
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3665
|
+
const child = node.child(i2);
|
|
3177
3666
|
if (!child) continue;
|
|
3178
3667
|
if (child.type === "html_start_tag") {
|
|
3179
3668
|
startTag = child;
|
|
@@ -3273,8 +3762,8 @@ function formatHtmlElement(node, context, forceInline = false) {
|
|
|
3273
3762
|
const formattedContent = formatBlockChildren(contentNodes, context);
|
|
3274
3763
|
const hasContent = hasDocContent(formattedContent);
|
|
3275
3764
|
if (hasContent) {
|
|
3276
|
-
const hasBlockChildren = contentNodes.some((child,
|
|
3277
|
-
if (!shouldTreatAsBlock(child,
|
|
3765
|
+
const hasBlockChildren = contentNodes.some((child, i2) => {
|
|
3766
|
+
if (!shouldTreatAsBlock(child, i2, contentNodes, tags)) {
|
|
3278
3767
|
return false;
|
|
3279
3768
|
}
|
|
3280
3769
|
const childDisplay = getCSSDisplay(child, tags);
|
|
@@ -3330,8 +3819,8 @@ function formatHtmlElement(node, context, forceInline = false) {
|
|
|
3330
3819
|
}
|
|
3331
3820
|
function formatScriptStyleElement(node, context) {
|
|
3332
3821
|
const parts = [];
|
|
3333
|
-
for (let
|
|
3334
|
-
const child = node.child(
|
|
3822
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3823
|
+
const child = node.child(i2);
|
|
3335
3824
|
if (!child) continue;
|
|
3336
3825
|
if (child.type === "html_start_tag") {
|
|
3337
3826
|
parts.push(formatStartTag(child, context));
|
|
@@ -3415,8 +3904,8 @@ function formatMustacheSection(node, context) {
|
|
|
3415
3904
|
let beginNode = null;
|
|
3416
3905
|
let endNode = null;
|
|
3417
3906
|
const contentNodes = [];
|
|
3418
|
-
for (let
|
|
3419
|
-
const child = node.child(
|
|
3907
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
3908
|
+
const child = node.child(i2);
|
|
3420
3909
|
if (!child) continue;
|
|
3421
3910
|
if (child.type === beginType) {
|
|
3422
3911
|
beginNode = child;
|
|
@@ -3431,7 +3920,7 @@ function formatMustacheSection(node, context) {
|
|
|
3431
3920
|
parts.push(text(mustacheText(beginNode.text, context)));
|
|
3432
3921
|
}
|
|
3433
3922
|
const hasImplicit = hasImplicitEndTags(contentNodes);
|
|
3434
|
-
const erroneousCount = contentNodes.filter((
|
|
3923
|
+
const erroneousCount = contentNodes.filter((n2) => n2.type === "html_erroneous_end_tag").length;
|
|
3435
3924
|
const hasStaircase = !hasImplicit && erroneousCount > 0;
|
|
3436
3925
|
if (hasStaircase) {
|
|
3437
3926
|
let virtualDepth = erroneousCount - 1;
|
|
@@ -3485,8 +3974,8 @@ function formatMustacheSection(node, context) {
|
|
|
3485
3974
|
parts.push(formattedContent);
|
|
3486
3975
|
parts.push(hardline);
|
|
3487
3976
|
} else {
|
|
3488
|
-
const hasBlockChildren = contentNodes.some((child,
|
|
3489
|
-
if (!shouldTreatAsBlock(child,
|
|
3977
|
+
const hasBlockChildren = contentNodes.some((child, i2) => {
|
|
3978
|
+
if (!shouldTreatAsBlock(child, i2, contentNodes, context.customTags)) {
|
|
3490
3979
|
return false;
|
|
3491
3980
|
}
|
|
3492
3981
|
const childDisplay = getCSSDisplay(child, context.customTags);
|
|
@@ -3508,8 +3997,8 @@ function formatMustacheSection(node, context) {
|
|
|
3508
3997
|
return group(concat(parts));
|
|
3509
3998
|
}
|
|
3510
3999
|
function startTagHasAttributes(startTag) {
|
|
3511
|
-
for (let
|
|
3512
|
-
const child = startTag.child(
|
|
4000
|
+
for (let i2 = 0; i2 < startTag.childCount; i2++) {
|
|
4001
|
+
const child = startTag.child(i2);
|
|
3513
4002
|
if (!child) continue;
|
|
3514
4003
|
if (child.type === "html_attribute" || child.type === "mustache_attribute" || child.type === "mustache_interpolation" || child.type === "mustache_triple") {
|
|
3515
4004
|
return true;
|
|
@@ -3520,8 +4009,8 @@ function startTagHasAttributes(startTag) {
|
|
|
3520
4009
|
function formatStartTag(node, context, bare = false) {
|
|
3521
4010
|
let tagNameText = "";
|
|
3522
4011
|
const attrs = [];
|
|
3523
|
-
for (let
|
|
3524
|
-
const child = node.child(
|
|
4012
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
4013
|
+
const child = node.child(i2);
|
|
3525
4014
|
if (!child) continue;
|
|
3526
4015
|
if (child.type === "html_tag_name") {
|
|
3527
4016
|
tagNameText = child.text;
|
|
@@ -3543,11 +4032,11 @@ function formatStartTag(node, context, bare = false) {
|
|
|
3543
4032
|
return text("<" + tagNameText + closingBracket);
|
|
3544
4033
|
}
|
|
3545
4034
|
const attrParts = [];
|
|
3546
|
-
for (let
|
|
3547
|
-
if (
|
|
4035
|
+
for (let i2 = 0; i2 < attrs.length; i2++) {
|
|
4036
|
+
if (i2 > 0) {
|
|
3548
4037
|
attrParts.push(line);
|
|
3549
4038
|
}
|
|
3550
|
-
attrParts.push(attrs[
|
|
4039
|
+
attrParts.push(attrs[i2]);
|
|
3551
4040
|
}
|
|
3552
4041
|
const breakClosingBracket = isSelfClosing ? "/>" : ">";
|
|
3553
4042
|
const inner = concat([
|
|
@@ -3559,8 +4048,8 @@ function formatStartTag(node, context, bare = false) {
|
|
|
3559
4048
|
return bare ? inner : group(inner);
|
|
3560
4049
|
}
|
|
3561
4050
|
function formatEndTag(node) {
|
|
3562
|
-
for (let
|
|
3563
|
-
const child = node.child(
|
|
4051
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
4052
|
+
const child = node.child(i2);
|
|
3564
4053
|
if (child && child.type === "html_tag_name") {
|
|
3565
4054
|
return text("</" + child.text + ">");
|
|
3566
4055
|
}
|
|
@@ -3569,8 +4058,8 @@ function formatEndTag(node) {
|
|
|
3569
4058
|
}
|
|
3570
4059
|
function formatAttribute(node, context) {
|
|
3571
4060
|
const parts = [];
|
|
3572
|
-
for (let
|
|
3573
|
-
const child = node.child(
|
|
4061
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
4062
|
+
const child = node.child(i2);
|
|
3574
4063
|
if (!child) continue;
|
|
3575
4064
|
if (child.type === "html_attribute_name") {
|
|
3576
4065
|
parts.push(text(child.text));
|
|
@@ -3595,21 +4084,21 @@ function textWords(str) {
|
|
|
3595
4084
|
const words = str.split(/\s+/).filter((w) => w.length > 0);
|
|
3596
4085
|
if (words.length === 0) return [];
|
|
3597
4086
|
const parts = [words[0]];
|
|
3598
|
-
for (let
|
|
4087
|
+
for (let i2 = 1; i2 < words.length; i2++) {
|
|
3599
4088
|
parts.push(line);
|
|
3600
|
-
parts.push(words[
|
|
4089
|
+
parts.push(words[i2]);
|
|
3601
4090
|
}
|
|
3602
4091
|
return parts;
|
|
3603
4092
|
}
|
|
3604
4093
|
function collapseDelimitedRegions(parts, delimiters) {
|
|
3605
4094
|
if (delimiters.length === 0) return parts;
|
|
3606
4095
|
const sorted = [...delimiters].sort(
|
|
3607
|
-
(
|
|
4096
|
+
(a2, b) => Math.max(b.start.length, b.end.length) - Math.max(a2.start.length, a2.end.length)
|
|
3608
4097
|
);
|
|
3609
4098
|
const result = [...parts];
|
|
3610
4099
|
let activeDelimiter = null;
|
|
3611
|
-
for (let
|
|
3612
|
-
const part = result[
|
|
4100
|
+
for (let i2 = 0; i2 < result.length; i2++) {
|
|
4101
|
+
const part = result[i2];
|
|
3613
4102
|
if (typeof part === "string") {
|
|
3614
4103
|
if (activeDelimiter === null) {
|
|
3615
4104
|
for (const delim of sorted) {
|
|
@@ -3630,7 +4119,7 @@ function collapseDelimitedRegions(parts, delimiters) {
|
|
|
3630
4119
|
}
|
|
3631
4120
|
}
|
|
3632
4121
|
} else if (activeDelimiter !== null && isLine(part)) {
|
|
3633
|
-
result[
|
|
4122
|
+
result[i2] = " ";
|
|
3634
4123
|
}
|
|
3635
4124
|
}
|
|
3636
4125
|
return result;
|
|
@@ -3682,8 +4171,8 @@ function formatBlockChildren(nodes, context) {
|
|
|
3682
4171
|
const parts2 = noBreakDelims ? collapseDelimitedRegions(currentLine, noBreakDelims) : currentLine;
|
|
3683
4172
|
return inlineContentToFill(parts2);
|
|
3684
4173
|
}
|
|
3685
|
-
for (let
|
|
3686
|
-
const node = nodes[
|
|
4174
|
+
for (let i2 = 0; i2 < nodes.length; i2++) {
|
|
4175
|
+
const node = nodes[i2];
|
|
3687
4176
|
if (lastNodeEnd >= 0 && node.startIndex > lastNodeEnd && !inIgnoreRegion) {
|
|
3688
4177
|
const gap = context.document.getText().slice(lastNodeEnd, node.startIndex);
|
|
3689
4178
|
const newlineCount = (gap.match(/\n/g) || []).length;
|
|
@@ -3756,10 +4245,10 @@ function formatBlockChildren(nodes, context) {
|
|
|
3756
4245
|
lastNodeEnd = node.endIndex;
|
|
3757
4246
|
continue;
|
|
3758
4247
|
}
|
|
3759
|
-
const treatAsBlock = shouldTreatAsBlock(node,
|
|
4248
|
+
const treatAsBlock = shouldTreatAsBlock(node, i2, nodes, context.customTags);
|
|
3760
4249
|
if (lastNodeEnd >= 0 && node.startIndex > lastNodeEnd) {
|
|
3761
|
-
const prevNode = nodes[
|
|
3762
|
-
const prevTreatAsBlock = shouldTreatAsBlock(prevNode,
|
|
4250
|
+
const prevNode = nodes[i2 - 1];
|
|
4251
|
+
const prevTreatAsBlock = shouldTreatAsBlock(prevNode, i2 - 1, nodes, context.customTags);
|
|
3763
4252
|
if (!prevTreatAsBlock && !treatAsBlock) {
|
|
3764
4253
|
const gap = context.document.getText().slice(lastNodeEnd, node.startIndex);
|
|
3765
4254
|
if (/\s/.test(gap)) {
|
|
@@ -3780,7 +4269,7 @@ function formatBlockChildren(nodes, context) {
|
|
|
3780
4269
|
pendingBlankLine = false;
|
|
3781
4270
|
} else if (node.type === "html_comment" || node.type === "mustache_comment") {
|
|
3782
4271
|
const isMultiline = node.startPosition.row !== node.endPosition.row;
|
|
3783
|
-
const isOnOwnLine =
|
|
4272
|
+
const isOnOwnLine = i2 > 0 && node.startPosition.row > nodes[i2 - 1].endPosition.row;
|
|
3784
4273
|
if (isMultiline || isOnOwnLine) {
|
|
3785
4274
|
if (currentLine.length > 0) {
|
|
3786
4275
|
const lineContent = trimDoc(flushCurrentLine());
|
|
@@ -3806,7 +4295,7 @@ function formatBlockChildren(nodes, context) {
|
|
|
3806
4295
|
blankLineBeforeCurrentLine = pendingBlankLine;
|
|
3807
4296
|
pendingBlankLine = false;
|
|
3808
4297
|
}
|
|
3809
|
-
const forceInline = isInTextFlow(node,
|
|
4298
|
+
const forceInline = isInTextFlow(node, i2, nodes);
|
|
3810
4299
|
const formatted = formatNode(node, context, forceInline);
|
|
3811
4300
|
if (typeof formatted === "string" && formatted.includes("\n")) {
|
|
3812
4301
|
const contentLines = formatted.split("\n");
|
|
@@ -3915,18 +4404,18 @@ function formatBlockChildren(nodes, context) {
|
|
|
3915
4404
|
return empty;
|
|
3916
4405
|
}
|
|
3917
4406
|
const parts = [];
|
|
3918
|
-
for (let
|
|
3919
|
-
if (
|
|
3920
|
-
if (lines[
|
|
4407
|
+
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
4408
|
+
if (i2 > 0) {
|
|
4409
|
+
if (lines[i2].blankLineBefore) {
|
|
3921
4410
|
parts.push("\n");
|
|
3922
4411
|
}
|
|
3923
|
-
if (lines[
|
|
4412
|
+
if (lines[i2].rawLine) {
|
|
3924
4413
|
parts.push("\n");
|
|
3925
4414
|
} else {
|
|
3926
4415
|
parts.push(hardline);
|
|
3927
4416
|
}
|
|
3928
4417
|
}
|
|
3929
|
-
parts.push(lines[
|
|
4418
|
+
parts.push(lines[i2].doc);
|
|
3930
4419
|
}
|
|
3931
4420
|
return concat(parts);
|
|
3932
4421
|
}
|
|
@@ -4035,8 +4524,8 @@ function getEmbeddedLanguageId(node) {
|
|
|
4035
4524
|
if (node.type === "html_style_element") {
|
|
4036
4525
|
return "css";
|
|
4037
4526
|
}
|
|
4038
|
-
for (let
|
|
4039
|
-
const child = node.child(
|
|
4527
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
4528
|
+
const child = node.child(i2);
|
|
4040
4529
|
if (child?.type === "html_start_tag") {
|
|
4041
4530
|
for (let j = 0; j < child.childCount; j++) {
|
|
4042
4531
|
const attr = child.child(j);
|
|
@@ -4062,8 +4551,8 @@ function collectEmbeddedRegions(rootNode) {
|
|
|
4062
4551
|
const regions = [];
|
|
4063
4552
|
const walk = (node) => {
|
|
4064
4553
|
if (node.type === "html_script_element" || node.type === "html_style_element") {
|
|
4065
|
-
for (let
|
|
4066
|
-
const child = node.child(
|
|
4554
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
4555
|
+
const child = node.child(i2);
|
|
4067
4556
|
if (child?.type === "html_raw_text") {
|
|
4068
4557
|
regions.push({
|
|
4069
4558
|
startIndex: child.startIndex,
|
|
@@ -4074,8 +4563,8 @@ function collectEmbeddedRegions(rootNode) {
|
|
|
4074
4563
|
}
|
|
4075
4564
|
return;
|
|
4076
4565
|
}
|
|
4077
|
-
for (let
|
|
4078
|
-
const child = node.child(
|
|
4566
|
+
for (let i2 = 0; i2 < node.childCount; i2++) {
|
|
4567
|
+
const child = node.child(i2);
|
|
4079
4568
|
if (child) walk(child);
|
|
4080
4569
|
}
|
|
4081
4570
|
};
|
|
@@ -4115,9 +4604,9 @@ function parseFlags(args) {
|
|
|
4115
4604
|
mustacheSpaces: void 0,
|
|
4116
4605
|
patterns: []
|
|
4117
4606
|
};
|
|
4118
|
-
let
|
|
4119
|
-
while (
|
|
4120
|
-
const arg = args[
|
|
4607
|
+
let i2 = 0;
|
|
4608
|
+
while (i2 < args.length) {
|
|
4609
|
+
const arg = args[i2];
|
|
4121
4610
|
switch (arg) {
|
|
4122
4611
|
case "--write":
|
|
4123
4612
|
flags.write = true;
|
|
@@ -4129,16 +4618,16 @@ function parseFlags(args) {
|
|
|
4129
4618
|
flags.stdin = true;
|
|
4130
4619
|
break;
|
|
4131
4620
|
case "--indent-size":
|
|
4132
|
-
|
|
4133
|
-
flags.indentSize = parseInt(args[
|
|
4621
|
+
i2++;
|
|
4622
|
+
flags.indentSize = parseInt(args[i2], 10);
|
|
4134
4623
|
if (isNaN(flags.indentSize)) {
|
|
4135
4624
|
console.error(source_default.red("Error: --indent-size requires a number"));
|
|
4136
4625
|
process.exit(1);
|
|
4137
4626
|
}
|
|
4138
4627
|
break;
|
|
4139
4628
|
case "--print-width":
|
|
4140
|
-
|
|
4141
|
-
flags.printWidth = parseInt(args[
|
|
4629
|
+
i2++;
|
|
4630
|
+
flags.printWidth = parseInt(args[i2], 10);
|
|
4142
4631
|
if (isNaN(flags.printWidth)) {
|
|
4143
4632
|
console.error(source_default.red("Error: --print-width requires a number"));
|
|
4144
4633
|
process.exit(1);
|
|
@@ -4151,7 +4640,7 @@ function parseFlags(args) {
|
|
|
4151
4640
|
flags.patterns.push(arg);
|
|
4152
4641
|
break;
|
|
4153
4642
|
}
|
|
4154
|
-
|
|
4643
|
+
i2++;
|
|
4155
4644
|
}
|
|
4156
4645
|
return flags;
|
|
4157
4646
|
}
|