מדיה ויקי:Gadget-TemplateParamWizard.js: הבדלים בין גרסאות בדף

ניסוי
מ 148 גרסאות של הדף wikipedia:he:מדיה_ויקי:Gadget-TemplateParamWizard.js יובאו
 
(106 גרסאות ביניים של 5 משתמשים אינן מוצגות)
שורה 1: שורה 1:
//Template parameters wizard
//Template parameters wizard
//Written by [[User:קיפודנחש]]
//Written by [[User:קיפודנחש]]
if($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1)
"use strict";
mw.loader.using(['jquery.ui.widget','jquery.tipsy','jquery.textSelection', 'jquery.ui.autocomplete', 'jquery.ui.dialog'], function() {
if(($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1) && ( !$('#wpTextbox1').prop( 'readonly' ) ) )
$(function() {
$(function($) {
// template parameter is an object with the following fields:
// template parameter is an object with the following fields:
// desc: desciption string
// desc: desciption string
שורה 11: שורה 11:
//// depends: another field's name
//// depends: another field's name
//// required: boolean
//// required: boolean
//// date: use JS date widget
//// choices: array of legal values for the field
//// 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 is keyed by paramName.
var templateParams,
templateParams,
paramsOrder,
// which template are we working on
// which template are we working on
template,
template,
שורה 22: שורה 27:
// the fields, keyed by paramName
// the fields, keyed by paramName
fieldsBypName,
fieldsBypName,
// boolean, indicating we did not find "Parameters" page, so the parameters are extracted from template page itself.
// boolean, indicating the source of data is templatedata.
tdTemplate,
// boolean, indicating the source of the data is analyzing the template page itself.
rawTemplate,
rawTemplate,
isInline,
rtl = $('body').is('.rtl'),
rtl = $('body').is('.rtl'),
// test to see if a string contains wikiCode and hence needs parsing, or cen be used as is.
// test to see if a string contains wikiCode and hence needs parsing, or cen be used as is.
wikiCodeFinder = /[\[\]\{\}\<\>]/,
wikiCodeFinder = /[\[\]\{\}<>]/,
globalExplanation = '';
globalExplanation = '',
extendedParamCssRule,
anyExtended = false,
localStorageKey = 'templateParamWizard',
emptiesKey = 'writeEmpties',
oneLineTemplate = 'oneLineTemplate',
allAliases = [];
 
function addParam(name) {
if ($.inArray(name, paramsOrder) == -1)
paramsOrder.push(name);
}


function paramsFromSelection() {
function paramsFromSelection() {
var selection = $("#wpTextbox1").textSelection('getSelection').replace(/^\s*\{\{|\}\}\s*$/g, ''); //scrap the first {{ and last }}
var selection = $("#wpTextbox1").textSelection('getSelection').replace(/^\s*\{\{|\}\}\s*$/g, ''); //scrap the first {{ and last }}
var specials = [];
var specials = [],
while (true) { //extract inner links, inner templates and inner params - we don't want to sptit those.
match;
var match = selection.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)
if (! match || ! match.length)
break;
break;
שורה 39: שורה 59:
selection = selection.replace(match[0], "\0" + specials.length + "\0");
selection = selection.replace(match[0], "\0" + specials.length + "\0");
}
}
var params = selection.split(/\s*\|\s*/);
var params = selection.split(/ *\| */);
params.shift(); // remove the template name
var ordered = 0;
for (var i in params) {
for (var i in params) {
var param = params[i];
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) {
while (true) {
var match = param.match(/\0(\d+)\0/);
match = val.match(/\0(\d+)\0/);
if (! match || ! match.length)
if (! match || ! match.length)
break;
break;
param = param.replace(match[0], specials[parseInt(match[1], 10)-1]);
val = val.replace(match[0], specials[parseInt(match[1], 10)-1]);
}
}
var paramPair = param.split("=");
var name = $.trim(paramPair.shift());
if (name && paramPair.length) {
if (name && paramPair.length) {
templateParams[name] = templateParams[name] || {options: {notInParamPage: 1}};
var tp = templateParams[name] =  
$.extend(templateParams[name].options, {'defval': paramPair.join('=')});
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 );  
}
}
}
}
שורה 59: שורה 96:
function buildParamsRaw(data) {
function buildParamsRaw(data) {
var
var
paramExtractor = /{{3,}(.*?)[\|}]/mg,
paramExtractor = /{{3,}(.*?)[<|}]/mg,
m;
m;
while (m = paramExtractor.exec(data))
while (m = paramExtractor.exec(data)) {
templateParams[m[1]] = {desc: '', options: {multiline: 5}};
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 = $('<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);
}
}
);
}
}
}


שורה 92: שורה 188:
line = lines.shift();
line = lines.shift();
if (line.indexOf('globalExplanation') + 1) {
if (line.indexOf('globalExplanation') + 1) {
extractGlobalExplanation()
extractGlobalExplanation();
continue;
continue;
}
}
שורה 110: שורה 206:


templateParams[name] = pAttribs;
templateParams[name] = pAttribs;
addParam(name);
}
}
}
}
שורה 115: שורה 213:
function analyzeOptions(str) {
function analyzeOptions(str) {
var res = {},
var res = {},
avail = ['multiline', 'required', 'depends', 'defval', 'choices'], // maybe we'll have more in the future
avail = ['multiline', 'required', 'depends', 'defval', 'choices', 'date', 'extended'], // maybe we'll have more in the future
tavail = $.map(avail, i18n),
tavail = $.map(avail, i18n),
options = str.split(/\s*;\s*/);
options = str.split(/\s*;\s*/);
שורה 124: שורה 222:
res[avail[ind]] = option.length > 1 ? option[1] : true;
res[avail[ind]] = option.length > 1 ? option[1] : true;
}
}
anyExtended = anyExtended || res.extended;
return res;
return res;
}
}


