@hyperframes/lint 0.8.193 → 0.8.194
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/dist/browser.js +97 -93
- package/dist/index.js +97 -93
- package/package.json +2 -2
package/dist/browser.js
CHANGED
|
@@ -814,6 +814,96 @@ function buildLintContext(html, options = {}) {
|
|
|
814
814
|
// src/rules/core.ts
|
|
815
815
|
import postcss from "postcss";
|
|
816
816
|
import selectorParser from "postcss-selector-parser";
|
|
817
|
+
|
|
818
|
+
// src/shaderDomains.ts
|
|
819
|
+
import { parse as parse2, parseExpressionAt } from "acorn";
|
|
820
|
+
import { simple as simple2 } from "acorn-walk";
|
|
821
|
+
var GLSL_SCRIPT_TYPES = /* @__PURE__ */ new Set(["x-shader/x-fragment", "x-shader/x-vertex", "text/glsl"]);
|
|
822
|
+
function withoutComments(source) {
|
|
823
|
+
return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
|
|
824
|
+
}
|
|
825
|
+
function staticShaders(source) {
|
|
826
|
+
const shaders = [];
|
|
827
|
+
try {
|
|
828
|
+
const ast = parse2(source, {
|
|
829
|
+
ecmaVersion: "latest",
|
|
830
|
+
sourceType: "module",
|
|
831
|
+
allowReturnOutsideFunction: true
|
|
832
|
+
});
|
|
833
|
+
simple2(ast, {
|
|
834
|
+
Literal(node) {
|
|
835
|
+
if (typeof node.value !== "string") return;
|
|
836
|
+
shaders.push({
|
|
837
|
+
text: node.value,
|
|
838
|
+
start: node.start + 1,
|
|
839
|
+
exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
|
|
840
|
+
});
|
|
841
|
+
},
|
|
842
|
+
TemplateLiteral(node) {
|
|
843
|
+
if (node.expressions.length !== 0) return;
|
|
844
|
+
const value = node.quasis[0]?.value;
|
|
845
|
+
if (value?.cooked == null) return;
|
|
846
|
+
shaders.push({
|
|
847
|
+
text: value.cooked,
|
|
848
|
+
start: node.start + 1,
|
|
849
|
+
exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
} catch {
|
|
854
|
+
}
|
|
855
|
+
return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
|
|
856
|
+
}
|
|
857
|
+
function isNumber(node, value) {
|
|
858
|
+
return node?.type === "Literal" && node.value === value;
|
|
859
|
+
}
|
|
860
|
+
function isCall(node, name) {
|
|
861
|
+
return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
|
|
862
|
+
}
|
|
863
|
+
function unboundedCosine(node) {
|
|
864
|
+
if (node.type !== "CallExpression") return false;
|
|
865
|
+
if (isCall(node, "dot")) return node.arguments.length === 2;
|
|
866
|
+
if (!isCall(node, "max") || node.arguments.length !== 2) return false;
|
|
867
|
+
const a = argumentAt(node, 0);
|
|
868
|
+
const b = argumentAt(node, 1);
|
|
869
|
+
return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
|
|
870
|
+
}
|
|
871
|
+
function argumentAt(call, index) {
|
|
872
|
+
const node = call.arguments[index];
|
|
873
|
+
return node?.type === "SpreadElement" ? void 0 : node;
|
|
874
|
+
}
|
|
875
|
+
function zeroFlooredDot(a, b) {
|
|
876
|
+
return isCall(a, "dot") && isNumber(b, 0);
|
|
877
|
+
}
|
|
878
|
+
function unsafeCosinePower(call) {
|
|
879
|
+
if (call.arguments.length !== 2) return false;
|
|
880
|
+
const [base2] = call.arguments;
|
|
881
|
+
return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
|
|
882
|
+
}
|
|
883
|
+
function unsafePowOffsets(source) {
|
|
884
|
+
const offsets = [];
|
|
885
|
+
const masked = withoutComments(source);
|
|
886
|
+
for (const match of masked.matchAll(/\bpow\s*\(/g)) {
|
|
887
|
+
try {
|
|
888
|
+
const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
|
|
889
|
+
simple2(expression, {
|
|
890
|
+
CallExpression(node) {
|
|
891
|
+
if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
} catch {
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return offsets;
|
|
898
|
+
}
|
|
899
|
+
function shaderDomainOffsets(source, glsl = false) {
|
|
900
|
+
const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
|
|
901
|
+
return shaders.flatMap(
|
|
902
|
+
({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
|
|
903
|
+
);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
// src/rules/core.ts
|
|
817
907
|
import {
|
|
818
908
|
HTML_BODY_CSS_WIDTH_FIRST_RE,
|
|
819
909
|
HTML_BODY_CSS_HEIGHT_FIRST_RE,
|
|
@@ -823,7 +913,8 @@ var SCRIPT_SYNTAX_EXEMPT_TYPES = /* @__PURE__ */ new Set([
|
|
|
823
913
|
"application/json",
|
|
824
914
|
"application/hyperframes-slideshow+json",
|
|
825
915
|
"importmap",
|
|
826
|
-
"module"
|
|
916
|
+
"module",
|
|
917
|
+
...GLSL_SCRIPT_TYPES
|
|
827
918
|
]);
|
|
828
919
|
function repeatedDescendantId(selector) {
|
|
829
920
|
let repeated = null;
|
|
@@ -2579,20 +2670,20 @@ function findAudioGroupCarveAttrFindings(ctx) {
|
|
|
2579
2670
|
}
|
|
2580
2671
|
|
|
2581
2672
|
// src/scriptPositions.ts
|
|
2582
|
-
import { parse as
|
|
2583
|
-
import { simple as
|
|
2673
|
+
import { parse as parse3 } from "acorn";
|
|
2674
|
+
import { simple as simple3 } from "acorn-walk";
|
|
2584
2675
|
var callIndexes = /* @__PURE__ */ new WeakMap();
|
|
2585
2676
|
function callsFor(script) {
|
|
2586
2677
|
const cached = callIndexes.get(script);
|
|
2587
2678
|
if (cached) return cached;
|
|
2588
2679
|
const calls = [];
|
|
2589
2680
|
try {
|
|
2590
|
-
const ast =
|
|
2681
|
+
const ast = parse3(script.content, {
|
|
2591
2682
|
ecmaVersion: "latest",
|
|
2592
2683
|
sourceType: "script",
|
|
2593
2684
|
allowReturnOutsideFunction: true
|
|
2594
2685
|
});
|
|
2595
|
-
|
|
2686
|
+
simple3(ast, {
|
|
2596
2687
|
CallExpression: (node) => {
|
|
2597
2688
|
calls.push(node);
|
|
2598
2689
|
}
|
|
@@ -6500,93 +6591,6 @@ var structureRules = [
|
|
|
6500
6591
|
}
|
|
6501
6592
|
];
|
|
6502
6593
|
|
|
6503
|
-
// src/shaderDomains.ts
|
|
6504
|
-
import { parse as parse3, parseExpressionAt } from "acorn";
|
|
6505
|
-
import { simple as simple3 } from "acorn-walk";
|
|
6506
|
-
function withoutComments(source) {
|
|
6507
|
-
return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
|
|
6508
|
-
}
|
|
6509
|
-
function staticShaders(source) {
|
|
6510
|
-
const shaders = [];
|
|
6511
|
-
try {
|
|
6512
|
-
const ast = parse3(source, {
|
|
6513
|
-
ecmaVersion: "latest",
|
|
6514
|
-
sourceType: "module",
|
|
6515
|
-
allowReturnOutsideFunction: true
|
|
6516
|
-
});
|
|
6517
|
-
simple3(ast, {
|
|
6518
|
-
Literal(node) {
|
|
6519
|
-
if (typeof node.value !== "string") return;
|
|
6520
|
-
shaders.push({
|
|
6521
|
-
text: node.value,
|
|
6522
|
-
start: node.start + 1,
|
|
6523
|
-
exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
|
|
6524
|
-
});
|
|
6525
|
-
},
|
|
6526
|
-
TemplateLiteral(node) {
|
|
6527
|
-
if (node.expressions.length !== 0) return;
|
|
6528
|
-
const value = node.quasis[0]?.value;
|
|
6529
|
-
if (value?.cooked == null) return;
|
|
6530
|
-
shaders.push({
|
|
6531
|
-
text: value.cooked,
|
|
6532
|
-
start: node.start + 1,
|
|
6533
|
-
exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
|
|
6534
|
-
});
|
|
6535
|
-
}
|
|
6536
|
-
});
|
|
6537
|
-
} catch {
|
|
6538
|
-
}
|
|
6539
|
-
return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
|
|
6540
|
-
}
|
|
6541
|
-
function isNumber(node, value) {
|
|
6542
|
-
return node?.type === "Literal" && node.value === value;
|
|
6543
|
-
}
|
|
6544
|
-
function isCall(node, name) {
|
|
6545
|
-
return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
|
|
6546
|
-
}
|
|
6547
|
-
function unboundedCosine(node) {
|
|
6548
|
-
if (node.type !== "CallExpression") return false;
|
|
6549
|
-
if (isCall(node, "dot")) return node.arguments.length === 2;
|
|
6550
|
-
if (!isCall(node, "max") || node.arguments.length !== 2) return false;
|
|
6551
|
-
const a = argumentAt(node, 0);
|
|
6552
|
-
const b = argumentAt(node, 1);
|
|
6553
|
-
return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
|
|
6554
|
-
}
|
|
6555
|
-
function argumentAt(call, index) {
|
|
6556
|
-
const node = call.arguments[index];
|
|
6557
|
-
return node?.type === "SpreadElement" ? void 0 : node;
|
|
6558
|
-
}
|
|
6559
|
-
function zeroFlooredDot(a, b) {
|
|
6560
|
-
return isCall(a, "dot") && isNumber(b, 0);
|
|
6561
|
-
}
|
|
6562
|
-
function unsafeCosinePower(call) {
|
|
6563
|
-
if (call.arguments.length !== 2) return false;
|
|
6564
|
-
const [base2] = call.arguments;
|
|
6565
|
-
return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
|
|
6566
|
-
}
|
|
6567
|
-
function unsafePowOffsets(source) {
|
|
6568
|
-
const offsets = [];
|
|
6569
|
-
const masked = withoutComments(source);
|
|
6570
|
-
for (const match of masked.matchAll(/\bpow\s*\(/g)) {
|
|
6571
|
-
try {
|
|
6572
|
-
const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
|
|
6573
|
-
simple3(expression, {
|
|
6574
|
-
CallExpression(node) {
|
|
6575
|
-
if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
|
|
6576
|
-
}
|
|
6577
|
-
});
|
|
6578
|
-
} catch {
|
|
6579
|
-
}
|
|
6580
|
-
}
|
|
6581
|
-
return offsets;
|
|
6582
|
-
}
|
|
6583
|
-
function shaderDomainOffsets(source, glsl = false) {
|
|
6584
|
-
const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
|
|
6585
|
-
return shaders.flatMap(
|
|
6586
|
-
({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
|
|
6587
|
-
);
|
|
6588
|
-
}
|
|
6589
|
-
|
|
6590
6594
|
// src/rules/shaders.ts
|
|
6591
6595
|
function shaderDomainWarning() {
|
|
6592
6596
|
return {
|
|
@@ -6601,7 +6605,7 @@ var shaderRules = [
|
|
|
6601
6605
|
const tag = `<script ${script.attrs}>`;
|
|
6602
6606
|
if (readAttr(tag, "src") !== null) return [];
|
|
6603
6607
|
const type = readAttr(tag, "type") ?? "";
|
|
6604
|
-
const glsl =
|
|
6608
|
+
const glsl = GLSL_SCRIPT_TYPES.has(type.toLowerCase());
|
|
6605
6609
|
if (type && !glsl && !/^(?:module|(?:text|application)\/javascript)$/i.test(type)) return [];
|
|
6606
6610
|
return shaderDomainOffsets(script.content, glsl).map((offset) => ({
|
|
6607
6611
|
...shaderDomainWarning(),
|
package/dist/index.js
CHANGED
|
@@ -820,6 +820,96 @@ function buildLintContext(html, options = {}) {
|
|
|
820
820
|
// src/rules/core.ts
|
|
821
821
|
import postcss from "postcss";
|
|
822
822
|
import selectorParser from "postcss-selector-parser";
|
|
823
|
+
|
|
824
|
+
// src/shaderDomains.ts
|
|
825
|
+
import { parse as parse2, parseExpressionAt } from "acorn";
|
|
826
|
+
import { simple as simple2 } from "acorn-walk";
|
|
827
|
+
var GLSL_SCRIPT_TYPES = /* @__PURE__ */ new Set(["x-shader/x-fragment", "x-shader/x-vertex", "text/glsl"]);
|
|
828
|
+
function withoutComments(source) {
|
|
829
|
+
return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
|
|
830
|
+
}
|
|
831
|
+
function staticShaders(source) {
|
|
832
|
+
const shaders = [];
|
|
833
|
+
try {
|
|
834
|
+
const ast = parse2(source, {
|
|
835
|
+
ecmaVersion: "latest",
|
|
836
|
+
sourceType: "module",
|
|
837
|
+
allowReturnOutsideFunction: true
|
|
838
|
+
});
|
|
839
|
+
simple2(ast, {
|
|
840
|
+
Literal(node) {
|
|
841
|
+
if (typeof node.value !== "string") return;
|
|
842
|
+
shaders.push({
|
|
843
|
+
text: node.value,
|
|
844
|
+
start: node.start + 1,
|
|
845
|
+
exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
|
|
846
|
+
});
|
|
847
|
+
},
|
|
848
|
+
TemplateLiteral(node) {
|
|
849
|
+
if (node.expressions.length !== 0) return;
|
|
850
|
+
const value = node.quasis[0]?.value;
|
|
851
|
+
if (value?.cooked == null) return;
|
|
852
|
+
shaders.push({
|
|
853
|
+
text: value.cooked,
|
|
854
|
+
start: node.start + 1,
|
|
855
|
+
exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
} catch {
|
|
860
|
+
}
|
|
861
|
+
return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
|
|
862
|
+
}
|
|
863
|
+
function isNumber(node, value) {
|
|
864
|
+
return node?.type === "Literal" && node.value === value;
|
|
865
|
+
}
|
|
866
|
+
function isCall(node, name) {
|
|
867
|
+
return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
|
|
868
|
+
}
|
|
869
|
+
function unboundedCosine(node) {
|
|
870
|
+
if (node.type !== "CallExpression") return false;
|
|
871
|
+
if (isCall(node, "dot")) return node.arguments.length === 2;
|
|
872
|
+
if (!isCall(node, "max") || node.arguments.length !== 2) return false;
|
|
873
|
+
const a = argumentAt(node, 0);
|
|
874
|
+
const b = argumentAt(node, 1);
|
|
875
|
+
return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
|
|
876
|
+
}
|
|
877
|
+
function argumentAt(call, index) {
|
|
878
|
+
const node = call.arguments[index];
|
|
879
|
+
return node?.type === "SpreadElement" ? void 0 : node;
|
|
880
|
+
}
|
|
881
|
+
function zeroFlooredDot(a, b) {
|
|
882
|
+
return isCall(a, "dot") && isNumber(b, 0);
|
|
883
|
+
}
|
|
884
|
+
function unsafeCosinePower(call) {
|
|
885
|
+
if (call.arguments.length !== 2) return false;
|
|
886
|
+
const [base2] = call.arguments;
|
|
887
|
+
return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
|
|
888
|
+
}
|
|
889
|
+
function unsafePowOffsets(source) {
|
|
890
|
+
const offsets = [];
|
|
891
|
+
const masked = withoutComments(source);
|
|
892
|
+
for (const match of masked.matchAll(/\bpow\s*\(/g)) {
|
|
893
|
+
try {
|
|
894
|
+
const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
|
|
895
|
+
simple2(expression, {
|
|
896
|
+
CallExpression(node) {
|
|
897
|
+
if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
} catch {
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
return offsets;
|
|
904
|
+
}
|
|
905
|
+
function shaderDomainOffsets(source, glsl = false) {
|
|
906
|
+
const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
|
|
907
|
+
return shaders.flatMap(
|
|
908
|
+
({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// src/rules/core.ts
|
|
823
913
|
import {
|
|
824
914
|
HTML_BODY_CSS_WIDTH_FIRST_RE,
|
|
825
915
|
HTML_BODY_CSS_HEIGHT_FIRST_RE,
|
|
@@ -829,7 +919,8 @@ var SCRIPT_SYNTAX_EXEMPT_TYPES = /* @__PURE__ */ new Set([
|
|
|
829
919
|
"application/json",
|
|
830
920
|
"application/hyperframes-slideshow+json",
|
|
831
921
|
"importmap",
|
|
832
|
-
"module"
|
|
922
|
+
"module",
|
|
923
|
+
...GLSL_SCRIPT_TYPES
|
|
833
924
|
]);
|
|
834
925
|
function repeatedDescendantId(selector) {
|
|
835
926
|
let repeated = null;
|
|
@@ -2585,20 +2676,20 @@ function findAudioGroupCarveAttrFindings(ctx) {
|
|
|
2585
2676
|
}
|
|
2586
2677
|
|
|
2587
2678
|
// src/scriptPositions.ts
|
|
2588
|
-
import { parse as
|
|
2589
|
-
import { simple as
|
|
2679
|
+
import { parse as parse3 } from "acorn";
|
|
2680
|
+
import { simple as simple3 } from "acorn-walk";
|
|
2590
2681
|
var callIndexes = /* @__PURE__ */ new WeakMap();
|
|
2591
2682
|
function callsFor(script) {
|
|
2592
2683
|
const cached = callIndexes.get(script);
|
|
2593
2684
|
if (cached) return cached;
|
|
2594
2685
|
const calls = [];
|
|
2595
2686
|
try {
|
|
2596
|
-
const ast =
|
|
2687
|
+
const ast = parse3(script.content, {
|
|
2597
2688
|
ecmaVersion: "latest",
|
|
2598
2689
|
sourceType: "script",
|
|
2599
2690
|
allowReturnOutsideFunction: true
|
|
2600
2691
|
});
|
|
2601
|
-
|
|
2692
|
+
simple3(ast, {
|
|
2602
2693
|
CallExpression: (node) => {
|
|
2603
2694
|
calls.push(node);
|
|
2604
2695
|
}
|
|
@@ -6506,93 +6597,6 @@ var structureRules = [
|
|
|
6506
6597
|
}
|
|
6507
6598
|
];
|
|
6508
6599
|
|
|
6509
|
-
// src/shaderDomains.ts
|
|
6510
|
-
import { parse as parse3, parseExpressionAt } from "acorn";
|
|
6511
|
-
import { simple as simple3 } from "acorn-walk";
|
|
6512
|
-
function withoutComments(source) {
|
|
6513
|
-
return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
|
|
6514
|
-
}
|
|
6515
|
-
function staticShaders(source) {
|
|
6516
|
-
const shaders = [];
|
|
6517
|
-
try {
|
|
6518
|
-
const ast = parse3(source, {
|
|
6519
|
-
ecmaVersion: "latest",
|
|
6520
|
-
sourceType: "module",
|
|
6521
|
-
allowReturnOutsideFunction: true
|
|
6522
|
-
});
|
|
6523
|
-
simple3(ast, {
|
|
6524
|
-
Literal(node) {
|
|
6525
|
-
if (typeof node.value !== "string") return;
|
|
6526
|
-
shaders.push({
|
|
6527
|
-
text: node.value,
|
|
6528
|
-
start: node.start + 1,
|
|
6529
|
-
exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
|
|
6530
|
-
});
|
|
6531
|
-
},
|
|
6532
|
-
TemplateLiteral(node) {
|
|
6533
|
-
if (node.expressions.length !== 0) return;
|
|
6534
|
-
const value = node.quasis[0]?.value;
|
|
6535
|
-
if (value?.cooked == null) return;
|
|
6536
|
-
shaders.push({
|
|
6537
|
-
text: value.cooked,
|
|
6538
|
-
start: node.start + 1,
|
|
6539
|
-
exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
|
|
6540
|
-
});
|
|
6541
|
-
}
|
|
6542
|
-
});
|
|
6543
|
-
} catch {
|
|
6544
|
-
}
|
|
6545
|
-
return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
|
|
6546
|
-
}
|
|
6547
|
-
function isNumber(node, value) {
|
|
6548
|
-
return node?.type === "Literal" && node.value === value;
|
|
6549
|
-
}
|
|
6550
|
-
function isCall(node, name) {
|
|
6551
|
-
return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
|
|
6552
|
-
}
|
|
6553
|
-
function unboundedCosine(node) {
|
|
6554
|
-
if (node.type !== "CallExpression") return false;
|
|
6555
|
-
if (isCall(node, "dot")) return node.arguments.length === 2;
|
|
6556
|
-
if (!isCall(node, "max") || node.arguments.length !== 2) return false;
|
|
6557
|
-
const a = argumentAt(node, 0);
|
|
6558
|
-
const b = argumentAt(node, 1);
|
|
6559
|
-
return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
|
|
6560
|
-
}
|
|
6561
|
-
function argumentAt(call, index) {
|
|
6562
|
-
const node = call.arguments[index];
|
|
6563
|
-
return node?.type === "SpreadElement" ? void 0 : node;
|
|
6564
|
-
}
|
|
6565
|
-
function zeroFlooredDot(a, b) {
|
|
6566
|
-
return isCall(a, "dot") && isNumber(b, 0);
|
|
6567
|
-
}
|
|
6568
|
-
function unsafeCosinePower(call) {
|
|
6569
|
-
if (call.arguments.length !== 2) return false;
|
|
6570
|
-
const [base2] = call.arguments;
|
|
6571
|
-
return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
|
|
6572
|
-
}
|
|
6573
|
-
function unsafePowOffsets(source) {
|
|
6574
|
-
const offsets = [];
|
|
6575
|
-
const masked = withoutComments(source);
|
|
6576
|
-
for (const match of masked.matchAll(/\bpow\s*\(/g)) {
|
|
6577
|
-
try {
|
|
6578
|
-
const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
|
|
6579
|
-
simple3(expression, {
|
|
6580
|
-
CallExpression(node) {
|
|
6581
|
-
if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
|
|
6582
|
-
}
|
|
6583
|
-
});
|
|
6584
|
-
} catch {
|
|
6585
|
-
}
|
|
6586
|
-
}
|
|
6587
|
-
return offsets;
|
|
6588
|
-
}
|
|
6589
|
-
function shaderDomainOffsets(source, glsl = false) {
|
|
6590
|
-
const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
|
|
6591
|
-
return shaders.flatMap(
|
|
6592
|
-
({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
|
|
6593
|
-
);
|
|
6594
|
-
}
|
|
6595
|
-
|
|
6596
6600
|
// src/rules/shaders.ts
|
|
6597
6601
|
function shaderDomainWarning() {
|
|
6598
6602
|
return {
|
|
@@ -6607,7 +6611,7 @@ var shaderRules = [
|
|
|
6607
6611
|
const tag = `<script ${script.attrs}>`;
|
|
6608
6612
|
if (readAttr(tag, "src") !== null) return [];
|
|
6609
6613
|
const type = readAttr(tag, "type") ?? "";
|
|
6610
|
-
const glsl =
|
|
6614
|
+
const glsl = GLSL_SCRIPT_TYPES.has(type.toLowerCase());
|
|
6611
6615
|
if (type && !glsl && !/^(?:module|(?:text|application)\/javascript)$/i.test(type)) return [];
|
|
6612
6616
|
return shaderDomainOffsets(script.content, glsl).map((offset) => ({
|
|
6613
6617
|
...shaderDomainWarning(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/lint",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.194",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"linkedom": "^0.18.12",
|
|
36
36
|
"postcss": "^8.5.8",
|
|
37
37
|
"postcss-selector-parser": "^7.1.4",
|
|
38
|
-
"@hyperframes/parsers": "0.8.
|
|
38
|
+
"@hyperframes/parsers": "0.8.194"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^25.0.10",
|