Ansico-diagnosekoder/ansico-diagnosekoder/assets/js/frontend.js

775 lines
35 KiB
JavaScript
Raw Permalink Normal View History

2026-04-18 22:06:24 +00:00
(function () {
var favoriteCodes = [];
var codeLinks = {};
function getPageId(root) {
var value = root && root.getAttribute ? root.getAttribute('data-page-id') : '';
var pageId = parseInt(value || '0', 10);
if (!Number.isFinite(pageId) || pageId <= 0) {
var stateNode = root ? root.querySelector('.ansico-diagnosekoder__page-state') : null;
if (stateNode) {
try {
var state = JSON.parse(stateNode.textContent || '{}');
pageId = parseInt(state.pageId || '0', 10);
} catch (error) {}
}
}
if ((!Number.isFinite(pageId) || pageId <= 0) && typeof AnsicoDiagnosekoderConfig.resultsPageId !== 'undefined') {
pageId = parseInt(AnsicoDiagnosekoderConfig.resultsPageId || '0', 10);
}
if ((!Number.isFinite(pageId) || pageId <= 0) && document.body) {
var match = (document.body.className || '').match(/(?:^|\s)page-id-(\d+)(?:\s|$)/);
if (match) {
pageId = parseInt(match[1], 10);
}
}
return Number.isFinite(pageId) && pageId > 0 ? pageId : 0;
}
function preloadPageState(root) {
if (!root || !root.getAttribute) {
return;
}
var stateNode = root.querySelector('.ansico-diagnosekoder__page-state');
if (stateNode) {
try {
var state = JSON.parse(stateNode.textContent || '{}');
if (Array.isArray(state.favorites)) {
favoriteCodes = state.favorites.map(normalizeCode);
}
if (state.links && typeof state.links === 'object') {
codeLinks = {};
Object.keys(state.links).forEach(function (code) {
codeLinks[normalizeCode(code)] = state.links[code];
});
}
if (state.pageId && root.getAttribute('data-page-id') !== String(state.pageId)) {
root.setAttribute('data-page-id', String(state.pageId));
}
return;
} catch (error) {}
}
var favoritesRaw = root.getAttribute('data-page-favorites') || '[]';
var linksRaw = root.getAttribute('data-page-links') || '{}';
try {
var parsedFavorites = JSON.parse(favoritesRaw);
if (Array.isArray(parsedFavorites)) {
favoriteCodes = parsedFavorites.map(normalizeCode);
}
} catch (error) {}
try {
var parsedLinks = JSON.parse(linksRaw);
if (parsedLinks && typeof parsedLinks === 'object') {
codeLinks = {};
Object.keys(parsedLinks).forEach(function (code) {
codeLinks[normalizeCode(code)] = parsedLinks[code];
});
}
} catch (error) {}
}
function debounce(fn, delay) {
var timer;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
function escapeHtml(str) {
return String(str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
function escapeRegExp(str) {
return String(str).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function normalizeCode(code) {
return String(code || '').replace(/\s+/g, '').toUpperCase();
}
function highlightText(text, query) {
var safeText = escapeHtml(text);
var trimmedQuery = String(query || '').trim();
if (!trimmedQuery) {
return safeText;
}
var parts = trimmedQuery.split(/\s+/).filter(Boolean);
if (!parts.length) {
return safeText;
}
var pattern = parts.map(escapeRegExp).join('|');
return safeText.replace(new RegExp('(' + pattern + ')', 'gi'), '<mark class="ansico-diagnosekoder__highlight">$1</mark>');
}
function getCopyIcon() {
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M16 1H6c-1.1 0-2 .9-2 2v12h2V3h10V1zm3 4H10c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H10V7h9v14z"></path></svg>';
}
function getStarIcon(isActive) {
if (isActive) {
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="currentColor"></path></svg>';
}
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false" fill="none"><path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
}
function getPlusIcon() {
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 11H13V5h-2v6H5v2h6v6h2v-6h6z"></path></svg>';
}
function getMinusIcon() {
return '<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M19 11H5v2h14z"></path></svg>';
}
function isFavorite(code) {
return favoriteCodes.indexOf(normalizeCode(code)) !== -1;
}
function getLinkedUrl(code, fallback) {
var normalized = normalizeCode(code);
if (normalized && typeof codeLinks[normalized] === 'string' && codeLinks[normalized]) {
return codeLinks[normalized];
}
return fallback || '';
}
function setTemporaryLabel(button, label, duration) {
var originalLabel = button.getAttribute('data-label-default') || button.getAttribute('aria-label') || '';
button.setAttribute('aria-label', label);
button.classList.add('is-feedback-visible');
window.setTimeout(function () {
button.setAttribute('aria-label', originalLabel);
button.classList.remove('is-feedback-visible');
}, duration || 1400);
}
function pulseButton(button) {
button.classList.remove('is-pressed');
void button.offsetWidth;
button.classList.add('is-pressed');
window.setTimeout(function () {
button.classList.remove('is-pressed');
}, 220);
}
function copyText(value, button) {
var successLabel = button.getAttribute('data-label-success') || button.getAttribute('aria-label') || '';
var errorLabel = button.getAttribute('data-label-error') || button.getAttribute('aria-label') || '';
pulseButton(button);
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(value).then(function () {
setTemporaryLabel(button, successLabel, 1400);
}).catch(function () {
setTemporaryLabel(button, errorLabel, 1400);
});
return;
}
try {
var temp = document.createElement('textarea');
temp.value = value;
temp.setAttribute('readonly', 'readonly');
temp.style.position = 'absolute';
temp.style.left = '-9999px';
document.body.appendChild(temp);
temp.select();
document.execCommand('copy');
document.body.removeChild(temp);
setTemporaryLabel(button, successLabel, 1400);
} catch (error) {
setTemporaryLabel(button, errorLabel, 1400);
}
}
function searchInternalContent(query) {
if (!AnsicoDiagnosekoderConfig.contentSearchUrl) {
return Promise.resolve([]);
}
var url = AnsicoDiagnosekoderConfig.contentSearchUrl + '?q=' + encodeURIComponent(query) + '&limit=8';
return fetch(url, {
credentials: 'same-origin',
headers: {
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
},
cache: 'no-store'
}).then(function (response) {
if (!response.ok) {
throw new Error('Internal content search failed');
}
return response.json();
}).then(function (data) {
return Array.isArray(data.results) ? data.results : [];
});
}
function ensureLinkModal() {
var existing = document.getElementById('ansico-diagnosekoder-link-modal');
if (existing) {
return existing;
}
var wrapper = document.createElement('div');
wrapper.id = 'ansico-diagnosekoder-link-modal';
wrapper.className = 'ansico-diagnosekoder__modal';
wrapper.setAttribute('hidden', 'hidden');
wrapper.innerHTML = '' +
'<div class="ansico-diagnosekoder__modal-backdrop" data-modal-close="1"></div>' +
'<div class="ansico-diagnosekoder__modal-dialog" role="dialog" aria-modal="true" aria-labelledby="ansico-diagnosekoder-link-modal-title">' +
'<div class="ansico-diagnosekoder__modal-header">' +
'<h3 id="ansico-diagnosekoder-link-modal-title" class="ansico-diagnosekoder__modal-title"></h3>' +
'<button type="button" class="ansico-diagnosekoder__modal-close" data-modal-close="1" aria-label="Luk">×</button>' +
'</div>' +
'<div class="ansico-diagnosekoder__modal-body">' +
'<div class="ansico-diagnosekoder__modal-field">' +
'<label class="ansico-diagnosekoder__modal-label" for="ansico-diagnosekoder-link-modal-code"></label>' +
'<input id="ansico-diagnosekoder-link-modal-code" class="ansico-diagnosekoder__modal-input" type="text" readonly />' +
'</div>' +
'<p class="ansico-diagnosekoder__modal-hint"></p>' +
'<div class="ansico-diagnosekoder__modal-field">' +
'<label class="ansico-diagnosekoder__modal-label" for="ansico-diagnosekoder-link-modal-url"></label>' +
'<input id="ansico-diagnosekoder-link-modal-url" class="ansico-diagnosekoder__modal-input" type="url" />' +
'</div>' +
'<div class="ansico-diagnosekoder__modal-field">' +
'<label class="ansico-diagnosekoder__modal-label" for="ansico-diagnosekoder-link-modal-search"></label>' +
'<input id="ansico-diagnosekoder-link-modal-search" class="ansico-diagnosekoder__modal-input" type="search" />' +
'</div>' +
'<div class="ansico-diagnosekoder__modal-search-results"></div>' +
'</div>' +
'<div class="ansico-diagnosekoder__modal-footer">' +
'<button type="button" class="ansico-diagnosekoder__modal-button ansico-diagnosekoder__modal-button--secondary" data-modal-cancel="1"></button>' +
'<button type="button" class="ansico-diagnosekoder__modal-button ansico-diagnosekoder__modal-button--primary" data-modal-save="1"></button>' +
'</div>' +
'</div>';
document.body.appendChild(wrapper);
return wrapper;
}
function openLinkModal(code, currentUrl) {
var modal = ensureLinkModal();
var titleNode = modal.querySelector('.ansico-diagnosekoder__modal-title');
var labels = modal.querySelectorAll('.ansico-diagnosekoder__modal-label');
var hintNode = modal.querySelector('.ansico-diagnosekoder__modal-hint');
var codeInput = modal.querySelector('#ansico-diagnosekoder-link-modal-code');
var urlInput = modal.querySelector('#ansico-diagnosekoder-link-modal-url');
var searchInput = modal.querySelector('#ansico-diagnosekoder-link-modal-search');
var resultsNode = modal.querySelector('.ansico-diagnosekoder__modal-search-results');
var cancelButton = modal.querySelector('[data-modal-cancel="1"]');
var saveButton = modal.querySelector('[data-modal-save="1"]');
var closeButtons = modal.querySelectorAll('[data-modal-close="1"]');
var activeSearchToken = 0;
titleNode.textContent = currentUrl ? AnsicoDiagnosekoderConfig.strings.linkModalTitleEdit : AnsicoDiagnosekoderConfig.strings.linkModalTitleAdd;
labels[0].textContent = AnsicoDiagnosekoderConfig.strings.linkModalCodeLabel;
labels[1].textContent = AnsicoDiagnosekoderConfig.strings.linkModalUrlLabel;
labels[2].textContent = AnsicoDiagnosekoderConfig.strings.linkModalSearchLabel;
hintNode.textContent = AnsicoDiagnosekoderConfig.strings.linkModalHint;
cancelButton.textContent = AnsicoDiagnosekoderConfig.strings.linkModalCancel;
saveButton.textContent = AnsicoDiagnosekoderConfig.strings.linkModalSave;
codeInput.value = code || '';
urlInput.value = currentUrl || '';
urlInput.placeholder = AnsicoDiagnosekoderConfig.strings.linkPromptDefault || 'https://';
searchInput.value = '';
searchInput.placeholder = AnsicoDiagnosekoderConfig.strings.linkModalSearchPlaceholder;
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkModalSearchEmpty) + '</p>';
modal.removeAttribute('hidden');
document.body.classList.add('ansico-diagnosekoder-modal-open');
function closeModal() {
modal.setAttribute('hidden', 'hidden');
document.body.classList.remove('ansico-diagnosekoder-modal-open');
saveButton.onclick = null;
cancelButton.onclick = null;
closeButtons.forEach(function (button) { button.onclick = null; });
searchInput.oninput = null;
document.removeEventListener('keydown', onKeyDown);
}
function onKeyDown(event) {
if (event.key === 'Escape') {
closeModal();
}
}
function renderSearchResults(items) {
if (!items.length) {
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkModalSearchNone) + '</p>';
return;
}
var html = '<ul class="ansico-diagnosekoder__modal-result-list">';
items.forEach(function (item) {
html += '<li class="ansico-diagnosekoder__modal-result-item">';
html += '<button type="button" class="ansico-diagnosekoder__modal-result-button" data-url="' + escapeHtml(item.url || '') + '">';
html += '<span class="ansico-diagnosekoder__modal-result-title">' + escapeHtml(item.title || item.url || '') + '</span>';
html += '<span class="ansico-diagnosekoder__modal-result-meta">' + escapeHtml(item.url || '') + '</span>';
html += '</button></li>';
});
html += '</ul>';
resultsNode.innerHTML = html;
resultsNode.querySelectorAll('.ansico-diagnosekoder__modal-result-button').forEach(function (button) {
button.addEventListener('click', function () {
urlInput.value = button.getAttribute('data-url') || '';
});
});
}
searchInput.oninput = debounce(function () {
var query = searchInput.value.trim();
activeSearchToken += 1;
var token = activeSearchToken;
if (!query) {
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkModalSearchEmpty) + '</p>';
return;
}
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.loading) + '</p>';
searchInternalContent(query).then(function (items) {
if (token !== activeSearchToken) {
return;
}
renderSearchResults(items);
}).catch(function () {
resultsNode.innerHTML = '<p class="ansico-diagnosekoder__modal-message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.linkSearchError) + '</p>';
});
}, 180);
var resolver;
var promise = new Promise(function (resolve) {
resolver = resolve;
});
saveButton.onclick = function () {
resolver(String(urlInput.value || '').trim());
closeModal();
};
cancelButton.onclick = function () {
resolver(null);
closeModal();
};
closeButtons.forEach(function (button) {
button.onclick = function () {
resolver(null);
closeModal();
};
});
document.addEventListener('keydown', onKeyDown);
window.setTimeout(function () { urlInput.focus(); urlInput.select(); }, 0);
return promise;
}
function fetchPageState(pageId) {
if (!pageId || !AnsicoDiagnosekoderConfig.pageStateUrl) {
return Promise.resolve({ favorites: favoriteCodes, links: codeLinks, page_id: pageId || 0 });
}
var url = AnsicoDiagnosekoderConfig.pageStateUrl + '?page_id=' + encodeURIComponent(pageId) + '&_ansico_ts=' + Date.now();
return fetch(url, {
credentials: 'same-origin',
cache: 'no-store'
}).then(function (response) {
if (!response.ok) {
throw new Error('Page state failed');
}
return response.json();
}).then(function (data) {
syncClientCollections(data || {});
return data || {};
}).catch(function () {
return { favorites: favoriteCodes, links: codeLinks, page_id: pageId || 0 };
});
}
function mergeAndSortResults(results) {
var merged = (Array.isArray(results) ? results : []).map(function (item, index) {
var normalizedCode = normalizeCode(item.code);
var favorite = isFavorite(normalizedCode) || !!item.is_favorite;
var linkedUrl = getLinkedUrl(normalizedCode, item.linked_url || '');
return Object.assign({}, item, {
is_favorite: favorite,
linked_url: linkedUrl,
_normalized_code: normalizedCode,
_render_index: index
});
});
merged.sort(function (a, b) {
if (!!a.is_favorite !== !!b.is_favorite) {
return a.is_favorite ? -1 : 1;
}
return a._render_index - b._render_index;
});
return merged;
}
function renderResults(container, results, query) {
if (!results.length) {
container.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.noResults) + '</p>';
return;
}
var sortedResults = mergeAndSortResults(results);
var html = '<ul class="ansico-diagnosekoder__list">';
sortedResults.forEach(function (item) {
var normalizedCode = item._normalized_code || normalizeCode(item.code);
var favorite = !!item.is_favorite;
var linkedUrl = item.linked_url || '';
var hasLink = !!linkedUrl;
var copyValue = item.code + ' - ' + item.text;
var copyAria = AnsicoDiagnosekoderConfig.strings.copyCodeAria.replace('%s', copyValue);
var favoriteAria = favorite ? AnsicoDiagnosekoderConfig.strings.removeFavorite : AnsicoDiagnosekoderConfig.strings.addFavorite;
var linkAria = hasLink ? AnsicoDiagnosekoderConfig.strings.removeLink : AnsicoDiagnosekoderConfig.strings.addLink;
var entryTagStart = hasLink ? '<a class="ansico-diagnosekoder__entry-link" href="' + escapeHtml(linkedUrl) + '">' : '';
var entryTagEnd = hasLink ? '</a>' : '';
html += '<li class="ansico-diagnosekoder__item' + (favorite ? ' is-favorite' : '') + (hasLink ? ' has-link' : '') + '" data-code="' + escapeHtml(normalizedCode) + '" data-is-favorite="' + (favorite ? '1' : '0') + '" data-has-link="' + (hasLink ? '1' : '0') + '">';
html += '<div class="ansico-diagnosekoder__row">';
html += entryTagStart + '<div class="ansico-diagnosekoder__entry">';
html += '<span class="ansico-diagnosekoder__code">' + highlightText(item.code, query) + '</span>';
html += '<span class="ansico-diagnosekoder__separator"> </span>';
html += '<span class="ansico-diagnosekoder__text">' + highlightText(item.text, query) + '</span>';
if (hasLink) {
html += '<span class="ansico-diagnosekoder__linked-badge">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.openLink) + '</span>';
}
html += '</div>' + entryTagEnd;
html += '<div class="ansico-diagnosekoder__actions">';
html += '<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__copy-button" data-copy-value="' + escapeHtml(copyValue) + '"';
html += ' data-label-default="' + escapeHtml(copyAria) + '"';
html += ' data-label-success="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.copied) + '"';
html += ' data-label-error="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.copyError) + '"';
html += ' aria-label="' + escapeHtml(copyAria) + '" title="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.copyIcon) + '">';
html += getCopyIcon() + '</button>';
if (AnsicoDiagnosekoderConfig.isLoggedIn) {
html += '<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__favorite-button' + (favorite ? ' is-active' : '') + '" data-code="' + escapeHtml(normalizedCode) + '" aria-pressed="' + (favorite ? 'true' : 'false') + '" data-label-default="' + escapeHtml(favoriteAria) + '" aria-label="' + escapeHtml(favoriteAria) + '" title="' + escapeHtml(AnsicoDiagnosekoderConfig.strings.favoriteIcon) + '">';
html += getStarIcon(favorite) + '</button>';
html += '<button type="button" class="ansico-diagnosekoder__icon-button ansico-diagnosekoder__link-button' + (hasLink ? ' is-active' : '') + '" data-code="' + escapeHtml(normalizedCode) + '" data-current-url="' + escapeHtml(linkedUrl) + '" data-label-default="' + escapeHtml(linkAria) + '" aria-label="' + escapeHtml(linkAria) + '" title="' + escapeHtml(hasLink ? AnsicoDiagnosekoderConfig.strings.removeLinkIcon : AnsicoDiagnosekoderConfig.strings.addLinkIcon) + '">';
html += hasLink ? getMinusIcon() : getPlusIcon();
html += '</button>';
}
html += '</div></div></li>';
});
html += '</ul>';
container.innerHTML = html;
}
function getQueryParam(name) {
var params = new URLSearchParams(window.location.search);
return params.get(name) || '';
}
function getSelectorEscaped(value) {
if (window.CSS && typeof window.CSS.escape === 'function') {
return window.CSS.escape(value);
}
return String(value).replace(/"/g, '\\"');
}
function updateFavoriteButtons(code, isFav, pageId) {
var normalizedCode = normalizeCode(code);
var selector = '.ansico-diagnosekoder__favorite-button[data-code="' + getSelectorEscaped(normalizedCode) + '"]';
if (pageId) {
selector = '.ansico-diagnosekoder[data-page-id="' + getSelectorEscaped(String(pageId)) + '"] ' + selector;
}
var buttons = document.querySelectorAll(selector);
buttons.forEach(function (button) {
var label = isFav ? AnsicoDiagnosekoderConfig.strings.removeFavorite : AnsicoDiagnosekoderConfig.strings.addFavorite;
button.classList.toggle('is-active', isFav);
button.setAttribute('aria-pressed', isFav ? 'true' : 'false');
button.setAttribute('aria-label', label);
button.setAttribute('data-label-default', label);
button.innerHTML = getStarIcon(isFav);
var item = button.closest('.ansico-diagnosekoder__item');
if (item) {
item.classList.toggle('is-favorite', isFav);
item.setAttribute('data-is-favorite', isFav ? '1' : '0');
}
});
}
function updateLinkButtons(code, url) {
var normalizedCode = normalizeCode(code);
var buttons = document.querySelectorAll('.ansico-diagnosekoder__link-button[data-code="' + getSelectorEscaped(normalizedCode) + '"]');
var hasLink = !!url;
buttons.forEach(function (button) {
var label = hasLink ? AnsicoDiagnosekoderConfig.strings.removeLink : AnsicoDiagnosekoderConfig.strings.addLink;
button.classList.toggle('is-active', hasLink);
button.setAttribute('aria-label', label);
button.setAttribute('data-label-default', label);
button.setAttribute('data-current-url', url || '');
button.setAttribute('title', hasLink ? AnsicoDiagnosekoderConfig.strings.removeLinkIcon : AnsicoDiagnosekoderConfig.strings.addLinkIcon);
button.innerHTML = hasLink ? getMinusIcon() : getPlusIcon();
var item = button.closest('.ansico-diagnosekoder__item');
if (item) {
item.classList.toggle('has-link', hasLink);
item.setAttribute('data-has-link', hasLink ? '1' : '0');
}
});
}
function syncClientCollections(data) {
if (Array.isArray(data.favorites)) {
favoriteCodes = data.favorites.map(normalizeCode);
}
if (data.links && typeof data.links === 'object') {
codeLinks = {};
Object.keys(data.links).forEach(function (code) {
codeLinks[normalizeCode(code)] = data.links[code];
});
}
}
function toggleFavorite(code, button, refreshCallback, pageId) {
fetch(AnsicoDiagnosekoderConfig.favoritesUrl, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
},
body: JSON.stringify({ code: normalizeCode(code), page_id: pageId || 0 })
}).then(function (response) {
if (!response.ok) {
throw new Error('Favorite toggle failed');
}
return response.json();
}).then(function (data) {
syncClientCollections(data);
pulseButton(button);
updateFavoriteButtons(code, !!data.is_favorite, pageId || 0);
if (typeof refreshCallback === 'function') {
refreshCallback();
}
}).catch(function () {
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.favoriteError, 1400);
});
}
function saveCodeLink(code, url, button, refreshCallback, pageId) {
fetch(AnsicoDiagnosekoderConfig.linksUrl, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
},
body: JSON.stringify({ code: normalizeCode(code), url: url, page_id: pageId || 0 })
}).then(function (response) {
if (!response.ok) {
throw new Error('Link save failed');
}
return response.json();
}).then(function (data) {
syncClientCollections(data);
pulseButton(button);
updateLinkButtons(code, data.url || '');
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkSaved, 1200);
if (typeof refreshCallback === 'function') {
refreshCallback();
}
}).catch(function () {
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkError, 1400);
});
}
function removeCodeLink(code, button, refreshCallback, pageId) {
var url = AnsicoDiagnosekoderConfig.linksUrl + '?code=' + encodeURIComponent(normalizeCode(code)) + '&page_id=' + encodeURIComponent(pageId || 0);
fetch(url, {
method: 'DELETE',
credentials: 'same-origin',
headers: {
'X-WP-Nonce': AnsicoDiagnosekoderConfig.nonce
}
}).then(function (response) {
if (!response.ok) {
throw new Error('Link removal failed');
}
return response.json();
}).then(function (data) {
syncClientCollections(data);
pulseButton(button);
updateLinkButtons(code, '');
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkRemoved, 1200);
if (typeof refreshCallback === 'function') {
refreshCallback();
}
}).catch(function () {
setTemporaryLabel(button, AnsicoDiagnosekoderConfig.strings.linkError, 1400);
});
}
function initResultsBlock(root) {
preloadPageState(root);
var input = root.querySelector('.ansico-diagnosekoder__input');
var results = root.querySelector('.ansico-diagnosekoder__results');
var hasData = root.getAttribute('data-has-data') === '1';
if (!input || !results || !hasData) {
return;
}
var runSearch = function () {
var query = input.value.trim();
if (!query) {
results.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.empty) + '</p>';
return;
}
results.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.loading) + '</p>';
var pageId = getPageId(root);
var url = AnsicoDiagnosekoderConfig.restUrl + '?q=' + encodeURIComponent(query) + '&limit=50&page_id=' + encodeURIComponent(pageId) + '&_ansico_ts=' + Date.now();
fetchPageState(pageId).then(function () {
return fetch(url, {
credentials: 'same-origin',
cache: 'no-store'
});
})
.then(function (response) {
if (!response.ok) {
throw new Error('Request failed');
}
return response.json();
})
.then(function (data) {
syncClientCollections(data);
if (
(!Array.isArray(data.favorites) || !data.favorites.length) &&
(!data.links || !Object.keys(data.links).length) &&
(!favoriteCodes.length && !Object.keys(codeLinks).length)
) {
preloadPageState(root);
}
renderResults(results, data.results || [], query);
})
.catch(function () {
results.innerHTML = '<p class="ansico-diagnosekoder__message">' + escapeHtml(AnsicoDiagnosekoderConfig.strings.error) + '</p>';
});
};
var debouncedSearch = debounce(runSearch, 200);
input.addEventListener('input', debouncedSearch);
results.addEventListener('click', function (event) {
var copyButton = event.target.closest('.ansico-diagnosekoder__copy-button');
if (copyButton) {
copyText(copyButton.getAttribute('data-copy-value') || '', copyButton);
return;
}
var favoriteButton = event.target.closest('.ansico-diagnosekoder__favorite-button');
if (favoriteButton) {
toggleFavorite(favoriteButton.getAttribute('data-code') || '', favoriteButton, runSearch, getPageId(root));
return;
}
var linkButton = event.target.closest('.ansico-diagnosekoder__link-button');
if (linkButton) {
var code = linkButton.getAttribute('data-code') || '';
var currentUrl = linkButton.getAttribute('data-current-url') || '';
if (currentUrl) {
removeCodeLink(code, linkButton, runSearch, getPageId(root));
return;
}
openLinkModal(code, currentUrl).then(function (enteredUrl) {
if (enteredUrl === null) {
return;
}
enteredUrl = String(enteredUrl).trim();
if (!enteredUrl) {
return;
}
saveCodeLink(code, enteredUrl, linkButton, runSearch, getPageId(root));
});
}
});
var stateNode = root.querySelector('.ansico-diagnosekoder__page-state');
var hasServerRenderedResults = false;
if (stateNode) {
try {
var initialState = JSON.parse(stateNode.textContent || '{}');
hasServerRenderedResults = !!(initialState && initialState.hasInitialResults);
} catch (error) {}
}
fetchPageState(getPageId(root)).then(function () {
var presetQuery = getQueryParam('q');
if (presetQuery) {
input.value = presetQuery;
if (!hasServerRenderedResults) {
runSearch();
}
}
});
}
function initSearchOnlyBlock(form) {
form.addEventListener('submit', function (event) {
var input = form.querySelector('.ansico-diagnosekoder__input');
var query = input ? input.value.trim() : '';
var resultsUrl = form.getAttribute('data-results-url') || AnsicoDiagnosekoderConfig.resultsUrl || '';
if (!resultsUrl) {
event.preventDefault();
var message = form.querySelector('.ansico-diagnosekoder__message');
if (message) {
message.textContent = AnsicoDiagnosekoderConfig.strings.missingResultsUrl;
}
return;
}
if (!query) {
event.preventDefault();
return;
}
event.preventDefault();
var url = new URL(resultsUrl, window.location.origin);
url.searchParams.set('q', query);
window.location.href = url.toString();
});
}
document.addEventListener('DOMContentLoaded', function () {
var resultsBlocks = document.querySelectorAll('.wp-block-ansico-diagnosekoder.ansico-diagnosekoder');
resultsBlocks.forEach(initResultsBlock);
var searchOnlyBlocks = document.querySelectorAll('.wp-block-ansico-diagnosekoder-soegefelt.ansico-diagnosekoder--search-only');
searchOnlyBlocks.forEach(initSearchOnlyBlock);
});
})();