مدیاویکی:Common.js: تفاوت میان نسخهها
Esfandiari (بحث | مشارکتها) بدون خلاصۀ ویرایش برچسب: برگرداندهشده |
Esfandiari (بحث | مشارکتها) بدون خلاصۀ ویرایش |
||
| (۲ نسخهٔ میانیِ ایجادشده توسط همین کاربر نشان داده نشد) | |||
| خط ۷۱۹: | خط ۷۱۹: | ||
}); | }); | ||
/* سیستم جستجوی شهرها و استانها */ | |||
mw.hook('wikipage.content').add(function ($content) { | |||
var $wrapper = $content.find('#city-search-wrapper'); | |||
// فقط در صفحاتی اجرا شود که قالب در آنها قرار دارد | |||
if (!$wrapper.length) { | |||
return; | |||
} | |||
/ | // جلوگیری از اجرای دو بار کد در صفحات داینامیک | ||
( | if ($wrapper.data('citySearchReady')) { | ||
return; | |||
} | |||
$wrapper.data('citySearchReady', true); | |||
var cityData = { | |||
"آذربایجان شرقی": [ | "آذربایجان شرقی": [ | ||
{ | { | ||
| خط ۴٬۵۴۱: | خط ۴٬۵۵۰: | ||
] | ] | ||
}; | }; | ||
var $input = $wrapper.find('.city-search-input'); | |||
var $container = $wrapper.find('.city-results-container'); | |||
function normalizeText(text) { | |||
return String(text) | |||
.replace(/ي/g, 'ی') | |||
.replace(/ك/g, 'ک') | |||
.trim() | |||
.toLowerCase(); | |||
} | |||
function escapeHtml(text) { | |||
return String(text) | |||
.replace(/&/g, '&') | |||
.replace(/</g, '<') | |||
.replace(/>/g, '>') | |||
.replace(/"/g, '"') | |||
.replace(/'/g, '''); | |||
} | |||
function render(filter) { | |||
var query = normalizeText(filter); | |||
var html = ''; | |||
var resultCount = 0; | |||
data.forEach(function (item) { | |||
var provinceMatches = normalizeText(item.province).indexOf(query) !== -1; | |||
var cities = item.cities.filter(function (city) { | |||
return provinceMatches || normalizeText(city).indexOf(query) !== -1; | |||
}); | |||
if (!cities.length) { | |||
return; | |||
} | |||
resultCount++; | |||
html += '<section class="province-section">'; | |||
html += '<h3 class="province-title">' + escapeHtml(item.province) + '</h3>'; | |||
html += '<ul class="city-list">'; | |||
cities.forEach(function (city) { | |||
html += '<li class="city-item">' + escapeHtml(city) + '</li>'; | |||
}); | |||
html += '</ul>'; | |||
html += '</section>'; | |||
}); | |||
if (!resultCount) { | |||
html = '<p class="city-no-result">شهری یا استانی با این نام پیدا نشد.</p>'; | |||
} | } | ||
$container.html(html); | |||
} | |||
$input.on('input', function () { | |||
render($(this).val()); | |||
}); | }); | ||
// لود اولیه | |||
render(''); | |||
}); | |||
/* | |||
Faraghaib / فراغیب | |||
Paste this file into: MediaWiki:Common.js | |||
Vanilla JavaScript; no external library or framework is required. | |||
*/ | |||
(function () { | |||
"use strict"; | |||
function toPersianNumber(value) { | |||
return String(value).replace(/\d/g, function (digit) { | |||
return "۰۱۲۳۴۵۶۷۸۹"[digit]; | |||
}); | |||
} | |||
function initCounter(counter) { | |||
if (counter.dataset.fgCounterReady === "true") { | |||
return; | |||
} | |||
counter.dataset.fgCounterReady = "true"; | |||
var target = Number(counter.getAttribute("data-fg-count")) || 0; | |||
var suffix = counter.getAttribute("data-fg-suffix") || ""; | |||
var duration = 1100; | |||
var start = null; | |||
function frame(timestamp) { | |||
if (start === null) { | |||
start = timestamp; | |||
} | |||
var progress = Math.min((timestamp - start) / duration, 1); | |||
var eased = 1 - Math.pow(1 - progress, 3); | |||
var current = Math.round(target * eased); | |||
counter.textContent = toPersianNumber(current) + suffix; | |||
if (progress < 1) { | |||
window.requestAnimationFrame(frame); | |||
} | |||
} | |||
window.requestAnimationFrame(frame); | |||
} | |||
function initCounters(root) { | |||
var counters = root.querySelectorAll("[data-fg-count]"); | |||
if (!counters.length) { | |||
return; | |||
} | |||
if (!("IntersectionObserver" in window)) { | |||
counters.forEach(initCounter); | |||
return; | |||
} | |||
var observer = new IntersectionObserver(function (entries, currentObserver) { | |||
entries.forEach(function (entry) { | |||
if (entry.isIntersecting) { | |||
initCounter(entry.target); | |||
currentObserver.unobserve(entry.target); | |||
} | |||
}); | |||
}, { threshold: 0.4 }); | |||
counters.forEach(function (counter) { | |||
observer.observe(counter); | |||
}); | |||
} | |||
function initReveal(root) { | |||
var elements = root.querySelectorAll(".fg-reveal"); | |||
if (!elements.length || !("IntersectionObserver" in window)) { | |||
return; | |||
} | |||
elements.forEach(function (element) { | |||
element.classList.add("fg-reveal--pending"); | |||
}); | |||
var observer = new IntersectionObserver(function (entries, currentObserver) { | |||
entries.forEach(function (entry) { | |||
if (entry.isIntersecting) { | |||
entry.target.classList.add("fg-reveal--visible"); | |||
currentObserver.unobserve(entry.target); | |||
} | |||
}); | |||
}, { threshold: 0.12 }); | |||
elements.forEach(function (element) { | |||
observer.observe(element); | |||
}); | |||
} | |||
function initSlider(slider) { | |||
if (slider.dataset.fgSliderReady === "true") { | |||
return; | |||
} | |||
var slides = Array.prototype.slice.call(slider.querySelectorAll(".fg-slide")); | |||
var dots = Array.prototype.slice.call(slider.querySelectorAll(".fg-slider__dot")); | |||
var previous = slider.querySelector(".fg-slider__button--prev"); | |||
var next = slider.querySelector(".fg-slider__button--next"); | |||
if (!slides.length || !dots.length) { | |||
return; | |||
} | |||
var activeIndex = 0; | |||
var timer = null; | |||
var reducedMotion = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches; | |||
slider.dataset.fgSliderReady = "true"; | |||
slider.classList.add("fg-slider--ready"); | |||
function show(index) { | |||
activeIndex = (index + slides.length) % slides.length; | |||
slides.forEach(function (slide, slideIndex) { | |||
var active = slideIndex === activeIndex; | |||
slide.classList.toggle("is-active", active); | |||
slide.setAttribute("aria-hidden", active ? "false" : "true"); | |||
}); | |||
dots.forEach(function (dot, dotIndex) { | |||
var active = dotIndex === activeIndex; | |||
dot.classList.toggle("is-active", active); | |||
dot.setAttribute("aria-selected", active ? "true" : "false"); | |||
dot.setAttribute("tabindex", active ? "0" : "-1"); | |||
}); | |||
} | |||
function stop() { | |||
if (timer !== null) { | |||
window.clearInterval(timer); | |||
timer = null; | |||
} | |||
} | |||
function start() { | |||
if (reducedMotion || document.hidden || timer !== null) { | |||
return; | |||
} | |||
timer = window.setInterval(function () { | |||
show(activeIndex + 1); | |||
}, 6200); | |||
} | |||
if (previous) { | |||
previous.addEventListener("click", function () { | |||
show(activeIndex - 1); | |||
stop(); | |||
start(); | |||
}); | |||
} | |||
if (next) { | |||
next.addEventListener("click", function () { | |||
show(activeIndex + 1); | |||
stop(); | |||
start(); | |||
}); | |||
} | |||
dots.forEach(function (dot, index) { | |||
dot.addEventListener("click", function () { | |||
show(index); | |||
stop(); | |||
start(); | |||
}); | |||
dot.addEventListener("keydown", function (event) { | |||
if (event.key === "ArrowLeft" || event.key === "ArrowRight") { | |||
event.preventDefault(); | |||
show(activeIndex + (event.key === "ArrowLeft" ? 1 : -1)); | |||
dots[activeIndex].focus(); | |||
stop(); | |||
start(); | |||
} | |||
}); | |||
}); | |||
slider.addEventListener("mouseenter", stop); | |||
slider.addEventListener("mouseleave", start); | |||
slider.addEventListener("focusin", stop); | |||
slider.addEventListener("focusout", function (event) { | |||
if (!slider.contains(event.relatedTarget)) { | |||
start(); | |||
} | |||
}); | |||
document.addEventListener("visibilitychange", function () { | |||
if (document.hidden) { | |||
stop(); | |||
} else { | |||
start(); | |||
} | |||
}); | |||
show(0); | |||
start(); | |||
} | |||
function init(root) { | |||
var container = root && root.jquery ? root[0] : root; | |||
var home = container && container.querySelector ? container.querySelector(".fg-home") : null; | |||
if (!home) { | |||
return; | |||
} | |||
home.querySelectorAll(".fg-slider").forEach(initSlider); | |||
initCounters(home); | |||
initReveal(home); | |||
} | |||
if (window.mw && window.mw.hook) { | |||
window.mw.hook("wikipage.content").add(init); | |||
} else { | |||
document.addEventListener("DOMContentLoaded", function () { | |||
init(document); | |||
}); | |||
} | |||
}()); | }()); | ||