feat: flag empty JS-populated containers during html intake - #890
Open
faisalahammad wants to merge 1 commit into
Open
feat: flag empty JS-populated containers during html intake#890faisalahammad wants to merge 1 commit into
faisalahammad wants to merge 1 commit into
Conversation
…ic#514) Direct-HTML intake (pasted HTML, URL, .html upload) now scans the raw body for empty container elements that carry client-side rendering signals before conversion. When found, an informational empty_js_populated_container diagnostic is appended to the import report and classified as unsupported_loss, so the gap is declared instead of silently producing an empty block. Detection is deliberately conservative to avoid false positives on legitimate empty spacer and layout divs. A container is flagged only when it has no element or meaningful-text children and either carries a non-internal data-* attribute, or pairs an app-shell id (root, app, __next, gatsby, mount) with a content-name token (grid, products, listing, featured, catalog, items, shelf, collection). The diagnostic is non-blocking (severity info), never aborts the import, and is not counted in empty_conversion_count. Whole-page CSR shells are already caught by the client_rendered_app_shell fetch guard; this covers the unhandled interior empty-container case. Adds a standalone PHP smoke covering the flagged and ignored cases, including the exact ticket example which must not be flagged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Direct-HTML intake (pasted HTML, public URL, or
.htmlupload) now scans the raw body for empty container elements that carry client-side rendering signals, before conversion. When found, an informationalempty_js_populated_containerdiagnostic is appended to the import report and classified asunsupported_loss. This declares the gap instead of silently producing an empty block.Fixes #514
Changes
includes/class-static-site-importer-page-materializer.php
Adds
find_empty_js_populated_containers()andempty_js_populated_container_diagnostic(), called from the'html'body-format branch ofsource_page_content_blocks()beforehtml_to_blocks().Why: A CSR container ships as
<div id="featuredGrid" class="wp-block-group grid"></div>that JS fills at runtime against a data fetch. The importer only sees the static snapshot, so that content is silently absent. This mirrors the existinghtml_to_blocks_empty_outputprecedent: the diagnostic flows into$report['diagnostics']automatically, with no finding-packet or quality-gate wiring.Detection is deliberately conservative to avoid false positives on legitimate empty spacer and layout divs. A container (
div|section|main|article|ul|ol) is flagged only when it has no element or meaningful-text children (comments and whitespace ignored) and either:data-*attribute (any except thedata-ssi-*namespace), orid(root,app,__next,gatsby,mount) with a content-name token inid/class(grid,products,product-list,listing,featured,catalog,items,shelf,collection).So a bare
<div class="grid">or<div class="spacer">is never reported, and neither is the exact ticket example<div id="featuredGrid" class="wp-block-group grid"></div>(content-name without an app-shell id or a data hook).The diagnostic is non-blocking (
severity: info), never aborts the import, and is not counted inempty_conversion_count. Whole-page CSR shells are already rejected by the existingclient_rendered_app_shellfetch guard (url-fetcher.php); this change covers the unhandled interior empty-container case.tests/smoke-empty-js-populated-container.php (new)
Standalone PHP smoke with 13 assertions covering the flagged and ignored cases:
*carrier flagged, app-shell id + content class flaggeddata-ssi-*internal attributes excludedunsupported_lossRegistered in
test-manifest.jsonand itshomeboy-test-manifest.jsonstandalone projection.Testing
Test 1: Detection
<div data-slider-container></div>or<section id="products" data-products></section>Result: an
empty_js_populated_containerdiagnostic appears withseverity: infoandloss_class: unsupported_loss.Test 2: No false positives
<div class="spacer"></div>,<div class="grid"></div>, and the ticket case<div id="featuredGrid" class="wp-block-group grid"></div>Result: no diagnostic is emitted.
Automated
php tests/smoke-empty-js-populated-container.php- 13 assertions passphp tests/smoke-diagnostic-loss-classes.php- regression still passesnpm test- 55 passed, 0 failed, manifest inventory in syncphpcs --standard=WordPress- zero new violations (7 remaining are all pre-existing on main)