Je me posais la question depuis un moment. Voici une preuve de concept (notez qu’elle ne résout pas le problème de la suppression des barres de défilement des iframes).
Ajoutez une balise script au message que vous intégrez :
<script>
function sendHeight() {
const body = document.body,
html = document.documentElement;
const height = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
window.parent.postMessage({
'iframeHeight': height,
'iframeId': 'zalgFrame' // Utilisez un identifiant unique si vous avez plusieurs iframes
}, '*'); // Envisagez de spécifier le domaine parent pour la sécurité
}
// Envoyer la hauteur initiale
window.onload = sendHeight;
// Optionnel : Mettre à jour la hauteur lors du redimensionnement ou d'autres événements
window.onresize = sendHeight;
</script>
J’utilise l’identifiant "zalgFrame" dans le script.
Dans votre thème Discourse :
<script type="text/discourse-plugin" version="1.29.0">
let iframeHeight, iframeId;
window.addEventListener('message', (event) => {
if (event.origin !== "http://wp-discourse.test") return; // mon domaine de test, mettez-le à jour vers votre domaine ou commentez-le
// récupère la hauteur de l'iframe passée depuis `wp-discourse.test` et confirme que l'iframeId correspond à l'iframeID que j'y ai défini
if (event.data.iframeHeight && event.data.iframeId === 'zalgFrame') {
// visitez la page Discourse avec l'iframe avec votre console ouverte
// vous devriez voir les hauteurs mises à jour envoyées depuis le site parent lorsque vous redimensionnez la fenêtre
console.log("we got an event:" + event.data.iframeHeight);
iframeHeight = event.data.iframeHeight;
iframeId = event.data.iframeId;
}
}, false);
</script>
Dans un message Discourse :
<div data-iframe-test-one>
<iframe src="http://wp-discourse.test/zalg_iframe/this-is-a-test-this-is-only-a-test/" width="100%" height="1659"></iframe>
</div>
Il est donc possible d’obtenir la hauteur réelle de l’iframe rendu depuis la fenêtre parente.
Je ne sais pas comment obtenir la hauteur à partir des données de l’écouteur d’événements pour l’appeler avec api.decorateCookedElement. Je ne suis pas sûr que cela suffirait à supprimer la barre de défilement verticale des iframes longs. Si j’essaie de coder en dur une grande hauteur (1600px) dans l’élément iframe, je me retrouve toujours avec une barre de défilement.
Edit : pour plus de complétude :
<script type="text/discourse-plugin" version="1.29.0">
api.decorateCookedElement(
(e) => {
let iframeHeight, iframeId;
function handleMessage(event) {
if (event.origin !== "http://wp-discourse.test") return;
if (event.data.iframeHeight && event.data.iframeId === "zalgFrame") {
iframeHeight = event.data.iframeHeight;
iframeId = event.data.iframeId;
// basé sur l'hypothèse qu'il n'y aura qu'un seul iframe enveloppé dans la div data-zalgFram
let iframe = e.querySelector("[data-zalgFrame] iframe");
if (iframe) {
iframe.style.height = `${iframeHeight}px`;
}
// après avoir défini la hauteur réelle rendue de l'iframe
// supprimer l'écouteur d'événements
window.removeEventListener("message", handleMessage, false);
}
}
window.addEventListener("message", handleMessage, false);
},
{ id: "component-id", onlyStream: true }
);
</script>
Pour tout ce qui dépasse ~1000px de hauteur, il ne semble y avoir aucun moyen d’éviter qu’une barre de défilement ne soit ajoutée par Discourse, je ne recommande donc pas cette approche.
Je pense que la réponse à la question initiale est que c’est en quelque sorte possible, mais que cela n’apporte probablement pas grand-chose. (Sauf que j’ai découvert la méthode window.postMessage() 