@cyber-dash-tech/revela 0.17.18 → 0.17.20
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.
|
@@ -81,6 +81,7 @@ const VISUAL_QUALITY_RULES = `Visual extraction and CSS quality rules:
|
|
|
81
81
|
|
|
82
82
|
const PREVIEW_REQUIREMENTS = `Preview requirements:
|
|
83
83
|
- \`preview.html\` must include a cover slide and a closing slide. Mark their \`<section class="slide">\` elements with \`data-slide-role="cover"\` and \`data-slide-role="closing"\`.
|
|
84
|
+
- \`preview.html\` must define an explicit CSS rule for \`.slide-canvas\` with \`width: 1920px\` and \`height: 1080px\`; every direct \`.slide-canvas\` is the fixed 1920px x 1080px export surface.
|
|
84
85
|
- \`preview.html\` must showcase every \`@component:*\` defined in \`DESIGN.md\`. Mark each showcased component with \`data-preview-component="<component-name>"\`.
|
|
85
86
|
- Do not save with \`revela-designs-author\` until every component has a corresponding preview marker. If a component is decorative or abstract, include a visible labeled sample state.
|
|
86
87
|
- When the design supports chart styling, \`preview.html\` should include a 3x3 ECharts gallery with at least 9 chart examples. This is a preview quality requirement, not a validation blocker.`
|
|
@@ -133,6 +134,7 @@ Hard requirements:
|
|
|
133
134
|
- \`DESIGN.md\` must include valid \`@design\`, \`@layout\`, and \`@component\` markers.
|
|
134
135
|
- \`DESIGN.md\` must include at least \`@design:foundation\`, \`@design:rules\`, one layout, and one component.
|
|
135
136
|
- \`preview.html\` must be self-contained and directly openable in a browser.
|
|
137
|
+
- \`preview.html\` must include an explicit CSS rule: \`.slide-canvas { width: 1920px; height: 1080px; }\`.
|
|
136
138
|
- Every preview slide must include \`slide-qa="true"\` or \`slide-qa="false"\`.
|
|
137
139
|
- \`preview.html\` must include \`data-slide-role="cover"\` and \`data-slide-role="closing"\` on slide sections.
|
|
138
140
|
- \`preview.html\` must showcase every \`@component:*\` with \`data-preview-component="<component-name>"\` before saving.
|
|
@@ -172,6 +174,7 @@ Hard requirements:
|
|
|
172
174
|
- Preserve valid frontmatter and marker structure.
|
|
173
175
|
- Preserve at least \`@design:foundation\`, \`@design:rules\`, one layout, and one component.
|
|
174
176
|
- \`preview.html\` must be self-contained and directly openable in a browser.
|
|
177
|
+
- \`preview.html\` must include an explicit CSS rule: \`.slide-canvas { width: 1920px; height: 1080px; }\`.
|
|
175
178
|
- Every preview slide must include \`slide-qa="true"\` or \`slide-qa="false"\`.
|
|
176
179
|
- \`preview.html\` must include \`data-slide-role="cover"\` and \`data-slide-role="closing"\` on slide sections.
|
|
177
180
|
- \`preview.html\` must showcase every \`@component:*\` with \`data-preview-component="<component-name>"\` before saving.
|
package/lib/design/designs.ts
CHANGED
|
@@ -264,6 +264,29 @@ function hasSlideRole(html: string, role: string): boolean {
|
|
|
264
264
|
return false
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
+
function cssRuleHasClassSelector(selectors: string, className: string): boolean {
|
|
268
|
+
const escaped = className.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
269
|
+
return new RegExp(`(^|[^a-zA-Z0-9_-])\\.${escaped}(?![a-zA-Z0-9_-])`).test(selectors)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function cssRuleHasFixedCanvasSize(body: string): boolean {
|
|
273
|
+
const width = /(?:^|[;\s])width\s*:\s*1920px(?:\s*!important)?\s*(?:;|$)/i.test(body)
|
|
274
|
+
const height = /(?:^|[;\s])height\s*:\s*1080px(?:\s*!important)?\s*(?:;|$)/i.test(body)
|
|
275
|
+
return width && height
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function hasFixedSizeCssRule(html: string, className: "slide-canvas"): boolean {
|
|
279
|
+
const withoutComments = html.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
280
|
+
const ruleRe = /([^{}]+)\{([^{}]+)\}/g
|
|
281
|
+
let match: RegExpExecArray | null
|
|
282
|
+
while ((match = ruleRe.exec(withoutComments)) !== null) {
|
|
283
|
+
if (cssRuleHasClassSelector(match[1] ?? "", className) && cssRuleHasFixedCanvasSize(match[2] ?? "")) {
|
|
284
|
+
return true
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return false
|
|
288
|
+
}
|
|
289
|
+
|
|
267
290
|
/** Validate a local design package for the minimum Revela design contract. */
|
|
268
291
|
export function validateDesignPackage(nameInput: string): ValidateDesignPackageResult {
|
|
269
292
|
let name = nameInput
|
|
@@ -312,6 +335,9 @@ export function validateDesignPackage(nameInput: string): ValidateDesignPackageR
|
|
|
312
335
|
if (!preview.includes('<section class="slide"')) errors.push("preview.html must include slide sections")
|
|
313
336
|
if (!preview.includes("slide-qa=")) errors.push("preview.html slides must include slide-qa attributes")
|
|
314
337
|
if (!preview.includes("slide-canvas")) errors.push("preview.html must include .slide-canvas")
|
|
338
|
+
if (!hasFixedSizeCssRule(preview, "slide-canvas")) {
|
|
339
|
+
errors.push("preview.html must define .slide-canvas CSS with width: 1920px and height: 1080px")
|
|
340
|
+
}
|
|
315
341
|
if (!hasSlideRole(preview, "cover")) errors.push('preview.html must include a slide section with data-slide-role="cover"')
|
|
316
342
|
if (!hasSlideRole(preview, "closing")) errors.push('preview.html must include a slide section with data-slide-role="closing"')
|
|
317
343
|
const missingComponents = components.filter((component) => !hasDataAttribute(preview, "data-preview-component", component))
|
package/lib/qa/checks.ts
CHANGED
|
@@ -209,19 +209,16 @@ function checkCanvas(metrics: SlideMetrics): LayoutIssue[] {
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
const canvasBad = Math.abs(metrics.canvasRect.width - CANVAS_W) > tol || Math.abs(metrics.canvasRect.height - CANVAS_H) > tol
|
|
212
|
-
const slideBad = Math.abs(metrics.slideRect.width - CANVAS_W) > tol || Math.abs(metrics.slideRect.height - CANVAS_H) > tol
|
|
213
212
|
|
|
214
|
-
if (canvasBad
|
|
213
|
+
if (canvasBad) {
|
|
215
214
|
issues.push({
|
|
216
215
|
type: "canvas",
|
|
217
216
|
sub: "size_mismatch",
|
|
218
217
|
severity: "error",
|
|
219
|
-
detail:
|
|
218
|
+
detail: `.slide-canvas must render exactly ${CANVAS_W}x${CANVAS_H}px. Measured canvas ${Math.round(metrics.canvasRect.width)}x${Math.round(metrics.canvasRect.height)}px.`,
|
|
220
219
|
data: {
|
|
221
220
|
expectedWidth: CANVAS_W,
|
|
222
221
|
expectedHeight: CANVAS_H,
|
|
223
|
-
slideWidth: Math.round(metrics.slideRect.width),
|
|
224
|
-
slideHeight: Math.round(metrics.slideRect.height),
|
|
225
222
|
canvasWidth: Math.round(metrics.canvasRect.width),
|
|
226
223
|
canvasHeight: Math.round(metrics.canvasRect.height),
|
|
227
224
|
},
|
|
@@ -911,7 +908,7 @@ export function formatReport(report: QAReport): string {
|
|
|
911
908
|
`### Action Required`,
|
|
912
909
|
``,
|
|
913
910
|
`Please fix the above hard-error issues in the HTML file. For each issue type:`,
|
|
914
|
-
`- **canvas**: ensure each slide and .slide-canvas
|
|
911
|
+
`- **canvas**: ensure each canonical .slide has exactly one direct .slide-canvas and that .slide-canvas renders exactly 1920x1080px, not merely any 16:9 size.`,
|
|
915
912
|
`- **scrollbar**: remove horizontal document/body scrolling and slide-internal scrolling. Multi-slide decks may use normal vertical document scroll for navigation.`,
|
|
916
913
|
`- **navigation**: keep every .slide in normal document flow; do not stack slides with fixed/absolute positioning or rely on aria-hidden/visibility toggles for pagination. Use scrollIntoView-based navigation.`,
|
|
917
914
|
`- **overflow**: reduce font size, padding, or content amount for the affected element.`,
|
package/package.json
CHANGED
package/plugins/revela/.mcp.json
CHANGED
|
@@ -29,6 +29,6 @@ After confirmation, read the base design with `revela_design_read`. Generate com
|
|
|
29
29
|
|
|
30
30
|
`DESIGN.md` must include frontmatter with `name`, `description`, `author`, and `version`, plus valid marker blocks for `@design:foundation`, `@design:rules`, at least one `@layout`, and at least one `@component`.
|
|
31
31
|
|
|
32
|
-
`preview.html` must be self-contained and directly openable in a browser. Every `<section class="slide">` must include `slide-qa` and exactly one direct `.slide-canvas` child. Include a cover slide with `data-slide-role="cover"`, a closing slide with `data-slide-role="closing"`, and a visible sample for every `@component:*` using `data-preview-component="<component-name>"`.
|
|
32
|
+
`preview.html` must be self-contained and directly openable in a browser. Every `<section class="slide">` must include `slide-qa` and exactly one direct `.slide-canvas` child. Every direct `.slide-canvas` is the fixed 1920px x 1080px export surface and must use explicit CSS with `width: 1920px` and `height: 1080px`; `.slide` may remain a viewport/navigation wrapper. Include a cover slide with `data-slide-role="cover"`, a closing slide with `data-slide-role="closing"`, and a visible sample for every `@component:*` using `data-preview-component="<component-name>"`.
|
|
33
33
|
|
|
34
34
|
Do not automatically activate a newly created design. Report the saved path and tell the user they can activate it with `revela_design_activate`.
|