[Bug]: rebuild() removes all attributes from an <img> that has srcset and rr_dataURL
Preflight Checklist
- I have searched the issue tracker for a bug report that matches the one I want to file, without success.
What package is this bug report for?
rrweb-snapshot
Version
2.0.1 and 2.1.4. Also on main.
Expected Behavior
An inlined <img> with srcset keeps alt, class, style, id and sizes after rebuild(). Only srcset moves to rrweb-original-srcset.
Actual Behavior
rebuild() removes every attribute except src. The image renders at natural size with no style.
Cause: packages/rrweb-snapshot/src/rebuild.ts, buildNode(), the branch that backs up srcset. It does not check name. For an img with srcset and rr_dataURL, every attribute in the loop goes into that branch.
} else if (
tagName === 'img' &&
n.attributes.srcset &&
n.attributes.rr_dataURL
) {
node.setAttribute('rrweb-original-srcset', n.attributes.srcset as string);
} else {
node.setAttribute(name, value.toString());Fix:
} else if (
+ name === 'srcset' &&
tagName === 'img' &&
- n.attributes.srcset &&
n.attributes.rr_dataURL
) {Steps to Reproduce
- Record a page with
inlineImages: trueand one<img>that hassrcsetand an inline style. - Replay it.
- The image has no style, class, alt or id.
Or, without a recording:
import { rebuild, createCache } from "rrweb-snapshot";
const PNG = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==";
const node = { type: 2, tagName: "img", id: 5, childNodes: [], attributes:
{ id: "x", alt: "hello", class: "c1", style: "width:40px", src: PNG, srcset: `${PNG} 1x`, rr_dataURL: PNG } };
const img = rebuild(node, { doc: document, cache: createCache(), UNSAFE_allowUnprotectedRebuild: true });
console.log(img.hasAttribute("style")); // false. Remove srcset from the node: true.Testcase Gist URL
Recording: two <img> nodes, same style (200x200, red border), same rr_dataURL. The first also has srcset. Correct: two red boxes. Bug: one.
Standalone repro (browser-only fiddle.html, plus a node script that runs 3 cases against 2.0.1 and 2.1.4): https://gist.github.com/SaintPepsi/6a3d3b1d699e0a68e6a6e52aeec0feb7
Additional Information
Introduced in #822. Real-world trigger: Next.js <Image fill>, which emits srcset plus style="position:absolute;inset:0;...". The image replays at natural size over the page.
Fix PR follows.
Source: rrweb-io/rrweb