The second link in the previous message shows some methods of getting the translated HTML string back into the document. As long as you don’t reload the page, I don’t see why the content script would run again.
I suppose, to test your code, you could use insertAdjacentHTML()
to start.
I think it causes problems if you try to replace an entire document because you will likely lose your scripts, at least your event listeners. This SO question explains why.
I tried to replace an entire HTML file in place without reload and lost all the event listeners:
fetch('file.html')
.then( response => response.text() )
.then( result => {
let parser = new DOMParser(),
doc = parser.parseFromString( result, 'text/html' );
document.replaceChild( doc.documentElement, document.documentElement );
} );
There are several options that I can think of and probably better ones that I don’t know about. One is you don’t have to serialize the entire document, but could try only the body element. Or, you could still serialize the entire document, then use DOMParser to convert it, and extract the nodes you need from it and replace them in the document, using document.importNode() and node.replaceChild() or childNode.replaceWith() and forgot replaceChildren() for convenience.
Some MDN links on DOMParser: 1, 2, 3.
I don’t know what can or cannot be approved in an extension concerning adding content by HTML string. The documents read that one cannot use innerHTML
and I’m not sure about insertAdjacentHTML
. I think it is because scripts can be injected that way. If a DOMParser is used, as described in this Mozilla Discourse question at response 15, the scripts can be removed.
If the extension wouldn’t be approved using insertAdjacentHTML
, depending upon what you’re translating, perhaps you could traverse the document for all nodes that have textContent
, keep the node references in a JS array and pass an array of the text in the same order. Translate it and pass it back to the JS, and replace thetextContent
of all the nodes using the stored references.
There are many methods for traversing and manipulating the DOM such that it would appear that you could accomplish what you want using some set of methods. I’m far from an expert, but you’d think that if you serialized the entire document to string and used a DOMParser
to convert your translated string into a new HTML document, excluding script elements, there’d be a one-to-one correspondence between the DOM trees of the translated and untranslated documents, such that you could walk through the translated document and update node-by-node if necessary. That is, if you couldn’t replace the whole DOM tree at once.
This may just be more confusing than helpful but I hope you can find something useful in it.