await dv.view("scripts/timeline"); await dv.view("scripts/locations"); // Уровень видимости "глобальный" для этого файла let locationCounter = 0; // счётчик, если нужно что-то уникальное async function updateTimeline(dv) { // Удаляем предыдущую диаграмму const oldContainer = dv.container.querySelector(".mermaid-timeline"); if (oldContainer) { oldContainer.remove(); } const locations = Array.from(dv.container.querySelectorAll(".location")).map( (input) => input.value ); const characters = Array.from( dv.container.querySelectorAll(".character") ).map((input) => input.value); const currentDate = dv.container.querySelector(".currentDate").value; const startDate = dv.container.querySelector(".startDate").value; const endDate = dv.container.querySelector(".endDate").value; const pcsParticipationOnly = dv.container.querySelector( ".pcsParticipationOnly" ).checked; const includeRegionsParticipants = dv.container.querySelector( ".includeRegionsParticipants" ).checked; // Вызываем рендеринг таймлайна (важно, чтобы dv был виден в этой функции) dv.timeline.showTimeline( dv, locations, characters, currentDate, startDate, endDate, pcsParticipationOnly, includeRegionsParticipants ); } /** * Заполняем общий всеми заметками. */ function setupAutocomplete(dv, locationsDataList, tag) { // Получаем список всех заметок const notes = dv.pages(tag).file.name; // это массив названий файлов // Очищаем текущие опции (на случай повторных вызовов) locationsDataList.innerHTML = ""; notes.forEach((note) => { const option = document.createElement("option"); option.value = note; locationsDataList.appendChild(option); }); } /** * Добавляет новый блок с для локации */ function addListFormField(container, inputName, dataListName) { // locationsDataList const div = document.createElement("div"); div.className = "locationContainer"; // Обратите внимание, указываем list="locationsDataList", а // будет один на всю форму div.innerHTML = ` `; container.appendChild(div); // При удалении блока убираем сам
div.querySelector(".removeDiv").addEventListener("click", () => { div.remove(); }); } async function run_show_timeline_widget(...args) { let dv = args[0].arg1; // Чтобы не путаться, явно назовём dvParam let defaultLocations = args[0].arg2 || []; let defaultCurrentDate = args[0].arg3 || ""; let defaultStartDate = args[0].arg4 || ""; let defaultEndDate = args[0].arg5 || ""; let defaultPcsParticipationOnly = args[0].arg6 || false; let defaultIncludeRegionsParticipants = args[0].arg7 || false; let fullWidth = args[0].arg8 || false; // Добавляем стили для полной ширины (чтобы диаграмму можно было растянуть максимально), если fullWidth = true const markdownPreviewSizer = dv.container.closest( ".markdown-preview-view .markdown-preview-sizer" ); if (markdownPreviewSizer) { if (fullWidth) { markdownPreviewSizer.style.maxWidth = "none"; markdownPreviewSizer.style.margin = "0 1em"; } else { markdownPreviewSizer.style.maxWidth = ""; markdownPreviewSizer.style.margin = ""; } } // Сохраним глобально dv, если нужно использовать вне этой функции window.dv = dv; // Формируем HTML формы dv.container.innerHTML = `
`; const locationsContainer = dv.container.querySelector(".locationsContainer"); const addLocationButton = dv.container.querySelector(".addLocation"); const locationsDataList = dv.container.querySelector("#locationsDataList"); // общий datalist const charactersContainer = dv.container.querySelector(".characters"); const addCharacterButton = dv.container.querySelector(".addCharacter"); const charactersDataList = dv.container.querySelector("#charactersDataList"); // общий datalist // Заполним общий datalist всеми заметками (автозаполнение) setupAutocomplete(dv, locationsDataList, "#location"); setupAutocomplete(dv, charactersDataList, "#npc"); // Инициализируем поля по умолчанию defaultLocations.forEach((location) => { addListFormField(locationsContainer, "location", "locationsDataList"); locationsContainer.lastChild.querySelector(".location").value = location; }); // Добавляем новое поле по кнопке addLocationButton.addEventListener("click", () => { addListFormField(locationsContainer, "location", "locationsDataList"); }); // Добавляем новое поле по кнопке addCharacterButton.addEventListener("click", () => { addListFormField(charactersContainer, "character", "charactersDataList"); }); // Обновляем график при нажатии на кнопку dv.container .querySelector(".updateButton") .addEventListener("click", () => updateTimeline(dv)); dv.container .querySelector(".copyMermaidButton") .addEventListener("click", () => { if (window.lastGeneratedMermaidCode) { navigator.clipboard .writeText(window.lastGeneratedMermaidCode) .then(() => { // Можно добавить визуальную обратную связь const button = dv.container.querySelector(".copyMermaidButton"); const originalText = button.textContent; button.textContent = "Скопировано!"; setTimeout(() => { button.textContent = originalText; }, 1000); }) .catch((err) => { console.error("Ошибка при копировании: ", err); }); } }); updateTimeline(dv); } await run_show_timeline_widget(input);