;
onError?: (message: string) => void;
+ allowFragmentContentModelWarnings?: boolean;
}) => {
const mergedInstances = new Map(instances);
for (const instance of fragment.instances) {
@@ -30,6 +70,11 @@ export const findClosestInstanceMatchingFragment = ({
for (const prop of fragment.props) {
mergedProps.set(prop.id, prop);
}
+ const allowedWarningKeys = new Set(
+ allowFragmentContentModelWarnings
+ ? getFragmentContentModelWarnings({ fragment, metas }).map(getWarningKey)
+ : []
+ );
let firstError = "";
for (let index = 0; index < instanceSelector.length; index += 1) {
const instanceId = instanceSelector[index];
@@ -46,17 +91,26 @@ export const findClosestInstanceMatchingFragment = ({
if (child.type !== "id") {
continue;
}
- matches &&= isTreeSatisfyingContentModel({
+ let hasNewViolation = false;
+ const isValid = isTreeSatisfyingContentModel({
instances: mergedInstances,
props: mergedProps,
metas,
instanceSelector: [child.value, ...instanceSelector.slice(index)],
- onError: (message) => {
+ onError: (message, errorSelector) => {
if (firstError === "") {
firstError = message;
}
+ if (
+ allowedWarningKeys.has(
+ getWarningKey({ instanceId: errorSelector[0], message })
+ ) === false
+ ) {
+ hasNewViolation = true;
+ }
},
});
+ matches &&= isValid || hasNewViolation === false;
}
if (matches) {
return index;
diff --git a/packages/project-build/src/runtime/pre-publish-audit.test.tsx b/packages/project-build/src/runtime/pre-publish-audit.test.tsx
index 68ac58149e7b..d97c7f5e0a71 100644
--- a/packages/project-build/src/runtime/pre-publish-audit.test.tsx
+++ b/packages/project-build/src/runtime/pre-publish-audit.test.tsx
@@ -6,7 +6,7 @@ import {
type Pages,
} from "@webstudio-is/sdk";
import { componentMetas } from "@webstudio-is/sdk-components-registry/metas";
-import { $, renderData } from "@webstudio-is/template";
+import { $, renderData, ws } from "@webstudio-is/template";
import {
formatPrePublishAuditFinding,
runPrePublishAudit,
@@ -52,14 +52,14 @@ const runAudit = ({
metas: componentMetas,
});
-test("returns a blocking finding with the page and instance identity", () => {
+test("warns without blocking legacy invalid HTML", () => {
const { instances, props } = renderData(
<$.Body ws:id="body">
- <$.Paragraph>
- <$.Heading ws:id="heading" ws:tag="h2">
- Analyze Global Markets
+
+ <$.Heading ws:id="heading" ws:tag="h3">
+ Legacy accordion trigger
$.Heading>
- $.Paragraph>
+
$.Body>
);
@@ -68,8 +68,8 @@ test("returns a blocking finding with the page and instance identity", () => {
expect(findings).toEqual([
{
ruleId: "html-content-model",
- severity: "error",
- message: "Placing element inside a
violates HTML spec.",
+ severity: "warning",
+ message: "Placing
element inside a