From b282797767e6980ebad340e352bef4b0552c150d Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 14 Aug 2026 16:35:02 +0200 Subject: Move the revision picker into admin_interface.js --- app/views/revisions/index.html.erb | 62 ------------------------------- public/javascripts/admin_interface.js | 70 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 62 deletions(-) diff --git a/app/views/revisions/index.html.erb b/app/views/revisions/index.html.erb index e951016f..4f854518 100644 --- a/app/views/revisions/index.html.erb +++ b/app/views/revisions/index.html.erb @@ -66,65 +66,3 @@ <% end %> - -<%= javascript_tag nonce: true do %> - (function () { - var table = document.getElementById('revisions'); - var form = document.getElementById('diff_form'); - if (!table || !form) { return; } - - var from_field = form.querySelector('input[name="start_revision"]'); - var to_field = form.querySelector('input[name="end_revision"]'); - var from_label = document.getElementById('diff_from'); - var to_label = document.getElementById('diff_to'); - var readout = document.getElementById('diff_selection_label'); - var submit = form.querySelector('input[type="submit"]'); - var rows = table.querySelectorAll('tbody tr'); - - // Two-slot FIFO: the newest pick becomes the target and the previous - // target becomes the source, so two taps anywhere give any pair. - // Picking the current target is a no-op; picking the current source - // swaps them. - var stack = [from_field.value, to_field.value].filter(function (v) { return v !== ''; }); - - function render() { - var from = stack[0] || ''; - var to = stack[1] || ''; - from_field.value = from; - to_field.value = to; - from_label.textContent = from; - to_label.textContent = to; - readout.hidden = !(from && to); - submit.disabled = !(from && to && from !== to); - - rows.forEach(function (row) { - var rev = row.dataset.revision; - row.classList.toggle('diff_source', rev === from); - row.classList.toggle('diff_target', rev === to); - row.setAttribute('aria-pressed', (rev === from || rev === to) ? 'true' : 'false'); - }); - } - - function pick(rev) { - if (rev === stack[1]) { return; } - stack.push(rev); - if (stack.length > 2) { stack.shift(); } - render(); - } - - rows.forEach(function (row) { - row.addEventListener('click', function (e) { - if (e.target.closest('a, button, input, label')) { return; } - pick(row.dataset.revision); - }); - row.addEventListener('keydown', function (e) { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - pick(row.dataset.revision); - } - }); - }); - - render(); - })(); -<% end %> diff --git a/public/javascripts/admin_interface.js b/public/javascripts/admin_interface.js index cbfa4dc6..b7cb1964 100644 --- a/public/javascripts/admin_interface.js +++ b/public/javascripts/admin_interface.js @@ -86,6 +86,10 @@ $(document).ready(function () { cccms.preview.initialize(); } + if (document.getElementById('revisions')) { + initialize_revision_diff_picker.initialize(); + } + var metadata_details = document.getElementById('metadata_details'); if (metadata_details) { var desktop_mq = window.matchMedia('(min-width: 1016px)'); @@ -559,3 +563,69 @@ rrule_builder = { } } }; + +initialize_revision_diff_picker = { + initialize : function() { + let table = document.getElementById('revisions'); + let rows = table.querySelectorAll('tbody tr'); + let form = document.getElementById('diff_form'); + let from_field = form.querySelector('input[name="start_revision"]'); + let to_field = form.querySelector('input[name="end_revision"]'); + + // Two-slot FIFO: the newest pick becomes the target and the previous + // target becomes the source, so two taps anywhere give any pair. + // Picking the current target is a no-op, picking the current source + // swaps them. + this.stack = [from_field.value, to_field.value].filter(function (v) { return v !== ''; }); + + rows.forEach(function (row) { + row.addEventListener('click', function (e) { + if (e.target.closest('a, button, input, label')) { return; } + initialize_revision_diff_picker.pick(row.dataset.revision); + }); + row.addEventListener('keydown', function (e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + initialize_revision_diff_picker.pick(row.dataset.revision); + } + }); + }); + + this.render(); + }, + + render : function() { + let table = document.getElementById('revisions'); + let rows = table.querySelectorAll('tbody tr'); + let form = document.getElementById('diff_form'); + let from_field = form.querySelector('input[name="start_revision"]'); + let to_field = form.querySelector('input[name="end_revision"]'); + let submit = form.querySelector('input[type="submit"]'); + let readout = document.getElementById('diff_selection_label'); + let from_label = document.getElementById('diff_from'); + let to_label = document.getElementById('diff_to'); + + let from = this.stack[0] || ''; + let to = this.stack[1] || ''; + from_field.value = from; + from_label.textContent = from; + to_field.value = to; + to_label.textContent = to; + readout.hidden = !(from && to); + submit.disabled = !(from && to && from !== to); + + rows.forEach(function (row) { + var rev = row.dataset.revision; + row.classList.toggle('diff_source', rev === from); + row.classList.toggle('diff_target', rev === to); + row.setAttribute('aria-pressed', (rev === from || rev === to) ? 'true' : 'false'); + }); + }, + + pick : function(rev) { + if (rev === this.stack[1]) { return; } + this.stack.push(rev); + if (this.stack.length > 2) { this.stack.shift(); } + this.render(); + } +}; -- cgit v1.3