MediaWiki:Gadget-ImprovedEditTools.js
Перейти до навігації
Перейти до пошуку
Увага: Після збереження слід очистити кеш оглядача, щоб побачити зміни.
- Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
- Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
- Internet Explorer: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
- Opera: очистіть кеш за допомогою Інструменти → Налаштування (Opera → Побажання на Apple Mac) та перейдіть на Приватність & безпека → очистити дані браузера → кеш
var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; if (typeof unsafeWindow !== "undefined" && unsafeWindow !== null) { window.$ = unsafeWindow.$; } window.rast = { clone: function(object) { return $.extend(true, {}, object); }, arrayMove: function(array, from, to) { return array.splice(to, 0, array.splice(from, 1)[0]); }, $getTextarea: function() { return $('#wpTextbox1'); }, $getCurrentInput: function() { return $(document.activeElement); }, insertion: { replaceSpecsymbols: function(s, symbols, toFunc) { var c, i, res; res = ''; c = void 0; i = 0; while (i < s.length) { c = s.charAt(i); if (rast.insertion.isEscaped(s, i)) { res += c; } else if (symbols.indexOf(c) > -1) { res += toFunc(c); } else { res += c; } i++; } return res; }, isEscaped: function(s, i) { var escSymbols; escSymbols = 0; i--; while (i > -1 && s.charAt(i) === '\\') { escSymbols++; i--; } return escSymbols % 2 === 1; }, indexOfUnescaped: function(s, symbol) { var i, index; index = -1; i = 0; while (i < s.length) { if (s.charAt(i) === symbol && !rast.insertion.isEscaped(s, i)) { index = i; break; } i++; } return index; } }, installJQueryPlugins: function() { $.fn.extend({ throbber: function(visibility, position, size) { var $elem, $throbber; $elem = $(this); $throbber = $elem.data('rastThrobber'); if ($throbber) { $throbber.toggle(visibility); } else { size = size || '20px'; $throbber = $('<img>'); $throbber.attr('src', 'https://upload.wikimedia.org/wikipedia/commons/d/de/Ajax-loader.gif'); $throbber.css('width', size); $throbber.css('height', size); $elem.data('rastThrobber', $throbber); $elem[position]($throbber); $elem.addClass('withRastThrobber'); } return $elem; }, asnavSelect: function(id) { var $tabs, first, tabContent; $tabs = $(this); $tabs.find('.asnav-content').hide(); $tabs.find('.asnav-tabs .asnav-selectedtab').removeClass('asnav-selectedtab'); tabContent = $tabs.find('.asnav-tabs [data-contentid="' + id + '"]:first'); if (tabContent.length) { tabContent.addClass('asnav-selectedtab'); return $tabs.find('#' + id).show(); } else { first = $tabs.find('.asnav-tabs [data-contentid]:first').addClass('asnav-selectedtab'); return $tabs.find('#' + first.attr('data-contentid')).show(); } }, etMakeTabs: function(activeTabId) { var selectFunc, tabs; tabs = $(this); selectFunc = function(a) { var $a; $a = $(a); tabs.asnavSelect($a.attr('data-contentid')); return $a.trigger('asNav:select', $a.attr('data-contentid')); }; tabs.on('click', '.asnav-tabs [data-contentid]', function() { return selectFunc(this); }); return tabs.asnavSelect(activeTabId); } }); return $.fn.extend({ insertTag: function(beginTag, endTag) { return this.each(function() { var SelReplace, pos, sel; SelReplace = void 0; pos = void 0; sel = void 0; SelReplace = function(s) { return rast.insertion.replaceSpecsymbols(s, '\\$', function(c) { if (c === '\\') { return ''; } else if (c === '$') { return sel; } }); }; $(this).focus(); sel = $(this).textSelection('getSelection'); beginTag = SelReplace(beginTag); endTag = endTag ? SelReplace(endTag) : ''; $(this).textSelection('encapsulateSelection', { pre: beginTag || '', peri: '', post: endTag || '', replace: true }); if (endTag && sel !== '') { pos = $(this).textSelection('getCaretPosition'); return $(this).textSelection('setSelection', { start: pos - endTag.length }); } }); }, setSelection: function(text) { return this.textSelection('encapsulateSelection', { post: text, replace: true }); }, getSelection: function(text) { return this.textSelection('getSelection'); } }); }, name: function(constructor) { return 'rast.' + constructor.name; }, processSelection: function(txtFunc) { var $textarea, txt; $textarea = rast.$getTextarea(); txt = $textarea.getSelection(); return $textarea.setSelection(txtFunc(txt)); }, perLineReplace: function(str, regex, to) { var i, len; str = str.split('\n'); len = str.length; i = 0; while (i < len) { str[i] = str[i].replace(regex, to); i += 1; } return str.join('\n'); }, linkifyList: function(s) { return rast.perLineReplace(s, /[^*;#—\s,][^*\.#—;,]+/g, '[[$&]]'); }, simpleList: function(s) { return rast.perLineReplace(s, /(([\*#]*)\s*)(.+)/g, '*$2 $3'); }, numericList: function(s) { return rast.perLineReplace(s, /(([\*#]*)\s*)(.+)/g, '#$2 $3'); }, searchAndReplace: { doSearchReplace: function(mode) { var $textarea, actualReplacement, context, e, end, flags, i, index, isRegex, match, matchCase, newText, offset, regex, replaceStr, searchStr, start, text, textRemainder; offset = void 0; textRemainder = void 0; regex = void 0; index = void 0; i = void 0; start = void 0; end = void 0; $('#et-replace-nomatch, #et-replace-success, #et-replace-emptysearch, #et-replace-invalidregex').hide(); searchStr = $('#et-replace-search').val(); if (searchStr === '') { $('#et-replace-emptysearch').show(); return; } replaceStr = $('#et-replace-replace').val(); flags = 'm'; matchCase = $('#et-replace-case').is(':checked'); if (!matchCase) { flags += 'i'; } isRegex = $('#et-replace-regex').is(':checked'); if (!isRegex) { searchStr = mw.util.escapeRegExp(searchStr); } if (mode === 'replaceAll') { flags += 'g'; } try { regex = new RegExp(searchStr, flags); } catch (_error) { e = _error; $('#et-replace-invalidregex').show(); return; } $textarea = rast.$getTextarea(); text = $textarea.textSelection('getContents'); match = false; if (mode !== 'replaceAll') { if (mode === 'replace') { offset = rast.searchAndReplace.matchIndex; } else { offset = rast.searchAndReplace.offset; } textRemainder = text.substr(offset); match = textRemainder.match(regex); } if (!match) { offset = 0; textRemainder = text; match = textRemainder.match(regex); } if (!match) { $('#et-replace-nomatch').show(); return; } if (mode === 'replaceAll') { newText = text.replace(regex, replaceStr); $textarea.select().textSelection('encapsulateSelection', { 'peri': newText, 'replace': true }); $('#et-replace-success').text('Здійснено замін: ' + match.length).show(); rast.searchAndReplace.offset = 0; return rast.searchAndReplace.matchIndex = 0; } else { if (mode === 'replace') { actualReplacement = void 0; if (isRegex) { actualReplacement = match[0].replace(regex, replaceStr); } else { actualReplacement = replaceStr; } if (match) { $textarea.textSelection('encapsulateSelection', { 'peri': actualReplacement, 'replace': true }); text = $textarea.textSelection('getContents'); } offset = offset + match[0].length + actualReplacement.length; textRemainder = text.substr(offset); match = textRemainder.match(regex); if (match) { start = offset + match.index; end = start + match[0].length; } else { textRemainder = text; match = textRemainder.match(regex); if (match) { start = match.index; end = start + match[0].length; } else { start = 0; end = 0; } } } else { start = offset + match.index; end = start + match[0].length; } rast.searchAndReplace.matchIndex = start; $textarea.textSelection('setSelection', { 'start': start, 'end': end }); $textarea.textSelection('scrollToCaretPosition'); rast.searchAndReplace.offset = end; context = rast.searchAndReplace.context; return $textarea[0].focus(); } } } }; rast.PanelDrawer = (function() { function PanelDrawer($panel1, subsetWrapper1, index1, mode1, subsets1, eventsHandler) { this.$panel = $panel1; this.subsetWrapper = subsetWrapper1; this.index = index1; this.mode = mode1; this.subsets = subsets1; this.eventsHandler = eventsHandler; } PanelDrawer.prototype.draw = function() { var generateMethod; if (this.mode === 'edit') { return this.drawEditMode(); } else if (this.mode === 'view') { generateMethod = 'generateHtml'; return this.generateHtml(this.$panel, this.subsetWrapper.slots, generateMethod); } }; PanelDrawer.prototype.sortableSlots = function($slots) { return $($slots).sortable({ delay: 150, containment: $slots, forceHelperSize: true, forcePlaceholderSize: true, items: '[data-id]', start: function(event, ui) { var copy; return copy = $(ui.item[0].outerHTML).clone(); }, placeholder: { element: function(copy, ui) { return $('<span class="ui-state-highlight">' + copy[0].innerHTML + '</li>'); }, update: function() {} }, receive: (function(_this) { return function(event, ui) { var index, newSlot, slotClass; slotClass = eval(ui.item.attr('data-slot-class')); index = $(event.target).data().sortable.currentItem.index(); newSlot = _this.subsets.addSlot(slotClass, _this.subsetWrapper, index); return _this.eventsHandler.onSlotAdded(newSlot); }; })(this), update: (function(_this) { return function(event, ui) { var newSlotIndex, slot, slotId; newSlotIndex = ui.item.index('[data-id]') - 1; if (newSlotIndex < 0) { return; } if (!$(ui.item).attr('data-id')) { return; } slotId = parseInt($(ui.item).attr('data-id')); slot = _this.subsets.slotById(slotId); _this.rearrangeSlot(slot, newSlotIndex); return _this.updatePreview(); }; })(this), revert: true }); }; PanelDrawer.prototype.drawEditMode = function() { var $descLabel, $preview, $previewContent, $slots, generateMethod, layout, nameInput, nameLabel, removeButton; nameLabel = new OO.ui.LabelWidget({ label: 'Назва панелі:' }); nameInput = new OO.ui.TextInputWidget({ value: this.subsetWrapper.caption }); nameInput.$element.on('keydown', function(event) { if (event.keyCode === 13) { event.preventDefault(); return false; } }); nameInput.$element.change({ subsetWrapper: this.subsetWrapper }, this.eventsHandler.onTabNameChanged); removeButton = new OO.ui.ButtonWidget({ label: 'Вилучити цю панель', flags: 'destructive' }); removeButton.on('click', (function(_this) { return function() { return _this.eventsHandler.onRemoveSubsetClick(_this.subsetWrapper); }; })(this)); layout = new OO.ui.HorizontalLayout({ items: [nameLabel, nameInput, removeButton] }); this.$panel.append(layout.$element); $descLabel = $('<span>'); $descLabel.text('Ви можете перетягувати комірки, щоб змінити їхній порядок. Клацніть по комірці, щоб редагувати її. Щоб додати комірку, перетягніть нижче один з цих видів:'); this.$panel.append($descLabel); this.drawSlotClasses(this.$panel); $slots = $('<div class="slots">'); this.$panel.append($slots); generateMethod = 'generateEditHtml'; this.sortableSlots($slots); if (!this.subsetWrapper.slots.length) { $slots.append('<span>Щоб додати комірку, сюди перетягніть потрібний вид.</span>'); } else { this.generateHtml($slots, this.subsetWrapper.slots, generateMethod); } $preview = $('<div>').css('border-top', '1px solid color: #aaa').addClass('preview'); $preview.append($('<div>Попередній перегляд:</div>')); $previewContent = $('<div class="content">'); this.generateHtml($previewContent, this.subsetWrapper.slots, 'generateHtml'); $preview.append($previewContent); return this.$panel.append($preview); }; PanelDrawer.prototype.generateHtml = function($slotsContainer, slots, generateMethod) { var k, len1, results1, slot; results1 = []; for (k = 0, len1 = slots.length; k < len1; k++) { slot = slots[k]; results1.push($slotsContainer.append(slot[generateMethod]())); } return results1; }; PanelDrawer.prototype.updatePreview = function(subsetWrapper) { var $previewContent; $previewContent = this.$panel.find('.preview .content'); $previewContent.empty(); return this.generateHtml($previewContent, this.subsetWrapper.slots, 'generateHtml'); }; PanelDrawer.prototype.rearrangeSlot = function(slot, newSlotIndex) { var slotIndex; slotIndex = this.subsets.slotIndex(slot); return rast.arrayMove(this.subsetWrapper.slots, slotIndex, newSlotIndex); }; PanelDrawer.prototype.drawSlotClasses = function($container) { var $slot, $slots, k, len1, ref, slotClass; $slots = $('<div class="slotClasses">'); ref = this.slotClasses(); for (k = 0, len1 = ref.length; k < len1; k++) { slotClass = ref[k]; $slot = $('<span class="slotClass">'); $slot.attr('data-slot-class', rast.name(slotClass)); $slot.text(slotClass.caption); $slot.attr('title', 'Перетягніть на панель, щоб вставити цей вид комірки'); $slots.append($slot); } $container.append($slots); return $slots.find('.slotClass').draggable({ connectToSortable: '.etPanel .slots', helper: 'clone' }); }; PanelDrawer.prototype.slotClasses = function() { return [rast.PlainTextSlot, rast.InsertionSlot, rast.MultipleInsertionsSlot, rast.HtmlSlot]; }; return PanelDrawer; })(); rast.Drawer = (function() { function Drawer() {} Drawer.prototype.$editButton = function() { var icon; icon = new OO.ui.IconWidget({ icon: 'settings', title: 'Редагувати символи', classes: ['gear'] }); return icon.$element; }; Drawer.prototype.drawMenu = function() { var $aboutLink, $editButton, $menu, cancelButton, persistButton, resetButton, saveButton; $menu = $('<div class="rastMenu">'); $menu.addClass(this.mode); if (this.mode === 'view') { $editButton = this.$editButton(); $editButton.click(this.eventsHandler.onEditClick); $menu.append($editButton); } else if (this.mode === 'edit') { persistButton = new OO.ui.ButtonWidget({ label: ' Зберегти на постійно', title: 'Символи буде збережено на підсторінку у Вашому просторі користувача.', icon: 'checkAll' }); persistButton.on('click', this.eventsHandler.onPersistClick); saveButton = new OO.ui.ButtonWidget({ label: ' Зберегти тимчасово', title: 'Зміни збережуться тільки на час редагування сторінки і втратяться після закриття або перевантаження сторінки.', icon: 'check' }); saveButton.on('click', this.eventsHandler.onSaveClick); cancelButton = new OO.ui.ButtonWidget({ label: ' Скасувати', title: 'Всі зміни цієї сесії редагування будуть відкинуті.', icon: 'cancel' }); cancelButton.on('click', this.eventsHandler.onCancelClick); resetButton = new OO.ui.ButtonWidget({ label: ' Відновити звичаєві', title: 'Буде відновлено набір символів за промовчанням.', icon: 'reload' }); resetButton.on('click', this.eventsHandler.onResetClick); $aboutLink = $("<a class=\"aboutLink\" target=\"_blank\" href=\"" + this.docLink + "\">про додаток</a>"); $menu.append(persistButton.$element, saveButton.$element, cancelButton.$element, resetButton.$element, $aboutLink); } return this.$container.append($menu); }; Drawer.prototype.drawTab = function($container, text) { var $a, $adiv; $a = $('<a>'); $adiv = $('<div>'); $a.text(text); $adiv.append($a); $container.append($adiv); return $adiv; }; Drawer.prototype.drawTabs = function($container) { var $adiv, i, id; i = 0; while (i < this.subsets.subsets.length) { $adiv = this.drawTab($container, this.subsets.subsets[i].caption); id = 'etTabContent' + i; if (this.activeTab === id) { $adiv.addClass('asnav-selectedtab'); } $adiv.attr('data-contentid', id); $adiv.click(this.eventsHandler.onTabClick); i++; } return $container; }; Drawer.prototype.drawNavigation = function() { var $addNewdiv, $outline, $tabs; $outline = $('<span>').addClass('asnav-tabs').addClass('specialchars-tabs'); $tabs = $('<div class="existingTabs">'); this.drawTabs($tabs); $outline.append($tabs); if (this.mode === 'edit') { $addNewdiv = this.drawTab($outline, '+ панель'); $addNewdiv.addClass('newPanelButton'); $addNewdiv.attr('title', 'Додати нову панель'); $addNewdiv.click(this.eventsHandler.onAddSubsetClick); } return this.$container.append($outline); }; Drawer.prototype.draw = function() { this.$container.empty(); this.drawMenu(); this.drawMessage(); this.drawNavigation(); return this.drawPanels(); }; Drawer.prototype.drawMessage = function() { return this.$container.append(this.message); }; Drawer.prototype.drawPanels = function() { var $content, $subset, $subsetDiv, i; $content = $('<div>').attr('id', 'etContent').addClass('overflowHidden'); this.$container.append($content); i = 0; while (i < this.subsets.subsets.length) { $subset = this.drawPanel(this.subsets.subsets[i], i); $subsetDiv = $('<div>').attr('id', 'etTabContent' + i).attr('data-id', this.subsets.subsets[i].id).appendTo($content).addClass('asnav-content').append($subset); i++; } this.$container.etMakeTabs(true); this.$container.append($('<div>').css('clear', 'both')); return this.$container.asnavSelect(this.activeTab); }; Drawer.prototype.drawPanel = function(subsetWrapper, index) { var $panel, panelDrawer; $panel = $('<div>').attr('id', 'spchars-' + index).addClass('etPanel'); panelDrawer = new rast.PanelDrawer($panel, subsetWrapper, index, this.mode, this.subsets, this.eventsHandler); panelDrawer.draw(); return $panel; }; return Drawer; })(); rast.PlainObjectParser = (function() { function PlainObjectParser() {} PlainObjectParser.charinsertDivider = ' '; PlainObjectParser.parseTokens = function(arr) { var k, len1, slot, slots, token; slots = []; for (k = 0, len1 = arr.length; k < len1; k++) { token = arr[k]; if (typeof token === 'string') { slots = slots.concat(this.strToMultipleInsertionsSlot(token)); } else if (Object.prototype.toString.call(token) === '[object Array]') { slots.push(this.slotFromArr(token)); } else if (typeof token === 'object') { slot = this.slotFromPlainObj(token); if (slot) { slots.push(slot); } } } return slots; }; PlainObjectParser.slotFromArr = function(arr) { return new rast.InsertionSlot({ insertion: arr[0], caption: arr[1] }); }; PlainObjectParser.slotsFromStr = function(str) { var k, len1, slot, slots, token, tokens; tokens = str.split(' '); slots = []; slot = void 0; for (k = 0, len1 = tokens.length; k < len1; k++) { token = tokens[k]; slot = this.slotFromStr(token); slots.push(slot); } return slots; }; PlainObjectParser.strToMultipleInsertionsSlot = function(str) { var slot, slots; slots = []; slot = new rast.MultipleInsertionsSlot({ insertion: str }); slots.push(slot); return slots; }; PlainObjectParser.lineReplace = function(c) { if (c === '\\') { return '\\'; } else if (c === '_') { return ' '; } }; PlainObjectParser.slotFromStr = function(token) { var modifiers, readModifiers, slot, tags; readModifiers = function() { var c, i, res; res = { bold: false, plain: false, italic: false }; i = token.length - 1; c = void 0; while (i > -1 && !rast.insertion.isEscaped(token, i)) { c = token.charAt(i).toLowerCase(); if (c === 'ж') { res.bold = true; } else if (c === 'н') { res.italic = true; } else if (c === 'п') { res.plain = true; } else { break; } token = token.substring(0, i); i--; } return res; }; modifiers = readModifiers(); slot = void 0; if (modifiers.plain || token === '' || token === '_') { slot = new rast.PlainTextSlot({ bold: modifiers.bold, italic: modifiers.italic }); if (token === '' || token === '_') { slot.text = this.charinsertDivider + ' '; } else { slot.text = rast.insertion.replaceSpecsymbols(token, '\\_', this.lineReplace) + ' '; } } else { tags = this.parseInsertion(token, ''); slot = new rast.InsertionSlot({ bold: modifiers.bold, italic: modifiers.italic, insertion: token, caption: tags.caption }); } return slot; }; PlainObjectParser.generateLink = function(obj) { var slot; slot = void 0; if (obj.ins || obj.insert) { slot = new rast.InsertionSlot({}); $.extend(slot, this.parseInsertion(obj.ins || obj.insert, obj.cap || obj.caption, { bold: obj.b || obj.bold, italic: obj.i || obj.italic })); } else if (obj.func) { slot = new rast.InsertionSlot({ clickFunc: obj.func, useClickFunc: true, caption: obj.cap || obj.caption || obj.ins }); $.extend(slot, { bold: obj.b || obj.bold, italic: obj.i || obj.italic }); } return slot; }; PlainObjectParser.parseInsertion = function(token, caption) { var n, tagClose, tagOpen; tagOpen = token; tagClose = ''; n = rast.insertion.indexOfUnescaped(token, '+'); if (n > -1) { tagOpen = token.substring(0, n); tagClose = token.substring(n + 1); } tagOpen = rast.insertion.replaceSpecsymbols(tagOpen, '\\_', this.lineReplace); tagClose = rast.insertion.replaceSpecsymbols(tagClose, '\\_', this.lineReplace); if (!caption) { caption = tagOpen + tagClose + ' '; caption = rast.insertion.replaceSpecsymbols(caption, '\\$', function(c) { if (c === '$') { return ''; } else if (c === '\\') { return ''; } }); } return { caption: caption, tagOpen: tagOpen, tagClose: tagClose }; }; PlainObjectParser.slotFromPlainObj = function(obj) { var slot; slot = void 0; if (obj.plain) { slot = new rast.PlainTextSlot({ text: obj.cap || obj.caption, bold: obj.b || obj.bold, italic: obj.i || obj.italic }); } else if (obj.html) { slot = new rast.HtmlSlot({ html: obj.html, onload: obj.onload }); } else { slot = this.generateLink(obj); if (!slot) { return; } } return slot; }; return PlainObjectParser; })(); rast.SubsetsManager = (function() { function SubsetsManager() { this.reset(); } SubsetsManager.prototype.slotById = function(id) { var k, l, len1, len2, ref, ref1, slot, subset; ref = this.subsets; for (k = 0, len1 = ref.length; k < len1; k++) { subset = ref[k]; ref1 = subset.slots; for (l = 0, len2 = ref1.length; l < len2; l++) { slot = ref1[l]; if (slot.id === id) { return slot; } } } return null; }; SubsetsManager.prototype.slotIndex = function(slot) { var k, len1, ref, slotIndex, subset; ref = this.subsets; for (k = 0, len1 = ref.length; k < len1; k++) { subset = ref[k]; slotIndex = subset.slots.indexOf(slot); if (slotIndex > -1) { return slotIndex; } } return null; }; SubsetsManager.prototype.subsetBySlot = function(slot) { var k, len1, ref, subset; ref = this.subsets; for (k = 0, len1 = ref.length; k < len1; k++) { subset = ref[k]; if (subset.slots.indexOf(slot) > -1) { return subset; } } return null; }; SubsetsManager.prototype.subsetBySlotId = function(slot) { var k, l, len1, len2, ref, ref1, subset; ref = this.subsets; for (k = 0, len1 = ref.length; k < len1; k++) { subset = ref[k]; ref1 = subset.slots; for (l = 0, len2 = ref1.length; l < len2; l++) { slot = ref1[l]; if (slot.id === id) { return subset; } } } return null; }; SubsetsManager.prototype.subsetById = function(id) { var k, len1, ref, subset; ref = this.subsets; for (k = 0, len1 = ref.length; k < len1; k++) { subset = ref[k]; if (subset.id === id) { return subset; } } return null; }; SubsetsManager.prototype.addSubset = function(caption, index) { var subset; subset = { caption: caption, slots: [], id: this.uniqueSubsetId() }; return this.insertOrAppend(this.subsets, index, subset); }; SubsetsManager.prototype.deleteSubset = function(subsetToBeRemoved) { return this.subsets = $.grep(this.subsets, function(subset, index) { return subsetToBeRemoved.id !== subset.id; }); }; SubsetsManager.prototype.addSlot = function(slotClassOrSlot, subset, index) { var slot; if (slotClassOrSlot instanceof rast.Slot) { slot = slotClassOrSlot; slot.id = this.uniqueSlotId(); } else { slot = new slotClassOrSlot({ id: this.uniqueSlotId() }); } return this.insertOrAppend(subset.slots, index, slot); }; SubsetsManager.prototype.deleteSlot = function(slotId) { var slot, slotIndex, subset; if (!(typeof slotId === 'number')) { return; } slot = this.slotById(slotId); slotIndex = this.slotIndex(slot); subset = this.subsetBySlot(slot); return subset.slots.splice(slotIndex, 1); }; SubsetsManager.prototype.uniqueSlotId = function() { var result; result = this.slotId; this.slotId++; return result; }; SubsetsManager.prototype.uniqueSubsetId = function() { var result; result = this.subsetId; this.subsetId++; return result; }; SubsetsManager.prototype.insertOrAppend = function(arr, index, item) { if (index) { arr.splice(index, 0, item); } else { arr.push(item); } return item; }; SubsetsManager.prototype.reset = function() { var self; this.subsets = []; self = this; this.slotId = 0; return this.subsetId = 0; }; SubsetsManager.prototype.readEncodedSubsets = function(encodedSubsets) { var j, len, results, subset; results = []; j = 0; len = encodedSubsets.length; while (j < len) { subset = encodedSubsets[j]; results.push(this.readEncodedSubset(subset)); j++; } return results; }; SubsetsManager.prototype.decodeSubset = function(encodedSubset) { var slots; slots = rast.PlainObjectParser.parseTokens(encodedSubset.symbols, this, this); return { slots: slots, caption: encodedSubset.caption }; }; SubsetsManager.prototype.readEncodedSubset = function(encodedSubset) { var internalSubset, k, len1, ref, results1, slot, subset; subset = this.decodeSubset(encodedSubset); internalSubset = this.addSubset(subset.caption); ref = subset.slots; results1 = []; for (k = 0, len1 = ref.length; k < len1; k++) { slot = ref[k]; results1.push(this.addSlot(slot, internalSubset)); } return results1; }; SubsetsManager.prototype.toJSON = function() { return this.subsets; }; SubsetsManager.prototype.deserialize = function(subsets) { return $.each(subsets, (function(_this) { return function(i, subset) { var cons, s, slot; s = _this.addSubset(subset.caption); cons = null; slot = null; return $.each(subset.slots, function(i, plainSlot) { cons = eval(plainSlot['class']); slot = new cons(plainSlot); return _this.addSlot(slot, s); }); }; })(this)); }; return SubsetsManager; })(); rast.UIwindow = (function() { function UIwindow() {} UIwindow.show = function($content) { var EditDialog, editDialog, windowManager; EditDialog = function(config) { return EditDialog["super"].call(this, config); }; OO.inheritClass(EditDialog, OO.ui.Dialog); EditDialog["static"].title = 'Simple dialog'; EditDialog["static"].name = 'Edit dialog'; EditDialog.prototype.initialize = function() { EditDialog["super"].prototype.initialize.call(this); this.$body.append($content); }; EditDialog.prototype.getBodyHeight = function() { return $content.outerHeight(true); }; editDialog = new EditDialog({ size: 'large' }); windowManager = new OO.ui.WindowManager; $('body').append(windowManager.$element); windowManager.addWindows([editDialog]); windowManager.openWindow(editDialog); return editDialog; }; return UIwindow; })(); rast.SlotAttributesEditor = (function() { function SlotAttributesEditor(options) { this.slot = options.slot; this.slotsManager = options.slotsManager; this.allInputs = []; } SlotAttributesEditor.prototype.fieldsetForAttrs = function(fieldsetName, attrs) { var OOinput, attribute, fieldOptions, fields, fieldset, inputData, inputs, k, len1, type, value; inputs = []; for (k = 0, len1 = attrs.length; k < len1; k++) { attribute = attrs[k]; value = this.slot[attribute.name]; type = attribute.type; OOinput = type === 'string' ? (fieldOptions = { value: value }, { getValue: 'getValue', OOobject: new OO.ui.TextInputWidget(fieldOptions) }) : type === 'text' ? (fieldOptions = { value: value, rows: 3, autosize: true }, { getValue: 'getValue', OOobject: new OO.ui.MultilineTextInputWidget(fieldOptions) }) : type === 'boolean' ? { getValue: 'getValue', OOobject: new OO.ui.ToggleSwitchWidget({ value: value }) } : void 0; inputData = { attribute: attribute.name, label: attribute.caption, input: OOinput.OOobject, getValueFunc: OOinput.getValue, labelAlignment: attribute.labelAlignment || 'left', helpText: attribute.help }; if (OOinput) { this.allInputs.push(inputData); inputs.push(inputData); } } fieldset = new OO.ui.FieldsetLayout({ label: fieldsetName }); fields = $.map(inputs, function(inputWrapper, index) { return new OO.ui.FieldLayout(inputWrapper.input, { label: inputWrapper.label, align: inputWrapper.labelAlignment, help: inputWrapper.helpText }); }); fieldset.addItems(fields); return fieldset; }; SlotAttributesEditor.prototype.startEditing = function() { var $content, attrs, bottomButtons, cancelButton, dialog, fieldset, panel, removeButton, saveButton, slotClass; slotClass = this.slot.constructor; attrs = slotClass.editableAttributes; $content = $('<div class="rastEditWindow">'); if (attrs.view) { fieldset = this.fieldsetForAttrs('Вигляд', attrs.view); $content.append(fieldset.$element); } if (attrs.functionality) { fieldset = this.fieldsetForAttrs('Функціонал', attrs.functionality); $content.append(fieldset.$element); } saveButton = new OO.ui.ButtonWidget({ icon: 'check', label: 'Зберегти' }); saveButton.on('click', (function(_this) { return function() { var inputWrapper, k, len1, ref; ref = _this.allInputs; for (k = 0, len1 = ref.length; k < len1; k++) { inputWrapper = ref[k]; _this.slot[inputWrapper.attribute] = inputWrapper.input[inputWrapper.getValueFunc](); } _this.slotsManager.onSlotSaved(); return dialog.close(); }; })(this)); cancelButton = new OO.ui.ButtonWidget({ icon: 'cancel', label: 'Скасувати' }); cancelButton.on('click', function() { return dialog.close(); }); removeButton = new OO.ui.ButtonWidget({ icon: 'remove', label: 'Вилучити комірку' }); removeButton.on('click', (function(_this) { return function() { var base; if (typeof (base = _this.slotsManager).onDeleteSlot === "function") { base.onDeleteSlot(_this.slot.id); } return dialog.close(); }; })(this)); bottomButtons = new OO.ui.HorizontalLayout({ items: [saveButton, cancelButton, removeButton], classes: ['bottomButtons'] }); $content.append(bottomButtons.$element); panel = new OO.ui.PanelLayout({ $: $, padded: true, expanded: false }); panel.$element.append($content); return dialog = rast.UIwindow.show(panel.$element); }; return SlotAttributesEditor; })(); rast.SlotAttributes = (function() { function SlotAttributes(attrsObj) { $.extend(this, attrsObj); } SlotAttributes.prototype.toArray = function() { var result; result = []; if (this.view) { result = result.concat(this.view); } if (this.functionality) { result = result.concat(this.functionality); } return result; }; return SlotAttributes; })(); rast.Slot = (function() { Slot.editableAttributes = new rast.SlotAttributes({}); Slot.editorClass = rast.SlotAttributesEditor; function Slot(options) { var attribute, k, len1, ref; if (options == null) { options = {}; } ref = this.constructor.editableAttributes.toArray(); for (k = 0, len1 = ref.length; k < len1; k++) { attribute = ref[k]; this[attribute.name] = attribute["default"]; } $.extend(this, options, { 'class': 'rast.' + this.constructor.name }); } Slot.prototype.generateEditHtml = function() { var $element; $element = this.generateHtml(); $($element).addClass('editedSlot'); return $element; }; Slot.prototype.toJSON = function() { var defaults, res, sanitized; defaults = new this.constructor; defaults = defaults.sanitizedAttributes(); sanitized = this.sanitizedAttributes(); res = {}; Object.keys(sanitized).forEach((function(_this) { return function(key) { if ((sanitized[key] !== defaults[key]) && defaults.hasOwnProperty(key)) { return res[key] = sanitized[key]; } }; })(this)); res['class'] = this['class']; delete res['id']; return res; }; Slot.prototype.sanitizedAttributes = function() { return rast.clone(this); }; return Slot; })(); rast.PlainTextSlot = (function(superClass) { extend(PlainTextSlot, superClass); function PlainTextSlot() { return PlainTextSlot.__super__.constructor.apply(this, arguments); } PlainTextSlot.caption = 'Простий текст'; PlainTextSlot.editableAttributes = new rast.SlotAttributes({ view: [ { name: 'css', type: 'text', "default": '', caption: 'CSS-стилі' }, { name: 'text', type: 'text', "default": 'текст', caption: 'Текст', labelAlignment: 'top' } ] }); PlainTextSlot.prototype.generateEditHtml = function() { var $elem; $elem = PlainTextSlot.__super__.generateEditHtml.call(this); return $elem.attr('title', this.text); }; PlainTextSlot.prototype.generateHtml = function(styles) { var $elem; $elem = $('<span>'); $elem.text(this.text); $elem.attr('data-id', this.id); $elem.attr('style', styles || this.css); return $elem; }; return PlainTextSlot; })(rast.Slot); rast.InsertionSlot = (function(superClass) { extend(InsertionSlot, superClass); function InsertionSlot() { return InsertionSlot.__super__.constructor.apply(this, arguments); } InsertionSlot.caption = 'Одна вставка'; InsertionSlot.editableAttributes = new rast.SlotAttributes({ view: [ { name: 'css', type: 'text', "default": '', caption: 'CSS-стилі' }, { name: 'caption', caption: 'Напис', type: 'text', "default": 'Нова вставка' }, { name: 'captionAsHtml', caption: 'Сприймати напис, як html-код?', type: 'boolean', "default": false } ], functionality: [ { name: 'insertion', caption: 'Текст вставки', type: 'text', "default": '$', labelAlignment: 'top', help: 'Символ долара "$" буде замінено на виділений текст. Перший символ додавання "+" позначає місце каретки після вставлення.\nЯкщо хочете екранувати ці символи, поставте "\\" перед потрібним символом; наприклад "\\$" вставлятиме знак долара.' }, { name: 'useClickFunc', caption: 'Замість вставляння виконати іншу дію?', type: 'boolean', "default": false }, { name: 'clickFunc', caption: 'Інша дія (при клацанні)', type: 'text', "default": '', labelAlignment: 'top' } ] }); InsertionSlot.insertFunc = function(insertion) { var tags; rast.$getTextarea().focus(); tags = rast.PlainObjectParser.parseInsertion(insertion, ''); return rast.$getTextarea().insertTag(tags.tagOpen, tags.tagClose); }; InsertionSlot.prototype.sanitizedAttributes = function() { var copy; copy = rast.clone(this); copy.clickFunc = $.trim(this.clickFunc); return copy; }; InsertionSlot.prototype.generateEditHtml = function() { var $elem; $elem = InsertionSlot.__super__.generateEditHtml.call(this); $elem.attr('title', (this.useClickFunc && this.clickFunc) || this.insertion); return $elem.append($('<div class="overlay">')); }; InsertionSlot.prototype.generateCommonHtml = function(styles) { var $a, $elem, caption; if (this.captionAsHtml) { $elem = $('<div>'); $elem.append(this.caption); $elem.attr('data-id', this.id); if (styles && styles.length) { $elem.attr('style', styles); } return $elem; } else { $a = $('<a>'); $a.attr('data-id', this.id); if (styles && styles.length) { $a.attr('style', styles); } caption = $('<div/>').text(this.caption).html(); $a.html(caption); return $a; } }; InsertionSlot.prototype.generateHtml = function(styles) { var $elem; $elem = this.generateCommonHtml(styles || this.css); $elem.click((function(_this) { return function(event) { event.preventDefault(); if (_this.useClickFunc) { return eval(_this.clickFunc); } else { return rast.InsertionSlot.insertFunc(_this.insertion); } }; })(this)); return $elem; }; return InsertionSlot; })(rast.Slot); rast.MultipleInsertionsSlot = (function(superClass) { extend(MultipleInsertionsSlot, superClass); function MultipleInsertionsSlot() { return MultipleInsertionsSlot.__super__.constructor.apply(this, arguments); } MultipleInsertionsSlot.caption = 'Набір вставок'; MultipleInsertionsSlot.editableAttributes = new rast.SlotAttributes({ view: [ { name: 'css', type: 'text', "default": '', caption: 'CSS-стилі' } ], functionality: [ { name: 'insertion', caption: 'Вставки', type: 'text', "default": 'вставка_1 ·п вставка_2', labelAlignment: 'top', help: 'Все, що розділене символами пробілу, вважається окремою коміркою.\nЯкщо комірка закірчується символом "п", вона вважатиметься не вставкою, а простим текстом.\nЯкщо хочете включити пробіл у вставку, пишіть нижнє підкреслення: "_".\nСимвол долара "$" буде замінено на виділений текст. Перший символ додавання "+" позначає місце каретки після вставлення.\nЯкщо хочете екранувати ці символи, поставте "\\" перед потрібним символом; наприклад "\\$" вставлятиме знак долара.' } ] }); MultipleInsertionsSlot.insertFunc = function(insertion) { var tags; rast.$getTextarea().focus(); tags = rast.PlainObjectParser.parseInsertion(insertion, ''); return rast.$getTextarea().insertTag(tags.tagOpen, tags.tagClose); }; MultipleInsertionsSlot.prototype.generateEditHtml = function() { var $elem; $elem = MultipleInsertionsSlot.__super__.generateEditHtml.call(this); $elem.attr('title', this.insertion); return $elem.prepend($('<div class="overlay">')); }; MultipleInsertionsSlot.prototype.generateCommonHtml = function(styles) { var $elem, $slot, k, len1, slot, slots; slots = rast.PlainObjectParser.slotsFromStr(this.insertion); $elem = $('<div>'); $elem.attr('data-id', this.id); if (styles && styles.length) { $elem.attr('style', styles); } for (k = 0, len1 = slots.length; k < len1; k++) { slot = slots[k]; $slot = $(slot.generateHtml(styles)); $elem.append($slot); } return $elem; }; MultipleInsertionsSlot.prototype.generateHtml = function(styles) { return this.generateCommonHtml(styles || this.css); }; return MultipleInsertionsSlot; })(rast.Slot); rast.HtmlSlot = (function(superClass) { extend(HtmlSlot, superClass); HtmlSlot.caption = 'Довільний код'; HtmlSlot.editableAttributes = new rast.SlotAttributes({ view: [ { name: 'html', type: 'text', "default": '<span>html</span>', caption: 'HTML', labelAlignment: 'top' } ], functionality: [ { name: 'onload', type: 'text', "default": '', caption: 'JavaScript, що виконається при ініціалізації', labelAlignment: 'top' } ] }); HtmlSlot.prototype.sanitizedAttributes = function() { var copy; copy = rast.clone(this); copy.onload = $.trim(this.onload); return copy; }; function HtmlSlot(options) { HtmlSlot.__super__.constructor.call(this, options); this.onload = $.trim(this.onload); if (this.onload.length) { editTools.addOnloadFunc((function(_this) { return function() { try { return eval(_this.onload); } catch (_error) {} }; })(this)); } } HtmlSlot.prototype.generateEditHtml = function() { var $elem; $elem = HtmlSlot.__super__.generateEditHtml.call(this); return $elem.attr('title', this.html); }; HtmlSlot.prototype.generateHtml = function() { var $elem, $overlay, $wrapper; $elem = $(this.html); $wrapper = $('<div>'); $wrapper.attr('data-id', this.id); $wrapper.append($elem); $overlay = $('<div class="overlay">'); $wrapper.append($overlay); return $wrapper; }; return HtmlSlot; })(rast.Slot); rast.PageStorage = (function() { function PageStorage() {} PageStorage.load = function(pagename, onLoaded, handler) { var api; api = new mw.Api; return api.get({ action: 'query', prop: 'revisions', rvprop: 'content', titles: pagename }).done(function(data) { var pageId, results1; results1 = []; for (pageId in data.query.pages) { if (data.query.pages[pageId].revisions) { results1.push(typeof onLoaded === "function" ? onLoaded(data.query.pages[pageId].revisions[0]['*']) : void 0); } else { results1.push(typeof handler.onSubpageNotFound === "function" ? handler.onSubpageNotFound(pageId) : void 0); } } return results1; }).fail(function() { return handler.onReadFromSubpageError(); }).always(function() { return handler.onEndReadingSubpage(); }); }; PageStorage.save = function(pagename, string, handler, summary) { var api; api = new mw.Api; return api.postWithEditToken({ action: 'edit', title: pagename, summary: summary, text: string }).done(function() { return handler.onSavedToSubpage(pagename); }).fail(function() { return handler.onSaveToSubpageError(pagename); }).always(function() { return handler.onEndSavingToSubpage(); }); }; return PageStorage; })(); $(function() { window.editTools = { onloadFuncs: [], mode: 'view', addOnloadFunc: (function(_this) { return function(func) { return editTools.onloadFuncs.push(func); }; })(this), fireOnloadFuncs: function() { var func, k, len1, ref, results1; ref = editTools.onloadFuncs; results1 = []; for (k = 0, len1 = ref.length; k < len1; k++) { func = ref[k]; results1.push(func()); } return results1; }, extraCSS: '#edittools .etPanel { margin-top: 5px; }\n#edittools .etPanel .slots [data-id] { margin: -1px -1px 0px 0px; }\n#edittools .etPanel .slots [data-id]:hover { z-index: 1; text-decoration: none; }\n#edittools .etPanel > [data-id], #edittools .etPanel .preview [data-id] { display: inline; padding: 0px 2px; }\n#edittools .etPanel > a[data-id], #edittools .etPanel .preview a[data-id] { cursor: pointer; }\n#edittools { min-height: 20px; }\n#edittools .rastMenu.view { position: absolute; left: -5px; }\n#edittools .rastMenu.edit { border-bottom: solid #aaaaaa 1px; padding: 2px 6px; }\n#edittools .slots.ui-sortable { min-height: 4em; border-width: 1px; border-style: dashed; margin: 5px 0px; background-color: white; }\n#edittools .slots.ui-sortable .emptyHint { }\n#edittools .editedSlot {\n cursor: pointer;\n min-width: 1em;\n min-height: 1em;\n border: 1px solid grey;\n margin-left: -1px;\n position: relative;\n display: block;\n}\n#edittools .editedSlot .overlay { width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; }\n#edittools .slotClasses { text-align: center; }\n#edittools .slotClass { cursor: copy; padding: 3px 5px; border: 1px solid grey; margin-left: 5px; }\n#edittools .panelRemoveButton, #edittools .menuButton { cursor: pointer; }\n#edittools .gear {\n min-height: 15px;\n min-width: 15px;\n cursor: pointer;\n}\n#edittools .ui-state-highlight {\n min-width: 1em;\n min-height: 1em;\n display: inline-block;\n}\n#edittools .ui-sortable-helper { min-width: 1em; min-height: 1em; }\n.specialchars-tabs {float: left; background: #E0E0E0; margin-right: 7px; }\n.specialchars-tabs a{ display: block; padding-left: 3px; }\n#edittools { border: solid #aaaaaa 1px; }\n.mw-editTools a{ cursor: pointer; }\n.overflowHidden { overflow: hidden; }\n.specialchars-tabs .asnav-selectedtab { background: #eaecf0; border-left: 2px solid #aaaaaa; }\n#edittools .highlighted { opacity: 0.5; }\n#edittools [data-id]:hover { border-color: red; }\n#edittools .notFoundWarning { padding: 4px; }\n#edittools .newPanelButton { padding: 4px; border-bottom: solid #aaaaaa 1px; }\n#edittools .removeIcon {\n background-image: url(\'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Ambox_delete_soft.svg/15px-Ambox_delete_soft.svg.png?uselang=uk\');\n display: inline-block;\n width: 15px;\n height: 15px;\n margin: 0px 0px 2px 4px;\n vertical-align: middle;\n}\n#edittools .panelNameLabel { margin-right: 5px; }\n#edittools .panelRemoveButton { margin-left: 20px; }\n#edittools .etPanel > .slots {\n padding: 6px 1px;\n border: 1px black dashed;\n overflow: auto;\n max-height: 240px;\n}\n.rastEditWindow .bottomButtons { margin-top: 10px; }\n\n#edittools .aboutLink { float: right; }\n}', appendExtraCSS: function() { mw.util.addCSS(this.extraCSS); }, parentId: '.mw-editTools', id: 'edittools', cookieName: 'edittool', createEditTools: function() { var $tabs, self; $tabs = $('<div></div>').attr('id', this.id); self = this; $tabs.on('click', '.asnav-content .etPanel .slots [data-id]', function($e) { var id, slot; if (editTools.mode === 'edit') { id = parseInt($(this).closest('.editedSlot').attr('data-id')); slot = editTools.temporarySubsets.slotById(id); return editTools.editWindow(slot); } }); return $tabs; }, editWindow: function(slot) { var editor; editor = new slot.constructor.editorClass({ slot: slot, slotsManager: this }); return editor.startEditing(); }, onDeleteSlot: function(slotId) { var id; id = parseInt(slotId); this.temporarySubsets.deleteSlot(id); return this.refresh(); }, edit: function() { this.mode = 'edit'; $('#' + this.id).find('.notFoundWarning').remove(); return this.refresh(); }, view: function() { this.mode = 'view'; return this.refresh(); }, reset: function() { this.onloadFuncs = []; return this.subsets.reset(); }, readFromSpecialSyntaxObject: function(obj) { if (!obj) { return false; } this.reset(); this.subsets.readEncodedSubsets(obj); this.resetTemporarySubsets(); this.refresh(); return true; }, resetTemporarySubsets: function() { return this.temporarySubsets = rast.clone(this.subsets); }, refresh: function() { var $tabs, etActiveTab; if (!this.created) { return; } $tabs = $('#' + this.id); etActiveTab = $tabs.find('.existingTabs .asnav-selectedtab').attr('data-contentid') || mw.cookie.get(editTools.cookieName + 'Selected') || 'etTabContent0'; this.drawer.$container = $tabs; this.drawer.mode = this.mode; this.drawer.subsets = this.temporarySubsets; this.drawer.message = this.message; this.message = null; this.drawer.activeTab = etActiveTab; this.drawer.draw(); setTimeout((function(_this) { return function() { return _this.fireOnloadFuncs(); }; })(this), 0); return $tabs.on('asNav:select', function(ev, selectedId) { return mw.cookie.set(editTools.cookieName + 'Selected', selectedId); }); }, save: function() { this.subsets = this.temporarySubsets; this.resetTemporarySubsets(); return this.view(); }, restoreDefaults: function() { return this.readFromSubpage('User:AS/defaults.js'); }, init: function() { var $placeholder, $tabs, etActiveTab; $tabs = $('#' + this.id); etActiveTab = $tabs.find('.existingTabs .asnav-selectedtab').attr('data-contentid') || mw.cookie.get(editTools.cookieName + 'Selected') || 'etTabContent0'; this.onSaveClick = (function(_this) { return function() { return _this.save(); }; })(this); this.onCancelClick = (function(_this) { return function() { _this.resetTemporarySubsets(); return _this.view(); }; })(this); this.onResetClick = (function(_this) { return function() { return _this.restoreDefaults(); }; })(this); this.onEditClick = (function(_this) { return function() { return _this.edit(); }; })(this); this.onTabNameChanged = (function(_this) { return function(event) { event.data.subsetWrapper.caption = $(event.target).val(); return _this.refresh(); }; })(this); this.onAddSubsetClick = (function(_this) { return function() { var subset; subset = _this.temporarySubsets.addSubset('Нова панель', _this.temporarySubsets.subsets.length); _this.refresh(); $tabs = $('#' + _this.id); return $tabs.asnavSelect('etTabContent' + subset.id); }; })(this); this.onRemoveSubsetClick = (function(_this) { return function(subsetWrapper) { _this.temporarySubsets.deleteSubset(subsetWrapper); return _this.refresh(); }; })(this); this.onSlotAdded = (function(_this) { return function() { return _this.refresh(); }; })(this); this.onPersistClick = (function(_this) { return function() { _this.save(); $tabs = $('#' + _this.id); $tabs.throbber(true, 'prepend'); return _this.saveToSubpage(); }; })(this); this.onSlotRemoved = (function(_this) { return function() { return _this.refresh(); }; })(this); this.drawer = new rast.Drawer(); $.extend(this.drawer, { docLink: this.docLink, onTabClick: null, eventsHandler: this }); $placeholder = $(this.parentId); if (!$placeholder.length) { return; } this.appendExtraCSS(); $placeholder.empty().append(this.createEditTools()); $('input#wpSummary').attr('style', 'margin-bottom: 3px;'); this.created = true; this.temporarySubsets = new rast.SubsetsManager; return this.reload(); }, reload: function() { var $tabs; $tabs = $('#' + this.id); $tabs.throbber(true, 'prepend'); return this.readFromSubpage(this.subpage(), (function(_this) { return function() { _this.subsets = rast.clone(_this.temporarySubsets); return _this.refresh(); }; })(this)); }, docLink: 'https://uk.wikipedia.org/wiki/%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D1%82%D1%83%D0%B2%D0%B0%D1%87:AS/%D0%9F%D0%9F%D0%A1-2', editButtonHtml: function() { return this.drawer.$editButtonIcon().prop('outerHTML'); }, showMessage: function(html) { this.message = html; return this.refresh(); }, onSubpageNotFound: function() { return this.showMessage("<div class=\"notFoundWarning\">Це повідомлення від додатка <a href=\"" + this.docLink + "\">Покращеної панелі спецсимволів</a> (Налаштування -> Додатки -> Редагування). Підсторінку із символами не знайдено або не вдалося завантажити. Це нормально, якщо ви ще не зберегли жодну версію. Натисніть зліва від панелі на " + (this.editButtonHtml()) + ", щоб редагувати символи.</div>"); }, serialize: function() { return JSON.stringify(this.subsets, null, 2); }, subpageStorageName: 'AStools.js', saveToSubpage: function() { return this.serializeToPage(this.subpage(), '[[Обговорення користувача:AS/rast.js|serialize]]'); }, subpage: function() { return 'User:' + mw.config.get('wgUserName') + '/' + this.subpageStorageName; }, trackingPage: 'User:AS/track', serializeToPage: function(pagename) { var serializedTools; serializedTools = "[[" + this.trackingPage + "]]<nowiki>" + (this.serialize()) + "</nowiki>"; return rast.PageStorage.save(pagename, serializedTools, this); }, subpageName: function() { return 'User:' + mw.config.get('wgUserName') + '/' + this.subpageStorageName; }, readFromSubpage: function(pagename, doneFunc) { var json; return json = rast.PageStorage.load(pagename || this.subpageName(), (function(_this) { return function(pagetext) { var pagetextWithoutNowiki, serializedTools; pagetextWithoutNowiki = pagetext.replace(/^(\[\[[^\]]+\]\])?<nowiki>/, '').replace(/<\/nowiki>$/, ''); serializedTools = JSON.parse(pagetextWithoutNowiki); _this.temporarySubsets.reset(); _this.temporarySubsets.deserialize(serializedTools); _this.refresh(); if (doneFunc != null) { return doneFunc(); } }; })(this), this); }, onReadFromSubpageError: function() { return this.showMessage("<div class=\"readingSubpageError\">Не вдалося завантажити підсторінку з символами.</div>"); }, onEndReadingSubpage: function() { var $tabs; $tabs = $('#' + this.id); return $tabs.throbber(false); }, onSavedToSubpage: function(pagename) { return mw.notify($("<span>Збережено на <a href='" + (mw.util.getUrl(pagename)) + "'>" + pagename + "</a></span>")); }, onSaveToSubpageError: function(pagename) { return mw.notify($("<span>Не вдалося зберегти на <a href='" + (mw.util.getUrl(pagename)) + "'>" + pagename + "</a></span>")); }, onEndSavingToSubpage: function() { var $tabs; $tabs = $('#' + this.id); return $tabs.throbber(false); }, setupOnEditPage: function() { if (mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit') { rast.installJQueryPlugins(); return editTools.init(); } }, onSlotSaved: function() { return this.refresh(); } }; rast.PlainObjectParser.addOnloadFunc = editTools.addOnloadFunc; return $(function() { return mw.loader.using(['mediawiki.cookie', 'oojs-ui', 'mediawiki.api', 'jquery.ui.sortable', 'jquery.ui.droppable', 'jquery.ui.draggable'], function() { return editTools.setupOnEditPage(); }); }); });