מדיה ויקי:Gadget-TemplateParamWizard.js – הבדלי גרסאות
יצירת דף עם התוכן "//Template parameters wizard //Written by User:קיפודנחש "use strict"; if(($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1) && ( !$('#wpTex..." |
אין תקציר עריכה |
||
| שורה 3: | שורה 3: | ||
"use strict"; | "use strict"; | ||
if(($.inArray(mw.config.get('wgAction'), ['edit', 'submit'])+1) && ( !$('#wpTextbox1').prop( 'readonly' ) ) ) | 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 | ||
| שורה 27: | שורה 27: | ||
// the fields, keyed by paramName | // the fields, keyed by paramName | ||
fieldsBypName, | fieldsBypName, | ||
// boolean, indicating | // 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, | extendedParamCssRule, | ||
anyExtended = false, | anyExtended = false, | ||
localStorageKey = 'templateParamWizard', | localStorageKey = 'templateParamWizard', | ||
emptiesKey = 'writeEmpties'; | emptiesKey = 'writeEmpties', | ||
oneLineTemplate = 'oneLineTemplate', | |||
allAliases = []; | |||
function addParam(name) { | function addParam(name) { | ||
| שורה 45: | שורה 50: | ||
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 | 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; | ||
| שורה 53: | שורה 59: | ||
selection = selection.replace(match[0], "\0" + specials.length + "\0"); | selection = selection.replace(match[0], "\0" + specials.length + "\0"); | ||
} | } | ||
var params = selection.split(/ | 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) { | ||
match = val.match(/\0(\d+)\0/); | |||
if (! match || ! match.length) | if (! match || ! match.length) | ||
break; | break; | ||
val = val.replace(match[0], specials[parseInt(match[1], 10)-1]); | |||
} | } | ||
if (name && paramPair.length) { | if (name && paramPair.length) { | ||
templateParams[name] = templateParams[name] || {options: {notInParamPage: 1}}; | var tp = templateParams[name] = | ||
templateParams[name] || | |||
~allAliases.indexOf(name) && { param:{}, options: {isAlias: 1} } || | |||
{param: {}, options: { notInParamPage: 1}}; | |||
addParam(name); | addParam(name); | ||
$.extend( | $.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 ); | |||
} | } | ||
} | } | ||
| שורה 78: | שורה 100: | ||
while (m = paramExtractor.exec(data)) { | while (m = paramExtractor.exec(data)) { | ||
var paramName = $.trim(m[1]); | var paramName = $.trim(m[1]); | ||
templateParams[paramName] = {desc: '', options: {multiline: 5}}; | templateParams[paramName] = { desc: '', options: {multiline: 5}, label: paramName, param:{} }; | ||
addParam(paramName); | 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); | |||
} | |||
} | |||
); | |||
} | } | ||
} | } | ||
| שורה 150: | שורה 228: | ||
function createWikiCode() { | function createWikiCode() { | ||
var par = [template], | var par = [template], | ||
delim = $('#oneLineTemplate | delim = $('#' + oneLineTemplate).prop('checked') ? '' : '\n', | ||
createEmpties = $('#createEmpties').prop('checked'); | 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 | ||
| שורה 157: | שורה 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 = | val = f.val().replace( /\s+$/, '' ); // leave leading newlines, for lists etc., but remove trailing. | ||
if ( | 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 = ""; | ||
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 + "|") + delim + "}}"; | return "{{" + par.join(delim + ($('#' + oneLineTemplate).prop('checked')? "|" : "| ")) + delim + "}}"; | ||
} | } | ||
| שורה 219: | שורה 321: | ||
case 'choices': return 'خيارات'; | case 'choices': return 'خيارات'; | ||
case 'date': return 'تاريخ'; | case 'date': return 'تاريخ'; | ||
case 'extended': return ' | case 'extended': return 'مفصل'; | ||
case 'button hint': return 'معالج وسائط القالب'; | case 'button hint': return 'معالج وسائط القالب'; | ||
case 'template selector title': return 'اكتب اسم القالب:'; | case 'template selector title': return 'اكتب اسم القالب:'; | ||
case 'notInParamPage': return 'وسيط "' + param + '" ليس من وسائط القالب'; | case 'notInParamPage': return 'وسيط "' + param + '" ليس من وسائط القالب'; | ||
| שורה 228: | שורה 329: | ||
case 'please select template': return 'اسم القالب'; | case 'please select template': return 'اسم القالب'; | ||
case 'oneliner': return 'اجعله في صف واحد'; | case 'oneliner': return 'اجعله في صف واحد'; | ||
case 'createempties': return ' | case 'createempties': return 'إضافة الوسائط فارغة'; | ||
case 'dateFormat': return 'd MM yy'; | |||
case 'extended labels': return 'عرض كل الوسائط'; | |||
default: return key; | |||
} | |||
break; | |||
case 'fa': | |||
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 'dateFormat': return 'd MM yy'; | ||
case 'extended labels': return ' | 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 'he': | case 'he': | ||
switch (key) { | switch (key) { | ||
case 'explain': return | case 'explain': return hebExplain(); | ||
case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.getUrl('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>'; | case 'wizard dialog title': return 'מילוי הפרמטרים עבור ' + '<a href="' + mw.util.getUrl('תבנית:' + template) + '" target="_blank">' + 'תבנית:' + template + '</a>'; | ||
case 'ok': return 'אישור'; | case 'ok': return 'אישור'; | ||
case 'cancel': return 'ביטול'; | case 'cancel': return 'ביטול'; | ||
case 'preview': return 'תצוגה מקדימה'; | case 'preview': return 'תצוגה מקדימה'; | ||
case 'options select': return 'בחרו ערך מהרשימה'; | case 'options select': return 'בחרו ערך מהרשימה'; | ||
| שורה 252: | שורה 387: | ||
case 'extended': return 'משני'; | case 'extended': return 'משני'; | ||
case 'button hint': return 'אשף מילוי תבניות'; | case 'button hint': return 'אשף מילוי תבניות'; | ||
case 'template selector title': return 'אנא הזינו את שם התבנית:'; | case 'template selector title': return 'אנא הזינו את שם התבנית:'; | ||
case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית'; | case 'notInParamPage': return 'השדה "' + param + '" לא מופיע ברשימת הפרמטרים של התבנית'; | ||
| שורה 262: | שורה 396: | ||
case 'dateFormat': return 'd בMM yy'; | case 'dateFormat': return 'd בMM yy'; | ||
case 'extended labels': return 'הראה את כל הפרמטרים'; | 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 'Показать все параметры'; | |||
} | |||
break; | |||
default: | default: | ||
switch (key) { | switch (key) { | ||
| שורה 268: | שורה 467: | ||
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'; | ||
| שורה 281: | שורה 480: | ||
case 'extended': return 'Extended'; | case 'extended': return 'Extended'; | ||
case 'button hint': return 'Template parameters wizard'; | case 'button hint': return 'Template parameters wizard'; | ||
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'; | ||
| שורה 291: | שורה 489: | ||
case 'dateFormat': return 'MM d, yy'; | case 'dateFormat': return 'MM d, yy'; | ||
case 'extended labels': return 'Show all parameters'; | 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'; | |||
} | } | ||
} | } | ||
| שורה 296: | שורה 500: | ||
} | } | ||
function | function hebExplain() { | ||
var explanation; | |||
function templatePage() {return mw.config.get('wgFormattedNamespaces')[10] + ':' + | 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(){ | ||
| שורה 317: | שורה 537: | ||
$(".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')) | 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 | var params = templateParams[paramName], | ||
options = params.options || {}, | |||
f, | f, | ||
checkbox = false; | checkbox = false; | ||
| שורה 328: | שורה 584: | ||
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) { | ||
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], text: 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]); | |||
} | } | ||
} | } | ||
| שורה 342: | שורה 602: | ||
var rows = options.multiline; | var rows = options.multiline; | ||
f = $('<textarea>', {rows: 1}) | f = $('<textarea>', {rows: 1}) | ||
.focus(function(){this.rows = 5;}) | |||
.focus(function(){this.rows = | |||
.blur(function(){this.rows = 1}); | .blur(function(){this.rows = 1}); | ||
} | } | ||
| שורה 354: | שורה 613: | ||
f.css({width: checkbox ? '1em' : '28em'}) | f.css({width: checkbox ? '1em' : '28em'}) | ||
.data({paramName: paramName, options: options}) | .data({paramName: paramName, options: options}) | ||
. | .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(' | f.addClass('tpw-required'); | ||
if (options.date) | if (options.date) | ||
f.datepicker({dateFormat: typeof options.date == "string" ? options.date : i18n('dateFormat')}); | f.datepicker({dateFormat: typeof options.date == "string" ? options.date : i18n('dateFormat')}); | ||
return f; | return f; | ||
} | } | ||
| שורה 370: | שורה 630: | ||
timer = null, | timer = null, | ||
lastVisited = $('<a>'); | lastVisited = $('<a>'); | ||
function addRow(paramName, table) { | function addRow(paramName, table) { | ||
| שורה 417: | שורה 635: | ||
def = templateParams[paramName], | def = templateParams[paramName], | ||
inputField = createInputField(paramName), | inputField = createInputField(paramName), | ||
nameColor = def.desc ? 'blue' : | tooltip = def.desc || '', | ||
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}) | ||
. | .data({ paramname: paramName }) | ||
.text(templateParams[paramName].label || paramName) | |||
. | .attr('title', tooltip) | ||
.attr('master', 'true') | .attr('master', 'true') | ||
) | ) | ||
| שורה 457: | שורה 676: | ||
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) { | ||
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: | title: title.html(), | ||
width: 'auto', | width: 'auto', | ||
overflow: 'auto', | overflow: 'auto', | ||
| שורה 473: | שורה 697: | ||
}) | }) | ||
.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(anyExtended ? createExtendedCheckBox() : '') | ||
.append(table) | .append(table) | ||
.append($('<p>') | .append($('<p>') | ||
.append(i18n('oneliner')) | .append(i18n('oneliner')) | ||
.append($('<input>', {type:'checkbox', id:' | .append($('<input>', {type: 'checkbox', id: oneLineTemplate}).prop('checked', isInline).change(updateRawPreview) | ||
) | ) | ||
) | ) | ||
| שורה 488: | שורה 712: | ||
) | ) | ||
) | ) | ||
.append($('<pre>', {id: 'tpw_preview'}) | .append($('<pre>', {id: 'tpw_preview'}).addClass('tpw-wikicode-preview')); | ||
while (paramsOrder.length) | while (paramsOrder.length) | ||
addRow(paramsOrder.shift(), table); | 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(); | ||
} | } | ||
| שורה 564: | שורה 790: | ||
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; | ||
$. | 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() { | function doIt() { | ||
mw.loader.using(['jquery.ui | // as a gadget, dependencies are already defined in mediawiki:gadgets-definition. we call loader.using here as a courtesy | ||
// so this script will work when loaded from another wiki not as a gadget. | |||
mw.loader.using(['jquery.ui','jquery.textSelection', 'mediawiki.api'], function() { | |||
init(); | init(); | ||
var match = | var match = templateContext().match(/^\{\{([^|}]*)/); | ||
template = match ? $.trim(match[1]) : null; | template = match ? $.trim(match[1]) : null; | ||
if (template) | if (template) | ||
| שורה 595: | שורה 876: | ||
}); | }); | ||
} | } | ||
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')) | if (mw.user.options.get('usebetatoolbar')) | ||
mw.loader.using([ | mw.loader.using(['ext.wikiEditor'], function() { | ||
if(typeof $.wikiEditor != 'undefined' | if(typeof $.wikiEditor != 'undefined') { | ||
$('#wpTextbox1'). | if ($('#wikiEditor-ui-toolbar').length === 1) addToWikiEditor();//in case it loaded after toolbar initaliztion | ||
else $( '#wpTextbox1' ).on( 'wikiEditor-toolbar-doneInitialSections', addToWikiEditor); | |||
} | |||
}); | }); | ||
else | else | ||
| שורה 621: | שורה 903: | ||
.click(doIt) | .click(doIt) | ||
); | ); | ||
}); | } ); | ||