@cloudhal/mcp-server 0.3.6 → 0.3.8
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.
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-page checks, part of `RENDER_CHECK_SCRIPT`: font-fallback.
|
|
3
|
+
* Plain source text, run inside the page; it shares the script's locals (see ./index.ts).
|
|
4
|
+
*/
|
|
5
|
+
export declare const FONT_CHECKS = " // font-fallback (RFC-0023 \u00A72): text set in a web font whose stack has no metric-matched fallback\n // right after it (a face with size-adjust or ascent-override). Without one, the text is first\n // drawn in a system font of another size and moves when the web font arrives.\n if (document.fonts) {\n const tuned = new Set(), web = new Set();\n const name = (f) => f.trim().replace(/^[\"']|[\"']$/g, \"\").toLowerCase();\n for (const f of document.fonts) {\n const fam = name(f.family);\n if ((f.sizeAdjust && f.sizeAdjust !== \"100%\") || (f.ascentOverride && f.ascentOverride !== \"normal\")) tuned.add(fam);\n else if (f.status === \"loaded\") web.add(fam);\n }\n const seen = new Set();\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);\n for (let n = walker.nextNode(); n; n = walker.nextNode()) {\n const el = n.parentElement;\n if (!el || !n.textContent.trim()) continue;\n const stack = getComputedStyle(el).fontFamily;\n if (seen.has(stack)) continue;\n seen.add(stack);\n const fams = stack.split(\",\").map(name);\n if (!web.has(fams[0]) || tuned.has(fams[0]) || tuned.has(fams[1] || \"\")) continue;\n if (!visible(el)) { seen.delete(stack); continue; }\n add(\"font-fallback\", el, JSON.stringify(fams[0]) + \" has no metric-matched fallback after it, so the text moves when the font loads\");\n }\n }\n";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-page checks, part of `RENDER_CHECK_SCRIPT`: font-fallback.
|
|
3
|
+
* Plain source text, run inside the page; it shares the script's locals (see ./index.ts).
|
|
4
|
+
*/
|
|
5
|
+
export const FONT_CHECKS = ` // font-fallback (RFC-0023 §2): text set in a web font whose stack has no metric-matched fallback
|
|
6
|
+
// right after it (a face with size-adjust or ascent-override). Without one, the text is first
|
|
7
|
+
// drawn in a system font of another size and moves when the web font arrives.
|
|
8
|
+
if (document.fonts) {
|
|
9
|
+
const tuned = new Set(), web = new Set();
|
|
10
|
+
const name = (f) => f.trim().replace(/^["']|["']$/g, "").toLowerCase();
|
|
11
|
+
for (const f of document.fonts) {
|
|
12
|
+
const fam = name(f.family);
|
|
13
|
+
if ((f.sizeAdjust && f.sizeAdjust !== "100%") || (f.ascentOverride && f.ascentOverride !== "normal")) tuned.add(fam);
|
|
14
|
+
else if (f.status === "loaded") web.add(fam);
|
|
15
|
+
}
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
18
|
+
for (let n = walker.nextNode(); n; n = walker.nextNode()) {
|
|
19
|
+
const el = n.parentElement;
|
|
20
|
+
if (!el || !n.textContent.trim()) continue;
|
|
21
|
+
const stack = getComputedStyle(el).fontFamily;
|
|
22
|
+
if (seen.has(stack)) continue;
|
|
23
|
+
seen.add(stack);
|
|
24
|
+
const fams = stack.split(",").map(name);
|
|
25
|
+
if (!web.has(fams[0]) || tuned.has(fams[0]) || tuned.has(fams[1] || "")) continue;
|
|
26
|
+
if (!visible(el)) { seen.delete(stack); continue; }
|
|
27
|
+
add("font-fallback", el, JSON.stringify(fams[0]) + " has no metric-matched fallback after it, so the text moves when the font loads");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { COMPONENT_CHECKS } from "./components.js";
|
|
11
11
|
import { CONTENT_CHECKS } from "./content.js";
|
|
12
12
|
import { CONTRAST_CHECKS } from "./contrast.js";
|
|
13
|
+
import { FONT_CHECKS } from "./fonts.js";
|
|
13
14
|
import { LAYOUT_CHECKS } from "./layout.js";
|
|
14
15
|
import { MOTION_CHECKS } from "./motion.js";
|
|
15
16
|
import { NAVIGATION_CHECKS } from "./navigation.js";
|
|
@@ -21,6 +22,7 @@ export const RENDER_CHECK_SCRIPT = [
|
|
|
21
22
|
LAYOUT_CHECKS,
|
|
22
23
|
CONTRAST_CHECKS,
|
|
23
24
|
CONTENT_CHECKS,
|
|
25
|
+
FONT_CHECKS,
|
|
24
26
|
MOTION_CHECKS,
|
|
25
27
|
NAVIGATION_CHECKS,
|
|
26
28
|
COMPONENT_CHECKS,
|
|
@@ -41,7 +41,7 @@ export interface RenderCheck {
|
|
|
41
41
|
/** The widths it failed at. */
|
|
42
42
|
widths: number[];
|
|
43
43
|
}
|
|
44
|
-
export declare const RENDER_CHECK_IDS: readonly ["overflow-x", "img-alt", "img-broken", "heading-order", "contrast", "empty-section", "tap-target", "long-line", "input-label", "chart-empty", "reduced-motion", "motion-cls", "motion-budget", "flash", "skip-link", "landmarks", "header-contrast", "focus-obscured", "overlay-open", "carousel-label", "carousel-lcp", "carousel-focus", "carousel-autoplay", "image-fit"];
|
|
44
|
+
export declare const RENDER_CHECK_IDS: readonly ["overflow-x", "img-alt", "img-broken", "heading-order", "contrast", "empty-section", "tap-target", "long-line", "input-label", "chart-empty", "reduced-motion", "motion-cls", "motion-budget", "flash", "skip-link", "landmarks", "header-contrast", "focus-obscured", "overlay-open", "carousel-label", "carousel-lcp", "carousel-focus", "carousel-autoplay", "image-fit", "font-fallback"];
|
|
45
45
|
export type RenderCheckId = (typeof RENDER_CHECK_IDS)[number];
|
|
46
46
|
export interface RenderShot {
|
|
47
47
|
width: number;
|
package/dist/src/render/types.js
CHANGED
|
@@ -87,6 +87,8 @@ export const RENDER_CHECK_IDS = [
|
|
|
87
87
|
"carousel-autoplay",
|
|
88
88
|
// RFC-0028: an image cropped hard by cover with no focal point to keep its subject in view.
|
|
89
89
|
"image-fit",
|
|
90
|
+
// RFC-0023 §2: a web font with no metric-matched fallback, so its text moves when it loads.
|
|
91
|
+
"font-fallback",
|
|
90
92
|
] ;
|
|
91
93
|
|
|
92
94
|
|
package/dist/src/render-tools.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudhal/mcp-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Cloudhal MCP server: semantic site tools (pages, articles, snapshots, preview, publish) governed by the policy engine",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://cloudhal.dev",
|
|
@@ -56,15 +56,15 @@
|
|
|
56
56
|
"README.md"
|
|
57
57
|
],
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@cloudhal/analytics": "0.3.
|
|
60
|
-
"@cloudhal/agent-runtime": "0.3.
|
|
61
|
-
"@cloudhal/astro-renderer": "0.3.
|
|
62
|
-
"@cloudhal/comments": "0.3.
|
|
63
|
-
"@cloudhal/core-contracts": "0.3.
|
|
64
|
-
"@cloudhal/core-ts": "0.3.
|
|
65
|
-
"@cloudhal/storage": "0.3.
|
|
59
|
+
"@cloudhal/analytics": "0.3.8",
|
|
60
|
+
"@cloudhal/agent-runtime": "0.3.8",
|
|
61
|
+
"@cloudhal/astro-renderer": "0.3.8",
|
|
62
|
+
"@cloudhal/comments": "0.3.8",
|
|
63
|
+
"@cloudhal/core-contracts": "0.3.8",
|
|
64
|
+
"@cloudhal/core-ts": "0.3.8",
|
|
65
|
+
"@cloudhal/storage": "0.3.8",
|
|
66
66
|
"@modelcontextprotocol/server": "2.3.1",
|
|
67
|
-
"@cloudhal/schedules": "0.3.
|
|
67
|
+
"@cloudhal/schedules": "0.3.8"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@cloudflare/workers-types": "^5.20261007.1",
|