즐겨찾기·홀드 미리보기·페이지 도움말·3개국어 번역을 추가하고, 덱 저장 시 썸네일을 1200px로 통일하며 Nginx/API 업로드 제한을 상향했다. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
2.9 KiB
JavaScript
97 lines
2.9 KiB
JavaScript
/**
|
|
* 페이지 제목 옆 ? 버튼 — 설명 툴팁
|
|
*/
|
|
(function initPageHelp() {
|
|
/** @type {HTMLElement|null} */
|
|
let activeTooltip = null;
|
|
|
|
/** @type {HTMLElement|null} */
|
|
let activeBtn = null;
|
|
|
|
function closeTooltip() {
|
|
if (activeTooltip) {
|
|
activeTooltip.remove();
|
|
activeTooltip = null;
|
|
}
|
|
if (activeBtn) {
|
|
activeBtn.setAttribute('aria-expanded', 'false');
|
|
activeBtn = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {HTMLElement} btn
|
|
* @param {string} text
|
|
*/
|
|
function openTooltip(btn, text) {
|
|
if (!text) return;
|
|
closeTooltip();
|
|
|
|
const tip = document.createElement('div');
|
|
tip.className = 'page-help-tooltip';
|
|
tip.setAttribute('role', 'tooltip');
|
|
tip.id = `page-help-tip-${Date.now()}`;
|
|
tip.textContent = text;
|
|
document.body.appendChild(tip);
|
|
btn.setAttribute('aria-expanded', 'true');
|
|
btn.setAttribute('aria-describedby', tip.id);
|
|
|
|
const rect = btn.getBoundingClientRect();
|
|
const margin = 12;
|
|
let left = rect.left + window.scrollX;
|
|
const top = rect.bottom + window.scrollY + 8;
|
|
const tipWidth = tip.offsetWidth;
|
|
|
|
if (left + tipWidth > window.innerWidth - margin) {
|
|
left = window.innerWidth - tipWidth - margin;
|
|
}
|
|
left = Math.max(margin, left);
|
|
|
|
tip.style.top = `${top}px`;
|
|
tip.style.left = `${left}px`;
|
|
|
|
activeTooltip = tip;
|
|
activeBtn = btn;
|
|
}
|
|
|
|
/**
|
|
* @param {object} [translations]
|
|
*/
|
|
function bindPageHelp(translations) {
|
|
const tFn = (key, fallback) => {
|
|
if (translations?.[key]) return translations[key];
|
|
if (window.UaPageI18n?.t) return window.UaPageI18n.t(key, fallback);
|
|
return fallback;
|
|
};
|
|
|
|
document.querySelectorAll('[data-i18n-tooltip]').forEach((btn) => {
|
|
const key = btn.dataset.i18nTooltip;
|
|
const text = tFn(key, '');
|
|
const helpLabel = tFn('pageHelpLabel', '페이지 안내');
|
|
btn.setAttribute('aria-label', text ? `${helpLabel}` : helpLabel);
|
|
|
|
if (btn.dataset.helpBound === '1') return;
|
|
btn.dataset.helpBound = '1';
|
|
|
|
btn.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
const current = tFn(key, '');
|
|
if (activeBtn === btn && activeTooltip) {
|
|
closeTooltip();
|
|
return;
|
|
}
|
|
openTooltip(btn, current);
|
|
});
|
|
});
|
|
}
|
|
|
|
document.addEventListener('click', closeTooltip);
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === 'Escape') closeTooltip();
|
|
});
|
|
window.addEventListener('scroll', closeTooltip, { passive: true });
|
|
window.addEventListener('resize', closeTooltip);
|
|
|
|
window.UaPageHelp = { bindPageHelp, closeTooltip };
|
|
})();
|