User:Ericliu1912/維基專題評級工具/rater app.js
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/***************************************************************************************************
Rater --- by Evad37
> Helps assess WikiProject banners.
This script is a loader that will load the actual script from the /app.js subpage
once Resource loader modules are loaded and the page DOM is ready.
Source code is available at https://github.com/evad37/rater
***************************************************************************************************/
// <nowiki>
$.when(
// Resource loader modules
mw.loader.using([
"mediawiki.util", "mediawiki.api", "mediawiki.Title",
"oojs-ui-core", "oojs-ui-widgets", "oojs-ui-windows",
"oojs-ui.styles.icons-content", "oojs-ui.styles.icons-interactions",
"oojs-ui.styles.icons-moderation", "oojs-ui.styles.icons-editing-core",
"mediawiki.widgets", "mediawiki.widgets.NamespacesMultiselectWidget",
]),
// Page ready
$.ready
).then(function() {
var conf = mw.config.get(["wgNamespaceNumber", "wgPageName"]);
// Do not operate on Special: pages, nor on non-existent pages or their talk pages
if ( conf.wgNamespaceNumber < 0 || $("li.new[id|=ca-nstab]").length ) {
return;
}
// Do not operate on top-level User and User_talk pages (only on subpages)
if (
conf.wgNamespaceNumber >= 2 &&
conf.wgNamespaceNumber <= 3 &&
conf.wgPageName.indexOf("/") === -1
) {
return;
}
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
module.exports={
"name": "rater_zhwiki",
"version": "1.2",
"description": "協助維基專題評級的維基百科使用者指令碼",
"homepage": "https://github.com/yfdyh000/rater_zhwiki",
"browser": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint:es5": "jshint index.js",
"lint:es6": "eslint index.js \"rater-src/**\"",
"lint:fix": "eslint index.js \"rater-src/**\" --fix",
"lint": "npm run lint:es6 && npm run lint:es5",
"build:bundle": "browserify rater-src/App.js --debug -t babelify --outfile dist/rater.js",
"build:minify": "uglifyjs dist/rater.js --compress -b ascii_only=true,beautify=false --output dist/rater.min.js",
"build:concat": "node ./index_warper.mjs commenttomin",
"build:dev": "npm run lint && npm run build:bundle && npm run build:dev_concat && npm run build:dev_pub",
"build:dev_concat": "node ./index_warper.mjs",
"build:dev_pub": "node ./index_warper.mjs pub",
"build": "npm run lint && npm run build:bundle && npm run build:minify && npm run build:concat",
"watch-build": "nodemon --watch rater-src --watch index_warper.mjs --exec npm run build",
"watch-dev": "nodemon --watch rater-src --watch index_warper.mjs --exec npm run build:dev"
},
"author": {
"name": "Evad37",
"url": "https://en.wikipedia.org/wiki/User:Evad37",
"name": "YFdyh000",
"url": "https://zh.wikipedia.org/wiki/User:YFdyh000",
"name": "Ericliu1912",
"url": "https://zh.wikipedia.org/wiki/User:Ericliu1912"
},
"repository": {
"type": "git",
"url": "https://github.com/yfdyh000/rater_zhwiki.git"
},
"license": "(MIT OR CC-BY-4.0)",
"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.0",
"babelify": "^10.0.0",
"browserify": "^16.5.0",
"concat-cli": "^4.0.0",
"eslint": "^6.8.0",
"jshint": "^2.11.0",
"nodemon": "^2.0.16",
"uglify-js": "^3.8.0"
}
}
},{}],2:[function(require,module,exports){
"use strict";
var _setup = _interopRequireDefault(require("./setup"));
var _autostart = _interopRequireDefault(require("./autostart"));
var _css = _interopRequireDefault(require("./css.js"));
var _api = require("./api");
var _windowManager = _interopRequireDefault(require("./windowManager"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
(function App() {
var stylesheet;
var showMainWindow = function showMainWindow(data) {
if (!data || !data.success) {
return;
}
if (stylesheet) {
stylesheet.disabled = false;
} else {
stylesheet = mw.util.addCSS(_css["default"]);
}
// Add css class to body to enable background scrolling
document.getElementsByTagName("body")[0].classList.add("rater-mainWindow-open");
// Open the window
_windowManager["default"].openWindow("main", data).closed.then(function (result) {
// Disable/remove the css styles, so as to not interfere with other scripts/content/OOUI windows
if (stylesheet) {
stylesheet.disabled = true;
}
document.getElementsByTagName("body")[0].classList.remove("rater-mainWindow-open");
// Restart if needed
if (result && result.restart) {
_windowManager["default"].removeWindows(["main"]).then(_setup["default"]).then(showMainWindow, showSetupError);
return;
}
// Show notification when saved successfully
if (result && result.success) {
var $message = $("<span>").append($("<strong>").text(wgULS("评级保存成功。", "成功儲存評級結果。")));
if (result.upgradedStub) {
$message.append($("<br>"),
// TODO: There should be a link that will edit the article for you
$("<span>").text("注意,条目似乎是一个小作品。"));
}
mw.notify($message, {
autoHide: true,
autoHideSeconds: "long",
tag: wgULS("评级已保存", "成功儲存評級")
});
}
});
};
var showSetupError = function showSetupError(code, jqxhr) {
return OO.ui.alert((0, _api.makeErrorMsg)(code, jqxhr), {
title: wgULS("工具打开失败", "工具無法開啟")
});
};
// Invocation by portlet link
if ($("#ca-rater").length === 0) {
var area = "";
switch (mw.config.get('skin')) {
case 'vector':
area = 'p-views';
break;
case 'minerva':
// Mobile skin
area = 'p-tb';
break;
default:
area = 'p-cactions';
break;
}
mw.util.addPortletLink(area, "#", wgULS("评级", "評級"), "ca-rater", wgULS("质量和重要度评级", "為頁面評級"), "5");
$("#ca-rater").click(function (event) {
event.preventDefault();
(0, _setup["default"])().then(showMainWindow, showSetupError);
});
}
// Invocation by auto-start (do not show message on error)
(0, _autostart["default"])().then(showMainWindow);
})();
// </nowiki>
},{"./api":15,"./autostart":16,"./css.js":19,"./setup":22,"./windowManager":24}],3:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getWithRedirectTo = exports.parseTemplates = exports.Template = void 0;
var _api = _interopRequireDefault(require("./api"));
var _util = require("./util");
var _config = _interopRequireDefault(require("./config"));
var cache = _interopRequireWildcard(require("./cache"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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; }
// <nowiki>
/** Template
*
* @class
* Represents the wikitext of template transclusion. Used by #parseTemplates.
* @prop {String} name Name of the template
* @prop {String} wikitext Full wikitext of the transclusion
* @prop {Object[]} parameters Parameters used in the translcusion, in order, of form:
{
name: {String|Number} parameter name, or position for unnamed parameters,
value: {String} Wikitext passed to the parameter (whitespace trimmed),
wikitext: {String} Full wikitext (including leading pipe, parameter name/equals sign (if applicable), value, and any whitespace)
}
* @constructor
* @param {String} wikitext Wikitext of a template transclusion, starting with '{{' and ending with '}}'.
*/
var Template = function Template(wikitext) {
this.wikitext = wikitext;
this.parameters = [];
// Spacing around pipes, equals signs, end braces (defaults)
this.pipeStyle = "|";
this.equalsStyle = "=";
this.endBracesStyle = "}}";
};
exports.Template = Template;
Template.prototype.addParam = function (name, val, wikitext) {
this.parameters.push({
"name": name,
"value": val,
"wikitext": "|" + wikitext
});
};
/**
* Get a parameter data by parameter name
*/
Template.prototype.getParam = function (paramName) {
return this.parameters.find(function (p) {
return p.name == paramName;
});
};
Template.prototype.setName = function (name) {
this.name = name.trim();
};
Template.prototype.getTitle = function () {
return mw.Title.newFromText("Template:" + this.name);
};
/**
* parseTemplates
*
* Parses templates from wikitext.
* Based on SD0001's version at <https://en.wikipedia.org/wiki/User:SD0001/parseAllTemplates.js>.
* Returns an array containing the template details:
* var templates = parseTemplates("Hello {{foo |Bar|baz=qux |2=loremipsum|3=}} world");
* console.log(templates[0]); // --> object
{
name: "foo",
wikitext:"{{foo |Bar|baz=qux | 2 = loremipsum |3=}}",
parameters: [
{
name: 1,
value: 'Bar',
wikitext: '|Bar'
},
{
name: 'baz',
value: 'qux',
wikitext: '|baz=qux '
},
{
name: '2',
value: 'loremipsum',
wikitext: '| 2 = loremipsum '
},
{
name: '3',
value: '',
wikitext: '|3='
}
],
getParam: function(paramName) {
return this.parameters.find(function(p) { return p.name == paramName; });
}
}
*
*
* @param {String} wikitext
* @param {Boolean} recursive Set to `true` to also parse templates that occur within other templates,
* rather than just top-level templates.
* @return {Template[]} templates
*/
var parseTemplates = function parseTemplates(wikitext, recursive) {
/* eslint-disable no-control-regex */
if (!wikitext) {
return [];
}
var strReplaceAt = function strReplaceAt(string, index, _char) {
return string.slice(0, index) + _char + string.slice(index + 1);
};
var result = [];
var processTemplateText = function processTemplateText(startIdx, endIdx) {
var text = wikitext.slice(startIdx, endIdx);
var template = new Template("{{" + text.replace(/\x01/g, "|") + "}}");
// swap out pipe in links with \x01 control character
// [[File: ]] can have multiple pipes, so might need multiple passes
while (/(\[\[[^\]]*?)\|(.*?\]\])/g.test(text)) {
text = text.replace(/(\[\[[^\]]*?)\|(.*?\]\])/g, "$1\x01$2");
}
// Figure out most-used spacing styles for pipes/equals
template.pipeStyle = (0, _util.mostFrequent)(text.match(/[\s\n]*\|[\s\n]*/g)) || "|";
template.equalsStyle = (0, _util.mostFrequent)(text.replace(/(=[^|]*)=+/g, "$1").match(/[\s\n]*=[\s\n]*/g)) || "=";
// Figure out end-braces style
var endSpacing = text.match(/[\s\n]*$/);
template.endBracesStyle = (endSpacing ? endSpacing[0] : "") + "}}";
var chunks = text.split("|").map(function (chunk) {
// change '\x01' control characters back to pipes
return chunk.replace(/\x01/g, "|");
});
template.setName(chunks[0]);
var parameterChunks = chunks.slice(1);
var unnamedIdx = 1;
parameterChunks.forEach(function (chunk) {
var indexOfEqualTo = chunk.indexOf("=");
var indexOfOpenBraces = chunk.indexOf("{{");
var isWithoutEquals = !chunk.includes("=");
var hasBracesBeforeEquals = chunk.includes("{{") && indexOfOpenBraces < indexOfEqualTo;
var isUnnamedParam = isWithoutEquals || hasBracesBeforeEquals;
var pName, pNum, pVal;
if (isUnnamedParam) {
// Get the next number not already used by either an unnamed parameter, or by a
// named parameter like `|1=val`
while (template.getParam(unnamedIdx)) {
unnamedIdx++;
}
pNum = unnamedIdx;
pVal = chunk.trim();
} else {
pName = chunk.slice(0, indexOfEqualTo).trim();
pVal = chunk.slice(indexOfEqualTo + 1).trim();
}
template.addParam(pName || pNum, pVal, chunk);
});
result.push(template);
};
var n = wikitext.length;
// number of unclosed braces
var numUnclosed = 0;
// are we inside a comment, or between nowiki tags, or in a {{{parameter}}}?
var inComment = false;
var inNowiki = false;
var inParameter = false;
var startIdx, endIdx;
for (var i = 0; i < n; i++) {
if (!inComment && !inNowiki && !inParameter) {
if (wikitext[i] === "{" && wikitext[i + 1] === "{" && wikitext[i + 2] === "{" && wikitext[i + 3] !== "{") {
inParameter = true;
i += 2;
} else if (wikitext[i] === "{" && wikitext[i + 1] === "{") {
if (numUnclosed === 0) {
startIdx = i + 2;
}
numUnclosed += 2;
i++;
} else if (wikitext[i] === "}" && wikitext[i + 1] === "}") {
if (numUnclosed === 2) {
endIdx = i;
processTemplateText(startIdx, endIdx);
}
numUnclosed -= 2;
i++;
} else if (wikitext[i] === "|" && numUnclosed > 2) {
// swap out pipes in nested templates with \x01 character
wikitext = strReplaceAt(wikitext, i, "\x01");
} else if (/^<!--/.test(wikitext.slice(i, i + 4))) {
inComment = true;
i += 3;
} else if (/^<nowiki ?>/.test(wikitext.slice(i, i + 9))) {
inNowiki = true;
i += 7;
}
} else {
// we are in a comment or nowiki or {{{parameter}}}
if (wikitext[i] === "|") {
// swap out pipes with \x01 character
wikitext = strReplaceAt(wikitext, i, "\x01");
} else if (/^-->/.test(wikitext.slice(i, i + 3))) {
inComment = false;
i += 2;
} else if (/^<\/nowiki ?>/.test(wikitext.slice(i, i + 10))) {
inNowiki = false;
i += 8;
} else if (wikitext[i] === "}" && wikitext[i + 1] === "}" && wikitext[i + 2] === "}") {
inParameter = false;
i += 2;
}
}
}
if (recursive) {
var subtemplates = (0, _util.filterAndMap)(result, function (template) {
return /\{\{(?:.|\n)*\}\}/.test(template.wikitext.slice(2, -2));
}, function (template) {
return parseTemplates(template.wikitext.slice(2, -2), true);
});
return result.concat.apply(result, subtemplates);
}
return result;
}; /* eslint-enable no-control-regex */
/**
* @param {Template|Template[]} templates
* @return {Promise<Template>|Promise<Template[]>}
*/
exports.parseTemplates = parseTemplates;
var getWithRedirectTo = function getWithRedirectTo(templates) {
var templatesArray = Array.isArray(templates) ? templates : [templates];
if (templatesArray.length === 0) {
return $.Deferred().resolve([]);
}
return _api["default"].get({
"action": "query",
"format": "json",
"titles": (0, _util.filterAndMap)(templatesArray, function (template) {
return template.getTitle() !== null;
}, function (template) {
return template.getTitle().getPrefixedText();
}),
"redirects": 1
}).then(function (result) {
if (!result || !result.query) {
return $.Deferred().reject("Empty response");
}
if (result.query.redirects) {
result.query.redirects.forEach(function (redirect) {
var i = templatesArray.findIndex(function (template) {
var title = template.getTitle();
return title && title.getPrefixedText() === redirect.from;
});
if (i !== -1) {
templatesArray[i].redirectTarget = mw.Title.newFromText(redirect.to);
}
});
}
return Array.isArray(templates) ? templatesArray : templatesArray[0];
});
};
exports.getWithRedirectTo = getWithRedirectTo;
Template.prototype.getDataForParam = function (key, paraName) {
if (!this.paramData) {
return null;
}
// If alias, switch from alias to preferred parameter name
var para = this.paramAliases[paraName] || paraName;
if (!this.paramData[para]) {
return;
}
var data = this.paramData[para][key];
// Data might actually be an object with key "en"
if (data && data.zh && !Array.isArray(data)) {
return data.zh;
}
return data;
};
Template.prototype.isShellTemplate = function () {
var mainText = this.redirectTarget ? this.redirectTarget.getMainText() : this.getTitle().getMainText();
return _config["default"].shellTemplates.includes(mainText);
};
Template.prototype.setParamDataAndSuggestions = function () {
var self = this;
var paramDataSet = $.Deferred();
if (self.paramData) {
return paramDataSet.resolve();
}
var prefixedText = self.redirectTarget ? self.redirectTarget.getPrefixedText() : self.getTitle().getPrefixedText();
var cachedInfo = cache.read(prefixedText + "-params");
if (cachedInfo && cachedInfo.value && cachedInfo.staleDate && cachedInfo.value.paramData != null && cachedInfo.value.parameterSuggestions != null && cachedInfo.value.paramAliases != null) {
self.notemplatedata = cachedInfo.value.notemplatedata;
self.paramData = cachedInfo.value.paramData;
self.parameterSuggestions = cachedInfo.value.parameterSuggestions;
self.paramAliases = cachedInfo.value.paramAliases;
paramDataSet.resolve();
if (!(0, _util.isAfterDate)(cachedInfo.staleDate)) {
// Just use the cached data
return paramDataSet;
} // else: Use the cache data for now, but also fetch new data from API
}
_api["default"].get({
action: "templatedata",
titles: prefixedText,
redirects: 1,
includeMissingTitles: 1
}).then(function (response) {
return response;
}, function /*error*/ () {
return null;
} // Ignore errors, will use default data
).then(function (result) {
// Figure out page id (beacuse action=templatedata doesn't have an indexpageids option)
var id = result && $.map(result.pages, function (_value, key) {
return key;
});
if (!result || !result.pages[id] || result.pages[id].notemplatedata || !result.pages[id].params) {
// No TemplateData, so use defaults (guesses)
self.notemplatedata = true;
self.templatedataApiError = !result;
if (new RegExp("WikiProject ", "i").test(prefixedText) || prefixedText.includes("专题") || prefixedText.includes("專題")) self.paramData = _config["default"].defaultParameterData;
} else {
// TODO: review for https://zh.wikipedia.org/w/index.php?title=Special:%E6%90%9C%E7%B4%A2&search=rater-data.js&profile=advanced&fulltext=1&ns10=1
self.paramData = result.pages[id].params;
}
self.paramAliases = {};
$.each(self.paramData, function (paraName, paraData) {
// Extract aliases for easier reference later on
if (paraData.aliases && paraData.aliases.length) {
paraData.aliases.forEach(function (alias) {
self.paramAliases[alias] = paraName;
});
}
// Extract allowed values array from description
if (paraData.description && /\[.*'.+?'.*?\]/.test(paraData.description.zh)) {
try {
var allowedVals = JSON.parse(paraData.description.zh.replace(/^.*\[/, "[").replace(/"/g, "\\\"").replace(/'/g, "\"").replace(/,\s*]/, "]").replace(/].*$/, "]"));
self.paramData[paraName].allowedValues = allowedVals;
} catch (e) {
console.warn("[Rater] Could not parse allowed values in description:\n " + paraData.description.zh + "\n Check TemplateData for parameter |" + paraName + "= in " + self.getTitle().getPrefixedText());
}
}
});
// Make suggestions for combobox
var allParamsArray = !self.notemplatedata && result.pages[id].paramOrder || $.map(self.paramData, function (_val, key) {
return key;
});
self.parameterSuggestions = allParamsArray.filter(function (paramName) {
return paramName && paramName !== "class" && paramName !== "importance";
}).map(function (paramName) {
var optionObject = {
data: paramName
};
var label = self.getDataForParam(label, paramName);
if (label) {
optionObject.label = label + " (|" + paramName + "=)";
}
return optionObject;
});
if (self.templatedataApiError) {
// Don't save defaults/guesses to cache;
return true;
}
cache.write(prefixedText + "-params", {
notemplatedata: self.notemplatedata,
paramData: self.paramData,
parameterSuggestions: self.parameterSuggestions,
paramAliases: self.paramAliases
}, 1);
return true;
}).then(paramDataSet.resolve, paramDataSet.reject);
return paramDataSet;
};
var makeListAs = function makeListAs(subjectTitle) {
var name = subjectTitle.getMainText().replace(/\s\(.*\)/, "");
if (name.indexOf(" ") === -1) {
return name;
}
var generationalSuffix = "";
if (/ (?:[JS]r.?|[IVX]+)$/.test(name)) {
generationalSuffix = name.slice(name.lastIndexOf(" "));
name = name.slice(0, name.lastIndexOf(" "));
if (name.indexOf(" ") === -1) {
return name + generationalSuffix;
}
}
var lastName = name.slice(name.lastIndexOf(" ") + 1).replace(/,$/, "");
var otherNames = name.slice(0, name.lastIndexOf(" "));
return lastName + ", " + otherNames + generationalSuffix;
};
Template.prototype.addMissingParams = function () {
var thisTemplate = this;
// Autofill listas parameter for WP:BIO
var isBiographyBanner = this.getTitle().getMainText() === "WikiProject Biography" ||
// TODO: check it
this.redirectTarget && this.redirectTarget.getMainText() === "WikiProject Biography";
if (isBiographyBanner && !this.getParam("listas")) {
var subjectTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getSubjectPage();
this.parameters.push({
name: "listas",
value: makeListAs(subjectTitle),
autofilled: true
});
}
// Make sure required/suggested parameters are present
$.each(thisTemplate.paramData, function (paraName, paraData) {
if ((paraData.required || paraData.suggested) && !thisTemplate.getParam(paraName)) {
// Check if already present in an alias, if any
if (paraData.aliases.length) {
var aliases = thisTemplate.parameters.filter(function (p) {
var isAlias = paraData.aliases.includes(p.name);
var isEmpty = !p.value;
return isAlias && !isEmpty;
});
if (aliases.length) {
// At least one non-empty alias, so do nothing
return;
}
}
// No non-empty aliases, so add this to the parameters list (with
// value set parameter to either the autovaule, or as null).
// Also set that it was autofilled.
thisTemplate.parameters.push({
name: paraName,
value: paraData.autovalue || null,
autofilled: true
});
}
});
return thisTemplate;
};
Template.prototype.setClassesAndImportances = function () {
var _this = this;
var parsed = $.Deferred();
// Don't re-parse if already parsed; no need to parse shell templates or banners without ratings
if (this.isShellTemplate()) {
this.classes = _toConsumableArray(_config["default"].bannerDefaults.classes);
return parsed.resolve();
} else if (this.classes && this.importances || this.withoutRatings) {
return parsed.resolve();
}
var mainText = this.getTitle().getMainText(); // page name without NS prefix
// Some projects have hardcoded values, to avoid standard classes or to prevent API issues (timeout and/or node count exceeded)
var redirectTargetOrMainText = this.redirectTarget ? this.redirectTarget.getMainText() : mainText;
if (_config["default"].customBanners[redirectTargetOrMainText]) {
this.classes = _config["default"].customBanners[redirectTargetOrMainText].classes;
this.importances = _config["default"].customBanners[redirectTargetOrMainText].importances;
return parsed.resolve();
}
// Otherwise try reading from cached data
var cachedRatings = cache.read(mainText + "-ratings");
if (cachedRatings && cachedRatings.value && cachedRatings.staleDate && cachedRatings.value.classes != null && cachedRatings.value.importances != null) {
this.classes = cachedRatings.value.classes;
this.importances = cachedRatings.value.importances;
parsed.resolve();
if (!(0, _util.isAfterDate)(cachedRatings.staleDate)) {
// Just use the cached data
return parsed;
} // else: Use the cache data for now, but also fetch new data from API
}
var wikitextToParse = "";
_config["default"].bannerDefaults.extendedClasses.forEach(function (classname, index) {
wikitextToParse += "{{" + mainText + "|class=" + classname + "|importance=" + (_config["default"].bannerDefaults.extendedImportances[index] || "") + "}}/n";
});
return _api["default"].get({
action: "parse",
title: "Talk:沙盒",
// note: it works even if the page doesn't exist
text: wikitextToParse,
prop: "categorieshtml"
}).then(function /* result */
() {
/* var catsHtml = result.parse.categorieshtml["*"];
var extendedClasses = config.bannerDefaults.extendedClasses.filter(function(cl) {
return catsHtml.indexOf(cl+"-Class") !== -1; // i18n
}); */
var extendedClasses = _config["default"].bannerDefaults.extendedClasses; // TODO
_this.classes = [].concat(_toConsumableArray(_config["default"].bannerDefaults.classes), _toConsumableArray(extendedClasses));
/* this.importances = config.bannerDefaults.extendedImportances.filter(function(imp) {
return catsHtml.indexOf(imp+"-importance") !== -1; // i18n
}); */
_this.importances = _config["default"].bannerDefaults.extendedImportances; // TODO
cache.write(mainText + "-ratings", {
classes: _this.classes,
importances: _this.importances
}, 1);
return true;
});
};
// </nowiki>
},{"./api":15,"./cache":17,"./config":18,"./util":23}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
var _BannerWidget = _interopRequireDefault(require("./BannerWidget"));
var _util = require("../../util");
var _ParameterWidget = _interopRequireDefault(require("./ParameterWidget"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); 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 _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
// <nowiki>
var BannerListWidget = function BannerListWidget(config) {
config = config || {};
// Call parent constructor
BannerListWidget.parent.call(this, config);
OO.ui.mixin.GroupElement.call(this, {
$group: this.$element
});
this.$element.addClass("rater-bannerListWidget").css({
"padding": "20px 10px 16px 10px"
});
// Prefs
this.preferences = config.preferences;
this.oresClass = config.oresClass;
this.changed = false;
// Events
this.aggregate({
"remove": "bannerRemove"
});
this.connect(this, {
"bannerRemove": "onBannerRemove"
});
this.aggregate({
"changed": "bannerChanged"
});
this.connect(this, {
"bannerChanged": "setChanged"
});
this.aggregate({
"biographyBannerChange": "biographyBannerChanged"
});
this.connect(this, {
"biographyBannerChanged": "syncShellTemplateWithBiographyBanner"
});
this.aggregate({
"updatedSize": "bannerUpdatedSize"
});
this.connect(this, {
"bannerUpdatedSize": "onUpdatedSize"
});
};
OO.inheritClass(BannerListWidget, OO.ui.Widget);
OO.mixinClass(BannerListWidget, OO.ui.mixin.GroupElement);
/*
methods from mixin:
- addItems( items, [index] ) : OO.ui.Element (CHAINABLE)
- clearItems( ) : OO.ui.Element (CHAINABLE)
- findItemFromData( data ) : OO.ui.Element|null
- findItemsFromData( data ) : OO.ui.Element[]
- removeItems( items ) : OO.ui.Element (CHAINABLE)
*/
BannerListWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
BannerListWidget.prototype.setChanged = function () {
this.changed = true;
};
BannerListWidget.prototype.onBannerRemove = function (banner) {
this.removeItems([banner]);
this.setChanged();
};
BannerListWidget.prototype.syncShellTemplateWithBiographyBanner = function (biographyBanner) {
biographyBanner = biographyBanner || this.items.find(function (banner) {
return banner.mainText === "WikiProject Biography" || banner.redirectTargetMainText === "WikiProject Biography";
});
if (!biographyBanner) return;
var bannerShellTemplate = this.items.find(function (banner) {
return banner.mainText === _config["default"].shellTemplates[0] || banner.redirectTargetMainText === _config["default"].shellTemplates[0];
});
if (!bannerShellTemplate) {
return;
}
var paramsToSync = [{
name: "living",
normalise: true
}, {
name: "blpo",
normalise: true
}, {
name: "activepol",
normalise: true
}, {
name: "listas",
normalise: false
}];
paramsToSync.forEach(function (paramToSync) {
var _map = [biographyBanner, bannerShellTemplate].map(function (banner) {
return banner.parameterList.getParameterItems().find(function (parameter) {
return parameter.name === paramToSync.name || banner.paramAliases[parameter.name] === paramToSync.name;
});
}),
_map2 = _slicedToArray(_map, 2),
biographyParam = _map2[0],
shellParam = _map2[1];
if (!biographyParam) return;
var paramSyncValue = paramToSync.normalise ? (0, _util.normaliseYesNo)(biographyParam.value) : biographyParam.value;
biographyParam["delete"]();
if (!shellParam && paramSyncValue) {
var index = bannerShellTemplate.addParameterLayout.isVisible() ? -1 // Insert at the very end
: bannerShellTemplate.parameterList.items.length - 1; // Insert prior to the "add parameter" button
bannerShellTemplate.parameterList.addItems([new _ParameterWidget["default"]({
"name": paramToSync.name,
"value": paramSyncValue,
"autofilled": true
}, bannerShellTemplate.paramData && bannerShellTemplate.paramData[paramToSync.name])], index);
} else if (!biographyParam.autofilled && paramSyncValue) {
shellParam.setValue(paramSyncValue);
shellParam.setAutofilled();
}
});
};
BannerListWidget.prototype.addShellTemplateIfNeeeded = function () {
var _this = this;
if (!this.items.some(function (banner) {
return banner.isShellTemplate;
})) {
_BannerWidget["default"].newFromTemplateName(_config["default"].shellTemplates[0], {
withoutRatings: true
}, {
preferences: this.preferences,
isArticle: this.pageInfo.isArticle
}).then(function (shellBannerWidget) {
OO.ui.mixin.GroupElement.prototype.addItems.call(_this, [shellBannerWidget], 0);
// Autofill ratings (if able to)
_this.autofillClassRatings({
forBannerShell: true
});
// emit updatedSize event
_this.onUpdatedSize();
});
}
return this;
};
BannerListWidget.prototype.addItems = function (items, index) {
if (items.length === 0) {
return this;
}
// Call mixin method to do the adding
OO.ui.mixin.GroupElement.prototype.addItems.call(this, items, index);
// Autofill ratings (if able to, and if enabled in preferences)
if (!this.items.some(function (banner) {
return banner.isShellTemplate;
})) {
this.autofillClassRatings();
}
this.autofillImportanceRatings();
// emit updatedSize event
this.onUpdatedSize();
return this;
};
BannerListWidget.prototype.autofillClassRatings = function (config) {
config = config || {};
// Only autofill if set in preferences
if (false || !this.preferences.autofillClassFromOthers && !this.preferences.autofillClassFromOres && !config.forBannerShell) {
return;
}
// Check what banners already have
var uniqueClassRatings = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.items, function (banner) {
if (banner.isShellTemplate || !banner.hasClassRatings) {
return false;
}
var classItem = banner.classDropdown.getMenu().findSelectedItem();
return classItem && classItem.getData();
}, function (banner) {
return banner.classDropdown.getMenu().findSelectedItem().getData();
}));
// Can't autofill if there isn't either a single value, or no value
if (uniqueClassRatings.length > 1) {
return;
}
// Determine what to autofill with
var autoClass;
if (uniqueClassRatings.length === 1 && (this.preferences.autofillClassFromOthers || config.forBannerShell)) {
autoClass = uniqueClassRatings[0];
} else if (uniqueClassRatings.length === 0 && this.preferences.autofillClassFromOres && this.oresClass) {
// Don't autofill above C-class
switch (this.oresClass) {
case "Stub":
case "Start":
case "C":
case "List":
autoClass = this.oresClass;
}
} else {
// nothing to do
return;
}
// Do the autofilling
this.items.forEach(function (banner) {
if (!banner.hasClassRatings && !banner.isShellTemplate) {
return;
}
var classItem = banner.classDropdown.getMenu().findSelectedItem();
if (classItem && classItem.getData() && !config.forBannerShell) {
return;
}
if (config.forBannerShell && !banner.isShellTemplate && classItem.getData() === autoClass) {
banner.classDropdown.getMenu().selectItemByData(null);
return;
}
banner.classDropdown.getMenu().selectItemByData(autoClass);
banner.classDropdown.setAutofilled(true);
});
};
BannerListWidget.prototype.autofillImportanceRatings = function () {
if (!this.preferences.autofillImportance) {
return;
}
var isRegularArticle = this.pageInfo && this.pageInfo.isArticle && !this.pageInfo.redirect && !this.pageInfo.isDisambig;
if (!isRegularArticle) {
return;
}
// TODO: Should try to find a smarter, banner-specific way of determining importance.
// Maybe do something with ORES's "drafttopic" model.
var autoImportance = "Low";
this.items.forEach(function (banner) {
if (!banner.hasImportanceRatings) {
return;
}
var importanceItem = banner.importanceDropdown.getMenu().findSelectedItem();
if (importanceItem && importanceItem.getData()) {
return;
}
banner.importanceDropdown.getMenu().selectItemByData(autoImportance);
banner.importanceDropdown.setAutofilled(true);
});
};
BannerListWidget.prototype.setPreferences = function (prefs) {
this.preferences = prefs;
this.items.forEach(function (banner) {
return banner.setPreferences(prefs);
});
this.autofillClassRatings();
this.autofillImportanceRatings();
};
BannerListWidget.prototype.makeWikitext = function () {
var bannersWikitext = (0, _util.filterAndMap)(this.items, function (banner) {
return !banner.isShellTemplate;
}, function (banner) {
return banner.makeWikitext();
}).join("\n");
var shellTemplate = this.items.find(function (banner) {
return banner.isShellTemplate;
});
if (!shellTemplate) {
return bannersWikitext;
}
var shellParam1 = new _ParameterWidget["default"]({
name: "1",
value: "\n" + bannersWikitext + "\n" + (shellTemplate.nonStandardTemplates ? shellTemplate.nonStandardTemplates + "\n" : "")
});
shellTemplate.parameterList.addItems([shellParam1]);
var shellWikitext = shellTemplate.makeWikitext();
shellTemplate.parameterList.removeItems([shellParam1]);
return shellWikitext;
};
var _default = BannerListWidget; // </nowiki>
exports["default"] = _default;
},{"../../config":18,"../../util":23,"./BannerWidget":5,"./ParameterWidget":9}],5:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
var _ParameterListWidget = _interopRequireDefault(require("./ParameterListWidget"));
var _ParameterWidget = _interopRequireDefault(require("./ParameterWidget"));
var _DropdownParameterWidget = _interopRequireDefault(require("./DropdownParameterWidget"));
var _SuggestionLookupTextInputWidget = _interopRequireDefault(require("./SuggestionLookupTextInputWidget"));
var _util = require("../../util");
var _Template = require("../../Template");
var _HorizontalLayoutWidget = _interopRequireDefault(require("./HorizontalLayoutWidget"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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; }
// <nowiki>
function BannerWidget(template, config) {
var _this = this;
// Configuration initialization
config = config || {};
// Call parent constructor
BannerWidget["super"].call(this, config);
this.$overlay = config.$overlay;
/* --- PREFS --- */
this.preferences = config.preferences;
/* --- PROPS --- */
this.paramData = template.paramData;
this.paramAliases = template.paramAliases || {};
this.parameterSuggestions = template.parameterSuggestions;
this.name = template.name;
this.wikitext = template.wikitext;
this.pipeStyle = template.pipeStyle;
this.equalsStyle = template.equalsStyle;
this.endBracesStyle = template.endBracesStyle;
this.mainText = template.getTitle().getMainText();
this.redirectTargetMainText = template.redirectTarget && template.redirectTarget.getMainText();
this.isShellTemplate = template.isShellTemplate();
this.changed = template.parameters.some(function (parameter) {
return parameter.autofilled;
}); // initially false, unless some parameters were autofilled
this.hasClassRatings = template.classes && template.classes.length;
this.hasImportanceRatings = template.importances && template.importances.length;
this.inactiveProject = template.inactiveProject;
/* --- TITLE AND RATINGS --- */
this.getLocalTitleForClasses = function (rName) {
// TODO: structure
return _config["default"].bannerDefaultsLabel.extendedClasses.find(function (n) {
return n.includes(rName + " -");
}) || _config["default"].bannerDefaultsLabel.classes.find(function (n) {
return n.includes(rName + " -");
}) || rName;
};
this.getLocalTitleForImportances = function (rName) {
return _config["default"].bannerDefaultsLabel.importances.find(function (n) {
return n.includes(rName + " -");
}) || _config["default"].bannerDefaultsLabel.extendedImportances.find(function (n) {
return n.includes(rName + " -");
}) || rName;
};
this.openButton = new OO.ui.ButtonWidget({
icon: "link",
label: wgULS("打开页面", "打开页面"),
title: wgULS("打开页面", "打开页面"),
$element: $("<div style=\"width:100%\">")
});
this.removeButton = new OO.ui.ButtonWidget({
icon: "trash",
label: wgULS("移除横幅", "移除橫幅"),
title: wgULS("移除横幅", "移除橫幅"),
flags: "destructive",
$element: $("<div style=\"width:100%\">")
});
this.clearButton = new OO.ui.ButtonWidget({
icon: "cancel",
label: wgULS("清空参数", "清除參數"),
title: wgULS("清空参数", "清除參數"),
flags: "destructive",
$element: $("<div style=\"width:100%\">")
});
this.openButton.$element.find("a").css("width", "100%");
this.removeButton.$element.find("a").css("width", "100%");
this.clearButton.$element.find("a").css("width", "100%");
this.titleButtonsGroup = new OO.ui.ButtonGroupWidget({
items: [this.removeButton, this.clearButton, this.openButton],
$element: $("<span style='width:100%;'>")
});
this.mainLabelPopupButton = new OO.ui.PopupButtonWidget({
label: "{{".concat(template.getTitle().getMainText(), "}}").concat(this.inactiveProject ? wgULS("(不活跃)", "(不活躍)") : ""),
$element: $("<span style='display:inline-block;width:48%;margin-right:0;padding-right:8px'>"),
$overlay: this.$overlay,
indicator: "down",
framed: false,
popup: {
$content: this.titleButtonsGroup.$element,
width: 200,
padded: false,
align: "force-right",
anchor: false
}
});
this.mainLabelPopupButton.$element.children("a").first().css({
"font-size": "110%"
}).find("span.oo-ui-labelElement-label").css({
"white-space": "normal"
});
// Rating dropdowns
if (this.isShellTemplate) {
this.classDropdown = new _DropdownParameterWidget["default"]({
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">Class</span>"),
menu: {
items: [new OO.ui.MenuOptionWidget({
data: null,
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">\uFF08".concat(config.isArticle ? wgULS("无质量", "未評定") : wgULS("自动检测", "自動偵測"), "\uFF09</span>"))
})].concat(_toConsumableArray(_config["default"].bannerDefaults.classes.map(function (classname) {
return new OO.ui.MenuOptionWidget({
data: classname,
label: _this.getLocalTitleForClasses(classname)
});
})))
},
$overlay: this.$overlay
});
var shellClassParam = template.parameters.find(function (parameter) {
return parameter.name === "class";
});
this.classDropdown.getMenu().selectItemByData(shellClassParam && (0, _util.classMask)(shellClassParam.value));
} else if (this.hasClassRatings) {
this.classDropdown = new _DropdownParameterWidget["default"]({
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">" + "质量" + "</span>"),
menu: {
items: [new OO.ui.MenuOptionWidget({
data: null,
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">".concat(config.isArticle ? wgULS("(继承自shell)", "(繼承自shell)") : wgULS("(自动检测)", "(自動偵測)"), "</span>"))
})].concat(_toConsumableArray(template.classes.map(function (classname) {
return new OO.ui.MenuOptionWidget({
data: classname,
label: _this.getLocalTitleForClasses(classname)
});
})))
},
$overlay: this.$overlay
});
var classParam = template.parameters.find(function (parameter) {
return parameter.name === "class";
});
this.classDropdown.getMenu().selectItemByData(classParam && (0, _util.classMask)(classParam.value));
}
if (this.hasImportanceRatings) {
this.importanceDropdown = new _DropdownParameterWidget["default"]({
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">重要度</span>"),
menu: {
items: [new OO.ui.MenuOptionWidget({
data: null,
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">".concat(config.isArticle ? wgULS("(无重要度)", "(未評定)") : wgULS("(自动检测)", "(自動偵測)"), "</span>"))
})].concat(_toConsumableArray(template.importances.map(function (importance) {
return new OO.ui.MenuOptionWidget({
data: importance,
label: _this.getLocalTitleForImportances(importance)
});
})))
},
$overlay: this.$overlay
});
var importanceParam = template.parameters.find(function (parameter) {
return parameter.name === "importance";
});
this.importanceDropdown.getMenu().selectItemByData(importanceParam && (0, _util.importanceMask)(importanceParam.value));
}
this.titleLayout = new OO.ui.HorizontalLayout({
items: [this.mainLabelPopupButton]
});
if (this.hasClassRatings || this.isShellTemplate) {
this.titleLayout.addItems([this.classDropdown]);
}
if (this.hasImportanceRatings) {
this.titleLayout.addItems([this.importanceDropdown]);
}
/* --- PARAMETERS LIST --- */
var parameterWidgets = (0, _util.filterAndMap)(template.parameters, function (param) {
if (_this.isShellTemplate) {
if (param.name == "1") {
_this.shellParam1Value = param.value;
return false;
}
return param.name !== "class";
}
return param.name !== "class" && param.name !== "importance";
}, function (param) {
return new _ParameterWidget["default"](param, template.paramData[param.name], {
$overlay: _this.$overlay
});
});
this.parameterList = new _ParameterListWidget["default"]({
items: parameterWidgets,
preferences: this.preferences
});
/* --- ADD PARAMETER SECTION --- */
this.addParameterNameInput = new _SuggestionLookupTextInputWidget["default"]({
suggestions: template.parameterSuggestions,
placeholder: wgULS("参数名", "參數名稱"),
$element: $("<div style='display:inline-block;width:40%'>"),
validate: function (val) {
var _this$getAddParameter = this.getAddParametersInfo(val),
validName = _this$getAddParameter.validName,
name = _this$getAddParameter.name,
value = _this$getAddParameter.value;
return !name && !value ? true : validName;
}.bind(this),
allowSuggestionsWhenEmpty: true,
$overlay: this.$overlay
});
this.updateAddParameterNameSuggestions();
this.addParameterValueInput = new _SuggestionLookupTextInputWidget["default"]({
placeholder: wgULS("参数值", "參數內容"),
$element: $("<div style='display:inline-block;width:40%'>"),
validate: function (val) {
var _this$getAddParameter2 = this.getAddParametersInfo(null, val),
validValue = _this$getAddParameter2.validValue,
name = _this$getAddParameter2.name,
value = _this$getAddParameter2.value;
return !name && !value ? true : validValue;
}.bind(this),
allowSuggestionsWhenEmpty: true,
$overlay: this.$overlay
});
this.addParameterButton = new OO.ui.ButtonWidget({
label: wgULS("添加", "新增"),
icon: "add",
flags: "progressive"
}).setDisabled(true);
this.addParameterControls = new _HorizontalLayoutWidget["default"]({
items: [this.addParameterNameInput, new OO.ui.LabelWidget({
label: "="
}), this.addParameterValueInput, this.addParameterButton]
});
this.addParameterLayout = new OO.ui.FieldLayout(this.addParameterControls, {
label: wgULS("添加参数:", "新增參數:"),
align: "top"
}).toggle(false);
// A hack to make messages appear on their own line
this.addParameterLayout.$element.find(".oo-ui-fieldLayout-messages").css({
"clear": "both",
"padding-top": 0
});
/* --- OVERALL LAYOUT/DISPLAY --- */
// Display the layout elements, and a rule
this.$element.addClass("rater-bannerWidget").append(this.titleLayout.$element, this.parameterList.$element, this.addParameterLayout.$element);
if (!this.isShellTemplate) {
this.$element.append($("<hr>"));
}
if (this.isShellTemplate) {
this.$element.css({
"background": "#eee",
"border-radius": "10px",
"padding": "0 10px 5px",
"margin-bottom": "12px",
"font-size": "92%"
});
}
/* --- EVENT HANDLING --- */
if (this.hasClassRatings) {
this.classDropdown.connect(this, {
"change": "onClassChange"
});
}
if (this.hasImportanceRatings) {
this.importanceDropdown.connect(this, {
"change": "onImportanceChange"
});
}
this.parameterList.connect(this, {
"change": "onParameterChange",
"addParametersButtonClick": "showAddParameterInputs",
"updatedSize": "onUpdatedSize"
});
this.addParameterButton.connect(this, {
"click": "onParameterAdd"
});
this.addParameterNameInput.connect(this, {
"change": "onAddParameterNameChange",
"enter": "onAddParameterNameEnter",
"choose": "onAddParameterNameEnter"
});
this.addParameterValueInput.connect(this, {
"change": "onAddParameterValueChange",
"enter": "onAddParameterValueEnter",
"choose": "onAddParameterValueEnter"
});
this.openButton.connect(this, {
"click": "onOpenButtonClick"
});
this.removeButton.connect(this, {
"click": "onRemoveButtonClick"
});
this.clearButton.connect(this, {
"click": "onClearButtonClick"
});
/* --- APPLY PREF -- */
if (this.preferences.bypassRedirects) {
this.bypassRedirect();
}
}
OO.inheritClass(BannerWidget, OO.ui.Widget);
/**
* @param {String} templateName
* @param {Object} [data]
* @param {Boolean} data.withoutRatings
* @param {Boolean} data.isWrapper
* @param {Object} config
* @returns {Promise<BannerWidget>}
*/
BannerWidget.newFromTemplateName = function (templateName, data, config) {
var template = new _Template.Template();
template.name = templateName;
if (data && data.withoutRatings) {
template.withoutRatings = true;
}
return (0, _Template.getWithRedirectTo)(template).then(function (template) {
return $.when(template.setClassesAndImportances(), template.setParamDataAndSuggestions()).then(function () {
// Add missing required/suggested values
template.addMissingParams();
// Return the now-modified template
return template;
});
}).then(function (template) {
return new BannerWidget(template, config);
});
};
BannerWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
BannerWidget.prototype.setChanged = function () {
this.changed = true;
this.emit("changed");
// TODO: check it
if (this.mainText === "WikiProject Biography" || this.redirectTargetMainText === "WikiProject Biography") {
// Emit event so BannerListWidget can update the banner shell template (if present)
this.emit("biographyBannerChange");
}
};
BannerWidget.prototype.onParameterChange = function () {
this.setChanged();
this.updateAddParameterNameSuggestions();
};
BannerWidget.prototype.onClassChange = function () {
this.setChanged();
this.classChanged = true;
var classItem = this.classDropdown.getMenu().findSelectedItem();
if (classItem && classItem.getData() == null) {
// clear selection
this.classDropdown.getMenu().selectItem();
}
};
BannerWidget.prototype.onImportanceChange = function () {
this.setChanged();
this.importanceChanged = true;
var importanceItem = this.importanceDropdown.getMenu().findSelectedItem();
if (importanceItem && importanceItem.getData() == null) {
// clear selection
this.importanceDropdown.getMenu().selectItem();
}
};
BannerWidget.prototype.showAddParameterInputs = function () {
this.addParameterLayout.toggle(true);
this.addParameterNameInput.focus();
this.onUpdatedSize();
};
BannerWidget.prototype.getAddParametersInfo = function (nameInputVal, valueInputVal) {
var name = nameInputVal && nameInputVal.trim() || this.addParameterNameInput.getValue().trim();
var paramAlreadyIncluded = name === "class" || name === "importance" || name === "1" && this.isShellTemplate || this.parameterList.getParameterItems().some(function (paramWidget) {
return paramWidget.name === name;
});
var value = valueInputVal && valueInputVal.trim() || this.addParameterValueInput.getValue().trim();
var autovalue = name && this.paramData[name] && this.paramData[name].autovalue || null;
return {
validName: !!(name && !paramAlreadyIncluded),
validValue: !!(value || autovalue),
isAutovalue: !!(!value && autovalue),
isAlreadyIncluded: !!(name && paramAlreadyIncluded),
name: name,
value: value,
autovalue: autovalue
};
};
BannerWidget.prototype.onAddParameterNameChange = function () {
var _this$getAddParameter3 = this.getAddParametersInfo(),
validName = _this$getAddParameter3.validName,
validValue = _this$getAddParameter3.validValue,
isAutovalue = _this$getAddParameter3.isAutovalue,
isAlreadyIncluded = _this$getAddParameter3.isAlreadyIncluded,
name = _this$getAddParameter3.name,
autovalue = _this$getAddParameter3.autovalue; // Set value input placeholder as the autovalue
this.addParameterValueInput.$input.attr("placeholder", autovalue || "");
// Set suggestions, if the parameter has a list of allowed values
var allowedValues = this.paramData[name] && this.paramData[name].allowedValues && this.paramData[name].allowedValues.map(function (val) {
return {
data: val,
label: val
};
});
this.addParameterValueInput.setSuggestions(allowedValues || []);
// Set button disabled state based on validity
this.addParameterButton.setDisabled(!validName || !validValue);
// Show notice if autovalue will be used
this.addParameterLayout.setNotices(validName && isAutovalue ? [wgULS("将自动填写参数值", "將自動填寫參數值")] : []);
// Show error is the banner already has the parameter set
this.addParameterLayout.setErrors(isAlreadyIncluded ? [wgULS("参数已存在", "參數已存在")] : []);
};
BannerWidget.prototype.onAddParameterNameEnter = function () {
this.addParameterValueInput.focus();
};
BannerWidget.prototype.onAddParameterValueChange = function () {
var _this$getAddParameter4 = this.getAddParametersInfo(),
validName = _this$getAddParameter4.validName,
validValue = _this$getAddParameter4.validValue,
isAutovalue = _this$getAddParameter4.isAutovalue;
this.addParameterButton.setDisabled(!validName || !validValue);
this.addParameterLayout.setNotices(validName && isAutovalue ? ["将自动填写参数值"] : []);
};
BannerWidget.prototype.onAddParameterValueEnter = function () {
// Make sure button state has been updated
this.onAddParameterValueChange();
// Do nothing if button is disabled (i.e. name and/or value are invalid)
if (this.addParameterButton.isDisabled()) {
return;
}
// Add parameter
this.onParameterAdd();
};
BannerWidget.prototype.onParameterAdd = function () {
var _this$getAddParameter5 = this.getAddParametersInfo(),
validName = _this$getAddParameter5.validName,
validValue = _this$getAddParameter5.validValue,
name = _this$getAddParameter5.name,
value = _this$getAddParameter5.value,
autovalue = _this$getAddParameter5.autovalue;
if (!validName || !validValue) {
// Error should already be shown via onAddParameter...Change methods
return;
}
var newParameter = new _ParameterWidget["default"]({
"name": name,
"value": value || autovalue
}, this.paramData[name], {
$overlay: this.$overlay
});
this.parameterList.addItems([newParameter]);
this.addParameterNameInput.setValue("");
this.addParameterValueInput.setValue("");
this.addParameterNameInput.$input.focus();
};
BannerWidget.prototype.updateAddParameterNameSuggestions = function () {
var paramsInUse = {};
this.parameterList.getParameterItems().forEach(function (paramWidget) {
return paramsInUse[paramWidget.name] = true;
});
this.addParameterNameInput.setSuggestions(this.parameterSuggestions.filter(function (suggestion) {
return !paramsInUse[suggestion.data];
}));
};
BannerWidget.prototype.onOpenButtonClick = function () {
window.open(mw.util.getUrl("Template:" + this.name), '_blank');
};
BannerWidget.prototype.onRemoveButtonClick = function () {
this.emit("remove");
};
BannerWidget.prototype.onClearButtonClick = function () {
this.parameterList.clearItems(this.parameterList.getParameterItems());
if (this.hasClassRatings) {
this.classDropdown.getMenu().selectItem();
}
if (this.hasImportanceRatings) {
this.importanceDropdown.getMenu().selectItem();
}
};
BannerWidget.prototype.bypassRedirect = function () {
if (!this.redirectTargetMainText) {
return;
}
// Store the bypassed name
this.bypassedName = this.name;
// Update title label
this.mainLabelPopupButton.setLabel("{{".concat(this.redirectTargetMainText, "}}").concat(this.inactiveProject ? wgULS("(不活跃)", "(不活躍)") : ""));
// Update properties
this.name = this.redirectTargetMainText;
this.mainText = this.redirectTargetMainText;
this.redirectTargetMainText = null;
this.setChanged();
};
BannerWidget.prototype.makeWikitext = function () {
if (!this.changed && this.wikitext) {
return this.wikitext;
}
var pipe = this.pipeStyle;
var equals = this.equalsStyle;
var classItem = (this.hasClassRatings || this.isShellTemplate) && this.classDropdown.getMenu().findSelectedItem();
var classVal = classItem && classItem.getData();
var importanceItem = this.hasImportanceRatings && this.importanceDropdown.getMenu().findSelectedItem();
var importanceVal = importanceItem && importanceItem.getData();
return ("{{" + this.name + ((this.hasClassRatings || this.isShellTemplate) && classVal != null ? "".concat(pipe, "class").concat(equals).concat(classVal || "") : "") + (this.hasImportanceRatings && importanceVal != null ? "".concat(pipe, "importance").concat(equals).concat(importanceVal || "") : "") + this.parameterList.getParameterItems().map(function (parameter) {
return parameter.makeWikitext(pipe, equals);
}).join("") + this.endBracesStyle).replace(/\n+}}$/, "\n}}"); // avoid empty line at end like [[Special:Diff/925982142]]
};
BannerWidget.prototype.setPreferences = function (prefs) {
this.preferences = prefs;
if (this.preferences.bypassRedirects) {
this.bypassRedirect();
}
this.parameterList.setPreferences(prefs);
};
var _default = BannerWidget; // </nowiki>
exports["default"] = _default;
},{"../../Template":3,"../../config":18,"../../util":23,"./DropdownParameterWidget":6,"./HorizontalLayoutWidget":7,"./ParameterListWidget":8,"./ParameterWidget":9,"./SuggestionLookupTextInputWidget":11}],6:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
function DropdownParameterWidget(config) {
// Configuration initialization
config = $.extend({
$element: $("<span style='display:inline-block;width:24%'>")
}, config || {});
// Call parent constructor
DropdownParameterWidget["super"].call(this, config);
this.$overlay = config.$overlay;
this.$element.addClass("rater-dropdownParameterWidget");
// Autofilled icon
this.autofilled = !!config.autofilled;
this.autofilledIcon = new OO.ui.IconWidget({
icon: "robot",
title: "自動填寫",
flags: "progressive",
$element: $("<span style='margin: 0 -5px 0 5px;min-width: 16px;width: 16px;left:unset;'>")
}).toggle(this.autofilled);
this.$element.find(".oo-ui-indicatorElement-indicator").before(this.autofilledIcon.$element);
// Events
this.menu.connect(this, {
"choose": "onDropdownMenuChoose",
"select": "onDropdownMenuSelect"
});
}
OO.inheritClass(DropdownParameterWidget, OO.ui.DropdownWidget);
DropdownParameterWidget.prototype.setAutofilled = function (setAutofill) {
this.autofilledIcon.toggle(!!setAutofill);
this.$element.find(".oo-ui-dropdownWidget-handle").css({
"border": setAutofill ? "1px dashed #36c" : ""
});
this.autofilled = !!setAutofill;
};
DropdownParameterWidget.prototype.onDropdownMenuChoose = function () {
this.setAutofilled(false);
this.emit("change");
};
DropdownParameterWidget.prototype.onDropdownMenuSelect = function () {
this.emit("change");
};
DropdownParameterWidget.prototype.getValue = function () {
var selectedItem = this.menu.findSelectedItem();
return selectedItem && selectedItem.getData();
};
var _default = DropdownParameterWidget; // </nowiki>
exports["default"] = _default;
},{}],7:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// <nowiki>
/**
* A HorizontalLayout that is also a widget, and can thus be placed within
* field layouts.
*
* @class
* @param {*} config configuration for OO.ui.HorizontalLayout
*/
function HorizontalLayoutWidget(config) {
// Configuration initialization
config = config || {};
// Call parent constructor
HorizontalLayoutWidget["super"].call(this, {});
this.layout = new OO.ui.HorizontalLayout(_objectSpread({}, config, {
$element: this.$element
}));
}
OO.inheritClass(HorizontalLayoutWidget, OO.ui.Widget);
var _default = HorizontalLayoutWidget; // </nowiki>
exports["default"] = _default;
},{}],8:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
/**
* @cfg {OO.ui.Element[]} items Items to be added
* @cfg {Number} displayLimit The most to show at once. If the number of items
* is more than this, then only the first (displayLimit - 1) items are shown.
*/
var ParameterListWidget = function ParameterListWidget(config) {
config = config || {};
// Call parent constructor
ParameterListWidget.parent.call(this, config);
OO.ui.mixin.GroupElement.call(this, {
$group: this.$element
});
this.addItems(config.items);
this.$element.addClass("rater-parameterListWidget");
this.preferences = config.preferences;
// Hide some parameters (initially), if more than set display limit -- which is the
// one more than collapseParamsLowerLimit, to prevent only one param being hidden
// (mostly: may occasionally occur if params were auto-filled).
var displayLimit = this.preferences.collapseParamsLowerLimit + 1;
if (displayLimit && this.items.length > displayLimit) {
var hideFromNumber = displayLimit - 1; // One-indexed
var hideFromIndex = hideFromNumber - 1; // Zero-indexed
var hiddenCount = 0;
for (var i = hideFromIndex; i < this.items.length; i++) {
if (!this.items[i].autofilled) {
// Don't hide auto-filled params
this.items[i].toggle(false);
hiddenCount++;
}
}
if (hiddenCount > 0) {
// Add button to show the hidden params
this.showMoreParametersButton = new OO.ui.ButtonWidget({
label: wgULS("显示额外", "顯示其他") + hiddenCount + wgULS("个参数", "個參數"),
framed: false,
$element: $("<span style='margin-bottom:0'>")
});
this.addItems([this.showMoreParametersButton]);
}
}
// Add the button that allows user to add more parameters
this.addParametersButton = new OO.ui.ButtonWidget({
label: wgULS("添加参数", "新增參數"),
icon: "add",
framed: false,
$element: $("<span style='margin-bottom:0'>")
});
this.addItems([this.addParametersButton]);
/* --- Events --- */
// Handle delete events from ParameterWidgets
this.aggregate({
"delete": "parameterDelete"
});
this.connect(this, {
parameterDelete: "onParameterDelete"
});
// Handle change events from ParameterWidgets
this.aggregate({
change: "parameterChange"
});
this.connect(this, {
parameterChange: "onParameterChange"
});
// Handle updatedSize events from ParameterWidgets
this.aggregate({
"updatedSize": "parameterUpdatedSize"
});
this.connect(this, {
"parameterUpdatedSize": "onUpdatedSize"
});
// Handle button clicks
if (this.showMoreParametersButton) {
this.showMoreParametersButton.connect(this, {
"click": "onShowMoreParametersButtonClick"
});
}
this.addParametersButton.connect(this, {
"click": "onAddParametersButtonClick"
});
};
OO.inheritClass(ParameterListWidget, OO.ui.Widget);
OO.mixinClass(ParameterListWidget, OO.ui.mixin.GroupElement);
/*
methods from mixin:
- addItems( items, [index] ) : OO.ui.Element (CHAINABLE)
- clearItems( ) : OO.ui.Element (CHAINABLE)
- findItemFromData( data ) : OO.ui.Element|null
- findItemsFromData( data ) : OO.ui.Element[]
- removeItems( items ) : OO.ui.Element (CHAINABLE)
*/
ParameterListWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
ParameterListWidget.prototype.addItems = function (items, index) {
if (items.length === 0) {
return this;
}
// Call mixin method to do the adding
OO.ui.mixin.GroupElement.prototype.addItems.call(this, items, index);
// emit updatedSize event
this.onUpdatedSize();
return this;
};
ParameterListWidget.prototype.onParameterDelete = function (parameter) {
this.removeItems([parameter]);
this.emit("change");
};
ParameterListWidget.prototype.onParameterChange = function () {
this.emit("change");
};
ParameterListWidget.prototype.getParameterItems = function () {
return this.items.filter(function (item) {
return item.constructor.name === "ParameterWidget";
});
};
ParameterListWidget.prototype.onShowMoreParametersButtonClick = function () {
this.removeItems([this.showMoreParametersButton]);
this.items.forEach(function (parameterWidget) {
return parameterWidget.toggle(true);
});
this.onUpdatedSize();
};
ParameterListWidget.prototype.onAddParametersButtonClick = function () {
this.removeItems([this.addParametersButton]);
this.emit("addParametersButtonClick");
};
ParameterListWidget.prototype.makeWikitext = function (pipeStyle, equalsStyle) {
return this.getParameterItems().map(function (parameter) {
return parameter.makeWikitext(pipeStyle, equalsStyle);
}).join("");
};
ParameterListWidget.prototype.setPreferences = function (prefs) {
this.preferences = prefs;
var params = this.getParameterItems();
// Unhide some parameters of the collapseParamsLowerLimit has increased.
// (Not hiding any if it decreased, since it's a *lower* limit of what needs to be shown.)
if (params.length <= this.preferences.collapseParamsLowerLimit) {
return;
}
var hiddenParams = params.filter(function (param) {
return !param.isVisible();
});
var visibleParamsCount = params.length - hiddenParams.length;
if (hiddenParams === 0 || visibleParamsCount >= this.preferences.collapseParamsLowerLimit) {
return;
}
var numToUnhide = Math.min(this.preferences.collapseParamsLowerLimit - visibleParamsCount, hiddenParams.length);
for (var i = 0; i < numToUnhide; i++) {
hiddenParams[i].toggle(true);
}
var stillHiddenCount = hiddenParams.length - numToUnhide;
if (stillHiddenCount === 0) {
this.removeItems([this.showMoreParametersButton]);
} else {
this.showMoreParametersButton.setLabel(wgULS("显示额外", "顯示其他") + stillHiddenCount + wgULS("个参数", "個參數"));
}
};
var _default = ParameterListWidget; // </nowiki>
exports["default"] = _default;
},{}],9:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _util = require("../../util");
var _HorizontalLayoutWidget = _interopRequireDefault(require("./HorizontalLayoutWidget"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
function ParameterWidget(parameter, paramData, config) {
// Configuration initialization
config = config || {};
// Call parent constructor
ParameterWidget["super"].call(this, config);
this.$overlay = config.$overlay;
this.name = parameter.name;
this.value = parameter.value;
this.autofilled = parameter.autofilled;
this.isInvalid = parameter.value == null;
this.paramData = paramData || {};
this.allowedValues = this.paramData.allowedValues || [];
this.isRequired = this.paramData.required;
this.isSuggested = this.paramData.suggested;
// Make a checkbox if only 1 or 2 allowed values
switch (this.allowedValues.length) {
/* eslint-disable no-fallthrough */
case 1:
this.allowedValues[1] = null;
/* fall-through */
case 2:
var isFirstAllowedVal = this.allowedValues.indexOf(parameter.value) === 0 || this.allowedValues.map(_util.normaliseYesNo).indexOf((0, _util.normaliseYesNo)(parameter.value)) === 0;
var isSecondAllowedVal = this.allowedValues.indexOf(parameter.value || null) === 1 || this.allowedValues.map(_util.normaliseYesNo).indexOf(parameter.value ? (0, _util.normaliseYesNo)(parameter.value) : null) === 1;
var isIndeterminate = !isFirstAllowedVal && !isSecondAllowedVal;
this.checkbox = new OO.ui.CheckboxInputWidget({
selected: isIndeterminate ? undefined : isFirstAllowedVal,
indeterminate: isIndeterminate ? true : undefined,
$element: $("<label style='margin:0 0 0 5px'>")
});
break;
default:
// No checkbox
} /* eslint-enable no-fallthrough */
/* --- EDIT PARAMETER LAYOUT --- */
this.input = new OO.ui.ComboBoxInputWidget({
value: this.value,
// label: parameter.name + " =",
// labelPosition: "before",
options: (0, _util.filterAndMap)(this.allowedValues, function (val) {
return val !== null;
}, function (val) {
return {
data: val,
label: val
};
}),
$element: $("<div style='margin-bottom:0;'>"),
$overlay: this.$overlay
});
// Reduce the excessive whitespace/height
this.input.$element.find("input").css({
"padding-top": 0,
"padding-bottom": "2px",
"height": "24px"
});
// Fix label positioning within the reduced height
this.input.$element.find("span.oo-ui-labelElement-label").css({
"line-height": "normal"
});
// Also reduce height of dropdown button (if options are present)
this.input.$element.find("a.oo-ui-buttonElement-button").css({
"padding-top": 0,
"height": "24px",
"min-height": "0"
});
this.confirmButton = new OO.ui.ButtonWidget({
icon: "check",
label: "完成",
framed: false,
flags: "progressive",
$element: $("<span style='margin-right:0'>")
});
this.cancelButton = new OO.ui.ButtonWidget({
icon: "undo",
label: "取消",
framed: false
});
this.deleteButton = new OO.ui.ButtonWidget({
icon: this.isRequired ? "restore" : "trash",
label: this.isRequired ? wgULS("必填参数", "必要參數") : wgULS("删除", "刪除"),
framed: false,
flags: "destructive",
disabled: this.isRequired
});
this.editButtonControls = new OO.ui.ButtonGroupWidget({
items: [this.confirmButton, this.cancelButton, this.deleteButton],
$element: $("<span style='font-size:92%'>")
});
this.editButtonControls.$element.find("a span:first-child").css({
"min-width": "unset",
"width": "16px",
"margin-right": 0
});
this.editLayoutControls = new _HorizontalLayoutWidget["default"]({
items: [this.input, this.editButtonControls]
//$element: $("<div style='width: 48%;margin:0;'>")
});
this.editLayout = new OO.ui.FieldLayout(this.editLayoutControls, {
label: this.name + " =",
align: "top",
help: this.paramData.description && this.paramData.description.zh || false,
helpInline: true
}).toggle();
this.editLayout.$element.find("label.oo-ui-inline-help").css({
"margin": "-10px 0 5px 10px"
});
/* --- READ (COLLAPSED) DISPLAY OF PARAMETER --- */
this.invalidIcon = new OO.ui.IconWidget({
icon: "block",
title: "无效参数:没有指定值!",
flags: "destructive",
$element: $("<span style='margin: 0 5px 0 -5px; min-width: 16px; width: 16px;'>")
}).toggle(this.isInvalid);
this.fullLabel = new OO.ui.LabelWidget({
label: this.name + (this.value ? " = " + this.value : " "),
$element: $("<label style='margin: 0;'>")
});
this.autofilledIcon = new OO.ui.IconWidget({
icon: "robot",
title: "自动填写",
flags: "progressive",
$element: $("<span style='margin: 0 -5px 0 5px;min-width: 16px;width: 16px;'>")
}).toggle(this.autofilled);
this.editButton = new OO.ui.ButtonWidget({
icon: "edit",
framed: false,
$element: $("<span style='margin-bottom: 0;'>")
});
this.editButton.$element.find("a").css({
"border-radius": "0 10px 10px 0",
"margin-left": "5px"
});
this.editButton.$element.find("a span").first().css({
"min-width": "unset",
"width": "16px"
});
this.readLayout = new OO.ui.HorizontalLayout({
items: [this.invalidIcon, this.fullLabel, this.autofilledIcon, this.editButton],
$element: $("<span style='margin:0;width:unset;'>")
});
if (this.checkbox) {
this.readLayout.addItems([this.checkbox], 2);
}
/* --- CONTAINER FOR BOTH LAYOUTS --- */
this.$element = $("<div>").addClass("rater-parameterWidget").css({
"width": "unset",
"display": "inline-block",
"border": this.autofilled ? "1px dashed #36c" : "1px solid #ddd",
"border-radius": "10px",
"padding-left": "10px",
"margin": "0 8px 8px 0",
"background": this.isInvalid ? "#fddd" : "#fffe"
}).append(this.readLayout.$element, this.editLayout.$element);
this.editButton.connect(this, {
"click": "onEditClick"
});
this.confirmButton.connect(this, {
"click": "onConfirmClick"
});
this.cancelButton.connect(this, {
"click": "onCancelClick"
});
this.deleteButton.connect(this, {
"click": "onDeleteClick"
});
if (this.checkbox) {
this.checkbox.connect(this, {
"change": "onCheckboxChange"
});
}
}
OO.inheritClass(ParameterWidget, OO.ui.Widget);
ParameterWidget.prototype.onUpdatedSize = function () {
// Emit an "updatedSize" event so the parent window can update size, if needed
this.emit("updatedSize");
};
ParameterWidget.prototype.onEditClick = function () {
this.readLayout.toggle(false);
this.editLayout.toggle(true);
this.$element.css({
"background": "#fffe"
});
this.input.focus();
this.onUpdatedSize();
};
ParameterWidget.prototype.onConfirmClick = function () {
this.setValue(this.input.getValue());
this.readLayout.toggle(true);
this.editLayout.toggle(false);
this.onUpdatedSize();
};
ParameterWidget.prototype.onCancelClick = function () {
this.input.setValue(this.value);
this.readLayout.toggle(true);
this.editLayout.toggle(false);
this.onUpdatedSize();
};
ParameterWidget.prototype.onDeleteClick = function () {
this["delete"]();
};
ParameterWidget.prototype.onCheckboxChange = function (isSelected, isIndeterminate) {
if (isIndeterminate) {
return;
}
if (isSelected) {
this.setValue(this.allowedValues[0]);
} else {
this.setValue(this.allowedValues[1]);
}
};
ParameterWidget.prototype["delete"] = function () {
this.emit("delete");
};
ParameterWidget.prototype.setValue = function (val) {
// Turn off autofill stylings/icon
this.autofilled = false;
this.autofilledIcon.toggle(false);
this.$element.css({
"border": "1px solid #ddd"
});
// Update the stored value
this.value = val;
// Update the input value for edit mode
this.input.setValue(this.value);
// Update validity
this.isInvalid = this.value == null;
this.invalidIcon.toggle(this.isInvalid);
this.$element.css({
"background": this.isInvalid ? "#fddd" : "#fffe"
});
// Updated the label for read mode
this.fullLabel.setLabel(this.name + (this.value ? " = " + this.value : ""));
// Update the checkbox (if there is one)
if (this.checkbox) {
var isFirstAllowedVal = this.allowedValues.indexOf(val) === 0 || this.allowedValues.map(_util.normaliseYesNo).indexOf((0, _util.normaliseYesNo)(val)) === 0;
var isSecondAllowedVal = this.allowedValues.indexOf(val || null) === 1 || this.allowedValues.map(_util.normaliseYesNo).indexOf(val ? (0, _util.normaliseYesNo)(val) : null) === 1;
var isIndeterminate = !isFirstAllowedVal && !isSecondAllowedVal;
this.checkbox.setIndeterminate(isIndeterminate, true);
if (!isIndeterminate) {
var isSelected = isFirstAllowedVal;
this.checkbox.setSelected(isSelected, true);
}
}
// Emit a change event
this.emit("change");
};
ParameterWidget.prototype.setAutofilled = function () {
this.autofilled = true;
this.autofilledIcon.toggle(true);
this.$element.css({
"border": "1px dashed #36c"
});
};
ParameterWidget.prototype.makeWikitext = function (pipeStyle, equalsStyle) {
if (this.isInvalid) {
return "";
}
return pipeStyle + this.name + equalsStyle + (this.value || "");
};
ParameterWidget.prototype.focusInput = function () {
return this.input.focus();
};
var _default = ParameterWidget; // </nowiki>
exports["default"] = _default;
},{"../../util":23,"./HorizontalLayoutWidget":7}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
function PrefsFormWidget(config) {
// Configuration initialization
config = config || {};
// Call parent constructor
PrefsFormWidget["super"].call(this, config);
this.$element.addClass("rater-prefsFormWidget");
this.layout = new OO.ui.FieldsetLayout({
label: "设置",
$element: this.$element
});
this.preferences = {
"autostart": {
input: new OO.ui.ToggleSwitchWidget(),
label: "自动打开工具"
},
"autostartRedirects": {
input: new OO.ui.ToggleSwitchWidget(),
label: "重定向上自动打开"
},
"autostartNamespaces": {
input: new mw.widgets.NamespacesMultiselectWidget(),
label: "下列命名空间中自动打开"
},
"bypassRedirects": {
input: new OO.ui.ToggleSwitchWidget(),
label: "Bypass redirects to banners" // TODO
},
"autofillClassFromOthers": {
input: new OO.ui.ToggleSwitchWidget(),
label: "基于其他横幅自动填写质量"
},
"autofillClassFromOres": {
input: new OO.ui.ToggleSwitchWidget(),
label: "基于ORES指标自动填写质量"
},
"autofillImportance": {
input: new OO.ui.ToggleSwitchWidget(),
label: "自动填写低重要度"
},
"collapseParamsLowerLimit": {
input: new OO.ui.NumberInputWidget({
"min": 1
}),
label: "自动折叠超过此数量的参数" // review it
},
"watchlist": {
input: new OO.ui.ButtonSelectWidget({
items: [new OO.ui.ButtonOptionWidget({
data: "preferences",
label: "默认",
title: "遵循参数设置中有关“编辑页面”的设置"
}), new OO.ui.ButtonOptionWidget({
data: "watch",
label: "始终",
title: "始终添加编辑的页面到监视列表"
}), new OO.ui.ButtonOptionWidget({
data: "nochange",
label: "从不",
title: "不添加编辑的页面到监视列表"
})]
}).selectItemByData("preferences"),
label: "添加编辑的页面到监视列表"
},
"resetCache": {
input: new OO.ui.ButtonWidget({
label: "重置缓存",
title: "重置缓存数据,其中包括维基专题列表和模板参数",
flags: ["destructive"]
})
}
};
for (var prefName in this.preferences) {
if (prefName === "autofillClassFromOres") continue; // l10n
this.layout.addItems([new OO.ui.FieldLayout(this.preferences[prefName].input, {
label: this.preferences[prefName].label,
align: "right"
})]);
}
this.preferences.resetCache.input.connect(this, {
"click": "onResetCacheClick"
});
}
OO.inheritClass(PrefsFormWidget, OO.ui.Widget);
PrefsFormWidget.prototype.setPrefValues = function (prefs) {
var _this = this;
var _loop = function _loop(prefName) {
var value = prefs[prefName];
var input = _this.preferences[prefName] && _this.preferences[prefName].input;
switch (input && input.constructor.name) {
case "OoUiButtonSelectWidget":
input.selectItemByData(value);
break;
case "OoUiNumberInputWidget":
case "OoUiToggleSwitchWidget":
input.setValue(value);
break;
case "MwWidgetsNamespacesMultiselectWidget":
input.clearItems();
value.forEach(function (ns) {
return input.addTag(ns.toString(), ns === 0 ? wgULS("条目", "條目") : _config["default"].mw.wgFormattedNamespaces[ns]);
});
break;
}
};
for (var prefName in prefs) {
_loop(prefName);
}
};
PrefsFormWidget.prototype.getPrefs = function () {
var prefs = {};
for (var prefName in this.preferences) {
var input = this.preferences[prefName].input;
var value = void 0;
switch (input.constructor.name) {
case "OoUiButtonSelectWidget":
value = input.findSelectedItem().getData();
break;
case "OoUiToggleSwitchWidget":
value = input.getValue();
break;
case "OoUiNumberInputWidget":
value = Number(input.getValue()); // widget uses strings, not numbers!
break;
case "MwWidgetsNamespacesMultiselectWidget":
value = input.getValue().map(Number); // widget uses strings, not numbers!
break;
}
prefs[prefName] = value;
}
return prefs;
};
PrefsFormWidget.prototype.onResetCacheClick = function () {
var _this2 = this;
OO.ui.confirm(wgULS("重置缓存后,工具将关闭并重启。已进行但未保存的更改将被放弃。", "在重設快取後,工具將自動重新啟動。此前未發布的變更將被捨棄。")).then(function (confirmed) {
if (confirmed) {
_this2.emit("resetCache");
}
});
};
var _default = PrefsFormWidget; // </nowiki>
exports["default"] = _default;
},{"../../config":18}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
var SuggestionLookupTextInputWidget = function SuggestionLookupTextInputWidget(config) {
OO.ui.TextInputWidget.call(this, config);
OO.ui.mixin.LookupElement.call(this, config);
this.suggestions = Array.isArray(config.suggestions) ? config.suggestions : [];
this.$element.addClass("rater-suggestionLookupTextInputWidget");
};
OO.inheritClass(SuggestionLookupTextInputWidget, OO.ui.TextInputWidget);
OO.mixinClass(SuggestionLookupTextInputWidget, OO.ui.mixin.LookupElement);
// Set suggestion. param: Object[] with objects of the form { data: ... , label: ... }
SuggestionLookupTextInputWidget.prototype.setSuggestions = function (suggestions) {
if (!Array.isArray(suggestions)) {
if (suggestions != null) {
console.warn("[Rater] SuggestionLookupTextInputWidget.prototype.setSuggestions called with a non-array value:", suggestions);
}
return;
}
this.suggestions = suggestions;
};
// Returns data, as a resolution to a promise, to be passed to #getLookupMenuOptionsFromData
SuggestionLookupTextInputWidget.prototype.getLookupRequest = function () {
var deferred = $.Deferred().resolve(new RegExp("\\b" + mw.util.escapeRegExp(this.getValue()), "i"));
return deferred.promise({
abort: function abort() {}
});
};
// ???
SuggestionLookupTextInputWidget.prototype.getLookupCacheDataFromResponse = function (response) {
return response || [];
};
// Is passed data from #getLookupRequest, returns an array of menu item widgets
SuggestionLookupTextInputWidget.prototype.getLookupMenuOptionsFromData = function (pattern) {
var noRegex = function noRegex(pattern) {
if (typeof pattern != "string") return pattern;
return pattern.replace(/[([\]){}]/g, "\\$0");
};
var labelMatchesInputVal = function labelMatchesInputVal(suggestionItem) {
return pattern.test(noRegex(suggestionItem.label)) || !noRegex(suggestionItem.label) && pattern.test(noRegex(suggestionItem.data));
};
var makeMenuOptionWidget = function makeMenuOptionWidget(optionItem) {
return new OO.ui.MenuOptionWidget({
data: optionItem.data,
label: optionItem.label || optionItem.data
});
};
return this.suggestions.filter(labelMatchesInputVal).map(makeMenuOptionWidget);
};
// Extend onLookupMenuChoose method to emit an choose event
SuggestionLookupTextInputWidget.prototype.onLookupMenuChoose = function (item) {
// Get data
var itemData = item.getData();
// Simplify item data if it is an object with a name property
if (itemData && itemData.name) {
item.setData(itemData.name);
}
// First blur the input, to prevent the menu popping back up
this.$input.blur();
OO.ui.mixin.LookupElement.prototype.onLookupMenuChoose.call(this, item);
this.emit("choose", itemData);
};
var _default = SuggestionLookupTextInputWidget; // </nowiki>
exports["default"] = _default;
},{}],12:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("../../config"));
var _SuggestionLookupTextInputWidget = _interopRequireDefault(require("./SuggestionLookupTextInputWidget"));
var _getBanners = require("../../getBanners");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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; }
// <nowiki>
function cutTitle(name) {
// cutWikiProjectTemplateTitle
return name.replace(/WikiProject /i, "").replace("专题", "").replace("專題", "");
}
function TopBarWidget(config) {
var _this = this;
// Configuration initialization
config = $.extend({
expanded: false,
framed: false,
padded: false
}, config || {});
// Call parent constructor
TopBarWidget["super"].call(this, config);
this.$overlay = config.$overlay;
// Search box
this.searchBox = new _SuggestionLookupTextInputWidget["default"]({
//placeholder: wgULS("新增 WikiProject...","新增專題⋯⋯"),
placeholder: wgULS("添加维基专题或相关模板...", "添加維基專題橫幅或相關模板⋯⋯"),
$element: $("<div style='display:inline-block; margin:0 -1px; width:calc(100% - 55px);'>"),
$overlay: this.$overlay
});
(0, _getBanners.getBannerNames)().then(function (banners) {
var o = [banners.withRatings.map(function (bannerName) {
return {
label: cutTitle(bannerName),
data: {
name: bannerName
}
};
}), banners.withoutRatings.map(function (bannerName) {
return {
label: cutTitle(bannerName),
data: {
name: bannerName,
withoutRatings: true
}
};
})].flat(1);
var catPagesNum = o.length;
for (var _i = 0, _Object$keys = Object.keys(banners.projectsJSON); _i < _Object$keys.length; _i++) {
var key = _Object$keys[_i];
var alias = banners.projectsJSON[key];
o.push({
label: cutTitle(key) + " - {" + alias.join(", ") + "}",
data: {
name: key,
zhProjects: "values"
}
});
}
o = o.filter(function (b, i) {
return (
//i < catPagesNum
i >= catPagesNum || o.findIndex(function (e) {
return e.data.name === b.data.name;
}) != i
);
}); // Remove duplicates
return o;
}).then(function (bannerOptions) {
return _this.searchBox.setSuggestions(bannerOptions);
});
// Add button
this.addBannerButton = new OO.ui.ButtonWidget({
icon: "add",
title: "新增",
flags: "progressive",
$element: $("<span style='float:right;margin: 0;transform: translateX(-12px);'>")
});
var $searchContainer = $("<div style='display:inline-block; flex-shrink:1; flex-grow:100; min-width:250px; width:50%;'>").append(this.searchBox.$element, this.addBannerButton.$element);
// Set all classes/importances
// in the style of a popup button with a menu (is actually a dropdown with a hidden label, because that makes the coding easier.)
this.setAllDropDown = new OO.ui.DropdownWidget({
icon: "tag",
label: wgULS("全部设为...", "全部統一設置"),
invisibleLabel: true,
menu: {
items: [new OO.ui.MenuSectionOptionWidget({
label: wgULS("质量", "品質")
}), new OO.ui.MenuOptionWidget({
data: {
"class": null
},
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">" + wgULS("(无质量)", "(未評定)") + "</span>")
})].concat(_toConsumableArray(_config["default"].bannerDefaults.classes.map(function (classname, i) {
var display = _config["default"].bannerDefaultsLabel.classes[i];
return new OO.ui.MenuOptionWidget({
data: {
"class": classname
},
label: typeof display != "undefined" ? display : classname
});
})), [new OO.ui.MenuSectionOptionWidget({
label: "重要度"
}), new OO.ui.MenuOptionWidget({
data: {
importance: null
},
label: new OO.ui.HtmlSnippet("<span style=\"color:#777\">" + wgULS("(无重要度)", "(未評定)") + "</span>")
})], _toConsumableArray(_config["default"].bannerDefaults.importances.map(function (importance, i) {
var display = _config["default"].bannerDefaultsLabel.importances[i];
return new OO.ui.MenuOptionWidget({
data: {
importance: importance
},
label: typeof display != "undefined" ? display : importance
});
})))
},
$element: $("<span style=\"width:auto;display:inline-block;float:left;margin:0\" title='" + wgULS("全部设为...", "全部統一設置") + "'>"),
$overlay: this.$overlay
});
// Remove all banners button
this.removeAllButton = new OO.ui.ButtonWidget({
icon: "trash",
title: wgULS("全部删除", "全部刪除"),
flags: "destructive"
});
// Clear all parameters button
this.clearAllButton = new OO.ui.ButtonWidget({
icon: "cancel",
title: wgULS("全部清空", "全部清除"),
flags: "destructive"
});
// Group the buttons together
this.menuButtons = new OO.ui.ButtonGroupWidget({
items: [this.removeAllButton, this.clearAllButton],
$element: $("<span style='flex:1 0 auto;'>")
});
// Include the dropdown in the group
this.menuButtons.$element.prepend(this.setAllDropDown.$element);
// Put everything into a layout
this.$element.addClass("rater-topBarWidget").css({
"position": "fixed",
"width": "100%",
"background": "#ccc",
"display": "flex",
"flex-wrap": "wrap",
"justify-content": "space-around",
"margin": "-2px 0 0 0"
}).append($searchContainer, this.menuButtons.$element);
/* --- Event handling --- */
this.searchBox.connect(this, {
"enter": "onSearchSelect",
"choose": "onSearchSelect"
});
this.addBannerButton.connect(this, {
"click": "onSearchSelect"
});
this.setAllDropDown.getMenu().connect(this, {
"choose": "onRatingChoose"
});
this.removeAllButton.connect(this, {
"click": "onRemoveAllClick"
});
this.clearAllButton.connect(this, {
"click": "onClearAllClick"
});
}
OO.inheritClass(TopBarWidget, OO.ui.PanelLayout);
TopBarWidget.prototype.onSearchSelect = function (data) {
this.emit("searchSelect", data);
};
TopBarWidget.prototype.onRatingChoose = function (item) {
var data = item.getData();
if (data["class"] || data["class"] === null) {
this.emit("setClasses", data["class"]);
}
if (data.importance || data.importance === null) {
this.emit("setImportances", data.importance);
}
};
TopBarWidget.prototype.onRemoveAllClick = function () {
this.emit("removeAll");
};
TopBarWidget.prototype.onClearAllClick = function () {
this.emit("clearAll");
};
TopBarWidget.prototype.setDisabled = function (disable) {
[this.searchBox, this.addBannerButton, this.setAllDropDown, this.removeAllButton, this.clearAllButton].forEach(function (widget) {
return widget.setDisabled(disable);
});
};
var _default = TopBarWidget; // </nowiki>
exports["default"] = _default;
},{"../../config":18,"../../getBanners":20,"./SuggestionLookupTextInputWidget":11}],13:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _api = require("../api");
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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; }
// <nowiki>
/* var incrementProgressByInterval = function() {
var incrementIntervalDelay = 100;
var incrementIntervalAmount = 0.1;
var incrementIntervalMaxval = 98;
return window.setInterval(
incrementProgress,
incrementIntervalDelay,
incrementIntervalAmount,
incrementIntervalMaxval
);
}; */
var LoadDialog = function LoadDialog(config) {
LoadDialog["super"].call(this, config);
};
OO.inheritClass(LoadDialog, OO.ui.Dialog);
LoadDialog["static"].name = "loadDialog";
LoadDialog["static"].title = wgULS("正在加载专题评级工具⋯⋯", "正在載入專題評級工具⋯⋯");
// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
LoadDialog.prototype.initialize = function () {
var _this$content$elemen;
// Call the parent method.
LoadDialog["super"].prototype.initialize.call(this);
// Create a layout
this.content = new OO.ui.PanelLayout({
padded: true,
expanded: false
});
// Create content
this.progressBar = new OO.ui.ProgressBarWidget({
progress: 1
});
this.setuptasks = [new OO.ui.LabelWidget({
label: wgULS("加载设置...", "載入偏好設定⋯⋯"),
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: wgULS("加载项目横幅列表⋯⋯", "載入專題橫幅⋯⋯"),
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: wgULS("加载讨论页内容⋯⋯", "載入討論頁原始碼⋯⋯"),
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: wgULS("解析讨论页模板⋯⋯", "分析討論頁模板⋯⋯"),
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: wgULS("获取模板参数数据⋯⋯", "取得模板參數內容⋯⋯"),
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: wgULS("检查主题页面⋯⋯", "檢查目標頁面⋯⋯"),
$element: $("<p style=\"display:block\">")
}), new OO.ui.LabelWidget({
label: wgULS("检索质量估算⋯⋯", "取得評級預測數據⋯⋯"),
$element: $("<p style=\"display:block\">")
}).toggle()];
this.closeButton = new OO.ui.ButtonWidget({
label: wgULS("关闭", "關閉")
}).toggle();
this.setupPromises = [];
// Append content to layout
(_this$content$elemen = this.content.$element).append.apply(_this$content$elemen, [this.progressBar.$element, new OO.ui.LabelWidget({
label: wgULS("正在初始化:", "正在初始化:"),
$element: $("<strong style=\"display:block\">")
}).$element].concat(_toConsumableArray(this.setuptasks.map(function (widget) {
return widget.$element;
})), [this.closeButton.$element]));
// Append layout to dialog
this.$body.append(this.content.$element);
// Connect events to handlers
this.closeButton.connect(this, {
"click": "onCloseButtonClick"
});
};
LoadDialog.prototype.onCloseButtonClick = function () {
// Close this dialog, without passing any data
this.close();
};
// Override the getBodyHeight() method to specify a custom height (or don't to use the automatically generated height).
LoadDialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight(true);
};
LoadDialog.prototype.incrementProgress = function (amount, maximum) {
var priorProgress = this.progressBar.getProgress();
var incrementedProgress = Math.min(maximum || 100, priorProgress + amount);
this.progressBar.setProgress(incrementedProgress);
};
LoadDialog.prototype.addTaskPromiseHandlers = function (taskPromises) {
var _this = this;
var onTaskDone = function onTaskDone(index) {
// Add "Done!" to label
var widget = _this.setuptasks[index];
widget.setLabel(widget.getLabel() + " 完成!");
// Increment status bar. Show a smooth transition by
// using small steps over a short duration.
var totalIncrement = 100 / _this.setuptasks.length; // percent
var totalTime = 400; // milliseconds
var totalSteps = 10;
var incrementPerStep = totalIncrement / totalSteps;
for (var step = 0; step < totalSteps; step++) {
window.setTimeout(_this.incrementProgress.bind(_this), totalTime * step / totalSteps, incrementPerStep);
}
};
var onTaskError = function onTaskError(index, code, info) {
var widget = _this.setuptasks[index];
widget.setLabel(widget.getLabel() + wgULS("失败。", "失敗⋯⋯") + (0, _api.makeErrorMsg)(code, info));
_this.closeButton.toggle(true);
_this.updateSize();
};
taskPromises.forEach(function (promise, index) {
promise.then(function () {
return onTaskDone(index);
}, function (code, info) {
return onTaskError(index, code, info);
});
});
};
// Use getSetupProcess() to set up the window with data passed to it at the time
// of opening
LoadDialog.prototype.getSetupProcess = function (data) {
var _this2 = this;
data = data || {};
return LoadDialog["super"].prototype.getSetupProcess.call(this, data).next(function () {
var showOresTask = !!data.ores;
_this2.setuptasks[6].toggle(showOresTask);
var taskPromises = data.ores ? data.promises : data.promises.slice(0, -1);
data.isOpened.then(function () {
return _this2.addTaskPromiseHandlers(taskPromises);
});
}, this);
};
// Prevent window from closing too quickly, using getHoldProcess()
LoadDialog.prototype.getHoldProcess = function (data) {
data = data || {};
if (data.success) {
// Wait a bit before processing the close, which happens automatically
return LoadDialog["super"].prototype.getHoldProcess.call(this, data).next(800);
}
// No need to wait if closed manually
return LoadDialog["super"].prototype.getHoldProcess.call(this, data);
};
// Use the getTeardownProcess() method to perform actions whenever the dialog is closed.
LoadDialog.prototype.getTeardownProcess = function (data) {
var _this3 = this;
return LoadDialog["super"].prototype.getTeardownProcess.call(this, data).first(function () {
// Perform cleanup: reset labels
_this3.setuptasks.forEach(function (setuptask) {
var currentLabel = setuptask.getLabel();
setuptask.setLabel(currentLabel.slice(0, currentLabel.indexOf("...") + 3));
});
}, this);
};
var _default = LoadDialog; // </nowiki>
exports["default"] = _default;
},{"../api":15}],14:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _BannerWidget = _interopRequireDefault(require("./Components/BannerWidget"));
var _BannerListWidget = _interopRequireDefault(require("./Components/BannerListWidget"));
var _config = _interopRequireDefault(require("../config"));
var _api = _interopRequireWildcard(require("../api"));
var _PrefsFormWidget = _interopRequireDefault(require("./Components/PrefsFormWidget"));
var _prefs = require("../prefs");
var _Template = require("../Template");
var _TopBarWidget = _interopRequireDefault(require("./Components/TopBarWidget"));
var _util = require("../util");
var cache = _interopRequireWildcard(require("../cache"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
function MainWindow(config) {
MainWindow["super"].call(this, config);
}
OO.inheritClass(MainWindow, OO.ui.ProcessDialog);
MainWindow["static"].name = "main";
MainWindow["static"].title = $("<span>").css({
"font-weight": "normal"
}).append($("<a>").css({
"font-weight": "bold"
}).attr({
"href": mw.util.getUrl("User:Ericliu1912/維基專題評級工具"),
"target": "_blank"
}).text("維基專題評級工具"), " (", $("<a>").attr({
"href": mw.util.getUrl("User talk:Ericliu1912/維基專題評級工具"),
"target": "_blank"
}).text("討論"), ") ", $("<span>").css({
"font-size": "90%"
}).text("v" + _config["default"].script.version));
MainWindow["static"].size = "large";
MainWindow["static"].actions = [
// Primary (top right):
{
label: "✕",
// not using an icon since color becomes inverted, i.e. white on light-grey
title: wgULS("关闭评级工具(放弃未保存更改)", "關閉評級工具(不儲存任何變更)"),
flags: "primary",
modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs"
},
// Safe (top left)
{
action: "showPrefs",
flags: "safe",
icon: "settings",
title: wgULS("设置", "偏好設定"),
modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs"
},
// Others (bottom)
{
action: "save",
accessKey: "s",
label: new OO.ui.HtmlSnippet("<span style='padding:0 1em;'>" + "保存" + "</span>"),
flags: ["primary", "progressive"],
modes: ["edit", "diff", "preview"] // available when current mode isn't "prefs"
}, {
action: "preview",
accessKey: "p",
label: wgULS("显示预览", "顯示預覽"),
modes: ["edit", "diff"] // available when current mode isn't "preview" or "prefs"
}, {
action: "changes",
accessKey: "v",
label: wgULS("显示更改", "顯示變更"),
modes: ["edit", "preview"] // available when current mode isn't "diff" or "prefs"
}, {
action: "back",
label: wgULS("后退", "返回"),
modes: ["diff", "preview"] // available when current mode is "diff" or "prefs"
},
// "prefs" mode only
{
action: "savePrefs",
label: wgULS("更新", "儲存設定"),
flags: ["primary", "progressive"],
modes: "prefs"
}, {
action: "closePrefs",
label: "取消",
flags: "safe",
modes: "prefs"
}];
// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
MainWindow.prototype.initialize = function () {
// Call the parent method.
MainWindow["super"].prototype.initialize.call(this);
/* --- PREFS --- */
this.preferences = _config["default"].defaultPrefs;
/* --- TOP BAR --- */
this.topBar = new _TopBarWidget["default"]({
$overlay: this.$overlay
});
this.$head.css({
"height": "73px"
}).append(this.topBar.$element);
/* --- FOOTER --- */
this.oresLabel = new OO.ui.LabelWidget({
$element: $("<span style='float:right; padding: 10px; max-width: 50%; text-align: center;'>"),
label: $("<span>").append($("<a>").attr({
"href": mw.util.getUrl("mw:ORES"),
"target": "_blank"
}).append($("<img>").css({
"vertical-align": "text-bottom;"
}).attr({
"src": "//upload.wikimedia.org/wikipedia/commons/thumb/5/51/Objective_Revision_Evaluation_Service_logo.svg/40px-Objective_Revision_Evaluation_Service_logo.svg.png",
"title": wgULS("ORES 程序提供的质量估算", "由客觀修訂評估服務(ORES)自動預測評級"),
"alt": wgULS("ORES logo", "ORES 識別標誌"),
"width": "20px",
"height": "20px"
})), " ", $("<span class='oresPrediction'>"))
}).toggle(false);
this.pagetypeLabel = new OO.ui.LabelWidget({
$element: $("<span style='float:right; padding: 10px; max-width: 33.33%; text-align: center;'>")
}).toggle(false);
this.$foot.prepend(this.oresLabel.$element, this.pagetypeLabel.$element);
/* --- CONTENT AREA --- */
// Banners added dynamically upon opening, so just need a layout with an empty list
this.bannerList = new _BannerListWidget["default"]({
preferences: this.preferences
});
this.editLayout = new OO.ui.PanelLayout({
padded: false,
expanded: false,
$content: this.bannerList.$element
});
// Preferences, filled in with current prefs upon loading.
// TODO: Make this into a component, add fields and inputs
this.prefsForm = new _PrefsFormWidget["default"]();
this.prefsLayout = new OO.ui.PanelLayout({
padded: true,
expanded: false,
$content: this.prefsForm.$element
});
// Preview, Show changes
this.parsedContentContainer = new OO.ui.FieldsetLayout({
label: wgULS("预览", "預覽")
});
this.parsedContentWidget = new OO.ui.LabelWidget({
label: "",
$element: $("<div>")
});
this.parsedContentContainer.addItems([new OO.ui.FieldLayout(this.parsedContentWidget, {
align: "top"
})]);
this.parsedContentLayout = new OO.ui.PanelLayout({
padded: true,
expanded: false,
$content: this.parsedContentContainer.$element
});
this.contentArea = new OO.ui.StackLayout({
items: [this.editLayout, this.prefsLayout, this.parsedContentLayout],
padded: false,
expanded: false
});
this.$body.css({
"top": "73px"
}).append(this.contentArea.$element);
/* --- EVENT HANDLING --- */
this.topBar.connect(this, {
"searchSelect": "onSearchSelect",
"setClasses": "onSetClasses",
"setImportances": "onSetImportances",
"removeAll": "onRemoveAll",
"clearAll": "onClearAll"
});
this.bannerList.connect(this, {
"updatedSize": "onBannerListUpdateSize"
});
// Handle certain keyboard events. Requires something in the Rater window to be focused,
// so add a tabindex to the body and it's parent container.
this.$body.attr("tabindex", "999").parent().attr("tabindex", "999").keydown(function (event) {
var scrollAmount;
switch (event.which) {
case 33:
// page up
scrollAmount = this.$body.scrollTop() - this.$body.height() * 0.9;
break;
case 34:
// page down
scrollAmount = this.$body.scrollTop() + this.$body.height() * 0.9;
break;
default:
return;
}
this.$body.scrollTop(scrollAmount);
event.preventDefault();
}.bind(this));
this.prefsForm.connect(this, {
"resetCache": "onResetCache"
});
};
MainWindow.prototype.onBannerListUpdateSize = function () {
// Get the current scroll amount
var scrollAmount = this.$body.scrollTop();
// Update size (which resets the scroll to 0)
this.updateSize();
// Scroll to where it was before
this.$body.scrollTop(scrollAmount);
};
MainWindow.prototype.makeDraggable = function () {
var $frameEl = this.$element.find(".oo-ui-window-frame");
var $handleEl = this.$element.find(".oo-ui-processDialog-location").css({
"cursor": "move"
});
// Position for css translate transformations, relative to initial position
// (which is centered on viewport when scrolled to top)
var position = {
x: 0,
y: 0
};
var constrain = function constrain(val, minVal, maxVal) {
if (val < minVal) return minVal;
if (val > maxVal) return maxVal;
return val;
};
var constrainX = function constrainX(val) {
// Don't too far horizontally (leave at least 100px visible)
var limit = window.innerWidth / 2 + $frameEl.outerWidth() / 2 - 100;
return constrain(val, -1 * limit, limit);
};
var constrainY = function constrainY(val) {
// Can't take title bar off the viewport, since it's the drag handle
var minLimit = -1 * (window.innerHeight - $frameEl.outerHeight()) / 2;
// Don't go too far down the page: (whole page height) - (initial position)
var maxLimit = (document.documentElement || document).scrollHeight - window.innerHeight / 2;
return constrain(val, minLimit, maxLimit);
};
var pointerdown = false;
var dragFrom = {};
var onDragStart = function onDragStart(event) {
pointerdown = true;
dragFrom.x = event.clientX;
dragFrom.y = event.clientY;
};
var onDragMove = function onDragMove(event) {
if (!pointerdown || dragFrom.x == null || dragFrom.y === null) {
return;
}
var dx = event.clientX - dragFrom.x;
var dy = event.clientY - dragFrom.y;
dragFrom.x = event.clientX;
dragFrom.y = event.clientY;
position.x = constrainX(position.x + dx);
position.y = constrainY(position.y + dy);
$frameEl.css("transform", "translate(".concat(position.x, "px, ").concat(position.y, "px)"));
};
var onDragEnd = function onDragEnd() {
pointerdown = false;
delete dragFrom.x;
delete dragFrom.y;
// Make sure final positions are whole numbers
position.x = Math.round(position.x);
position.y = Math.round(position.y);
$frameEl.css("transform", "translate(".concat(position.x, "px, ").concat(position.y, "px)"));
};
// Use pointer events if available; otherwise use mouse events
var pointer = "PointerEvent" in window ? "pointer" : "mouse";
$handleEl.on(pointer + "enter.raterMainWin", function () {
return $frameEl.css("will-change", "transform");
}); // Tell browser to optimise transform
$handleEl.on(pointer + "leave.raterMainWin", function () {
if (!pointerdown) $frameEl.css("will-change", "");
}); // Remove optimisation if not dragging
$handleEl.on(pointer + "down.raterMainWin", onDragStart);
$("body").on(pointer + "move.raterMainWin", onDragMove);
$("body").on(pointer + "up.raterMainWin", onDragEnd);
};
// Override the getBodyHeight() method to specify a custom height
MainWindow.prototype.getBodyHeight = function () {
var currentlayout = this.contentArea.getCurrentItem();
var layoutHeight = currentlayout && currentlayout.$element.outerHeight(true);
var contentHeight = currentlayout && currentlayout.$element.children(":first-child").outerHeight(true);
return Math.max(200, layoutHeight, contentHeight);
};
// Use getSetupProcess() to set up the window with data passed to it at the time
// of opening
MainWindow.prototype.getSetupProcess = function (data) {
var _this = this;
data = data || {};
return MainWindow["super"].prototype.getSetupProcess.call(this, data).next(function () {
_this.makeDraggable();
// Set up preferences
_this.setPreferences(data.preferences);
_this.prefsForm.setPrefValues(data.preferences);
// Set subject page info
_this.subjectPage = data.subjectPage;
_this.pageInfo = {
redirect: data.redirectTarget,
isDisambig: data.disambig,
hasStubtag: data.stubtag,
isArticle: data.isArticle
};
// Set up edit mode banners
_this.actions.setMode("edit");
_this.bannerList.oresClass = data.isArticle && data.isList ? "列表" : data.ores && data.ores.prediction;
_this.bannerList.pageInfo = _this.pageInfo;
_this.bannerList.addItems(data.banners.map(function (bannerTemplate) {
return new _BannerWidget["default"](bannerTemplate, {
preferences: _this.preferences,
$overlay: _this.$overlay,
isArticle: _this.pageInfo.isArticle
});
}));
var shellTemplateBanner = _this.bannerList.items.find(function (banner) {
return banner.isShellTemplate;
});
if (shellTemplateBanner && shellTemplateBanner.shellParam1Value) {
shellTemplateBanner.nonStandardTemplates = _this.bannerList.items.reduce(function (bannersList, curBanner) {
return bannersList.replace(curBanner.wikitext, "");
}, shellTemplateBanner.shellParam1Value).trim().replace(/\n+/g, "\n");
}
_this.bannerList.addShellTemplateIfNeeeded().syncShellTemplateWithBiographyBanner();
// Show page type, or ORES prediction, if available
if (_this.pageInfo.redirect) {
_this.pagetypeLabel.setLabel(wgULS("重定向页面", "重新導向頁面")).toggle(true);
} else if (_this.pageInfo.isDisambig) {
_this.pagetypeLabel.setLabel(wgULS("消歧义页面", "消歧義頁面")).toggle(true);
} else if (_this.pageInfo.isArticle && data.isGA) {
_this.pagetypeLabel.setLabel(wgULS("优良条目", "優良條目")).toggle(true);
} else if (_this.pageInfo.isArticle && data.isFA) {
_this.pagetypeLabel.setLabel(wgULS("典范条目", "典範條目")).toggle(true);
} else if (_this.pageInfo.isArticle && data.isFL) {
_this.pagetypeLabel.setLabel("特色列表").toggle(true);
} else if (_this.pageInfo.isArticle && data.isList) {
_this.pagetypeLabel.setLabel("列表").toggle(true);
} else if (data.ores) {
_this.oresClass = data.ores.prediction;
_this.oresLabel.toggle(true).$element.find(".oresPrediction").append(wgULS("估算:", "預測品質:"), $("<strong>").text(data.ores.prediction), "(" + data.ores.probability + ")");
} else if (_this.pageInfo.isArticle) {
_this.pagetypeLabel.setLabel(wgULS("条目", "條目")).toggle(true);
} else {
// TODO: i18n
_this.pagetypeLabel.setLabel(_this.subjectPage.getNamespacePrefix().slice(0, -1) + wgULS("页面", "頁面")).toggle(true);
}
// Set props for use in making wikitext and edit summaries
_this.talkWikitext = data.talkWikitext;
_this.existingBannerNames = data.banners.map(function (bannerTemplate) {
return bannerTemplate.name;
});
_this.talkpage = data.talkpage;
// Force a size update to ensure eveything fits okay
_this.updateSize();
}, this);
};
// Set up the window it is ready: attached to the DOM, and opening animation completed
MainWindow.prototype.getReadyProcess = function (data) {
var _this2 = this;
data = data || {};
return MainWindow["super"].prototype.getReadyProcess.call(this, data).next(function () {
return _this2.topBar.searchBox.focus();
});
};
// Use the getActionProcess() method to do things when actions are clicked
MainWindow.prototype.getActionProcess = function (action) {
var _this3 = this;
if (action === "showPrefs") {
this.actions.setMode("prefs");
this.contentArea.setItem(this.prefsLayout);
this.topBar.setDisabled(true);
this.updateSize();
} else if (action === "savePrefs") {
var updatedPrefs = this.prefsForm.getPrefs();
return new OO.ui.Process().next((0, _prefs.setPrefs)(updatedPrefs).then(
// Success
function () {
_this3.setPreferences(updatedPrefs);
_this3.actions.setMode("edit");
_this3.contentArea.setItem(_this3.editLayout);
_this3.topBar.setDisabled(false);
_this3.updateSize();
},
// Failure
function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text(wgULS("保存设置失败。", "無法儲存設定。")), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
}));
} else if (action === "clearCache") {
return new OO.ui.Process().next(function () {
cache.clearAllItems();
_this3.close({
restart: true
});
});
} else if (action === "closePrefs") {
this.actions.setMode("edit");
this.contentArea.setItem(this.editLayout);
this.topBar.setDisabled(false);
this.prefsForm.setPrefValues(this.preferences);
this.updateSize();
} else if (action === "save") {
return new OO.ui.Process().next(_api["default"].editWithRetry(this.talkpage.getPrefixedText(), {
rvsection: 0
}, function (revision) {
return {
section: 0,
text: _this3.transformTalkWikitext(revision.content),
summary: _this3.makeEditSummary(),
watchlist: _this3.preferences.watchlist
};
})["catch"](function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text(wgULS("保存更改失败。", "無法儲存變更。")), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
})).next(function () {
return _this3.close({
success: true,
upgradedStub: _this3.pageInfo.hasStubtag && _this3.isRatedAndNotStub()
});
});
} else if (action === "preview") {
return new OO.ui.Process().next(_api["default"].post({
action: "parse",
contentmodel: "wikitext",
text: this.transformTalkWikitext(this.talkWikitext) + "\n<hr>\n" + wgULS("'''编辑摘要:''' ", "'''編輯摘要:'''") + this.makeEditSummary(),
title: this.talkpage.getPrefixedText(),
pst: 1
}).then(function (result) {
if (!result || !result.parse || !result.parse.text || !result.parse.text["*"]) {
return $.Deferred().reject("收到空结果\n可能没有产生变化。");
}
var previewHtmlSnippet = new OO.ui.HtmlSnippet(result.parse.text["*"]);
_this3.parsedContentWidget.setLabel(previewHtmlSnippet);
_this3.parsedContentContainer.setLabel(wgULS("预览:", "預覽:"));
_this3.actions.setMode("preview");
_this3.contentArea.setItem(_this3.parsedContentLayout);
_this3.topBar.setDisabled(true);
_this3.updateSize();
})["catch"](function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text(wgULS("显示变更失败。", "無法顯示變更。")), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
}));
} else if (action === "changes") {
return new OO.ui.Process().next(_api["default"].post({
action: "compare",
format: "json",
fromtext: this.talkWikitext,
fromcontentmodel: "wikitext",
totext: this.transformTalkWikitext(this.talkWikitext),
tocontentmodel: "wikitext",
prop: "diff"
}).then(function (result) {
if (!result || !result.compare || !result.compare["*"]) {
return $.Deferred().reject("收到空结果。\n可能没有产生变化。");
}
var $diff = $("<table>").addClass("diff").css("width", "100%").append($("<tr>").append($("<th>").attr({
"colspan": "2",
"scope": "col"
}).css("width", "50%").text("最新修订版本"), $("<th>").attr({
"colspan": "2",
"scope": "col"
}).css("width", "50%").text("新文本")), result.compare["*"], $("<tfoot>").append($("<tr>").append($("<td colspan='4'>").append($("<strong>").text(wgULS("编辑摘要:", "編輯摘要:"), _this3.makeEditSummary())))));
_this3.parsedContentWidget.setLabel($diff);
_this3.parsedContentContainer.setLabel("变更:");
_this3.actions.setMode("diff");
_this3.contentArea.setItem(_this3.parsedContentLayout);
_this3.topBar.setDisabled(true);
_this3.updateSize();
})["catch"](function (code, err) {
return $.Deferred().reject(new OO.ui.Error($("<div>").append($("<strong style='display:block;'>").text("显示更改失败。"), $("<span style='color:#777'>").text((0, _api.makeErrorMsg)(code, err)))));
}));
} else if (action === "back") {
this.actions.setMode("edit");
this.contentArea.setItem(this.editLayout);
this.topBar.setDisabled(false);
this.updateSize();
} else if (!action && this.bannerList.changed) {
// Confirm closing of dialog if there have been changes
if (confirm(wgULS("关闭工具将放弃未保存的更改,确认关闭?", "關閉工具將放棄未儲存的變更,確認關閉?"))) {
this.close();
}
}
return MainWindow["super"].prototype.getActionProcess.call(this, action);
};
// Use the getTeardownProcess() method to perform actions whenever the dialog is closed.
// `data` is the data passed into the window's .close() method.
MainWindow.prototype.getTeardownProcess = function (data) {
var _this4 = this;
return MainWindow["super"].prototype.getTeardownProcess.call(this, data).first(function () {
_this4.bannerList.clearItems();
_this4.topBar.searchBox.setValue("");
_this4.contentArea.setItem(_this4.editLayout);
_this4.topBar.setDisabled(false);
_this4.oresLabel.toggle(false).$element.find(".oresPrediction").empty();
_this4.pagetypeLabel.toggle(false).setLabel("");
_this4.$element.find(".oo-ui-window-frame").css("transform", "");
_this4.$element.find(".oo-ui-processDialog-location").off(".raterMainWin");
$("body").off(".raterMainWin");
});
};
MainWindow.prototype.setPreferences = function (prefs) {
this.preferences = $.extend({}, _config["default"].defaultPrefs, prefs);
// Applies preferences to existing items in the window:
this.bannerList.setPreferences(this.preferences);
};
MainWindow.prototype.onResetCache = function () {
this.executeAction("clearCache");
};
MainWindow.prototype.onSearchSelect = function (data) {
var _this5 = this;
this.topBar.searchBox.pushPending();
var name = this.topBar.searchBox.getValue().trim();
if (!name) {
this.topBar.searchBox.popPending().focus();
return;
}
var existingBanner = this.bannerList.items.find(function (banner) {
return banner.mainText === name || banner.redirectTargetMainText === name;
});
// Abort and show alert if banner already exists
if (existingBanner) {
this.topBar.searchBox.popPending();
return OO.ui.alert(wgULS("已有一个{{" + name + "}}横幅", "{{" + name + "}} 專題橫幅已經存在!")).then(this.searchBox.focus());
}
// Confirmation required for banners missing WikiProject from name, and for uncreated disambiguation talk pages
var confirmText; // TODO: recognize it later?
/* if (!/^[Ww](?:P|iki[Pp]roject)/.test(name)) { // i18n
confirmText = new OO.ui.HtmlSnippet(
wgULS("{{" + mw.html.escape(name) + "}} 是无法识别的WikiProject横幅。<br/>是否继续?",
"無法識別 {{" + mw.html.escape(name) + "}} 是否為維基專題橫幅。<br/>是否繼續操作?")
);
} else if (name === "WikiProject Disambiguation" && $("#ca-talk.new").length !== 0 && this.bannerList.items.length === 0) { // TODO: l10n
// eslint-disable-next-line no-useless-escape
confirmText = "New talk pages shouldn't be created if they will only contain the \{\{WikiProject Disambiguation\}\} banner. Continue?"; // TODO: right?
} */
$.when(confirmText ? OO.ui.confirm(confirmText) : true).then(function (confirmed) {
if (!confirmed) return;
// Create Template object
return _BannerWidget["default"].newFromTemplateName(name, data, {
preferences: _this5.preferences,
$overlay: _this5.$overlay,
isArticle: _this5.pageInfo.isArticle
}).then(function (banner) {
_this5.bannerList.addItems([banner]);
banner.setChanged();
_this5.updateSize();
});
}).then(function () {
return _this5.topBar.searchBox.setValue("").focus().popPending();
});
};
MainWindow.prototype.onSetClasses = function (classVal) {
var shellTemplate = this.bannerList.items.find(function (banner) {
return banner.isShellTemplate;
});
if (shellTemplate) {
shellTemplate.classDropdown.getMenu().selectItemByData(classVal);
shellTemplate.classDropdown.setAutofilled(false);
}
this.bannerList.items.forEach(function (banner) {
if (banner.hasClassRatings && !banner.isShellTemplate) {
banner.classDropdown.getMenu().selectItemByData(shellTemplate ? null : classVal);
banner.classDropdown.setAutofilled(false);
}
});
};
MainWindow.prototype.onSetImportances = function (importanceVal) {
this.bannerList.items.forEach(function (banner) {
if (banner.hasImportanceRatings) {
banner.importanceDropdown.getMenu().selectItemByData(importanceVal);
banner.importanceDropdown.setAutofilled(false);
}
});
};
MainWindow.prototype.onRemoveAll = function () {
this.bannerList.clearItems();
};
MainWindow.prototype.onClearAll = function () {
this.bannerList.items.forEach(function (banner) {
return banner.onClearButtonClick();
});
};
MainWindow.prototype.transformTalkWikitext = function (talkWikitext) {
var _this6 = this;
var bannersWikitext = this.bannerList.makeWikitext();
if (!talkWikitext) {
return bannersWikitext.trim();
}
// Reparse templates, in case talkpage wikitext has changed
var talkTemplates = (0, _Template.parseTemplates)(talkWikitext, true);
// replace existing banners wikitext with a control character
talkTemplates.forEach(function (template) {
if (_this6.existingBannerNames.includes(template.name)) {
talkWikitext = talkWikitext.replace(template.wikitext, "\x01");
}
});
// replace insertion point (first control character) with a different control character
talkWikitext = talkWikitext.replace("\x01", "\x02");
// remove other control characters
/* eslint-disable-next-line no-control-regex */
talkWikitext = talkWikitext.replace(/(?:\s|\n)*\x01(?:\s|\n)*/g, "");
// split into wikitext before/after the remaining control character (and trim each section)
var talkWikitextSections = talkWikitext.split("\x02").map(function (t) {
return t.trim();
});
if (talkWikitextSections.length === 2) {
// Found the insertion point for the banners
return (talkWikitextSections[0] + "\n" + bannersWikitext.trim() + "\n" + talkWikitextSections[1]).trim();
}
// Check if there's anything beside templates
var tempStr = talkWikitext;
talkTemplates.forEach(function (template) {
tempStr = tempStr.replace(template.wikitext, "");
});
if (/^#REDIRECT/i.test(talkWikitext) || !tempStr.trim()) {
// Is a redirect, or everything is a template: insert at the end
return talkWikitext.trim() + "\n" + bannersWikitext.trim();
} else {
// There is non-template content, so insert at the start
return bannersWikitext.trim() + "\n" + talkWikitext.trim();
}
};
MainWindow.prototype.isRatedAndNotStub = function () {
var nonStubRatinggs = this.bannerList.items.filter(function (banner) {
return banner.hasClassRatings && banner.classDropdown.getValue() && banner.classDropdown.getValue() !== "Stub";
});
return nonStubRatinggs.length > 0;
};
MainWindow.prototype.makeEditSummary = function () {
var _this7 = this;
var removedBanners = [];
var editedBanners = [];
var newBanners = [];
var shortName = function shortName(name) {
return name.replace("WikiProject ", "").replace("Subst:", "");
};
// Overall class/importance, if all the same
var allClasses = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.bannerList.items, function (banner) {
return banner.hasClassRatings || banner.isShellTemplate;
}, function (banner) {
return banner.classDropdown.getValue();
}));
var overallClass = allClasses.length === 1 && allClasses[0];
var allImportances = (0, _util.uniqueArray)((0, _util.filterAndMap)(this.bannerList.items, function (banner) {
return banner.hasImportanceRatings;
}, function (banner) {
return banner.importanceDropdown.getValue();
}));
var overallImportance = allImportances.length === 1 && allImportances[0];
// Don't use them unless some have changed
var someClassesChanged = false;
var someImportancesChanged = false;
// removed banners:
this.existingBannerNames.forEach(function (name) {
var banner = _this7.bannerList.items.find(function (banner) {
return banner.name === name || banner.bypassedName === name;
});
if (!banner) {
removedBanners.push(wgULS("−", "移除") + shortName(name));
}
});
// edited & new banners
this.bannerList.items.forEach(function (banner) {
var isNew = !banner.wikitext; // not added from wikitext on page
if (!isNew && !banner.changed) {
// Not changed
return;
}
var newClass = banner.hasClassRatings && (isNew || banner.classChanged) && banner.classDropdown.getValue();
if (newClass) {
someClassesChanged = true;
}
if (overallClass) {
newClass = null;
}
var newImportance = banner.hasImportanceRatings && (isNew || banner.importanceChanged) && banner.importanceDropdown.getValue();
if (newImportance) {
someImportancesChanged = true;
}
if (overallImportance) {
newImportance = null;
}
var rating = newClass && newImportance ? newClass + "/" + newImportance : newClass || newImportance || "";
if (rating) {
rating = " (" + rating + ")";
}
if (isNew) {
newBanners.push(wgULS("+", "新增") + shortName(banner.name) + rating);
} else {
editedBanners.push(shortName(banner.name) + rating);
}
});
// overall rating
var overallRating = someClassesChanged && overallClass && someImportancesChanged && overallImportance ? overallClass + "/" + overallImportance : someClassesChanged && overallClass || someImportancesChanged && overallImportance || "";
if (overallRating) {
overallRating = wgULS("(", "[") + overallRating + wgULS(")", "]");
}
return "\u8A55\u7D1A".concat(overallRating, "\uFF1A").concat([].concat(editedBanners, newBanners, removedBanners).join("、")).concat(_config["default"].script.advert);
};
var _default = MainWindow; // </nowiki>
exports["default"] = _default;
},{"../Template":3,"../api":15,"../cache":17,"../config":18,"../prefs":21,"../util":23,"./Components/BannerListWidget":4,"./Components/BannerWidget":5,"./Components/PrefsFormWidget":10,"./Components/TopBarWidget":12}],15:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.makeErrorMsg = exports["default"] = void 0;
var _config = _interopRequireDefault(require("./config"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
// <nowiki>
var API = new mw.Api({
ajax: {
headers: {
"Api-User-Agent": "Rater/" + _config["default"].script.version + " ( https://en.wikipedia.org/wiki/User:Evad37/Rater )" // TODO
}
}
});
/* ---------- API for ORES ---------------------------------------------------------------------- */
API.getORES = function (revisionID) {
return $.get("https://ores.wikimedia.org/v3/scores/zhwiki?models=articlequality&revids=" + revisionID);
};
/* ---------- Raw wikitext ---------------------------------------------------------------------- */
API.getRaw = function (page) {
return $.get("https:" + _config["default"].mw.wgServer + mw.util.getUrl(page, {
action: "raw"
})).then(function (data) {
if (!data) {
return $.Deferred().reject("ok-but-empty");
}
return data;
});
};
/* ---------- Edit with retry ------------------------------------------------------------------- */
/**
* @param {String} title
* @param {Object?} params additional params for the get request
* @returns {Promise<Object, string>} page, starttime timestamp
*/
var getPage = function getPage(title, params) {
return API.get($.extend({
"action": "query",
"format": "json",
"curtimestamp": 1,
"titles": title,
"prop": "revisions|info",
"rvprop": "content|timestamp",
"rvslots": "main"
}, params)).then(function (response) {
var page = Object.values(response.query.pages)[0];
var starttime = response.curtimestamp;
return $.Deferred().resolve(page, starttime);
});
};
/**
* @param {Object} page details object from API
* @param {string} starttime timestamp
* @param {Function} transform callback that prepares the edit:
* {Object} simplifiedPage => {Object|Promise<Object>} edit params
* @returns {Promise<Object>} params for edit query
*/
var processPage = function processPage(page, starttime, transform) {
var basetimestamp = page.revisions && page.revisions[0].timestamp;
var simplifiedPage = {
pageid: page.pageid,
missing: page.missing === "",
redirect: page.redirect === "",
categories: page.categories,
ns: page.ns,
title: page.title,
content: page.revisions && page.revisions[0].slots.main["*"]
};
return $.when(transform(simplifiedPage)).then(function (editParams) {
return $.extend({
action: "edit",
title: page.title,
// Protect against errors and conflicts
assert: "user",
basetimestamp: basetimestamp,
starttimestamp: starttime
}, editParams);
});
};
/** editWithRetry
*
* Edits a page, resolving edit conflicts, and retrying edits that fail. The
* tranform function may return a rejected promise if the page should not be
* edited; the @returns {Promise} will will be rejected with the same rejection
* values.
*
* Note: Unlike [mw.Api#Edit], a missing page will be created, unless the
* transform callback includes the "nocreate" param.
*
* [mw.Api#Edit]: <https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.edit>
*
* @param {String} title page to be edited
* @param {Object|null} getParams additional params for the get request
* @param {Function} transform callback that prepares the edit:
* {Object} simplifiedPage => {Object|Promise<Object>} params for API editing
* @returns {Promise<object>} promise, resolved on success, rejected if
* page was not edited
*/
API.editWithRetry = function (title, getParams, transform) {
return getPage(title, getParams).then(
// Succes: process the page
function (page, starttime) {
return processPage(page, starttime, transform);
},
// Failure: try again
function () {
return getPage(title, getParams).then(processPage, transform);
}).then(function (editParams) {
return API.postWithToken("csrf", editParams)["catch"](function (errorCode) {
if (errorCode === "editconflict") {
// Try again, starting over
return API.editWithRetry(title, getParams, transform);
}
// Try again
return API.postWithToken("csrf", editParams);
});
});
};
var makeErrorMsg = function makeErrorMsg(first, second) {
var code, xhr, message;
if (_typeof(first) === "object" && typeof second === "string") {
// Errors from $.get being rejected (ORES & Raw wikitext)
var errorObj = first.responseJSON && first.responseJSON.error;
if (errorObj) {
// Got an api-specific error code/message
code = errorObj.code;
message = errorObj.message;
} else {
xhr = first;
}
} else if (typeof first === "string" && _typeof(second) === "object") {
// Errors from mw.Api object
var mwErrorObj = second.error;
if (mwErrorObj) {
// Got an api-specific error code/message
code = errorObj.code;
message = errorObj.info;
} else if (first === "ok-but-empty") {
code = null;
message = "Got an empty response from the server";
} else {
xhr = second && second.xhr;
}
}
if (code && message) {
return "API error ".concat(code, ": ").concat(message);
} else if (message) {
return "API error: ".concat(message);
} else if (xhr) {
return "HTTP error ".concat(xhr.status);
} else if (typeof first === "string" && first !== "error" && typeof second === "string" && second !== "error") {
return "Error ".concat(first, ": ").concat(second);
} else if (typeof first === "string" && first !== "error") {
return "Error: ".concat(first);
} else {
return "Unknown API error";
}
};
exports.makeErrorMsg = makeErrorMsg;
var _default = API; // </nowiki>
exports["default"] = _default;
},{"./config":18}],16:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("./config"));
var _prefs = require("./prefs");
var _api = _interopRequireWildcard(require("./api"));
var _setup = _interopRequireDefault(require("./setup"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
var autoStart = function autoStart() {
return (0, _prefs.getPrefs)().then(function (prefs) {
// Check if pref is turned off
if (!prefs.autostart) {
return;
}
// Check if pref is turned off for redirects, and current page is a redirect
if (!prefs.autostartRedirects && window.location.search.includes("redirect=no")) {
return;
}
// Check if viewing diff/history/old version
if (/(action|diff|oldid)/.test(window.location.search)) {
return;
}
var subjectTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getSubjectPage();
// Check if subject page is the main page
if (subjectTitle.getPrefixedText() === "Main Page") {
return;
}
// Check subject page namespace
if (prefs.autostartNamespaces && prefs.autostartNamespaces.length && !prefs.autostartNamespaces.includes(_config["default"].mw.wgNamespaceNumber)) {
return;
}
// If talk page does not exist, can just autostart
if ($("#ca-talk.new").length) {
return (0, _setup["default"])();
}
/* Check templates present on talk page. Fetches indirectly transcluded templates, so will find
Template:WPBannerMeta (and its subtemplates). But some banners such as MILHIST don't use that
meta template, so we also have to check for template titles containg 'WikiProject'
*/
var talkTitle = mw.Title.newFromText(_config["default"].mw.wgPageName).getTalkPage();
return _api["default"].get({
action: "query",
format: "json",
prop: "templates",
titles: talkTitle.getPrefixedText(),
tlnamespace: "10",
tllimit: "500",
indexpageids: 1
}).then(function (result) {
var id = result.query.pageids;
var templates = result.query.pages[id].templates;
if (!templates) {
return (0, _setup["default"])();
}
var hasWikiproject = templates.some(function (template) {
return /(WikiProject|WPBanner)/.test(template.title);
});
if (!hasWikiproject) {
return (0, _setup["default"])();
}
}, function (code, jqxhr) {
// Silently ignore failures (just log to console)
console.warn("[Rater] Error while checking whether to autostart." + (code == null) ? "" : " " + (0, _api.makeErrorMsg)(code, jqxhr));
return $.Deferred().reject();
});
});
};
var _default = autoStart; // </nowiki>
exports["default"] = _default;
},{"./api":15,"./config":18,"./prefs":21,"./setup":22}],17:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clearAllItems = exports.clearInvalidItems = exports.clearItemIfInvalid = exports.read = exports.write = void 0;
var _util = require("./util");
// <nowiki>
/** write
* @param {String} key
* @param {Array|Object} val
* @param {Number} staleDays Number of days after which the data becomes stale (usable, but should
* be updated for next time).
* @param {Number} expiryDays Number of days after which the cached data may be deleted.
*/
var write = function write(key, val, staleDays, expiryDays) {
try {
var defaultStaleDays = 1;
var defaultExpiryDays = 30;
var millisecondsPerDay = 24 * 60 * 60 * 1000;
var staleDuration = (staleDays || defaultStaleDays) * millisecondsPerDay;
var expiryDuration = (expiryDays || defaultExpiryDays) * millisecondsPerDay;
var stringVal = JSON.stringify({
value: val,
staleDate: new Date(Date.now() + staleDuration).toISOString(),
expiryDate: new Date(Date.now() + expiryDuration).toISOString()
});
localStorage.setItem("Rater-" + key, stringVal);
} catch (e) {} // eslint-disable-line no-empty
};
/** read
* @param {String} key
* @returns {Array|Object|String|Null} Cached array or object, or empty string if not yet cached,
* or null if there was error.
*/
exports.write = write;
var read = function read(key) {
var val;
try {
var stringVal = localStorage.getItem("Rater-" + key);
if (stringVal !== "") {
val = JSON.parse(stringVal);
}
} catch (e) {
console.log("[Rater] error reading " + key + " from localStorage cache:");
console.log("\t" + e.name + " message: " + e.message + (e.at ? " at: " + e.at : "") + (e.text ? " text: " + e.text : ""));
}
return val || null;
};
exports.read = read;
var isRaterKey = function isRaterKey(key) {
return key && key.indexOf("Rater-") === 0;
};
var clearItemIfInvalid = function clearItemIfInvalid(key) {
if (!isRaterKey(key)) {
return;
}
var item = read(key.replace("Rater-", ""));
var isInvalid = !item || !item.expiryDate || (0, _util.isAfterDate)(item.expiryDate);
if (isInvalid) {
localStorage.removeItem(key);
}
};
exports.clearItemIfInvalid = clearItemIfInvalid;
var clearInvalidItems = function clearInvalidItems() {
// Loop backwards as localStorage length will decrease as items are removed
for (var i = localStorage.length; i >= 0; i--) {
setTimeout(clearItemIfInvalid, 100, localStorage.key(i));
}
};
exports.clearInvalidItems = clearInvalidItems;
var clearAllItems = function clearAllItems() {
// Loop backwards as localStorage length will decrease as items are removed
for (var i = localStorage.length; i >= 0; i--) {
var key = localStorage.key(i);
if (isRaterKey(key)) {
localStorage.removeItem(key);
}
}
};
// </nowiki>
exports.clearAllItems = clearAllItems;
},{"./util":23}],18:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
var packagejson = require("../package.json");
var version = packagejson.version;
// A global object that stores all the page and user configuration and settings
var config = {
// Script info
script: {
// Advert to append to edit summaries
advert: "[由[[User:Ericliu1912/維基專題評級工具#".concat(version,"|維基專題評級工具]]輔助]"),
version: version
},
// Default preferences, if user subpage raterPrefs.json does not exist
defaultPrefs: {
"autostart": false,
"autostartRedirects": false,
"autostartNamespaces": [0],
"minForShell": 1,
"bypassRedirects": true,
"autofillClassFromOthers": true,
"autofillClassFromOres": true,
"autofillImportance": true,
"collapseParamsLowerLimit": 6,
"watchlist": "preferences"
},
// MediaWiki configuration values
mw: mw.config.get(["skin", "wgPageName", "wgNamespaceNumber", "wgUserName", "wgFormattedNamespaces", "wgMonthNames", "wgRevisionId", "wgScriptPath", "wgServer", "wgCategories", "wgIsMainPage"]),
bannerDefaults: {
classes: ["FA", "FL", "A", "GA", "B", "C", "start", "stub", "list"],
importances: ["top", "high", "mid", "low"],
extendedClasses: ["category", "draft", "file", "FM", "portal", "project", "template",
//"Bplus",
"future", "current", "disambig", "NA", "redirect"
//"Book"
],
extendedImportances: ["top", "high", "mid", "low", "bottom", "NA"]
},
bannerDefaultsLabel: {
// i18n. this must be synchronized with the wiki and the above definition
classes: wgULS(["典范条目", "特色列表", "甲", "优良", "乙", "丙", "初", "小作品", "列表"], ["典範條目", "特色列表", "甲", "優良", "乙", "丙", "初", "小作品", "列表"]),
importances: wgULS(["极高", "高", "中", "低"], ["極高", "高", "中", "低"]),
extendedClasses: wgULS(["分类", "草稿", "文件", "典范媒体", "主题", "项目", "模板",
//"Bplus",
"未来", "动态", "消歧义", "不适用", "重定向"
//"Book"
], ["分類", "草稿", "檔案", "典範媒體", "主題", "計畫", "模板",
//"Bplus",
"未來", "動態", "消歧義", "不適用", "重新導向"]),
extendedImportances: wgULS(["极高", "高", "中", "低", "极低", "不适用"], ["極高", "高", "中", "低", "極低", "不適用"])
},
customBanners: {},
shellTemplates: [
// TODO: check it
"WikiProject banner shell", "WikiProjectBanners", "WikiProject Banners", "WPB", "WPBS", "Wikiprojectbannershell", "WikiProject Banner Shell", "Wpb", "WPBannerShell", "Wpbs", "Wikiprojectbanners", "WP Banner Shell", "WP banner shell", "Bannershell", "Wikiproject banner shell", "WikiProject Banners Shell", "WikiProjectBanner Shell", "WikiProjectBannerShell", "WikiProject BannerShell", "WikiprojectBannerShell", "WikiProject banner shell/redirect", "WikiProject Shell", "Banner shell", "Scope shell", "Project shell", "WikiProject banner"],
defaultParameterData: {
"auto": {
"label": {
"en": "Auto-rated",
"zh": "自动评级"
},
"description": {
"en": "Automatically rated by a bot. Allowed values: ['yes'].",
"zh": "机器人完成的自动评级。允许的值:['yes']。"
},
"autovalue": "yes"
},
"listas": {
"label": {
"en": "List as",
"zh": "排序索引"
},
"description": {
"en": "Sortkey for talk page",
"zh": "讨论页的排序索引"
}
},
"small": {
"label": {
"en": "Small?",
"zh": "小型?"
},
"description": {
"en": "Display a small version. Allowed values: ['yes'].",
"zh": "显示小型版本。允许的值:['yes']。"
},
"autovalue": "yes"
},
"attention": {
"label": {
"en": "Attention required?",
"zh": "需要关注?"
},
"description": {
"en": "Immediate attention required. Allowed values: ['yes'].",
"zh": "需要立即关注。允许的值:['yes']。"
},
"autovalue": "yes"
},
"needs-image": {
"label": {
"en": "Needs image?",
"zh": "需要图像?"
},
"description": {
"en": "Request that an image or photograph of the subject be added to the article. Allowed values: ['yes'].",
"zh": "条目需要本主题的图像或照片。允许的值:['yes']。"
},
"aliases": ["needs-photo"],
"autovalue": "yes",
"suggested": true
},
"needs-infobox": {
"label": {
"en": "Needs infobox?",
"zh": "需要信息框?"
},
"description": {
"en": "Request that an infobox be added to the article. Allowed values: ['yes'].",
"zh": "条目需要一个信息框。允许的值:['yes']。"
},
"aliases": ["needs-photo" // TODO: why?
],
"autovalue": "yes",
"suggested": true
}
}
};
var _default = config; // </nowiki>
exports["default"] = _default;
},{"../package.json":1}],19:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
// <nowiki>
// Attribution: Diff styles based on <https://en.wikipedia.org/wiki/Wikipedia:AutoWikiBrowser/style.css>
var styles = "table.diff, td.diff-otitle, td.diff-ntitle { table-layout: auto !important;; }\ntd.diff-otitle, td.diff-ntitle { text-align: center; }\ntd.diff-marker { text-align: right; font-weight: bold; font-size: 1.25em; }\ntd.diff-lineno { font-weight: bold; }\ntd.diff-addedline, td.diff-deletedline, td.diff-context { font-size: 88%; vertical-align: top; white-space: -moz-pre-wrap; white-space: pre-wrap; }\ntd.diff-addedline, td.diff-deletedline { border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; }\ntd.diff-addedline { border-color: #a3d3ff; }\ntd.diff-deletedline { border-color: #ffe49c; }\ntd.diff-context { background: #f3f3f3; color: #333333; border-style: solid; border-width: 1px 1px 1px 4px; border-color: #e6e6e6; border-radius: 0.33em; }\n.diffchange { font-weight: bold; text-decoration: none; }\ntable.diff {\n border: none;\n width: 98%; border-spacing: 4px;\n table-layout: fixed; /* Ensures that colums are of equal width */\n}\ntd.diff-addedline .diffchange, td.diff-deletedline .diffchange { border-radius: 0.33em; padding: 0.25em 0; }\ntd.diff-addedline .diffchange {\tbackground: #d8ecff; }\ntd.diff-deletedline .diffchange { background: #feeec8; }\ntable.diff td {\tpadding: 0.33em 0.66em; }\ntable.diff col.diff-marker { width: 2%; }\ntable.diff col.diff-content { width: 48%; }\ntable.diff td div {\n /* Force-wrap very long lines such as URLs or page-widening char strings. */\n word-wrap: break-word;\n /* As fallback (FF<3.5, Opera <10.5), scrollbars will be added for very wide cells\n instead of text overflowing or widening */\n overflow: auto;\n}" + // Override OOUI window manager preventing background scrolling/interaction
"html body.rater-mainWindow-open {\n\tposition: unset;\n\toverflow: unset;\n}\nhtml body.rater-mainWindow-open .oo-ui-windowManager-modal > .oo-ui-dialog.oo-ui-window-active {\n position: static;\n padding: 0;\n}" + // Increase z-index, to be above skin menus etc; smooth transition for dragging (transform:translate)
"html body.rater-mainWindow-open .oo-ui-dialog.oo-ui-window-active > div {\n z-index: 110;\n transition: all 0.25s ease-out 0s, transform 0s !important\n}\n" + // Ensure close dialog is visible
"html body.rater-mainWindow-open #mw-teleport-target {\n top: 0;\n bottom: 0;\n left: 0;\n right:0;\n}\n";
var _default = styles; // </nowiki>
exports["default"] = _default;
},{}],20:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getBannerNames = void 0;
var _api = _interopRequireWildcard(require("./api"));
var _util = require("./util");
var cache = _interopRequireWildcard(require("./cache"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
// <nowiki>
var cacheBanners = function cacheBanners(banners) {
cache.write("banners", banners, 2, 60);
};
// The code snippet from https://zh.wikipedia.org/wiki/User:Chiefwei/rater/rater.js
var raterData = {};
var dataurl = "";
function getRaterData(kind) {
if (kind === "default") {
dataurl = mw.config.get("wgScript") + "?action=raw&ctype=application/json&maxage=86400&title=User:Chiefwei/rater/" + kind + ".js";
} else {
dataurl = mw.config.get("wgScript") + "?action=raw&ctype=application/json&maxage=86400&title=User:Sz-iwbot/rater/" + kind + ".json";
}
if (raterData[kind] === void null) {
try {
$.ajax({
"url": dataurl,
"dataType": "json",
"async": false,
"success": function success(data) {
raterData[kind] = data;
},
"error": function error(xhr, message) {
mw.log.error(new Error(message));
}
});
} catch (e) {
alert("获取评级工具“" + kind + "”数据错误:" + e.message + "。评级工具可能无法正常工作。");
raterData[kind] = null;
}
}
return raterData[kind];
}
/**
* Gets banners/options from the Api
*
* @returns {Promise} Resolved with: banners object, bannerOptions array
*/
var getListOfBannersFromApi = function getListOfBannersFromApi() {
var finishedPromise = $.Deferred();
var querySkeleton = {
action: "query",
format: "json",
list: "categorymembers",
cmprop: "title",
cmnamespace: "10",
cmlimit: "500"
};
var categories = [
// i18n configure
{
title: "Category:含质量评级的专题横幅",
abbreviation: "withRatings",
banners: [],
processed: $.Deferred()
}, {
title: "Category:不含质量评级的专题横幅",
abbreviation: "withoutRatings",
banners: [],
processed: $.Deferred()
} /*,
{
title: "Category:WikiProject banner wrapper templates", // TODO: missing and review is needed
abbreviation: "wrappers",
banners: [],
processed: $.Deferred()
},
{
title: "Category:WikiProject banner templates not based on WPBannerMeta", // TODO: same as above
abbreviation: "notWPBM",
banners: [],
processed: $.Deferred()
},
{
title: "Category:Inactive WikiProject banners", // TODO: same as above
abbreviation: "inactive",
banners: [],
processed: $.Deferred()
}*/];
var processQuery = function processQuery(result, catIndex) {
if (!result.query || !result.query.categorymembers) {
// No results
// TODO: error or warning ********
finishedPromise.reject();
return;
}
// Gather titles into array - excluding "Template:" prefix
var resultTitles = result.query.categorymembers.map(function (info) {
return info.title.slice(9);
});
Array.prototype.push.apply(categories[catIndex].banners, resultTitles);
// Continue query if needed
if (result["continue"]) {
doApiQuery($.extend(categories[catIndex].query, result["continue"]), catIndex);
return;
}
categories[catIndex].processed.resolve();
};
var doApiQuery = function doApiQuery(q, catIndex) {
_api["default"].get(q).done(function (result) {
processQuery(result, catIndex);
}).fail(function (code, jqxhr) {
console.warn("[Rater] " + (0, _api.makeErrorMsg)(code, jqxhr, "Could not retrieve pages from [[:" + q.cmtitle + "]]"));
finishedPromise.reject();
});
};
categories.forEach(function (cat, index, arr) {
cat.query = $.extend({
"cmtitle": cat.title
}, querySkeleton);
$.when(arr[index - 1] && arr[index - 1].processed || true).then(function () {
doApiQuery(cat.query, index);
});
});
categories[categories.length - 1].processed.then(function () {
var banners = {};
categories.forEach(function (catObject) {
banners[catObject.abbreviation] = catObject.banners;
});
banners["projectsJSON"] = getRaterData("projects");
finishedPromise.resolve(banners);
});
return finishedPromise;
};
/**
* Gets banners from cache, if there and not too old
*
* @returns {Promise} Resolved with banners object
*/
var getBannersFromCache = function getBannersFromCache() {
var cachedBanners = cache.read("banners"); //TODO
if (!cachedBanners || !cachedBanners.value || !cachedBanners.staleDate) {
return $.Deferred().reject();
}
if ((0, _util.isAfterDate)(cachedBanners.staleDate)) {
// Update in the background; still use old list until then
getListOfBannersFromApi().then(cacheBanners);
}
return $.Deferred().resolve(cachedBanners.value);
};
/**
* Gets banner names, grouped by type (withRatings, withoutRatings, wrappers, notWPBM)
* @returns {Promise<Object>} Object of string arrays keyed by type (withRatings, withoutRatings, wrappers, notWPBM)
*/
var getBannerNames = function getBannerNames() {
return getBannersFromCache().then(function (banners) {
// Ensure all keys exist
if (!banners.withRatings || !banners.withoutRatings || !banners.projectsJSON /* || !banners.wrappers || !banners.notWPBM || !banners.inactive || !banners.wir*/) {
getListOfBannersFromApi().then(cacheBanners);
return $.extend({
withRatings: [],
withoutRatings: [],
projectsJSON: [] /* , wrappers: [], notWPBM: [], inactive: [], wir: []*/
}, banners);
}
// Success: pass through
return banners;
})["catch"](function () {
// Failure: get from Api, then cache them
var bannersPromise = getListOfBannersFromApi();
bannersPromise.then(cacheBanners);
return bannersPromise;
});
};
// </nowiki>
exports.getBannerNames = getBannerNames;
},{"./api":15,"./cache":17,"./util":23}],21:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setPrefs = exports.getPrefs = exports["default"] = void 0;
var _api = _interopRequireDefault(require("./api"));
var _util = require("./util");
var _config = _interopRequireDefault(require("./config"));
var cache = _interopRequireWildcard(require("./cache"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
var prefsPage = "User:".concat(mw.config.get("wgUserName"), "/raterPrefs.json");
var writePrefsToCache = function writePrefsToCache(prefs) {
return cache.write("prefs", prefs, 1 / 24 / 60 * 1,
// 1 min
1 / 24 / 60 * 1 // 1 min
);
};
var getPrefsFromApi = function getPrefsFromApi() {
if (mw.config.get("wgUserName") == null) {
return $.Deferred().resolve({});
}
return _api["default"].get({
"action": "query",
"format": "json",
"prop": "revisions",
"titles": prefsPage,
"rvprop": "content",
"rvslots": "main"
}).then(function (response) {
var page = response.query.pages[Object.keys(response.query.pages)[0]];
if (!page.pageid || page.missing === "") {
return _config["default"].defaultPrefs;
}
var prefs;
try {
prefs = JSON.parse(page.revisions[0].slots.main["*"]);
} catch (e) {
return $.Deferred().reject("JSON-parsing-error", e); // not work?
}
writePrefsToCache(prefs);
return prefs;
});
};
var getPrefsFromCache = function getPrefsFromCache() {
var cachedPrefs = cache.read("prefs");
if (!cachedPrefs || !cachedPrefs.value || !cachedPrefs.staleDate || (0, _util.isAfterDate)(cachedPrefs.staleDate)) {
// No cached value, or is too old
return $.Deferred().reject();
}
return $.Deferred().resolve(cachedPrefs.value);
};
var getPrefs = function getPrefs() {
return getPrefsFromCache().then(
// Success: pass through (first param only)
function (prefs) {
return $.Deferred().resolve(prefs);
},
// Failure: get from Api
function () {
return getPrefsFromApi();
});
};
/**
*
* @param {Object} updatedPrefs object with key:value pairs for preferences json.
*/
exports.getPrefs = getPrefs;
var setPrefs = function setPrefs(updatedPrefs) {
return _api["default"].editWithRetry(prefsPage, null, function () {
return {
"text": JSON.stringify(updatedPrefs),
"summary": "保存偏好設定" + _config["default"].script.advert
};
}).then(function () {
return writePrefsToCache(updatedPrefs);
});
};
exports.setPrefs = setPrefs;
var _default = {
get: getPrefs,
set: setPrefs
}; // </nowiki>
exports["default"] = _default;
},{"./api":15,"./cache":17,"./config":18,"./util":23}],22:[function(require,module,exports){
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _config = _interopRequireDefault(require("./config"));
var _api = _interopRequireDefault(require("./api"));
var _Template = require("./Template");
var _getBanners = require("./getBanners");
var cache = _interopRequireWildcard(require("./cache"));
var _windowManager = _interopRequireDefault(require("./windowManager"));
var _prefs = require("./prefs");
var _util = require("./util");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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; }
// <nowiki>
var setupRater = function setupRater(clickEvent) {
if (clickEvent) {
clickEvent.preventDefault();
}
var setupCompletedPromise = $.Deferred();
var currentPage = mw.Title.newFromText(_config["default"].mw.wgPageName);
var talkPage = currentPage && currentPage.getTalkPage();
var subjectPage = currentPage && currentPage.getSubjectPage();
var subjectIsArticle = _config["default"].mw.wgNamespaceNumber <= 1;
// Get preferences (task 0)
var prefsPromise = (0, _prefs.getPrefs)();
// Get lists of all banners (task 1)
var bannersPromise = (0, _getBanners.getBannerNames)();
// Load talk page (task 2)
var loadTalkPromise = _api["default"].get({
action: "query",
prop: "revisions",
rvprop: "content",
rvsection: "0",
titles: talkPage.getPrefixedText(),
indexpageids: 1
}).then(function (result) {
var id = result.query.pageids;
var wikitext = id < 0 ? "" : result.query.pages[id].revisions[0]["*"];
return wikitext;
});
var curAllTemplateAlias = null;
var getAllTemplateAlias = function getAllTemplateAlias(JSON) {
if (curAllTemplateAlias != null) return curAllTemplateAlias; // cache
var o = [];
o = o.concat(Object.keys(JSON));
for (var _i = 0, _Object$keys = Object.keys(JSON); _i < _Object$keys.length; _i++) {
var key = _Object$keys[_i];
var alias = JSON[key];
o.push(alias);
}
curAllTemplateAlias = o;
return curAllTemplateAlias;
};
// Parse talk page for banners (task 3)
var parseTalkPromise = loadTalkPromise.then(function (wikitext) {
return (0, _Template.parseTemplates)(wikitext, true);
}) // Get all templates
.then(function (templates) {
return templates.filter(function (template) {
return template.getTitle() !== null;
});
}) // Filter out invalid templates (e.g. parser functions)
.then(function (templates) {
return (0, _Template.getWithRedirectTo)(templates);
}) // Check for redirects
.then(function (templates) {
return bannersPromise.then(function (allBanners) {
// Get list of all banner templates
return (0, _util.filterAndMap)(templates,
// Filter out non-banners
function (template) {
if (template.isShellTemplate()) {
return true;
}
var mainText = template.redirectTarget ? template.redirectTarget.getMainText() : template.getTitle().getMainText();
return allBanners.withRatings.includes(mainText) || allBanners.withoutRatings.includes(mainText) || getAllTemplateAlias(allBanners.projectsJSON).includes(mainText);
},
// Set additional properties if needed
function (template) {
var mainText = template.redirectTarget ? template.redirectTarget.getMainText() : template.getTitle().getMainText();
if (allBanners.withoutRatings.includes(mainText)) {
template.withoutRatings = true;
}
if (!(new RegExp("WikiProject ", "i").test(mainText) || mainText.includes("专题") || mainText.includes("專題"))) {
template.nonBanner = true;
}
return template;
});
});
});
// Retrieve and store classes, importances, and TemplateData (task 4)
var templateDetailsPromise = parseTalkPromise.then(function (templates) {
// Wait for all promises to resolve
return $.when.apply(null, [].concat(_toConsumableArray(templates.map(function (template) {
return template.isShellTemplate() ? null : template.setClassesAndImportances();
})), _toConsumableArray(templates.map(function (template) {
return template.setParamDataAndSuggestions();
})))).then(function () {
// Add missing required/suggested values
templates.forEach(function (template) {
return template.addMissingParams();
});
// Return the now-modified templates
return templates;
});
});
// Check subject page features (task 5) - but don't error out if request fails
var subjectPageCheckPromise = _api["default"].get({
action: "query",
format: "json",
formatversion: "2",
prop: "categories",
titles: subjectPage.getPrefixedText(),
redirects: 1
//,clcategories: ["Category:全部消歧義頁面", "Category:全部小作品", "Category:優良條目", "Category:典范条目", "Category:特色列表"] // i18n; disabling it will return all categories, the hasCategoryRegex require it.
}).then(function (response) {
if (!response || !response.query || !response.query.pages) {
return null;
}
var redirectTarget = response.query.redirects && response.query.redirects[0].to || false;
if (redirectTarget || !subjectIsArticle) {
return {
redirectTarget: redirectTarget
};
}
var page = response.query.pages[0];
var hasCategory = function hasCategory(category) {
return page.categories && page.categories.find(function (cat) {
return cat.title === "Category:" + category;
});
};
var hasCategoryRegex = function hasCategoryRegex(regex) {
return page.categories && page.categories.find(function (cat) {
return regex.test(cat.title);
});
};
return {
// i18n
redirectTarget: redirectTarget,
disambig: hasCategory("全部消歧義頁面"),
stubtag: hasCategory("全部小作品"),
isGA: hasCategory("優良條目"),
isFA: hasCategory("典范条目"),
isFL: hasCategory("特色列表"),
isList: !hasCategory("特色列表") && hasCategoryRegex(/^Category:.*列表.*/)
};
})["catch"](function () {
return null;
}); // Failure ignored
// Retrieve rating from ORES (task 6, only needed for articles) - but don't error out if request fails
var shouldGetOres = false; //( subjectIsArticle ); // TODO: Don't need to get ORES for redirects or disambigs
if (false || shouldGetOres) {
var latestRevIdPromise = !currentPage.isTalkPage() ? $.Deferred().resolve(_config["default"].mw.wgRevisionId) : _api["default"].get({
action: "query",
format: "json",
prop: "revisions",
titles: subjectPage.getPrefixedText(),
rvprop: "ids",
indexpageids: 1
}).then(function (result) {
if (result.query.redirects) {
return false;
}
var id = result.query.pageids;
var page = result.query.pages[id];
if (page.missing === "") {
return false;
}
if (id < 0) {
return $.Deferred().reject();
}
return page.revisions[0].revid;
});
var oresPromise = latestRevIdPromise.then(function (latestRevId) {
if (!latestRevId) {
return false;
}
return _api["default"].getORES(latestRevId).then(function (result) {
var data = result.zhwiki.scores[latestRevId].articlequality;
if (data.error) {
return $.Deferred().reject(data.error.type, data.error.message);
}
var prediction = data.score.prediction;
var probabilities = data.score.probability;
if (prediction === "FA" || prediction === "GA") {
return {
prediction: "B or higher",
probability: ((probabilities.FA + probabilities.GA + probabilities.B) * 100).toFixed(1) + "%"
};
}
return {
prediction: prediction,
probability: (probabilities[prediction] * 100).toFixed(1) + "%"
};
})["catch"](function () {
return null;
}); // Failure ignored;
});
}
// Open the load dialog
var isOpenedPromise = $.Deferred();
var loadDialogWin = _windowManager["default"].openWindow("loadDialog", {
promises: [bannersPromise, loadTalkPromise, parseTalkPromise, templateDetailsPromise, subjectPageCheckPromise, shouldGetOres && oresPromise],
ores: shouldGetOres,
isOpened: isOpenedPromise
});
loadDialogWin.opened.then(isOpenedPromise.resolve);
$.when(prefsPromise, loadTalkPromise, templateDetailsPromise, subjectPageCheckPromise, shouldGetOres && oresPromise).then(
// All succeded
function (preferences, talkWikitext, banners, subjectPageCheck, oresPredicition) {
var result = {
success: true,
talkpage: talkPage,
subjectPage: subjectPage,
talkWikitext: talkWikitext,
banners: banners,
preferences: preferences,
isArticle: subjectIsArticle
};
if (subjectPageCheck) {
result = _objectSpread({}, result, {}, subjectPageCheck);
}
if (oresPredicition && subjectPageCheck && !subjectPageCheck.isGA && !subjectPageCheck.isFA && !subjectPageCheck.isFL) {
result.ores = oresPredicition;
}
_windowManager["default"].closeWindow("loadDialog", result);
}); // Any failures are handled by the loadDialog window itself
// On window closed, check data, and resolve/reject setupCompletedPromise
loadDialogWin.closed.then(function (data) {
if (data && data.success) {
// Got everything needed: Resolve promise with this data
setupCompletedPromise.resolve(data);
} else if (data && data.error) {
// There was an error: Reject promise with error code/info
setupCompletedPromise.reject(data.error.code, data.error.info);
} else {
// Window closed before completion: resolve promise without any data
setupCompletedPromise.resolve(null);
}
cache.clearInvalidItems();
});
return setupCompletedPromise;
};
var _default = setupRater; // </nowiki>
exports["default"] = _default;
},{"./Template":3,"./api":15,"./cache":17,"./config":18,"./getBanners":20,"./prefs":21,"./util":23,"./windowManager":24}],23:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mostFrequent = mostFrequent;
exports.uniqueArray = uniqueArray;
exports.classMask = classMask;
exports.importanceMask = importanceMask;
exports.normaliseYesNo = exports.filterAndMap = exports.isAfterDate = void 0;
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
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(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
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; }
// <nowiki>
// Various utility functions and objects that might be used in multiple places
var isAfterDate = function isAfterDate(dateString) {
return new Date(dateString) < new Date();
};
exports.isAfterDate = isAfterDate;
var yesWords = [
// TODO: L10
"add", "added", "affirm", "affirmed", "include", "included", "on", "true", "yes", "y", "1"];
var noWords = [
// TODO: L10
"decline", "declined", "exclude", "excluded", "false", "none", "not", "no", "n", "off", "omit", "omitted", "remove", "removed", "0"];
var normaliseYesNo = function normaliseYesNo(val) {
if (val == null) {
return val;
}
var trimmedLcVal = val.trim().toLowerCase();
if (yesWords.includes(trimmedLcVal)) {
return "yes";
} else if (noWords.includes(trimmedLcVal)) {
return "no";
} else {
return trimmedLcVal;
}
};
/**
*
* @param {Array} array
* @param {Function} filterPredicate (currentVal, currentIndex, array) => {boolean}
* @param {Function} mapTransform (currentVal, currentIndex, array) => {any}
* @returns {Array}
*/
exports.normaliseYesNo = normaliseYesNo;
var filterAndMap = function filterAndMap(array, filterPredicate, mapTransform) {
return array.reduce(function (accumulated, currentVal, currentIndex) {
if (filterPredicate(currentVal, currentIndex, array)) {
return [].concat(_toConsumableArray(accumulated), [mapTransform(currentVal, currentIndex, array)]);
}
return accumulated;
}, []);
};
/**
*
* @param {string[]|number[]} array
* @returns {string|null} item with the highest frequency
* e.g. `mostFrequent(["apple", "apple", "orange"])` returns `"apple"`
*/
exports.filterAndMap = filterAndMap;
function mostFrequent(array) {
if (!array || !Array.isArray(array) || array.length === 0) return null;
var map = {};
var mostFreq = null;
array.forEach(function (item) {
map[item] = (map[item] || 0) + 1;
if (mostFreq === null || map[item] > map[mostFreq]) {
mostFreq = item;
}
});
return mostFreq;
}
/**
*
* @param {string[]|number[]} array
* @returns {string[]|number[]} array with only unique values
* e.g. `uniqueArray(["apple", "apple", "orange"])` returns `["apple", "orange"]`
*/
function uniqueArray(array) {
if (!array || !Array.isArray(array) || array.length === 0) return [];
var seen = {};
var unique = [];
array.forEach(function (item) {
if (!seen[item]) {
unique.push(item);
seen[item] = true;
}
});
return unique;
}
function classMask(classVal) {
// TODO: check it
if (!classVal) {
return classVal;
}
switch (classVal.toLowerCase()) {
case "fa":
case "fl":
case "a":
case "ga":
case "b":
case "c":
case "na":
case "fm":
case "al":
case "bl":
case "cl":
return classVal.toUpperCase();
case "File":
case "image":
case "img":
return "file";
case "Category":
case "cat":
case "categ":
return "category";
case "disambiguation":
case "Disambig":
case "disamb":
case "dab":
return "disambig";
case "Redirect":
case "redir":
case "red":
return "redirect";
case "Template":
case "temp":
case "tpl":
return "template";
case "bplus":
case "b+":
return "Bplus";
default:
return classVal;
}
}
function importanceMask(importance) {
if (!importance) {
return importance;
}
if (importance.toLowerCase() === "na") {
return "NA";
}
return importance.slice(0, 1).toUpperCase() + importance.slice(1).toLowerCase();
}
// </nowiki>
},{}],24:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _LoadDialog = _interopRequireDefault(require("./Windows/LoadDialog"));
var _MainWindow = _interopRequireDefault(require("./Windows/MainWindow"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
// <nowiki>
var factory = new OO.Factory();
// Register window constructors with the factory.
factory.register(_LoadDialog["default"]);
factory.register(_MainWindow["default"]);
var manager = new OO.ui.WindowManager({
"factory": factory
});
$(document.body).append(manager.$element);
var _default = manager; // </nowiki>
exports["default"] = _default;
},{"./Windows/LoadDialog":13,"./Windows/MainWindow":14}]},{},[2])
});
// </nowiki>