User:1F616EMO/NotabilitySearchRedo/core.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/*
* Smarter notability search assistant (Chinese Wikipedia) v2.0
*
* Use the following line to load this script:
* mw.loader.load( "https://zh.wikipedia.org/w/index.php?title=User:1F616EMO/NotabilitySearchRedo/core.js&action=raw&ctype=text/javascript" );
*
* This script is made by 1F616EMO on zhwiki, licensed under CC BY-SA 4.0.
*/
// <nowiki>
mw.loader.using([
'mediawiki.api',
'mediawiki.jqueryMsg',
'ext.gadget.HanAssist',
]).then((require) => {
window.NotabilitySearch = window.NotabilitySearch || {};
window.NotabilitySearch.version = window.NotabilitySearch.version || '2.0';
const api = new mw.Api();
const { batchConv } = require('ext.gadget.HanAssist');
mw.messages.set(batchConv({
'notability-searchbox-close': {
hans: '关闭',
hant: '關閉',
},
'notability-searchbox-title': {
hans: '检查条目是否符合收录标准',
hant: '檢查條目是否符合收錄標準',
},
'notability-searchbox-section-titles-title': {
hans: '条目标题',
hant: '條目標題',
},
'notability-searchbox-section-categories-title': {
hans: '条目分类',
hant: '條目分類',
},
'notability-searchbox-section-hiddencats-title': {
hans: '条目隐藏分类',
hant: '條目隱藏分類',
},
'notability-searchbox-section-utilities-title': {
hans: '搜寻工具',
hant: '搜尋工具',
},
'notability-searchbox-submit': {
hans: '搜索',
hant: '搜尋',
},
'notability-searchbox-twaction-notability': {
hans: '不符合收录标准',
hant: '不符合收錄標準',
},
'notability-searchbox-twaction-notability-unreferenced': {
hans: '收录标准无来源',
hant: '收錄標準無來源',
},
'notability-searchbox-twaction-notability-xfd': {
hans: '收录标准提删',
hant: '收錄標準提刪',
},
'notability-searchbox-portlet-text': {
hans: '收录标准搜寻',
hant: '收錄標準搜尋',
},
'notability-searchbox-portlet-description': {
hans: '从条目标题和分类构建搜索关键字',
hant: '從條目標題和分類構建搜尋關鍵字',
},
'notability-searchbox-button': {
hans: '高级收录标准搜索',
hant: '進階收錄標準搜尋',
},
}));
// See mediawiki/includes/parser/Parser.php:4751
const tc = '.'; // Over simplified but works cuz Mediawiki already denied illegal ones
const titleRegexes = [
new RegExp(`^(${tc}+?)( ?\\(${tc}+\\))$`), // $p1
new RegExp(`^(${tc}+?)( ?(${tc}+))$`), // $p2
new RegExp(`^(${tc}+?)( ?\\(${tc}+\\)|)((?:, |,|، )${tc}+|)$`), // $p3
];
const ContentLineRegex = /^(?!{{| *\|).*$/gm;
const langRegex = /{{[Ll]ang(?:-|x\|)[a-z]{2,}\|([^|}]*?)(?:\|[^}]*?)?}}/g;
function getTitles(titles) {
const pagename = mw.config.get("wgPageName");
titles.add(pagename.replace('_', ' '));
const title = mw.config.get("wgTitle");
titles.add(title);
const nameparts = title.split('/');
const subname = nameparts[nameparts.length - 1];
titles.add(subname);
// Extract capture group 1 from each of p1,4,3
for (let i = 0; i < titleRegexes.length; i++) {
const regex = titleRegexes[i];
const matches = title.match(regex);
if (matches && matches[1]) {
titles.add(matches[1]);
}
}
// Here comes the async part
// fetch possible title form {{lang-xx|text|<other arguments...>}} and {{langx|xx|text|<other arguments...>}}
return api.get({
action: 'parse',
prop: 'wikitext',
page: pagename,
section: 0,
}).done((data) => {
const wikitext = data.parse.wikitext['*'];
const nonTemplateLineMatches = wikitext.match(ContentLineRegex);
if (nonTemplateLineMatches) {
for (let i = 0; i < nonTemplateLineMatches.length; i++) {
const line = nonTemplateLineMatches[i];
while (matches = langRegex.exec(line)) {
titles.add(matches[1]);
}
}
}
});
}
function getCategories(categories, hiddencats) {
return api.get({
action: 'query',
prop: 'categories',
titles: mw.config.get('wgPageName'),
clprop: 'hidden',
cllimit: 'max',
formatversion: 2,
}).done((data) => {
const page = data.query.pages[0];
if (page && page.categories) {
for (let i = 0; i < page.categories.length; i++) {
const catname = page.categories[i].title.replace(/^Category:/, '');
if (page.categories[i].hidden) {
hiddencats.add(catname);
} else {
categories.add(catname);
}
}
}
});
}
window.NotabilitySearch.searchUtilityFunctions = window.NotabilitySearch.searchUtilityFunctions || [];
function getSearchUtilities(searchUtilities, titles, categories, hiddencats) {
const promises = [];
for (const func of window.NotabilitySearch.searchUtilityFunctions) {
if (typeof func === 'function') {
const result = func(searchUtilities, titles, categories, hiddencats);
if (result && result.then) {
promises.push(result);
}
} else {
searchUtilities.add(func);
}
}
return Promise.all(promises);
}
// {Display text, function on click}
window.NotabilitySearch.buttonUtilitiesFunctions = window.NotabilitySearch.buttonUtilitiesFunctions || [];
function getButtonUtilities($actionlist) {
const promises = [];
const addButtonUtility = (data) => {
if (typeof data[0] == 'object') {
// Hmm, nested
for (const item of data) {
addButtonUtility(item);
}
return;
}
const [text, func] = data;
$("<button>")
.attr('aria-label', text)
.attr('title', text)
.text(text)
.on('click', func)
.appendTo($actionlist);
}
for (const func of window.NotabilitySearch.buttonUtilitiesFunctions) {
if (typeof func === 'function') {
const result = func(addButtonUtility);
if (result && result.then) {
promises.push(result.then((data) => addButtonUtility(data)));
} else if (result) {
addButtonUtility(result);
}
} else {
addButtonUtility(func);
}
}
return Promise.all(promises);
}
window.NotabilitySearch.createNotabilitySearchBox = function () {
if ($('#notability-searchbox').length) return;
const titles = new Set();
const categories = new Set();
const hiddencats = new Set();
const searchUtilities = new Set();
const $actionlist = $('<div class="notability-searchbox-twaction-list">');
Promise.all([
getTitles(titles),
getCategories(categories, hiddencats),
getButtonUtilities($actionlist),
]).then(() => {
return getSearchUtilities(searchUtilities, titles, categories, hiddencats);
}).then(() => {
const $searchbox = $('<div id="notability-searchbox" class="notability-searchbox skin-invert">');
$('<button class="notability-searchbox-close">')
.attr('aria-label', mw.message('notability-searchbox-close').text())
.attr('title', mw.message('notability-searchbox-close').text())
.html('×')
.on('click', () => {
$searchbox.remove();
})
.appendTo($searchbox);
$('<div class="notability-searchbox-title">')
.text(mw.message('notability-searchbox-title').text())
.appendTo($searchbox);
const $section_titles = $('<div class="notability-searchbox-section" id="notability-searchbox-section-titles">')
.appendTo($searchbox);
$('<div class="notability-searchbox-section-title">')
.text(mw.message('notability-searchbox-section-titles-title').text())
.appendTo($section_titles);
const $section_titles_content = $('<ul class="notability-searchbox-section-content">')
.appendTo($section_titles);
for (const title of titles) {
$('<li>')
.html($('<bdi>').html($('<a>')
.attr('href', 'javascript:addNotabilityQuery("' + title + '")')
.text(title)))
.appendTo($section_titles_content);
}
const $section_categories = $('<div class="notability-searchbox-section" id="notability-searchbox-section-categories">')
.appendTo($searchbox);
$('<div class="notability-searchbox-section-title">')
.text(mw.message('notability-searchbox-section-categories-title').text())
.appendTo($section_categories);
const $section_categories_content = $('<ul class="notability-searchbox-section-content">')
.appendTo($section_categories);
for (category of categories) {
$('<li>')
.html($('<bdi>').html($('<a>')
.attr('href', 'javascript:addNotabilityQuery("' + category + '")')
.text(category)))
.appendTo($section_categories_content);
}
const $section_hiddencats = $('<div class="notability-searchbox-section" id="notability-searchbox-section-hiddencats">')
.appendTo($searchbox);
$('<div class="notability-searchbox-section-title">')
.text(mw.message('notability-searchbox-section-hiddencats-title').text())
.appendTo($section_hiddencats);
const $section_hiddencats_content = $('<ul class="notability-searchbox-section-content">')
.appendTo($section_hiddencats);
for (hiddencat of hiddencats) {
$('<li>')
.html($('<bdi>').html($('<a>')
.attr('href', 'javascript:addNotabilityQuery("' + hiddencat + '")')
.text(hiddencat)))
.appendTo($section_hiddencats_content);
}
const $section_utilities = $('<div class="notability-searchbox-section" id="notability-searchbox-section-utilities">')
.appendTo($searchbox);
$('<div class="notability-searchbox-section-title">')
.text(mw.message('notability-searchbox-section-utilities-title').text())
.appendTo($section_utilities);
const $section_utilities_content = $('<ul class="notability-searchbox-section-content">')
.appendTo($section_utilities);
for (utility of searchUtilities) {
$('<li>')
.html($('<bdi>').html($('<a>')
.attr('href', 'javascript:addNotabilityQuery("' + utility + '")')
.text(utility)))
.appendTo($section_utilities_content);
}
const $searchform = $('<form class="notability-searchbox-form">')
.attr('action', 'https://www.google.com/search')
.attr('autocomplete', 'off')
.attr('method', 'get')
.attr('role', 'search')
.attr('target', '_blank')
.appendTo($searchbox);
$('<input type="text" class="notability-searchbox-input">')
.attr('name', 'q')
.attr('placeholder', mw.message('notability-searchbox-input-placeholder').text())
.val('-wikipedia ')
.appendTo($searchform);
$('<input type="submit" class="notability-searchbox-submit">')
.attr('aria-label', mw.message('notability-searchbox-submit').text())
.attr('title', mw.message('notability-searchbox-submit').text())
.val(mw.message('notability-searchbox-submit').text())
.appendTo($searchform);
$actionlist.appendTo($searchbox);
$('<div style="clear:both">')
.appendTo($searchform);
$searchbox.insertBefore('#mw-content-text');
$('#notability-searchbox .notability-searchbox-form input[name="q"]').focus();
});
}
window.addNotabilityQuery = function (query) {
const $input = $('#notability-searchbox .notability-searchbox-form input[name="q"]');
const currentValue = $input.val() ?? '';
$input.val(currentValue + query + ' ');
$input.focus();
};
mw.loader.load('//zh.wikipedia.org/w/index.php?title=User:1F616EMO/NotabilitySearchRedo/core.css&action=raw&ctype=text/css', 'text/css');
// Add portlet link
$(mw.util.addPortletLink(
$("#p-cactions").length ? 'p-cactions' : 'p-tb', '#',
mw.message('notability-searchbox-portlet-text').text(), 'notability-searchbox-portlet',
mw.message('notability-searchbox-portlet-description').text(), '1'))
.click((e) => {
e.preventDefault();
window.NotabilitySearch.createNotabilitySearchBox();
});
// Add into notability template
$(".box-Notability .mbox-text-span").append($('<a class="notability-searchbox-button hide-when-compact">')
.text(mw.message('notability-searchbox-button').text())
.attr('title', mw.message('notability-searchbox-button').text())
.attr('aria-label', mw.message('notability-searchbox-button').text())
.click((e) => {
e.preventDefault();
$(".overlay-issues button.cancel").click();
window.NotabilitySearch.createNotabilitySearchBox();
})
);
// zhwiki custom
window.NotabilitySearch.buttonUtilitiesFunctions.push(() => {
const utilities = [];
if (window.Twinkle) {
utilities.push([
mw.message('notability-searchbox-twaction-notability').text(),
(e) => {
e.preventDefault();
$("#friendly-tag a").first().click(); // Tag window
$(`.morebits-dialog-content input[value="Notability"]:not(:checked)`).click();
},
]);
utilities.push([
mw.message('notability-searchbox-twaction-notability-unreferenced').text(),
(e) => {
e.preventDefault();
$("#friendly-tag a").first().click(); // Tag window
$(`.morebits-dialog-content input[value="Notability Unreferenced"]:not(:checked)`).click();
},
]);
utilities.push([
mw.message('notability-searchbox-twaction-notability-xfd').text(),
(e) => {
e.preventDefault();
$("#tw-xfd a").first().click(); // XFD window
const $xfdcat = $('.morebits-dialog-content select[name="xfdcat"]')
.val('fame');
Twinkle.xfd.callback.change_afd_category({
target: $xfdcat[0],
});
},
]);
}
if (($m2dButton = $("#ca-m2d")).length) {
// Move to draft
utilities.push([
$m2dButton.find("a span").text(),
(e) => {
e.preventDefault();
$m2dButton.click();
}
]);
}
return utilities;
});
});