Замечание: Возможно, после публикации вам придётся очистить кэш своего браузера, чтобы увидеть изменения.
- Firefox / Safari: Удерживая клавишу Shift, нажмите на панели инструментов Обновить либо нажмите Ctrl+F5 или Ctrl+R (⌘+R на Mac)
- Google Chrome: Нажмите Ctrl+Shift+R (⌘+Shift+R на Mac)
- Edge: Удерживая Ctrl, нажмите Обновить либо нажмите Ctrl+F5
- Opera: Нажмите Ctrl+F5.
mw.loader.using(['mediawiki.api'], function() { var commonMessages = { addTitle: 'Добавить объект', editTitle: 'Редактировать объект', submitApiError: 'Во время сохранения листинга на сервере произошла ошибка, пожайлуста, попробуйте сохранить ещё раз', submitBlacklistError: 'Ошибка: текст содержит ссылку из чёрного списка, пожайлуста, удалите её и попробуйте сохранить снова', submitUnknownError: 'Ошибка: при попытке сохранить листинг произошла неизвестная ошибка, пожайлуста, попробуйте сохранить ещё раз', submitHttpError: 'Ошибка: сервер сообщил о HTTP ошибке, возникшей во время сохранения листинга, пожайлуста, попробуйте сохранить ещё раз', submitEmptyError: 'Ошибка: сервер вернул пустой ответ при попытке сохранить листинг, пожайлуста, попробуйте сохранить ещё раз', enterCaptcha: 'Введите CAPTCHA', changesSummaryAdded: 'Добавлен объект', changesSummaryUpdated: 'Обновлён объект', captchaSubmit: 'Продолжить', captchaCancel: 'Отмена' }; var StringUtils = { contains: function contains(string, substring) { return string.indexOf(substring) >= 0; }, trim: function trim(string) { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim return string.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } }; var ArrayUtils = { hasElement: function hasElement(array, element) { return array.indexOf(element) >= 0; }, inArray: function inArray(element, array) { return this.hasElement(array, element); } }; var AsyncUtils = { runSequence: function runSequence(functions, onSuccess, results) { if (!results) { results = []; } if (functions.length > 0) { var firstFunction = functions[0]; firstFunction(function (result) { results.push(result); setTimeout( // hack to break recursion chain function () { AsyncUtils.runSequence(functions.slice(1), onSuccess, results); }, 0); }); } else { onSuccess(results); } }, runChunks: function runChunks(runSingleChunkFunction, maxChunkSize, data, onSuccess) { var chunkRunFunctions = []; var _loop = function _loop(dataNumStart) { var dataChunk = data.slice(dataNumStart, dataNumStart + maxChunkSize); chunkRunFunctions.push(function (onSuccess) { return runSingleChunkFunction(dataChunk, onSuccess); }); }; for (var dataNumStart = 0; dataNumStart < data.length; dataNumStart += maxChunkSize) { _loop(dataNumStart); } this.runSequence(chunkRunFunctions, function (chunkResults) { var result = chunkResults.reduce(function (current, total) { return total.concat(current); }, []); onSuccess(result); }); } }; var ObjectUtils = { merge: function merge(obj1, obj2) { var result = {}; for (var prop in obj1) { if (obj1.hasOwnProperty(prop)) { result[prop] = obj1[prop]; } } for (var _prop in obj2) { if (obj2.hasOwnProperty(_prop)) { result[_prop] = obj2[_prop]; } } return result; } }; var ValidationUtils = { normalizeUrl: function normalizeUrl(url) { var webRegex = new RegExp('^https?://', 'i'); if (!webRegex.test(url) && url !== '') { return 'http://' + url; } else { return url; } } }; var MediaWikiPage = { getPageName: function getPageName() { return mw.config.get('wgPageName'); }, isDiffMode: function isDiffMode() { return $('table.diff').length > 0; }, isLastRevision: function isLastRevision() { return mw.config.get('wgCurRevisionId') === mw.config.get('wgRevisionId'); }, isViewAction: function isViewAction() { return mw.config.get('wgAction') === 'view'; }, isViewSourceMode: function isViewSourceMode() { return $('#ca-viewsource').length > 0; }, isViewSpecificRevisionMode: function isViewSpecificRevisionMode() { return $('#mw-revision-info').length > 0; }, isRegularNamespace: function isRegularNamespace() { var namespace = mw.config.get('wgNamespaceNumber'); return namespace === 0 || namespace === 2 || namespace === 4; } }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var CaptchaDialog = function () { function CaptchaDialog(captchaImgSrc, onCaptchaSubmit) { var _this = this; _classCallCheck(this, CaptchaDialog); this._captcha = $('<div id="captcha-dialog">'); $('<img class="fancycaptcha-image">').attr('src', captchaImgSrc).appendTo(this._captcha); $('<input id="input-captcha" type="text">').appendTo(this._captcha); this._captcha.dialog({ modal: true, title: commonMessages.enterCaptcha, buttons: [{ text: commonMessages.captchaSubmit, click: function click() { onCaptchaSubmit($('#input-captcha').val()); _this.destroy(); } }, { text: commonMessages.captchaCancel, click: function click() { return _this.destroy(); } }] }); } _createClass(CaptchaDialog, [{ key: 'destroy', value: function destroy() { this._captcha.dialog('destroy').remove(); } }]); return CaptchaDialog; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var ListingSection = function () { function ListingSection(headerElement, sectionIndex) { _classCallCheck(this, ListingSection); this._headerElement = headerElement; this._sectionIndex = sectionIndex; } _createClass(ListingSection, [{ key: 'getHeaderElement', value: function getHeaderElement() { return this._headerElement; } }, { key: 'getSectionIndex', value: function getSectionIndex() { return this._sectionIndex; } }]); return ListingSection; }(); var ListingTable = function () { function ListingTable(tableElement, sectionIndex, listingIndex) { _classCallCheck(this, ListingTable); this._tableElement = tableElement; this._sectionIndex = sectionIndex; this._listingIndex = listingIndex; } _createClass(ListingTable, [{ key: 'getTableElement', value: function getTableElement() { return this._tableElement; } }, { key: 'getSectionIndex', value: function getSectionIndex() { return this._sectionIndex; } }, { key: 'getListingIndex', value: function getListingIndex() { return this._listingIndex; } }]); return ListingTable; }(); var ListingPageElements = function () { function ListingPageElements(sections, listingTables) { _classCallCheck(this, ListingPageElements); this._sections = sections; this._listingTables = listingTables; } /** * @returns {ListingSection[]} */ _createClass(ListingPageElements, [{ key: 'getSections', value: function getSections() { return this._sections; } }, { key: 'getListingTables', value: function getListingTables() { return this._listingTables; } }]); return ListingPageElements; }(); var ListingEditorUtils = { isEditablePage: function isEditablePage() { return MediaWikiPage.isRegularNamespace() && MediaWikiPage.isViewAction() && MediaWikiPage.isLastRevision() && !MediaWikiPage.isDiffMode() && !MediaWikiPage.isViewSpecificRevisionMode() && !MediaWikiPage.isViewSourceMode(); }, /** * @returns {ListingPageElements} */ getListingPageElements: function getListingPageElements() { var pageBodyContentElement = $('.mw-parser-output'); var currentSectionIndex = 0; var currentListingIndex = 0; var sections = []; var listingTables = []; function isTableOfContentsHeader(headerElement) { return headerElement.parents('.toc').length > 0; } // Here we add buttons to: // - add new listing - for each section header // - edit existing listing - for each existing listing // // - section index, to which we are going to add new listing // - section index and listing index (within a section) for listing which we are going to edit // To calculate section index and listing index, we iterate over all section header and listing // table elements sequentially (in the same order as we have them in HTML). // When we meet header - we consider that new section is started and increase current section index, // and reset current listing index (listings are enumerated within section). All listings belong // to that section until we meet the next header. // When we meet listing table - we increase current listing index. pageBodyContentElement.find('h1, h2, h3, h4, h5, h6, table.monument').each(function () { if (ArrayUtils.inArray(this.tagName, ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'])) { var headerElement = $(this); if (!isTableOfContentsHeader(headerElement)) { currentSectionIndex++; currentListingIndex = 0; sections.push(new ListingSection(headerElement, currentSectionIndex)); } } else if (this.tagName === 'TABLE') { var listingTable = $(this); listingTables.push(new ListingTable(listingTable, currentSectionIndex, currentListingIndex)); currentListingIndex++; } }); return new ListingPageElements(sections, listingTables); } }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var ListingEditorButtonEdit = function () { function ListingEditorButtonEdit(button, listingTable) { _classCallCheck(this, ListingEditorButtonEdit); this._button = button; this._listingTable = listingTable; } _createClass(ListingEditorButtonEdit, [{ key: 'click', value: function click(handler) { var _this = this; this._button.click(function () { return handler(_this._listingTable); }); } }]); return ListingEditorButtonEdit; }(); var ListingEditorButtonAdd = function () { function ListingEditorButtonAdd(button, section) { _classCallCheck(this, ListingEditorButtonAdd); this._button = button; this._section = section; } _createClass(ListingEditorButtonAdd, [{ key: 'click', value: function click(handler) { var _this2 = this; this._button.click(function () { return handler(_this2._section); }); } }]); return ListingEditorButtonAdd; }(); var ListingEditorButtons = { /** * * @param listingTable ListingTable */ createListingEditButton: function createListingEditButton(listingTable) { var editListingButton = $('<span class="vcard-edit-button noprint" style="padding-left: 5px;">'); editListingButton.html('<a href="javascript:" class="icon-pencil" title="Редактировать">Редактировать</a>'); var nameElement = listingTable.getTableElement().find('span.monument-name').first(); if (nameElement) { nameElement.append(editListingButton); } return new ListingEditorButtonEdit(editListingButton, listingTable); }, createListingAddButton: function createListingAddButton(section) { var sectionAddButton = $('<a href="javascript:">добавить</a>'); var bracketStart = $('<span class="mw-editsection-bracket">[</span>'); var bracketEnd = $('<span class="mw-editsection-bracket">]</span>'); section.getHeaderElement().append($('<span class="mw-editsection"/>').append(bracketStart).append(sectionAddButton).append(bracketEnd)); return new ListingEditorButtonAdd(sectionAddButton, section); } }; var MAX_DIALOG_WIDTH = 1200; var LICENSE_TEXT = 'Нажимая кнопку «Сохранить», вы соглашаетесь с <a class="external" target="_blank" href="https://wikimediafoundation.org/wiki/Terms_of_Use/ru">условиями использования</a>, а также соглашаетесь на неотзывную публикацию по лицензии <a class="external" target="_blank" href="https://en.wikipedia.org/wiki/ru:Википедия:Текст_Лицензии_Creative_Commons_Attribution-ShareAlike_3.0_Unported">CC-BY-SA 3.0</a>.'; var ListingEditorDialog = { showDialog: function showDialog(formElement, dialogTitle, onSubmit, onCancel, onHelp) { var windowWidth = $(window).width(); var dialogWidth = windowWidth > MAX_DIALOG_WIDTH ? MAX_DIALOG_WIDTH : 'auto'; mw.loader.using(['jquery.ui'], function () { formElement.dialog({ modal: true, height: 'auto', width: dialogWidth, title: dialogTitle, dialogClass: 'listing-editor-dialog', buttons: [{ text: '?', id: 'listing-help', click: function click() { onHelp(); } }, { text: "Сохранить", click: function click() { onSubmit(); } }, { text: "Отмена", click: function click() { onCancel(); } }], create: function create() { $('.ui-dialog-buttonpane').append('<div class="listing-license">' + LICENSE_TEXT + '</div>'); } }); }); } }; var ListingEditorFormComposer = { createInputFormRow: function createInputFormRow(inputElementId, labelText) { var rowElement = $('<tr>'); var label = $('<label>', { 'for': inputElementId, 'html': labelText }); var labelColumn = $('<td>', { 'class': "editor-label-col", 'style': "width: 200px" }).append(label); var inputColumnElement = $('<td>'); rowElement.append(labelColumn).append(inputColumnElement); return { 'rowElement': rowElement, 'inputColumnElement': inputColumnElement }; }, createInputFormRowCheckbox: function createInputFormRowCheckbox(inputElementId, labelText) { var row = this.createInputFormRow(inputElementId, labelText); var inputElement = $('<input>', { 'type': 'checkbox', 'id': inputElementId }); row.inputColumnElement.append(inputElement); return { 'rowElement': row.rowElement, 'inputElement': inputElement }; }, createInputFormRowSelect: function createInputFormRowSelect(inputElementId, labelText, options) { var row = this.createInputFormRow(inputElementId, labelText); var inputElement = $('<select>', { 'id': inputElementId }); options.forEach(function (option) { var optionElement = $('<option>', { 'value': option.value, 'html': option.title }); inputElement.append(optionElement); }); row.inputColumnElement.append(inputElement); return { 'rowElement': row.rowElement, 'inputElement': inputElement }; }, createInputFormRowText: function createInputFormRowText(inputElementId, labelText, placeholderText, partialWidth, insertSymbols) { if (!placeholderText) { placeholderText = ''; } var row = this.createInputFormRow(inputElementId, labelText); var inputElement = $('<input>', { 'type': 'text', 'class': partialWidth ? 'editor-partialwidth' : 'editor-fullwidth', 'style': insertSymbols ? 'width: 90%' : '', 'placeholder': placeholderText, 'id': inputElementId }); row.inputColumnElement.append(inputElement); if (insertSymbols) { var buttonInsertQuotes = $('<a>', { 'class': 'name-quotes-template', href: 'javascript:;', html: '«»' }); var buttonInsertDash = $('<a>', { 'class': 'name-dash-template', href: 'javascript:;', html: '—' }); InputInsertSymbols.addDashInsertHandler(buttonInsertDash, inputElement); InputInsertSymbols.addQuotesInsertHandler(buttonInsertQuotes, inputElement); row.inputColumnElement.append(' '); row.inputColumnElement.append(buttonInsertQuotes); row.inputColumnElement.append(' '); row.inputColumnElement.append(buttonInsertDash); } return { 'rowElement': row.rowElement, 'inputElement': inputElement }; }, createRowDivider: function createRowDivider() { return $('<tr>').append($('<td>', { 'colspan': "2" }).append($('<div>', { 'class': "listing-divider", 'style': "margin: 3px 0" }))); }, createRowLink: function createRowLink(linkText) { var linkElement = $("<a>", { 'href': 'javascript:;', 'html': linkText }); var rowElement = $('<tr>').append($('<td>')).append($('<td>').append(linkElement)); return { 'rowElement': rowElement, 'linkElement': linkElement }; }, createChangesDescriptionRow: function createChangesDescriptionRow() { var inputChangesSummary = $('<input>', { 'type': "text", 'class': "editor-partialwidth", 'placeholder': "что именно было изменено", 'id': "input-summary" }); var inputIsMinorChanges = $('<input>', { 'type': "checkbox", 'id': "input-minor" }); var labelChangesSummary = $('<label>', { 'for': "input-summary", 'html': 'Описание изменений' }); var labelIsMinorChanges = $('<label>', { 'for': "input-minor", 'class': "listing-tooltip", 'title': "Установите галочку, если изменение незначительное, например, исправление опечатки", 'html': 'незначительное изменение?' }); var spanIsMinorChanges = $('<span>', { id: "span-minor" }); spanIsMinorChanges.append(inputIsMinorChanges).append(labelIsMinorChanges); var row = $('<tr>'); row.append($('<td>', { 'class': "editor-label-col", style: "width: 200px" }).append(labelChangesSummary)); row.append($('<td>').append(inputChangesSummary).append(spanIsMinorChanges)); return { 'row': row, 'inputChangesSummary': inputChangesSummary, 'inputIsMinorChanges': inputIsMinorChanges }; }, createObjectDescriptionRow: function createObjectDescriptionRow() { var inputDescription = $('<textarea>', { 'rows': "4", 'class': "editor-fullwidth", 'placeholder': "описание объекта", 'id': "input-description" }); var labelDescription = $('<label>', { 'for': "input-description", 'html': "Описание" }); var row = $('<tr>'); row.append($('<td>', { 'class': "editor-label-col", 'style': "width: 200px" }).append(labelDescription)); row.append($('<td>').append(inputDescription)); return { 'row': row, 'inputDescription': inputDescription }; }, createTableFullWidth: function createTableFullWidth() { var tableElement = $('<table>', { 'class': 'editor-fullwidth' }); var wrapperElement = $('<div>'); wrapperElement.append(tableElement); return { 'wrapperElement': wrapperElement, 'tableElement': tableElement }; }, createTableTwoColumns: function createTableTwoColumns() { var leftTableElement = $('<table>', { 'class': "editor-fullwidth" }); var rightTableElement = $('<table>', { 'class': "editor-fullwidth" }); var wrapperElement = $('<div>'); wrapperElement.append($('<div>', { 'class': 'listing-col listing-span_1_of_2' }).append(leftTableElement)); wrapperElement.append($('<div>', { 'class': 'listing-col listing-span_1_of_2' }).append(rightTableElement)); return { 'wrapperElement': wrapperElement, 'leftTableElement': leftTableElement, 'rightTableElement': rightTableElement }; }, createForm: function createForm() { var formElement = $('<form id="listing-editor">'); formElement.append($('<br>')); return { 'formElement': formElement }; } }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Region = function () { function Region(id, title) { _classCallCheck(this, Region); this._id = id; this._title = title; } _createClass(Region, [{ key: "getId", value: function getId() { return this._id; } }, { key: "getTitle", value: function getTitle() { return this._title; } }]); return Region; }(); var regions = [new Region("", "не задан"), new Region("ru-ad", "Адыгея"), new Region("ru-ba", "Башкортостан"), new Region("ru-bu", "Бурятия"), new Region("ru-al", "Алтай"), new Region("ru-da", "Дагестан"), new Region("ru-in", "Ингушетия"), new Region("ru-kb", "Кабардино-Балкария"), new Region("ru-kl", "Калмыкия"), new Region("ru-kc", "Карачаево-Черкесия"), new Region("ru-krl", "Карелия"), new Region("ru-ko", "республика Коми"), new Region("ru-me", "Марий Эл"), new Region("ru-mo", "Мордовия"), new Region("ru-sa", "Якутия (Саха)"), new Region("ru-se", "Северная Осетия"), new Region("ru-ta", "Татарстан"), new Region("ru-ty", "Тува"), new Region("ru-ud", "Удмуртия"), new Region("ru-kk", "Хакасия"), new Region("ru-ce", "Чеченская республика"), new Region("ru-chv", "Чувашия"), new Region("ru-alt", "Алтайский край"), new Region("ru-kda", "Краснодарский край"), new Region("ru-kya", "Красноярский край"), new Region("ru-pri", "Приморский край"), new Region("ru-sta", "Ставропольский край"), new Region("ru-kha", "Хабаровский край"), new Region("ru-amu", "Амурская область"), new Region("ru-ark", "Архангельская область"), new Region("ru-ast", "Астраханская область"), new Region("ru-bel", "Белгородская область"), new Region("ru-bry", "Брянская область"), new Region("ru-vla", "Владимирская область"), new Region("ru-vgg", "Волгоградская область"), new Region("ru-vol", "Вологодская область"), new Region("ru-vor", "Воронежская область"), new Region("ru-iva", "Ивановская область"), new Region("ru-irk", "Иркутская область"), new Region("ru-kal", "Калининградская область"), new Region("ru-klu", "Калужская область"), new Region("ru-kam", "Камчатский край"), new Region("ru-kem", "Кемеровская область"), new Region("ru-kir", "Кировская область"), new Region("ru-kos", "Костромская область"), new Region("ru-kgn", "Курганская область"), new Region("ru-krs", "Курская область"), new Region("ru-len", "Ленинградская область"), new Region("ru-lip", "Липецкая область"), new Region("ru-mag", "Магаданская область"), new Region("ru-mos", "Московская область"), new Region("ru-mur", "Мурманская область"), new Region("ru-niz", "Нижегородская область"), new Region("ru-ngr", "Новгородская область"), new Region("ru-nvs", "Новосибирская область"), new Region("ru-oms", "Омская область"), new Region("ru-ore", "Оренбургская область"), new Region("ru-orl", "Орловская область"), new Region("ru-pnz", "Пензенская область"), new Region("ru-per", "Пермский край"), new Region("ru-psk", "Псковская область"), new Region("ru-ros", "Ростовская область"), new Region("ru-rya", "Рязанская область"), new Region("ru-sam", "Самарская область"), new Region("ru-sar", "Саратовская область"), new Region("ru-sak", "Сахалинская область"), new Region("ru-sve", "Свердловская область"), new Region("ru-smo", "Смоленская область"), new Region("ru-tam", "Тамбовская область"), new Region("ru-tve", "Тверская область"), new Region("ru-tom", "Томская область"), new Region("ru-tul", "Тульская область"), new Region("ru-tyu", "Тюменская область"), new Region("ru-uly", "Ульяновская область"), new Region("ru-che", "Челябинская область"), new Region("ru-zab", "Забайкальский край"), new Region("ru-yar", "Ярославская область"), new Region("ru-mow", "Москва"), new Region("ru-spb", "Санкт-Петербург"), new Region("ru-jew", "Еврейская автономная область"), new Region("ru-km", "Крым"), new Region("ru-nen", "Ненецкий автономный округ"), new Region("ru-khm", "Ханты-Мансийский автономный округ"), new Region("ru-chu", "Чукотский автономный округ"), new Region("ru-yam", "Ямало-Ненецкий автономный округ"), new Region("ru-sev", "Севастополь")]; var api = new mw.Api(); var MediaWikiPageWikitext = { loadSectionWikitext: function loadSectionWikitext(sectionIndex, onSuccess) { $.ajax({ url: mw.util.wikiScript(''), data: { title: mw.config.get('wgPageName'), action: 'raw', section: sectionIndex }, cache: false }).done(function (data) { onSuccess(data); }).fail(function (jqXHR, textStatus, errorThrown) { alert('Ошибка при получении исходного вики-текста статьи: ' + textStatus + ' ' + errorThrown); }); }, saveSectionWikitext: function saveSectionWikitext(sectionIndex, sectionWikitext, changesSummary, changesIsMinor, captchaId, captchaAnswer, onSuccess, onFailure, onCaptcha) { var editPayload = { action: "edit", title: mw.config.get("wgPageName"), section: sectionIndex, text: sectionWikitext, summary: changesSummary, captchaid: captchaId, captchaword: captchaAnswer }; if (changesIsMinor) { $.extend(editPayload, { minor: 'true' }); } api.postWithToken("csrf", editPayload).done(function (data) { if (data && data.edit && data.edit.result === 'Success') { onSuccess(); } else if (data && data.error) { onFailure(commonMessages.submitApiError + ' "' + data.error.code + '": ' + data.error.info); } else if (data && data.edit.spamblacklist) { onFailure(commonMessages.submitBlacklistError + ': ' + data.edit.spamblacklist); } else if (data && data.edit.captcha) { onCaptcha(data.edit.captcha.url, data.edit.captcha.id); } else { onFailure(commonMessages.submitUnknownError); } }).fail(function (code, result) { if (code === "http") { onFailure(commonMessages.submitHttpError + ': ' + result.textStatus); } else if (code === "ok-but-empty") { onFailure(commonMessages.submitEmptyError); } else { onFailure(commonMessages.submitUnknownError + ': ' + code); } }); }, getSectionName: function getSectionName(sectionWikitext) { var HEADING_REGEX = /^=+\s*([^=]+)\s*=+\s*\n/; var result = HEADING_REGEX.exec(sectionWikitext); return result !== null ? result[1].trim() : ""; } }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Region = function () { function Region(id, title) { _classCallCheck(this, Region); this._id = id; this._title = title; } _createClass(Region, [{ key: "getId", value: function getId() { return this._id; } }, { key: "getTitle", value: function getTitle() { return this._title; } }]); return Region; }(); var regions = [new Region("", "не задан"), new Region("ru-ad", "Адыгея"), new Region("ru-ba", "Башкортостан"), new Region("ru-bu", "Бурятия"), new Region("ru-al", "Алтай"), new Region("ru-da", "Дагестан"), new Region("ru-in", "Ингушетия"), new Region("ru-kb", "Кабардино-Балкария"), new Region("ru-kl", "Калмыкия"), new Region("ru-kc", "Карачаево-Черкесия"), new Region("ru-krl", "Карелия"), new Region("ru-ko", "республика Коми"), new Region("ru-me", "Марий Эл"), new Region("ru-mo", "Мордовия"), new Region("ru-sa", "Якутия (Саха)"), new Region("ru-se", "Северная Осетия"), new Region("ru-ta", "Татарстан"), new Region("ru-ty", "Тува"), new Region("ru-ud", "Удмуртия"), new Region("ru-kk", "Хакасия"), new Region("ru-ce", "Чеченская республика"), new Region("ru-chv", "Чувашия"), new Region("ru-alt", "Алтайский край"), new Region("ru-kda", "Краснодарский край"), new Region("ru-kya", "Красноярский край"), new Region("ru-pri", "Приморский край"), new Region("ru-sta", "Ставропольский край"), new Region("ru-kha", "Хабаровский край"), new Region("ru-amu", "Амурская область"), new Region("ru-ark", "Архангельская область"), new Region("ru-ast", "Астраханская область"), new Region("ru-bel", "Белгородская область"), new Region("ru-bry", "Брянская область"), new Region("ru-vla", "Владимирская область"), new Region("ru-vgg", "Волгоградская область"), new Region("ru-vol", "Вологодская область"), new Region("ru-vor", "Воронежская область"), new Region("ru-iva", "Ивановская область"), new Region("ru-irk", "Иркутская область"), new Region("ru-kal", "Калининградская область"), new Region("ru-klu", "Калужская область"), new Region("ru-kam", "Камчатский край"), new Region("ru-kem", "Кемеровская область"), new Region("ru-kir", "Кировская область"), new Region("ru-kos", "Костромская область"), new Region("ru-kgn", "Курганская область"), new Region("ru-krs", "Курская область"), new Region("ru-len", "Ленинградская область"), new Region("ru-lip", "Липецкая область"), new Region("ru-mag", "Магаданская область"), new Region("ru-mos", "Московская область"), new Region("ru-mur", "Мурманская область"), new Region("ru-niz", "Нижегородская область"), new Region("ru-ngr", "Новгородская область"), new Region("ru-nvs", "Новосибирская область"), new Region("ru-oms", "Омская область"), new Region("ru-ore", "Оренбургская область"), new Region("ru-orl", "Орловская область"), new Region("ru-pnz", "Пензенская область"), new Region("ru-per", "Пермский край"), new Region("ru-psk", "Псковская область"), new Region("ru-ros", "Ростовская область"), new Region("ru-rya", "Рязанская область"), new Region("ru-sam", "Самарская область"), new Region("ru-sar", "Саратовская область"), new Region("ru-sak", "Сахалинская область"), new Region("ru-sve", "Свердловская область"), new Region("ru-smo", "Смоленская область"), new Region("ru-tam", "Тамбовская область"), new Region("ru-tve", "Тверская область"), new Region("ru-tom", "Томская область"), new Region("ru-tul", "Тульская область"), new Region("ru-tyu", "Тюменская область"), new Region("ru-uly", "Ульяновская область"), new Region("ru-che", "Челябинская область"), new Region("ru-zab", "Забайкальский край"), new Region("ru-yar", "Ярославская область"), new Region("ru-mow", "Москва"), new Region("ru-spb", "Санкт-Петербург"), new Region("ru-jew", "Еврейская автономная область"), new Region("ru-km", "Крым"), new Region("ru-nen", "Ненецкий автономный округ"), new Region("ru-khm", "Ханты-Мансийский автономный округ"), new Region("ru-chu", "Чукотский автономный округ"), new Region("ru-yam", "Ямало-Ненецкий автономный округ"), new Region("ru-sev", "Севастополь")]; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NaturalMonumentCategory = function () { function NaturalMonumentCategory(id, title) { _classCallCheck(this, NaturalMonumentCategory); this._id = id; this._title = title; } _createClass(NaturalMonumentCategory, [{ key: 'getId', value: function getId() { return this._id; } }, { key: 'getTitle', value: function getTitle() { return this._title; } }]); return NaturalMonumentCategory; }(); var naturalMonumentCategories = [new NaturalMonumentCategory('', 'не задано'), new NaturalMonumentCategory('federal', 'федерального значения'), new NaturalMonumentCategory('regional', 'регионального значения'), new NaturalMonumentCategory('municipal', 'местного значения'), new NaturalMonumentCategory('new', 'выявленный памятник')]; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NaturalMonumentStatus = function () { function NaturalMonumentStatus(id, title) { _classCallCheck(this, NaturalMonumentStatus); this._id = id; this._title = title; } _createClass(NaturalMonumentStatus, [{ key: 'getId', value: function getId() { return this._id; } }, { key: 'getTitle', value: function getTitle() { return this._title; } }]); return NaturalMonumentStatus; }(); var naturalMonumentStatuses = [new NaturalMonumentStatus('', 'действующий'), new NaturalMonumentStatus('destroyed', 'утрачен'), new NaturalMonumentStatus('dismissed', 'упразднён'), new NaturalMonumentStatus('rejected', 'предложенный, не созданный'), new NaturalMonumentStatus('reorganized', 'реорганизованный'), new NaturalMonumentStatus('planned', 'перспективный')]; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NaturalMonumentType = function () { function NaturalMonumentType(id, title) { _classCallCheck(this, NaturalMonumentType); this._id = id; this._title = title; } _createClass(NaturalMonumentType, [{ key: 'getId', value: function getId() { return this._id; } }, { key: 'getTitle', value: function getTitle() { return this._title; } }]); return NaturalMonumentType; }(); var naturalMonumentTypes = [new NaturalMonumentType('', 'не задано'), new NaturalMonumentType('reserve', 'заповедник'), new NaturalMonumentType('sanctuary', 'заказник'), new NaturalMonumentType('resource reserve', 'ресурсный резерват'), new NaturalMonumentType('arboretum', 'ботанический сад / дендрарий'), new NaturalMonumentType('national park', 'национальный парк'), new NaturalMonumentType('nature park', 'природный парк'), new NaturalMonumentType('city park', 'городской парк'), new NaturalMonumentType('garden', 'памятник садово-паркового искусства'), new NaturalMonumentType('traditional', 'территории традиционного природопользования'), new NaturalMonumentType('resort', 'рекреационная местность / курорт'), new NaturalMonumentType('nature', 'памятник природы'), new NaturalMonumentType('general', 'другое')]; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NaturalHeritageEditorForm = function () { function NaturalHeritageEditorForm() { var _this = this; _classCallCheck(this, NaturalHeritageEditorForm); this._form = ListingEditorFormComposer.createForm(); this._inputObjectName = ListingEditorFormComposer.createInputFormRowText('input-name', 'Название', 'название объекта', false, true); this._inputStatus = ListingEditorFormComposer.createInputFormRowSelect('input-status', 'Статус', naturalMonumentStatuses.map(function (status) { return { title: status.getTitle(), value: status.getId() }; })); this._inputType = ListingEditorFormComposer.createInputFormRowSelect('input-type', 'Тип', naturalMonumentTypes.map(function (type) { return { title: type.getTitle(), value: type.getId() }; })); this._inputCategory = ListingEditorFormComposer.createInputFormRowSelect('input-category', 'Категория', naturalMonumentCategories.map(function (category) { return { title: category.getTitle(), value: category.getId() }; })); this._inputRegion = ListingEditorFormComposer.createInputFormRowSelect('input-region', 'Регион', regions.map(function (region) { return { title: region.getTitle(), value: region.getId() }; })); this._inputDistrict = ListingEditorFormComposer.createInputFormRowText('input-district', 'Район'); this._inputMunicipality = ListingEditorFormComposer.createInputFormRowText('input-municipality', 'Населённый пункт'); this._inputAddress = ListingEditorFormComposer.createInputFormRowText('input-address', 'Адрес', 'улица название, номер дома'); this._inputLat = ListingEditorFormComposer.createInputFormRowText('input-lat', 'Широта', '11.11111', true); this._inputLong = ListingEditorFormComposer.createInputFormRowText('input-long', 'Долгота', '111.11111', true); this._inputPrecise = ListingEditorFormComposer.createInputFormRowCheckbox('input-precise', 'Точные координаты'); this._inputArea = ListingEditorFormComposer.createInputFormRowText('input-area', 'Площадь'); this._inputKnid = ListingEditorFormComposer.createInputFormRowText('input-knid', '№ объекта', 'dddddddddd', true); this._inputComplex = ListingEditorFormComposer.createInputFormRowText('input-complex', '№ комплекса', 'dddddddddd', true); this._inputUid = ListingEditorFormComposer.createInputFormRowText('input-uid', '№ объекта (UA)', 'dddddddddd', true); this._inputImage = ListingEditorFormComposer.createInputFormRowText('input-image', 'Изображение', 'изображение на Викискладе'); this._inputWiki = ListingEditorFormComposer.createInputFormRowText('input-wiki', 'Википедия', 'статья в русской Википедии'); this._inputWdid = ListingEditorFormComposer.createInputFormRowText('input-wdid', 'Викиданные', 'идентификатор Викиданных', true); this._inputCommonscat = ListingEditorFormComposer.createInputFormRowText('input-commonscat', 'Викисклад', 'категория Викисклада'); this._inputMunid = ListingEditorFormComposer.createInputFormRowText('input-munid', 'Викиданные нас. пункта', 'идентификатор Викиданных', true); this._inputLink = ListingEditorFormComposer.createInputFormRowText('input-link', 'Ссылка №1', 'внешняя ссылка с дополнительной информацией об объекте'); this._inputLinkExtra = ListingEditorFormComposer.createInputFormRowText('input-linkextra', 'Ссылка №2', 'внешняя ссылка с дополнительной информацией об объекте'); this._inputOopt = ListingEditorFormComposer.createInputFormRowText('input-oopt', 'На сайте ООПТ России'); this._inputDocument = ListingEditorFormComposer.createInputFormRowText('input-document', 'Документ', '', true); var selectImageLinkRow = ListingEditorFormComposer.createRowLink('выбрать изображение из галереи'); selectImageLinkRow.linkElement.click(function () { CommonsImagesSelectDialog.showDialog( /*knidWLM=*/null, _this._inputKnid.inputElement.val(), _this._inputCommonscat.inputElement.val(), function (selectedImage) { _this._inputImage.inputElement.val(selectedImage); }); }); var tableObjectName = ListingEditorFormComposer.createTableFullWidth(); tableObjectName.tableElement.append(this._inputObjectName.rowElement); tableObjectName.tableElement.append(ListingEditorFormComposer.createRowDivider()); this._form.formElement.append(tableObjectName.wrapperElement); var tableObjectProperties = ListingEditorFormComposer.createTableTwoColumns(); tableObjectProperties.leftTableElement.append(this._inputType.rowElement); tableObjectProperties.leftTableElement.append(this._inputStatus.rowElement); tableObjectProperties.leftTableElement.append(this._inputCategory.rowElement); tableObjectProperties.leftTableElement.append(ListingEditorFormComposer.createRowDivider()); tableObjectProperties.leftTableElement.append(this._inputRegion.rowElement); tableObjectProperties.leftTableElement.append(this._inputDistrict.rowElement); tableObjectProperties.leftTableElement.append(this._inputMunicipality.rowElement); tableObjectProperties.leftTableElement.append(this._inputAddress.rowElement); tableObjectProperties.leftTableElement.append(ListingEditorFormComposer.createRowDivider()); tableObjectProperties.leftTableElement.append(this._inputLat.rowElement); tableObjectProperties.leftTableElement.append(this._inputLong.rowElement); tableObjectProperties.leftTableElement.append(this._inputPrecise.rowElement); tableObjectProperties.leftTableElement.append(ListingEditorFormComposer.createRowDivider()); tableObjectProperties.leftTableElement.append(this._inputArea.rowElement); tableObjectProperties.rightTableElement.append(this._inputKnid.rowElement); tableObjectProperties.rightTableElement.append(this._inputComplex.rowElement); tableObjectProperties.rightTableElement.append(this._inputUid.rowElement); tableObjectProperties.rightTableElement.append(ListingEditorFormComposer.createRowDivider()); tableObjectProperties.rightTableElement.append(this._inputImage.rowElement); tableObjectProperties.rightTableElement.append(selectImageLinkRow.rowElement); tableObjectProperties.rightTableElement.append(this._inputWiki.rowElement); tableObjectProperties.rightTableElement.append(this._inputWdid.rowElement); tableObjectProperties.rightTableElement.append(this._inputCommonscat.rowElement); tableObjectProperties.rightTableElement.append(this._inputMunid.rowElement); tableObjectProperties.rightTableElement.append(ListingEditorFormComposer.createRowDivider()); tableObjectProperties.rightTableElement.append(this._inputLink.rowElement); tableObjectProperties.rightTableElement.append(this._inputLinkExtra.rowElement); tableObjectProperties.rightTableElement.append(this._inputOopt.rowElement); tableObjectProperties.rightTableElement.append(this._inputDocument.rowElement); this._form.formElement.append(tableObjectProperties.wrapperElement); var tableObjectDescription = ListingEditorFormComposer.createTableFullWidth(); var objectDescriptionRow = ListingEditorFormComposer.createObjectDescriptionRow(); this._inputDescription = objectDescriptionRow.inputDescription; tableObjectDescription.tableElement.append(objectDescriptionRow.row); tableObjectDescription.tableElement.append(ListingEditorFormComposer.createRowDivider()); this._form.formElement.append(tableObjectDescription.wrapperElement); var tableChanges = ListingEditorFormComposer.createTableFullWidth(); var changesDescriptionRow = ListingEditorFormComposer.createChangesDescriptionRow(); this._inputChangesSummary = changesDescriptionRow.inputChangesSummary; this._inputIsMinorChanges = changesDescriptionRow.inputIsMinorChanges; tableChanges.tableElement.append(ListingEditorFormComposer.createRowDivider()); tableChanges.tableElement.append(changesDescriptionRow.row); this._form.formElement.append(tableChanges.wrapperElement); this._directMappingInputs = { name: this._inputObjectName.inputElement, status: this._inputStatus.inputElement, type: this._inputType.inputElement, category: this._inputCategory.inputElement, region: this._inputRegion.inputElement, district: this._inputDistrict.inputElement, municipality: this._inputMunicipality.inputElement, address: this._inputAddress.inputElement, lat: this._inputLat.inputElement, long: this._inputLong.inputElement, description: this._inputDescription, area: this._inputArea.inputElement, knid: this._inputKnid.inputElement, complex: this._inputComplex.inputElement, uid: this._inputUid.inputElement, image: this._inputImage.inputElement, wiki: this._inputWiki.inputElement, wdid: this._inputWdid.inputElement, commonscat: this._inputCommonscat.inputElement, munid: this._inputMunid.inputElement, link: this._inputLink.inputElement, linkextra: this._inputLinkExtra.inputElement, document: this._inputDocument.inputElement, oopt: this._inputOopt.inputElement }; } _createClass(NaturalHeritageEditorForm, [{ key: 'getForm', value: function getForm() { return this._form; } }, { key: 'setData', value: function setData(listingData) { var _this2 = this; Object.keys(this._directMappingInputs).forEach(function (key) { if (listingData[key]) { _this2._directMappingInputs[key].val(listingData[key]); } }); this._inputPrecise.inputElement.attr('checked', listingData['precise'] === 'yes'); } }, { key: 'getData', value: function getData() { var _this3 = this; var data = {}; Object.keys(this._directMappingInputs).forEach(function (key) { data[key] = _this3._directMappingInputs[key].val(); }); if (this._inputPrecise.inputElement.is(':checked')) { data['precise'] = 'yes'; } else { data['precise'] = 'no'; } data['link'] = ValidationUtils.normalizeUrl(data['link']); data['linkextra'] = ValidationUtils.normalizeUrl(data['linkextra']); return data; } }, { key: 'getObjectName', value: function getObjectName() { return this._inputObjectName.inputElement.val(); } }, { key: 'getChangesSummary', value: function getChangesSummary() { return this._inputChangesSummary.val(); } }, { key: 'getChangesIsMinor', value: function getChangesIsMinor() { return this._inputIsMinorChanges.is(':checked'); } }]); return NaturalHeritageEditorForm; }(); var WikitextParser = { /** * Given a listing index, return the full wikitext for that listing * ("{{listing|key=value|...}}"). An index of 0 returns the first listing * template invocation, 1 returns the second, etc. */ getListingWikitextBraces: function getListingWikitextBraces(wikitext, listingName, listingIndex) { // find the listing wikitext that matches the same index as the listing index var listingRegex = new RegExp('{{\\s*(' + listingName + ')(\\s|\\|)', 'ig'); // look through all matches for "{{listing|see|do...}}" within the section // wikitext, returning the nth match, where 'n' is equal to the index of the // edit link that was clicked var listingSyntax = void 0, regexResult = void 0, listingMatchIndex = void 0; for (var i = 0; i <= listingIndex; i++) { regexResult = listingRegex.exec(wikitext); listingMatchIndex = regexResult.index; listingSyntax = regexResult[0]; } // listings may contain nested templates, so step through all section // text after the matched text to find MATCHING closing braces // the first two braces are matched by the listing regex and already // captured in the listingSyntax variable var curlyBraceCount = 2; var endPos = wikitext.length; var startPos = listingMatchIndex + listingSyntax.length; var matchFound = false; for (var j = startPos; j < endPos; j++) { if (wikitext[j] === '{') { ++curlyBraceCount; } else if (wikitext[j] === '}') { --curlyBraceCount; } if (curlyBraceCount === 0 && j + 1 < endPos) { listingSyntax = wikitext.substring(listingMatchIndex, j + 1); matchFound = true; break; } } if (!matchFound) { listingSyntax = wikitext.substring(listingMatchIndex); } return StringUtils.trim(listingSyntax); }, /** * Convert raw wiki listing syntax into a mapping of key-value pairs * corresponding to the listing template parameters. */ wikiTextToListing: function wikiTextToListing(wikitext) { // remove the trailing braces if there are some for (var i = 0; i < 2; i++) { if (wikitext[wikitext.length - 1] === '}') { wikitext = wikitext.slice(0, -1); } } var listingData = {}; var lastKey = void 0; var listParams = WikitextParser.listingTemplateToParamsArray(wikitext); for (var _i = 1; _i < listParams.length; _i++) { var param = listParams[_i]; var index = param.indexOf('='); if (index > 0) { // param is of the form key=value var key = StringUtils.trim(param.substr(0, index)); listingData[key] = StringUtils.trim(param.substr(index + 1)); lastKey = key; } else if (listingData[lastKey].length) { // there was a pipe character within a param value, such as // "key=value1|value2", so just append to the previous param listingData[lastKey] += '|' + param; } } return listingData; }, /** * Split the raw template wikitext into an array of params. The pipe * symbol delimits template params, but this method will also inspect the * description to deal with nested templates or wikilinks that might contain * pipe characters that should not be used as delimiters. */ listingTemplateToParamsArray: function listingTemplateToParamsArray(wikitext) { var results = []; var paramValue = ''; var pos = 0; while (pos < wikitext.length) { var remainingString = wikitext.substr(pos); // check for a nested template or wikilink var patternMatch = WikitextParser.findPatternMatch(remainingString, "{{", "}}"); if (patternMatch.length === 0) { patternMatch = WikitextParser.findPatternMatch(remainingString, "[[", "]]"); } if (patternMatch.length > 0) { paramValue += patternMatch; pos += patternMatch.length; } else if (wikitext.charAt(pos) === '|') { // delimiter - push the previous param and move on to the next results.push(paramValue); paramValue = ''; pos++; } else { // append the character to the param value being built paramValue += wikitext.charAt(pos); pos++; } } if (paramValue.length > 0) { // append the last param value results.push(paramValue); } return results; }, /** * Utility method for finding a matching end pattern for a specified start * pattern, including nesting. The specified value must start with the * start value, otherwise an empty string will be returned. */ findPatternMatch: function findPatternMatch(value, startPattern, endPattern) { var matchString = ''; var startRegex = new RegExp('^' + WikitextParser.replaceSpecial(startPattern), 'i'); if (startRegex.test(value)) { var endRegex = new RegExp('^' + WikitextParser.replaceSpecial(endPattern), 'i'); var matchCount = 1; for (var i = startPattern.length; i < value.length; i++) { var remainingValue = value.substr(i); if (startRegex.test(remainingValue)) { matchCount++; } else if (endRegex.test(remainingValue)) { matchCount--; } if (matchCount === 0) { matchString = value.substr(0, i); break; } } } return matchString; }, replaceSpecial: function replaceSpecial(str) { return str.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); } }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var WikitextSectionEditor = function () { function WikitextSectionEditor(sectionText, listingName) { _classCallCheck(this, WikitextSectionEditor); this._sectionText = sectionText; this._listingName = listingName; this._commentReplacements = {}; this._stripComments(); } _createClass(WikitextSectionEditor, [{ key: 'getListingData', value: function getListingData(listingIndex) { var listingText = WikitextParser.getListingWikitextBraces(this._sectionText, this._listingName, listingIndex); var listingData = WikitextParser.wikiTextToListing(listingText); for (var key in listingData) { if (!listingData.hasOwnProperty(key)) { continue; } listingData[key] = this._restoreComments(listingData[key]); } return listingData; } }, { key: 'getSectionTextWithReplacedListing', value: function getSectionTextWithReplacedListing(listingIndex, newListingText) { var oldListingText = WikitextParser.getListingWikitextBraces(this._sectionText, this._listingName, listingIndex); var result = this._sectionText; result = result.replace(oldListingText, newListingText); result = this._restoreComments(result); return result; } }, { key: 'getSectionTextWithAddedListing', value: function getSectionTextWithAddedListing(newListingText) { var result = this._sectionText; var index = result.indexOf('{{footer'); if (index > 0) { result = result.substr(0, index) + '\n' + newListingText + '\n' + result.substr(index); } else { result += '\n' + newListingText; } result = this._restoreComments(result); return result; } /** * Commented-out listings can result in the wrong listing being edited, so * strip out any comments and replace them with placeholders that can be * restored prior to saving changes. */ }, { key: '_stripComments', value: function _stripComments() { var comments = this._sectionText.match(/<!--[\s\S]*?-->/mig); if (comments !== null) { for (var i = 0; i < comments.length; i++) { var comment = comments[i]; var rep = '<<<COMMENT' + i + '>>>'; this._sectionText = this._sectionText.replace(comment, rep); this._commentReplacements[rep] = comment; } } } /** * Search the text provided, and if it contains any text that was * previously stripped out for replacement purposes, restore it. */ }, { key: '_restoreComments', value: function _restoreComments(sectionText) { for (var key in this._commentReplacements) { var val = this._commentReplacements[key]; sectionText = sectionText.replace(key, val); } return sectionText; } }]); return WikitextSectionEditor; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var ListingSerializer = function () { function ListingSerializer(listingType, listingData) { _classCallCheck(this, ListingSerializer); this._listingType = listingType; this._listingData = listingData; this._serializedListing = ''; this._serializedParameters = []; } _createClass(ListingSerializer, [{ key: 'writeListingStart', value: function writeListingStart(addNewline) { this._serializedListing += '{{' + this._listingType; if (addNewline) { this._serializedListing += "\n"; } else { this._serializedListing += ' '; } } }, { key: 'writeParameterLine', value: function writeParameterLine(parameterName, optional) { var parameterValue = this._listingData[parameterName]; if (optional && (parameterValue === '' || parameterValue === undefined)) { return; } if (parameterValue === undefined) { parameterValue = ''; } this._serializedListing += '|' + parameterName + "=" + parameterValue + "\n"; this._serializedParameters.push(parameterName); } }, { key: 'writeParametersLine', value: function writeParametersLine(parameterNames) { for (var i = 0; i < parameterNames.length; i++) { var parameterName = parameterNames[i]; var parameterValue = this._listingData[parameterName]; if (parameterValue === undefined) { parameterValue = ''; } if (i > 0) { this._serializedListing += " "; } this._serializedListing += "|" + parameterName + "=" + parameterValue; this._serializedParameters.push(parameterName); } this._serializedListing += "\n"; } }, { key: 'writeOtherNonEmptyParameters', value: function writeOtherNonEmptyParameters() { for (var parameterName in this._listingData) { if (!this._listingData.hasOwnProperty(parameterName)) { continue; } if (!ArrayUtils.hasElement(this._serializedParameters, parameterName)) { var parameterValue = this._listingData[parameterName]; if (parameterValue !== '' && parameterValue !== undefined) { this._serializedListing += '|' + parameterName + "=" + parameterValue + "\n"; } } } } }, { key: 'writeListingEnd', value: function writeListingEnd() { this._serializedListing += '}}'; } }, { key: 'getSerializedListing', value: function getSerializedListing() { return this._serializedListing; } }]); return ListingSerializer; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var NaturalEditorListingSerializer = function () { function NaturalEditorListingSerializer() { _classCallCheck(this, NaturalEditorListingSerializer); } _createClass(NaturalEditorListingSerializer, [{ key: "serializeListingData", value: function serializeListingData(listingData) { var listingSerializer = new ListingSerializer('natural monument', listingData); listingSerializer.writeListingStart(); listingSerializer.writeParametersLine(["type", "status"]); listingSerializer.writeParametersLine(["lat", "long", "precise"]); listingSerializer.writeParameterLine("name"); listingSerializer.writeParameterLine("category", true); listingSerializer.writeParameterLine("knid"); listingSerializer.writeParameterLine("complex", true); listingSerializer.writeParameterLine("uid", true); listingSerializer.writeParametersLine(["region", "district"]); listingSerializer.writeParametersLine(["municipality", "munid"]); listingSerializer.writeParameterLine("address"); listingSerializer.writeParameterLine("area", true); listingSerializer.writeParameterLine("description"); listingSerializer.writeParameterLine("image"); listingSerializer.writeParameterLine("wdid"); listingSerializer.writeParameterLine("wiki"); listingSerializer.writeParameterLine("commonscat"); listingSerializer.writeParameterLine("link", true); listingSerializer.writeParameterLine("linkextra", true); listingSerializer.writeParameterLine("document", true); listingSerializer.writeParameterLine("oopt", true); listingSerializer.writeOtherNonEmptyParameters(); listingSerializer.writeListingEnd(); return listingSerializer.getSerializedListing(); } }]); return NaturalEditorListingSerializer; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var SavingForm = function () { function SavingForm() { _classCallCheck(this, SavingForm); this._progress = $('<div id="progress-dialog">' + 'Сохранение...' + '</div>'); this._progress.dialog({ modal: true, height: 100, width: 300, title: '' }); $(".ui-dialog-titlebar").hide(); } _createClass(SavingForm, [{ key: 'destroy', value: function destroy() { this._progress.dialog('destroy').remove(); } }]); return SavingForm; }(); InputInsertSymbols = { addQuotesInsertHandler: function addQuotesInsertHandler(insertButton, insertToInput) { insertButton.click(function () { var selectionStart = insertToInput[0].selectionStart; var selectionEnd = insertToInput[0].selectionEnd; var oldValue