「利用者:Dragoniez/scripts/AN Reporter.js」の版間の差分

削除された内容 追加された内容
v7.3: 潜在的な、テンプレートの表示バグに繋がりうるコーディングを修正 (関連: 特別:差分/90126179)
v7.4: 報告先改名の下準備、多少立ち上げと報告処理を高速化、LTA名称リンクのコピー機能を追加、ブラウザ互換性向上に向けて多少改変
2行目:
* AN Reporter (ANR) *
* Author: Dragoniez *
* Version: 7.34 *
************************************/
//<nowiki>
78行目:
 
// Debugging Mode
constvar debugModeDebugMode = {
'scriptAd': false, // 'AN Reporter Experimental' if true
'editSummary': false, // 'Test edit via mediawiki API' + scriptAd if true
'editTarget': false, // 'User:Dragoniez/test' if true
'portletLink': false,
87 ⟶ 86行目:
'drPreviewSections': 'tarSectionsS' // I, S, 3RR, SubpagedLTA
};
 
const scriptAd = ' ([[User:Dragoniez/scripts/AN Reporter|' + (debugMode.scriptAd ? 'AN Reporter Experimental]])' : 'AN Reporter]])');
var ScriptAd = ' ([[User:Dragoniez/scripts/AN Reporter|' + (DebugMode.scriptAd ? 'AN Reporter Experimental]])' : 'AN Reporter]])'),
const portletLinkText = debugMode.portletLink ? '報告β' : '報告';
PortletLinkText = DebugMode.portletLink ? '報告β' : '報告',
const developerLink = `<a href="${mw.util.getUrl('User talk:Dragoniez/scripts/AN Reporter')}" target="_blank">開発者</a>`;
DeveloperLink = '<a href="' + mw.util.getUrl('User talk:Dragoniez/scripts/AN Reporter') + '" target="_blank">開発者</a>',
const library = debugMode.library ?
Library = DebugMode.library ?
'http://127.0.0.1:5500/dragoLib/dragoLib.js' :
'//ja.wikipedia.org/w/index.php?title=User:Dragoniez/scripts/dragoLib.js&action=raw&ctype=text/javascript';
 
// Page names
const// var ANI = 'Wikipedia:管理者伝言板/投稿ブロック';,
const// ANS = 'Wikipedia:管理者伝言板/投稿ブロック/ソックパペット';,
const// AN3RR = 'Wikipedia:管理者伝言板/3RR';,
// Iccic = ANS + '/Iccic',
const VIP = 'Wikipedia:進行中の荒らし行為';
// ISECHIKA = ANS + '/いせちか',
const Iccic = 'Wikipedia:進行中の荒らし行為/長期/Iccic/投稿ブロック依頼'; //SockInfo
// KAGE = ANS + '/影武者',
const ISECHIKA = 'Wikipedia:管理者伝言板/投稿ブロック/いせちか';
// KIYOSHIMA = ANS + '/清島達郎',
const KAGE = 'Wikipedia:管理者伝言板/投稿ブロック/影武者';
// SHINJU = ANS + '/真珠王子',
const KIYOSHIMA = 'Wikipedia:管理者伝言板/投稿ブロック/清島達郎';
const// SHINJU VIP = 'Wikipedia:管理者伝言板/投稿ブロック/真珠王子進行中の荒らし行為';,
const// TEST = '利用者:Dragoniez/test';
var ANI = 'Wikipedia:管理者伝言板/投稿ブロック',
ANS = 'Wikipedia:管理者伝言板/投稿ブロック/ソックパペット',
AN3RR = 'Wikipedia:管理者伝言板/3RR',
Iccic = 'Wikipedia:進行中の荒らし行為/長期/Iccic/投稿ブロック依頼',
ISECHIKA = 'Wikipedia:管理者伝言板/投稿ブロック/いせちか',
KAGE = 'Wikipedia:管理者伝言板/投稿ブロック/影武者',
KIYOSHIMA = 'Wikipedia:管理者伝言板/投稿ブロック/清島達郎',
SHINJU = 'Wikipedia:管理者伝言板/投稿ブロック/真珠王子',
VIP = 'Wikipedia:進行中の荒らし行為',
TEST = '利用者:Dragoniez/test';
 
/**
* Object to store logids for usernames {user1: logid, user2: logid...}
*/
constvar Logids = {};
 
