b-fuze / deno-dom

Browser DOM & HTML parser in Deno
https://jsr.io/@b-fuze/deno-dom
MIT License
425 stars 47 forks source link

Setting innerHTML with lots of nodes fails with: Maximum call stack size exceeded #129

Closed Sembiance closed 2 years ago

Sembiance commented 2 years ago

Using v0.1.35-alpha and deno 1.26.1 if you attempt to use .innerHTML = "..." and there is a LOT of data, it will fail with an exception.

Extract the attached test.zip and run the following: deno run --allow-read=test.html,newLines.html test.js

The test.js file is as follows:

import {initParser as initDOMParser, DOMParser} from "https://deno.land/x/deno_dom@v0.1.35-alpha/deno-dom-wasm-noinit.ts";

await initDOMParser();

const doc = new DOMParser().parseFromString(await Deno.readTextFile("test.html"), "text/html");
doc.querySelector("ol").innerHTML = await Deno.readTextFile("newLines.html");

It will read and parse test.html and then attempt to insert into a node via .innerHTML the HTML content in newLines.html

The following error occurs:

error: Uncaught (in promise) RangeError: Maximum call stack size exceeded
      mutator.push(...parsed.childNodes[0].childNodes);
              ^
    at Element.set innerHTML (https://deno.land/x/deno_dom@v0.1.35-alpha/src/dom/element.ts:619:15)
    at file:///tmp/test.js:6:35

This is due to the use of the spread operator and there being too many items in the parsed childNodes to call push. This of course applies to anywhere else that you use the spread operator.

A workaround would be to manually iterate over all the elements and push them in 1 by 1 or use .concat()

b-fuze commented 2 years ago

Thanks for reporting this. It looks like the best solution is just to iterate over them manually 🤔