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
8 changes: 8 additions & 0 deletions packages/dom/src/clone-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ export function cloneNodeAndShadow(ctx) {
}
};

// A comment inside a <style> is raw text, not markup: templating libraries
// such as Lit leave empty marker comments there around bindings. Cloned, it
// serializes as a literal `<!---->` in the CSS, which the parser reads as a
// CDO/CDC token that swallows the declaration after it (PER-11066).
if (node.nodeType === 8 /* COMMENT_NODE */ && /^style$/i.test(node.parentNode.nodeName)) {
return;
}

if (node.nodeName === 'BASE') {
let clone = node.cloneNode(false);
parent.appendChild(clone);
Expand Down
21 changes: 21 additions & 0 deletions packages/dom/test/serialize-css.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -552,5 +552,26 @@ describe('serializeCSSOM', () => {
expect(clonedStyle.innerHTML).toBe(liveText);
expect(clonedStyle.getAttribute('data-percy-cssom-serialized')).toBeNull();
});

it('drops comment nodes inside <style>, keeping the declarations around them (PER-11066)', () => {
// Lit renders `<style>.grid { ${css} }</style>` with empty marker comments
// around the binding; serialized as `<!---->` they make `display: flex` drop.
withExample('<style id="lit-markers"></style><div class="grid"></div>', { withShadow: false });

let liveStyle = document.getElementById('lit-markers');
liveStyle.append(
'.grid {\n',
document.createComment(''),
' display: flex; gap: 16px; }',
document.createComment('')
);
expect(window.getComputedStyle(document.querySelector('.grid')).display).toBe('flex');

let $ = parseDOM(serializeDOM(), 'plain');
let clonedStyle = $('#lit-markers')[0];

expect(clonedStyle.innerHTML).not.toContain('<!--');
expect(clonedStyle.innerHTML).toBe(liveStyle.textContent);
});
});
});
Loading