User:Ahmad252/scripts/UserWarning.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
 * This gadget is a substantial rewrite of the UserMessages gadget, influenced by
 * [[n:en:MediaWiki:Gadget-UserMessages.js]] and [[n:MediaWiki:Gadget-UserMessages.js]]. The base code is from [[:w:fa:MediaWiki:Gadget-UserMessages.js]], but has been localized for Wikidata by User:Ahmad252.
 */

(function($, mw) {
  'use strict';
  var windowManager;
  var UM;
  var UMOptions = {
    install: function() {
      if (mw.config.get('wgAction') === 'view' | (mw.config.get('wgAction') === 'edit' & mw.config.get('wgCurRevisionId') === 0)) {
        $(mw.util.addPortletLink( 'p-cactions', '#', 'Warn', 'ca-warn', 'Warn this user using UserWarning templates', '*')).click(function(e) {
          mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'mediawiki.api']).done(UMOptions.createWindow);
          e.preventDefault();
        });
        // Late pre-loading
        mw.loader.load(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows', 'mediawiki.api']);
      }
    },
    createWindow: function() {
      function PreviewPanel(config) {
        PreviewPanel.parent.call(this, config);
        
        this.$content = $('<div>').addClass('oo-ui-PreviewPanel');
      }
      OO.inheritClass(PreviewPanel, OO.ui.PanelLayout);
      PreviewPanel.prototype.setContent = function ($content) {
        this.$element.children().detach();
        this.$element.append($content);
        windowManager.getCurrentWindow().updateSize();
      };
      function UserMessages(config) {
        UserMessages.super.call(this, config);
      }
      OO.inheritClass(UserMessages, OO.ui.ProcessDialog);
      UserMessages.static.name = 'Warn dialog';
      UserMessages.static.title = 'Choose the appropriate warning';
      UserMessages.static.actions = [
        {
          action: 'warn',
          label: 'Submit',
          flags: 'primary'
        },
        {
          label: 'Cancel',
          flags: [ 'safe', 'destructive' ]
        }
      ];
      UserMessages.prototype.initialize = function() {
        var dialog = this;
        UserMessages.super.prototype.initialize.apply(this, arguments);
        
        this.buttons = [];
        this.buttons['Groups'] = [];
        this.buttons['Disrupt'] = [];
        this.buttons['Removal'] = [];
        this.buttons['Item'] = [];
        this.buttons['Description'] = [];
        this.buttons['Block'] = [];
        this.buttons['Other'] = [];

        this.buttons['Groups']['Disrupt'] = new OO.ui.ButtonOptionWidget({
          label: 'Disruptive editing',
          data: {
            group: 'Disrupt'
          }
        });
        this.buttons['Groups']['Removal'] = new OO.ui.ButtonOptionWidget({
          label: 'Link removal',
          data: {
            group: 'Removal'
          }
        });
        this.buttons['Groups']['Item'] = new OO.ui.ButtonOptionWidget({
          label: 'Item-related',
          data: {
            group: 'Item'
          }
        });
        this.buttons['Groups']['Description'] = new OO.ui.ButtonOptionWidget({
          label: 'Description-related',
          data: {
            group: 'Description'
          }
        });
        this.buttons['Groups']['Block'] = new OO.ui.ButtonOptionWidget({
          label: 'Block',
          data: {
            group: 'Block'
          }
        });
        this.buttons['Groups']['Other'] = new OO.ui.ButtonOptionWidget({
          label: 'Other',
          data: {
            group: 'Other'
          }
        });

        this.buttonSelectGroups = new OO.ui.ButtonSelectWidget({
          items: [
            this.buttons['Groups']['Disrupt'],
            this.buttons['Groups']['Removal'],
            this.buttons['Groups']['Description'],
            this.buttons['Groups']['Item'],
            this.buttons['Groups']['Other']
          ]
        });
        if ($(mw.config.get('wgUserGroups')).filter(['sysop']).length > 0) {
          this.buttonSelectGroups.addItems([
            this.buttons['Groups']['Block']
          ]);
        }
        this.buttonSelectGroups.selectItem(this.buttons['Groups']['Disrupt']);
        this.buttonSelectGroups.on('choose', function(item) {
          dialog.buttonSelectChoices = new OO.ui.ButtonSelectWidget({
            items: dialog.buttonSelectChoicesItems[item.data.group]
          });
          dialog.buttonSelectChoices.selectItem();
          dialog.panelChoices.$element.children().detach();
          dialog.panelChoices.$element.append(dialog.buttonSelectChoices.$element);
          dialog.setChooseAction();
          dialog.panelParams.toggle(false);
          dialog.previewResult.toggle(false);
          windowManager.getCurrentWindow().updateSize();
        });

        this.buttons['Disrupt']['Vandalism1'] = new OO.ui.ButtonOptionWidget({
          label: 'Vandalism 1',
          data: {
            template: 'Uw-vandalism1',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['Vandalism2'] = new OO.ui.ButtonOptionWidget({
          label: 'Vandalism 2',
          data: {
            template: 'Uw-vandalism2',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['Vandalism3'] = new OO.ui.ButtonOptionWidget({
          label: 'Vandalism 3',
          data: {
            template: 'Uw-vandalism3',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['Vandalism4'] = new OO.ui.ButtonOptionWidget({
          label: 'Vandalism 4',
          data: {
            template: 'Uw-vandalism4',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['Test1'] = new OO.ui.ButtonOptionWidget({
          label: 'Test 1',
          data: {
            template: 'Uw-test1',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['Test2'] = new OO.ui.ButtonOptionWidget({
          label: 'Test 2',
          data: {
            template: 'Uw-test2',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['Test3'] = new OO.ui.ButtonOptionWidget({
          label: 'Test 3',
          data: {
            template: 'Uw-test3',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Disrupt']['selfrevert'] = new OO.ui.ButtonOptionWidget({
          label: 'Self-revert',
          data: {
            template: 'Uw-selfrevert',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Removal']['link-removal1'] = new OO.ui.ButtonOptionWidget({
          label: 'Link removal 1',
          data: {
            template: 'Uw-link-removal1',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Removal']['link-removal2'] = new OO.ui.ButtonOptionWidget({
          label: 'Link removal 2',
          data: {
            template: 'Uw-link-removal2',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Removal']['link-removal3'] = new OO.ui.ButtonOptionWidget({
          label: 'Link removal 3',
          data: {
            template: 'Uw-link-removal3',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Removal']['link-removal4'] = new OO.ui.ButtonOptionWidget({
          label: 'Link removal 4',
          data: {
            template: 'Uw-link-removal4',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Item']['merger'] = new OO.ui.ButtonOptionWidget({
          label: 'How to merge',
          data: {
            template: 'Uw-merge',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Item']['duplicate'] = new OO.ui.ButtonOptionWidget({
          label: 'Creating duplicate items',
          data: {
            template: 'Uw-duplicate',
            params: [
              {
                id: '1',
                label: 'Additional message'
              }
            ]
          }
        });
        this.buttons['Item']['Wikinews'] = new OO.ui.ButtonOptionWidget({
          label: 'Merging news items to concepts',
          data: {
            template: 'Uw-Wikinews-article-merged-with-concept'
          }
        });
        this.buttons['Description']['articles'] = new OO.ui.ButtonOptionWidget({
          label: 'Use of articles',
          data: {
            template: 'Uw-articles'
          }
        });
        this.buttons['Description']['description1'] = new OO.ui.ButtonOptionWidget({
          label: 'Bad description',
          data: {
            template: 'Uw-description1',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Description']['LangAsDesc'] = new OO.ui.ButtonOptionWidget({
          label: 'No lang as desc',
          data: {
            template: 'Uw-lang as desc',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Description']['lowercase'] = new OO.ui.ButtonOptionWidget({
          label: 'Using lowercase letter',
          data: {
            template: 'Uw-lowercase'
          }
        });
        this.buttons['Other']['tilde'] = new OO.ui.ButtonOptionWidget({
          label: 'How to sign',
          data: {
            template: 'Uw-tilde',
            params: [
              {
                id: '1',
                label: 'Page (optional)'
              }
            ]
          }
        });
        this.buttons['Other']['paid-username'] = new OO.ui.ButtonOptionWidget({
          label: 'Possible paid editing',
          data: {
            template: 'Uw-paid-username'
          }
        });
        this.buttons['Block']['blocked'] = new OO.ui.ButtonOptionWidget({
          label: 'Block notification',
          data: {
            template: 'Block',
            params: [
              {
                id: '1',
                label: 'Duration (optional)'
              },
              {
                id: '2',
                label: 'Reason (optional)'
              }
            ]
          }
        });

        this.buttonSelectChoicesItems = [];
        this.buttonSelectChoicesItems['Disrupt'] = [
          this.buttons['Disrupt']['Vandalism1'],
          this.buttons['Disrupt']['Vandalism2'],
          this.buttons['Disrupt']['Vandalism3'],
          this.buttons['Disrupt']['Vandalism4'],
          this.buttons['Disrupt']['Test1'],
          this.buttons['Disrupt']['Test2'],
          this.buttons['Disrupt']['Test3'],
          this.buttons['Disrupt']['selfrevert']
        ];
        this.buttonSelectChoicesItems['Removal'] = [
          this.buttons['Removal']['link-removal1'],
          this.buttons['Removal']['link-removal2'],
          this.buttons['Removal']['link-removal3'],
          this.buttons['Removal']['link-removal4']
        ];
        this.buttonSelectChoicesItems['Item'] = [
          this.buttons['Item']['merger'],
          this.buttons['Item']['duplicate'],
          this.buttons['Item']['Wikinews']
        ];
        this.buttonSelectChoicesItems['Description'] = [
          this.buttons['Description']['articles'],
          this.buttons['Description']['description1'],
          this.buttons['Description']['LangAsDesc'],
          this.buttons['Description']['lowercase']
        ];
        this.buttonSelectChoicesItems['Other'] = [
          this.buttons['Other']['tilde'],
          this.buttons['Other']['paid-username']
        ];
        this.buttonSelectChoicesItems['Block'] = [
          this.buttons['Block']['blocked']
        ];

        // The default choice
        this.buttonSelectChoices = new OO.ui.ButtonSelectWidget({
          items: this.buttonSelectChoicesItems['Disrupt']
        });

        this.setChooseAction = function() {
          dialog.buttonSelectChoices.on('choose', function(item) {
            dialog.previewResult.toggle(false);
            if (item.data !== undefined & item.data.params !== undefined) {
              dialog.panelParams.toggle(true);
              dialog.buttonPreview.toggle(true);
              dialog.buttonReset.toggle(true);
              for (var i = 0; i < item.data.params.length; i++) {
                dialog.textParamLayouts[i].toggle(true);
                dialog.textParamLayouts[i].setLabel(item.data.params[i].label);
                dialog.textParamLayouts[i].setData(item.data.params[i].id);
              }
              for (var i = item.data.params.length; i < 4; i++) {
                dialog.textParamLayouts[i].toggle(false);
              }
            } else {
              for (var i = 0; i < 4; i++) {
                dialog.textParamLayouts[i].toggle(false);
              }
              dialog.panelParams.toggle(true);
              dialog.buttonPreview.toggle(true);
              dialog.buttonReset.toggle(true);
            }
            windowManager.getCurrentWindow().updateSize();
          });          
        }
        this.setChooseAction();

        // The parameters
        this.textParams = [];
        this.textParamLayouts = [];

        this.textParams[0] = new OO.ui.TextInputWidget({
          placeholder: 'Type here'
        });
        this.textParams[1] = new OO.ui.TextInputWidget({
          placeholder: 'Type here'
        });
        this.textParams[2] = new OO.ui.TextInputWidget({
          placeholder: 'Type here'
        });
        this.textParams[3] = new OO.ui.TextInputWidget({
          placeholder: 'Type here'
        });
        this.textParamLayouts[0] = new OO.ui.FieldLayout( this.textParams[0], {
          label: '1st parameter'
        });
        this.textParamLayouts[1] = new OO.ui.FieldLayout( this.textParams[1], {
          label: '2nd parameter'
        });
        this.textParamLayouts[2] = new OO.ui.FieldLayout( this.textParams[2], {
          label: '3rd parameter'
        });
        this.textParamLayouts[3] = new OO.ui.FieldLayout( this.textParams[3], {
          label: '4th parameter'
        });
        this.paramFieldset = new OO.ui.FieldsetLayout({
          items: this.textParamLayouts
        });
        this.buttonPreview = new OO.ui.ButtonWidget({
          label: 'Preview',
          icon: 'check',
          title: 'Preview',
          flags: 'progressive'
        });
        this.buttonPreview.on('click', function() {
          dialog.previewResult.toggle(true);
          dialog.previewResult.setContent(''); // Makes any previous preview results go away, so the user notices the change
          windowManager.getCurrentWindow().updateSize();
          var wikitext = UserMessages.prepareWikitext(dialog);
          var api = new mw.Api();
          api.get({
            action: 'parse',
            text: wikitext,
            pst: true
          }).done(function( data ) {
            dialog.previewResult.setContent($(data.parse.text['*']));
          });
        });
        this.buttonReset = new OO.ui.ButtonWidget({
          label: 'Clear',
          icon: 'clear',
          title: 'Clear',
          flags: 'destructive'
        });
        this.buttonReset.on('click', function() {
          for (var i = 0; i < 4; i++) {
              dialog.textParams[i].setValue('');
          }
          dialog.previewResult.toggle(false);
          dialog.buttonPreview.toggle(true);
          dialog.buttonReset.toggle(true);
          windowManager.getCurrentWindow().updateSize();
        });
        this.panelParams = new OO.ui.PanelLayout({
          expanded: true,
          padded: true
        });
        this.previewResult = new PreviewPanel({
          expanded: true,
          padded: true,
          $content: ''
        });
        this.previewResult.toggle(false);
        this.panelParams.$element.append(this.paramFieldset.$element);
        this.panelParams.$element.append(this.buttonPreview.$element);
        this.panelParams.$element.append(this.buttonReset.$element);
        for (var i = 0; i < 4; i++) {
            this.textParamLayouts[i].toggle(false);
        }
        this.buttonPreview.toggle(false);
        this.buttonReset.toggle(false);
        this.panelGroups = new OO.ui.PanelLayout({
          expanded: true,
          padded: true,
          classes: ['panelGroups']
        });
        this.panelGroups.$element.append(this.buttonSelectGroups.$element);
        this.panelChoices = new OO.ui.PanelLayout({
          expanded: true,
          padded: true,
          classes: ['panelChoices']
        });
        this.panelChoices.$element.append(this.buttonSelectChoices.$element);
        this.panelPreview = new OO.ui.PanelLayout({
          expanded: true,
          padded: true
        });
        this.panelPreview.$element.append(this.previewResult.$element);

        this.stackLayout = new OO.ui.StackLayout({
          items: [
            this.panelGroups,
            this.panelChoices,
            this.panelParams,
            this.panelPreview
          ],
          continuous: true,
          scrollable: false
        });
        this.$body.append(this.stackLayout.$element);
      };
      UserMessages.prepareWikitext = function(dialog) {
        var paramNames = [];
        var paramValues = [];
        var btn = dialog.buttonSelectChoices.findSelectedItem().getData();
        var wikitext = '{{subst:' + btn.template;
        for (var i = 0; i < 4; i ++) {
          paramNames[i] = dialog.textParamLayouts[i].getData();
          paramValues[i] = dialog.textParams[i].getValue();
          if (dialog.textParamLayouts[i].isVisible()) {
            wikitext += '|' + paramNames[i] + '=' + paramValues[i];
          }
        }
        wikitext += '}}';
        return wikitext;
      }
      UserMessages.prototype.getSetupProcess = function(data) {
        data = data || {};
        return UserMessages.super.prototype.getSetupProcess.call( this, data )
          .next( function () {
            // Do something
          }, this );
      };
      UserMessages.prototype.getActionProcess = function(action) {
        var dialog = this;
        if (action === 'warn') {
          var wikitext = UserMessages.prepareWikitext(dialog);
          var summary = 'Adding "[[Template:' + dialog.buttonSelectChoices.findSelectedItem().getData().template + ']]" ([[WD:UW|UW]])';
          return new OO.ui.Process(function() {
            UMOptions.savePage(mw.config.get('wgPageName'), wikitext, summary, function() {
              location.reload();
            });
            dialog.close({
              action: action
            }).done(function() {
              // Page will be reloaded once saved
            });
          });
        }
        return UserMessages.super.prototype.getActionProcess.call(this, action);
      };
      if (!windowManager) {
        windowManager = new OO.ui.WindowManager();
        $('body').append(windowManager.$element);
      }
      UM = new UserMessages({
        size: 'large'
      });
      windowManager.addWindows([UM]);
      windowManager.openWindow(UM);
    },
    savePage: function(title, text, summary, callback) {
      (new mw.Api()).post({
        action: 'edit',
        title: title,
        summary: summary,
        appendtext: '\n' + text,
        token: mw.user.tokens.get('csrfToken')
      }).done(function(data) {
        if (data.error && data.error.info) {
          if (data.error.info == 'missingtitle') {
            mw.notify('The page ' + title + ' doesn\'t exist!', {
              type: 'error'
            });
          } else {
            mw.notify(data.error.info, {
              type: 'error'
            });
          }
        } else {
          callback();
        }
      }).fail(function(data) {
        mw.notify(data);
      });
    },
  };
  if (mw.config.get('wgNamespaceNumber') === 3 | mw.config.get('wgPageName') === 'Wikidata:Sandbox') {
    $(UMOptions.install);
  }
})(jQuery, mediaWiki);