mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-04 08:54:36 +03:00
Removed signup form preview flickering in Safari and improved responsiveness
no issue - In Safari, we'll poll longer before animating to the new iframe - Update the iframe immediately if the last change was a while ago, to improve responsiveness
This commit is contained in:
parent
feac482859
commit
0ae1dad2d2
@ -9,13 +9,15 @@ export default class Preview extends Component {
|
|||||||
|
|
||||||
@tracked
|
@tracked
|
||||||
iframes = [
|
iframes = [
|
||||||
{element: null, html: '', loading: true, style: ''},
|
{element: null, html: '', loading: false, style: ''},
|
||||||
{element: null, html: '', loading: true, style: ''}
|
{element: null, html: '', loading: false, style: ''}
|
||||||
];
|
];
|
||||||
|
|
||||||
@tracked
|
@tracked
|
||||||
visibleIframeIndex = 0;
|
visibleIframeIndex = 0;
|
||||||
|
|
||||||
|
lastChange = new Date();
|
||||||
|
|
||||||
get visibleHtml() {
|
get visibleHtml() {
|
||||||
return this.iframes[this.visibleIframeIndex].html;
|
return this.iframes[this.visibleIframeIndex].html;
|
||||||
}
|
}
|
||||||
@ -35,28 +37,70 @@ export default class Preview extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iframe.timer) {
|
||||||
|
clearTimeout(iframe.timer);
|
||||||
|
iframe.timer = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!iframe.element) {
|
if (!iframe.element) {
|
||||||
iframe.element = event.currentTarget;
|
iframe.element = event.currentTarget;
|
||||||
|
|
||||||
if (index === this.visibleIframeIndex) {
|
if (index === this.visibleIframeIndex) {
|
||||||
this.updateContent(index);
|
setTimeout(() => {
|
||||||
|
this.updateContent(index);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Finished loading this iframe
|
if (!iframe.loading) {
|
||||||
iframe.loading = false;
|
return;
|
||||||
this.visibleIframeIndex = index;
|
}
|
||||||
|
// We need to wait until the iframe is fully rendered. The onLoad is kinda okay in Chrome, but on Safari it is fired too early
|
||||||
|
// So we need to poll if needed
|
||||||
|
// Check if this iframe element has an iframe inside of the body
|
||||||
|
// If so, we need to wait for that iframe to load as well
|
||||||
|
const iframeElement = iframe.element.contentWindow.document.querySelector('iframe');
|
||||||
|
|
||||||
// Force tracked update
|
// Check that iframe contains a non empty body
|
||||||
this.iframes = [...this.iframes];
|
const hasChildren = iframeElement && iframeElement.contentWindow.document.body && iframeElement.contentWindow.document.body.children.length > 0;
|
||||||
|
|
||||||
|
if (hasChildren) {
|
||||||
|
// Finished loading this iframe
|
||||||
|
this.visibleIframeIndex = index;
|
||||||
|
|
||||||
|
// Force tracked update
|
||||||
|
this.iframes = [...this.iframes];
|
||||||
|
iframe.loading = false;
|
||||||
|
} else {
|
||||||
|
// Wait 50ms
|
||||||
|
iframe.timer = setTimeout(() => {
|
||||||
|
this.onLoad(index, event);
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action onChangeHtml() {
|
@action onChangeHtml() {
|
||||||
// Get next iframe
|
// Check if no loading iframes
|
||||||
throttle(this, this.throttledUpdate, 300, false);
|
if (!this.iframes[0].loading && !this.iframes[1].loading && this.lastChange < new Date() - 500) {
|
||||||
|
// We make it feel more responsive by updating the frame immediately, but only if the last change was more than 500ms ago
|
||||||
|
// otherwise we get a lot of flickering
|
||||||
|
|
||||||
|
this.lastChange = new Date();
|
||||||
|
this.throttledUpdate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update the iframe after 400ms, with 400ms in between
|
||||||
|
this.lastChange = new Date();
|
||||||
|
throttle(this, this.throttledUpdate, 400, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
throttledUpdate() {
|
throttledUpdate() {
|
||||||
|
const currentVisibleHtml = this.iframes[this.visibleIframeIndex].html;
|
||||||
|
if (currentVisibleHtml === this.args.html) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Update the invisible iframe content
|
// Update the invisible iframe content
|
||||||
const index = this.visibleIframeIndex === 0 ? 1 : 0;
|
const index = this.visibleIframeIndex === 0 ? 1 : 0;
|
||||||
this.updateContent(index);
|
this.updateContent(index);
|
||||||
@ -69,8 +113,9 @@ export default class Preview extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index === this.visibleIframeIndex && !iframe.loading) {
|
if (iframe.timer) {
|
||||||
return;
|
clearTimeout(iframe.timer);
|
||||||
|
iframe.timer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe.loading = true;
|
iframe.loading = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user