mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-01 10:14:34 +08:00
## Summary When Discourse is loaded in full app embed mode with `dynamicHeight: true`, the iframe was not resizing in production despite `discourse-resize` messages arriving correctly. The full app path sets `iframe.style.height` as an inline style for the initial height. Inline styles always win over the `height` HTML attribute, so our resize handler — which set `iframe.height = ...` — had no visible effect. This changes the resize handler to set `iframe.style.height` so it actually overrides the inline style. This also works for the standard (non-full-app) embed path since no inline style is set there initially. ## Test plan - [ ] Full app embed with `dynamicHeight: true` — verify iframe height updates as content loads - [ ] Standard (non-full-app) embed — verify iframe still resizes correctly - [ ] CSS `max-height` on the iframe still wins (inline `height` doesn't override `max-height`)
124 lines
3 KiB
JavaScript
124 lines
3 KiB
JavaScript
(function () {
|
|
var DE = window.DiscourseEmbed || {};
|
|
var comments = document.getElementById("discourse-comments");
|
|
var iframe = document.createElement("iframe");
|
|
|
|
[
|
|
"discourseUrl",
|
|
"discourseEmbedUrl",
|
|
"discourseUserName",
|
|
"discourseReferrerPolicy",
|
|
].forEach(function (i) {
|
|
if (window[i]) {
|
|
DE[i] = DE[i] || window[i];
|
|
}
|
|
});
|
|
|
|
var queryParams = {};
|
|
|
|
if (DE.discourseEmbedUrl) {
|
|
if (DE.discourseEmbedUrl.startsWith("/")) {
|
|
console.error(
|
|
"discourseEmbedUrl must be a full URL, not a relative path"
|
|
);
|
|
}
|
|
|
|
queryParams.embed_url = encodeURIComponent(DE.discourseEmbedUrl);
|
|
}
|
|
|
|
if (DE.discourseUserName) {
|
|
queryParams.discourse_username = DE.discourseUserName;
|
|
}
|
|
|
|
if (DE.topicId) {
|
|
queryParams.topic_id = DE.topicId;
|
|
}
|
|
|
|
if (DE.className) {
|
|
queryParams.class_name = DE.className;
|
|
}
|
|
|
|
if (DE.fullApp) {
|
|
queryParams.full_app = "true";
|
|
}
|
|
|
|
var src = DE.discourseUrl + "embed/comments";
|
|
var keys = Object.keys(queryParams);
|
|
if (keys.length > 0) {
|
|
src += "?";
|
|
|
|
for (var i = 0; i < keys.length; i++) {
|
|
if (i > 0) {
|
|
src += "&";
|
|
}
|
|
|
|
var k = keys[i];
|
|
src += k + "=" + queryParams[k];
|
|
}
|
|
}
|
|
|
|
iframe.src = src;
|
|
iframe.id = "discourse-embed-frame";
|
|
iframe.width = "100%";
|
|
iframe.frameBorder = "0";
|
|
iframe.scrolling = DE.fullApp ? "yes" : "no";
|
|
if (DE.fullApp) {
|
|
iframe.style.height = DE.embedHeight || "600px";
|
|
iframe.loading = DE.lazyLoad === false ? "eager" : "lazy";
|
|
}
|
|
iframe.referrerPolicy =
|
|
DE.discourseReferrerPolicy || "no-referrer-when-downgrade";
|
|
comments.appendChild(iframe);
|
|
|
|
// Thanks http://amendsoft-javascript.blogspot.ca/2010/04/find-x-and-y-coordinate-of-html-control.html
|
|
function findPosY(obj) {
|
|
var top = 0;
|
|
if (obj.offsetParent) {
|
|
while (1) {
|
|
top += obj.offsetTop;
|
|
if (!obj.offsetParent) break;
|
|
obj = obj.offsetParent;
|
|
}
|
|
} else if (obj.y) {
|
|
top += obj.y;
|
|
}
|
|
return top;
|
|
}
|
|
|
|
function normalizeUrl(url) {
|
|
return url.replace(/^https?(\:\/\/)?/, "");
|
|
}
|
|
|
|
function postMessageReceived(e) {
|
|
if (!e) {
|
|
return;
|
|
}
|
|
if (!normalizeUrl(DE.discourseUrl).includes(normalizeUrl(e.origin))) {
|
|
return;
|
|
}
|
|
|
|
if (e.data) {
|
|
if (e.data.type === "discourse-resize" && e.data.height) {
|
|
if (DE.fullApp && !DE.dynamicHeight) {
|
|
return;
|
|
}
|
|
|
|
var height = e.data.height;
|
|
if (DE.embedMinHeight) {
|
|
height = Math.max(height, parseInt(DE.embedMinHeight, 10));
|
|
}
|
|
if (DE.embedMaxHeight) {
|
|
height = Math.min(height, parseInt(DE.embedMaxHeight, 10));
|
|
}
|
|
iframe.style.height = height + "px";
|
|
}
|
|
|
|
if (e.data.type === "discourse-scroll" && e.data.top) {
|
|
// find iframe offset
|
|
var destY = findPosY(iframe) + e.data.top;
|
|
window.scrollTo(0, destY);
|
|
}
|
|
}
|
|
}
|
|
window.addEventListener("message", postMessageReceived, false);
|
|
})();
|