// Related to dialog creation
var userDiv;, // What to append when the 'add' button is hit
var userCnt = 1; // *ID number of the elements in the appended userDiv
constvar mainDialogButtonsMainDialogButtons = [{ // Buttons
'text': '報告',
'click': report
}, {
'text': 'プレビュー',
'click': preview
}, {
'text': '閉じる',
'click': function() {
$(this).dialog('close');
}
132 ⟶ 142行目:
$.when(
$.getScript('https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js'),
$.getScript(libraryLibrary),
mw.loader.using('jquery.ui'),
$.ready
140 ⟶ 150行目:
$('head').append('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css">'); // For Select2
$('head').append(
`'<style>' +
'.select2-selection__rendered {' +
'padding: 1px 2px;' +
'font-size: 1em;' +
'line-height: normal !important;' +
'}' +
'.select2-results__option,' +
'.select2-results__group {' +
'padding: 1px 8px;' +
'font-size: ${' + anrConfig.dropdownFontSize} + ';' +
'margin: 0;' +
'}' +
'.select2-container,' +
'.select2-selection--single {' +
'height: auto !important;' +
'}' +
'.anr-dialog-label {' +
'display: inline-block;' +
'width: 8ch;' +
'}' +
'.anr-dialog-select,' +
'.anr-dialog-input {' +
'border: 1px solid #d3d3d3;' +
'border-radius: 1%;' +
'background-color: white;' +
'padding: 2px 4px;' +
'}' +
'.anr-dialog-button {' +
'color: black;' +
'font-weight: normal;' +
'border: 1px solid #d3d3d3;' +
'background-color: white;' +
'padding: 0.2em 0.5em;' +
'border-radius: 10%;' +
'}' +
'.anr-dialog-textarea {' +
'width: 100%;' +
'box-sizing: border-box;' +
'}' +
'.anr-dialog-needmargin {' +
'margin: 1em0.3em 0;' +
'}' +
'#anr-modal-dialog input {' +
</style>`
'margin-right: 0.3em;' +
'}' +
'</style>'
);
 
185 ⟶ 201行目:
if (dragoLib.inGroup('autoconfirmed') && mw.config.get('wgAction') !== 'edit') {
// Add a portletlink for ANR
$(mw.util.addPortletLink(anrConfig.portletlinkPosition, '#', portletLinkTextPortletLinkText, 'ca-anr', '管理者伝言板に利用者を報告', null, '#ca-move')).click(openAnrDialog);
}
 
196 ⟶ 212行目:
 
// The whole html contour
constvar modalHtmlModalHtml =
`'<div id="anr-modal-dialog" title="AN Reporter" style="max-height: 80vh;">`' +
` '<div id="anr-modal-header">`' +
` '<h2>利用者を報告</h2>`' +
` '</div>`' +
` '<div id="anr-modal-body">`' +
` '<form>`' +
` '<div id="anr-target-div" class="anr-dialog-needmargin">`' +
` '<label for="anr-target-options" id="anr-target-options-label" class="anr-dialog-label">報告先</label>`' +
` '<select id="anr-target-options" class="anr-dialog-select">`' +
` '<option selected disabled hidden>選択してください</option>`' +
` '<option>${' + ANI} + '</option>`' +
` '<option>${' + ANS} + '</option>`' +
` '<option>${' + AN3RR} + '</option>`' +
` '</select>`' +
` '<div id="anr-target-pagelink-div" style="display: none;">`' +
` '<label class="anr-emptylabel anr-dialog-label" for="anr-target-pagelink"></label>`' +
` '<a id="anr-target-pagelink" href="" target="_blank">報告先を確認</a>`' +
` '</div>`' +
` '</div>`' +
` '<div id="anr-section-i-div" class="anr-dialog-needmargin" style="display: none;">`' +
` '<label for="anr-section-i-select" class="anr-dialog-label">節</label>`' +
` '<select id="anr-section-i-select" class="anr-dialog-select">`' +
` '<option selected disabled hidden class="anr-section-options-initial">選択してください</option>`' +
` '<option id="anr-section-i-options-date"></option>`' +
` '<option>不適切な利用者名</option>`' +
` '<option>公開アカウント</option>`' +
` '<option>公開プロキシ・ゾンビマシン・ボット・不特定多数</option>`' +
` '<option>犯罪行為またはその疑いのある投稿</option>`' +
` '</select>`' +
` '</div>`' +
` '<div id="anr-section-s-div" class="anr-dialog-needmargin" style="display: none;">`' +
` '<label for="anr-section-s-select" class="anr-dialog-label">節</label>`' +
` '<select id="anr-section-s-select" class="anr-dialog-select">`' +
` '<option selected disabled hidden class="anr-section-options-initial">選択してください</option>`' +
` '<optgroup label="系列が立てられていないもの">`' +
` '<option>著作権侵害・犯罪予告</option>`' +
` '<option>名誉毀損・なりすまし・個人情報</option>`' +
` '<option>妨害編集・いたずら</option>`' +
` '<option>その他</option>`' +
` '</optgroup>`' +
` '<optgroup id="anr-section-s-lta" label="LTA">`' +
// // getSectionsSgetSectionTitles()
` '</optgroup>`' +
` '</select>`' +
` '</div>`' +
` '<div id="anr-user-div" class="anr-dialog-needmargin">`' +
` '<div id="anr-user1-div">`' +
` '<div id="anr-user1-input-div">`' +
` '<label for="anr-user1-input" class="anr-dialog-label">利用者</label>`' +
` '<input id="anr-user1-input" class="anr-dialog-input" style="width: 34ch;">`' +
` '<select disabled id="anr-user1-select" class="anr-dialog-select">`' +
` '<option class="anr-opt-UNL">UNL</option>`' +
` '<option class="anr-opt-User2">User2</option>`' +
` '<option class="anr-opt-IP2">IP2</option>`' +
` '<option class="anr-opt-logid">logid</option>`' +
` '<option class="anr-opt-diff">diff</option>`' +
` '<option selected class="anr-opt-none">none</option>`' +
` '</select>`' +
` '</div>`' +
` '<div id="anr-user1-checkbox-div" style="display: none;">`' +
` '<label class="anr-emptylabel anr-dialog-label"></label>`' +
` '<input type="checkbox" id="anr-user1-checkbox">`' +
` '<label for="anr-user1-checkbox">利用者名を隠す</label>`' +
` '</div>`' +
` '<div id="anr-user1-idlink-div" style="display: none;">`' +
` '<label for="anr-user1-idlink" class="anr-dialog-label"></label>`' +
` '<a id="anr-user1-idlink" href="" target="_blank"></a>`' +
` '</div>`' +
` '<div id="anr-user1-blockstatus-div" style="display: none;">`' +
` '<label for="anr-user1-blockstatus" class="anr-dialog-label"></label>`' +
` '<a id="anr-user1-blockstatus" href="" target="_blank" style="color: MediumVioletRed;">ブロックあり</a>`' +
` '</div>`' +
` '</div>`' +
` '<div id="anr-btn-div">`' +
` '<button type="button" id="anr-addBtn" class="anr-dialog-button">追加</button>`' +
` '</div>`' +
` '</div>`' +
' '<div id="anr-viplist-div" class="anr-dialog-needmargin" style="width: 100%; display: none;">' +
` '<label for="anr-viplist-select" class="anr-dialog-label">VIP</label>`' +
` '<select id="anr-viplist-select">`' +
' '<optgroup style="display: none;">' + // Adjust font size
' '<option selected disabled hidden>コピーする場合は選択してください</option>' +
// // getVipListgetSectionTitles()
' '</optgroup>' +
' '</select>' +
' '</div>' +
` '<div id="anr-predefinedreasonsltalist-div" class="anr-dialog-needmargin" style="width: 100%; display: none;">`' +
` '<label for="anr-predefinedreasonsltalist-select" class="anr-dialog-label">定型文LTA</label>`' +
` '<select id="anr-predefinedreasonsltalist-select">`' +
' '<optgroup style="display: none;">' + // Adjust font size
` '<option selected disabled hidden>定型文を使用コピーする場合は選択してください</option>`' +
' < /optgroup>'/ +getSectionTitles()
` '</selectoptgroup>`' +
` '</divselect>`' +
` '</div id="anr-reason-div" class="anr-dialog-needmargin">`' +
` '<labeldiv forid="anr-reasonpredefinedreasons-textdiv" class="anr-dialog-labelneedmargin" style="display: none;">理由</label>`' +
` '<textarealabel idfor="anr-reasonpredefinedreasons-textselect" class="anr-dialog-textarea" rows="6label">定型文</textarealabel>`' +
` '</divselect id="anr-predefinedreasons-select">`' +
` '<divoptgroup idstyle="anr-summary-div"display: class="anr-dialog-needmarginnone;">`' + // Adjust font size
'<option selected>定型文を使用する場合は選択してください</option>' +
` <input id="anr-summary-checkbox" type="checkbox">` +
` <label for="anr-summary-checkbox">要約にコメントを追加 '</labeloptgroup>`' +
'</select>' +
` <textarea id="anr-summary-text" class="anr-dialog-textarea" rows="3" style="display: none;"></textarea>` +
` '</div>`' +
` '<div id="anr-checkboxreason-div" class="anr-dialog-needmargin">`' +
` '<inputlabel checked idfor="anr-blockstatusreason-checkboxtext" typeclass="checkboxanr-dialog-label">`理由</label>' +
` '<labeltextarea forid="anr-blockstatusreason-checkboxtext" class="anr-dialog-textarea" rows="6">報告前にブロック状態をチェック</labeltextarea>`' +
` '<br/div>`' +
` '<input checkeddiv id="anr-duplicatereportsummary-checkboxdiv" typeclass="checkboxanr-dialog-needmargin">`' +
` '<labelinput forid="anr-duplicatereportsummary-checkbox" type="checkbox">報告前に重複報告をチェック</label>`' +
` '<label for="anr-summary-checkbox">要約にコメントを追加<br/label>`' +
` '<input checkedtextarea id="anr-watchlistsummary-checkboxtext" typeclass="checkboxanr-dialog-textarea" rows="3" style="display: none;"></textarea>`' +
'</div>' +
` <label for="anr-watchlist-checkbox">報告対象者をウォッチリストに追加</label>` +
` '</div id="anr-checkbox-div" class="anr-dialog-needmargin">`' +
'<input checked id="anr-blockstatus-checkbox" type="checkbox">' +
` </form>` +
'<label for="anr-blockstatus-checkbox">報告前にブロック状態をチェック</label>' +
` </div>` +
'<br>' +
`</div>`;
'<input checked id="anr-duplicatereport-checkbox" type="checkbox">' +
'<label for="anr-duplicatereport-checkbox">報告前に重複報告をチェック</label>' +
'<br>' +
'<input checked id="anr-watchlist-checkbox" type="checkbox">' +
'<label for="anr-watchlist-checkbox">報告対象者をウォッチリストに追加</label>' +
'</div>' +
'</form>' +
'</div>' +
'</div>';
 
// Add the frame div to the page
$('body').append(modalHtmlModalHtml);
 
// Show dialog
324 ⟶ 349行目:
'modal': true,
'open': initializeAnrDialog,
'buttons': mainDialogButtonsMainDialogButtons
});
 
335 ⟶ 360行目:
userCnt = 1;
 
getSectionsS(); // Get sections on WP:AN/S
dragoLib.dialogCSS(anrConfig.headerColor, anrConfig.backgroundColor, anrConfig.fontSize); // Initialize the design of the dialog
getSectionTitles();
getVipList(); // Show VIP list
getLtaList();
getPredefinedReasons(); // Show the select box for predefined reasons
 
// Add to wathchlist?
if (anrConfig.addToWatchlist === false) {$('#anr-watchlist-checkbox').prop('checked', false);
$('#anr-watchlist-checkbox').prop('checked', false);
};
 
// Get the name of the user to report if it can be retrieved from the page
350 ⟶ 373行目:
// Workaround to pick up IP ranges
if (!username && mw.config.get('wgCanonicalSpecialPageName') === 'Contributions') {
constvar relUsername = $('#firstHeading').text().replace('の投稿記録', '');
if (mw.util.isIPAddress(relUsername, true)) username = relUsername;
}
358 ⟶ 381行目:
 
// Initialize the username input and type dropdown
constvar inputID = '#anr-user1-input',
selectID = '#anr-user1-select',
checkboxDivID = '#anr-user1-checkbox-div';
 
$(inputID).val(username); // Fill the input with the username
384 ⟶ 409行目:
$(checkboxDivID).css('display', 'block'); // show 'hide username' checkbox
toggleBlockStatusLink(inputID, false, false);
 
}
 
}
 
