@hyperframes/lint 0.8.41 → 0.8.43

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 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,35 @@ 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 findScaffoldSizeMismatches(source, dataWidth, dataHeight) {
816
+ return [
817
+ describeSizeMismatch("html/body CSS", readHtmlBodyCssSize(source), dataWidth, dataHeight),
818
+ describeSizeMismatch("the viewport meta", readViewportMetaSize(source), dataWidth, dataHeight)
819
+ ].filter((mismatch) => mismatch !== null);
820
+ }
787
821
  var coreRules = [
788
822
  // id_requires_css_escape
789
823
  ({ tags }) => {
@@ -828,6 +862,37 @@ var coreRules = [
828
862
  }
829
863
  return findings;
830
864
  },
865
+ // root_dimensions_mismatch
866
+ //
867
+ // Render size and the runtime's forced #root size both read the root's own
868
+ // data-width/data-height, so they stay correct. But editing only those two
869
+ // attributes — rather than scaffolding with `hyperframes init --resolution`,
870
+ // which rewrites the scaffold's other copies of the resolution too — leaves
871
+ // the `html, body` CSS and the `<meta viewport>` at the old value, and a
872
+ // stale body with `overflow: hidden` visually clips the correctly-sized
873
+ // root. `hyperframes check`'s layout audits can't see it: they measure
874
+ // against the root's own (already-correct) rect, not the body's.
875
+ //
876
+ // A sub-composition fragment has no html/body or viewport to compare
877
+ // against, which makes this top-level-only without a separate guard.
878
+ ({ rootTag, source }) => {
879
+ if (!rootTag) return [];
880
+ const dataWidth = readAttr(rootTag.raw, "data-width");
881
+ const dataHeight = readAttr(rootTag.raw, "data-height");
882
+ if (!dataWidth || !dataHeight) return [];
883
+ const mismatches = findScaffoldSizeMismatches(source, dataWidth, dataHeight);
884
+ if (mismatches.length === 0) return [];
885
+ return [
886
+ {
887
+ code: "root_dimensions_mismatch",
888
+ severity: "warning",
889
+ message: `Root composition declares data-width="${dataWidth}" data-height="${dataHeight}", but ${mismatches.join(" and ")}. The scaffolded body clips the composition at its old size.`,
890
+ elementId: readAttr(rootTag.raw, "id") || void 0,
891
+ fixHint: "update html/body CSS and the meta viewport to match, or scaffold with `hyperframes init --resolution portrait`",
892
+ snippet: truncateSnippet(rootTag.raw)
893
+ }
894
+ ];
895
+ },
831
896
  // unbalanced_style_tags
832
897
  ({ source }) => {
833
898
  let opens = 0;