Увага: Після публікування слід очистити кеш браузера, щоб побачити зміни.

  • Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
  • Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
  • Internet Explorer / Edge: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
  • Opera: натисніть Ctrl-F5
/*
*****************************************
* Щоб увімкнути додаток, зайдіть у ваші налаштування, відкрийте вкладку «Додатки»
* та поставте галочку навпроти тексту «Дозволяє швидко номінувати статтю на повільне вилучення»
* (розділ «Редагування»)
*****************************************
* @author RLuts & others (see: https://uk.wikipedia.org/w/index.php?title=MediaWiki:Gadget-NominateToDel.js&action=history)
* for ukwiki only
* @ver 1.2
*/

//<nowiki>
if (typeof(window.NominateToDel) == 'undefined') {
  var DEBUG = mw.config.get('debug');
  window.NominateToDel = {

    install: function () {
      if($.inArray('Статті-кандидати на вилучення', mw.config.get('wgCategories')) >= 0) {
        return;
      }
      //Текст
      this.talkPrefix = "Вікіпедія:Статті-кандидати на вилучення";
      this.preloadPage = "Вікіпедія:Статті-кандидати на вилучення/Заготовка";
      this.userTalkPrefix = 'User_talk:';
      this.nomText = 'Номінувати на вилучення';
      this.emptyReason = "Введіть причину номінації";
      this.summary = 'Статтю {article} номіновано на вилучення ([[Вікіпедія:Додатки/NominateForDel|NominateForDel.js]])';
      this.addTemplateSummary = 'Статтю номіновано на вилучення ([[Вікіпедія:Додатки/NominateForDel|NominateForDel.js]])';
      this.userTalkSummary = 'Статтю {article} номіновано на вилучення ([[Вікіпедія:Додатки/NominateForDel|NominateForDel.js]])';

      /* Для відлагодження додатку. Прохання не вилучати!!! У режимі «debug» замість префікса «Вікіпедія:Статті-кандидати на вилучення», «User_talk:»
      * сторінки зберігаються в наступних префіксах:
      */
      if(DEBUG) {
        this.talkPrefix = "User:RLuts/scripttest";
        this.userTalkPrefix = 'User:RLuts/scripttest/User_talk:';
      }

      var ntd = this;
      var link = mw.util.addPortletLink( 'p-cactions', '#',  this.nomText );
      $( link ).click( function ( e ) {
        e.preventDefault();
        ntd.showDialog();
      });
    },
    
    initEditor: function() {
    	var DesktopTarget = function ( config ) {
    		DesktopTarget.super.call( this, config );
    	}
    	OO.inheritClass( DesktopTarget, ve.init.mw.DesktopArticleTarget );
    	DesktopTarget.prototype.getEditableContent = function () {
			return $( '#ntd-reasonbox' );
		};
		DesktopTarget.static.actionGroups = [
			{
				name: 'help',
				include: [ 'help', 'notices' ]
			},
			{
				name: 'pageMenu',
				type: 'list',
				icon: 'menu',
				indicator: null,
				title: ve.msg( 'visualeditor-pagemenu-tooltip' ),
				label: ve.msg( 'visualeditor-pagemenu-tooltip' ),
				invisibleLabel: true,
				include: [ 'meta', 'categories', 'settings', 'advancedSettings', 'languages', 'templatesUsed', 'changeDirectionality', 'findAndReplace' ]
			},
			{
				name: 'editMode',
				type: 'list',
				icon: 'edit',
				title: ve.msg( 'visualeditor-mweditmode-tooltip' ),
				label: ve.msg( 'visualeditor-mweditmode-tooltip' ),
				invisibleLabel: true,
				include: [ 'editModeSource' ]
			}
		];
		DesktopTarget.prototype.setupToolbarSaveButton = function () {};
		DesktopTarget.prototype.updateToolbarSaveButtonState = function () {};
		DesktopTarget.prototype.updateTabs = function () {};
		DesktopTarget.prototype.storeDocState = function () {};
		DesktopTarget.prototype.initAutosave = function () {};
		DesktopTarget.prototype.loadSuccess = function ( response ) {
			var mode, section,
			data = response ? ( response.visualeditor || response.visualeditoredit ) : null;
			console.log(data)
			this.track( 'trace.parseResponse.enter' );
			this.originalHtml = '';
			this.etag = null;
			this.fromEditedState = false;
			this.switched = false;
			mode = this.getDefaultMode();
			this.doc = this.constructor.static.parseDocument( this.originalHtml, 'source', false );
			this.originalDmDocPromise = null;
			this.recovered = false;
	
			// Parse data this not available in RESTBase
			if ( !this.parseMetadata( response ) ) {
				// Invalid metadata, loadFail() or load() has been called
				return;
			}
	
			this.track( 'trace.parseResponse.exit' );
	
			// Everything worked, the page was loaded, continue initializing the editor
			this.documentReady( this.doc );
		
		};
		this.Editor = new DesktopTarget({defaultMode: 'source', modes: ['source']});
    },

    initDialogs: function () {
      var ntd = this;
      function ProcessDialog( config ) {
        ProcessDialog.super.call( this, config );
      }
      OO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );
      function PreviewedLayout( name, config ) {
        PreviewedLayout.super.call( this, name, config );
      }
      OO.inheritClass( PreviewedLayout, OO.ui.TabPanelLayout );
      PreviewedLayout.prototype.toggle = function(show) {
        PreviewedLayout.super.prototype.toggle.apply( this, [show] );
        if(show) {
          this.$element.append('<div id="ntd-preview"></div>');
          ntd.preview();
        }
        else {
          var $preview = this.$element.find('#ntd-preview');
          if ($preview.length) {
            $preview.remove()
          }
        }
      }
      

      var tabPanel1 = new OO.ui.TabPanelLayout( 'main', { label: 'Редактор' } );
      var tabPanel2 = new PreviewedLayout( 'preview', { label: 'Попередній перегляд' } );
	  this.initEditor()
      tabPanel1.$element.append( '<p style="font-size:.8em; color:red">Цей інструмент дозволяє створити нове обговорення на сторінці <a style="color:red; text-decoration:underline" href="https://uk.wikipedia.org/wiki/Вікіпедія:ВИЛ">ВП:ВИЛ</a>. Підпис додається автоматично</p>' );
      tabPanel1.$element.append('<div id="ntd-reasonbox"></div>');
      tabPanel1.$element.append(this.Editor.$element);
      this.Editor.activate();
		window.Editor = this.Editor;  // TODO: remove it
      var index = new OO.ui.IndexLayout();

      index.addTabPanels( [ tabPanel1, tabPanel2 ] );

      ProcessDialog.static.name = 'myProcessDialog';
      ProcessDialog.static.title = this.nomText;
      ProcessDialog.static.size = 'full';
      ProcessDialog.static.actions = [
        { action: 'save', label: 'Зберегти', flags: ['primary', 'progressive'] },
        { label: 'Скасувати', flags: 'safe' }
      ];
      ProcessDialog.prototype.initialize = function () {
        ProcessDialog.super.prototype.initialize.apply( this, arguments );
        this.content = index;
        this.content.$element.append( index.$element );
        this.$body.append( this.content.$element );
      };
      ProcessDialog.prototype.getActionProcess = function ( action ) {
        var dialog = this;
        if (action === 'save') {
          return new OO.ui.Process(function () {
            ntd.check();
          });
        }
        	return new OO.ui.Process(function () { 
        		ntd.windowManager && ntd.windowManager.destroy();
        	});
      };
      ProcessDialog.prototype.getBodyHeight = function () {
        return this.content.$element.outerHeight( true );
      };

      this.processDialog = ProcessDialog;
    },

    showDialog: function () {
      this.initDialogs();
      this.windowManager = new OO.ui.WindowManager();
      $( document.body ).append( this.windowManager.$element );
      this.dialog = new this.processDialog();
      window.Dialog = this.dialog;  // TODO: remove it
      this.windowManager.addWindows( [ this.dialog ] );
      this.windowManager.openWindow( this.dialog );
      window.windowManager = this.windowManager;
    },

    preview: function () {
	  var ntd = this; 
      var reason = this.generateText(this.Editor.surface.getHtml()).replace(/~~~~/g, mw.user.options.get('nickname'));
      var param = {
        action: 'parse',
        format: 'json',
        prop: 'text',
        text: reason
      };
      $.get(mw.util.wikiScript('api'), param).done(function(data) {
        $('#ntd-preview').html(data.parse.text['*']);
      });
    },

    check: function () {
      var reason = this.Editor.surface.getHtml();
      if( this.isEmpty( reason ) ) {
        $('#ntd-dialog').append( '<p style="font-size:80%; color:red">' + this.emptyReason + '</p>' );
        return 0;
      } else {
        this.reason = this.Editor.surface.getHtml()
        this.wait('Створюється нове обговорення на сторінці ВП:ВИЛ');
        this.getDate();
      }
    },

    getDate: function () {
      var ntd = this;
      var curtime;
      var param = {
        action: 'query',
        format: 'json',
        meta: 'siteinfo',
        siprop: 'general'
      };
      $.get(mw.util.wikiScript('api'), param).done(function(data) {
        curtime = data.query.general.time;
        var reg = /([0-9]{4})-([0-9]{2})-([0-9]{2})/;
        var arr = reg.exec(curtime);
        var year = arr[1];
        var mon;
        switch(arr[2]) {
          case "01": mon = ' січня '; break;
          case "02": mon = ' лютого '; break;
          case "03": mon = ' березня '; break;
          case "04": mon = ' квітня '; break;
          case "05": mon = ' травня '; break;
          case "06": mon = ' червня '; break;
          case "07": mon = ' липня '; break;
          case "08": mon = ' серпня '; break;
          case "09": mon = ' вересня '; break;
          case "10": mon = ' жовтня '; break;
          case "11": mon = ' листопада '; break;
          case "12": mon = ' грудня '; break;
        }
        var day = arr[3];
        var dayreg = /0([1-9])/;
        if(dayreg.exec(day)) {
          day = dayreg.exec(day)[1];
        }
        ntd.date = day + mon + year;
        ntd.getTalkPage(ntd.talkPrefix + "/" + day + mon + year);
      });
    },

    generateText: function (reason) {
      var nominatedGender = mw.user.options.get('gender') === 'female' ? 'Поставила' : 'Поставив';
      return '\n\n== [[' + mw.config.get('wgPageName').replace(/_/g,' ').replace('Файл:', ':Файл:') + ']] ==\n* \'\'\'' + nominatedGender + ':\'\'\' --~~~~\n* {{За}}:\n# ' + $.trim(reason) + ' --~~~~\n* {{Проти}}:\n* {{Утримаюсь}}:\n';
    },

    getTalkPage: function (page) {
      var ntd = this;
      var talkcont;
      var param = {
        action: 'query',
        format: 'json',
        rvprop: 'ids',
        rvlimit: '1',
        prop: 'revisions',
        titles: page
      };
      $.get(mw.util.wikiScript('api'), param).done(function(data) {
        param.rvprop = 'content|timestamp';
        param.indexpageids = '';
        if(data.query.pages[-1]) {
          param.titles = ntd.preloadPage;
          $.get(mw.util.wikiScript('api'), param).done(function(data) {
            talkcont = data.query.pages[data.query.pageids[0]].revisions[0]['*'].split('-->')[0] + '-->' + ntd.generateText(ntd.reason);
            ntd.addTalk(page, talkcont);
          });
        } else {
          param.titles = page;
          $.get(mw.util.wikiScript('api'), param).done(function(data) {
            talkcont = data.query.pages[data.query.pageids[0]].revisions[0]['*'] + ntd.generateText(ntd.reason);
            var timestamp = data.query.pages[data.query.pageids[0]].revisions[0].timestamp;
            ntd.addTalk(page, talkcont, timestamp);
          });
        }
      });
    },

    addTalk: function (pgtalk, talkcont, timestamp) {
      var ntd = this;
      var t = '';
      if(mw.config.get( 'wgNamespaceNumber' ) === 6) t = ':';
      this.writeInPage( pgtalk, talkcont, timestamp, this.summary.replace('{article}', '[[' + t + mw.config.get('wgPageName') + ']]').replace(/_/g,' '), null, null, function() {
        ntd.addTemplate();
      });
    },

    addTemplate: function () {
      var ntd = this;
      this.wait('Додається шаблон {{delete}} на сторінку ' + mw.config.get( 'wgPageName' ).replace(/_/g,' '));
      this.writeInPage( mw.config.get( 'wgPageName' ), '{{subst:afd}}\n', '', this.addTemplateSummary, 'prependtext', null, function () {
        ntd.getCreator();
      });
    },

    getCreator: function () {
      var ntd = this;
      this.wait('Додається повідомлення на сторінку обговорення автора статті');
      var param = {
        action: 'query',
        prop: 'revisions',
        format: 'json',
        rvlimit: '1',
        rvdir: 'newer',
        rvprop: 'user',
        indexpageids: '',
        titles: mw.config.get ( 'wgPageName' )
      };
      $.get(mw.util.wikiScript('api'), param).done(function(data) {
        if(data.query.pages[data.query.pageids[0]].revisions[0].anon === undefined && data.query.pages[data.query.pageids[0]].revisions[0].user) {
          ntd.isOnTop(data.query.pages[data.query.pageids[0]].revisions[0].user);
        } else {
          ntd.success();
        }
      });
    },

    isOnTop: function (user) {
      var ntd = this;
      var param = {
        action: 'query',
        prop: 'templates',
        format: 'json',
        tllimit: '1',
        tltemplates: 'Template:Нові_зверху',
        indexpageids: '',
        titles: this.userTalkPrefix + user
      };
      $.get(mw.util.wikiScript('api'), param).done(function(data) {
        if(data.query.pages[data.query.pageids[0]].templates) {
          ntd.notifyUser(user, true);
        } else {
          ntd.notifyUser(user, false);
        }
      });
    },

    notifyUser: function (user, top) {
      var ntd = this;
      var content, timestamp;
      if(top) {
        var param = {
          action: 'query',
          prop: 'revisions',
          format: 'json',
          rvprop: 'content|timestamp',
          rvlimit: '1',
          rvsection: '0',
          titles: this.userTalkPrefix + user,
          indexpageids: ''
        };
        $.get(mw.util.wikiScript('api'), param).done(function(data) {
          content = data.query.pages[data.query.pageids[0]].revisions[0]['*'] + '\n\n{{subst:папв|' + mw.config.get( 'wgPageName' ).replace(/_/g,' ') + '|' + ntd.date + '}} --~~~~';
          timestamp = data.query.pages[data.query.pageids[0]].revisions[0].timestamp;
          ntd.writeInPage ( ntd.userTalkPrefix + user, content, timestamp, ntd.userTalkSummary.replace('{article}', '[[' + mw.config.get('wgPageName').replace(/_/g,' ') + ']]'), null, 0, function() {
            ntd.success();
          });
        });
      } else {
        content = '\n\n{{subst:папв|' + mw.config.get( 'wgPageName' ).replace(/_/g,' ') + '|' + ntd.date + '}} --~~~~';
        ntd.writeInPage ( ntd.userTalkPrefix + user, content, '', ntd.userTalkSummary.replace('{article}', '[[' + mw.config.get('wgPageName') + ']]').replace(/_/g,' '), 'appendtext', null, function() {
          ntd.success();
        });
      }
    },

    success: function() {
      this.wait('Перезавантаження сторінки');
      setTimeout(function(){
        $( '#ntd-dialog' ).dialog('close');
        location.reload(); },1000
      );
    },

    wait: function(mes) {
      this.dialog.pushPending()
      this.dialog.title.$label.html(mes)
    },

    isEmpty: function( str ) {
      return (!/\S/.test(str));
    },

    writeInPage: function ( title, content, timestamp, summary, option, section, success ) {
      var ntd = this;
      var param = {
        action: 'edit',
        title: title,
        summary: summary,
        watchlist: 'watch',
        basetimestamp: timestamp,
        token: mw.user.tokens.get('csrfToken'),
        format: 'json'
      };
      param[option || 'text'] = content;
      if (section || section === 0)
        param.section = section;
      $.post(mw.util.wikiScript('api'), param).done( function(data) {
        if (data.hasOwnProperty('edit') && data.edit.result === 'Success') {
          success();
        } else if (data.hasOwnProperty('edit') && data.edit.result === 'Failure') {
          if(data.edit.hasOwnProperty('code')) {
            var code = data.edit.code;
            switch(code) {
              case 'editconflict':
                alert('Конфлікт редагувань на сторінці ' + title + '. Відкиньте редагування, зроблені цим додатком за останні декілька секунд та спробуйте ще раз');
                break;
              case 'protectedtitle':
                alert('Сторінка ' + title + ' захищена. Зв\'яжіться з адміністраторами на сторінці ВП:Запити до адміністраторів');
                break;
              case 'spamdetected':
                alert('При редагуванні сторінки ' + title + ' автоматичний фільтр визначив ваш текст, як спам');
                break;
              case 'blocked':
                alert('Ви заблоковані у цій вікі. Спробуйте, будь ласка, пізніше');
                break;
              case 'filtered':
              case 'abusefilter-disallowed':
                alert('Автоматичний фільтр заборонив редагування сторінки ' + title);
                break;
              case 'notoken':
                alert('Неможливо отримати токен. Зверніться, будь ласка, у «Кнайпу (адміністрування)»');
                break;
              default:
                alert('Невідома помилка при редагуванні сторінки ' + title + '. Відкиньте редагування, зроблені цим додатком за останні декілька секунд та спробуйте пізніше');
                break;
            }
          } else if(data.edit.hasOwnProperty('captcha')) {
            alert('API Вікіпедії повернув капчу, яку цей додаток поки що не підтримує. Можливо ви занадто часто робите редагування? Спробуйте, будь ласка, через декілька хвилин');
          }
          ntd.success();
        }
      });
    }
  };
}
//</nowiki>
$(document).ready(function () {
  mw.loader.using( ['oojs-ui-core', 'ext.visualEditor.core', 'ext.visualEditor.mediawiki', 'ext.visualEditor.mwwikitext', 'ext.visualEditor.targetLoader', 'ext.visualEditor.desktopTarget', 'ext.visualEditor.mwextensions.desktop', 'ext.visualEditor.desktopArticleTarget', 'ext.visualEditor.desktopArticleTarget.init'] ).done( function () {
    if(mw.config.get( 'wgNamespaceNumber' ) === 0 || DEBUG || mw.config.get( 'wgNamespaceNumber' ) === 6 || mw.config.get( 'wgNamespaceNumber' ) === 10) {
      NominateToDel.install();
    }
  });
});