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
34 changes: 34 additions & 0 deletions php-transformer/src/HtmlToBlocks/HtmlTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -2165,6 +2165,10 @@ private function convertElement(DOMElement $element, array &$fallbacks, bool $ca
return $readableControlBlock;
}

if ( $this->preserveStandaloneFormControlAsRuntimeIsland($element) ) {
return null;
}

if ( $captureUnsupported ) {
$fallback = array(
'type' => 'unsupported_element',
Expand Down Expand Up @@ -5200,6 +5204,36 @@ private function readableFormControlBlockFromElement(DOMElement $element): ?arra
return $this->createBlock('core/paragraph', array_merge($this->presentationAttributes($element), array( 'content' => $summary )), array(), $element);
}

/**
* Preserve a standalone form control that has no faithful native block or
* readable static approximation as a bounded runtime island instead of an
* unsupported-element loss.
*
* Reached only after the readable-control and search paths decline, so the
* control is one whose behavior depends on a client runtime: file/hidden/
* color/date-style inputs core blocks cannot represent, or any control
* carrying inline event handlers. The source markup is carried in the
* island snippet so the behavior can be re-attached, and no misleading
* static text is emitted for controls (often hidden) that have no visual
* representation. This yields a `preserved_runtime_island` outcome rather
* than an `unsupported_element_loss`.
*/
private function preserveStandaloneFormControlAsRuntimeIsland(DOMElement $element): bool
{
$tagName = strtolower($element->tagName);
if ( ! in_array($tagName, array( 'input', 'select', 'textarea' ), true) ) {
return false;
}

$this->recordRuntimeIsland($element, 'control', 'form_control_requires_runtime', 'client_form_control_runtime', array(
'control' => $this->formControlMetadata($element),
'events' => $this->eventMetadata($element),
'required_scripts' => $this->requiredScriptsForElement($element),
));

return true;
}

/**
* @return array<string, mixed>|null
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"schema": "blocks-engine/php-transformer/parity-fixture/v1",
"name": "html-standalone-input-runtime-island-preserved",
"description": "Preserves a standalone non-readable form-control input (a hidden file picker) as a bounded runtime island with an acceptable runtime_island_preserved loss class instead of an unsupported_element_loss fallback.",
"source_reference": {
"repo": "php-transformer",
"path": "tests/fixtures/parity/html-standalone-input-runtime-island-preserved.json",
"notes": "Mirrors the corpus JSON-import file inputs in 58-infinite-whiteboard, 59-spreadsheet, 60-node-editor, 64-kanban-board, 67-dataviz-studio, and 68-drum-machine, which previously produced unsupported_input (html_unsupported_element) findings."
},
"legacy_comparison": {
"skip": true,
"reason": "This upstream primitive fixture has no downstream legacy comparison."
},
"operation": "html_transformer.transform",
"input": {
"content": "<input type=\"file\" id=\"import-file\" accept=\"application/json,.json\" hidden>"
},
"expected_blocks": [],
"expected_fallbacks": [],
"expect": [
{ "path": "status", "assert": "equals", "value": "success" },
{ "path": "blocks", "assert": "count", "count": 0 },
{ "path": "fallbacks", "assert": "count", "count": 0 },
{ "path": "source_reports.html.runtime_islands", "assert": "count", "count": 1 },
{ "path": "source_reports.html.runtime_islands.0.kind", "assert": "equals", "value": "control" },
{ "path": "source_reports.html.runtime_islands.0.tag", "assert": "equals", "value": "input" },
{ "path": "source_reports.html.runtime_islands.0.selector", "assert": "equals", "value": "#import-file" },
{ "path": "source_reports.html.runtime_islands.0.preservation_reason", "assert": "equals", "value": "form_control_requires_runtime" },
{ "path": "source_reports.html.runtime_islands.0.source_snippet", "assert": "contains", "value": "<input type=\"file\" id=\"import-file\"" },
{ "path": "diagnostics.1.code", "assert": "equals", "value": "preserved_runtime_island" },
{ "path": "diagnostics.1.loss_class", "assert": "equals", "value": "runtime_island_preserved" },
{ "path": "diagnostics.1.conversion_classification", "assert": "equals", "value": "runtime_island_preserved" },
{ "path": "coverage.0.fallback_count", "assert": "equals", "value": 0 },
{ "path": "serialized_blocks", "assert": "not_contains", "value": "<!-- wp:html" },
{ "path": "serialized_blocks", "assert": "not_contains", "value": "<input" }
]
}
Loading