ميدياويكي:Gadget-shiftrefs.js
ملاحظة: بعد الحفظ، قد يلزمك إفراغ الكاش لرؤية التغييرات.
/*
// Temporary copy from https://ru.wikipedia.org/wiki/Участник:Ignatus/shiftrefs.js
// Authors: https://ru.wikipedia.org/wiki/Участник:Ignatus/shiftrefs.js?action=history
function lebedevrefs()
{
var diglasttext;
var getsimpletext;
diglasttext = function (n)
{
return n.lastChild ? diglasttext(n.lastChild) : n
};
getsimpletext = function (n)
{
return n.innerHTML.replace(/<(?:"(?:\\\\|\\"|\\[^"]|[^\\"])*"|'(?:\\\\|\\'|\\[^']|[^\\'])*'|[^"'>])+>/ig, ''); //'
}; //innerText работает не везде
var zone = document.getElementById('wikiPreview') || document.getElementById('bodyContent') ||
document.getElementById('mw_contentholder') || document.getElementById('article') || document.getElementsByClassName("wikEdFrameBodySyntax")[0];
var alles = Array();
{
var j = zone.getElementsByTagName('*');
for (var i = 0; i < j.length; i++)
{
alles[i] = j[i]
};
};
var getdots = /^([\s\S]*?)([.,…،؛]*)$/;
var i = 0;
var f = function ()
{
if (i < alles.length)
{
var ch = alles[i].childNodes;
// Ищем последовательности элементов класса reference
// а также рассматриваем ноды до и после них
for (var j = 0; j < ch.length; j++)
{
var l = 0;
while (j + l < ch.length // &&
&&
(ch[j + l].nodeType == 1) // && // элемент
&&
/(^|\s)reference(\s|$)/i.test(ch[j + l].className)
)
{
l++
};
if (l)
{ //есть группа
var grp = document.createElement('span');
for (var k = 0; k < l; k++)
{
grp.appendChild(ch[j]);
//alles[i].removeChild(ch[j]);//автоматом
};
if (j < ch.length)
{
alles[i].insertBefore(grp, ch[j])
}
else
{
alles[i].appendChild(grp)
};
grp.style.whiteSpace = 'nowrap';
var ppw = 0.;
if (j)
{
if (ch[j - 1].nodeType == 3)
{ // текст
var a = /^([\S\s]*\s)?(\S*?)([،؛.,…]*)?$/.exec(ch[j - 1].nodeValue);
ch[j - 1].nodeValue = a[1] || '';
var b = document.createElement('span');
var t = document.createTextNode(a[3] || a[2]);
b.appendChild(t);
grp.insertBefore(b, grp.firstChild);
if (a[3])
{
if (mw.config.get('wgPageContentLanguage') == 'ar')
{
b.style.marginLeft = '-' + b.offsetWidth + 'px';
}
else
{
b.style.marginRight = '-' + b.offsetWidth + 'px';
}
t.nodeValue = a[2] + t.nodeValue;
};
ppw = b.offsetWidth;
}
else
{ // если предыдущий узел - элемент
var lt = diglasttext(ch[j - 1]);
var a = getdots.exec(lt.nodeValue);
if (a[2])
{ //финишные точки выделяем
lt.nodeValue = a[1];
var b = document.createElement('span');
b.appendChild(document.createTextNode(a[2]));
lt.parentNode.appendChild(b);
ppw = b.offsetWidth;
if (mw.config.get('wgPageContentLanguage') == 'ar')
{
b.style.marginLeft = '-' + ppw + 'px';
}
else
{
b.style.marginRight = '-' + ppw + 'px';
}
};
if (/nowrap|pre$/.test(ch[j - 1].style.whiteSpace) || !/\s/.test(getsimpletext(ch[j - 1])))
{
//если его можно втащить в неразрывный текст, делаем это
grp.insertBefore(ch[j - 1], grp.firstChild);
ppw += grp.firstChild.offsetWidth;
}
}; //else
}; //if ( j )
if (grp.nextSibling)
{ //Смотрим дальше, если текст, отрезаем начальную точку
if (grp.nextSibling.nodeType == 3)
{
var a = /^([.،؛,…]*)([\s\S]*?)$/.exec(grp.nextSibling.nodeValue);
if (a[1])
{
grp.nextSibling.nodeValue = a[2];
var b = document.createElement('span');
b.appendChild(document.createTextNode(a[1]));
grpw = grp.offsetWidth;
grp.appendChild(b);
if (mw.config.get('wgPageContentLanguage') == 'ar')
{
b.previousSibling.style.marginLeft = (ppw - grpw) + 'px';
}
else
{
b.previousSibling.style.marginRight = (ppw - grpw) + 'px';
}
b.previousSibling.style.position = 'relative';
if (mw.config.get('wgPageContentLanguage') == 'ar')
{
b.previousSibling.style.right = '2px';
}
else
{
b.previousSibling.style.left = '2px';
}
b.previousSibling.style.borderBottom = 'red 2px dotted';
if (mw.config.get('wgPageContentLanguage') == 'ar')
{
b.style.marginLeft = (grpw - ppw - b.offsetWidth) + 'px';
}
else
{
b.style.marginRight = (grpw - ppw - b.offsetWidth) + 'px';
}
} //if(a[1])
} //if( grp.nextSibling.nodeType==3 )
} //if(grp.nextSibling)
} //if(l)
}; //for(ch)
i++;
window.setTimeout(f, 0); //обрабатываем действия пользователя, затем идём дальше
}
else
{ //(i>=alles.length)
f = null; //помогаем мусорнице
}; //if(i<alles.length)
}; //f
if (alles.length)
{
f()
}; //запускаем выполнение
};
if (mw.config.get('wgNamespaceNumber') >= 0 && mw.config.get('wgUserName')) $(lebedevrefs);
log('loaded shiftrefs');
});
*/
//زر صندوق التحرير
//importScript( 'User:Erutuon/scripts/footnoteCleanup.js' ); // Backlink: [[User:Erutuon/scripts/footnoteCleanup.js]] // Moves refs and citation needed tags after punctuation.
var customizeToolbar = function ()
{
$('#wpTextbox1').wikiEditor('addToToolbar',
{
'section': 'advanced',
'group': 'format',
'tools':
{
'section':
{
label: 'تصويب مكان علامات المراجع',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/e/e0/نقطة_مرجع_محرر_الويكي.png',
action:
{
type: 'callback',
execute: function (context)
{
cleanUpFootnotes();
}
}
}
}
});
};
/* Check if view is in edit mode and that the required modules are available. Then, customize the toolbar … */
if (['edit', 'submit'].indexOf(mw.config.get('wgAction')) !== -1)
{
mw.loader.using('user.options').then(function ()
{
// This can be the string "0" if the user disabled the preference ([[phab:T54542#555387]])
if (mw.user.options.get('usebetatoolbar') == 1)
{
$.when(
mw.loader.using('ext.wikiEditor'), $.ready
).then(customizeToolbar);
}
});
}
// Add the customizations to LiquidThreads' edit toolbar, if available
mw.hook('ext.lqt.textareaCreated').add(customizeToolbar);
function cleanUpFootnotes()
{
var textbox = $("#wpTextbox1");
if (!textbox)
return;
const oldContents = textbox.val();
var contents = oldContents;
var escaped = [];
var i = 0;
var replacements = [];
var count = 0;
var escape = function (text, regexString)
{
var regex = new RegExp(regexString, "g");
text = text.replace(
regex,
function (match)
{
escaped[i] = match;
var replacement = "%%" + i + "%%";
i += 1;
return replacement;
}
);
return text;
};
var puncRegex = /((?:%%\d+%%)+)([\؛\،\.\,\;\:\"]{1,3})/g;
var reorder = function (match, capture1, capture2)
{
count += 1;
var replacement = capture2 + capture1;
replacements.push(replacement);
return replacement;
};
var fixPunctuationPlacement = function (text)
{
while (puncRegex.test(text))
text = text.replace(
/((?:%%\d+%%)+)([\؛\،\.\,\;\:\"]{1,3})/g,
reorder
);
return text;
};
/* Escape various things:
ref tags */
contents = escape(
contents,
"<ref[^>]*>[^<]+<\\/ref>"
);
contents = escape(
contents,
"<ref[^\\/]+\\/>"
);
// citation needed
contents = escape(
contents,
"\\{\\{(?:[Cc]itation needed|[Cc]n|[Ff]act|[Cc]b|[Cc]tn|[Rr]ef\\?)\\|[^\}]+\\}\\}"
);
contents = fixPunctuationPlacement(contents);
// footnote templates
/* Handles up to one level of nested templates.
Any more, and there may be problems. */
contents = escape(
contents,
"\\{\\{(?:sfn|efn|rfn)\\|(?:[^\\}]*?(?:\\{\\{[^\\}]+\\}\\})?)+\\}\\}"
);
if (i > 0)
{
mw.notify(i + " refs found.");
}
contents = fixPunctuationPlacement(contents);
if (count > 0)
{
mw.notify(count + " correction" + ((count > 1 && "s") || "") + " made: " + replacements.join());
}
/* Unescape the various things escaped above.
This has to be done twice, since escaping was done twice. */
contents = contents.replace(
/%%(\d+)%%/g,
function (wholematch, number)
{
number = Number(number);
return escaped[number];
}
);
contents = contents.replace(
/%%(\d+)%%/g,
function (wholematch, number)
{
number = Number(number);
return escaped[number];
}
);
var isUnchanged = (oldContents === contents);
if (isUnchanged)
{
mw.notify("No misplaced footnotes or tagging templates were found.");
}
textbox.val(contents);
$("#wpSummary").val(function (index, summary)
{
var addition = "[[:ar:mediawiki:gadget-shiftrefs|تصويب مكان علامة المرجع]]";
const afterSectionName = summary.match(/^(?:\/\*[^\*]+\*\/)?\s*(.+)/);
if (afterSectionName && afterSectionName[1].length > 1)
{
addition = "; " + addition;
}
if (!isUnchanged && (!afterSectionName || !afterSectionName[1].includes(addition)))
return summary + addition;
else
return summary;
});
}