@hyperframes/lint 0.8.142 → 0.8.143
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 +37 -17
- package/dist/browser.js.map +1 -1
- package/dist/index.js +37 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -108,10 +108,7 @@ function hasUnquotedLessThan(attrs) {
|
|
|
108
108
|
return false;
|
|
109
109
|
}
|
|
110
110
|
function readAttr(tagSource, attr) {
|
|
111
|
-
|
|
112
|
-
const escaped = attr.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
113
|
-
const match = tagSource.match(new RegExp(`(?<![\\w-])${escaped}\\s*=\\s*["']([^"']+)["']`, "i"));
|
|
114
|
-
return match?.[1] || null;
|
|
111
|
+
return readAttributeValue(tagSource, attr, false) || null;
|
|
115
112
|
}
|
|
116
113
|
function hasAttrName(tagSource, attr) {
|
|
117
114
|
return readDecodedAttr(tagSource, attr) !== null;
|
|
@@ -134,15 +131,18 @@ function mediaWindowsOverlap(a, b) {
|
|
|
134
131
|
return a.start < b.end && b.start < a.end;
|
|
135
132
|
}
|
|
136
133
|
function readDecodedAttr(tagSource, attr) {
|
|
134
|
+
return readAttributeValue(tagSource, attr, true);
|
|
135
|
+
}
|
|
136
|
+
function readAttributeValue(tagSource, attr, decodeEntities) {
|
|
137
137
|
if (!tagSource) return null;
|
|
138
138
|
let value = null;
|
|
139
139
|
const parser = new Parser(
|
|
140
140
|
{
|
|
141
|
-
onattribute(name,
|
|
142
|
-
if (value === null && name.toLowerCase() === attr.toLowerCase()) value =
|
|
141
|
+
onattribute(name, attributeValue) {
|
|
142
|
+
if (value === null && name.toLowerCase() === attr.toLowerCase()) value = attributeValue;
|
|
143
143
|
}
|
|
144
144
|
},
|
|
145
|
-
{ decodeEntities
|
|
145
|
+
{ decodeEntities, lowerCaseAttributeNames: false, lowerCaseTags: true }
|
|
146
146
|
);
|
|
147
147
|
parser.end(tagSource);
|
|
148
148
|
return value;
|
|
@@ -748,6 +748,12 @@ import {
|
|
|
748
748
|
HTML_BODY_CSS_HEIGHT_FIRST_RE,
|
|
749
749
|
VIEWPORT_META_SIZE_RE
|
|
750
750
|
} from "@hyperframes/parsers/composition";
|
|
751
|
+
var SCRIPT_SYNTAX_EXEMPT_TYPES = /* @__PURE__ */ new Set([
|
|
752
|
+
"application/json",
|
|
753
|
+
"application/hyperframes-slideshow+json",
|
|
754
|
+
"importmap",
|
|
755
|
+
"module"
|
|
756
|
+
]);
|
|
751
757
|
function repeatedDescendantId(selector) {
|
|
752
758
|
let repeated = null;
|
|
753
759
|
const requiredPseudoIds = (pseudo) => {
|
|
@@ -1366,10 +1372,8 @@ var coreRules = [
|
|
|
1366
1372
|
({ scripts, locate }) => {
|
|
1367
1373
|
const findings = [];
|
|
1368
1374
|
for (const script of scripts) {
|
|
1369
|
-
const
|
|
1370
|
-
if (
|
|
1371
|
-
attrs
|
|
1372
|
-
))
|
|
1375
|
+
const type = readDecodedAttr(script.raw, "type")?.trim().toLowerCase() ?? "";
|
|
1376
|
+
if (readDecodedAttr(script.raw, "src") !== null || SCRIPT_SYNTAX_EXEMPT_TYPES.has(type))
|
|
1373
1377
|
continue;
|
|
1374
1378
|
const syntaxError = getInlineScriptSyntaxError(script.content);
|
|
1375
1379
|
if (!syntaxError) continue;
|
|
@@ -1786,6 +1790,7 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1786
1790
|
};
|
|
1787
1791
|
if (mediaTags.length === 0 || ctx.scripts.length === 0) return findings;
|
|
1788
1792
|
for (const script of ctx.scripts) {
|
|
1793
|
+
const code = stripJsCode(script.content);
|
|
1789
1794
|
const mediaVars = /* @__PURE__ */ new Map();
|
|
1790
1795
|
const assignmentPatterns = [
|
|
1791
1796
|
{
|
|
@@ -1802,6 +1807,7 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1802
1807
|
for (const { pattern, variableIndex, targetIndex } of assignmentPatterns) {
|
|
1803
1808
|
let match;
|
|
1804
1809
|
while ((match = pattern.exec(script.content)) !== null) {
|
|
1810
|
+
if (code[match.index] !== script.content[match.index]) continue;
|
|
1805
1811
|
const variableName = match[variableIndex];
|
|
1806
1812
|
const target = match[targetIndex];
|
|
1807
1813
|
if (!variableName || !target) continue;
|
|
@@ -1812,12 +1818,12 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1812
1818
|
}
|
|
1813
1819
|
const directIdPatterns = [
|
|
1814
1820
|
{
|
|
1815
|
-
pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)
|
|
1821
|
+
pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)\s*(?:\?\.|\.)\s*play\s*(?:\?\.\s*)?\(/g,
|
|
1816
1822
|
kind: "play()",
|
|
1817
1823
|
targetIndex: 1
|
|
1818
1824
|
},
|
|
1819
1825
|
{
|
|
1820
|
-
pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)
|
|
1826
|
+
pattern: /\b(?:document|window\.document)\.getElementById\(\s*["']([^"']+)["']\s*\)\s*(?:\?\.|\.)\s*pause\s*(?:\?\.\s*)?\(/g,
|
|
1821
1827
|
kind: "pause()",
|
|
1822
1828
|
targetIndex: 1
|
|
1823
1829
|
},
|
|
@@ -1832,12 +1838,12 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1832
1838
|
targetIndex: 1
|
|
1833
1839
|
},
|
|
1834
1840
|
{
|
|
1835
|
-
pattern: /\b(?:document|window\.document)\.querySelector\(\s*(["'])([\s\S]*?)\1\s*\)
|
|
1841
|
+
pattern: /\b(?:document|window\.document)\.querySelector\(\s*(["'])([\s\S]*?)\1\s*\)\s*(?:\?\.|\.)\s*play\s*(?:\?\.\s*)?\(/g,
|
|
1836
1842
|
kind: "play()",
|
|
1837
1843
|
targetIndex: 2
|
|
1838
1844
|
},
|
|
1839
1845
|
{
|
|
1840
|
-
pattern: /\b(?:document|window\.document)\.querySelector\(\s*(["'])([\s\S]*?)\1\s*\)
|
|
1846
|
+
pattern: /\b(?:document|window\.document)\.querySelector\(\s*(["'])([\s\S]*?)\1\s*\)\s*(?:\?\.|\.)\s*pause\s*(?:\?\.\s*)?\(/g,
|
|
1841
1847
|
kind: "pause()",
|
|
1842
1848
|
targetIndex: 2
|
|
1843
1849
|
},
|
|
@@ -1855,6 +1861,7 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1855
1861
|
for (const { pattern, kind, targetIndex } of directIdPatterns) {
|
|
1856
1862
|
let match;
|
|
1857
1863
|
while ((match = pattern.exec(script.content)) !== null) {
|
|
1864
|
+
if (code[match.index] !== script.content[match.index]) continue;
|
|
1858
1865
|
const target = match[targetIndex];
|
|
1859
1866
|
if (!target) continue;
|
|
1860
1867
|
const elementId = mediaIndex.ids.has(target) ? target : selectorTargetsManagedMedia(target, mediaIndex) ? void 0 : null;
|
|
@@ -1872,8 +1879,20 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1872
1879
|
for (const [variableName, elementId] of mediaVars) {
|
|
1873
1880
|
const escapedVar = escapeRegExp(variableName);
|
|
1874
1881
|
const variablePatterns = [
|
|
1875
|
-
{
|
|
1876
|
-
|
|
1882
|
+
{
|
|
1883
|
+
pattern: new RegExp(
|
|
1884
|
+
`\\b${escapedVar}\\s*(?:\\?\\.|\\.)\\s*play\\s*(?:\\?\\.\\s*)?\\(`,
|
|
1885
|
+
"g"
|
|
1886
|
+
),
|
|
1887
|
+
kind: "play()"
|
|
1888
|
+
},
|
|
1889
|
+
{
|
|
1890
|
+
pattern: new RegExp(
|
|
1891
|
+
`\\b${escapedVar}\\s*(?:\\?\\.|\\.)\\s*pause\\s*(?:\\?\\.\\s*)?\\(`,
|
|
1892
|
+
"g"
|
|
1893
|
+
),
|
|
1894
|
+
kind: "pause()"
|
|
1895
|
+
},
|
|
1877
1896
|
{ pattern: new RegExp(`\\b${escapedVar}\\.currentTime\\s*=`, "g"), kind: "currentTime" },
|
|
1878
1897
|
{
|
|
1879
1898
|
pattern: new RegExp(`\\b${escapedVar}\\.muted\\s*=`, "g"),
|
|
@@ -1883,6 +1902,7 @@ function findImperativeMediaControlFindings(ctx) {
|
|
|
1883
1902
|
for (const { pattern, kind } of variablePatterns) {
|
|
1884
1903
|
let match;
|
|
1885
1904
|
while ((match = pattern.exec(script.content)) !== null) {
|
|
1905
|
+
if (code[match.index] !== script.content[match.index]) continue;
|
|
1886
1906
|
findings.push({
|
|
1887
1907
|
code: "imperative_media_control",
|
|
1888
1908
|
severity: "error",
|