prima bozza sito sindacato
This commit is contained in:
commit
59ef4db64f
31 changed files with 1576 additions and 0 deletions
153
assets/js/csv-tables.js
Normal file
153
assets/js/csv-tables.js
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
function parseCsv(text) {
|
||||
var rows = [];
|
||||
var row = [];
|
||||
var field = '';
|
||||
var i = 0;
|
||||
var inQuotes = false;
|
||||
|
||||
while (i < text.length) {
|
||||
var ch = text[i];
|
||||
|
||||
if (inQuotes) {
|
||||
if (ch === '"') {
|
||||
if (text[i + 1] === '"') {
|
||||
field += '"';
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
inQuotes = false;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
field += ch;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === '"') {
|
||||
inQuotes = true;
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === ',') {
|
||||
row.push(field);
|
||||
field = '';
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === '\n') {
|
||||
row.push(field);
|
||||
rows.push(row);
|
||||
row = [];
|
||||
field = '';
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch === '\r') {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
field += ch;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (field.length > 0 || row.length > 0) {
|
||||
row.push(field);
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
return rows.filter(function (r) {
|
||||
return r.length > 1 || (r.length === 1 && r[0].trim() !== '');
|
||||
});
|
||||
}
|
||||
|
||||
function buildTable(headers, dataRows) {
|
||||
var table = document.createElement('table');
|
||||
table.className = 'csv-table__table';
|
||||
|
||||
var thead = document.createElement('thead');
|
||||
var headRow = document.createElement('tr');
|
||||
|
||||
headers.forEach(function (h) {
|
||||
var th = document.createElement('th');
|
||||
th.textContent = h;
|
||||
headRow.appendChild(th);
|
||||
});
|
||||
|
||||
thead.appendChild(headRow);
|
||||
table.appendChild(thead);
|
||||
|
||||
var tbody = document.createElement('tbody');
|
||||
dataRows.forEach(function (r) {
|
||||
var tr = document.createElement('tr');
|
||||
headers.forEach(function (_, idx) {
|
||||
var td = document.createElement('td');
|
||||
td.textContent = r[idx] !== undefined ? r[idx] : '';
|
||||
tr.appendChild(td);
|
||||
});
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
|
||||
table.appendChild(tbody);
|
||||
return table;
|
||||
}
|
||||
|
||||
function renderCsvTable(container) {
|
||||
var src = container.getAttribute('data-src');
|
||||
var countEl = container.querySelector('[data-csv-count]');
|
||||
var statusEl = container.querySelector('[data-csv-status]');
|
||||
var viewport = container.querySelector('[data-csv-viewport]');
|
||||
|
||||
if (!src || !viewport || !statusEl || !countEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(src)
|
||||
.then(function (response) {
|
||||
if (!response.ok) {
|
||||
throw new Error('HTTP ' + response.status);
|
||||
}
|
||||
return response.text();
|
||||
})
|
||||
.then(function (csvText) {
|
||||
var rows = parseCsv(csvText);
|
||||
|
||||
if (rows.length === 0) {
|
||||
statusEl.textContent = 'CSV vuoto.';
|
||||
countEl.textContent = 'Righe: 0';
|
||||
return;
|
||||
}
|
||||
|
||||
var headers = rows[0];
|
||||
var dataRows = rows.slice(1);
|
||||
var table = buildTable(headers, dataRows);
|
||||
|
||||
viewport.innerHTML = '';
|
||||
viewport.appendChild(table);
|
||||
|
||||
countEl.textContent = 'Righe: ' + dataRows.length;
|
||||
})
|
||||
.catch(function (error) {
|
||||
statusEl.textContent = 'Impossibile caricare il CSV (' + error.message + ').';
|
||||
countEl.textContent = 'Righe: n/d';
|
||||
});
|
||||
}
|
||||
|
||||
function initCsvTables() {
|
||||
var containers = document.querySelectorAll('[data-csv-table]');
|
||||
containers.forEach(renderCsvTable);
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initCsvTables);
|
||||
} else {
|
||||
initCsvTables();
|
||||
}
|
||||
})();
|
||||
106
assets/js/sidenotes.js
Normal file
106
assets/js/sidenotes.js
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**
|
||||
* sidenotes.js
|
||||
* Takes Hugo-rendered Goldmark footnotes and repositions them
|
||||
* as margin notes alongside the text that references them.
|
||||
*
|
||||
* Hugo/Goldmark renders footnotes as:
|
||||
* - References: <sup id="fnref:N"><a href="#fn:N">N</a></sup>
|
||||
* or <sup id="fnref1:N"><a href="#fn:N">N</a></sup> (for duplicate refs)
|
||||
* - Section: <section class="footnotes"> … <ol> <li id="fn:N"> … </li> </ol> </section>
|
||||
*/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const MARGIN_TOP_PX = 12; // minimum vertical gap between sidenotes
|
||||
|
||||
function initSidenotes() {
|
||||
const container = document.querySelector('.sidenote-layout .content-body');
|
||||
if (!container) return;
|
||||
|
||||
const footnotesSection = container.querySelector('.footnotes, section.footnotes');
|
||||
if (!footnotesSection) return;
|
||||
|
||||
// Collect all footnote reference <sup> elements
|
||||
const refs = container.querySelectorAll('sup[id^="fnref"]');
|
||||
if (refs.length === 0) return;
|
||||
|
||||
// Check viewport: skip sidenote placement on narrow screens
|
||||
if (window.innerWidth < 900) {
|
||||
container.classList.add('sidenotes-fallback');
|
||||
footnotesSection.style.display = '';
|
||||
return;
|
||||
}
|
||||
|
||||
let lastBottom = 0;
|
||||
|
||||
refs.forEach(function (sup) {
|
||||
// Get the footnote id from the <a> inside the <sup>
|
||||
const anchor = sup.querySelector('a[href^="#fn"]');
|
||||
if (!anchor) return;
|
||||
|
||||
const fnId = anchor.getAttribute('href').replace('#', '');
|
||||
const footnoteLi = footnotesSection.querySelector('#' + CSS.escape(fnId));
|
||||
if (!footnoteLi) return;
|
||||
|
||||
// Extract footnote content (skip the back-reference link)
|
||||
const clone = footnoteLi.cloneNode(true);
|
||||
const backlinks = clone.querySelectorAll('.footnote-backref, a[href^="#fnref"]');
|
||||
backlinks.forEach(function (bl) { bl.remove(); });
|
||||
const noteHTML = clone.innerHTML.trim();
|
||||
|
||||
// Extract footnote number from the sup text
|
||||
const noteNumber = anchor.textContent.trim();
|
||||
|
||||
// Create sidenote element
|
||||
const sidenote = document.createElement('span');
|
||||
sidenote.className = 'sidenote';
|
||||
sidenote.setAttribute('role', 'note');
|
||||
sidenote.innerHTML =
|
||||
'<span class="sidenote-number">' + noteNumber + '.</span> ' + noteHTML;
|
||||
|
||||
// Append to content-body (absolutely positioned)
|
||||
container.appendChild(sidenote);
|
||||
|
||||
// Position vertically aligned with the reference
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
const supRect = sup.getBoundingClientRect();
|
||||
let desiredTop = supRect.top - containerRect.top;
|
||||
|
||||
// Prevent overlap with previous sidenote
|
||||
if (desiredTop < lastBottom + MARGIN_TOP_PX) {
|
||||
desiredTop = lastBottom + MARGIN_TOP_PX;
|
||||
}
|
||||
|
||||
sidenote.style.top = desiredTop + 'px';
|
||||
|
||||
// Track the bottom of this sidenote for collision avoidance
|
||||
lastBottom = desiredTop + sidenote.offsetHeight;
|
||||
});
|
||||
|
||||
// Hide the original footnotes section
|
||||
footnotesSection.style.display = 'none';
|
||||
}
|
||||
|
||||
// Run on load
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initSidenotes);
|
||||
} else {
|
||||
initSidenotes();
|
||||
}
|
||||
|
||||
// Re-run on resize (debounced)
|
||||
let resizeTimer;
|
||||
window.addEventListener('resize', function () {
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(function () {
|
||||
// Remove existing sidenotes and re-init
|
||||
document.querySelectorAll('.sidenote').forEach(function (el) { el.remove(); });
|
||||
const fs = document.querySelector('.sidenote-layout .content-body .footnotes, .sidenote-layout .content-body section.footnotes');
|
||||
if (fs) fs.style.display = '';
|
||||
var fb = document.querySelector('.sidenotes-fallback');
|
||||
if (fb) fb.classList.remove('sidenotes-fallback');
|
||||
initSidenotes();
|
||||
}, 250);
|
||||
});
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue