tldr: I'm looking to keep the other text in the srcdoc attribute of an iframe alone, but only swap out the link to the stylesheet using vanilla Javascript.
Longer version:
I'm customizing a Publii blog template and embedding a Cusdis comment widget using their hosted JS SDK.
Publii makes use of HTML, CSS, Javascript, and Handlebars.
The Cusdis widget works by pasting the following code in your html document:
<div id="cusdis_thread"
data-host="https://cusdis.com"
data-app-id="{{ APP_ID }}"
data-page-id="{{ PAGE_ID }}"
data-page-url="{{ PAGE_URL }}"
data-page-title="{{ PAGE_TITLE }}"
>
<script async src="https://cusdis.com/js/cusdis.es.js"></script>
Then, the Cusdis SDK will find the element with id cusdis_thread
, then mount the iframe widget on it:
<iframe srcdoc='<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cusdis.com/js/style.css">
<base target="_parent" />
<link>
<script>
window.CUSDIS_LOCALE = undefined
window.__DATA__ = {"host":"https://cusdis.com","appId":"...","pageId":"...","pageUrl":"...","pageTitle":"..."}
</script>
</head>
<body>
<div id="root"></div>
<script src="https://cusdis.com/js/iframe.umd.js" type="module"
</script>
</body>
</html>'
style="width: 100%; border: 0px none; height: 323px;">
#document
</iframe>
My issue is the following:
- I want to edit the Cusdis widget's CSS so that the look goes better with my site.
- I've tried editing my own stylesheet and selecting Cusdis's CSS classes, but the changes aren't reflected in the output (even with !important). I suspect that it's because the widget generates an iframe, and the elements I want to edit are contained in the iframe.
- The workaround seems to be to replace the stylesheet in the iframe's "srcdoc" attribute with a link to another external stylesheet
Because the iframe is automatically generated by Cusdis's SDK, I can't edit that HTML on my end. I'm trying to find a way to replace the stylesheet in the generated iframe's srcdoc using vanilla Javascript.
Here is what I've tried:
Using setAttribute to replace the contents of the attribute:
document.querySelector("#cusdis_thread iframe").setAttribute('srcdoc', '<!DOCTYPE html><html><head><link rel="stylesheet" href="..."><base target="_parent" /><link><script> window.CUSDIS_LOCALE = undefined window.__DATA__ = {"host":"https://cusdis.com", appId":"...","pageId":"{{id}}","pageUrl":"{{url}}","pageTitle":"{{title}}"} </script> </head> <body> <div id="root"></div> <script src="https://cusdis.com/js/iframe.umd.js" type="module"> </script></body></html>');
Result: It worked in theory, but the comment section wasn't generated. When I inspected the code, the attribute's content was replaced. However, I'm using handlebars expressions {{}} to add the PAGE_ID, PAGE_URL, and PAGE_TITLE dynamically, but these expressions are kept inside the srcdoc (so, instead of the iframe displaying the actual URL in the window.__DATA__ =...
section, it's still showing the handlebars expression {{url}}).
So, I'm looking for a solution which will keep the other text in the srcdoc attribute alone, but only swap out the link to the stylesheet. Here are my attempts at this:
Using .replace to find the url of Cusdis's stylesheet and replacing it with my own:
document.querySelector("#cusdis_thread iframe").replace("https://cusdis.com/js/style.css", "...");
Result: it was ignored
Using setAttribute for just the stylesheet:
document.querySelector("#cusdis_thread iframe").setAttribute('srcdoc', '<link rel="stylesheet" href="...">');
Result: it was ignored