توفي الفنان المصري محمود ياسين عن عمر ناهز 79 عاما بعد صراع طويل مع المرض.
0;
if (clearWrapper) clearWrapper.style.display = hasVal ? 'flex' : 'none';
searchBtn.disabled = !hasVal;
}
function showSuggestions(val) {
if (!suggestionsEl) return;
var lower = val.toLowerCase();
var visible = 0;
items.forEach(function (item) {
var match = item.dataset.value.toLowerCase().indexOf(lower) !== -1;
item.style.display = match ? '' : 'none';
if (match) visible++;
});
var show = visible > 0;
suggestionsEl.style.display = show ? 'block' : 'none';
searchForm.classList.toggle('suggestions-open', show);
}
function hideSuggestions() {
if (suggestionsEl) suggestionsEl.style.display = 'none';
searchForm.classList.remove('suggestions-open');
}
// BEIRUT-6923: blur schedules hideSuggestions() after a 200ms delay so a
// click on a suggestion/clear button can register first. Without
// tracking that timeout, a blur immediately followed by a refocus
// (within the 200ms window) still let the stale timeout fire and hide
// the just-reopened dropdown. Cancelling it on focus keeps the
// dropdown's visibility in sync with the input's actual focus state.
var hideSuggestionsTimeout = null;
input.addEventListener('input', function () {
syncControls(this.value);
showSuggestions(this.value);
});
input.addEventListener('focus', function () {
if (hideSuggestionsTimeout) {
clearTimeout(hideSuggestionsTimeout);
hideSuggestionsTimeout = null;
}
showSuggestions(this.value);
});
input.addEventListener('blur', function () {
hideSuggestionsTimeout = setTimeout(hideSuggestions, 200);
});
input.addEventListener('keydown', function (e) {
if (e.key === 'Enter' && this.value) submitQuery(this.value);
});
searchBtn.addEventListener('click', function () {
submitQuery(input.value);
});
if (clearBtn) {
clearBtn.addEventListener('click', function () {
input.value = '';
syncControls('');
hideSuggestions();
input.focus();
});
}
items.forEach(function (item) {
item.addEventListener('mousedown', function () {
var val = this.dataset.value;
input.value = val;
syncControls(val);
submitQuery(val);
});
});
// Pre-populate if there is an existing search query
if (input.value) syncControls(input.value);
// Search / AI Mode toggle
var modeToggle = document.getElementById('search-mode-toggle');
var modeSearchBtn = document.getElementById('search-mode-search');
var modeAiBtn = document.getElementById('search-mode-ai');
var startersEl = document.getElementById('search-starters');
// Starter buttons are server-rendered AI Mode-ready (sideconvo_button
// class + data-sideconvo-* attributes, same as the sitewide banner's
// starters) and are never modified at runtime. SideConvo's own script
// loads asynchronously and appears to scan/bind once against whatever
// is already in the DOM at that point; an earlier version of this file
// toggled the sideconvo_button class per mode, which meant SideConvo
// could bind before the class was ever present (Search mode is the
// default on load) and would never pick the buttons up again — even
// after switching to AI Mode and restoring the class. That was the
// actual cause of AI Mode clicks doing nothing. Mode switching is now
// handled purely via a capture-phase click listener below: Search mode
// cancels the click before it can reach SideConvo's handler, AI Mode
// lets the untouched native click straight through.
function applyStarterMode(isAi) {
if (startersEl) startersEl.classList.toggle('ai-mode', isAi);
}
// AI Mode has no known JS API to open the spotlight overlay directly —
// the only integration surface this codebase has is a real click on an
// element carrying the sideconvo_button class + data-sideconvo-message.
// A typed query (as opposed to clicking an existing starter chip) is
// submitted by reusing one of the real starter buttons already on the
// page, since SideConvo has had a chance to bind to it since page
// load, temporarily overwriting the message it carries before clicking
// it. With no starters configured there's nothing to reuse; a
// throwaway off-screen button is synthesized as a last-resort best
// effort, though it's unlikely to work if SideConvo only binds to
// elements present at its own load time.
function triggerSpotlight(message) {
var reusable = startersEl
? startersEl.querySelector('.search-starter-btn:not(.search-starters-init)')
: null;
if (reusable) {
var originalMessage = reusable.getAttribute('data-sideconvo-message');
reusable.setAttribute('data-sideconvo-message', message);
reusable.click();
window.setTimeout(function () {
reusable.setAttribute('data-sideconvo-message', originalMessage || '');
}, 1000);
return;
}
var trigger = document.createElement('button');
trigger.type = 'button';
trigger.className = 'sideconvo_button sideconvo_button_ltr';
trigger.setAttribute('data-placement', 'search-page-submit');
trigger.setAttribute('data-sideconvo-mode', 'CHAT');
trigger.setAttribute('data-sideconvo-message', message);
trigger.style.cssText = 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;';
document.body.appendChild(trigger);
trigger.click();
window.setTimeout(function () { trigger.remove(); }, 1000);
}
function submitQuery(query) {
if (!query) return;
if (modeToggle && modeToggle.dataset.mode === 'ai') {
triggerSpotlight(query);
} else {
navigate(query);
}
}
if (startersEl) {
// Capture phase, not bubble: this must run and cancel the click
// before it reaches the button itself, so that in Search mode
// SideConvo's own click handling — whatever form it takes, delegated
// or bound directly to the element — never fires. In AI Mode this
// listener does nothing and the native click proceeds straight
// through to SideConvo untouched.
startersEl.addEventListener('click', function (event) {
if (!modeToggle || modeToggle.dataset.mode !== 'search') return;
var btn = event.target.closest('.search-starter-btn');
if (!btn || btn.classList.contains('search-starters-init')) return;
event.preventDefault();
event.stopPropagation();
var val = stripEmoji(btn.textContent.trim());
input.value = val;
syncControls(val);
navigate(val);
}, true);
}
if (modeToggle && modeSearchBtn && modeAiBtn) {
var setMode = function (mode) {
var isAi = mode === 'ai';
input.setAttribute('placeholder', isAi ? saData.ai_placeholder : saData.search_placeholder);
searchBtn.setAttribute('aria-label', isAi ? saData.ai_submit_label : saData.search_submit_label);
modeAiBtn.classList.toggle('is-active', isAi);
modeAiBtn.setAttribute('aria-pressed', String(isAi));
modeSearchBtn.classList.toggle('is-active', !isAi);
modeSearchBtn.setAttribute('aria-pressed', String(!isAi));
modeToggle.dataset.mode = mode;
applyStarterMode(isAi);
searchForm.classList.toggle('ai-mode', isAi);
};
modeSearchBtn.addEventListener('click', function () { setMode('search'); });
modeAiBtn.addEventListener('click', function () {
setMode('ai');
// Switching into AI Mode with a query already typed launches the
// spotlight immediately with that text, instead of leaving the user
// to press enter/search again after the mode switch.
if (input.value.trim()) {
triggerSpotlight(input.value.trim());
}
});
setMode('search');
}
});
}());