function createWikiCode() {
function createWikiCode() {
var par = [template];
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) {
for (var i in dialogFields) {
var
var
שורה 134: שורה 251:
name = $.trim(field[0]),
name = $.trim(field[0]),
f = field[1],
f = field[1],
opts = f.data('options'),
param = templateParams[name],
hidden = f.parents('.tpw_hidden').length,
hidden = f.parents('.tpw_hidden').length,
val = $.trim(f.val());
val = f.val().replace( /\s+$/, '' ); // leave leading newlines, for lists etc., but remove trailing.
if(val=="" && f.attr('type') != 'checkbox') continue;//skip parameters with no value
if (param && param.param && param.param.type === 'url')  
val = val.replace(/\|/g, '{{!}}');
if (f.attr('type') == 'checkbox' && ! f.prop('checked'))
if (f.attr('type') == 'checkbox' && ! f.prop('checked'))
val = "";
val = "";
par.push(name + '=' + 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("\n|") + "\n}}";
return "{{" + par.join(delim + ($('#' + oneLineTemplate).prop('checked')? "|" : "| ")) + delim + "}}";
}
}


שורה 176: שורה 302:


function i18n(key, param) {
function i18n(key, param) {
switch (mw.config.get('wgContentLanguage')) {
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':
case 'he':
switch (key) {
switch (key) {
case 'explain': return rawTemplate
case 'explain': return hebExplain();
? 'לתבנית "' + template + '" אין דף פרמטרים, ולכן לשדות אין תיאור.'
case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.getUrl('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>';
: 'השדות המסומנים באדום הם חובה, השאר אופציונליים.';
case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.wikiGetlink('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>';
case 'ok': return 'אישור';
case 'ok': return 'אישור';
case 'cancel': return 'ביטול'
case 'cancel': return 'ביטול';
case 'params subpage': return 'פרמטרים';
case 'preview': return 'תצוגה מקדימה';
case 'preview': return 'תצוגה מקדימה';
case 'options select': return 'בחרו ערך מהרשימה';
case 'options select': return 'בחרו ערך מהרשימה';
שורה 194: שורה 349:
case 'defval': return 'ברירת מחדל';
case 'defval': return 'ברירת מחדל';
case 'choices': return 'אפשרויות';
case 'choices': return 'אפשרויות';
case 'date': return 'תאריך';
case 'extended': return 'משני';
case 'button hint': return 'אשף מילוי תבניות';
case 'button hint': return 'אשף מילוי תבניות';
case 'able templates category name': return 'תבניות הנתמכות על ידי אשף התבניות';
case 'template selector title': return 'אנא הזינו את שם התבנית:';
case 'template selector title': return 'אנא הזינו את שם התבנית:';
case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית';
case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית';
שורה 201: שורה 357:
case 'unknown error': return 'טעות בהפעלת האשף.\n' + param;
case 'unknown error': return 'טעות בהפעלת האשף.\n' + param;
case 'please select template': return 'שם התבנית';
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:
default:
שורה 207: שורה 431:
case 'wizard dialog title': return 'Set up parameters for template: ' + template;
case 'wizard dialog title': return 'Set up parameters for template: ' + template;
case 'ok': return 'OK';
case 'ok': return 'OK';
case 'cancel': return 'Cancel'
case 'cancel': return 'Cancel';
case 'params subpage': return 'Parameters';
case 'params subpage': return 'Parameters';
case 'preview': return 'Preview';
case 'preview': return 'Preview';
שורה 217: שורה 441:
case 'defval': return 'Default';
case 'defval': return 'Default';
case 'choices': return 'Choices';
case 'choices': return 'Choices';
case 'date': return 'Date';
case 'extended': return 'Extended';
case 'button hint': return 'Template parameters wizard';
case 'button hint': return 'Template parameters wizard';
case 'able templates category name': throw('Must define category name for wizard-capable templates');
case 'template selector title': return 'Please enter the template name';
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 'notInParamPage': return 'field "' + param + '" does not appear in the template\'s parameters list';
שורה 224: שורה 449:
case 'unknown error': return 'Error occured: \n' + param;
case 'unknown error': return 'Error occured: \n' + param;
case 'please select template': return 'Please enter template name';
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';
}
}
}
}
שורה 230: שורה 464:
}
}


function paramPage() {return mw.config.get('wgFormattedNamespaces')[10] + ':' + $.trim(template) + '/' + i18n('params subpage');}
function hebExplain() {
 
var explanation;
function templatePage() {return mw.config.get('wgFormattedNamespaces')[10] + ':' + $.trim(template);}
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(){
function updateRawPreview(){
שורה 251: שורה 501:
$(".ui-dialog-buttonpane button:contains('" + i18n('ok') + "')").button(canOK);
$(".ui-dialog-buttonpane button:contains('" + i18n('ok') + "')").button(canOK);
$('#tpw_preview').text(createWikiCode());
$('#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) {
function createInputField(paramName) {
var options = templateParams[paramName].options || {},
var params = templateParams[paramName],
options = params.options || {},
f,
f,
checkbox = false;
checkbox = false;
שורה 261: שורה 548:
var choices = options.choices.split(/\s*,\s*/);
var choices = options.choices.split(/\s*,\s*/);
if (choices.length > 1) {
if (choices.length > 1) {
f = $('<select>').append($('<option>', {text: i18n('options select'), value: ''}));
f = $('<select>').append($('<option>', {text: i18n('options select'), value: '' }));
for (var i in choices)
for (var i in choices) {
f.append($('<option>', {text: choices[i], value: choices[i]}));
var choice = choices[i].trim(); // first and last may carry spaces
var option = $('<option>', {text: choice, value: choice});
f.append(option);
}
}
}
else {
else {
checkbox = true;
checkbox = true;
f = $('<input>', {type: 'checkbox', value: choices[0]})
var choice = choices[0].trim();
.css({float: rtl ? 'right' : 'left'})
f = $('<input>', {type: 'checkbox', value: choices[0], text: choices[0].trim()})
f.prop('checked', options.defval && options.defval == choices[0]);
.css({float: rtl ? 'right' : 'left'});
f.prop('checked', options.defval && options.defval.trim() == choices[0]);
}
}
}
}
שורה 275: שורה 566:
var rows = options.multiline;
var rows = options.multiline;
f = $('<textarea>', {rows: 1})
f = $('<textarea>', {rows: 1})
.data({dispRows: isNaN(parseInt(rows)) ? 5 : rows})
.focus(function(){this.rows = 5;})
.focus(function(){this.rows = $(this).data('dispRows');})
.blur(function(){this.rows = 1});
.blur(function(){this.rows = 1});
}
}
שורה 287: שורה 577:
f.css({width: checkbox ? '1em' : '28em'})
f.css({width: checkbox ? '1em' : '28em'})
.data({paramName: paramName, options: options})
.data({paramName: paramName, options: options})
.bind('paste cut drop input change', updateRawPreview);
.on('paste cut drop input change', updateRawPreview);


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


if (options.required)
if (options.required)
f.addClass('tpw_required').css({border: '1px red solid'});
f.addClass('tpw-required');
 
if (options.date)
f.datepicker({dateFormat: typeof options.date  == "string" ? options.date : i18n('dateFormat')});
return f;
return f;
}
}
שורה 316: שורה 610:
function tipsyContent() {
function tipsyContent() {
var
var
paramName = $(this).text(),
paramName = $(this).data('paramname'),
def = templateParams[paramName],
def = templateParams[paramName],
desc = def.desc || '';
desc = def && def.desc || '';
if (!def) return ''; // early terminate if param name is not valid
if (def.htmlDesc)
if (def.htmlDesc)
return def.htmlDesc;
return def.htmlDesc;
if (def.options.notInParamPage)
return $('<div>')
.append(i18n('notInParamPage', paramName) + '<br />')
.append($('<a>', {href: mw.util.wikiGetlink(paramPage()) + '?action=edit', target: '_blank', text: i18n('editParamPage')}))
.html();
if (wikiCodeFinder.test(desc)) // does it need parsing?
if (wikiCodeFinder.test(desc)) // does it need parsing?
$.ajax({
$.ajax({
שורה 347: שורה 637:
def = templateParams[paramName],
def = templateParams[paramName],
inputField = createInputField(paramName),
inputField = createInputField(paramName),
nameColor = def.desc ? 'blue' : (def.options.notInParamPage ? 'red' : 'black'),
nameColor = def.desc  
? 'blue'  
: def.options.notInParamPage  
? 'red'  
: def.options.isAlias
? 'green'
: 'black',
tr = $('<tr>')
tr = $('<tr>')
.append(
.append(
$('<td>', {width: 120})
$('<td>', {width: 120})
.css({fontWeight: 'bold', color: nameColor})
.css({fontWeight: 'bold', color: nameColor})
.text(paramName)
.data({ paramname: paramName })
.text(templateParams[paramName].label || paramName)
.tipsy({html: true, trigger: 'manual', title: tipsyContent})
.tipsy({html: true, trigger: 'manual', title: tipsyContent})
.mouseenter(function() {
.mouseenter(function() {
שורה 365: שורה 662:
.append($('<td>').css({width: '30em'}).append(inputField));
.append($('<td>').css({width: '30em'}).append(inputField));
dialogFields.push([paramName, inputField]);
dialogFields.push([paramName, inputField]);
if (def.options.extended)
tr.addClass('tpw_extended');
table.append(tr);
table.append(tr);
rowsBypName[paramName] = tr;
rowsBypName[paramName] = tr;
שורה 372: שורה 671:
function injectResults() {
function injectResults() {
$("#wpTextbox1").textSelection('encapsulateSelection', {replace: true, peri: createWikiCode()});
$("#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) {
function buildDialog(data) {
var title = $('<span>').html(i18n('wizard dialog title', template));
$('.tpw_disposable').remove();
$('.tpw_disposable').remove();
if (rawTemplate)
if (rawTemplate)
buildParamsRaw(data)
buildParamsRaw(data);
else
else if (tdTemplate) {
buildParams(data);
buildParamsTd(data);
if (data.description) title.find('a').attr({ title: data.description });
}
paramsFromSelection();
paramsFromSelection();
var table = $('<table>');
var table = $('<table>');
var dialog = $('<div>', {'class': 'tpw_disposable'})
var dialog = $('<div>', {'class': 'tpw_disposable'})
.dialog({height: 'auto',
.dialog({height: 'auto',
title: i18n('wizard dialog title', template),
title: title.html(),
width: 'auto',
width: 'auto',
overflow: 'auto',
overflow: 'auto',
שורה 391: שורה 705:
})
})
.append($('<div>', {id: 'tpw_globalExplanation'}).html(globalExplanation))
.append($('<div>', {id: 'tpw_globalExplanation'}).html(globalExplanation))
.append($('<p>').html(i18n('explain')))
.append($('<p>', { id: 'tpw-explain' } ).html(i18n('explain')) )
.append(anyExtended ? createExtendedCheckBox() : '')
.append(table)
.append(table)
.append($('<p>').css({height: '2em'}))
.append($('<p>')
.append($('<pre>', {id: 'tpw_preview'})
.append(i18n('oneliner'))
.css({backgroundColor: "lightGreen", maxWidth: '40em', maxHeight: '8em', overflow: 'auto'}));
.append($('<input>', {type: 'checkbox', id: oneLineTemplate}).prop('checked', isInline).change(updateRawPreview)
 
)
for (var paramName in templateParams)
)
addRow(paramName, table);
.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.
var buttons = {}; // we need to do it this way, because with literal object, the keys must be literal.
buttons[i18n('ok')] = function() {injectResults(); dialog.dialog('close'); };
buttons[i18n('ok')] = function() {
buttons[i18n('cancel')] = function() {dialog.dialog('close');}
if (! validate() && ! confirm(i18n('pve-approve-close' ) ) ) return;
injectResults();  
dialog.dialog('close');  
};
buttons[i18n('cancel')] = function() {dialog.dialog('close');};
buttons[i18n('preview')] = showPreview;
buttons[i18n('preview')] = showPreview;
dialog.dialog('option', 'buttons', buttons);
dialog.dialog('option', 'buttons', buttons);
circumventRtlBug();
circumventRtlBug();
updateRawPreview();
updateRawPreview();
$('.tipsy')
$('.tipsy').hover(enterTipsy, leaveTipsy);
.live('mouseenter', enterTipsy)
.live('mouseleave', leaveTipsy);
}
}


שורה 415: שורה 742:
template = null;
template = null;
templateParams = {};
templateParams = {};
paramsOrder = [];
dialogFields = [];
dialogFields = [];
rowsBypName = {};
rowsBypName = {};
fieldsBypName = {};
fieldsBypName = {};
mw.util.addCSS(".tpw_hidden{display:none;}");
mw.util.addCSS(".tpw_hidden{display:none;}");
anyExtended = false;
extendedParamCssRule = extendedParamCssRule || mw.util.addCSS(".tpw_extended{display:none;}");
}
}


function reportError(a,b,error) {
function reportError(a,b,error) {
var key;
if (typeof console != 'undefined') {
if (typeof console != 'undefined') {
for (key in a)
for (key in a)
שורה 432: שורה 763:
}
}


function pickTemplate() {
function pickTemplate(item) {
function okButtonPressed(e, ui) {
template = ui ? ui.item.value : selector.val();
fireDialog();
templateSelector.dialog("close");
}
var selector = $('<input>')
var selector = $('<input>')
.css({width: '28em'})
.css({width: '28em'})
שורה 445: שורה 781:
}
}
);
);
}
},
select: okButtonPressed
});
});
var templateSelector = $('<div>').dialog({
var templateSelector = $('<div>').dialog({
שורה 453: שורה 790:
modal: true,
modal: true,
buttons: [
buttons: [
{text: i18n('ok'), click: function(){template = selector.val(); fireDialog(); templateSelector.dialog("close")}},
{text: i18n('ok'), click: okButtonPressed},
{text: i18n('cancel'), click: function(){templateSelector.dialog("close")}}
{text: i18n('cancel'), click: function(){templateSelector.dialog("close")}}
]
]
}).append(selector);
}).append(selector);
circumventRtlBug();
circumventRtlBug();
selector.focus();
}
}


function fireDialog() {
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;
rawTemplate = false;
$.ajax({
readTemplateData();
url: mw.util.wikiScript(),
}
data: {title: paramPage(), action: 'raw', ctype: 'text/x-wiki'},
 
success: buildDialog,
function templateContext() {
error: function() {
var selection = $("#wpTextbox1").textSelection('getSelection'),
rawTemplate = true;
caretPos, beforeText, afterText, templateStart, templateEnd;
$.ajax({
 
url: mw.util.wikiScript(),
// trust the user
data: {title: templatePage(), action: 'raw', ctype: 'text/x-wiki'},
if ( selection.length > 0 ) {
success: buildDialog,
return selection;
error: reportError
}
});
 
}
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() {
function doIt() {
init();
mw.loader.using(['jquery.ui','jquery.tipsy','jquery.textSelection', 'mediawiki.api'], function() {
var match = $("#wpTextbox1").textSelection('getSelection').match(/^\{\{([^|}]*)/);
init();
template = match ? $.trim(match[1]) : null;
var match = templateContext().match(/^\{\{([^|}]*)/);
if (template)
template = match ? $.trim(match[1]) : null;
fireDialog();
if (template)
else
fireDialog();
pickTemplate();
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'))
$(document).ready(function() {
mw.loader.using(['ext.wikiEditor'], function() {
if (typeof $.wikiEditor == 'object' && $.wikiEditor.supported && mw.user.options.get('usebetatoolbar'))
if(typeof $.wikiEditor != 'undefined') {
mw.loader.using('ext.wikiEditor.toolbar', function() {
if ($('#wikiEditor-ui-toolbar').length === 1) addToWikiEditor();//in case it loaded after toolbar initaliztion
$('#wpTextbox1').wikiEditor('addToToolbar', {
else $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', addToWikiEditor);
section: 'advanced',
}
groups: 'wizards': {
tools: {
'linkTemplatewizard': {
label: i18n('button hint'),
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/d/dd/Vector_toolbar_template_button.png',
action: {type: 'callback', execute: doIt}
}
}
}
});
});
});
else
else
שורה 512: שורה 910:
.click(doIt)
.click(doIt)
);
);
 
} );
});
 
});
});