نکته: پس از انتشار ممکن است برای دیدن تغییرات نیاز باشد که حافظهٔ نهانی مرورگر خود را پاک کنید.
- فایرفاکس / سافاری: کلید Shift را نگه دارید و روی دکمهٔ Reload کلیک کنید، یا کلیدهای Ctrl-F5 یا Ctrl-R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-R)
- گوگل کروم: کلیدهای Ctrl+Shift+R را با هم فشار دهید (در رایانههای اپل مکینتاش کلیدهای ⌘-Shift-R)
- Edge: کلید Ctrl را نگهدارید و روی دکمهٔ Refresh کلیک کنید، یا کلیدهای Ctrl-F5 را با هم فشار دهید
// <pre> // This will break toggling if run on mobile skin so exit early. if ( mw.config.get( 'skin' ) === 'minerva' ) { return; } window.ListingEditor = {}; ListingEditor.allFields = { 'type': {right:true, newline:true, parameter:'نوع', label:'نوع', tip:'نوع فهرست', regx:'(نوع فهرست|type)' }, 'name': {right:false, newline:false, parameter:'نام', label:'نام', tip:'نام مکان', regx:'(نام|name)'}, 'alt': {right:true, newline:false, parameter:'نام دیگر', label:'نام دیگر', tip:'همچنین با این نام نیز شناخته می\u200cشود', regx:'(نام دیگر|alt)'}, 'url': {right:false, newline:false, parameter:'نشانی اینترنتی', label:'وب\u200cسایت', tip:'http://www.example.com', regx:'(نشانی اینترنتی|url)'}, 'email': {right:true, newline:true, parameter:'پست الکترونیکی', label:'پست الکترونیکی', tip:'[email protected]', regx:'(پست الکترونیکی|email|رایانامه)'}, 'address': {right:false, newline:false, parameter:'نشانی', label:'نشانی', tip:'نشانی مکان', regx:'(نشانی|address)'}, 'lat': {right:true, newline:false, parameter:'عرض جغرافیایی', label:'عرض جغرافیایی', tip:'11.11111', regx:'(عرض جغرافیایی|lat)'}, 'long': {right:true, newline:false, parameter:'طول جغرافیایی', label:'طول جغرافیایی', tip:'111.11111', regx:'(طول جغرافیایی|long)'}, 'directions': {right:false, newline:true, parameter:'مسیرها', label:'مسیرها', tip:'چه طوری به آنجا می\u200cرسید', regx:'(مسیرها|directions)'}, 'phone': {right:false, newline:false, parameter:'تلفن', label:'تلفن', tip: '+۹۸ ۲۱ ۸۸۸۸۸۸۸۸', regx:'(تلفن|phone)'}, 'tollfree': {right:true, newline:false, parameter:'تماس رایگان', label:'تماس رایگان', tip:'شماره تلفنی که تماس با آن خرج ندارد', regx:'(تماس رایگان|tollfree)'}, 'fax': {right:true, newline:false, parameter:'دورنگار', label:'دورنگار', tip: '+۹۸ ۲۱ ۸۸۸۸۸۸۸۸', regx:'(دورنگار|fax)'}, 'image': {right:true, newline:true, parameter:'تصویر', label:'تصویر', tip: 'تصویر مکان', regx:'(تصویر مکان|image)'}, 'hours': {right:false, newline:false, parameter:'ساعت\u200cها', label:'ساعت\u200cها', tip: 'ساعت\u200cهای کاری', regx:'(ساعت\u200cهای کاری|hours)'}, 'checkin': {right:true, newline:false, parameter:'زمان پذیرش', label:'زمان پذیرش', tip: 'زمان پذیرش', regx:'(زمان پذیرش|checkin)'}, 'checkout': {right:true, newline:false, parameter:'زمان اتمام پذیرش', label:'زمان اتمام پذیرش', tip: 'زمان اتمام پذیرش', regx:'(زمان اتمام پذیرش|checkout)'}, 'price': {right:false, newline:true, parameter:'بها', label:'بها', tip: 'بهای خدمات', regx:'(بها|price)'}, 'content': {rows:8, right:false, newline:true, parameter:'متن', label:'متن', tip: 'توضیح درباره مکان', regx:'(متن|content)'} }; ListingEditor.currencySigns = ['\ufdfc','\u062f\u002e\u0625\u002e','\u0024','\u00A3', '\u20AC', '\u00A5', '\u20A9']; ListingEditor.listingTypes = {'see':'دیدن', 'do':'انجام\u200cدادن', 'buy':'خریدن', 'eat':'خوردن', 'drink':'نوشیدن', 'sleep':'خوابیدن', 'listing':'فهرست\u200cبندی'}; ListingEditor.listingTypesLabels = {'see':'دیدن', 'do':'انجام\u200cدادن', 'buy':'خریدن', 'eat':'خوردن', 'drink':'نوشیدن', 'sleep':'خوابیدن', 'listing':'عمومی'}; ListingEditor.listingTypesRegex = {'see':'(دیدن|see)', 'do':'(انجام دادن|do|انجام\u200cدادن)', 'buy':'(خریدن|buy)', 'eat':'(خوردن|eat)', 'drink':'(نوشیدن|drink|آشامیدن)', 'sleep':'(خوابیدن|sleep|خواب)', 'listing':'(listing|فهرست\u200cنویسی|فهرست\u200cبندی|فهرست بندی|فهرست)'}; ListingEditor.addListingSections = {'see':'(دیدن|دیدنی ها|دیدنی\u200cها|جاذبه های گردشگری|جاذبه\u200cهای گردشگری|جاذبه ها|جاذبه\u200cها)','do':'(انجام\u200cدادن|انجام دادن|باید انجام داد|انجام دادنی\u200cها)','buy':'(خریدن|خرید کردن|خرید)','eat':'(خوردن|رستوران ها|رستوران\u200cها)','drink':'(نوشیدن|آشامیدن|نوشیدن و کافی شاپ|نوشیدن و کافی\u200cشاپ)','sleep':'(خوابیدن|خواب|هتل\u200cها|هتل ها)','listing':'(ارتباطات|آموزش|سفارت خانه\u200cها|سفارت خانه ها|سفارت\u200cخانه\u200cها|سفارت\u200cخانه ها)'}; ListingEditor.LICENSE_TEXT = 'با کلیک بر روی «ثبت»، شما با <a class="external" target="_blank" href="http://wikimediafoundation.org/wiki/Terms_of_use">شرایط استفاده</a> موافقت می\u200cکنید، و همچنین مشارکت شما برای مدت نامحدود تحت <a class="external" target="_blank" href="http://en.wikivoyage.org/wiki/Wikivoyage:Full_text_of_the_Attribution-ShareAlike_3.0_license">گواهینامه CC-BY-SA 3.0</a> منتشر خواهد شد.'; ListingEditor.translateStr = { 'add': 'افزودن به فهرست', 'edit': 'ویرایش', 'preview': 'پیش\u200cنمایش', 'closed': 'بسته شده؟', 'saving': 'در حال ذخیره', 'submit': 'ثبت', 'cancel': 'لغو', 'validationalert': 'خواهش می\u200cکنم نام و یا نشانی را وارد کنید', 'added': 'افزودن: ', 'updated': 'به روز رسانی: ', 'removed': 'بسته شده: ', 'cities': 'Cities', 'destination': 'Other_destinations', 'geomap': 'مشاهده موقعیت روی نقشه', 'help-page': '//fa.wikivoyage.org/wiki/%D9%88%DB%8C%DA%A9%DB%8C%E2%80%8C%D8%B3%D9%81%D8%B1:%D9%88%DB%8C%D8%B1%D8%A7%DB%8C%D8%B4%DA%AF%D8%B1_%D9%81%D9%87%D8%B1%D8%B3%D8%AA%E2%80%8C%D8%A8%D9%86%D8%AF%DB%8C%E2%80%8C%D9%87%D8%A7', 'enter-captcha': 'حروف به هم ریخته را وارد کنید', 'external-links': 'ویرایش شما شامل پیوندهای خارجی تازه می\u200cباشد.' }; ListingEditor.loadingIcon = 'data:image/gif;base64,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'; ListingEditor.ToolIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAAAzFBMVEUAAAAAoP+A0P9VwP9OnetVpO5aqfBVqfFSpfVVp/ZYqfZTo/FTpPJXqvRYq/VVpvVXpvFWpvJVpfNWqfVWp/JVpfJXqfNWp/NXqPNWpvRXqPNWp/NVp/RXqPRWp/JXqfRXqvRWpfJWpvJXqPNXqfNXqPRVpfNWpvRVpvRWqfRWpvJVpfJWp/NWpvNVpfNWp/RWp/NVpfNWqPNVpfNWpvNWp/NWp/NWp/NWp/NWp/NWp/NWqPNWp/NWp/NWp/NWp/NWp/NWp/NWp/NWp/Ox28KLAAAAQ3RSTlMAAQIGDQ8REhkbHSUoLzEzODtCSk1RUlZYXGdub3B5h4qLjpOZnLCys7S1trrDxcnMzs/R2ebn6Orr7u/x8/X5+v3+w2zu5gAAAJJJREFUeAFlyNW2gkAABdDD5drdIgYqdmC3InP+/5980DWLGfbjRljrvGtA0xH0K9pZgqxBsyAff3r2SDqA0a+HMkeSg5TLKSSjdOXXUp454c89L29Okl5A3grq+YmkPcyqJ2xI8trKzSKXcTaRK77eF/2wOqbR1Q7PERCnC8X28A+LTTWr4rQO9iZU5bHnxNT6AAC2HLAUiyuPAAAAAElFTkSuQmCC'; ListingEditor.wrapContent = function () { $('h2').each(function(){ $(this).nextUntil("h2").addBack().wrapAll('<div class="mw-h2section" />'); }); }; ListingEditor.addListingButtons = function () { if ($('#'+ListingEditor.translateStr['cities']).length || $('#'+ListingEditor.translateStr['destination']).length || $('#'+'Islands').length || $('#'+'print-districts').length) { return false; } var editButton = $('<span class="mw-addlisting noprint">') .css('cursor','pointer') .click(function() { var listingEntry = $(this).parent(); ListingEditor.popupForm('add', listingEntry); }).append(' [').append($('<a/>').text(ListingEditor.translateStr['add']).click( function(e) { e.preventDefault(); })).append(']'); $('.mw-h2section h2 span').each( function() { for (var key in ListingEditor.addListingSections) { var value = ListingEditor.addListingSections[key]; var rgx = new RegExp('^'+value+'$','g'); if($(this).text().match(rgx)!=null) { $(this).parent('h2').addClass('mw-addhere'); $(this).closest('div.mw-h2section').children('h3').addClass('mw-addhere'); } } }); $('.mw-addhere').append(editButton); }; ListingEditor.addEditButtons = function () { var editButton = $('<span class="vcard-edit-button noprint">') .css('cursor','pointer') .click(function() { var listingEntry = $(this).parent(); ListingEditor.popupForm('edit', listingEntry); }).append(' ').append($('<a/>').text(ListingEditor.translateStr['edit']).click( function(e) { e.preventDefault(); })); $('.listing-item').append( editButton ); }; ListingEditor.isInline = function (entry) { if (entry.parent('p').length == 0) return false; return true; }; ListingEditor.findSectionNumber = function (entry) { var link = entry.find( '.mw-editsection a' ).attr( 'href' ); if (link === undefined) link = entry.closest('div.mw-h2section').find( '.mw-editsection a' ).attr( 'href' ); if (link != undefined) return link.split( '=' ).pop(); return 0; }; ListingEditor.findSectionType = function (entry) { var section = entry.closest('div.mw-h2section').children('h2').find('.mw-headline').text(); for (var key in ListingEditor.addListingSections) { var value = ListingEditor.addListingSections[key]; var rgx = new RegExp('^'+value+'$','g'); if(section.match(rgx)) return key; } return ListingEditor.listingTypes.listing; }; ListingEditor.replacements = {}; ListingEditor.getSectionText = function (number, entry) { var wikiText = $.ajax({ url: mw.util.wikiScript(''), data: { title:mw.config.get('wgPageName'), action:'raw', section:number }, async: false, cache: false, // required beforeSend: function () { var loading = $('<span/>'); loading.attr('class','listing_loading'); var img = $('<img/>'); img.attr('src',ListingEditor.loadingIcon); loading.append(img); loading.prepend(' '); loading.insertAfter(entry); }, complete: function() { $('.listing_loading').remove(); }, }).responseText; var comments = wikiText.match(/<!--[\s\S]*?-->/mig); if ( comments !== null ) { for(var i = 0; i < comments.length; i++ ) { var comment = comments[i]; var rep = '<<<COMMENT' + i + '>>>'; wikiText = wikiText.replace(comment, rep); ListingEditor.replacements[rep] = comment; } } return wikiText; }; ListingEditor.replaceSpecial = function ( str ) { return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); }; ListingEditor.getListingWikitextBraces = function (entry) { ListingEditor.sectionText = ListingEditor.sectionText.replace(/[^\S\n]+/g,' '); var parent = $(entry.parentsUntil('.mw-h2section').parent()[0]); var cnt = 0; parent.find('.listing-item').each( function(){ if($(entry[0]).is($(this))) { return false; } cnt += 1; }); var regex = [] for(var key in ListingEditor.listingTypesRegex) { regex.push(ListingEditor.listingTypesRegex[key]); } var listingRegex = new RegExp("{{\\s*("+regex.join('|')+')','g'); var matches = ListingEditor.sectionText.match(listingRegex); var string = matches[cnt]; var parttxt = ListingEditor.sectionText; var index = 0; for(var i = 0; i < cnt; i++) { index += parttxt.indexOf(matches[i])+matches[i].length+1; parttxt = parttxt.slice(parttxt.indexOf(matches[i])+matches[i].length+1); } index += parttxt.indexOf(matches[cnt]); var curly = 2; var str1 = '', str2 = ''; // search for open and close braces for (var i=index; i>0; i--) { if (ListingEditor.sectionText[i]=='}') ++curly; else if (ListingEditor.sectionText[i]=='{') --curly; if(curly == 0) { str1 = ListingEditor.sectionText.substr(i,index-i); break; } } if (string.indexOf('}}') < 0) curly = 2; var textLength = ListingEditor.sectionText.length; for (var j=index+string.length; j<textLength; j++) { if (ListingEditor.sectionText[j]=='{') ++curly; else if (ListingEditor.sectionText[j]=='}') --curly; if (curly == 0) { str2 = ListingEditor.sectionText.substr(index, j-index+1); break; } } if (str2 === '') str2 = ListingEditor.sectionText.substr(index, textLength); string = str1 + str2; return $.trim(string); }; ListingEditor.wikiTextToListing = function (string) { string = string.slice(0,-2); var type = 'listing'; for(key in ListingEditor.listingTypesRegex) { var typeRegex = new RegExp('{{\\s*'+ListingEditor.listingTypesRegex[key],'g'); var match = typeRegex.exec(string); if(match != null) { type = key; } } if(typeof ListingEditor.listingTypes[type.toLowerCase()] != "undefined") type = ListingEditor.listingTypes[type.toLowerCase()]; var regex = [] for(var key in ListingEditor.listingTypesRegex) { regex.push(ListingEditor.listingTypesRegex[key]); } var listingRegex = new RegExp("{{\\s*("+regex.join('|')+')','g'); string = string.replace(listingRegex,'{{فهرست\u200cبندی| type=' + type); var listing = {}; var lastKey; var OpenBracket = 0; var OpenSquareBrackets = 0; var listParams = []; var buff = ''; for ( var i = 0; i < string.length; i++ ) { var chr = string.charAt(i); if ( chr == '{' ) { OpenBracket++; } else if ( chr == '}' ) { OpenBracket--; } else if ( chr == '[' ) { OpenSquareBrackets++; } else if ( chr == ']' ) { OpenSquareBrackets--; } if ( chr == '|' && OpenBracket == 2 && OpenSquareBrackets === 0 ) { listParams.push(buff); buff = ''; } else { buff += chr; } } if ( buff !== '' ) { listParams.push(buff); buff = ''; } for (var j=1;j<listParams.length;j++) { var param = listParams[j]; var index = param.indexOf('='); if (index > 0) { var key = $.trim(param.substr(0, index)); var value = $.trim(param.substr(index+1)); for(var key2 in ListingEditor.allFields) { var regx = new RegExp("^"+ListingEditor.allFields[key2]['regx']+"$") if(key.match(regx)) { key = key2; break; } } listing[key] = value; lastKey = key; } else if (listing[lastKey].length) { listing[lastKey] += '|' + param; } } return listing; }; ListingEditor.getListing = function (entry) { ListingEditor.listingText = ListingEditor.getListingWikitextBraces(entry); var listing = ListingEditor.wikiTextToListing(ListingEditor.listingText); return listing; }; /*** Functions to handle form creation and editing ***/ ListingEditor.popupForm = function (mode, entry) { mw.loader.using( ['jquery.ui'], function () { var sectionType, listing; var sectionNumber = ListingEditor.findSectionNumber(entry); ListingEditor.inlineListing = ListingEditor.isInline(entry); ListingEditor.sectionText = ListingEditor.getSectionText(sectionNumber,entry); if (mode == 'add') { sectionType = ListingEditor.findSectionType(entry); listing = {}; ListingEditor.sectionTitle = $($(entry.parent()[0]).find('h2 span')[0]).text(); } else { sectionType = ''; listing = ListingEditor.getListing(entry); ListingEditor.sectionTitle = $($(entry.parentsUntil('.mw-h2section').parent()[0]).find('h2 span')[0]).text(); } var form = $(ListingEditor.createForm(mode, sectionType, listing)); // modal form - must submit or cancel form.dialog({ // IE different behavior drag: function(event, ui) { $(this).parent().css('right', ( $(window).innerWidth() - parseInt($(this).parent().css('left')) - $(this).parent().width() )+'px' ); $(this).parent().css('left',''); }, modal: true, height: 'auto', width: '800px', title: ListingEditor.translateStr[mode], buttons: [ { text: '؟', id: 'listing-help', click: function() { window.open(ListingEditor.translateStr['help-page']);}}, {text: ListingEditor.translateStr['cancel'], click: function() {$(this).dialog('destroy').remove()}}, { text: ListingEditor.translateStr['preview'], click: function() { if(ListingEditor.validateForm()) { ListingEditor.preview(); } } }, { text: ListingEditor.translateStr['submit'], click: function() { if(ListingEditor.validateForm()) { ListingEditor.formToText(mode, sectionNumber); $(this).dialog('close'); } } }, ], open: function() { $('.ui-dialog-buttonpane').append('<div style="width:320px;padding-top:0.8em;font-size:xx-small;">'+ListingEditor.LICENSE_TEXT+'</div>'); if ($('#input-address').val() != '') { $('#geomap-link').attr('href', $('#geomap-link').attr('href') + '&location=' + encodeURIComponent($('#input-address').val())); } else if ($('#input-name').val() != '') { $('#geomap-link').attr('href', $('#geomap-link').attr('href') + '&location=' + encodeURIComponent($('#input-name').val())); } $('#input-address').change( function () { var link = $('#geomap-link').attr('href'); var index = link.indexOf('&location'); if (index < 0) index = link.length; $('#geomap-link').attr('href', link.substr(0,index) + '&location=' + encodeURIComponent($('#input-address').val())); }); // IE different behavior $(this).parent().css('right', ( $(window).innerWidth() - parseInt($(this).parent().css('left')) - $(this).parent().width() )+'px' ); $(this).parent().css('left',''); }, close: function() { $(this).dialog('destroy').remove()} }); }); }; ListingEditor.buttonGenerator = function (callback, summaryText, replaceSummary, image, title, alt, idSuffix) { var button = $('<span>', { style: 'padding-right: 2px; cursor: pointer;' }).click(callback).append( $('<img>').attr({ src: image, title: title, alt: alt }).on("error", function () { button.replaceWith($('<button>', { text: alt }).click(callback)); }) ); return button; }; ListingEditor.createForm = function (mode, type, listing) { var form = $('<form id="listing-editor">'); var leftFields = $('<table id="left-fields" style="display: inline-flex;">').appendTo(form); var rightFields = $('<table id="right-fields" style="display: inline-flex;">').appendTo(form); $('<div style="clear:both">').appendTo(form); //create form according to fields for (var key in ListingEditor.allFields) { var keyvalue = ListingEditor.allFields[key]; var row = $('<tr class="input-text">') .attr('id', 'div_' + key); var cell = $('<td/>').appendTo(row); var label = $('<label>').appendTo(cell) .text(keyvalue['label']) .attr('for', 'input-' + key); var cell = $('<td/>').appendTo(row); // input text for everything except content which gets textarea var parameter = key; if (key == 'type') { var subnode = $('<select id="option-type">').appendTo(cell); for (var n in ListingEditor.listingTypes) { var option = $('<option value="'+ListingEditor.listingTypes[n]+'">'); option.text(ListingEditor.listingTypesLabels[n]).appendTo(subnode); } if (mode == 'add') { subnode.val(ListingEditor.listingTypes[type]); listing[parameter] = ListingEditor.listingTypes[type]; } } else if (key != 'content') { var subnode = $('<input type="text" style="width: 100%;">').appendTo(cell); } else { var subnode = $('<textarea style="width: 100%;">').appendTo(cell) .attr('rows', keyvalue['rows']); } subnode.attr('placeholder', keyvalue['tip']) .attr('id', 'input-' + key); if (listing[parameter]) { subnode.val(listing[parameter]); } // customise hiding parameters if (listing[ListingEditor.allFields['type']['parameter']] == ListingEditor.listingTypes['sleep'] && key == 'hours') row.hide(); if (key == 'checkin' || key == 'checkout' || key == 'fax' || key == 'image') row.hide(); // some special form features if (key == 'type' && mode == 'edit') { var closedSpan = $('<span id="span_closed">'); var closedLabel = $('<label for="input-closed">').appendTo(closedSpan) .text(ListingEditor.translateStr['closed']); var closedInput = $('<input type="checkbox">').appendTo(closedSpan) .attr('id', 'input-closed'); cell.append(closedSpan); } if (key == 'price') { var currencySpan = $('<span id="span_currency">'); for (var i=0; i < ListingEditor.currencySigns.length; i++) { var currencyButton = $('<span class="currency-signs">') .html(' <u><a href="javascript:">'+ListingEditor.currencySigns[i]+'</a></u>' ) .click(function() { var caretPos = document.getElementById('input-price').selectionStart; var price = $('#input-price').val(); $('#input-price').val(price.substring(0, caretPos) + $(this).find('a').text() + price.substring(caretPos) ); }); currencySpan.append(currencyButton); } cell.append(currencySpan); } if (key == 'lat') { var latlngStr = '?'; if ($('#geodata').length) { var latlng = $('#geodata').text().split('; '); latlngStr += 'lat='+latlng[0]+'&lon='+latlng[1]+'&zoom=15'; } cell.append(' <u><a id="geomap-link" target="_blank" ' +'href="http://maps.wikivoyage-ev.org/w/geomap.php'+latlngStr+'">' +ListingEditor.translateStr['geomap']+'</a></u>'); } if (key == 'content') { var tb = $('<table/>').css('width','100%'); $(row.children()[0]).css('width','1px'); tb.append(row); form.append(tb); } else if (ListingEditor.allFields[key]['right'] == true) { rightFields.append(row); } else { leftFields.append(row); } } if(typeof persianWikiTools != 'undefined' && typeof persianWikiTools.superToolMove != 'undefined') { form.find('input[type=text]').each(function(){ var me = $(this); me.css('width','88%'); var btn = ListingEditor.buttonGenerator( function () { var me = $(this); var target = $(me.parent().children()[0]); target.val(persianWikiTools.superToolMove(target.val())); }, 'تصحیح خودکار', false, ListingEditor.ToolIcon, 'تصحیح خودکار', 'تصحیح خودکار', 'super-tool' ); btn.insertAfter(me); }); form.find('textarea').each(function(){ var me = $(this); me.parent().parent().append($('<td/>').css('width','1px')); var btn = ListingEditor.buttonGenerator( function () { var me = $(this); var target = $($(me.parent().parent().children()[1]).children()[0]); target.val(persianWikiTools.superToolMove(target.val())); }, 'تصحیح خودکار', false, ListingEditor.ToolIcon, 'تصحیح خودکار', 'تصحیح خودکار', 'super-tool' ); $(me.parent().parent().children()[2]).append(btn); }); } //form.append($('<div style="text-align: center; font-size: 120%; padding: 10px; margin: 10px; color: rgb(255, 20, 28); border: 1px solid rgb(255, 254, 41); background-color: rgb(249, 254, 201); border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px;">قبل از ذخیره کردن، بر روی دکمهٔ <img alt="تصحیح خودکار" title="تصحیح خودکار" src="' + ListingEditor.ToolIcon + '"> در هر بخش کلیک کنید تا تصحیحات لازم انجام شود.</div>')); if (mw.config.get('wgUserName') == null) form.append($('<div style="background-color: rgb(255, 228, 225); color: rgb(0, 0, 0); border: 1px solid rgb(234, 164, 215); border-radius: 10px; -webkit-border-radius: 10px; -moz-border-radius: 10px; padding: 10px; margin: 10px;"><span style="color: #FF0000;">توجه:</span> شما با نام کاربری وارد نشده\u200cاید، ویرایش شما با آی\u200cپی شما ثبت می\u200cشود، می\u200cتوانید ابتدا <a href="//fa.wikivoyage.org/wiki/Special:Login/signup" target="_blank">ثبت نام کنید</a>، اگر در حال حاضر در ویکی\u200cسفر و یا در دیگر پروژه\u200cهای بنیاد ویکی\u200cمدیا حساب کاربری دارید می\u200cتوانید به سیستم <a href="//fa.wikivoyage.org/wiki/Special:Login" target="_blank">وارد شوید</a>، برای اطلاعات بیشتر <a href="//fa.wikivoyage.org/wiki/%D9%88%DB%8C%DA%A9%DB%8C%E2%80%8C%D8%B3%D9%81%D8%B1:%D9%88%D8%B1%D9%88%D8%AF_%DB%8C%DA%A9%D9%BE%D8%A7%D8%B1%DA%86%D9%87" target="_blank">ویکی\u200cسفر:ورود یکپارچه</a> را بخوانید.</div>')); return form; }; ListingEditor.validateForm = function () { //TODO more form validation? if ($('#input-name').val() == '' && $('#input-address').val() == '' && $('#input-alt').val() == '') { alert(ListingEditor.translateStr['validationalert']); return false; } $('#input-content').val($.trim($('#input-content').val()).replace(/\n+/g, ' ')); var webRegex = new RegExp('^https?://', 'i'); var url = $('#input-url').val(); if (!webRegex.test(url) && url != '') { $('#input-url').val('http://' + url); } return true; }; ListingEditor.upperCaseFirst = function (str) { str = str.toLowerCase().replace(/\b[a-z]/g, function(letter) { return letter.toUpperCase(); }); return str; }; ListingEditor.preview = function () { var listing = {}; for ( var key in ListingEditor.allFields ) { var parameter = ListingEditor.allFields[key]['parameter']; listing[parameter]= $("#input-"+key).val(); } if (listing[ListingEditor.allFields['type']['parameter']] != ListingEditor.listingTypes.sleep) { listing[ListingEditor.allFields['checkin']['parameter']] = null; listing[ListingEditor.allFields['checkout']['parameter']] = null; } else { listing[ListingEditor.allFields['hours']['parameter']] = null; } var text = ListingEditor.listingToStr(listing); $.ajax({ url: mw.config.get('wgScriptPath') + '/api.php?' + $.param({ action: 'parse', prop: 'text', contentmodel: 'wikitext', format: 'json', 'text': text, }), beforeSend: function (xhr) { if($('#listing-editor .preview-section').length == 0) { $('#listing-editor').append($('<hr/>')); $('#listing-editor').append($('<h5/>').text(ListingEditor.translateStr['preview'])); $('#listing-editor').append($('<div/>') .attr('class','preview-section') .append($('<div/>') .attr('class','preview-content') ) .css('background-color','#fff') .css('border-radius','10px') .css('-moz-border-radius','10px') .css('-webkit-border-radius','10px') .css('padding','10px') ); } var loading = $('<span/>'); loading.attr('class','listing_previewing'); var img = $('<img/>'); img.attr('src',ListingEditor.loadingIcon); loading.append(img); loading.prepend(' '); $('#listing-editor .preview-section').prepend(loading); }, error: function(jqXHR, txt){ $('#listing-editor .preview-section .listing_previewing').remove(); }, success: function (data) { $('#listing-editor .preview-section .listing_previewing').remove(); $('#listing-editor .preview-section .preview-content').html(data.parse.text['*']); }, }); }; ListingEditor.formToText = function (mode, number) { var listing = {}; for ( var key in ListingEditor.allFields ) { var parameter = ListingEditor.allFields[key]['parameter']; listing[parameter]= $("#input-"+key).val(); } if (listing[ListingEditor.allFields['type']['parameter']] != ListingEditor.listingTypes.sleep) { listing[ListingEditor.allFields['checkin']['parameter']] = null; listing[ListingEditor.allFields['checkout']['parameter']] = null; } else { listing[ListingEditor.allFields['hours']['parameter']] = null; } var text = ListingEditor.listingToStr(listing); var summary = '/* ' + ListingEditor.sectionTitle + ' */ '; if (mode == 'add') { summary += ListingEditor.translateStr['added']; var index = ListingEditor.sectionText.indexOf('==='); if ( index == 0 ) { index = ListingEditor.sectionText.indexOf('===='); } if ( index > 0 ) { ListingEditor.sectionText = ListingEditor.sectionText.substr(0, index) + '* ' + text + '\n' + ListingEditor.sectionText.substr(index); } else { ListingEditor.sectionText += '\n'+ '* ' +text; } } else { if ($('#input-closed').is(':checked')) { text = ''; summary += ListingEditor.translateStr['removed']; var listRegex = new RegExp('\\n\\*+\\s?'+ListingEditor.replaceSpecial(ListingEditor.listingText)); ListingEditor.sectionText = ListingEditor.sectionText.replace(listRegex, ListingEditor.listingText); } else { summary += ListingEditor.translateStr['updated']; } ListingEditor.sectionText = ListingEditor.sectionText.replace(ListingEditor.listingText, text); } summary += $("#input-name").val(); ListingEditor.saveForm(summary, ListingEditor.sectionText, number, '', ''); return; }; ListingEditor.savingForm = function () { var progress = $('<div id="progress-dialog">'+ListingEditor.translateStr['saving']+'...</div>'); progress.dialog({ modal: true, height: 100, width: 300, title: '' }); $(".ui-dialog-titlebar").hide(); }; ListingEditor.saveForm = function (summary, content, number, cid, answer) { for (var key in ListingEditor.replacements) { var val = ListingEditor.replacements[key]; content = content.replace(key, val); } ListingEditor.replacements = {}; $.ajax( { url: mw.util.wikiScript( 'api' ), data: { 'format': 'json', 'action': 'edit', 'title': mw.config.get('wgPageName'), 'section': number, 'token': mw.user.tokens.get( 'csrfToken' ), 'text': content, 'summary': summary, 'captchaid': cid, 'captchaword': answer }, type: 'POST', datatype: 'json', success: function( data ) { if ( data && data.edit && data.edit.result == 'Success' ) { window.location.reload(); // reload page if edit was successful } else if ( data && data.error ) { alert( 'خطا: API کد مقابل را برگرداند "' + data.error.code + '": ' + data.error.info ); } else if ( data && data.edit.spamblacklist ) { alert( 'خطا: "'+ data.edit.spamblacklist + '" در فهرست سیاه قرار دارد' ); $('#progress-dialog').dialog('destroy').remove(); } else if ( data && data.edit.captcha ) { var captcha = $('<div id="captcha-dialog">').text(ListingEditor.translateStr['external-links']); var image = $('<img class="fancycaptcha-image">') .attr('src', data.edit.captcha.url) .appendTo(captcha); var label = $('<label for="input-captcha">').text(ListingEditor.translateStr['enter-captcha']).appendTo(captcha); var input = $('<input id="input-captcha" type="text">').appendTo(captcha); captcha.dialog({ title: ListingEditor.translateStr['enter-captcha'], buttons: [ { text: ListingEditor.translateStr['submit'], click: function() { ListingEditor.saveForm(summary, content, number, data.edit.captcha.id, $('#input-captcha').val()); } }, { text: ListingEditor.translateStr['cancel'], click: function() { $(this).dialog('destroy').remove(); $('#progress-dialog').dialog('destroy').remove(); }} ] }); } else { alert( 'خطا: نتیجه نامعلوم از API دریافت شد.' ); } }, error: function( xhr ) { alert( 'خطا: درخواست ناموفق بود.' ); } } ) ListingEditor.savingForm(); }; ListingEditor.listingToStr = function (listing) { var saveStr = '{{'+listing[ListingEditor.allFields['type']['parameter']]; if (!ListingEditor.inlineListing && ListingEditor.allFields['type']['newline']) saveStr += '\n'; for ( var key in ListingEditor.allFields ) { var parameter = ListingEditor.allFields[key]['parameter']; if (key != 'type' && listing[parameter] != null) { if (ListingEditor.inlineListing) { if (listing[parameter] != '') { saveStr += ' | ' + parameter + '=' +listing[parameter]; } } else { if (key != 'image' || listing[ListingEditor.allFields['image']['parameter']] != '') { saveStr +='| '+parameter+ '=' + listing[parameter]; } if (ListingEditor.allFields[key]['newline']) { saveStr += '\n'; } else { saveStr += ' '; } } } } saveStr += '}}'; return saveStr; }; ListingEditor.init = function() { var namespace = mw.config.get( 'wgNamespaceNumber' ); if (namespace != 0 && namespace != 2 && namespace != 4) { return; } if ( mw.config.get('wgAction') != 'view' || $('#mw-revision-info').length || mw.config.get('wgCurRevisionId') != mw.config.get('wgRevisionId') || $('#ca-viewsource').length ) { return; } ListingEditor.wrapContent(); ListingEditor.addListingButtons(); ListingEditor.addEditButtons(); }; // only run on supported skins // (on mobile this breaks section collapsing) if ( mw.config.get( 'skin' ) !== 'minerva' ) { $(ListingEditor.init); }