Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion php-transformer/src/ArtifactCompiler/ArtifactCompiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function compile(array $artifact): TransformerResult
);
$sourceReports['compiled_site'] = $this->compiledSiteReport($normalized, $entryPath, $documents['documents'], $assets, $blockTypes, $serializedBlocks);
$sourceReports['materialization_plan'] = ( new MaterializationPlanBuilder() )->fromCompiledSite($sourceReports['compiled_site']);
$sourceReports['runtime_dependency_parity'] = ( new RuntimeDependencyParityReport() )->fromArtifact($normalized['files'], $html, $serializedBlocks);
$sourceReports['runtime_dependency_parity'] = ( new RuntimeDependencyParityReport() )->fromArtifact($normalized['files'], $html, $serializedBlocks, $entryPath);
$provenance = array(
array(
'source_format' => 'artifact',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ final class RuntimeDependencyParityReport
* @param array<int, array<string, mixed>> $files
* @return array<string, mixed>
*/
public function fromArtifact(array $files, string $sourceHtml, string $generatedHtml): array
public function fromArtifact(array $files, string $sourceHtml, string $generatedHtml, string $sourcePath = ''): array
{
$sourceTargets = $this->sourceTargets($sourceHtml);
$sourceTargets = $this->sourceTargets($sourceHtml, $sourcePath);
$generatedTargets = $this->htmlTargets($generatedHtml);
$dependencies = array();
$findings = array();
Expand All @@ -39,9 +39,12 @@ public function fromArtifact(array $files, string $sourceHtml, string $generated
$exists = $this->targetExists($dependency, $generatedTargets);
$canvasApi = true === $dependency['canvas_api'] && 'canvas' === ($target['tag'] ?? '');
$dependencyRow = array_filter(array(
'source_path' => $target['source_path'] ?? $sourcePath,
'script_path' => $scriptPath,
'script_kind' => $scriptKind,
'selector' => $selector,
'target_id' => $target['id'] ?? '',
'target_class' => $target['class'] ?? '',
'target_kind' => $target['tag'] ?? '',
'dependency_kind' => $dependency['kind'],
'events' => $dependency['events'],
Expand All @@ -56,16 +59,24 @@ public function fromArtifact(array $files, string $sourceHtml, string $generated
}

$severity = 'telemetry' === $scriptKind ? 'info' : 'warning';
$repairBucket = $canvasApi ? 'runtime_canvas_target_preservation' : 'runtime_dom_target_preservation';
$findings[] = array_filter(array(
'code' => 'runtime_dependency_target_missing',
'severity' => $severity,
'source_path' => $target['source_path'] ?? $sourcePath,
'script_path' => $scriptPath,
'script_kind' => $scriptKind,
'selector' => $selector,
'target_id' => $target['id'] ?? '',
'target_class' => $target['class'] ?? '',
'target_kind' => $target['tag'] ?? '',
'dependency_kind' => $dependency['kind'],
'events' => $dependency['events'],
'canvas_api' => $canvasApi,
'repair_bucket' => $repairBucket,
'suggested_primitive' => $canvasApi ? 'runtime_canvas' : 'runtime_dom_target',
'actionability' => $canvasApi ? 'preserve_canvas_markup_with_matching_script_runtime_or_rebuild_canvas_behavior' : 'preserve_or_recreate_the_referenced_dom_target_for_script_runtime',
'materialization_hint' => $canvasApi ? 'preserve_canvas_id_class_and_markup_for_runtime_mapping' : 'preserve_id_class_or_wrapper_markup_required_by_first_party_script',
'message' => sprintf('Script %s references %s, but the generated block markup does not expose that DOM target.', $scriptPath, $selector),
), static fn (mixed $value): bool => null !== $value && '' !== $value && array() !== $value);
}
Expand All @@ -90,9 +101,9 @@ private function isScriptFile(array $file): bool
}

/**
* @return array<string, array{tag: string}>
* @return array<string, array{tag: string, source_path: string, id?: string, class?: string}>
*/
private function sourceTargets(string $html): array
private function sourceTargets(string $html, string $sourcePath): array
{
$targets = array();
$document = new DOMDocument();
Expand All @@ -111,11 +122,11 @@ private function sourceTargets(string $html): array
$tag = strtolower($element->tagName);
$id = trim($element->hasAttribute('id') ? $element->getAttribute('id') : '');
if ( '' !== $id ) {
$targets['#' . $id] = array('tag' => $tag);
$targets['#' . $id] = array('tag' => $tag, 'source_path' => $sourcePath, 'id' => $id);
}
foreach ( preg_split('/\s+/', trim($element->hasAttribute('class') ? $element->getAttribute('class') : '')) ?: array() as $class ) {
if ( '' !== $class ) {
$targets['.' . $class] = array('tag' => $tag);
$targets['.' . $class] = array('tag' => $tag, 'source_path' => $sourcePath, 'class' => $class);
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions php-transformer/tests/contract/run.php
Original file line number Diff line number Diff line change
Expand Up @@ -612,10 +612,17 @@ function serialize_blocks(array $blocks): string
$assert('blocks-engine/php-transformer/runtime-dependency-parity/v1' === ($runtimeDependencyReport['schema'] ?? ''), 'runtime dependency parity report exposes schema');
$assert($runtimeDependencyReport === $runtimeDependencyConversionReport, 'conversion report projects runtime dependency parity');
$assert('runtime_dependency_target_missing' === ($canvasFinding['code'] ?? ''), 'runtime dependency parity reports missing canvas DOM target');
$assert('index.html' === ($canvasFinding['source_path'] ?? ''), 'runtime dependency parity reports source path for missing canvas DOM target');
$assert('canvas' === ($canvasFinding['target_id'] ?? ''), 'runtime dependency parity reports missing canvas target id');
$assert('canvas' === ($canvasFinding['target_kind'] ?? ''), 'runtime dependency parity identifies canvas source target kind');
$assert(true === ($canvasFinding['canvas_api'] ?? null), 'runtime dependency parity flags canvas 2d API usage');
$assert('warning' === ($canvasFinding['severity'] ?? ''), 'first-party missing runtime dependency target is warning severity');
$assert('runtime_canvas_target_preservation' === ($canvasFinding['repair_bucket'] ?? ''), 'runtime dependency parity reports repair bucket for missing canvas DOM target');
$assert('runtime_canvas' === ($canvasFinding['suggested_primitive'] ?? ''), 'runtime dependency parity reports suggested primitive for missing canvas DOM target');
$assert(isset($canvasFinding['actionability']) && '' !== $canvasFinding['actionability'], 'runtime dependency parity reports actionability for missing canvas DOM target');
$assert(isset($canvasFinding['materialization_hint']) && '' !== $canvasFinding['materialization_hint'], 'runtime dependency parity reports materialization hint for missing canvas DOM target');
$assert(null !== $statusDependency, 'runtime dependency parity records preserved status container dependency');
$assert('index.html' === ($statusDependency['source_path'] ?? ''), 'runtime dependency parity records source path for preserved DOM dependency');
$assert(true === ($statusDependency['generated_present'] ?? null), 'runtime dependency parity passes preserved div id target');
$assert(! empty($statusDependency['events'] ?? array()), 'runtime dependency parity records simple addEventListener usage');
$assert('info' === ($rumFinding['severity'] ?? ''), 'telemetry-like runtime dependency misses are info severity');
Expand Down
Loading