HTML
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('search-input');
const searchBtn = document.getElementById('search-btn');
const clearBtn = document.getElementById('clear-btn');
const searchResults = document.getElementById('search-results');
const poemTable = document.querySelector('.poem-table');
const popup = document.getElementById('footnote-popup');
const popupContent = document.getElementById('popup-content');
const closePopup = document.getElementById('close-popup');
const copyButton = document.getElementById('copy-button');
const overlay = document.getElementById('overlay');
const footnoteSection = document.getElementById('footnote-section');
const toggleFootnotesBtn = document.getElementById('toggle-footnotes');
const footnoteData = document.getElementById('footnote-data');
// 1. Footnote Popup Logic
const popupLinks = document.querySelectorAll('.footnote-popup-link');
popupLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const footnoteId = this.getAttribute('data-footnote');
const footnoteItem = document.getElementById('footnote-' + footnoteId);
if (footnoteItem) {
// Get components
const vocabHeader = footnoteItem.querySelector('.vocab-header');
const vocabDivs = Array.from(footnoteItem.querySelectorAll('div')).filter(div => div.querySelector('.vocab-item'));
const explanationHeader = footnoteItem.querySelector('.explanation-header');
// Get all text nodes or elements after explanationHeader up to the end
let explanationHtml = '';
if (explanationHeader) {
let nextElem = explanationHeader.nextSibling;
while(nextElem) {
if (nextElem.nodeType === Node.ELEMENT_NODE) {
explanationHtml += nextElem.outerHTML;
} else if (nextElem.nodeType === Node.TEXT_NODE) {
explanationHtml += nextElem.textContent;
}
nextElem = nextElem.nextSibling;
}
}
// Build full popup content
let fullContent = '';
if (vocabHeader) fullContent += vocabHeader.outerHTML;
vocabDivs.forEach(div => { fullContent += div.outerHTML; });
if (explanationHeader) fullContent += explanationHeader.outerHTML;
if (explanationHtml) fullContent += explanationHtml;
popupContent.innerHTML = fullContent;
// Set the title number
const footnoteTitle = document.getElementById('footnote-title');
if (footnoteTitle) {
footnoteTitle.innerHTML = 'حاشية تفسيرية <span class="footnote-number">[' + footnoteId + ']</span>';
}
// Set attribute for copying raw text later
popup.setAttribute('data-footnote-number', footnoteId);
// Show popup & overlay
popup.style.display = 'block';
overlay.style.display = 'block';
// Reflow
popup.offsetHeight;
overlay.offsetHeight;
popup.classList.add('active');
overlay.classList.add('active');
popup.focus();
}
});
});
function closeFootnotePopup() {
popup.classList.remove('active');
overlay.classList.remove('active');
setTimeout(() => {
popup.style.display = 'none';
overlay.style.display = 'none';
}, 400);
}
if (closePopup) closePopup.addEventListener('click', closeFootnotePopup);
if (overlay) overlay.addEventListener('click', closeFootnotePopup);
// Escape key listener for popup
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && popup.classList.contains('active')) {
closeFootnotePopup();
}
});
// 2. Copy Functionality
if (copyButton) {
copyButton.addEventListener('click', function() {
const footnoteNum = popup.getAttribute('data-footnote-number');
const footnoteItem = document.getElementById('footnote-' + footnoteNum);
if (footnoteItem) {
// Clone the item to manipulate text easily without breaking UI
const clone = footnoteItem.cloneNode(true);
// Remove the back link element so it's not copied
const backLink = clone.querySelector('.footnote-link-back');
if (backLink) backLink.remove();
const textToCopy = clone.innerText.trim();
navigator.clipboard.writeText(textToCopy).then(() => {
const originalText = copyButton.textContent;
copyButton.textContent = 'تم النسخ!';
copyButton.style.background = '#28a745';
setTimeout(() => {
copyButton.textContent = originalText;
copyButton.style.background = '#d4a373';
}, 2000);
}).catch(err => {
console.error('Failed to copy: ', err);
});
}
});
}
// 3. Smooth Scroll Navigation Link & Back Link Highlight Logic
const navLinks = document.querySelectorAll('.footnote-nav-link, .footnote-link-back');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href').substring(1);
const targetElem = document.getElementById(targetId);
if (targetElem) {
// If it's going down to a footnote item, ensure section is open
if (targetId.startsWith('footnote-')) {
if (footnoteSection.classList.contains('collapsed')) {
footnoteSection.classList.remove('collapsed');
toggleFootnotesBtn.textContent = 'إخفاء الحواشي';
}
}
targetElem.scrollIntoView({ behavior: 'smooth', block: 'center' });
// Add highlight & flashing red dot
targetElem.classList.add('highlight');
// Add visual red dot indicator
let dot = document.createElement('span');
dot.className = targetId.startsWith('footnote-') ? 'search-red-dot' : 'red-dot';
if (targetId.startsWith('footnote-')) {
// Prepend to footnote item
targetElem.insertBefore(dot, targetElem.firstChild);
} else {
// For poem rows, append to the first cell or line number cell
const cell = targetElem.querySelector('td:first-child');
if (cell) cell.appendChild(dot);
}
// Remove after 6 seconds
setTimeout(() => {
targetElem.classList.remove('highlight');
dot.remove();
}, 6000);
}
});
});
// 4. Toggle Footnotes Section Logic with Auto-Scroll
if (toggleFootnotesBtn && footnoteSection) {
toggleFootnotesBtn.addEventListener('click', function() {
const isCollapsed = footnoteSection.classList.contains('collapsed');
if (isCollapsed) {
footnoteSection.classList.remove('collapsed');
this.textContent = 'إخفاء الحواشي';
// Smooth scroll to the footnote section once opened
setTimeout(() => {
footnoteSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
}, 100);
} else {
footnoteSection.classList.add('collapsed');
this.textContent = 'إظهار الحواشي';
}
});
}
// 5. Advanced Search Engine
function performSearch() {
const query = searchInput.value.trim().toLowerCase();
searchResults.innerHTML = '';
if (!query) {
searchResults.style.display = 'none';
return;
}
const results = [];
const rows = poemTable.querySelectorAll('tbody tr:not([colspan])');
rows.forEach(row => {
const cells = row.querySelectorAll('td');
if (cells.length >= 3) {
const lineNum = cells[0].textContent.trim();
const shatr1 = cells[1].textContent;
const shatr2 = cells[2].textContent;
const fullLineText = shatr1 + ' ' + shatr2;
if (fullLineText.toLowerCase().includes(query)) {
results.push({
type: 'poem',
id: row.id,
label: `البيت ${lineNum}`,
text: fullLineText,
shatr1: cells[1].innerHTML,
shatr2: cells[2].innerHTML
});
}
}
});
const footnoteItems = document.querySelectorAll('.footnote-item');
footnoteItems.forEach(item => {
const itemText = item.innerText;
if (itemText.toLowerCase().includes(query)) {
const id = item.id.replace('footnote-', '');
results.push({
type: 'footnote',
id: item.id,
label: `حاشية البيت [${id}]`,
text: itemText
});
}
});
if (results.length > 0) {
const ul = document.createElement('ul');
results.forEach(res => {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = '#' + res.id;
a.innerHTML = `<span class="search-red-dot"></span><strong>${res.label}:</strong> `;
let snippet = res.text;
if (snippet.length > 120) {
const idx = snippet.toLowerCase().indexOf(query);
const start = Math.max(0, idx - 40);
const end = Math.min(snippet.length, idx + query.length + 60);
snippet = (start > 0 ? '...' : '') + snippet.substring(start, end) + (end < snippet.length ? '...' : '');
}
const regex = new RegExp(`(${escapeRegExp(query)})`, 'gi');
snippet = snippet.replace(regex, '<mark>$1</mark>');
a.innerHTML += snippet;
a.addEventListener('click', function(e) {
e.preventDefault();
searchResults.style.display = 'none';
searchInput.value = '';
if (res.type === 'footnote' && footnoteSection.classList.contains('collapsed')) {
footnoteSection.classList.remove('collapsed');
toggleFootnotesBtn.textContent = 'إخفاء الحواشي';
}
const targetElem = document.getElementById(res.id);
if (targetElem) {
targetElem.scrollIntoView({ behavior: 'smooth', block: 'center' });
targetElem.classList.add('highlight');
let dot = document.createElement('span');
dot.className = res.type === 'footnote' ? 'search-red-dot' : 'red-dot';
if (res.type === 'footnote') {
targetElem.insertBefore(dot, targetElem.firstChild);
} else {
const cell = targetElem.querySelector('td:first-child');
if (cell) cell.appendChild(dot);
}
setTimeout(() => {
targetElem.classList.remove('highlight');
dot.remove();
}, 6000);
}
});
li.appendChild(a);
ul.appendChild(li);
});
searchResults.appendChild(ul);
searchResults.style.display = 'block';
} else {
searchResults.innerHTML = '<p style="margin:0; color:#666;">لم يتم العثور على نتائج.</p>';
searchResults.style.display = 'block';
}
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
if (searchBtn) searchBtn.addEventListener('click', performSearch);
if (searchInput) {
searchInput.addEventListener('keyup', function(e) {
if (e.key === 'Enter') performSearch();
else if (this.value.trim() === '') {
searchResults.innerHTML = '';
searchResults.style.display = 'none';
}
});
}
if (clearBtn) {
clearBtn.addEventListener('click', function() {
searchInput.value = '';
searchResults.innerHTML = '';
searchResults.style.display = 'none';
});
}
// 6. Guidelines Collapsible State Manager Logic
function toggleGuidelines() {
const content = document.getElementById('guidelinesContent');
const icon = document.getElementById('toggleIcon');
const label = document.getElementById('toggleLabel');
content.classList.toggle('show');
icon.classList.toggle('rotated');
label.textContent = content.classList.contains('show') ? 'إخفاء' : 'إظهار';
localStorage.setItem('guidelinesState', content.classList.contains('show') ? 'open' : 'closed');
}
const header = document.getElementById('guidelines-header');
const content = document.getElementById('guidelinesContent');
const icon = document.getElementById('toggleIcon');
const label = document.getElementById('toggleLabel');
localStorage.setItem('guidelinesState', 'closed');
content.classList.remove('show');
icon.classList.remove('rotated');
label.textContent = 'إظهار';
const savedState = localStorage.getItem('guidelinesState');
if (savedState === 'open') {
content.classList.add('show');
icon.classList.add('rotated');
label.textContent = 'إخفاء';
}
header.addEventListener('click', toggleGuidelines);
});
css
#footnote-popup {
background: linear-gradient(135deg, #fffaf0 0%, #f5f5f5 100%);
border: 2px solid #d4a373;
border-radius: 15px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
direction: rtl;
display: none;
font-size: 15px;
line-height: 1.6;
max-height: 70vh;
max-width: 90%;
width: 550px;
overflow-y: auto;
padding: 20px;
position: fixed;
text-align: right;
z-index: 1000;
opacity: 0;
transform: translate(-50%, -50%) scale(0.95);
transition: opacity 0.4s ease, transform 0.4s ease;
left: 50%;
top: 50%;
}
#footnote-popup.active {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
display: block;
}
#footnote-title {
display: block;
font-size: 20px;
font-weight: 700;
text-align: center;
padding-bottom: 10px;
border-bottom: 3px solid #d4a373;
margin-bottom: 10px;
color: #808080;
}
#footnote-title .footnote-number {
color: #990000;
}
#footnote-popup::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill="none" stroke="%23d4a373" stroke-opacity="0.2" d="M20,80 Q40,60 50,80 T80,80 Q60,100 50,80 T20,80 Z"/></svg>') center;
opacity: 0.08;
z-index: -1;
}
#close-popup {
background: #d4a373;
color: #fff;
cursor: pointer;
font-size: 20px;
font-weight: 700;
width: 35px;
height: 35px;
line-height: 35px;
text-align: center;
border-radius: 50%;
position: absolute;
right: 15px;
top: 15px;
transition: background 0.3s ease, transform 0.3s ease;
}
#close-popup:hover,
#close-popup:focus {
background: #a67b5b;
transform: rotate(180deg);
}
#copy-button {
background: #d4a373;
color: #fff;
cursor: pointer;
font-size: 14px;
font-weight: 600;
padding: 8px 15px;
border: none;
border-radius: 8px;
position: absolute;
left: 15px;
top: 15px;
transition: background 0.3s ease, transform 0.2s ease;
}
#copy-button:hover,
#copy-button:focus {
background: #a67b5b;
transform: scale(1.05);
}
#popup-content {
color: #333;
text-align: right;
padding: 10px 0;
}
#popup-content strong {
display: block;
margin: 5px 0;
color: #4a3728;
}
#popup-content strong.vocab-header,
#popup-content strong.explanation-header {
display: inline-block;
background-color: #f0e8df;
padding: 2px 4px;
}
#popup-content .vocab-item,
#footnote-data .vocab-item {
font-weight: bold;
color: #4a3728;
}
#popup-content .explanation {
margin: 0;
display: inline;
}
#overlay {
background-color: rgba(0, 0, 0, 0.7);
display: none;
height: 100%;
left: 0;
position: fixed;
top: 0;
width: 100%;
z-index: 999;
opacity: 0;
transition: opacity 0.4s ease;
}
#overlay.active {
opacity: 1;
display: block;
}
.footnote-popup-link {
color: #990000;
font-weight: bold;
text-decoration: none;
cursor: pointer;
transition: color 0.3s ease;
}
.footnote-popup-link:hover {
color: #990000;
}
.footnote-nav-link {
color: #0000FF;
font-weight: bold;
text-decoration: none;
cursor: pointer;
transition: color 0.3s ease;
}
.footnote-nav-link:hover {
color: #0000CC;
}
.footnote-nav-link::after {
content: '\21B4';
font-size: 12px;
vertical-align: super;
margin-right: 4px;
}
.poem-container {
background: transparent;
border-radius: 8px;
box-shadow: rgba(0, 0, 0, 0.05) 0px 2px 5px;
direction: rtl;
margin: 0 auto 30px auto;
max-width: 600px;
padding: 5px 20px 20px 20px; /* Reduced padding-top from 20px to 5px */
}
.poem-header {
text-align: center;
margin-bottom: 0px; /* Reduced from 5px to 0px */
color: #000000;
}
.poem-header h1 {
font-size: 24px;
font-weight: 700;
margin: 10px 0;
}
.poem-header p {
font-size: 16px;
line-height: 1.6;
}
.poem-table {
border-collapse: collapse;
direction: rtl;
margin: 15px 0;
text-align: right;
width: 100%;
}
.poem-table td {
border: 1px solid #ddd;
color: #000000;
padding: 12px;
text-align: right;
vertical-align: top;
width: 45%;
}
.poem-table td:first-child {
width: 5%;
text-align: center;
font-weight: normal;
}
.footnote-section {
margin-top: 40px;
padding: 20px;
background-color: #FFFFFF;
border-radius: 8px;
border: 1px solid #ddd;
color: #000000;
}
.footnote-section.collapsed #footnote-data {
display: none;
}
.footnote-section:not(.collapsed) #footnote-data {
display: block;
}
.footnote-section h2 {
font-size: 18px;
color: #333;
text-align: center;
margin-bottom: 2.33px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 2px solid;
border-image: linear-gradient(to right, #d4a373 0%, #a67b5b 100%) 1;
padding-bottom: 2px;
}
@media (max-width: 600px) {
.footnote-section h2 {
font-size: 13px;
white-space: nowrap;
flex-wrap: nowrap;
padding: 0;
border-bottom: 1.5px solid;
border-image: linear-gradient(to right, #d4a373 0%, #a67b5b 100%) 1;
padding-bottom: 2px;
margin-bottom: 2.33px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
position: relative;
}
}
#toggle-footnotes {
background: #d4a373;
color: #fff;
border: none;
padding: 8px 15px;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: 600;
transition: background 0.3s ease, transform 0.2s ease;
}
#toggle-footnotes:hover,
#toggle-footnotes:focus {
background: #a67b5b;
transform: scale(1.05);
}
.footnote-section .footnote-item {
margin-bottom: 20px;
position: relative;
transition: background-color 0.5s ease;
}
.footnote-section .footnote-item.highlight {
background-color: #fff3e0;
}
.footnote-section .footnote-item.highlight::before {
content: '\25CF';
color: #ff0000;
font-size: 16px;
position: absolute;
right: -20px;
top: 5px;
animation: pulse 1s ease-in-out infinite;
}
.poem-table .red-dot {
display: inline-block;
width: 8px;
height: 8px;
background-color: #ff0000;
border-radius: 50%;
margin-left: 2px;
vertical-align: middle;
animation: pulse 1s ease-in-out infinite;
}
@keyframes pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.5); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
.footnote-section .footnote-link-back {
color: #990000;
text-decoration: none;
font-weight: bold;
cursor: pointer;
transition: color 0.3s ease;
}
.footnote-section .footnote-link-back:hover {
color: #990000;
}
.footnote-section .footnote-link-back::before {
content: '\2934';
font-size: 0.9em;
vertical-align: super;
margin-left: 4px;
}
/* Styles for Shawqi image and text alignment */
.shawqi-content {
display: block;
margin-bottom: 0px;
margin-top: 0px;
}
.shawqi-image-container {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
width: 200px;
}
.shawqi-image {
width: 150px;
height: 150px;
object-fit: cover;
border-radius: 50%;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.shawqi-image-caption {
font-size: 14px;
color: #555;
margin-top: 8px;
text-align: center;
}
.shawqi-text {
font-size: 16px;
line-height: 1.6;
margin-top: -4px;
}
/* Desktop view (screens wider than 600px) */
@media (min-width: 601px) {
.shawqi-content {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 0px;
margin-top: 0px;
flex-direction: row;
}
.shawqi-image-container {
margin: 0;
width: auto;
}
.shawqi-image {
width: 150px;
height: 150px;
border-radius: 50%;
}
.shawqi-text {
text-align: justify;
flex: 1;
font-size: 16px;
margin-top: -4px;
}
}
.guidelines-container {
max-width: 700px;
margin: 0 auto;
border: 1px solid #ddd;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
line-height: 1.6;
color: #333;
direction: rtl;
font-size: 13px;
}
.guidelines-header {
background-color: #f5f5f5;
padding: 8px;
cursor: pointer;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
user-select: none;
}
.guidelines-header:hover {
background-color: #eee;
}
.guidelines-content {
padding: 0;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out, padding 0.3s ease;
background-color: #fff;
}
.guidelines-content-inner {
padding: 15px;
}
.guidelines-content.show {
padding: 0 15px;
max-height: 1000px;
transition: max-height 0.5s ease-in, padding 0.3s ease;
}
.toggle-group {
display: inline-flex;
align-items: center;
}
.toggle-icon {
transition: transform 0.3s ease;
margin-right: 2px;
}
.toggle-icon.rotated {
transform: rotate(180deg);
}
.toggle-label {
margin-right: 2px;
}
.red-link {
color: #990000;
}
.blue-link {
color: #0000FF;
}
.guidelines-container ul {
padding-right: 0;
padding-left: 30px;
list-style-position: outside;
margin-right: 20px;
direction: rtl;
}
.guidelines-container ul.no-bullets {
list-style: none;
padding-left: 0;
margin-right: 20px;
}
.guidelines-container li {
margin-bottom: 10px;
text-align: right;
direction: rtl;
}
/* Search Styles */
.search-container {
max-width: 600px;
margin: 20px auto;
display: flex;
gap: 10px;
direction: rtl;
width: 100%;
box-sizing: border-box;
align-items: center;
}
.buttons-row {
display: flex;
gap: 10px;
flex-shrink: 0;
}
#search-input {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
min-width: 200px;
box-sizing: border-box;
}
#search-btn, #clear-btn {
padding: 10px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
box-sizing: border-box;
flex-shrink: 0;
}
#search-btn {
background: #d4a373;
color: white;
}
#search-btn:hover {
background: #a67b5b;
}
#clear-btn {
background: #ff6b6b;
color: white;
}
#clear-btn:hover {
background: #ee5a52;
}
#search-results {
max-width: 600px;
margin: 20px auto;
background: white;
border: 1px solid #ddd;
border-radius: 5px;
padding: 10px;
direction: rtl;
text-align: right;
display: none;
width: 100%;
box-sizing: border-box;
}
#search-results ul {
list-style: none;
padding: 0;
margin: 0;
}
#search-results li {
margin-bottom: 10px;
border-bottom: 1px solid #eee;
padding-bottom: 5px;
}
#search-results a {
color: #0000FF;
text-decoration: none;
font-weight: bold;
}
#search-results a:hover {
text-decoration: underline;
}
#search-results mark {
background: yellow;
color: black;
}
.search-red-dot {
display: inline-block;
width: 8px;
height: 8px;
background-color: #ff0000;
border-radius: 50%;
margin-right: 8px;
vertical-align: middle;
animation: pulse 1s ease-in-out infinite;
}
@media (max-width: 600px) {
.search-container {
margin: 10px 15px;
flex-direction: column;
gap: 10px;
width: calc(100% - 30px);
}
.buttons-row {
justify-content: center;
gap: 5px;
}
#search-input {
width: 100%;
min-width: 0;
}
#search-btn, #clear-btn {
padding: 8px 12px;
font-size: 14px;
width: auto;
}
#search-results {
margin: 10px 15px;
width: calc(100% - 30px);
}
#footnote-popup {
width: 80%;
max-height: 65vh;
padding: 15px;
font-size: 14px;
}
#footnote-popup.active {
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) scale(1);
}
#close-popup {
width: 28px;
height: 28px;
line-height: 28px;
font-size: 16px;
}
#copy-button {
font-size: 13px;
padding: 6px 12px;
}
#footnote-title {
font-size: 16px;
}
#overlay {
background-color: rgba(0, 0, 0, 0.6);
}
.poem-container {
margin: 0 15px 30px 15px;
padding: 5px 15px 15px 15px; /* Reduced padding-top from 15px to 5px */
}
.poem-header {
margin-bottom: 0px; /* Reduced from 5px to 0px */
}
.poem-header h1 {
font-size: 20px;
}
.poem-header p {
font-size: 14px;
}
.footnote-section h2 {
font-size: 13px;
white-space: nowrap;
flex-wrap: nowrap;
padding: 0;
border-bottom: 1.5px solid;
border-image: linear-gradient(to right, #d4a373 0%, #a67b5b 100%) 1;
padding-bottom: 3px;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
position: relative;
}
.footnote-section h2 span.title {
flex: 0 0 auto;
margin-left: 0;
margin-right: 0;
padding-right: 5px;
}
#toggle-footnotes {
font-size: 13px;
padding: 6px 12px;
white-space: nowrap;
flex: 0 0 auto;
margin-right: 0;
}
.footnote-section .footnote-item.highlight::before {
right: -15px;
top: 3px;
font-size: 14px;
}
.poem-table .red-dot {
width: 6px;
height: 6px;
margin-left: 2px;
}
.shawqi-image-container {
margin: 20px auto;
width: 150px;
}
.shawqi-image {
width: 150px;
height: 150px;
object-fit: cover;
border-radius: 50%;
}
.shawqi-image-caption {
font-size: 12px;
}
.shawqi-text {
font-size: 14px;
text-align: justify;
margin-top: -4px;
}
.search-red-dot {
width: 6px;
height: 6px;
margin-right: 6px;
}
}
javasrip
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('search-input');
const searchBtn = document.getElementById('search-btn');
const clearBtn = document.getElementById('clear-btn');
const searchResults = document.getElementById('search-results');
const poemTable = document.querySelector('.poem-table');
const popup = document.getElementById('footnote-popup');
const popupContent = document.getElementById('popup-content');
const closePopup = document.getElementById('close-popup');
const copyButton = document.getElementById('copy-button');
const overlay = document.getElementById('overlay');
const footnoteSection = document.getElementById('footnote-section');
const toggleFootnotesBtn = document.getElementById('toggle-footnotes');
const footnoteData = document.getElementById('footnote-data');
// 1. Footnote Popup Logic
const popupLinks = document.querySelectorAll('.footnote-popup-link');
popupLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const footnoteId = this.getAttribute('data-footnote');
const footnoteItem = document.getElementById('footnote-' + footnoteId);
if (footnoteItem) {
// Get components
const vocabHeader = footnoteItem.querySelector('.vocab-header');
const vocabDivs = Array.from(footnoteItem.querySelectorAll('div')).filter(div => div.querySelector('.vocab-item'));
const explanationHeader = footnoteItem.querySelector('.explanation-header');
// Get all text nodes or elements after explanationHeader up to the end
let explanationHtml = '';
if (explanationHeader) {
let nextElem = explanationHeader.nextSibling;
while(nextElem) {
if (nextElem.nodeType === Node.ELEMENT_NODE) {
explanationHtml += nextElem.outerHTML;
} else if (nextElem.nodeType === Node.TEXT_NODE) {
explanationHtml += nextElem.textContent;
}
nextElem = nextElem.nextSibling;
}
}
// Build full popup content
let fullContent = '';
if (vocabHeader) fullContent += vocabHeader.outerHTML;
vocabDivs.forEach(div => { fullContent += div.outerHTML; });
if (explanationHeader) fullContent += explanationHeader.outerHTML;
if (explanationHtml) fullContent += explanationHtml;
popupContent.innerHTML = fullContent;
// Set the title number
const footnoteTitle = document.getElementById('footnote-title');
if (footnoteTitle) {
footnoteTitle.innerHTML = 'حاشية تفسيرية <span class="footnote-number">[' + footnoteId + ']</span>';
}
// Set attribute for copying raw text later
popup.setAttribute('data-footnote-number', footnoteId);
// Show popup & overlay
popup.style.display = 'block';
overlay.style.display = 'block';
// Reflow
popup.offsetHeight;
overlay.offsetHeight;
popup.classList.add('active');
overlay.classList.add('active');
popup.focus();
}
});
});
function closeFootnotePopup() {
popup.classList.remove('active');
overlay.classList.remove('active');
setTimeout(() => {
popup.style.display = 'none';
overlay.style.display = 'none';
}, 400);
}
if (closePopup) closePopup.addEventListener('click', closeFootnotePopup);
if (overlay) overlay.addEventListener('click', closeFootnotePopup);
// Escape key listener for popup
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && popup.classList.contains('active')) {
closeFootnotePopup();
}
});
// 2. Copy Functionality
if (copyButton) {
copyButton.addEventListener('click', function() {
const footnoteNum = popup.getAttribute('data-footnote-number');
const footnoteItem = document.getElementById('footnote-' + footnoteNum);
if (footnoteItem) {
// Clone the item to manipulate text easily without breaking UI
const clone = footnoteItem.cloneNode(true);
// Remove the back link element so it's not copied
const backLink = clone.querySelector('.footnote-link-back');
if (backLink) backLink.remove();
const textToCopy = clone.innerText.trim();
navigator.clipboard.writeText(textToCopy).then(() => {
const originalText = copyButton.textContent;
copyButton.textContent = 'تم النسخ!';
copyButton.style.background = '#28a745';
setTimeout(() => {
copyButton.textContent = originalText;
copyButton.style.background = '#d4a373';
}, 2000);
}).catch(err => {
console.error('Failed to copy: ', err);
});
}
});
}
// 3. Smooth Scroll Navigation Link & Back Link Highlight Logic
const navLinks = document.querySelectorAll('.footnote-nav-link, .footnote-link-back');
navLinks.forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const targetId = this.getAttribute('href').substring(1);
const targetElem = document.getElementById(targetId);
if (targetElem) {
// If it's going down to a footnote item, ensure section is open
if (targetId.startsWith('footnote-')) {
if (footnoteSection.classList.contains('collapsed')) {
footnoteSection.classList.remove('collapsed');
toggleFootnotesBtn.textContent = 'إخفاء الحواشي';
}
}
targetElem.scrollIntoView({ behavior: 'smooth', block: 'center' });
// Add highlight & flashing red dot
targetElem.classList.add('highlight');
// Add visual red dot indicator
let dot = document.createElement('span');
dot.className = targetId.startsWith('footnote-') ? 'search-red-dot' : 'red-dot';
if (targetId.startsWith('footnote-')) {
// Prepend to footnote item
targetElem.insertBefore(dot, targetElem.firstChild);
} else {
// For poem rows, append to the first cell or line number cell
const cell = targetElem.querySelector('td:first-child');
if (cell) cell.appendChild(dot);
}
// Remove after 6 seconds
setTimeout(() => {
targetElem.classList.remove('highlight');
dot.remove();
}, 6000);
}
});
});
// 4. Toggle Footnotes Section Logic with Auto-Scroll
if (toggleFootnotesBtn && footnoteSection) {
toggleFootnotesBtn.addEventListener('click', function() {
const isCollapsed = footnoteSection.classList.contains('collapsed');
if (isCollapsed) {
footnoteSection.classList.remove('collapsed');
this.textContent = 'إخفاء الحواشي';
// Smooth scroll to the footnote section once opened
setTimeout(() => {
footnoteSection.scrollIntoView({ behavior: 'smooth', block: 'start' });
}, 100);
} else {
footnoteSection.classList.add('collapsed');
this.textContent = 'إظهار الحواشي';
}
});
}
// 5. Advanced Search Engine
function performSearch() {
const query = searchInput.value.trim().toLowerCase();
searchResults.innerHTML = '';
if (!query) {
searchResults.style.display = 'none';
return;
}
const results = [];
const rows = poemTable.querySelectorAll('tbody tr:not([colspan])');
rows.forEach(row => {
const cells = row.querySelectorAll('td');
if (cells.length >= 3) {
const lineNum = cells[0].textContent.trim();
const shatr1 = cells[1].textContent;
const shatr2 = cells[2].textContent;
const fullLineText = shatr1 + ' ' + shatr2;
if (fullLineText.toLowerCase().includes(query)) {
results.push({
type: 'poem',
id: row.id,
label: `البيت ${lineNum}`,
text: fullLineText,
shatr1: cells[1].innerHTML,
shatr2: cells[2].innerHTML
});
}
}
});
const footnoteItems = document.querySelectorAll('.footnote-item');
footnoteItems.forEach(item => {
const itemText = item.innerText;
if (itemText.toLowerCase().includes(query)) {
const id = item.id.replace('footnote-', '');
results.push({
type: 'footnote',
id: item.id,
label: `حاشية البيت [${id}]`,
text: itemText
});
}
});
if (results.length > 0) {
const ul = document.createElement('ul');
results.forEach(res => {
const li = document.createElement('li');
const a = document.createElement('a');
a.href = '#' + res.id;
a.innerHTML = `<span class="search-red-dot"></span><strong>${res.label}:</strong> `;
let snippet = res.text;
if (snippet.length > 120) {
const idx = snippet.toLowerCase().indexOf(query);
const start = Math.max(0, idx - 40);
const end = Math.min(snippet.length, idx + query.length + 60);
snippet = (start > 0 ? '...' : '') + snippet.substring(start, end) + (end < snippet.length ? '...' : '');
}
const regex = new RegExp(`(${escapeRegExp(query)})`, 'gi');
snippet = snippet.replace(regex, '<mark>$1</mark>');
a.innerHTML += snippet;
a.addEventListener('click', function(e) {
e.preventDefault();
searchResults.style.display = 'none';
searchInput.value = '';
if (res.type === 'footnote' && footnoteSection.classList.contains('collapsed')) {
footnoteSection.classList.remove('collapsed');
toggleFootnotesBtn.textContent = 'إخفاء الحواشي';
}
const targetElem = document.getElementById(res.id);
if (targetElem) {
targetElem.scrollIntoView({ behavior: 'smooth', block: 'center' });
targetElem.classList.add('highlight');
let dot = document.createElement('span');
dot.className = res.type === 'footnote' ? 'search-red-dot' : 'red-dot';
if (res.type === 'footnote') {
targetElem.insertBefore(dot, targetElem.firstChild);
} else {
const cell = targetElem.querySelector('td:first-child');
if (cell) cell.appendChild(dot);
}
setTimeout(() => {
targetElem.classList.remove('highlight');
dot.remove();
}, 6000);
}
});
li.appendChild(a);
ul.appendChild(li);
});
searchResults.appendChild(ul);
searchResults.style.display = 'block';
} else {
searchResults.innerHTML = '<p style="margin:0; color:#666;">لم يتم العثور على نتائج.</p>';
searchResults.style.display = 'block';
}
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
if (searchBtn) searchBtn.addEventListener('click', performSearch);
if (searchInput) {
searchInput.addEventListener('keyup', function(e) {
if (e.key === 'Enter') performSearch();
else if (this.value.trim() === '') {
searchResults.innerHTML = '';
searchResults.style.display = 'none';
}
});
}
if (clearBtn) {
clearBtn.addEventListener('click', function() {
searchInput.value = '';
searchResults.innerHTML = '';
searchResults.style.display = 'none';
});
}
// 6. Guidelines Collapsible State Manager Logic
function toggleGuidelines() {
const content = document.getElementById('guidelinesContent');
const icon = document.getElementById('toggleIcon');
const label = document.getElementById('toggleLabel');
content.classList.toggle('show');
icon.classList.toggle('rotated');
label.textContent = content.classList.contains('show') ? 'إخفاء' : 'إظهار';
localStorage.setItem('guidelinesState', content.classList.contains('show') ? 'open' : 'closed');
}
const header = document.getElementById('guidelines-header');
const content = document.getElementById('guidelinesContent');
const icon = document.getElementById('toggleIcon');
const label = document.getElementById('toggleLabel');
localStorage.setItem('guidelinesState', 'closed');
content.classList.remove('show');
icon.classList.remove('rotated');
label.textContent = 'إظهار';
const savedState = localStorage.getItem('guidelinesState');
if (savedState === 'open') {
content.classList.add('show');
icon.classList.add('rotated');
label.textContent = 'إخفاء';
}
header.addEventListener('click', toggleGuidelines);
});