مدیاویکی:Common.js
از ویکییاد
نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
- فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلیدهای Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-R)
- گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-Shift-R)
- Edge: کلید Ctrl را نگهدارید و روی دکمهٔ Refresh کلیک کنید، یا کلیدهای Ctrl-F5 را با هم فشار دهید
/**
* Umami Analytics tracking (privacy-focused, self-hosted)
*/
(function() {
// Create the script element
var script = document.createElement('script');
// Set attributes exactly as provided by Umami
script.defer = true;
script.src = 'https://cloud.umami.is/script.js';
script.setAttribute('data-website-id', 'f5f75b33-a7ed-4d71-ac5a-7750a48efaa0');
// Append to head (or body – head is preferred for earlier loading)
document.head.appendChild(script);
})();
/**
* Gallery to background-cover: set img src as background on .thumb div + hide img
* → ONLY when the gallerybox is inside an element with class "javidnam"
*/
(function () {
'use strict';
function processGalleries() {
document.querySelectorAll('li.gallerybox').forEach(function (box) {
// Check if this gallerybox is inside a .javidnam container
const container = box.closest('.javidnam');
if (!container) {
return; // skip if not inside .javidnam
}
const thumbDiv = box.querySelector('div.thumb');
if (!thumbDiv) return;
// Quick skip: if this thumb is a known broken/placeholder structure
if (thumbDiv.querySelector('.mw-broken-media, .mw-file-element:not(img), span[typeof="mw:Error"]')) {
return; // broken file link → leave untouched
}
const img = thumbDiv.querySelector('img.mw-file-element');
if (!img) return;
const src = img.src && img.src.trim();
if (!src || src === '' ||
src.includes('brokenimage') ||
src.includes('noimage') ||
src.includes('Special:Redirect/file/') ||
img.alt === '' || img.alt === null) {
return;
}
// Skip tiny/unloaded images (common for broken ones)
if (img.naturalWidth <= 4 || img.naturalHeight <= 4 || img.complete === false) {
return;
}
// Already processed?
if (thumbDiv.dataset.backgroundApplied) {
return;
}
// Apply background
thumbDiv.style.backgroundImage = 'url(' + src + ')';
thumbDiv.style.backgroundSize = 'cover';
thumbDiv.style.backgroundPosition = 'center center';
thumbDiv.style.backgroundRepeat = 'no-repeat';
// Hide original img
img.style.display = 'none';
// Mark as processed
thumbDiv.dataset.backgroundApplied = 'true';
});
}
// Run when DOM is ready
function init() {
processGalleries();
}
if (document.readyState !== 'loading') {
init();
} else {
document.addEventListener('DOMContentLoaded', init);
}
// Mutation observer for dynamic content (DPL, AJAX loads, etc.)
const observer = new MutationObserver(processGalleries);
observer.observe(document.body, { childList: true, subtree: true });
// Extra delayed runs for late-loading thumbs / lazy images
setTimeout(processGalleries, 600);
setTimeout(processGalleries, 1500);
setTimeout(processGalleries, 3500);
})();
// Persian digits → Latin digits converter for CAPTCHA inputs
// Works on edit, login, confirm-edit forms (MathCaptcha, FancyCaptcha, etc.)
( function () {
'use strict';
// Map Persian/Arabic digits to Latin/ASCII
const persianToLatin = {
'۰': '0', '۱': '1', '۲': '2', '۳': '3', '۴': '4',
'۵': '5', '۶': '6', '۷': '7', '۸': '8', '۹': '9',
'٠': '0', '١': '1', '٢': '2', '٣': '3', '٤': '4',
'٥': '5', '٦': '6', '٧': '7', '٨': '8', '٩': '9'
};
function normalizeInput( input ) {
if ( !input || !input.value ) return;
let oldValue = input.value;
let newValue = '';
for ( let char of oldValue ) {
newValue += persianToLatin[char] || char;
}
if ( newValue !== oldValue ) {
input.value = newValue;
// Optional visual feedback (green border flash)
input.style.borderColor = '#4CAF50';
setTimeout( () => { input.style.borderColor = ''; }, 1200 );
}
}
function attachToCaptchaFields() {
// Common CAPTCHA input selectors in MediaWiki
const selectors = [
'#wpCaptchaWord',
'#mw-captcha-text',
'input[name="wpCaptchaWord"]',
'input[name="captchaWord"]',
'input[name="fancycaptcha"]',
'#captchaWord',
'#captchaInput',
'input[type="text"][name*="captcha"]',
'input[type="text"][id*="captcha"]',
'#mw-confirm-edit-captcha-input' // sometimes used
];
selectors.forEach( sel => {
document.querySelectorAll( sel ).forEach( input => {
if ( input.dataset.persianFixAttached ) return;
input.dataset.persianFixAttached = 'true';
// Convert on form submit (main fix)
const form = input.closest( 'form' );
if ( form ) {
form.addEventListener( 'submit', () => {
normalizeInput( input );
}, { capture: true } );
}
// Also convert live (preview, blur, etc.)
input.addEventListener( 'input', () => normalizeInput( input ) );
input.addEventListener( 'blur', () => normalizeInput( input ) );
} );
} );
}
// Run once on load
attachToCaptchaFields();
// Watch for dynamically added forms (AJAX edit dialog, login popup, etc.)
const observer = new MutationObserver( attachToCaptchaFields );
observer.observe( document.body, {
childList: true,
subtree: true
} );
}() );
