From e0f2394fd0816ef03bf4b928ab9fa5a18c32ffda Mon Sep 17 00:00:00 2001 From: erdgeist Date: Tue, 14 Jul 2026 04:10:01 +0200 Subject: Add a toggleable live preview panel to both editors Hidden by default, shares horizontal space with the body editor once opened rather than a separate section, and only requests the iframe's src on first toggle -- no preview traffic at all until someone actually wants to see it. Refreshes automatically on every successful autosave; a separate force-render button re-attempts a save-and- refresh cycle immediately, for when the normal 7-second cycle has been interrupted (a lock-lost error, a transient failure) and waiting for the next tick isn't good enough. --- public/javascripts/admin_interface.js | 43 ++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'public/javascripts') diff --git a/public/javascripts/admin_interface.js b/public/javascripts/admin_interface.js index e3d4ff1..9da5d28 100644 --- a/public/javascripts/admin_interface.js +++ b/public/javascripts/admin_interface.js @@ -67,6 +67,10 @@ $(document).ready(function () { rrule_builder.initialize(); } + if ($("#preview_panel").length != 0) { + cccms.preview.initialize(); + } + if ($('#recent_changes_toggle').length != 0) { hide_all(); $('#recent_changes_toggle').attr("class", "selected"); @@ -165,7 +169,8 @@ cccms = { } jQuery.fn.submitWithAjax = function(options) { - if (page.title_has_changed() || page.abstract_has_changed() || page.body_has_changed()) { + options = options || {}; + if (options.force || page.title_has_changed() || page.abstract_has_changed() || page.body_has_changed()) { tinymce.triggerSave(); page.cached_title = elements.title.val(); @@ -181,6 +186,9 @@ cccms = { type: "POST", url: this.attr("data-autosave-url"), data: data, + success: function() { + cccms.preview.refresh_if_open(); + }, error: function(xhr) { if (xhr.status === 423) { clearInterval(cccms.autosave_timer); @@ -211,6 +219,39 @@ cccms = { $banner.append("."); $flash.html($banner); + }, + + preview : { + is_open : false, + + initialize : function() { + var $panel = $('#preview_panel'); + var $toggle = $('#preview_toggle'); + var $force = $('#preview_force_render'); + + $toggle.on('click', function() { + cccms.preview.is_open = !cccms.preview.is_open; + $panel.toggle(cccms.preview.is_open); + $force.toggle(cccms.preview.is_open); + $toggle.attr('aria-pressed', cccms.preview.is_open); + if (cccms.preview.is_open) cccms.preview.refresh(); + }); + + $force.on('click', function() { + $("#page_editor > form").submitWithAjax({ force: true }); + }); + }, + + refresh : function() { + var $iframe = $('#live_preview_iframe'); + if ($iframe.length === 0) return; + var base = $iframe.data('src'); + $iframe.attr('src', base + (base.indexOf('?') === -1 ? '?' : '&') + '_t=' + Date.now()); + }, + + refresh_if_open : function() { + if (cccms.preview.is_open) cccms.preview.refresh(); + } } } -- cgit v1.3