Skip to content
This repository was archived by the owner on Oct 14, 2026. It is now read-only.

Commit 460fe0b

Browse files
anuj-adobeCopilot
andcommitted
fix(html-analyzer): preserve map info content
Preserve each Google Maps InfoWindow header and body before removing the runtime root, while excluding close controls. Cover modern and legacy windows across browser, Cheerio, and markdown paths, and tighten the DOM shim semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent c219c67 commit 460fe0b

2 files changed

Lines changed: 45 additions & 17 deletions

File tree

‎packages/spacecat-shared-html-analyzer/src/html-filter.js‎

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,12 @@ const VIDEO_PLAYER_SELECTORS = [
101101
'.playkit-player', // Kaltura PlayKit
102102
].join(', ');
103103

104-
// Exact Google Maps runtime classes only; never match customer map wrappers by name or substring.
105-
// Open InfoWindow content is preserved before the runtime root is removed.
104+
// Match exact Google Maps runtime classes only, never customer wrappers by name or substring.
105+
// Preserve open InfoWindow headers/bodies, but not marker labels, overlays, or custom controls.
106106
const MAPS_RUNTIME_ROOT_SELECTOR = '.gm-style';
107107
const MAPS_CONTROL_SELECTORS = [
108108
// These controls can be detached from .gm-style in serialized or partial DOM snapshots.
109+
// LGLeeN is generated by Google and may change in a future Maps release.
109110
'.LGLeeN-keyboard-shortcuts-view',
110111
'.gm-style-cc',
111112
'.gm-bundled-control',
@@ -119,13 +120,13 @@ const MAPS_CONTROL_SELECTORS = [
119120
*/
120121
function removeMapWidgets(element) {
121122
element.querySelectorAll(MAPS_RUNTIME_ROOT_SELECTOR).forEach((mapRoot) => {
122-
const detailedInfoWindows = mapRoot.querySelectorAll('.gm-style-iw-d');
123-
const infoWindows = detailedInfoWindows.length
124-
? detailedInfoWindows
125-
: mapRoot.querySelectorAll('.gm-style-iw');
123+
mapRoot.querySelectorAll('.gm-style-iw').forEach((infoWindow) => {
124+
const contentParts = infoWindow.querySelectorAll('.gm-style-iw-ch, .gm-style-iw-d');
125+
const preservedNodes = contentParts.length ? contentParts : [infoWindow];
126126

127-
infoWindows.forEach((infoWindow) => {
128-
mapRoot.parentNode?.insertBefore(infoWindow, mapRoot);
127+
preservedNodes.forEach((node) => {
128+
mapRoot.parentNode.insertBefore(node, mapRoot);
129+
});
129130
});
130131
mapRoot.remove();
131132
});
@@ -139,13 +140,14 @@ function removeMapWidgets(element) {
139140
function removeMapWidgetsCheerio($) {
140141
$(MAPS_RUNTIME_ROOT_SELECTOR).each((i, mapRoot) => {
141142
const $mapRoot = $(mapRoot);
142-
const $detailedInfoWindows = $mapRoot.find('.gm-style-iw-d');
143-
const $infoWindows = $detailedInfoWindows.length
144-
? $detailedInfoWindows
145-
: $mapRoot.find('.gm-style-iw');
146-
147-
$infoWindows.each((j, infoWindow) => {
148-
$mapRoot.before(infoWindow);
143+
$mapRoot.find('.gm-style-iw').each((j, infoWindow) => {
144+
const $infoWindow = $(infoWindow);
145+
const $contentParts = $infoWindow.find('.gm-style-iw-ch, .gm-style-iw-d');
146+
const $preservedNodes = $contentParts.length ? $contentParts : $infoWindow;
147+
148+
$preservedNodes.each((k, node) => {
149+
$mapRoot.before(node);
150+
});
149151
});
150152
$mapRoot.remove();
151153
});

‎packages/spacecat-shared-html-analyzer/test/index.test.js‎

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,12 @@ function installBrowserDomParserShim() {
5454
if (!element || !$(element).parent().length) {
5555
return null;
5656
}
57+
const parentElement = $(element).parent()[0];
5758
return {
5859
insertBefore(child, reference) {
60+
if ($(reference.cheerioElement).parent()[0] !== parentElement) {
61+
throw new Error('NotFoundError');
62+
}
5963
$(reference.cheerioElement).before(child.cheerioElement);
6064
},
6165
};
@@ -405,18 +409,22 @@ describe('HTML Visibility Analyzer', () => {
405409
expect(text).to.not.include('Play Pause');
406410
});
407411

408-
it('should remove Google Maps widget container (.gm-style) and its label text', async () => {
412+
it('should preserve InfoWindow content while removing Google Maps runtime text', async () => {
409413
const html = `<html><body>
410414
<h1>Estaciones de servicio</h1>
411415
<p>Encuentra tu estación más cercana.</p>
412416
<div id="map-container">
413417
<div class="gm-style">
414418
<div class="gm-style-iw">
419+
<div class="gm-style-iw-chr">
420+
<div class="gm-style-iw-ch">Estación Repsol Centro</div>
421+
<button aria-label="Close">Close window</button>
422+
</div>
415423
<div class="gm-style-iw-d">
416-
<h2>Estación Repsol Centro</h2>
417424
<p>Calle Mayor 1, Madrid</p>
418425
</div>
419426
</div>
427+
<div class="gm-style-iw">Legacy InfoWindow: Sevilla office.</div>
420428
<div class="gm-bundled-control">
421429
<div class="gmnoprint">
422430
<div class="gm-svpc">Pegman</div>
@@ -437,6 +445,8 @@ describe('HTML Visibility Analyzer', () => {
437445
expect(text).to.include('Horario');
438446
expect(text).to.include('Estación Repsol Centro');
439447
expect(text).to.include('Calle Mayor 1, Madrid');
448+
expect(text).to.include('Legacy InfoWindow: Sevilla office.');
449+
expect(text).to.not.include('Close window');
440450
expect(text).to.not.include('Map data');
441451
expect(text).to.not.include('Pegman');
442452
expect(text).to.not.include('40.4168');
@@ -540,6 +550,11 @@ describe('HTML Visibility Analyzer', () => {
540550
<div>Sorry, we have no imagery here.</div>
541551
<div class="gm-style-cc">Map Data Terms</div>
542552
<div class="gm-style-iw">Open Madrid location details.</div>
553+
<div class="gm-style-iw">
554+
<div class="gm-style-iw-ch">Barcelona office.</div>
555+
<div class="gm-style-iw-d">Carrer de Mallorca 1.</div>
556+
<button>Close window</button>
557+
</div>
543558
</div>
544559
<gmp-map>
545560
<gmp-advanced-marker>Customer-authored marker details.</gmp-advanced-marker>
@@ -552,7 +567,10 @@ describe('HTML Visibility Analyzer', () => {
552567
expect(text).to.include('Office locations');
553568
expect(text).to.include('Real office content.');
554569
expect(text).to.include('Open Madrid location details.');
570+
expect(text).to.include('Barcelona office.');
571+
expect(text).to.include('Carrer de Mallorca 1.');
555572
expect(text).to.include('Customer-authored marker details.');
573+
expect(text).to.not.include('Close window');
556574
expect(text).to.not.include('Sorry, we have no imagery here');
557575
expect(text).to.not.include('Map Data');
558576
} finally {
@@ -619,13 +637,21 @@ describe('HTML Visibility Analyzer', () => {
619637
<div class="gm-style">
620638
<div>Sorry, we have no imagery here.</div>
621639
<div class="gm-style-cc">Map data ©2026 Google</div>
640+
<div class="gm-style-iw">
641+
<div class="gm-style-iw-ch">Madrid office.</div>
642+
<div class="gm-style-iw-d">Calle Mayor 1.</div>
643+
<button>Close window</button>
644+
</div>
622645
</div>
623646
<p>Madrid office details.</p>
624647
</body></html>`;
625648

626649
const { currentRenderedHtml } = await generateMarkdownDiff(serverHtml, clientHtml, false);
627650

628651
expect(currentRenderedHtml).to.include('Madrid office details.');
652+
expect(currentRenderedHtml).to.include('Madrid office.');
653+
expect(currentRenderedHtml).to.include('Calle Mayor 1.');
654+
expect(currentRenderedHtml).to.not.include('Close window');
629655
expect(currentRenderedHtml).to.not.include('Sorry, we have no imagery here.');
630656
expect(currentRenderedHtml).to.not.include('Map data');
631657
});

0 commit comments

Comments
 (0)