MediaWiki:Gadget-RefToolbarBase.js

MediaWiki系统消息页面
/* global CiteTB */
'use strict';

/* <nowiki> */
/**
 * SPDX-License-Identifier: CC-BY-SA-4.0
 * _addText: '{{Gadget Header|license=CC-BY-SA-4.0}}'
 *
 * @source <zh.wikipedia.org/wiki/MediaWiki:Gadget-refToolbarBase.js>
 */
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
(function ($, mw) {
  if (window.CiteTB === undefined) {
    window.CiteTB = {
      Templates: {},
      // All templates
      Options: {},
      // Global options
      UserOptions: {},
      // User options
      DefaultOptions: {},
      // Script defaults
      ErrorChecks: {} // Error check functions
    };
  }

  if (typeof mw.usability === 'undefined') {
    mw.usability = {};
    mw.usability.getMsg = function (m) {
      return mw.messages.get(m);
    };
    mw.usability.addMessages = function (msgs) {
      mw.messages.set(msgs);
    };
  }

  // Object for cite templates
  window.citeTemplate = function (templatename, shortform, basicfields, expandedfields) {
    // Properties
    this.templatename = templatename; // The template name - "cite web", "cite book", etc.
    this.shortform = shortform; // A short form, used for the dropdown box
    this.basic = basicfields; // Basic fields - author, title, publisher...
    // Less common - quote, archiveurl - should be everything the template supports minus the basic ones
    this.extra = expandedfields;
    this.incrementables = {};

    // Add it to the list
    CiteTB.Templates[this.templatename] = this;
    // Methods
    this.makeFormInner = function (fields, incrsetup) {
      var _this = this;
      var trs = [];
      var autofills = [];
      var tr;
      fields.forEach(function (fieldobj, i) {
        var field = fieldobj.field;
        var labelfield = fieldobj.field;
        var ad = false;
        var im;
        if (incrsetup && fieldobj.increment_group) {
          field = fieldobj.field.replace('<N>', '1');
          labelfield = fieldobj.field.replace('<N>', '');
          if (_this.incrementables[fieldobj.increment_group] && !_this.incrementables[fieldobj.increment_group].setup) {
            // The object has been created, but not fully initialized
            _this.incrementables[fieldobj.increment_group].fields.push(fieldobj);
          } else if (!_this.incrementables[fieldobj.increment_group]) {
            // Object not yet created
            _this.incrementables[fieldobj.increment_group] = {
              fields: [fieldobj],
              val: 1,
              setup: false
            };
          } else if (_this.incrementables[fieldobj.increment_group] && _this.incrementables[fieldobj.increment_group].setup) {
            // Fully initialized from a previous invocation of this function, just resetting the number
            _this.incrementables[fieldobj.increment_group].val = 1;
          }
        } else if (fieldobj.increment_group) {
          // Adding a new row
          var incrval = _this.incrementables[fieldobj.increment_group].val;
          field = fieldobj.field.replace('<N>', incrval.toString());
          labelfield = fieldobj.field.replace('<N>', '');
        }
        var autodateFields = CiteTB.getOption('autodate fields');
        if (autodateFields.includes(field)) {
          im = $('<img>').attr('src', '//youshou.wiki/images/thumb/7/7b/Nuvola_apps_date.svg/24px-Nuvola_apps_date.svg.png');
          im.attr('alt', mw.usability.getMsg('cite-insert-date')).attr('title', mw.usability.getMsg('cite-insert-date'));
          ad = $('<a>').attr('href', '#');
          ad.append(im);
          ad.attr('id', "cite-date-".concat(CiteTB.escStr(_this.shortform), "-").concat(field));
          $(document).on('click', "#cite-date-".concat(CiteTB.escStr(_this.shortform), "-").concat(field), CiteTB.fillAccessdate);
        }
        if (fieldobj.autofillid) {
          var autotype = fieldobj.autofillid;
          im = $('<img>').attr('src', '//youshou.wiki/images/thumb/1/17/System-search.svg/24px-System-search.svg.png');
          im.attr('alt', mw.usability.getMsg('cite-autofill-alt')).attr('title', mw.usability.getMsg('cite-autofill-alt'));
          ad = $('<a>').attr('href', '#');
          ad.append(im);
          ad.attr('id', "cite-auto-".concat(CiteTB.escStr(_this.shortform), "-").concat(field, "-").concat(autotype));
          autofills.push("#cite-auto-".concat(CiteTB.escStr(_this.shortform), "-").concat(field, "-").concat(autotype));
        }
        if (fieldobj.increment_button) {
          var incrtype = fieldobj.increment_group;
          im = $('<img>').attr('src', '//youshou.wiki/images/thumb/b/b9/Nuvola_action_edit_add.svg/24px-Nuvola_action_edit_add.svg.png');
          im.attr('alt', mw.usability.getMsg('cite-increment-alt')).attr('title', mw.usability.getMsg('cite-increment-alt'));
          ad = $('<a>').attr('href', '#');
          ad.append(im);
          ad.attr('id', "cite-incr-".concat(CiteTB.escStr(_this.shortform), "-").concat(incrtype));
        }
        var display = mw.usability.getMsg("cite-".concat(labelfield, "-label"));
        if (typeof display !== 'string') {
          if (fieldobj.label) {
            display = CiteTB.fixStr(fieldobj.label);
          } else {
            display = CiteTB.fixStr(labelfield);
          }
        }
        var tooltip = fieldobj.tooltip ? $('<abbr>').attr('title', mw.usability.getMsg(fieldobj.tooltip)).html($('<sup>').text('?')) : false;
        var input = '';
        if (ad) {
          input = $('<input>').attr({
            tabindex: '1',
            style: 'width: 85%',
            type: 'text'
          });
        } else {
          input = $('<input>').attr({
            tabindex: '1',
            style: 'width: 100%',
            type: 'text'
          });
        }
        input.attr('id', "cite-".concat(CiteTB.escStr(_this.shortform), "-").concat(field));
        if (fieldobj.autofillprop) {
          var classname = "cite-".concat(CiteTB.escStr(_this.shortform), "-").concat(fieldobj.autofillprop);
          if (fieldobj.increment_group) {
            input.addClass("cite-".concat(CiteTB.escStr(_this.shortform), "-incr-").concat(fieldobj.increment_group));
            classname += "-".concat(_this.incrementables[fieldobj.increment_group].val.toString());
          }
          input.addClass(classname);
        }
        var label = $('<label>');
        label.attr('for', "cite-".concat(CiteTB.escStr(_this.shortform), "-").concat(field)).text(display);
        if (tooltip) {
          label.append(tooltip);
        }
        var style = 'text-align: right; width: 20%;';
        if (i % 2 === 1) {
          style += ' padding-left: 1em;';
        } else {
          tr = $('<tr>');
        }
        var td1 = $('<td>').attr({
          'class': 'cite-form-td',
          style: style
        });
        td1.append(label);
        tr.append(td1);
        var td2 = $('<td>').attr({
          'class': 'cite-form-td',
          style: 'width: 30%'
        });
        td2.append(input);
        if (ad) {
          td2.append(ad);
        }
        tr.append(td2);
        if (i % 2 === 0) {
          trs.push(tr);
        }
      });
      var needsetup = false;
      for (var g in this.incrementables) {
        if (!this.incrementables[g].setup) {
          needsetup = true;
          $(document).on('click', "#cite-incr-".concat(CiteTB.escStr(this.shortform), "-").concat(g), CiteTB.incrementFields);
          this.incrementables[g].setup = true;
        }
      }
      if (needsetup || $.isEmptyObject(this.incrementables)) {
        var _iterator = _createForOfIteratorHelper(autofills),
          _step;
        try {
          for (_iterator.s(); !(_step = _iterator.n()).done;) {
            var autofill = _step.value;
            $(document).on('click', autofill, CiteTB.initAutofill);
          }
        } catch (err) {
          _iterator.e(err);
        } finally {
          _iterator.f();
        }
      }
      return trs;
    };

    // gives a little bit of HTML so the open form can be identified
    this.getInitial = function () {
      var hidden = $('<input>').attr({
        type: 'hidden',
        'class': 'cite-template',
        value: this.templatename
      });
      return hidden;
    };

    // makes the form used in the dialog boxes
    this.getForm = function () {
      var main = $('<div>').attr('class', 'cite-form-container');
      var form1 = $('<table>').attr({
        'class': 'cite-basic-fields',
        style: 'width: 100%; background-color: transparent;'
      });
      var trs = this.makeFormInner(this.basic, true);
      var _iterator2 = _createForOfIteratorHelper(trs),
        _step2;
      try {
        for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
          var tr_ = _step2.value;
          form1.append(tr_);
        }
      } catch (err) {
        _iterator2.e(err);
      } finally {
        _iterator2.f();
      }
      var form2 = $('<table>').attr({
        'class': 'cite-extra-fields',
        style: 'width: 100%; background-color: transparent; display: none'
      });
      trs = this.makeFormInner(this.extra, true);
      var _iterator3 = _createForOfIteratorHelper(trs),
        _step3;
      try {
        for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
          var _tr_ = _step3.value;
          form2.append(_tr_);
        }
      } catch (err) {
        _iterator3.e(err);
      } finally {
        _iterator3.f();
      }
      main.append(form1).append(form2);
      var form3 = $('<table>').attr({
        style: 'width: 100%; background-color: transparent; padding-top: 1em',
        'class': 'cite-other-fields'
      });
      var tr = $('<tr>');
      var td1 = $('<td>').attr({
        'class': 'cite-form-td',
        style: 'text-align: right; width: 20%'
      });
      var label1 = $('<label>');
      label1.attr('for', "cite-".concat(CiteTB.escStr(this.shortform), "-name")).text(mw.usability.getMsg('cite-name-label'));
      td1.append(label1);
      var td2 = $('<td>').attr({
        'class': 'cite-form-td',
        style: 'width: 30%'
      });
      var input1 = $('<input>').attr({
        tabindex: '1',
        style: 'width: 100%',
        type: 'text'
      });
      input1.attr('id', "cite-".concat(CiteTB.escStr(this.shortform), "-name"));
      td2.append(input1);
      var td3 = $('<td>').attr({
        'class': 'cite-form-td',
        style: 'text-align: right; padding-left: 1em; width: 20%'
      });
      var label2 = $('<label>');
      label2.attr('for', "cite-".concat(CiteTB.escStr(this.shortform), "-group")).text(mw.usability.getMsg('cite-group-label'));
      td3.append(label2);
      var td4 = $('<td>').attr({
        'class': 'cite-form-td',
        style: 'width: 30%'
      });
      var input2 = $('<input>').attr({
        tabindex: '1',
        style: 'width: 100%',
        type: 'text'
      });
      input2.attr('id', "cite-".concat(CiteTB.escStr(this.shortform), "-group"));
      td4.append(input2);
      tr.append(td1).append(td2).append(td3).append(td4);
      form3.append(tr);
      main.append(form3);
      var extras = $('<div>');
      extras.append($('<input>').attr({
        type: 'hidden',
        'class': 'cite-form-status',
        value: 'closed'
      }));
      var hidden = $('<input>').attr({
        'class': 'cite-template',
        type: 'hidden'
      });
      hidden.val(this.templatename);
      extras.append(hidden);
      var span1 = $('<span>').attr({
        'class': 'cite-preview-label',
        style: 'display: none;'
      });
      span1.text(mw.usability.getMsg('cite-raw-preview'));
      extras.append(span1).append($('<div>').attr({
        'class': 'cite-ref-preview',
        style: 'padding: 0.5em; font-size: 110%'
      }));
      var span2 = $('<span>').attr({
        'class': 'cite-prev-parsed-label',
        style: 'display: none;'
      });
      span2.text(mw.usability.getMsg('cite-parsed-label'));
      extras.append(span2).append($('<div>').attr({
        'class': 'cite-preview-parsed',
        style: 'padding-bottom: 0.5em; font-size: 110%'
      }));
      var link = $('<a>').attr({
        href: '#',
        'class': 'cite-prev-parse',
        style: 'margin: 0 1em 0 1em; display: none; color: darkblue'
      });
      link.text(mw.usability.getMsg('cite-form-parse'));
      extras.append(link);
      main.append(extras);
      return main;
    };
  };

  /* Class for error checks
   FIXME: DOCS OUT OF DATE
  type - type of error check - current options:
   * 'refcheck' - apply a function on each ref individually
  * function should accept a ref object, return a string
   * 'reflist' - apply a function on the entire ref list
  * function should accept an array of ref objects, return an array of strings
   * 'search' - apply a function ro the page text
  * function should accept the page text as a string, return an array of strings
  The strings returned by the function should be valid HTML
   func - The function described above
  testname - Name of the error check, must not contain spaces
  desc - A short description of the test
  */

  window.citeErrorCheck = function (obj) {
    this.obj = obj;
    CiteTB.ErrorChecks[this.obj.testname] = this;
    this.run = function () {
      var errors = [];
      switch (this.obj.type) {
        case 'refcheck':
          {
            CiteTB.loadRefs();
            for (var i = 0; i < CiteTB.mainRefList.length; i++) {
              var e = this.obj.func(CiteTB.mainRefList[i]);
              if (e) {
                errors.push(e);
              }
            }
            break;
          }
        case 'reflist':
          {
            CiteTB.loadRefs();
            errors = this.obj.func(CiteTB.mainRefList);
            break;
          }
        case 'search':
          {
            var func = this.obj.func;
            CiteTB.getPageText(function (text) {
              errors = func(text);
            });
            break;
          }
      }
      return errors;
    };
    this.getRow = function () {
      var row = $('<li>');
      var check = $('<input>').attr({
        type: 'checkbox',
        name: 'cite-err-test'
      });
      check.attr('value', this.obj.testname);
      var label = $('<label>').html(mw.usability.getMsg(this.obj.desc));
      label.attr('for', this.obj.testname);
      row.append(check).append(' &ndash; ').append(label);
      return row;
    };
  };
  $('head').trigger('reftoolbarbase');
})(jQuery, mediaWiki);

/* </nowiki> */