@hyperframes/lint 0.8.42 → 0.8.44
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 +88 -0
- package/dist/browser.js.map +1 -1
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/browser.js
CHANGED
|
@@ -612,6 +612,11 @@ function buildLintContext(html, options = {}) {
|
|
|
612
612
|
// src/rules/core.ts
|
|
613
613
|
import postcss from "postcss";
|
|
614
614
|
import selectorParser from "postcss-selector-parser";
|
|
615
|
+
import {
|
|
616
|
+
HTML_BODY_CSS_WIDTH_FIRST_RE,
|
|
617
|
+
HTML_BODY_CSS_HEIGHT_FIRST_RE,
|
|
618
|
+
VIEWPORT_META_SIZE_RE
|
|
619
|
+
} from "@hyperframes/parsers";
|
|
615
620
|
function repeatedDescendantId(selector) {
|
|
616
621
|
let repeated = null;
|
|
617
622
|
const requiredPseudoIds = (pseudo) => {
|
|
@@ -784,6 +789,56 @@ function findVisibleMarkupCommentLeak(source) {
|
|
|
784
789
|
}
|
|
785
790
|
return null;
|
|
786
791
|
}
|
|
792
|
+
function readHtmlBodyCssSize(source) {
|
|
793
|
+
const widthFirst = source.match(HTML_BODY_CSS_WIDTH_FIRST_RE);
|
|
794
|
+
if (widthFirst) {
|
|
795
|
+
const [, , width = "", , height = ""] = widthFirst;
|
|
796
|
+
return { width, height };
|
|
797
|
+
}
|
|
798
|
+
const heightFirst = source.match(HTML_BODY_CSS_HEIGHT_FIRST_RE);
|
|
799
|
+
if (heightFirst) {
|
|
800
|
+
const [, , height = "", , width = ""] = heightFirst;
|
|
801
|
+
return { width, height };
|
|
802
|
+
}
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
function readViewportMetaSize(source) {
|
|
806
|
+
const match = source.match(VIEWPORT_META_SIZE_RE);
|
|
807
|
+
if (!match) return null;
|
|
808
|
+
const [, , width = "", , height = ""] = match;
|
|
809
|
+
return { width, height };
|
|
810
|
+
}
|
|
811
|
+
function describeSizeMismatch(label, size, dataWidth, dataHeight) {
|
|
812
|
+
if (!size || size.width === dataWidth && size.height === dataHeight) return null;
|
|
813
|
+
return `${label} is ${size.width}x${size.height}`;
|
|
814
|
+
}
|
|
815
|
+
function describeRootDimensionsDrift(source, dataWidth, dataHeight) {
|
|
816
|
+
const bodyCssMismatch = describeSizeMismatch(
|
|
817
|
+
"html/body CSS",
|
|
818
|
+
readHtmlBodyCssSize(source),
|
|
819
|
+
dataWidth,
|
|
820
|
+
dataHeight
|
|
821
|
+
);
|
|
822
|
+
const viewportMismatch = describeSizeMismatch(
|
|
823
|
+
"the viewport meta",
|
|
824
|
+
readViewportMetaSize(source),
|
|
825
|
+
dataWidth,
|
|
826
|
+
dataHeight
|
|
827
|
+
);
|
|
828
|
+
if (!bodyCssMismatch && !viewportMismatch) return null;
|
|
829
|
+
const declared = `Root composition declares data-width="${dataWidth}" data-height="${dataHeight}"`;
|
|
830
|
+
if (!bodyCssMismatch) {
|
|
831
|
+
return {
|
|
832
|
+
message: `${declared}, but ${viewportMismatch}. The viewport meta has no effect on capture \u2014 the renderer sizes the viewport from the root's own data-width/data-height \u2014 so this is stale metadata, not a clipping risk.`,
|
|
833
|
+
fixHint: "update the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`"
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
const mismatches = viewportMismatch ? `${bodyCssMismatch} and ${viewportMismatch}` : bodyCssMismatch;
|
|
837
|
+
return {
|
|
838
|
+
message: `${declared}, but ${mismatches}. The scaffolded body clips the composition at its old size.`,
|
|
839
|
+
fixHint: "update html/body CSS and the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`"
|
|
840
|
+
};
|
|
841
|
+
}
|
|
787
842
|
var coreRules = [
|
|
788
843
|
// id_requires_css_escape
|
|
789
844
|
({ tags }) => {
|
|
@@ -828,6 +883,39 @@ var coreRules = [
|
|
|
828
883
|
}
|
|
829
884
|
return findings;
|
|
830
885
|
},
|
|
886
|
+
// root_dimensions_mismatch
|
|
887
|
+
//
|
|
888
|
+
// Render size and the runtime's forced #root size both read the root's own
|
|
889
|
+
// data-width/data-height, so they stay correct. But editing only those two
|
|
890
|
+
// attributes — rather than scaffolding with `hyperframes init --resolution`,
|
|
891
|
+
// which rewrites the scaffold's other copies of the resolution too — leaves
|
|
892
|
+
// the `html, body` CSS and the `<meta viewport>` at the old value, and a
|
|
893
|
+
// stale body with `overflow: hidden` visually clips the correctly-sized
|
|
894
|
+
// root. `hyperframes check`'s layout audits can't see it: they measure
|
|
895
|
+
// against the root's own (already-correct) rect, not the body's.
|
|
896
|
+
//
|
|
897
|
+
// Sub-compositions are exempt: loadExternalCompositions (packages/core/src/
|
|
898
|
+
// runtime/compositionLoader.ts) mounts only the matched <template>/<body>
|
|
899
|
+
// subtree, so a sub-comp's own <html>/<head>/<meta viewport> never reach
|
|
900
|
+
// the rendering document, even when it's a full standalone document.
|
|
901
|
+
({ rootTag, source, options }) => {
|
|
902
|
+
if (!rootTag || options.isSubComposition) return [];
|
|
903
|
+
const dataWidth = readAttr(rootTag.raw, "data-width");
|
|
904
|
+
const dataHeight = readAttr(rootTag.raw, "data-height");
|
|
905
|
+
if (!dataWidth || !dataHeight) return [];
|
|
906
|
+
const drift = describeRootDimensionsDrift(source, dataWidth, dataHeight);
|
|
907
|
+
if (!drift) return [];
|
|
908
|
+
return [
|
|
909
|
+
{
|
|
910
|
+
code: "root_dimensions_mismatch",
|
|
911
|
+
severity: "warning",
|
|
912
|
+
message: drift.message,
|
|
913
|
+
elementId: readAttr(rootTag.raw, "id") || void 0,
|
|
914
|
+
fixHint: drift.fixHint,
|
|
915
|
+
snippet: truncateSnippet(rootTag.raw)
|
|
916
|
+
}
|
|
917
|
+
];
|
|
918
|
+
},
|
|
831
919
|
// unbalanced_style_tags
|
|
832
920
|
({ source }) => {
|
|
833
921
|
let opens = 0;
|