ميدياويكي:Gadget-Numeral-converter-toggle.js
المظهر
هذه الصفحة هي جزء من الإضافة «Numeral-converter-toggle»، يستعملها 183 مستخدم. |
ملاحظة: بعد الحفظ، قد يلزمك إفراغ الكاش لرؤية التغييرات ( ).
/**
* Numeral converter toggle
* forked from [[mw:MediaWiki:Gadget-Numerakri.js]]
* maintainer حبيشان
*/
mw.loader.using(['mediawiki.cookie', 'mediawiki.util', 'mediawiki.user']).then(function () {
'use strict';
const skipclass = ['mwgadget-numconv-skip', 'mw-json'],
we = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '%'],
es = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩', '٪'],
rejectedTags = ['input', 'textarea', 'style', 'script', 'pre'],
settingkey = 'gadget-Numeral_converter',
msgs = {
'numconv-turn-on-label': 'أرقام مشرقية',
'numconv-turn-on-tooltip': 'تحويل الأرقام إلى أرقام مشرقية',
'numconv-turn-off-label': 'أرقام مغربية',
'numconv-turn-off-tooltip': 'إبقاء الأرقام مغربية',
};
var isOn = mw.loader.getState('ext.gadget.Numeral_converter') === 'ready',
walker;
function hasAnyClass(element, classes) {
let ret = false;
for(let i=1; i<classes.length; i++) {
if (element.hasClass(classes[i])) {
ret = true;
break;
}
}
return ret;
}
/**
* @param {HTMLElement|TextNode} node
* @return {number} NodeFilter.FILTER_* constant
*/
function filterNode(node) {
if (node.nodeType === Node.TEXT_NODE) {
return NodeFilter.FILTER_ACCEPT;
}
var n = node.nodeName && node.nodeName.toLowerCase();
if ( rejectedTags.indexOf(n) > -1 ||
// node.hasAttribute('contenteditable') ||
hasAnyClass($(node), skipclass)
) {
// Skip this element and skip its children
return NodeFilter.FILTER_REJECT;
}
// Skip this element, but check its children
return NodeFilter.FILTER_SKIP;
}
/**
* @param {TextNode} node
*/
function handleTextNode(node) {
function we2es(text) {
for (let i=0; i <= 10; i++) {
text = text.replaceAll(we[i], es[i]);
}
return text
}
function es2we(text) {
for (let i=0; i <= 10; i++) {
text = text.replaceAll(es[i], we[i]);
}
return text
}
var original = node.nodeValue,
changed;
if (isOn) {
changed = we2es(original);
changed = changed.replaceAll(/([A-z]\s*)([٠-٩٪\-\.]+)/g, (match, p1, p2, offset, string) => p1 + es2we(p2));
changed = changed.replaceAll(/([٠-٩٪\-\.]+)([A-z])/g, (match, p1, p2, offset, string) => es2we(p1) + p2);
} else {
changed = es2we(original);
}
if (original !== changed) {
node.nodeValue = changed;
}
}
// https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw-method-requestIdleCallback
function idleWalker(deadline) {
var el;
if (!walker) {
return;
}
while (deadline.timeRemaining() > 0) {
el = walker.nextNode();
if (!el) {
// Reached the end
walker = null;
return;
}
handleTextNode(el);
}
// The user may interact with the page. We pause so the browser can process
// interaction. The text handler will continue after that.
if (walker) {
mw.requestIdleCallback(idleWalker);
}
}
function startPageConversion() {
if (isOn) {
$('ol:lang(ar) li, ol.references, li.references').css('list-style-type', 'arabic-indic');
} else {
$('ol:lang(ar) li, ol.references, li.references').css('list-style-type', 'decimal');
}
// If a walker is already active, replace it.
// If no walker is active yet, start it.
if (!walker) {
mw.requestIdleCallback(idleWalker);
}
walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ALL, filterNode, false);
}
/**
* Save a browser cookie for 30 days, or remove it.
* @param {string|null} value
*/
function saveType(value) {
mw.requestIdleCallback(function () {
if (mw.user.isAnon()) {
mw.cookie.set(settingkey, value, { expires: 30 * 86400 , path: '/' });
} else {
new mw.Api().saveOption(settingkey, value);
mw.user.options.set(settingkey, value);
}
mw.storage.session.set(settingkey, value);
});
}
/**
* @return {string}
*/
function getStoredType() {
var value = mw.user.isAnon() ? mw.cookie.get(settingkey, '0') : mw.user.options.get(settingkey) || '0';
var svalue = mw.storage.session.get(settingkey);
if (svalue && svalue !== value) {
value = svalue;
saveType(value);
} else if (value && Number(value)>1 ) {
value = value === '2'? '1': '0';
saveType(value);
}
return value === '1';
}
function togglePortlets() {
var labelSelector;
switch (mw.config.get('skin')) {
case 'vector':
case 'vector-2022':
case 'minerva':
labelSelector = '#pt-numconvert span:not(:empty), #pt-numconvert-sticky-header span:not(:empty)';
break;
default:
labelSelector = '#pt-numconvert a';
}
$(labelSelector).text(getMsg('label'));
$('#pt-numconvert a, #pt-numconvert-sticky-header a')
.attr('title', getMsg('tooltip'));
}
function setHtmlClass() {
$(document.documentElement).toggleClass('numconv-on', isOn);
}
function toggleMode() {
isOn = !isOn;
saveType(isOn? '1': '0');
togglePortlets();
setHtmlClass()
startPageConversion();
//if (isOn) {
// mw.loader.load('ext.gadget.Numeral_converter');
// } else {
// startPageConversion();
// }
}
function getMsg(suffix) {
var key = 'numconv-turn-' + (isOn ? 'off' : 'on') + '-' + suffix;
return msgs[key];
}
function init() {
// Decide selected type
isOn = getStoredType();
setHtmlClass();
if (isOn && mw.user.isAnon()) {
// mw.loader.load('ext.gadget.Numeral_converter');
startPageConversion();
}
$(mw.util.addPortletLink(
mw.user.isAnon() ? 'p-user-menu-anon-editor' : 'p-personal',
'#',
getMsg('label'),
'pt-numconvert',
getMsg('tooltip'),
null,
mw.user.isAnon() ?
'#pt-createaccount' :
'#pt-preferences'
))
.children().on('click', function (e) {
e.preventDefault();
toggleMode();
});
};
$(function () {
mw.requestIdleCallback(init);
});
});