feat: annotate inside/contains overflow metrics with clipping awareness
- insidePredicate: add hasClippedOverflow=1 when reference element clips its content (contain:paint or overflow:hidden) and the subject overflows beyond the reference bounds - containsPredicate: same, checking the subject (container) clips - Reads world.clipping table to determine if the container clips - Safe when clipping data is absent (unit test fixtures)
This commit is contained in:
@@ -459,7 +459,7 @@ export const insidePredicate: PredicateEvaluator = {
|
||||
sRect.top >= rRect.top - effectiveTolerance &&
|
||||
sRect.right <= rRect.right + effectiveTolerance &&
|
||||
sRect.bottom <= rRect.bottom + effectiveTolerance;
|
||||
const metrics = {
|
||||
const metrics: Record<string, number> = {
|
||||
overflowLeft: Math.max(0, rRect.left - sRect.left),
|
||||
overflowTop: Math.max(0, rRect.top - sRect.top),
|
||||
overflowRight: Math.max(0, sRect.right - rRect.right),
|
||||
@@ -476,6 +476,16 @@ export const insidePredicate: PredicateEvaluator = {
|
||||
refRight: rRect.right,
|
||||
refBottom: rRect.bottom,
|
||||
};
|
||||
const hasOverflow = metrics.overflowLeft > 0 || metrics.overflowTop > 0
|
||||
|| metrics.overflowRight > 0 || metrics.overflowBottom > 0;
|
||||
if (hasOverflow && world.clipping?.subjectId) {
|
||||
for (let i = 0; i < world.clipping.subjectId.length; i++) {
|
||||
if (world.clipping.subjectId[i] === referenceId) {
|
||||
metrics.hasClippedOverflow = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const diagnostics = pass ? undefined : makePredicateDiagnostic('inside', metrics, [subjectId, referenceId]);
|
||||
return makePredicateResult(pass ? 'true' : 'false', metrics, [subjectId, referenceId], diagnostics);
|
||||
},
|
||||
@@ -499,7 +509,7 @@ export const containsPredicate: PredicateEvaluator = {
|
||||
rRect.top >= sRect.top - tolerance &&
|
||||
rRect.right <= sRect.right + tolerance &&
|
||||
rRect.bottom <= sRect.bottom + tolerance;
|
||||
const metrics = {
|
||||
const metrics: Record<string, number> = {
|
||||
tolerance,
|
||||
subjectLeft: sRect.left,
|
||||
subjectTop: sRect.top,
|
||||
@@ -510,6 +520,20 @@ export const containsPredicate: PredicateEvaluator = {
|
||||
refRight: rRect.right,
|
||||
refBottom: rRect.bottom,
|
||||
};
|
||||
const overflowLeft = Math.max(0, sRect.left - rRect.left);
|
||||
const overflowTop = Math.max(0, sRect.top - rRect.top);
|
||||
const overflowRight = Math.max(0, rRect.right - sRect.right);
|
||||
const overflowBottom = Math.max(0, rRect.bottom - sRect.bottom);
|
||||
if (overflowLeft > 0 || overflowTop > 0 || overflowRight > 0 || overflowBottom > 0) {
|
||||
if (world.clipping?.subjectId) {
|
||||
for (let i = 0; i < world.clipping.subjectId.length; i++) {
|
||||
if (world.clipping.subjectId[i] === subjectId) {
|
||||
metrics.hasClippedOverflow = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const diagnostics = pass ? undefined : makePredicateDiagnostic('contains', metrics, [subjectId, referenceId]);
|
||||
return makePredicateResult(pass ? 'true' : 'false', metrics, [subjectId, referenceId], diagnostics);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user