Refactor live preview and make it work on safari

This commit is contained in:
Gabriel Augendre 2020-12-29 20:04:51 +01:00
parent 4e89c1798d
commit eae1baa326
No known key found for this signature in database
GPG key ID: 1E693F4CE4AEE7B4

View file

@ -1,56 +1,67 @@
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
let preview = null;
window.onload = function () {
const previewButton = document.querySelector("input#_live_preview");
previewButton.addEventListener("click", event => {
event.preventDefault();
const params = "width=800,height=1000,menubar=no,toolbar=no,location=no,status=no,resizable=yes,scrollbars=yes";
if (preview !== null) {
preview.close();
}
preview = window.open("about:blank", "Preview", params);
const id = Number(window.location.pathname.match(/\d+/)[0]);
const loadPreview = debounce(function () {
const body = new FormData();
const articleContent = document.getElementById("id_content").value;
body.set("content", articleContent);
const csrfToken = document.querySelector("input[name=csrfmiddlewaretoken]").value;
body.set("csrfmiddlewaretoken", csrfToken);
fetch(`/api/render/${id}/`, {method: "POST", body: body})
.then(function (response) {
response.text().then(value => {
preview.document.querySelector("html").innerHTML = value
});
})
}, 500);
preview.onload = loadPreview;
const content = document.getElementById("id_content");
content.addEventListener("input", event => {
event.preventDefault();
loadPreview();
});
})
previewButton.addEventListener("click", openPreviewPopup);
};
window.onbeforeunload = function () {
if (preview !== null) {
preview.close();
}
};
let preview = null;
function openPreviewPopup(event) {
event.preventDefault();
const params = "width=800,height=1000,menubar=no,toolbar=no,location=no,status=no,resizable=yes,scrollbars=yes";
if (preview !== null) {
preview.close();
}
preview = window.open("about:blank", "Preview", params);
setTimeout(loadPreview, 1000);
setupLivePreview();
}
function loadPreview() {
const id = Number(window.location.pathname.match(/\d+/)[0]);
const body = new FormData();
const articleContent = document.getElementById("id_content").value;
body.set("content", articleContent);
const csrfToken = document.querySelector("input[name=csrfmiddlewaretoken]").value;
body.set("csrfmiddlewaretoken", csrfToken);
fetch(`/api/render/${id}/`, {method: "POST", body: body})
.then(function (response) {
response.text().then(value => {
preview.document.open("text/html", "replace");
preview.document.write(value);
preview.document.close();
});
})
}
function setupLivePreview() {
const debouncedLoadPreview = debounce(loadPreview, 500);
const content = document.getElementById("id_content");
content.addEventListener("input", event => {
event.preventDefault();
debouncedLoadPreview();
});
}
/**
* Returns a function, that, as long as it continues to be invoked, will not
* be triggered. The function will be called after it stops being called for
* `wait` milliseconds.
*/
function debounce(func, wait) {
let timeout;
return function () {
const context = this, args = arguments;
const later = function () {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}