/** * @name FollowingNotes * @author Julie Blanc * @see { @link https://gitlab.com/csspageweaver/plugins/followingNotes/ } */ import { Handler } from '/csspageweaver/lib/paged.esm.js'; export default class followingNotes extends Handler { constructor(chunker, polisher, caller) { super(chunker, polisher, caller); this.parameters = cssPageWeaver.features.followingNotes.parameters; this.notesClass = this.parameters?.selector || ".inline-note"; this.newNotesClass = this.parameters?.newNotesClass || "following-note"; this.reset = this.parameters?.reset; this.align = this.parameters?.align; this.followingNoteOverflow = new Set(); } beforeParsed(content) { console.log("floatnotes"); let newNotesClass = this.newNotesClass; resetCounter(content, this.reset, this.notesClass); createCallandMarker(content, this.notesClass, newNotesClass); let notes = content.querySelectorAll(this.notesClass); notes.forEach(function (note) { let paragraph = note.closest("p"); if (!paragraph) return; let container = paragraph.nextElementSibling; if (!container || !container.classList.contains("container-following-note")) { container = document.createElement("div"); container.classList.add("container-following-note"); paragraph.after(container); } container.appendChild(note); }); } } /// FUNCTIONS ----------------------------------------------------- // RESET COUNTER function resetCounter(content, reset, notesClass){ if(reset && reset != ""){ const elements = content.querySelectorAll(reset + ", " + notesClass); let resetEligible = false; elements.forEach(element => { if (element.matches(reset)) { resetEligible = true; } else if (resetEligible && element.matches(notesClass)) { element.dataset.resetCounterFollowingNote = true; resetEligible = false; } }); } } // CALL & MARKER function createCallandMarker(content, notesClass, newNotesClass){ let notes = content.querySelectorAll(notesClass); let resetNum = 0; notes.forEach(function (note, index) { if (note.dataset.resetCounterFollowingNote === "true") { resetNum = index; } let num = index + 1 - resetNum; note.classList.add(newNotesClass); note.dataset.counterNote = num; // call let ref_note = document.createElement('span'); ref_note.className = newNotesClass + "_call"; ref_note.dataset.counterNote = num; ref_note.innerHTML = num; // wrap preceding word + call in .wrapper__note-call let wrapper = document.createElement('span'); wrapper.className = 'wrapper__note-call'; let prevSibling = note.previousSibling; if (prevSibling && prevSibling.nodeType === Node.TEXT_NODE) { let text = prevSibling.textContent; let m = text.match(/^([\s\S]*\s)(\S+\s*)$/); if (m) { let before = m[1]; let extracted = m[2]; // Si le dernier mot extrait est uniquement », prendre aussi le mot d'avant if (/^»\s*$/.test(extracted)) { let m2 = before.trimEnd().match(/^([\s\S]*\s|)(\S+)$/); if (m2) { let spaceBetween = before.slice(m2[1].length + m2[2].length); before = m2[1]; extracted = m2[2] + spaceBetween + extracted; } } prevSibling.textContent = before; wrapper.appendChild(document.createTextNode(extracted)); } else { prevSibling.textContent = ''; wrapper.appendChild(document.createTextNode(text)); } } wrapper.appendChild(ref_note); note.after(wrapper); // marker + content note wrapped in body_note let marker_note = document.createElement('span'); marker_note.className = newNotesClass + "_marker"; //marker_note.innerHTML = num + ". "; marker_note.innerHTML = num; let body_note = document.createElement('div'); body_note.className = 'body_note'; while (note.firstChild) { body_note.appendChild(note.firstChild); } body_note.prepend(marker_note); note.appendChild(body_note); }); } // MARGINS function marginNoteTop(elem) { let marginTop = parseInt(window.getComputedStyle(elem).marginTop, 10) return marginTop; } function marginNoteBottom(elem) { let marginBottom = parseInt(window.getComputedStyle(elem).marginBottom, 10) return marginBottom; } function biggestMargin(a, b) { let margin; let marginBottom = marginNoteBottom(a); let marginTop = marginNoteTop(b); if (marginBottom > marginTop) { margin = marginBottom; } else { margin = marginTop; } return margin; } function checkOverflownote(notesClass, pageElement, maxHeight, arrayOverflow, container) { let notes = pageElement.querySelectorAll(notesClass); let notesHeightAll = []; for (let n = 0; n < notes.length; ++n) { // Add height of the notes to array notesHeightAll let noteHeight = notes[n].offsetHeight; notesHeightAll.push(noteHeight); // Add margins of the notes to array notesHeightAll if (n >= 1) { let margins = biggestMargin(notes[n - 1], notes[n]); notesHeightAll.push(margins); } } // If notes on page if (notesHeightAll.length > 0) { // Calculate if all notes fit on the page; let reducer = (accumulator, currentValue) => accumulator + currentValue; let allHeight = notesHeightAll.reduce(reducer); let paddingTop = getComputedStyle(container).paddingTop; let paddingContainer = parseInt(paddingTop); let totalHeight = allHeight + paddingContainer; if (totalHeight > maxHeight) { let lastNote = notes[notes.length - 1]; arrayOverflow.add(lastNote); lastNote.remove(); checkOverflownote(notesClass, pageElement, maxHeight, arrayOverflow, container); } } }