Ghost/ghost/admin/app/components/gh-html-iframe.js
Kevin Ansfield 977e4d55f4 Fixed design settings preview losing scroll position when changing settings
refs https://github.com/TryGhost/Team/issues/1149

- replicated the visible iframe's `scrollTop` to the hidden iframe before swapping visibility between them so the scroll position remains consistent even though the contents and frames are fully reloaded and swapped
2021-10-19 13:52:47 +01:00

73 lines
2.2 KiB
JavaScript

import Component from '@glimmer/component';
import {action} from '@ember/object';
export default class GhHtmlIframeComponent extends Component {
iframes = [];
renderedIframe = 0;
toRenderIframe = 1;
get hiddenIframeStyle() {
return 'position: absolute; visibility: hidden; border: none;';
}
get visibleIframeStyle() {
return 'border: none;';
}
@action
replaceIframeContents() {
const iframe = this.iframes[this.toRenderIframe];
if (iframe && this.args.html) {
iframe.contentWindow.document.open();
iframe.contentWindow.document.write(this.args.html);
iframe.contentWindow.document.close();
// force swap of iframes after a set timeout to account for slower connections
// so we display _something_ in the iframe even though it's still loading
this.swapTimeout = setTimeout(() => {
this.swapIframes(iframe);
}, 500);
}
}
@action
registerIframe(iframe) {
this.iframes.push(iframe);
if (this.iframes.indexOf(iframe) === 0) {
iframe.style = this.visibleIframeStyle;
this.replaceIframeContents();
}
if (this.iframes.indexOf(iframe) === 1) {
iframe.style = this.hiddenIframeStyle;
}
}
@action
didLoad(event) {
if (this.isDestroyed || this.isDestroying) {
return;
}
this.swapIframes(event.target);
}
swapIframes(renderedIframe) {
if (this.isDestroyed || this.isDestroying) {
return;
}
window.clearTimeout(this.swapTimeout);
if (this.iframes.indexOf(renderedIframe) !== this.renderedIframe) {
this.iframes[this.toRenderIframe].contentDocument.body.scrollTop = this.iframes[this.renderedIframe].contentDocument.body.scrollTop;
this.iframes[this.toRenderIframe].style = this.visibleIframeStyle;
this.renderedIframe = this.toRenderIframe;
this.toRenderIframe = this.toRenderIframe === 0 ? 1 : 0;
this.iframes[this.toRenderIframe].style = this.hiddenIframeStyle;
}
}
}