/**
// Function to get sections on WP:AN/S from the API
* Get the section titles of WP:AN/S and WP:VIP, sort them out, and show then on the dialog as dropdown options
async function getSectionsS() {
* @returns {jQuery.Promise}
const $label = $('#anr-target-options-label'); // Label of '報告先'
*/
function getSectionTitles() {
 
var def = new $.Deferred();
 
var $label = $('#anr-target-options-label'); // Label of '報告先'
$label.append(dragoLib.toggleLoadingSpinner('add')); // Show a loading spinner while trying to get sections on WP:AN/S
 
// Get the latest revisions of the two pages including their contents
const parsed = await dragoLib.parsePage(ANS);
dragoLib.getLatestRevision([ANS, VIP]).then(function(lr) {
if (parsed) {
 
//if Get(!lr VIP's|| nameslr.length === 0) {
dragoLib.toggleLoadingSpinner('remove');
const sectionInfo = parsed.sections;
return alert('WP:AN/Sのセクション情報の取得に失敗しました。ダイアログを開き直すと改善する場合があります。');
const excludeList = [
}
'系列が立てられていないもの',
 
'著作権侵害・犯罪予告',
// Create an object
'名誉毀損・なりすまし・個人情報',
var pages = '妨害編集・いたずら',{
'その他',ANS: {
'A. 最優先' content: undefined,
'暫定A' sections: undefined,
'休止中A', exclude: [
'B. 優先度高 '系列が立てられていないもの',
'暫定B著作権侵害・犯罪予告',
'休止中B名誉毀損・なりすまし・個人情報',
'C. 優先度中 '妨害編集・いたずら',
'暫定Cその他',
'休止中CA. 最優先',
'D. 優先度低 '暫定A',
'暫定D休止中A',
'休止中DB. 優先度高',
'N. 未分類 '暫定B',
'サブページなし休止中B',
'休止C. 優先度N',
]; '暫定C',
const sectionList = []; '休止中C',
for (let i = 0; i < sectionInfo.length; i++) { 'D. 優先度低',
'暫定D',
if ($.inArray(sectionInfo[i].line, excludeList) === -1 && sectionInfo[i].index.indexOf('T') === -1) {
sectionList.push(`<option>${sectionInfo[i].line}</option>`); '休止中D',
'N. 未分類',
'サブページなし',
'休止中N'
]
},
VIP: {
content: undefined,
sections: undefined,
exclude: [
'記述について',
'急を要する二段階',
'配列',
'ブロック等の手段',
'このページに利用者名を加える',
'注意と選択',
'警告の方法',
'未登録(匿名・IP)ユーザーの場合',
'登録済み(ログイン)ユーザーの場合',
'警告中',
'関連項目'
]
}
};
 
// Get the content of each page from the resnpose of the API request
lr.forEach(function(obj) {
if (obj.title === ANS) pages.ANS.content = obj.content;
if (obj.title === VIP) pages.VIP.content = obj.content;
});
 
// Get setion titles of WP:AN/S and add them to the dropdown
if (pages.ANS.content) pages.ANS.sections = dragoLib.parseContentBySection(pages.ANS.content);
var sectionTitles;
if (pages.ANS.sections && pages.ANS.sections.length !== 0) {
sectionTitles = pages.ANS.sections.filter(function(obj) {
return obj.title && $.inArray(obj.title, pages.ANS.exclude) === -1;
}).map(function(obj) {
return '<option>' + obj.title + '</option>';
});
if (sectionTitles.length !== 0) $('#anr-section-s-lta').append(sectionTitles.join(''));
dragoLib.toggleLoadingSpinner('remove');
}
 
// Get setion titles of WP:VIP and add them to the dropdown
$('#anr-section-s-lta').append(sectionList.join(''));
if (pages.VIP.content) pages.VIP.sections = dragoLib.parseContentBySection(pages.VIP.content);
var sectionTitles;
if (pages.VIP.sections && pages.VIP.sections.length !== 0) {
sectionTitles = pages.VIP.sections.filter(function(obj) {
return obj.title && $.inArray(obj.title, pages.VIP.exclude) === -1 && obj.level === 3;
}).map(function(obj) {
return '<option>' + obj.title + '</option>';
});
if (sectionTitles.length !== 0) {
$('#anr-viplist-select')
.css('width', $('#anr-target-options').innerWidth())
.select2()
.children('optgroup').append(sectionTitles.join(''));
$('#anr-viplist-div').css('display', 'block');
dragoLib.centerDialog('#anr-modal-dialog');
}
}
});
 
return def.promise();
} else {
alert('WP:AN/Sのセクションリストを取得できませんでした。ダイアログを開き直すと改善する場合があります。');
}
dragoLib.toggleLoadingSpinner('remove');
 
}
 
/**
// WP:VIP list (for copy to clipboard)
* Get a list of LTA names
async function getVipList() {
* @returns {jQuery.Promise}
*/
function getLtaList() {
 
constvar parseddef = awaitnew dragoLib$.parsePageDeferred(VIP);
if (parsed) {
 
// Prepare an independent function as a workaround for when more than 500 names match
// Get VIP's names
var ltalist = [];
const sectionInfo = parsed.sections;
var query = function(apcontinue) {
const excludeList = [
'記述について',
var deferred = new '急を要する二段階',$.Deferred();
 
'配列',
new 'ブロック等の手段',mw.Api().get({
action: 'このページに利用者名を加えるquery',
list: '注意と選択allpages',
apprefix: '警告の方法LTA:',
apnamespace: '0',
'未登録(匿名・IP)ユーザーの場合',
apfilterredir: 'redirects',
'登録済み(ログイン)ユーザーの場合',
aplimit: '警告中max',
'関連項目'apcontinue: apcontinue,
]; formatversion: '2'
const}).then(function(res) vipList = [];{
 
for (let i = 0; i < sectionInfo.length; i++) {
var resPages;
if ($.inArray(sectionInfo[i].line, excludeList) === -1 && sectionInfo[i].level == 3) {
if (!res || !res.query || !(resPages = res.query.allpages)) return deferred.resolve();
vipList.push(`<option>${sectionInfo[i].line}</option>`);
 
resPages.forEach(function(obj) {
if (obj.title !== 'LTA:' && obj.title.match(/^LTA:/) && obj.title.indexOf('/') === -1) ltalist.push(obj.title.replace(/^LTA:/, ''));
});
 
if (res.continue) {
query(res.continue.apcontinue).then(function() {
deferred.resolve();
});
} else {
deferred.resolve();
}
}
 
if }).catch(vipList.length ===function(code, 0err) {
return mwdeferred.logresolve(console.error('VIP list: There\'s no VIP to fetcherr.error.'info));
} else {);
$('#anr-viplist-select')
.css('width', $('#anr-target-options').innerWidth())
.select2()
.children('optgroup').append(vipList.join(''));
$('#anr-viplist-div').css('display', 'block');
dragoLib.centerDialog('#anr-modal-dialog');
}
 
return deferred.promise();
} else {
 
return mw.log.error('VIP list: The API returned an unresolvable object.');
};
 
query().then(function() {
 
if (ltalist.length === 0) return def.resolve();
 
ltalist = ltalist.map(function(lta) {
return '<option>' + lta + '</option>';
}).sort();
$('#anr-ltalist-select')
.css('width', $('#anr-target-options').innerWidth())
.select2()
.children('optgroup').append(ltalist.join(''));
$('#anr-ltalist-div').css('display', 'block');
dragoLib.centerDialog('#anr-modal-dialog');
def.resolve();
 
});
 
return def.promise();
 
}
483 ⟶ 596行目:
// Function to show the select div for predefined report reasons if they're predefined
function getPredefinedReasons() {
constvar pdReasons = anrConfig.predefinedReasons;
if (typeof pdReasons !== 'undefined' && !$.isEmptyObject(pdReasons)) { // If the user has fixed reasons prepared
 
constvar $reasons = $('#anr-predefinedreasons-select');
$reasons.css('width', $('#anr-target-options').innerWidth()).select2();
for (letvar key in pdReasons) {
$reasons.children('optgroup').append(`'<option>${' + pdReasons[key]} + '</option>`');
}
$('#anr-predefinedreasons-div').css('display', 'block');
589 ⟶ 702行目:
// Check if necessary fields are filled
if (pageToEdit === '選択してください' || sectionToEdit === '選択してください' || reason === '' || users.length === 0) {
return alert('必須項目が入力・選択されていません');
return;
}
 
602 ⟶ 714行目:
 
// If the reason doesn't contain a signature, add one
if (reason.substring(reason.length - 4) !== '~~~~') {reason += '--~~~~';
reason += '--~~~~';
}
 
// Get edit summary
632 ⟶ 742行目:
const customSummary = dragoLib.trim2($('#anr-summary-text').val()),
editSummarySection = '/*' + sectionToEdit + '*/';
const editSummary = editSummarySection + '+' + summaryLinks + (customSummary ? ' - ' + customSummary : '') + scriptAdScriptAd;
 
// Get text to add to the page
647 ⟶ 757行目:
'users': users,
'types': types,
'pageToEdit': debugModeDebugMode.editTarget ? TEST : pageToEdit,
'sectionToEdit': sectionToEdit,
'wikiPagename': debugModeDebugMode.editTarget ? TEST + '#' + sectionToEdit : pageToEdit + '#' + sectionToEdit,
'reportToANS': reportToANS,
'editSummary': debugMode.editSummary ? 'Test edit via mediawiki API' + scriptAd : editSummary,
'reportText': reportText
};
 
}
 
782 ⟶ 893行目:
$(this).dialog({
'width': 'auto',
'buttons': mainDialogButtonsMainDialogButtons
});
}
849 ⟶ 960行目:
var msg = `<p>最新版を取得しています${dragoLib.toggleLoadingSpinner('add')}</p>`;
$('.anr-editing').append(msg);
constvar tslr = await dragoLib.getTimestampsgetLatestRevision(ep.pageToEdit);
if (!lr || lr.length === 0) return queryFailed(ep);
if (!ts) {
lr = queryFailed(ep)lr[0];
 
return;
// Parse the content by section and get the content and number of the section to which the report will be added
var sections = dragoLib.parseContentBySection(lr.content);
var sectionNum, wikitext;
if (sections && sections.length !== 0) {
sections.some(function(obj) {
if (obj.title === ep.sectionToEdit) {
sectionNum = obj.index;
wikitext = obj.content;
return true;
}
});
}
if (!sectionNum) return sectionNotFound(ep);
msg = '<p style="color: MediumSeaGreen">取得に成功しました</p>' +
`<p>セクション情報を取得しています${dragoLib.toggleLoadingSpinner('move')}</p>`;
$('.anr-editing').append(msg);
 
// GetCreate sectionreport number and contenttext
var reportText;
const parsed = await dragoLib.parsePage(ep.pageToEdit, ep.sectionToEdit);
if (parsedep.reportToANS) { // If the target is WP:AN/S
var sectionNum = parsed.sectionNumber, wikitext = parsed.wikitext[0], reportText;
 
// Add div if the target section is 'その他' but lacks div for the current date
if (!sectionNum) {
var miscHeader = `{{bgcolor|#eee|{{Visible anchor|他${dragoLib.today()}}}|div}}`;
sectionNotFound(ep);
if (ep.sectionToEdit === 'その他' && wikitext.indexOf(miscHeader) === -1) ep.reportText = '; ' + miscHeader + '\n\n' + ep.reportText;
 
// Get the report text to submit
var sockInfo = dragoLib.findTemplates(wikitext, 'sockinfo'); // Array
if (sockInfo.length === 1) { // One section on WP:AN/S should have one SockInfo
sockInfo = sockInfo[0];
var sockInfoNoClosure = dragoLib.trim2(sockInfo.substring(0, sockInfo.length - 2));
reportText = wikitext.replace(sockInfo, sockInfoNoClosure + '\n\n' + ep.reportText + '\n\n}}');
} else { // There's a problem with SockInfo
msg = // Show error and quit the procedure
dragoLib.toggleLoadingSpinner('remove') +
'<p style="color: MediumVioletRed">取得に失敗しました</p>' +
`<p>報告先セクションに{{SockInfo}}がない、または複数個あるため報告場所を特定できませんでした</p>` +
manualEdit(ep);
$('.anr-editing').append(msg);
editDone(ep, true);
return;
}
 
if (ep.reportToANS) { // If the target is WP:AN/S
 
// Add div if the target section is 'その他' but lacks div for the current date
const miscHeader = `{{bgcolor|#eee|{{Visible anchor|他${dragoLib.today()}}}|div}}`;
if (ep.sectionToEdit === 'その他' && wikitext.indexOf(miscHeader) === -1) ep.reportText = '; ' + miscHeader + '\n\n' + ep.reportText;
 
// Get the report text to submit
let sockInfo = dragoLib.findTemplates(wikitext, 'sockinfo'); // Array
if (sockInfo.length === 1) { // One section on WP:AN/S should have one SockInfo
sockInfo = sockInfo[0];
const sockInfoNoClosure = dragoLib.trim2(sockInfo.substring(0, sockInfo.length - 2));
reportText = wikitext.replace(sockInfo, sockInfoNoClosure + '\n\n' + ep.reportText + '\n\n}}');
} else { // There's a problem with SockInfo
msg = // Show error and quit the procedure
dragoLib.toggleLoadingSpinner('remove') +
'<p style="color: MediumVioletRed">取得に失敗しました</p>' +
`<p>報告先セクションに{{SockInfo}}がない、または複数個あるため報告場所を特定できませんでした</p>` +
manualEdit(ep);
$('.anr-editing').append(msg);
editDone(ep, true);
return;
}
 
} else { // If the target is WP:AN/I or WP:AN/3RR
reportText = dragoLib.trim2(wikitext) + '\n\n' + ep.reportText;
}
 
} else { // If the target is WP:AN/I or WP:AN/3RR
reportText = dragoLib.trim2(wikitext) + '\n\n' + ep.reportText;
queryFailed(ep);
return;
}
 
msg = '<p style="color: MediumSeaGreen">取得に成功しました</p>' +
`<p>報告を試みています${dragoLib.toggleLoadingSpinner('move')}</p>`;
904 ⟶ 1,012行目:
 
// Edit
const result = await new mw.Api().post({
const result = await dragoLib.editPage(ep.pageToEdit, reportText, 'text', ts.baseTS, ts.curTS, sectionNum, ep.editSummary, debugMode.causeIntentionalError ? '' : undefined);
action: 'edit',
title: ep.pageToEdit,
section: sectionNum,
text: reportText,
basetimestamp: lr.basetimestamp,
starttimestamp: lr.curtimestamp,
summary: ep.editSummary,
token: DebugMode.causeIntentionalError ? '' : mw.user.tokens.get('csrfToken'),
format: 'json'
}).then(function(res) {
if (res && res.edit) {
if (res.edit.result === 'Success') return true;
}
return false;
}).catch(function(code, err) {
return err.error.info;
});
dragoLib.toggleLoadingSpinner('remove');
switch(result) {
1,057 ⟶ 1,182行目:
break;
case TEST: // For debugging
eval(`tarSections = ${debugModeDebugMode.drPreviewSections}`);
break;
default: // Error: Target pagename not defined
1,063 ⟶ 1,188行目:
dragoLib.toggleLoadingSpinner('remove') +
'<p style="color: MediumVioletRed">致命的なエラーが発生しました</p>' +
`<p>${developerLinkDeveloperLink}に、<u>${ep.wikiPagename}</u>への報告においてこのエラーが発生したことの報告をお願いします。</p>` +
manualEdit(ep);
$('.anr-editing').append(msg);
1,192 ⟶ 1,317行目:
'<p>手動編集用:</p>' +
`<textarea disabled class="anr-dialog-textarea" rows="3">${ep.reportText}</textarea>` +
`<textarea disabled class="anr-dialog-textarea" rows="2" style="margin-top: 0.5em;">${ep.editSummary.replace(scriptAdScriptAd, '')}</textarea>`;
return meHtml;
}
1,465 ⟶ 1,590行目:
// ******************** EVENT HANDLERS ********************
 
// Copy a VIP/LTA name when the selection is changed
$(document).off('change', '#anr-viplist-select, #anr-ltalist-select').on('change', '#anr-viplist-select, #anr-ltalist-select', function() {
var id = $(this).prop('id'),
const vipSelectVal = $('#anr-viplist-select').find('option').filter(':selected').text().trim();
selectVal = $('#' + id).find('option').filter(':selected').text().trim();
dragoLib.copyToClipboard('[[WP:VIP#' + vipSelectVal + ']]');
switch (id) {
case 'anr-viplist-select':
dragoLib.copyToClipboard('[[WP:VIP#' + selectVal + ']]');
break;
case 'anr-ltalist-select':
dragoLib.copyToClipboard('[[LTA:' + selectVal + ']]');
}
});