אונטערשייד צווישן ווערסיעס פון "מעדיעוויקי שמועס:Gadget-TemplateParamWizard"

פון המכלול
קפיצה לניווט קפיצה לחיפוש
ק (החלפת טקסט – "עזרה:גאדג'טים" ב־"הילף:טשאטשקעס")
אין תקציר עריכה
צייכן: צוריקגעשטעלט
שורה 1: שורה 1:
[[קובץ:TemplatesWizard.png|250px|ממוזער|דוגמה לשימוש באשף תבניות עם ה[[המכלול:תבנית|תבנית]] "{{תב|מדען}}". לאחר בחירת תבנית, ייפתח [[טופס]] למילוי תבנית כמוצג.]]
//Template parameters wizard
'''אשף התבניות''' (לא "אשף תבניות קישורים"), מאפשר הוספה ומילוי של [[המכלול:תבנית|תבניות]] קיימות היישר מ[[הילף:רעדאגירן א בלאט|דף העריכה]], בקלות ובמהירות. האשף הכללי עובד בצורה חלקית. אשף התבניות עובד באופן שלם, רק כאשר יש לתבנית מבוקשת templatedata (ראו בהמשך).
//Written by [[User:קיפודנחש]]
"use strict";
if(($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1) && ( !$('#wpTextbox1').prop( 'readonly' ) ) )
$(function($) {
// template parameter is an object with the following fields:
// desc: desciption string
// defval: default value (optional)
// options: object with optional fields:
//// multiline: number of lines
//// depends: another field's name
//// required: boolean
//// date: use JS date widget
//// choices: array of legal values for the field
//// extended: this field will not show on initial screen, and will appear once the user selects "show all fields"


אשף התבניות בעורך קוד מקור פועל בצורה דומה לאשף המקביל בעורך החזותי. בעורך החזותי מפעילים את האשף על ידי הקשה על התבנית, ואז "עריכה", או, כדי להוסיף תבנית חדשה, הקשה על "הוספה" בתפריט העליון, ובחירה ב"תבנית".
var
// templateParams is keyed by paramName.
templateParams,
paramsOrder,
// which template are we working on
template,
// array of pairs - [paramName, inputField]
dialogFields,
// table rows keyed by paramName
rowsBypName,
// the fields, keyed by paramName
fieldsBypName,
// boolean, indicating the source of data is templatedata.
tdTemplate,
// boolean, indicating the source of the data is analyzing the template page itself.
rawTemplate,
isInline,
rtl = $('body').is('.rtl'),
// test to see if a string contains wikiCode and hence needs parsing, or cen be used as is.
wikiCodeFinder = /[\[\]\{\}<>]/,
globalExplanation = '',
extendedParamCssRule,
anyExtended = false,
localStorageKey = 'templateParamWizard',
emptiesKey = 'writeEmpties',
oneLineTemplate = 'oneLineTemplate',
allAliases = [];


==התקנת האשף==
function addParam(name) {
בראש הדף, תחת "העדפות" ← "[[הילף:טשאטשקעס|גאדג'טים]]" ([[באַזונדער:העדפות#mw-prefsection-gadgets]]), יש לבחור "{{מדיה ויקי:Gadget-TemplateParamWizard}}". שימו לב, שהבחירה הזו מאופשרת כ[[ברירת מחדל]].
if ($.inArray(name, paramsOrder) == -1)
paramsOrder.push(name);
}


אם הוספתם את השורה הבאה ל[[באַזונדער:הדף שלי/common.js]], אנא הסירו אותה:
function paramsFromSelection() {
<syntaxhighlight lang="javascript">
var selection = $("#wpTextbox1").textSelection('getSelection').replace(/^\s*\{\{|\}\}\s*$/g, ''); //scrap the first {{ and last }}
importScript('mediawiki:TemplateParamWizard.js');
var specials = [],
</syntaxhighlight>
match;
while (true) { //extract inner links, inner templates and inner params - we don't want to split those.
match = selection.match(/(\{\{[^\{\}\]\[]*\}\}|\[\[[^\{\}\]\[]*\]\]|\[[^\{\}\]\[]*\])/);
if (! match || ! match.length)
break;
specials.push(match[0]);
selection = selection.replace(match[0], "\0" + specials.length + "\0");
}
var params = selection.split(/ *\| */);
params.shift(); // remove the template name
var ordered = 0;
for (var i in params) {
var param = params[i];
if ( ! /=/.test(param) ) {
param = ++ordered + '=' + param;
}
var paramPair = param.split("=");
var name = $.trim(paramPair.shift());
if ( ! isNaN( name ) ) {
ordered = parseInt( name ); // this still won't work as advertise when template contains explicit parameter 2 before implicit 1: {{x | 2 = hey | ho }}
}
var val = paramPair.join('=');
while (true) {
match = val.match(/\0(\d+)\0/);
if (! match || ! match.length)
break;
val = val.replace(match[0], specials[parseInt(match[1], 10)-1]);
}
if (name && paramPair.length) {
var tp = templateParams[name] =
templateParams[name] ||
~allAliases.indexOf(name) && { param:{}, options: {isAlias: 1} } ||
{param: {}, options: { notInParamPage: 1}};
addParam(name);
$.extend( tp.options, { defval: val } );
if ( /\n/.test( val ) ) $.extend( tp.options, { multiline : 5 } );
// next line is for the case where there are "choices"' but current value is not one of them: add it as a new choice.
if ( typeof tp.options.choices === 'string' && tp.options.choices.indexOf( val ) < 0 )
tp.options.choices += ( ', ' + val );
}
}
}


==הוראות שימוש==
function buildParamsRaw(data) {
קיימות שתי דרכים להשתמש במוסטער:
var
# '''יצירת''' תבנית חדשה בעת עריכת ערך.
paramExtractor = /{{3,}(.*?)[<|}]/mg,
# '''עדכון''' תבנית על בסיס תבנית קיימת בעת עריכת ערך.
m;
while (m = paramExtractor.exec(data)) {
var paramName = $.trim(m[1]);
templateParams[paramName] = { desc: '', options: {multiline: 5}, label: paramName, param:{} };
addParam(paramName);
}
}
function buildParamsTd(data) {
var params = data.params,
paramOrder = data.paramOrder;


===יצירת תבנית חדשה===
function optionsOfParam(param) {
בכדי ליצור תבנית חדשה, יש ללחוץ על הכפתור [[קובץ:Vector toolbar template button.png]] כאשר נמצאים במצב עריכה. האשף יפתח חלון, שמאפשר להזין את שם התבנית הרצויה מתוך רשימה. לאחר לחיצה על "אישור", תגיעו לאשף עצמו.
var options = {};
if (param.required) options.required = true;
if (param.suggestedvalues && param.suggestedvalues.length) options.choices = param.suggestedvalues.join(',');
return options;
}


ניתן גם לרשום את שם התבנית בערך באופן הבא <nowiki>{{שם תבנית}}</nowiki>, ואז לסמן את התבנית וללחוץ על הכפתור [[קובץ:Vector toolbar template button.png]]. האשף מייצר ומציג טופס עם שם הפרמטר, ותיבת הכנסת טקסט ([[שדה (אחסון נתונים)|שדה מילוי]]).
function onemore(name) {
var param = params[name];
if (param.deprecated)
return; // ignore deprecated parameters - pretend they are not in TD.
templateParams[name] = {  
desc: param.description || '',
options: optionsOfParam(param),
label: param.label || name,  
param: param
};
if (param.aliases) $.merge(allAliases, param.aliases); // collect alliases if there are any
addParam(name);
}
isInline = data.format === 'inline';
if (paramOrder && paramOrder.length)
for (var ind in paramOrder)
onemore(paramOrder[ind]);
else // no order - take them as they come.
for (var paramname in params)
onemore(paramname);


===עדכון תבנית קיימת===
// derive placeholders for feilds derived from wikidata
ניתן להשתמש באשף גם לתיקונים קטנים (או גדולים) בתבנית קיימת, שכבר מולאה באופן חלקי. לשם כך, יש לסמן את התבנית הקיימת בערך וללחוץ על כפתור [[קובץ:Vector toolbar template button.png]]. האשף יקרא את הנתונים מהערך עצמו.
if (data.maps && data.maps.hasOwnProperty('wikidata') && mw.config.get('wgWikibaseItemId')) {
var wikidataFormattedValues = $('<div>');
for (var k in data.maps['wikidata']) {
wikidataFormattedValues.append($('<span>', {id: k, text:'{{#property:' + k + '}}'}))
}
$.post(
mw.util.wikiScript('api'),
{action: 'parse', text: wikidataFormattedValues.html(), disablelimitreport: 1, format: 'json', prop: 'text', title: mw.config.get('wgPageName')},
function(wbd) {
if (!wbd || !wbd.parse || !wbd.parse.text) return;
for (var k in data.maps['wikidata']) {
var wikidataVal = $('#' + k, wbd.parse.text['*']).text(),
field = fieldsBypName[data.maps['wikidata'][k]];
if (field)
field.prop('placeholder', wikidataVal);
}
}
);
}
}


'''שימו לב''', שיש לסמן את התבנית כולה, כולל הפרמטרים שכבר קיימים. האשף יאסוף את הערכים הללו מהדף וימלא את השדות המתאימים.
function buildParams(data) {
var
lines = data.split("\n"),
line;


בזמן עריכה, אם מאופשר אצלכם ה[[הילף:טשאטשקעס|גאדג'ט]] של autocomplete, הוא יעבוד גם על השדות באשף; כלומר, כאשר תוסיפו <code><nowiki>[[</nowiki></code> לאחד השדות באשף ותתחילו להקיש שם ערך, האשף יציע ערכים מתאימים לתווים שכבר הקשתם, בדומה ל[[המכלול:ניווט|תיבת החיפוש]].
function extractGlobalExplanation() {
line = line.replace(/[!\|][^\|]*\|/, '');
if (wikiCodeFinder.test(line))
$.post(
mw.util.wikiScript('api'),
{action: 'parse', text: line, disablepp: 1, format: 'json'},
function(data) {
var html = data.parse.text['*'];
globalExplanation = html;
$('#tpw_globalExplanation').html(html).find('a').attr({target: '_blank'});
}
);
else
globalExplanation = line;
}


== templatedata ==
while (lines && lines.length) {
כאשר יש לתבנית tempaltedata, האשף ישתמש בה לרשימת הפרמטרים, תיאור כל פרמטר, החלטה מתי פרמטר מסוים הוא "חובה", והחלטה האם לסדר תבנית בשורה אחת או שורה לכל פרמטר. אם אין tempaltedata, האשף מנסה למצות את רשימת הפרמטרים על ידי ניתוח דף התבנית, פעולה שהצלחתה אינה מובטחת. אם רשימת הפרמטרים שהאשף מציע אינה נכונה, יש ליצור tempaltedata בתבנית, או לתקן את הקיים.
line = lines.shift();
if (!(/^\|-/.test(line))) // look for |- this is wikitext for table row.
continue;
line = lines.shift();
if (line.indexOf('globalExplanation') + 1) {
extractGlobalExplanation();
continue;
}
if (! line || ! (/^\|/.test(line))) //wikitext for column
continue;
line = line.substr(1); // get rid of the leading |
var fields = line.split('||');
if (fields.length < 2)
continue;
var name = $.trim(fields[0]);
if (! name)
continue;
var desc = $.trim(fields[1]);
var pAttribs = {desc: desc};
if (fields.length > 2)
pAttribs.options = analyzeOptions($.trim(fields[2]));


מידע נוסף על tempaltedata ניתן למצוא ב[[mw:Help:TemplateData/he]].
templateParams[name] = pAttribs;
addParam(name);


==ראו גם==
}
* [[המכלול:תבנית]]
}
* [[הילף:מוסטערן]]


[[קאטעגאריע:המכלול טעכנישע הילף]]
function analyzeOptions(str) {
var res = {},
avail = ['multiline', 'required', 'depends', 'defval', 'choices', 'date', 'extended'], // maybe we'll have more in the future
tavail = $.map(avail, i18n),
options = str.split(/\s*;\s*/);
for (var i in options) {
var option = options[i].split(/\s*=\s*/);
var ind = $.inArray(option[0], tavail);
if (ind + 1)
res[avail[ind]] = option.length > 1 ? option[1] : true;
}
anyExtended = anyExtended || res.extended;
return res;
}
 
function createWikiCode() {
var par = [template],
delim = $('#' + oneLineTemplate).prop('checked') ? '' : '\n',
paramValueDelim =  $('#' + oneLineTemplate).prop('checked') ? '=' : ' = ',
createEmpties = $('#createEmpties').prop('checked'),
mustNumberNameless,
valuedOrdered;
for (var i = dialogFields.length - 1; i >= 0; i--) {
var field = dialogFields[i],
val = $.trim(field[1].val());
if (isNaN(field[0])) continue; // look only at order-based fields
mustNumberNameless |=
/=/.test(val) // order-based value containing "="
|| valuedOrdered && !val; // empty ordered w lower index than a non-empty one.
if (val) valuedOrdered = true;
}
for (var i in dialogFields) {
var
field = dialogFields[i],
name = $.trim(field[0]),
f = field[1],
opts = f.data('options'),
param = templateParams[name],
hidden = f.parents('.tpw_hidden').length,
val = f.val().replace( /\s+$/, '' ); // leave leading newlines, for lists etc., but remove trailing.
if (param && param.param && param.param.type === 'url')
val = val.replace(/\|/g, '{{!}}');
if (f.attr('type') == 'checkbox' && ! f.prop('checked'))
val = "";
if ( ( !createEmpties || opts.notInParamPage )  && $.trim( val ) === "" )
continue;//skip parameters with no value
var next = mustNumberNameless || isNaN(name)
? name + paramValueDelim + $.trim( val )
: $.trim( val );
par.push(next);
}
return "{{" + par.join(delim + ($('#' + oneLineTemplate).prop('checked')? "|" : "| ")) + delim + "}}";
}
 
function showPreview() {
var temp = createWikiCode();
$.post(mw.util.wikiScript('api'),
{action: 'parse',
title: mw.config.get('wgPageName'),
prop: 'text',
text: temp,
format: 'json'
},
function(data) {
if (data && data.parse && data.parse.text) {
var buttons = [{text: i18n('close'), click: function() {$(this).dialog('close');}}],
div = $('<div>').html(data.parse.text['*']);
$('a', div).attr('target', '_blank'); // we don't want people to click on links in preview - they'll lose their work.
$('<div>')
.dialog(
{title: i18n('preview'),
modal: true,
position: [60, 60],
buttons: buttons})
.append(div);
circumventRtlBug();
}
});
}
 
function circumventRtlBug() {
if (rtl)
$('.ui-dialog-buttonpane button').css({float: 'right'}); // jQuery has problems with rtl dialogs + ie is braindamaged.
}
 
function i18n(key, param) {
switch (mw.config.get('wgUserLanguage')) {
case 'ar':
switch (key) {
case 'explain': return rawTemplate
? 'قالب "' + template + '" ليس له صفحة وسائط فرعية، لذلك فما من وصف لمعطياته.'
: 'الوسائط الضرورية محددة بالأحمر والبقية اختيارية.';
case 'wizard dialog title': return 'وسائط ' + '<a href="' + mw.util.getUrl('قالب:' + template) + '" target="_blank">' + 'قالب:' + template + '</a>';
case 'ok': return 'موافقة';
case 'cancel': return 'إلغاء';
case 'params subpage': return 'وسائط';
case 'preview': return 'معاينة';
case 'options select': return 'اختر معطى';
case 'multiline': return 'عدد صفوف';
case 'close': return 'أغلق';
case 'required': return 'ضروري';
case 'depends': return 'يلزمه';
case 'defval': return 'غيابي';
case 'choices': return 'خيارات';
case 'date': return 'تاريخ';
case 'extended': return 'مفصل';
case 'button hint': return 'معالج وسائط القالب';
case 'template selector title': return 'اكتب اسم القالب:';
case 'notInParamPage': return 'وسيط "' + param + '" ليس من وسائط القالب';
case 'editParamPage': return 'عدل صفحة الوسائط';
case 'unknown error': return 'وقع خطأ.\n' + param;
case 'please select template': return 'اسم القالب';
case 'oneliner': return 'اجعله في صف واحد';
case 'createempties': return 'إضافة الوسائط فارغة';
case 'dateFormat': return 'd MM yy';
case 'extended labels': return 'عرض كل الوسائط';
default: return key;
}
break;
case 'he':
switch (key) {
case 'explain': return hebExplain();
case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.getUrl('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>';
case 'ok': return 'אישור';
case 'cancel': return 'ביטול';
case 'preview': return 'תצוגה מקדימה';
case 'options select': return 'בחרו ערך מהרשימה';
case 'multiline': return 'מספר שורות';
case 'close': return 'סגור';
case 'required': return 'שדה חובה';
case 'depends': return 'תלוי';
case 'defval': return 'ברירת מחדל';
case 'choices': return 'אפשרויות';
case 'date': return 'תאריך';
case 'extended': return 'משני';
case 'button hint': return 'אשף מילוי תבניות';
case 'template selector title': return 'אנא הזינו את שם התבנית:';
case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית';
case 'editParamPage': return 'לעריכת דף הפרמטרים';
case 'unknown error': return 'טעות בהפעלת האשף.\n' + param;
case 'please select template': return 'שם התבנית';
case 'oneliner': return 'תבנית בשורה אחת';
case 'createempties': return 'רשום שדות ריקים';
case 'dateFormat': return 'd בMM yy';
case 'extended labels': return 'הראה את כל הפרמטרים';
case 'pve-required-empty': return 'התבנית דורשת שפרמטר זה יקבל ערך';
case 'pve-deprecated': return 'שימוש בפרמטר מיושן';
case 'pve-incompatible': return 'שדה זה מצפה לערך מספרי';
case 'pve-no-such-name': return 'שדה זה לא קיים בתבנית';
case 'explain-pve': return 'שדות עם שגיאה מסומנים ברקע ורוד';
case 'pve-approve-close': return 'יש בתבנית שגיאות. אנא אשרו יציאה מהאשף';
}
break;
case 'ur':
switch (key) {
case 'explain': return 'جو خانے لازمی ہیں ان کے گرد سرخ رنگ کی لکیر کھینچ دی گئی ہے، بقیہ خانے اختیاری ہوں گے۔';
case 'wizard dialog title': return 'سانچہ: "' + template + '" میں مطلوبہ معلومات درج کریں۔';
case 'ok': return 'ٹھیک';
case 'cancel': return 'منسوخ کریں';
case 'params subpage': return 'پیرامیٹر';
case 'preview': return 'نمائش';
case 'options select': return 'کسی ایک کو منتخب کریں:';
case 'multiline': return 'سطروں کی تعداد';
case 'close': return 'بند کریں';
case 'required': return 'لازمی';
case 'depends': return 'اس پر موقوف ہے';
case 'defval': return 'طے شدہ';
case 'choices': return 'اختیارات';
case 'date': return 'تاریخ';
case 'extended': return 'مفصل';
case 'button hint': return 'ساحر محددات سانچہ';
case 'template selector title': return 'براہ کرم سانچہ کا نام درج کریں';
case 'notInParamPage': return 'پیرامیٹر کی فہرست میں "' + param + '" ظاہر نہیں ہو رہا ہے';
case 'editParamPage': return 'پیرامیٹر کے صفحہ میں ترمیم کریں';
case 'unknown error': return 'نقص پیش آیا: \n' + param;
case 'please select template': return 'براہ کرم سانچہ کا نام درج کریں';
case 'oneliner': return 'یک سطری';
case 'createempties': return 'صفحہ میں خالی پیرامیٹر درج کریں';
case 'dateFormat': return 'd MM yy';
case 'extended labels': return 'تمام پیرامیٹر دکھائیں';
}
break;
case 'ru':
switch (key) {
case 'explain': return 'поля с красной рамкой обязательны, остальные - по желанию';
case 'wizard dialog title': return 'Настройте параметры для шаблона: ' + template;
case 'ok': return 'OK';
case 'cancel': return 'Отмена';
case 'params subpage': return 'Параметры';
case 'preview': return 'Просмотр';
case 'options select': return 'Выбрать:';
case 'multiline': return 'Многострочный вид';
case 'close': return 'Закрыть';
case 'required': return 'Необходимое';
case 'depends': return 'Зависит от';
case 'defval': return 'По умолчанию';
case 'choices': return 'Выбор';
case 'date': return 'Дата';
case 'extended': return 'Расширенный';
case 'button hint': return 'Мастер параметров шаблона';
case 'able templates category name': throw('Необходимо определить название категории для шаблонов с поддержкой мастера');
case 'template selector title': return 'Пожалуйста, введите имя шаблона';
case 'notInParamPage': return 'поле "' + param + '" не отображается в списке параметров шаблона';
case 'editParamPage': return 'Править страницу параметров';
case 'unknown error': return 'Произошла ошибка: \n' + param;
case 'please select template': return 'Пожалуйста, введите имя шаблона';
case 'oneliner': return 'Однострочный вид';
case 'dateFormat': return 'ММ дд, гг';
case 'extended labels': return 'Показать все параметры';
}
default:
switch (key) {
case 'explain': return 'fields with red border are required, the rest are optional';
case 'wizard dialog title': return 'Set up parameters for template: ' + template;
case 'ok': return 'OK';
case 'cancel': return 'Cancel';
case 'params subpage': return 'Parameters';
case 'preview': return 'Preview';
case 'options select': return 'Select one:';
case 'multiline': return 'Multiline';
case 'close': return 'Close';
case 'required': return 'Required';
case 'depends': return 'Depends on';
case 'defval': return 'Default';
case 'choices': return 'Choices';
case 'date': return 'Date';
case 'extended': return 'Extended';
case 'button hint': return 'Template parameters wizard';
case 'template selector title': return 'Please enter the template name';
case 'notInParamPage': return 'field "' + param + '" does not appear in the template\'s parameters list';
case 'editParamPage': return 'Edit paramters page';
case 'unknown error': return 'Error occured: \n' + param;
case 'please select template': return 'Please enter template name';
case 'oneliner': return 'Single-line template';
case 'createempties': return 'Write empty parameters to page';
case 'dateFormat': return 'MM d, yy';
case 'extended labels': return 'Show all parameters';
case 'pve-required-empty': return 'The template requires a value for this filedך';
case 'pve-deprecated': return 'deprecated parameter';
case 'pve-incompatible': return 'expaects numteric value';
case 'pve-no-such-name': return 'undercgonzed parameter';
case 'explain-pve': return 'fields with errors are marked with pink background';
case 'pve-approve-close': return 'Template contains errors. Please confim exit';
}
}
return key;
}
 
function hebExplain() {
var explanation;
if (rawTemplate) return 'לתבנית "' + template + '" אין דף פרמטרים, ולכן לשדות אין תיאור.';
if (anyRequiredParam()) return 'שדות חובה מסומנים במסגרת אדומה';
return '';
}
function anyRequiredParam() {
for (name in templateParams) {
var param = templateParams[name];
if (param.options.required) return true;
}
return false;
}
function templatePage() {
var t = $.trim(template)
return t.match(':') ? t : mw.config.get('wgFormattedNamespaces')[10] + ':' + t;
}
 
function updateRawPreview(){
var canOK = 'enable';
for (var i in dialogFields) {
var df = dialogFields[i][1];
var opts = df.data('options');
if (opts && opts.required && $.trim(df.val()).length == 0)
canOK = 'disable';
if (opts && opts.depends) {
var dep = fieldsBypName[opts.depends];
var depEmpty = (dep && dep.val() && $.trim(dep.val())) ? false : true;
var row = rowsBypName[df.data('paramName')];
if (row)
row.toggleClass('tpw_hidden', depEmpty);
}
}
$(".ui-dialog-buttonpane button:contains('" + i18n('ok') + "')").button(canOK);
$('#tpw_preview').text(createWikiCode());
localStorage.setItem(localStorageKey + '.' + emptiesKey, $('#createEmpties').prop('checked'));
validate();
}
function validate() {
function validateField(param, input) {
function markError(msg) {
input
.addClass('tpw-paramvalidation')
.attr('title', i18n(msg));
return false;
}
var hasVal = !! input.val();
if (param.options.notInParamPage && hasVal) return markError('pve-no-such-name');
if (param.param.required && ! hasVal) return markError('pve-required-empty');
if (param.param.deprecated && hasVal) return markError('pve-deprecated');
if (param.param.type === 'number' && isNaN( Number( input.val().replace(/,/g, '') ) ) ) return markError('pve-incompatible');
return true;
}
var aOK = true;
for (var i in dialogFields) {
var
field = dialogFields[i],
name = $.trim(field[0]),
input = field[1].removeClass('tpw-paramvalidation'),
param = templateParams[name];
aOK = validateField(param, input) && aOK;
}
$('#tpw-explain').html(i18n(aOK ? 'explain' : 'explain-pve') );
return aOK;
}
 
function createInputField(paramName) {
var params = templateParams[paramName],
options = params.options || {},
f,
checkbox = false;
 
if (options.choices) {
var choices = options.choices.split(/\s*,\s*/);
if (choices.length > 1) {
f = $('<select>').append($('<option>', {text: i18n('options select'), value: '' }));
for (var i in choices) {
var choice = choices[i].trim(); // first and last may carry spaces
var option = $('<option>', {text: choice, value: choice});
f.append(option);
}
}
else {
checkbox = true;
var choice = choices[0].trim();
f = $('<input>', {type: 'checkbox', value: choices[0], text: choices[0].trim()})
.css({float: rtl ? 'right' : 'left'});
f.prop('checked', options.defval && options.defval.trim() == choices[0]);
}
}
else if (options.multiline) {
var rows = options.multiline;
f = $('<textarea>', {rows: 1})
.focus(function(){this.rows = 5;})
.blur(function(){this.rows = 1});
}
else
f = $('<input>', {type: 'text'});
 
if (!checkbox && f.autoCompleteWikiText) // teach the controls to autocomplete.
f.autoCompleteWikiText({positionMy: rtl ? "left top" : "right top"});
 
f.css({width: checkbox ? '1em' : '28em'})
.data({paramName: paramName, options: options})
.on('paste cut drop input change', updateRawPreview);
 
if (options.defval && ! checkbox)
f.val(options.defval.trim());
 
if (options.required)
f.addClass('tpw-required');
 
if (options.date)
f.datepicker({dateFormat: typeof options.date  == "string" ? options.date : i18n('dateFormat')});
return f;
}
 
var
timer = null,
lastVisited = $('<a>');
 
function enterTipsy() {
clearTimeout(timer);
$(this).attr('inside', 1);
}
 
function leaveTipsy() {
var $this = $(this);
if ($this.attr('master') || $this.attr('inside')) {
$this.attr('inside', '');
timer = setTimeout(function(){lastVisited.tipsy('hide');}, 500);
}
}
 
function tipsyContent() {
var
paramName = $(this).data('paramname'),
def = templateParams[paramName],
desc = def && def.desc || '';
if (!def) return ''; // early terminate if param name is not valid
if (def.htmlDesc)
return def.htmlDesc;
if (wikiCodeFinder.test(desc)) // does it need parsing?
$.ajax({
url: mw.util.wikiScript('api'),
async: false,
type: 'post',
data: {action: 'parse', text: desc, disablepp: 1, format: 'json'}, // parse it.
success: function(data) {
var div = $('<div>').html(data.parse.text['*']);
$('a', div).attr({target: '_blank'});
def.htmlDesc = div.html();
}
});
else
def.htmlDesc = desc;
return def.htmlDesc;
}
 
function addRow(paramName, table) {
var
def = templateParams[paramName],
inputField = createInputField(paramName),
nameColor = def.desc
? 'blue'
: def.options.notInParamPage
? 'red'
: def.options.isAlias
? 'green'
: 'black',
tr = $('<tr>')
.append(
$('<td>', {width: 120})
.css({fontWeight: 'bold', color: nameColor})
.data({ paramname: paramName })
.text(templateParams[paramName].label || paramName)
.tipsy({html: true, trigger: 'manual', title: tipsyContent})
.mouseenter(function() {
clearTimeout(timer);
$('.tipsy').remove();
lastVisited = $(this);
lastVisited.tipsy('show');
})
.mouseleave(leaveTipsy)
.attr('master', 'true')
)
.append($('<td>').css({width: '30em'}).append(inputField));
dialogFields.push([paramName, inputField]);
if (def.options.extended)
tr.addClass('tpw_extended');
table.append(tr);
rowsBypName[paramName] = tr;
fieldsBypName[paramName] = inputField;
}
 
function injectResults() {
$("#wpTextbox1").textSelection('encapsulateSelection', {replace: true, peri: createWikiCode()});
}
 
function createExtendedCheckBox() {
return $('<p>')
.text(i18n('extended labels'))
.append($('<input>', {type: 'checkbox'})
.change(function() {
extendedParamCssRule.disabled = $(this).prop('checked');
})
);
}
 
function buildDialog(data) {
var title = $('<span>').html(i18n('wizard dialog title', template));
$('.tpw_disposable').remove();
if (rawTemplate)
buildParamsRaw(data);
else if (tdTemplate) {
buildParamsTd(data);
if (data.description) title.find('a').attr({ title: data.description });
}
paramsFromSelection();
var table = $('<table>');
var dialog = $('<div>', {'class': 'tpw_disposable'})
.dialog({height: 'auto',
title: title.html(),
width: 'auto',
overflow: 'auto',
position: [$('body').width() * 0.2, $('body').height() * 0.1],
open: function() {$(this).css({'max-height': Math.round($('body').height() * 0.7)});}
})
.append($('<div>', {id: 'tpw_globalExplanation'}).html(globalExplanation))
.append($('<p>', { id: 'tpw-explain' } ).html(i18n('explain')) )
.append(anyExtended ? createExtendedCheckBox() : '')
.append(table)
.append($('<p>')
.append(i18n('oneliner'))
.append($('<input>', {type: 'checkbox', id: oneLineTemplate}).prop('checked', isInline).change(updateRawPreview)
)
)
.append($('<p>')
.append(i18n('createempties'))
.append($('<input>', {type:'checkbox', id:'createEmpties'})
.change(updateRawPreview)
.prop('checked', localStorage.getItem(localStorageKey + '.' + emptiesKey) == "true")
)
)
.append($('<pre>', {id: 'tpw_preview'}).addClass('tpw-wikicode-preview'));
while (paramsOrder.length)
addRow(paramsOrder.shift(), table);
 
var buttons = {}; // we need to do it this way, because with literal object, the keys must be literal.
buttons[i18n('ok')] = function() {
if (! validate() && ! confirm(i18n('pve-approve-close' ) ) ) return;
injectResults();
dialog.dialog('close');
};
buttons[i18n('cancel')] = function() {dialog.dialog('close');};
buttons[i18n('preview')] = showPreview;
dialog.dialog('option', 'buttons', buttons);
circumventRtlBug();
updateRawPreview();
$('.tipsy').hover(enterTipsy, leaveTipsy);
}
 
function init() {
template = null;
templateParams = {};
paramsOrder = [];
dialogFields = [];
rowsBypName = {};
fieldsBypName = {};
mw.util.addCSS(".tpw_hidden{display:none;}");
anyExtended = false;
extendedParamCssRule = extendedParamCssRule || mw.util.addCSS(".tpw_extended{display:none;}");
}
 
function reportError(a,b,error) {
var key;
if (typeof console != 'undefined') {
for (key in a)
if (typeof a[key] != 'function')
console.log(key + '=>' + a[key]);
console.log(b);
console.log(error);
}
alert(i18n('unknown error', error));
}
 
function pickTemplate(item) {
function okButtonPressed(e, ui) {
template = ui ? ui.item.value : selector.val();
fireDialog();
templateSelector.dialog("close");
}
var selector = $('<input>')
.css({width: '28em'})
.autocomplete({
source: function(request, response) {
$.getJSON(
mw.util.wikiScript('api'),
{action:'opensearch', search: request.term, namespace: 10},
function(data){
if(data[1])
response($(data[1]).map(function(index,item){return item.replace(/.*:/, '');}));
}
);
},
select: okButtonPressed
});
var templateSelector = $('<div>').dialog({
title: i18n('template selector title'),
height: 'auto',
width: 'auto',
modal: true,
buttons: [
{text: i18n('ok'), click: okButtonPressed},
{text: i18n('cancel'), click: function(){templateSelector.dialog("close")}}
]
}).append(selector);
circumventRtlBug();
selector.focus();
}
 
function fireDialog() {
var readRaw = function() {
rawTemplate = true;
$.ajax({
url: mw.util.wikiScript(),
data: {title: templatePage(), action: 'raw'},
dataType: 'text',
success: buildDialog,
error: reportError
});
},
readTemplateData = function() {
$.ajax({
url: mw.util.wikiScript('api'),
data: {action: 'templatedata', titles: templatePage(), redirects: true, format: 'json', lang: mw.config.get('wgUserLanguage') },
dataType: 'json',
success: function(data) {
var found = false;
if (data && data.pages)
for (var pageid in data.pages) {
tdTemplate = true;
found = true;
buildDialog(data.pages[pageid]);
break;
}
if (! found)
readRaw();
},
error: readRaw
});
};
rawTemplate = false;
readTemplateData();
}
 
function templateContext() {
var selection = $("#wpTextbox1").textSelection('getSelection'),
caretPos, beforeText, afterText, templateStart, templateEnd;
 
// trust the user
if ( selection.length > 0 ) {
return selection;
}
 
caretPos =  $("#wpTextbox1").textSelection('getCaretPosition');
beforeText = $("#wpTextbox1").val().substr(0, caretPos);
afterText = $("#wpTextbox1").val().substr(caretPos);
templateStart = beforeText.lastIndexOf('{{');
templateEnd = afterText.indexOf('}}') + 2;
 
// only under opportunistic template context assumptions
if ( $("#wpTextbox1").val().split('{').length != $("#wpTextbox1").val().split('}').length ||
  (beforeText.split('{{').length === beforeText.split('}}').length) ||
  (afterText.split('{{').length === afterText.split('}}').length) )
return '';
 
// determine the start and the end of the template context
while (beforeText.substr(templateStart).split('{{').length <= beforeText.substr(templateStart).split('}}').length)
templateStart = beforeText.lastIndexOf('{{', templateStart - 1)
 
while (afterText.substr(0, templateEnd).split('{{').length >= afterText.substr(0, templateEnd).split('}}').length)
templateEnd = afterText.indexOf('}}', templateEnd) + 2;
 
// extend the selection to the current template context
$("#wpTextbox1").focus().textSelection('setSelection', {
start: templateStart,
end: caretPos + templateEnd
});
return $("#wpTextbox1").textSelection('getSelection');
}
 
function doIt() {
mw.loader.using(['jquery.ui','jquery.tipsy','jquery.textSelection', 'mediawiki.api'], function() {
init();
var match = templateContext().match(/^\{\{([^|}]*)/);
template = match ? $.trim(match[1]) : null;
if (template)
fireDialog();
else
pickTemplate();
});
}
function addToWikiEditor(){
$('#wpTextbox1').wikiEditor('addToToolbar', {
section: 'main',
group: 'insert',
tools: {
'templateParamsWizard': {
label: i18n('button hint'),
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Template_alt_full_black_22.svg/22px-Template_alt_full_black_22.svg.png',
action: {type: 'callback', execute: doIt}
}
}
});
}
if (mw.user.options.get('usebetatoolbar'))
mw.loader.using(['ext.wikiEditor'], function() {
if(typeof $.wikiEditor != 'undefined') {
if ($('#wikiEditor-ui-toolbar').length === 1) addToWikiEditor();//in case it loaded after toolbar initaliztion
else $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', addToWikiEditor);
}
});
else
$('div #toolbar').append( // "old style"
$('<img>', {src: '//upload.wikimedia.org/wikipedia/commons/e/eb/Button_plantilla.png', title: i18n('button hint'), 'class': 'mw-toolbar-editbutton'})
.css({cursor: 'pointer'})
.click(doIt)
);
} );

רעוויזיע פון 17:11, 19 פעברואר 2023

//Template parameters wizard //Written by User:קיפודנחש "use strict"; if(($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1) && ( !$('#wpTextbox1').prop( 'readonly' ) ) ) $(function($) { // template parameter is an object with the following fields: // desc: desciption string // defval: default value (optional) // options: object with optional fields: //// multiline: number of lines //// depends: another field's name //// required: boolean //// date: use JS date widget //// choices: array of legal values for the field //// extended: this field will not show on initial screen, and will appear once the user selects "show all fields"

var // templateParams is keyed by paramName. templateParams, paramsOrder, // which template are we working on template, // array of pairs - [paramName, inputField] dialogFields, // table rows keyed by paramName rowsBypName, // the fields, keyed by paramName fieldsBypName, // boolean, indicating the source of data is templatedata. tdTemplate, // boolean, indicating the source of the data is analyzing the template page itself. rawTemplate, isInline, rtl = $('body').is('.rtl'), // test to see if a string contains wikiCode and hence needs parsing, or cen be used as is. wikiCodeFinder = /[\[\]\{\}<>]/, globalExplanation = , extendedParamCssRule, anyExtended = false, localStorageKey = 'templateParamWizard', emptiesKey = 'writeEmpties', oneLineTemplate = 'oneLineTemplate', allAliases = [];

function addParam(name) { if ($.inArray(name, paramsOrder) == -1) paramsOrder.push(name); }

function paramsFromSelection() { var selection = $("#wpTextbox1").textSelection('getSelection').replace(/^\s*\{\{|\}\}\s*$/g, ); //scrap the first מוסטער:And last var specials = [], match; while (true) { //extract inner links, inner templates and inner params - we don't want to split those. match = selection.match(/(\{\{[^\{\}\]\[]*\}\}|\[\[[^\{\}\]\[]*\]\]|\[[^\{\}\]\[]*\])/); if (! match || ! match.length) break; specials.push(match[0]); selection = selection.replace(match[0], "\0" + specials.length + "\0"); } var params = selection.split(/ *\| */); params.shift(); // remove the template name var ordered = 0; for (var i in params) { var param = params[i]; if ( ! /=/.test(param) ) { param = ++ordered + '=' + param; } var paramPair = param.split("="); var name = $.trim(paramPair.shift()); if ( ! isNaN( name ) ) { ordered = parseInt( name ); // this still won't work as advertise when template contains explicit parameter 2 before implicit 1: Pictogram voting delete.svg } var val = paramPair.join('='); while (true) { match = val.match(/\0(\d+)\0/); if (! match || ! match.length) break; val = val.replace(match[0], specials[parseInt(match[1], 10)-1]); } if (name && paramPair.length) { var tp = templateParams[name] = templateParams[name] || ~allAliases.indexOf(name) && { param:{}, options: {isAlias: 1} } || {param: {}, options: { notInParamPage: 1}}; addParam(name); $.extend( tp.options, { defval: val } ); if ( /\n/.test( val ) ) $.extend( tp.options, { multiline : 5 } ); // next line is for the case where there are "choices"' but current value is not one of them: add it as a new choice. if ( typeof tp.options.choices === 'string' && tp.options.choices.indexOf( val ) < 0 ) tp.options.choices += ( ', ' + val ); } } }

function buildParamsRaw(data) { var paramExtractor = /{{3,}(.*?)[<|}]/mg, m; while (m = paramExtractor.exec(data)) { var paramName = $.trim(m[1]); templateParams[paramName] = { desc: , options: {multiline: 5}, label: paramName, param:{} }; addParam(paramName); } }

function buildParamsTd(data) { var params = data.params, paramOrder = data.paramOrder;

function optionsOfParam(param) { var options = {}; if (param.required) options.required = true; if (param.suggestedvalues && param.suggestedvalues.length) options.choices = param.suggestedvalues.join(','); return options; }

function onemore(name) { var param = params[name]; if (param.deprecated) return; // ignore deprecated parameters - pretend they are not in TD. templateParams[name] = { desc: param.description || , options: optionsOfParam(param), label: param.label || name, param: param }; if (param.aliases) $.merge(allAliases, param.aliases); // collect alliases if there are any addParam(name); }

isInline = data.format === 'inline';

if (paramOrder && paramOrder.length) for (var ind in paramOrder) onemore(paramOrder[ind]); else // no order - take them as they come. for (var paramname in params) onemore(paramname);

// derive placeholders for feilds derived from wikidata if (data.maps && data.maps.hasOwnProperty('wikidata') && mw.config.get('wgWikibaseItemId')) {

var wikidataFormattedValues = $('

');

for (var k in data.maps['wikidata']) { wikidataFormattedValues.append($('', {id: k, text:'{{#property:' + k + '}}'})) } $.post( mw.util.wikiScript('api'), {action: 'parse', text: wikidataFormattedValues.html(), disablelimitreport: 1, format: 'json', prop: 'text', title: mw.config.get('wgPageName')}, function(wbd) { if (!wbd || !wbd.parse || !wbd.parse.text) return; for (var k in data.maps['wikidata']) { var wikidataVal = $('#' + k, wbd.parse.text['*']).text(), field = fieldsBypName[data.maps['wikidata'][k]]; if (field) field.prop('placeholder', wikidataVal); } } ); } }

function buildParams(data) { var lines = data.split("\n"), line;

function extractGlobalExplanation() { line = line.replace(/[!\|][^\|]*\|/, ); if (wikiCodeFinder.test(line)) $.post( mw.util.wikiScript('api'), {action: 'parse', text: line, disablepp: 1, format: 'json'}, function(data) { var html = data.parse.text['*']; globalExplanation = html; $('#tpw_globalExplanation').html(html).find('a').attr({target: '_blank'}); } ); else globalExplanation = line; }

while (lines && lines.length) { line = lines.shift(); if (!(/^\|-/.test(line))) // look for |- this is wikitext for table row. continue; line = lines.shift(); if (line.indexOf('globalExplanation') + 1) { extractGlobalExplanation(); continue; } if (! line || ! (/^\|/.test(line))) //wikitext for column continue; line = line.substr(1); // get rid of the leading | var fields = line.split('||'); if (fields.length < 2) continue; var name = $.trim(fields[0]); if (! name) continue; var desc = $.trim(fields[1]); var pAttribs = {desc: desc}; if (fields.length > 2) pAttribs.options = analyzeOptions($.trim(fields[2]));

templateParams[name] = pAttribs; addParam(name);

} }

function analyzeOptions(str) { var res = {}, avail = ['multiline', 'required', 'depends', 'defval', 'choices', 'date', 'extended'], // maybe we'll have more in the future tavail = $.map(avail, i18n), options = str.split(/\s*;\s*/); for (var i in options) { var option = options[i].split(/\s*=\s*/); var ind = $.inArray(option[0], tavail); if (ind + 1) res[avail[ind]] = option.length > 1 ? option[1] : true; } anyExtended = anyExtended || res.extended; return res; }

function createWikiCode() { var par = [template], delim = $('#' + oneLineTemplate).prop('checked') ?  : '\n', paramValueDelim = $('#' + oneLineTemplate).prop('checked') ? '=' : ' = ', createEmpties = $('#createEmpties').prop('checked'), mustNumberNameless, valuedOrdered;

for (var i = dialogFields.length - 1; i >= 0; i--) { var field = dialogFields[i], val = $.trim(field[1].val());

if (isNaN(field[0])) continue; // look only at order-based fields

mustNumberNameless |= /=/.test(val) // order-based value containing "=" || valuedOrdered && !val; // empty ordered w lower index than a non-empty one. if (val) valuedOrdered = true; }

for (var i in dialogFields) { var field = dialogFields[i], name = $.trim(field[0]), f = field[1], opts = f.data('options'), param = templateParams[name], hidden = f.parents('.tpw_hidden').length, val = f.val().replace( /\s+$/, ); // leave leading newlines, for lists etc., but remove trailing. if (param && param.param && param.param.type === 'url') val = val.replace(/\|/g, '|'); if (f.attr('type') == 'checkbox' && ! f.prop('checked')) val = ""; if ( ( !createEmpties || opts.notInParamPage ) && $.trim( val ) === "" ) continue;//skip parameters with no value

var next = mustNumberNameless || isNaN(name) ? name + paramValueDelim + $.trim( val ) : $.trim( val ); par.push(next); } return "מוסטער:" + par.join(delim + ($('"; }

function showPreview() { var temp = createWikiCode(); $.post(mw.util.wikiScript('api'), {action: 'parse', title: mw.config.get('wgPageName'), prop: 'text', text: temp, format: 'json' }, function(data) { if (data && data.parse && data.parse.text) { var buttons = [{text: i18n('close'), click: function() {$(this).dialog('close');}}],

div = $('
').html(data.parse.text['*']);

$('a', div).attr('target', '_blank'); // we don't want people to click on links in preview - they'll lose their work.

$('
')

.dialog( {title: i18n('preview'), modal: true, position: [60, 60], buttons: buttons}) .append(div); circumventRtlBug(); } }); }

function circumventRtlBug() { if (rtl) $('.ui-dialog-buttonpane button').css({float: 'right'}); // jQuery has problems with rtl dialogs + ie is braindamaged. }

function i18n(key, param) { switch (mw.config.get('wgUserLanguage')) { case 'ar': switch (key) { case 'explain': return rawTemplate ? 'قالب "' + template + '" ليس له صفحة وسائط فرعية، لذلك فما من وصف لمعطياته.' : 'الوسائط الضرورية محددة بالأحمر والبقية اختيارية.'; case 'wizard dialog title': return 'وسائط ' + '<a href="' + mw.util.getUrl('قالب:' + template) + '" target="_blank">' + 'قالب:' + template + '</a>'; case 'ok': return 'موافقة'; case 'cancel': return 'إلغاء'; case 'params subpage': return 'وسائط'; case 'preview': return 'معاينة'; case 'options select': return 'اختر معطى'; case 'multiline': return 'عدد صفوف'; case 'close': return 'أغلق'; case 'required': return 'ضروري'; case 'depends': return 'يلزمه'; case 'defval': return 'غيابي'; case 'choices': return 'خيارات'; case 'date': return 'تاريخ'; case 'extended': return 'مفصل'; case 'button hint': return 'معالج وسائط القالب'; case 'template selector title': return 'اكتب اسم القالب:'; case 'notInParamPage': return 'وسيط "' + param + '" ليس من وسائط القالب'; case 'editParamPage': return 'عدل صفحة الوسائط'; case 'unknown error': return 'وقع خطأ.\n' + param; case 'please select template': return 'اسم القالب'; case 'oneliner': return 'اجعله في صف واحد'; case 'createempties': return 'إضافة الوسائط فارغة'; case 'dateFormat': return 'd MM yy'; case 'extended labels': return 'عرض كل الوسائط'; default: return key; } break; case 'he': switch (key) { case 'explain': return hebExplain(); case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.getUrl('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>'; case 'ok': return 'אישור'; case 'cancel': return 'ביטול'; case 'preview': return 'תצוגה מקדימה'; case 'options select': return 'בחרו ערך מהרשימה'; case 'multiline': return 'מספר שורות'; case 'close': return 'סגור'; case 'required': return 'שדה חובה'; case 'depends': return 'תלוי'; case 'defval': return 'ברירת מחדל'; case 'choices': return 'אפשרויות'; case 'date': return 'תאריך'; case 'extended': return 'משני'; case 'button hint': return 'אשף מילוי תבניות'; case 'template selector title': return 'אנא הזינו את שם התבנית:'; case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית'; case 'editParamPage': return 'לעריכת דף הפרמטרים'; case 'unknown error': return 'טעות בהפעלת האשף.\n' + param; case 'please select template': return 'שם התבנית'; case 'oneliner': return 'תבנית בשורה אחת'; case 'createempties': return 'רשום שדות ריקים'; case 'dateFormat': return 'd בMM yy'; case 'extended labels': return 'הראה את כל הפרמטרים'; case 'pve-required-empty': return 'התבנית דורשת שפרמטר זה יקבל ערך'; case 'pve-deprecated': return 'שימוש בפרמטר מיושן'; case 'pve-incompatible': return 'שדה זה מצפה לערך מספרי'; case 'pve-no-such-name': return 'שדה זה לא קיים בתבנית'; case 'explain-pve': return 'שדות עם שגיאה מסומנים ברקע ורוד'; case 'pve-approve-close': return 'יש בתבנית שגיאות. אנא אשרו יציאה מהאשף'; } break; case 'ur': switch (key) { case 'explain': return 'جو خانے لازمی ہیں ان کے گرد سرخ رنگ کی لکیر کھینچ دی گئی ہے، بقیہ خانے اختیاری ہوں گے۔'; case 'wizard dialog title': return 'سانچہ: "' + template + '" میں مطلوبہ معلومات درج کریں۔'; case 'ok': return 'ٹھیک'; case 'cancel': return 'منسوخ کریں'; case 'params subpage': return 'پیرامیٹر'; case 'preview': return 'نمائش'; case 'options select': return 'کسی ایک کو منتخب کریں:'; case 'multiline': return 'سطروں کی تعداد'; case 'close': return 'بند کریں'; case 'required': return 'لازمی'; case 'depends': return 'اس پر موقوف ہے'; case 'defval': return 'طے شدہ'; case 'choices': return 'اختیارات'; case 'date': return 'تاریخ'; case 'extended': return 'مفصل'; case 'button hint': return 'ساحر محددات سانچہ'; case 'template selector title': return 'براہ کرم سانچہ کا نام درج کریں'; case 'notInParamPage': return 'پیرامیٹر کی فہرست میں "' + param + '" ظاہر نہیں ہو رہا ہے'; case 'editParamPage': return 'پیرامیٹر کے صفحہ میں ترمیم کریں'; case 'unknown error': return 'نقص پیش آیا: \n' + param; case 'please select template': return 'براہ کرم سانچہ کا نام درج کریں'; case 'oneliner': return 'یک سطری'; case 'createempties': return 'صفحہ میں خالی پیرامیٹر درج کریں'; case 'dateFormat': return 'd MM yy'; case 'extended labels': return 'تمام پیرامیٹر دکھائیں'; } break; case 'ru': switch (key) { case 'explain': return 'поля с красной рамкой обязательны, остальные - по желанию'; case 'wizard dialog title': return 'Настройте параметры для шаблона: ' + template; case 'ok': return 'OK'; case 'cancel': return 'Отмена'; case 'params subpage': return 'Параметры'; case 'preview': return 'Просмотр'; case 'options select': return 'Выбрать:'; case 'multiline': return 'Многострочный вид'; case 'close': return 'Закрыть'; case 'required': return 'Необходимое'; case 'depends': return 'Зависит от'; case 'defval': return 'По умолчанию'; case 'choices': return 'Выбор'; case 'date': return 'Дата'; case 'extended': return 'Расширенный'; case 'button hint': return 'Мастер параметров шаблона'; case 'able templates category name': throw('Необходимо определить название категории для шаблонов с поддержкой мастера'); case 'template selector title': return 'Пожалуйста, введите имя шаблона'; case 'notInParamPage': return 'поле "' + param + '" не отображается в списке параметров шаблона'; case 'editParamPage': return 'Править страницу параметров'; case 'unknown error': return 'Произошла ошибка: \n' + param; case 'please select template': return 'Пожалуйста, введите имя шаблона'; case 'oneliner': return 'Однострочный вид'; case 'dateFormat': return 'ММ дд, гг'; case 'extended labels': return 'Показать все параметры'; } default: switch (key) { case 'explain': return 'fields with red border are required, the rest are optional'; case 'wizard dialog title': return 'Set up parameters for template: ' + template; case 'ok': return 'OK'; case 'cancel': return 'Cancel'; case 'params subpage': return 'Parameters'; case 'preview': return 'Preview'; case 'options select': return 'Select one:'; case 'multiline': return 'Multiline'; case 'close': return 'Close'; case 'required': return 'Required'; case 'depends': return 'Depends on'; case 'defval': return 'Default'; case 'choices': return 'Choices'; case 'date': return 'Date'; case 'extended': return 'Extended'; case 'button hint': return 'Template parameters wizard'; case 'template selector title': return 'Please enter the template name'; case 'notInParamPage': return 'field "' + param + '" does not appear in the template\'s parameters list'; case 'editParamPage': return 'Edit paramters page'; case 'unknown error': return 'Error occured: \n' + param; case 'please select template': return 'Please enter template name'; case 'oneliner': return 'Single-line template'; case 'createempties': return 'Write empty parameters to page'; case 'dateFormat': return 'MM d, yy'; case 'extended labels': return 'Show all parameters'; case 'pve-required-empty': return 'The template requires a value for this filedך'; case 'pve-deprecated': return 'deprecated parameter'; case 'pve-incompatible': return 'expaects numteric value'; case 'pve-no-such-name': return 'undercgonzed parameter'; case 'explain-pve': return 'fields with errors are marked with pink background'; case 'pve-approve-close': return 'Template contains errors. Please confim exit'; } } return key; }

function hebExplain() { var explanation; if (rawTemplate) return 'לתבנית "' + template + '" אין דף פרמטרים, ולכן לשדות אין תיאור.'; if (anyRequiredParam()) return 'שדות חובה מסומנים במסגרת אדומה'; return ; }

function anyRequiredParam() { for (name in templateParams) { var param = templateParams[name]; if (param.options.required) return true; } return false; }

function templatePage() { var t = $.trim(template) return t.match(':') ? t : mw.config.get('wgFormattedNamespaces')[10] + ':' + t; }

function updateRawPreview(){ var canOK = 'enable'; for (var i in dialogFields) { var df = dialogFields[i][1]; var opts = df.data('options'); if (opts && opts.required && $.trim(df.val()).length == 0) canOK = 'disable'; if (opts && opts.depends) { var dep = fieldsBypName[opts.depends]; var depEmpty = (dep && dep.val() && $.trim(dep.val())) ? false : true; var row = rowsBypName[df.data('paramName')]; if (row) row.toggleClass('tpw_hidden', depEmpty); } } $(".ui-dialog-buttonpane button:contains('" + i18n('ok') + "')").button(canOK); $('#tpw_preview').text(createWikiCode()); localStorage.setItem(localStorageKey + '.' + emptiesKey, $('#createEmpties').prop('checked')); validate(); }

function validate() {

function validateField(param, input) { function markError(msg) { input .addClass('tpw-paramvalidation') .attr('title', i18n(msg)); return false; }

var hasVal = !! input.val(); if (param.options.notInParamPage && hasVal) return markError('pve-no-such-name'); if (param.param.required && ! hasVal) return markError('pve-required-empty'); if (param.param.deprecated && hasVal) return markError('pve-deprecated'); if (param.param.type === 'number' && isNaN( Number( input.val().replace(/,/g, ) ) ) ) return markError('pve-incompatible'); return true; }

var aOK = true; for (var i in dialogFields) { var field = dialogFields[i], name = $.trim(field[0]), input = field[1].removeClass('tpw-paramvalidation'), param = templateParams[name];

aOK = validateField(param, input) && aOK; }

$('#tpw-explain').html(i18n(aOK ? 'explain' : 'explain-pve') );

return aOK; }

function createInputField(paramName) { var params = templateParams[paramName], options = params.options || {}, f, checkbox = false;

if (options.choices) { var choices = options.choices.split(/\s*,\s*/); if (choices.length > 1) { f = $('<select>').append($('<option>', {text: i18n('options select'), value: })); for (var i in choices) { var choice = choices[i].trim(); // first and last may carry spaces var option = $('<option>', {text: choice, value: choice}); f.append(option); } } else { checkbox = true; var choice = choices[0].trim(); f = $('<input>', {type: 'checkbox', value: choices[0], text: choices[0].trim()}) .css({float: rtl ? 'right' : 'left'}); f.prop('checked', options.defval && options.defval.trim() == choices[0]); } } else if (options.multiline) { var rows = options.multiline; f = $('<textarea>', {rows: 1}) .focus(function(){this.rows = 5;}) .blur(function(){this.rows = 1}); } else f = $('<input>', {type: 'text'});

if (!checkbox && f.autoCompleteWikiText) // teach the controls to autocomplete. f.autoCompleteWikiText({positionMy: rtl ? "left top" : "right top"});

f.css({width: checkbox ? '1em' : '28em'}) .data({paramName: paramName, options: options}) .on('paste cut drop input change', updateRawPreview);

if (options.defval && ! checkbox) f.val(options.defval.trim());

if (options.required) f.addClass('tpw-required');

if (options.date) f.datepicker({dateFormat: typeof options.date == "string" ? options.date : i18n('dateFormat')});

return f; }

var timer = null, lastVisited = $('<a>');

function enterTipsy() { clearTimeout(timer); $(this).attr('inside', 1); }

function leaveTipsy() { var $this = $(this); if ($this.attr('master') || $this.attr('inside')) { $this.attr('inside', ); timer = setTimeout(function(){lastVisited.tipsy('hide');}, 500); } }

function tipsyContent() { var paramName = $(this).data('paramname'), def = templateParams[paramName], desc = def && def.desc || ; if (!def) return ; // early terminate if param name is not valid if (def.htmlDesc) return def.htmlDesc; if (wikiCodeFinder.test(desc)) // does it need parsing? $.ajax({ url: mw.util.wikiScript('api'), async: false, type: 'post', data: {action: 'parse', text: desc, disablepp: 1, format: 'json'}, // parse it. success: function(data) {

var div = $('
').html(data.parse.text['*']);

$('a', div).attr({target: '_blank'}); def.htmlDesc = div.html(); } }); else def.htmlDesc = desc; return def.htmlDesc; }

function addRow(paramName, table) { var def = templateParams[paramName], inputField = createInputField(paramName), nameColor = def.desc ? 'blue' : def.options.notInParamPage ? 'red' : def.options.isAlias ? 'green' : 'black',

tr = $('') .append( $('', {width: 120})

.css({fontWeight: 'bold', color: nameColor}) .data({ paramname: paramName }) .text(templateParams[paramName].label || paramName) .tipsy({html: true, trigger: 'manual', title: tipsyContent}) .mouseenter(function() { clearTimeout(timer); $('.tipsy').remove(); lastVisited = $(this); lastVisited.tipsy('show'); }) .mouseleave(leaveTipsy) .attr('master', 'true') )

.append($('').css({width: '30em'}).append(inputField));

dialogFields.push([paramName, inputField]); if (def.options.extended) tr.addClass('tpw_extended'); table.append(tr); rowsBypName[paramName] = tr; fieldsBypName[paramName] = inputField; }

function injectResults() { $("#wpTextbox1").textSelection('encapsulateSelection', {replace: true, peri: createWikiCode()}); }

function createExtendedCheckBox() {

return $('

') .text(i18n('extended labels')) .append($('<input>', {type: 'checkbox'}) .change(function() { extendedParamCssRule.disabled = $(this).prop('checked'); }) ); } function buildDialog(data) { var title = $('').html(i18n('wizard dialog title', template)); $('.tpw_disposable').remove(); if (rawTemplate) buildParamsRaw(data); else if (tdTemplate) { buildParamsTd(data); if (data.description) title.find('a').attr({ title: data.description }); } paramsFromSelection(); var table = $('

'); var dialog = $('
', {'class': 'tpw_disposable'})

.dialog({height: 'auto', title: title.html(), width: 'auto', overflow: 'auto', position: [$('body').width() * 0.2, $('body').height() * 0.1], open: function() {$(this).css({'max-height': Math.round($('body').height() * 0.7)});} })

.append($('
', {id: 'tpw_globalExplanation'}).html(globalExplanation)) .append($('

', { id: 'tpw-explain' } ).html(i18n('explain')) ) .append(anyExtended ? createExtendedCheckBox() : ) .append(table) .append($('

') .append(i18n('oneliner')) .append($('<input>', {type: 'checkbox', id: oneLineTemplate}).prop('checked', isInline).change(updateRawPreview) ) ) .append($('

') .append(i18n('createempties')) .append($('<input>', {type:'checkbox', id:'createEmpties'}) .change(updateRawPreview) .prop('checked', localStorage.getItem(localStorageKey + '.' + emptiesKey) == "true") ) ) .append($('

', {id: 'tpw_preview'}).addClass('tpw-wikicode-preview'));
				
		while (paramsOrder.length)
			addRow(paramsOrder.shift(), table);

		var buttons = {}; // we need to do it this way, because with literal object, the keys must be literal.
		buttons[i18n('ok')] = function() {
			if (! validate() && ! confirm(i18n('pve-approve-close' ) ) ) return;
			injectResults(); 
			dialog.dialog('close'); 
		};
		buttons[i18n('cancel')] = function() {dialog.dialog('close');};
		buttons[i18n('preview')] = showPreview;
		dialog.dialog('option', 'buttons', buttons);
		circumventRtlBug();
		updateRawPreview();
		$('.tipsy').hover(enterTipsy, leaveTipsy);
	}

	function init() {
		template = null;
		templateParams = {};
		paramsOrder = [];
		dialogFields = [];
		rowsBypName = {};
		fieldsBypName = {};
		mw.util.addCSS(".tpw_hidden{display:none;}");
		anyExtended = false;
		extendedParamCssRule = extendedParamCssRule || mw.util.addCSS(".tpw_extended{display:none;}");
	}

	function reportError(a,b,error) {
		var key;
		if (typeof console != 'undefined') {
			for (key in a)
				if (typeof a[key] != 'function')
					console.log(key + '=>' + a[key]);
			console.log(b);
			console.log(error);
		}
		alert(i18n('unknown error', error));
	}

	function pickTemplate(item) {
		function okButtonPressed(e, ui) {
			template = ui ? ui.item.value : selector.val();
			fireDialog();
			templateSelector.dialog("close");
		}
		var selector = $('<input>')
			.css({width: '28em'})
			.autocomplete({
				source: function(request, response) {
					$.getJSON(
						mw.util.wikiScript('api'),
						{action:'opensearch', search: request.term, namespace: 10},
						function(data){
							if(data[1])
								response($(data[1]).map(function(index,item){return item.replace(/.*:/, );}));
						}
					);
				},
				select: okButtonPressed
			});
		var templateSelector = $('
').dialog({ title: i18n('template selector title'), height: 'auto', width: 'auto', modal: true, buttons: [ {text: i18n('ok'), click: okButtonPressed}, {text: i18n('cancel'), click: function(){templateSelector.dialog("close")}} ] }).append(selector); circumventRtlBug(); selector.focus(); } function fireDialog() { var readRaw = function() { rawTemplate = true; $.ajax({ url: mw.util.wikiScript(), data: {title: templatePage(), action: 'raw'}, dataType: 'text', success: buildDialog, error: reportError }); }, readTemplateData = function() { $.ajax({ url: mw.util.wikiScript('api'), data: {action: 'templatedata', titles: templatePage(), redirects: true, format: 'json', lang: mw.config.get('wgUserLanguage') }, dataType: 'json', success: function(data) { var found = false; if (data && data.pages) for (var pageid in data.pages) { tdTemplate = true; found = true; buildDialog(data.pages[pageid]); break; } if (! found) readRaw(); }, error: readRaw }); }; rawTemplate = false; readTemplateData(); } function templateContext() { var selection = $("#wpTextbox1").textSelection('getSelection'), caretPos, beforeText, afterText, templateStart, templateEnd; // trust the user if ( selection.length > 0 ) { return selection; } caretPos = $("#wpTextbox1").textSelection('getCaretPosition'); beforeText = $("#wpTextbox1").val().substr(0, caretPos); afterText = $("#wpTextbox1").val().substr(caretPos); templateStart = beforeText.lastIndexOf('{{'); templateEnd = afterText.indexOf('}}') + 2; // only under opportunistic template context assumptions if ( $("#wpTextbox1").val().split('{').length != $("#wpTextbox1").val().split('}').length || (beforeText.split('מוסטער:').length === beforeText.split('').length) || (afterText.split('מוסטער:').length === afterText.split('').length) ) return ; // determine the start and the end of the template context while (beforeText.substr(templateStart).split('{{').length <= beforeText.substr(templateStart).split('}}').length) templateStart = beforeText.lastIndexOf('{{', templateStart - 1) while (afterText.substr(0, templateEnd).split('{{').length >= afterText.substr(0, templateEnd).split('}}').length) templateEnd = afterText.indexOf('}}', templateEnd) + 2; // extend the selection to the current template context $("#wpTextbox1").focus().textSelection('setSelection', { start: templateStart, end: caretPos + templateEnd }); return $("#wpTextbox1").textSelection('getSelection'); } function doIt() { mw.loader.using(['jquery.ui','jquery.tipsy','jquery.textSelection', 'mediawiki.api'], function() { init(); var match = templateContext().match(/^\{\{([^|}]*)/); template = match ? $.trim(match[1]) : null; if (template) fireDialog(); else pickTemplate(); }); } function addToWikiEditor(){ $('#wpTextbox1').wikiEditor('addToToolbar', { section: 'main', group: 'insert', tools: { 'templateParamsWizard': { label: i18n('button hint'), type: 'button', icon: '//upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Template_alt_full_black_22.svg/22px-Template_alt_full_black_22.svg.png', action: {type: 'callback', execute: doIt} } } }); } if (mw.user.options.get('usebetatoolbar')) mw.loader.using(['ext.wikiEditor'], function() { if(typeof $.wikiEditor != 'undefined') { if ($('#wikiEditor-ui-toolbar').length === 1) addToWikiEditor();//in case it loaded after toolbar initaliztion else $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', addToWikiEditor); } }); else $('div #toolbar').append( // "old style" $('<img>', {src: '//upload.wikimedia.org/wikipedia/commons/e/eb/Button_plantilla.png', title: i18n('button hint'), 'class': 'mw-toolbar-editbutton'}) .css({cursor: 'pointer'}) .click(doIt) ); } );