User:Wugapodes/Capricorn.js: Difference between revisions
Appearance
Content deleted Content added
m Fix requested on WP:IANB |
no longer runs on diff views; earlier and less costly abort on non-redirects; allow collapsing of rcats; remove deprecated API call; refactor code |
||
Line 6: | Line 6: | ||
/*globals jQuery, mw, importStylesheet */ |
/*globals jQuery, mw, importStylesheet */ |
||
//////////////////////////////////////////////////////////////////////////////// |
|||
$.getJSON("https://en.wikipedia.org/w/index.php?title=User:Wugapodes/Capricorn/RedirectAliases.json&action=raw&ctype=application/json",function(aliasJSON) { |
|||
// Helper function definitions |
|||
var templateAliases = aliasJSON; |
|||
function encodeCodePoint(c) { |
|||
console.log(templateAliases); |
|||
if (c === 0x20) |
|||
$.getJSON("https://en.wikipedia.org/w/index.php?title=User:Wugapodes/Capricorn/RedirectTemplates.json&action=raw&ctype=application/json",function(templateJSON) { |
|||
return '_'; |
|||
var redirectTemplates = templateJSON; |
|||
if (c < 0x80) { |
|||
console.log(redirectTemplates); |
|||
return '.' + c.toString(16).toUpperCase(); |
|||
} else if (c < 0x800) { |
|||
mw.loader.using(['jquery.suggestions', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.action.view.redirectPage'], function () { // <nowiki> |
|||
return '.' + (0xc0 | (c >>> 6) ).toString(16).toUpperCase() + |
|||
'use strict'; |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x10000) { |
|||
if (mw.config.get('wgNamespaceNumber') < 0) |
|||
return '.' + (0xe0 | (c >>> 12) ).toString(16).toUpperCase() + |
|||
return; |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
importStylesheet('User:Wugapodes/Capricorn.css'); |
|||
} else if (c < 0x200000) { |
|||
return '.' + (0xf0 | (c >>> 18) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x4000000) { |
|||
return '.' + (0xf8 | (c >>> 24) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 18) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x80000000) { |
|||
return '.' + (0xfc | (c >>> 30) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 24) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 18) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} |
|||
} |
|||
function normaliseAnchor(anchor) { |
function normaliseAnchor(anchor) { |
||
function encodeCodePoint(c) { |
|||
if (c === 0x20) |
|||
return '_'; |
|||
if (c < 0x80) { |
|||
return '.' + c.toString(16).toUpperCase(); |
|||
} else if (c < 0x800) { |
|||
return '.' + (0xc0 | (c >>> 6) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x10000) { |
|||
return '.' + (0xe0 | (c >>> 12) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x200000) { |
|||
return '.' + (0xf0 | (c >>> 18) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x4000000) { |
|||
return '.' + (0xf8 | (c >>> 24) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 18) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} else if (c < 0x80000000) { |
|||
return '.' + (0xfc | (c >>> 30) ).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 24) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 18) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() + |
|||
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase(); |
|||
} |
|||
} |
|||
// "." is not escaped! |
// "." is not escaped! |
||
return anchor.replace(/[^0-9A-Za-z_:\.]/g, function (m) { /* [\ud800-\udbff][\udc00-\dfff]| */ |
return anchor.replace(/[^0-9A-Za-z_:\.]/g, function (m) { /* [\ud800-\udbff][\udc00-\dfff]| */ |
||
Line 158: | Line 144: | ||
}; |
}; |
||
//////////////////////////////////////////////////////////////////////////////// |
|||
var wgNamespaceIds = mw.config.get('wgNamespaceIds'); |
|||
// Callback functions |
|||
function mainCallback(aliasJSON, templateJSON) { |
|||
var api = new mw.Api(); |
|||
var templateAliases = aliasJSON; |
|||
var contentText = document.getElementById('mw-content-text'); |
|||
var redirectTemplates = templateJSON; |
|||
var firstHeading = document.getElementById('firstHeading'); |
|||
//console.log(templateAliases); |
|||
var redirMsg = contentText.getElementsByClassName('redirectMsg')[0]; |
|||
//console.log(redirectTemplates); |
|||
var uiWrapper = el('div'); |
|||
// <nowiki> |
|||
var edittoken = null; |
|||
'use strict'; |
|||
importStylesheet('User:Wugapodes/Capricorn.css'); |
|||
function MarkupBlob(markup) { |
|||
if (!markup) { |
|||
this.target = ''; |
|||
var wgNamespaceIds = mw.config.get('wgNamespaceIds'); |
|||
this.rcatt = {}; |
|||
this.tail = ''; |
|||
var contentText = document.getElementById('mw-content-text'); |
|||
} else |
|||
var firstHeading = document.getElementById('firstHeading'); |
|||
this.parse(markup); |
|||
var redirMsg = contentText.getElementsByClassName('redirectMsg')[0]; |
|||
} |
|||
var uiWrapper = el('div'); |
|||
var edittoken = null; |
|||
MarkupBlob.prototype.parse = function (markup) { |
|||
var rdrx = /^#REDIRECT:?\s*\[\[\s*([^\|{}[\]]+?)\s*]]\s*/i; |
|||
var tprx = /^\s*{{([A-Za-z ]+)((?:\|(?:[^|{}]*|{{[^|}]*}})+)*)}}\s*/i; |
|||
function MarkupBlob(markup) { |
|||
var m; |
|||
if (!markup) { |
|||
this.target = ''; |
|||
if (!(m = rdrx.exec(markup))) |
|||
this.rcatt = {}; |
|||
throw new Error('Not a redirect'); |
|||
this.tail = ''; |
|||
markup = markup.substr(m[0].length); |
|||
} else |
|||
this.target = m[1]; |
|||
this.parse(markup); |
|||
this.rcatt = {}; |
|||
out: while ((m = tprx.exec(markup))) { |
|||
var alias = normaliseTitle(m[1]); |
|||
while (templateAliases[alias]) |
|||
alias = templateAliases[alias]; // hopefully there are no loops. |
|||
if (alias === "This is a redirect") { |
|||
var params = m[2].split('|'); |
|||
for (var j = 0; j < params.length; ++j) { |
|||
if (!params[j]) |
|||
continue; |
|||
if (params[j].indexOf('=') !== -1) |
|||
break out; |
|||
alias = normaliseTitle("R " + params[j]); |
|||
while (templateAliases[alias]) |
|||
alias = templateAliases[alias]; // hopefully there are still no loops. |
|||
if (alias in redirectTemplates) |
|||
this.rcatt[alias] = true; |
|||
else |
|||
break out; |
|||
} |
|||
} else if (alias === "Redirect category shell") { |
|||
var mm, rr = /{{(.*?)}}/g; |
|||
while (mm = rr.exec(m[2])) { |
|||
alias = normaliseTitle(mm[1]); |
|||
while (templateAliases[alias]) |
|||
alias = templateAliases[alias]; |
|||
if (alias in redirectTemplates) |
|||
this.rcatt[alias] = true; |
|||
} |
|||
} else if (alias in redirectTemplates) { |
|||
if (m[2]) // TODO |
|||
break; |
|||
this.rcatt[alias] = true; |
|||
} else { |
|||
break; |
|||
} |
|||
markup = markup.substr(m[0].length); |
|||
} |
} |
||
this.tail = markup; |
|||
}; |
|||
MarkupBlob.prototype.toString = function () { |
|||
var markup = '#REDIRECT [[' + this.target + ']]\n'; |
|||
var tail = ''; |
|||
var wrapped = []; |
|||
for (var key in this.rcatt) { |
|||
if (this.rcatt[key]) |
|||
if ((wrapped.length < 6) && /^R\s+/.test(key)) |
|||
wrapped.push('{{' + key + '}}\n'); |
|||
else |
|||
tail += '{{' + key + '}}\n'; |
|||
} |
|||
if (wrapped.length) |
|||
markup += "\n{{Redirect category shell|\n" + wrapped.join("") + "}}\n"; |
|||
markup += tail + '\n'; |
|||
markup += this.tail; |
|||
return markup; |
|||
}; |
|||
function buildTagList(rcatt) { |
|||
function makeCheckBox(key) { |
|||
return el('label', [ |
|||
el('input', null, { |
|||
type: "checkbox", |
|||
checked: (key in rcatt) ? "checked" : null, |
|||
}, { |
|||
change: function (ev) { |
|||
rcatt[key] = this.checked; |
|||
} |
|||
}), |
|||
' ', |
|||
redirectTemplates[key].label |
|||
], { |
|||
"title": redirectTemplates[key].tooltip |
|||
}); |
|||
} |
|||
var list = el('dl', null, { "class": "tag-list" }); |
|||
var group = {}; |
|||
for (var key in templateGroups) { |
|||
list.appendChild(el('dt', templateGroups[key])); |
|||
list.appendChild(el('dd', group[key] = el('ul'))); |
|||
} |
|||
for (var key in redirectTemplates) { |
|||
var label = makeCheckBox(key); |
|||
group[redirectTemplates[key].group].appendChild(el('li', label)); |
|||
} |
|||
return list; |
|||
} |
|||
// |
|||
// Interface creation |
|||
// |
|||
function buildEditingUI(mblob, saveCallback) { |
|||
var statusbar; |
|||
var needsCheck = true; |
|||
var doSave; |
|||
var uiLink, uiTarget; |
|||
mblob = mblob || new MarkupBlob(); |
|||
MarkupBlob.prototype.parse = function (markup) { |
|||
// Change text of status bar |
|||
var rdrx = /^#REDIRECT:?\s*\[\[\s*([^\|{}[\]]+?)\s*]]\s*/i; |
|||
function setStatus(status) { |
|||
var tprx = /^\s*{{([A-Za-z ]+)((?:\|(?:[^|{}]*|{{[^|}]*}})+)*)}}\s*/i; |
|||
while (statusbar.firstChild) // Remove previous statuses |
|||
var m; |
|||
statusbar.removeChild(statusbar.firstChild); |
|||
if (status) { // If status is a string, add it |
|||
m = rdrx.exec(markup) |
|||
if (typeof status === 'string') |
|||
markup = markup.substr(m[0].length); |
|||
statusbar.appendChild(document.createTextNode(status)); |
|||
this.target = m[1]; |
|||
else { // Otherwise, loop through list and add statuses |
|||
for (var j = 0; j < status.length; ++j) { |
|||
this.rcatt = {}; |
|||
if (typeof status[j] === 'string') |
|||
out: while ((m = tprx.exec(markup))) { |
|||
statusbar.appendChild(document.createTextNode(status[j])); |
|||
var alias = normaliseTitle(m[1]); |
|||
while (templateAliases[alias]) |
|||
alias = templateAliases[alias]; // hopefully there are no loops. |
|||
if (alias === "This is a redirect") { |
|||
var params = m[2].split('|'); |
|||
for (var j = 0; j < params.length; ++j) { |
|||
if (!params[j]) |
|||
continue; |
|||
if (params[j].indexOf('=') !== -1) |
|||
break out; |
|||
alias = normaliseTitle("R " + params[j]); |
|||
while (templateAliases[alias]) |
|||
alias = templateAliases[alias]; // hopefully there are still no loops. |
|||
if (alias in redirectTemplates) |
|||
this.rcatt[alias] = true; |
|||
else |
else |
||
break out; |
|||
statusbar.appendChild(status[j]); |
|||
} |
} |
||
} else if (alias === "Redirect category shell") { |
|||
var mm, rr = /{{(.*?)}}/g; |
|||
while (mm = rr.exec(m[2])) { |
|||
alias = normaliseTitle(mm[1]); |
|||
while (templateAliases[alias]) |
|||
alias = templateAliases[alias]; |
|||
if (alias in redirectTemplates) |
|||
this.rcatt[alias] = true; |
|||
} |
|||
} else if (alias in redirectTemplates) { |
|||
if (m[2]) // TODO |
|||
break; |
|||
this.rcatt[alias] = true; |
|||
} else { |
|||
break; |
|||
} |
} |
||
markup = markup.substr(m[0].length); |
|||
} |
} |
||
} |
|||
this.tail = markup; |
|||
// Check if the target has changed?? |
|||
}; |
|||
// Not actually sure what this does yet 21 Oct 2019 |
|||
function inputChanged(ev) { |
|||
MarkupBlob.prototype.toString = function () { |
|||
/*jshint validthis:true */ |
|||
var markup = '#REDIRECT [[' + this.target + ']]\n'; |
|||
try { |
|||
var tail = ''; |
|||
var wrapped = []; |
|||
for (var key in this.rcatt) { |
|||
var frag = t.getFragment() ? '#' + normaliseAnchor(t.getFragment()) : ''; |
|||
if (this.rcatt[key]) |
|||
if (uiLink) uiLink.href = mw.util.getUrl(t.getPrefixedDb(), { redirect: "no" }) + frag; |
|||
if ((wrapped.length < 6) && /^R\s+/.test(key)) |
|||
setStatus(); |
|||
wrapped.push('{{' + key + '}}\n'); |
|||
} catch (e) { |
|||
else |
|||
setStatus('Invalid title.'); |
|||
tail += '{{' + key + '}}\n'; |
|||
if (uiLink) uiLink.href = 'javascript:void(0);'; |
|||
} |
} |
||
if (wrapped.length) |
|||
needsCheck = true; |
|||
markup += "\n{{Redirect category shell|\n" + wrapped.join("") + "}}\n"; |
|||
} |
|||
markup += tail + '\n'; |
|||
markup += this.tail; |
|||
return markup; |
|||
}; |
|||
function buildTagList(rcatt) { |
|||
var uiStatusLine; |
|||
function makeCheckBox(key) { |
|||
var patrolLine; |
|||
return el('label', [ |
|||
var origTarget = mblob.target |
|||
el('input', null, { |
|||
type: "checkbox", |
|||
el('div', [ |
|||
checked: (key in rcatt) ? "checked" : null, |
|||
el('ul', [ |
|||
}, { |
|||
change: function (ev) { |
|||
rcatt[key] = this.checked; |
|||
} |
|||
'class': 'redirectText', |
|||
}), |
|||
'value': mblob.target |
|||
' ', |
|||
redirectTemplates[key].label |
|||
'input': inputChanged, |
|||
'change': inputChanged, |
|||
'blur': function (ev) { // i would not have to write this, if it were not for jQuery. seriously. |
|||
if (mblob.target === this.value) |
|||
return; |
|||
inputChanged.call(this, ev); |
|||
} |
|||
}) |
|||
]) |
|||
], { 'class': 'redirectText' }) |
|||
], { 'class': 'redirectMsg' }), |
|||
buildTagList(mblob.rcatt), |
|||
uiStatusLine = el('p', [ |
|||
patrolLine = el('span', [], {}), |
|||
statusbar = el('span', [], { |
|||
'class': 'status-line' |
|||
}), |
|||
el('span', [ |
|||
link(["Statistics for this page"], 'https://tools.wmflabs.org/pageviews?project=en.wikipedia.org&pages=' + encodeURIComponent(mw.config.get('wgPageName'))), |
|||
' • ', |
|||
link(["WP:TMR"], mw.util.getUrl("Wikipedia:Template messages/Redirect pages")), |
|||
' • ', |
|||
link(["About Capricorn"], mw.util.getUrl("User:Wugapodes/Capricorn")) |
|||
], { |
], { |
||
"title": redirectTemplates[key].tooltip |
|||
'style': 'float: right;' |
|||
}) |
}); |
||
} |
|||
], { |
|||
var list = el('dl', null, { "class": "tag-list" }); |
|||
'action': 'javascript:void(0)', |
|||
var group = {}; |
|||
'class': 'kephir-sagittarius-editor' |
|||
for (var key in templateGroups) { |
|||
}, { |
|||
list.appendChild(el('dt', templateGroups[key])); |
|||
'submit': function (ev) { |
|||
list.appendChild(el('dd', group[key] = el('ul'))); |
|||
ev.preventDefault(); |
|||
} |
|||
if (uiStatusLine.childNodes[1].childNodes[0]) { |
|||
for (var key in redirectTemplates) { |
|||
var patrolVal = uiStatusLine.childNodes[1].childNodes[0].childNodes[0].checked; |
|||
var label = makeCheckBox(key); |
|||
if (patrolVal) { |
|||
group[redirectTemplates[key].group].appendChild(el('li', label)); |
|||
api.get({ |
|||
} |
|||
"action": "query", |
|||
"format": "json", |
|||
var collapsibleContent = el('div', list, { |
|||
"prop": "revisions", |
|||
"class": "mw-collapsible-content", |
|||
"id": "capricorn-toggle-content" |
|||
"titles": mw.config.get('wgPageName'), |
|||
}) |
|||
"rvprop": "ids", |
|||
return collapsibleContent; |
|||
"rvslots": "", |
|||
} |
|||
"rvlimit": "1", |
|||
"rvdir": "newer", |
|||
// |
|||
"type": "patrol" |
|||
// Interface creation |
|||
}, { |
|||
// |
|||
success: function (result) { |
|||
function buildEditingUI(mblob, saveCallback) { |
|||
//console.log(mw.config.get('wgPageName')) |
|||
var statusbar; |
|||
var patrolToken = result["query"]["tokens"]["patroltoken"]; |
|||
var needsCheck = true; |
|||
var doSave; |
|||
var uiLink, uiTarget; |
|||
for (var page in revIDpart) { |
|||
mblob = mblob || new MarkupBlob(); |
|||
revID = revIDpart[page]["revisions"][0]["revid"]; |
|||
// Change text of status bar |
|||
//console.log(revID) |
|||
function setStatus(status) { |
|||
api.post({ |
|||
while (statusbar.firstChild) // Remove previous statuses |
|||
"action": 'patrol', |
|||
statusbar.removeChild(statusbar.firstChild); |
|||
"revid": revID, |
|||
if (status) { // If status is a string, add it |
|||
"token": patrolToken |
|||
if (typeof status === 'string') |
|||
}, { |
|||
statusbar.appendChild(document.createTextNode(status)); |
|||
success: function (result) { |
|||
else { // Otherwise, loop through list and add statuses |
|||
if (result.error) { |
|||
for (var j = 0; j < status.length; ++j) { |
|||
console.log(result.error); |
|||
if (typeof status[j] === 'string') |
|||
setStatus([ |
|||
statusbar.appendChild(document.createTextNode(status[j])); |
|||
'API error: "', |
|||
else |
|||
statusbar.appendChild(status[j]); |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
} |
|||
console.log(result.error) |
|||
return; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
} |
} |
||
} |
} |
||
ui.doCheck(saveCallback); |
|||
} |
} |
||
}); |
|||
// Check if the target has changed?? |
|||
ui.statusLine = uiStatusLine; |
|||
// Not actually sure what this does yet 21 Oct 2019 |
|||
ui.patrolLine = patrolLine; |
|||
function inputChanged(ev) { |
|||
ui.origTarget = origTarget |
|||
/*jshint validthis:true */ |
|||
try { |
|||
var sectCache = {}; |
|||
mblob.target = this.value; |
|||
var $uiTarget = jQuery(uiTarget); |
|||
var t = new mw.Title(this.value); |
|||
$uiTarget.suggestions({ |
|||
var frag = t.getFragment() ? '#' + normaliseAnchor(t.getFragment()) : ''; |
|||
submitOnClick: false, |
|||
if (uiLink) uiLink.href = mw.util.getUrl(t.getPrefixedDb(), { redirect: "no" }) + frag; |
|||
delay: 500, |
|||
setStatus(); |
|||
fetch: function (query) { |
|||
} catch (e) { |
|||
$uiTarget.suggestions('suggestions', []); |
|||
setStatus('Invalid title.'); |
|||
if (query.indexOf('#') !== -1) { |
|||
if (uiLink) uiLink.href = 'javascript:void(0);'; |
|||
var title = query.substr(0, query.indexOf('#')); |
|||
} |
|||
var sect = query.substr(query.indexOf('#') + 1); |
|||
needsCheck = true; |
|||
} |
|||
if (sectCache[title]) { |
|||
var normSect = normaliseAnchor(sect); |
|||
var uiStatusLine; |
|||
$uiTarget.suggestions('suggestions', |
|||
var patrolLine; |
|||
sectCache[title].filter(function (item) { |
|||
var origTarget = mblob.target |
|||
var norm = normaliseAnchor(item.anchor); |
|||
var ui = el('form', [ |
|||
return norm.substr(0, normSect.length) === normSect; |
|||
el('div', [ |
|||
el('ul', [ |
|||
el('li', [ |
|||
uiTarget = el('input', null, { |
|||
'type': 'text', |
|||
'class': 'redirectText', |
|||
'value': mblob.target |
|||
}, { |
|||
'input': inputChanged, |
|||
'change': inputChanged, |
|||
'blur': function (ev) { // i would not have to write this, if it were not for jQuery. seriously. |
|||
if (mblob.target === this.value) |
|||
return; |
|||
inputChanged.call(this, ev); |
|||
} |
|||
}) |
}) |
||
) |
]) |
||
], { 'class': 'redirectText' }), |
|||
return; |
|||
el('input', null, { |
|||
"type": "button", |
|||
"class":"capricorn-toggle", |
|||
"id": "capricorn-toggle-button", |
|||
"value": "Hide rcat list" |
|||
}, { |
|||
'click': function() { |
|||
$( "#capricorn-toggle-content" ).toggle(); |
|||
var buttonText = $("#capricorn-toggle-button")[0].value; |
|||
if (buttonText === "Hide rcat list") { |
|||
$("#capricorn-toggle-button")[0].value = "Show rcat list" |
|||
} else { |
|||
$("#capricorn-toggle-button")[0].value = "Hide rcat list" |
|||
}; |
|||
} |
|||
}) |
|||
], { 'class': 'redirectMsg' }), |
|||
buildTagList(mblob.rcatt), |
|||
uiStatusLine = el('p', [ |
|||
patrolLine = el('span', [], {}), |
|||
statusbar = el('span', [], { |
|||
'class': 'status-line' |
|||
}), |
|||
el('span', [ |
|||
link(["Statistics for this page"], 'https://tools.wmflabs.org/pageviews?project=en.wikipedia.org&pages=' + encodeURIComponent(mw.config.get('wgPageName'))), |
|||
' • ', |
|||
link(["WP:TMR"], mw.util.getUrl("Wikipedia:Template messages/Redirect pages")), |
|||
' • ', |
|||
link(["About Capricorn"], mw.util.getUrl("User:Wugapodes/Capricorn")) |
|||
], { |
|||
'style': 'float: right;' |
|||
}) |
|||
]) |
|||
], { |
|||
'action': 'javascript:void(0)', |
|||
'class': 'kephir-sagittarius-editor' |
|||
}, { |
|||
'submit': function (ev) { |
|||
ev.preventDefault(); |
|||
if (uiStatusLine.childNodes[1].childNodes[0]) { |
|||
var patrolVal = uiStatusLine.childNodes[1].childNodes[0].childNodes[0].checked; |
|||
if (patrolVal) { |
|||
api.get({ |
|||
"action": "query", |
|||
"format": "json", |
|||
"prop": "revisions", |
|||
"meta": "tokens", |
|||
"titles": mw.config.get('wgPageName'), |
|||
"rvprop": "ids", |
|||
"rvslots": "", |
|||
"rvlimit": "1", |
|||
"rvdir": "newer", |
|||
"type": "patrol" |
|||
}, { |
|||
success: function (result) { |
|||
//console.log(mw.config.get('wgPageName')) |
|||
var patrolToken = result["query"]["tokens"]["patroltoken"]; |
|||
var revIDpart = result["query"]["pages"]; |
|||
var revID = null; |
|||
for (var page in revIDpart) { |
|||
revID = revIDpart[page]["revisions"][0]["revid"]; |
|||
} |
|||
//console.log(revID) |
|||
api.post({ |
|||
"action": 'patrol', |
|||
"revid": revID, |
|||
"token": patrolToken |
|||
}, { |
|||
success: function (result) { |
|||
if (result.error) { |
|||
console.log(result.error); |
|||
setStatus([ |
|||
'API error: "', |
|||
result.error.info, |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
]); |
|||
console.log(result.error) |
|||
return; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
} |
} |
||
ui.doCheck(saveCallback); |
|||
} |
|||
}); |
|||
ui.statusLine = uiStatusLine; |
|||
ui.patrolLine = patrolLine; |
|||
ui.origTarget = origTarget |
|||
var sectCache = {}; |
|||
var $uiTarget = jQuery(uiTarget); |
|||
$uiTarget.suggestions({ |
|||
submitOnClick: false, |
|||
delay: 500, |
|||
fetch: function (query) { |
|||
$uiTarget.suggestions('suggestions', []); |
|||
if (query.indexOf('#') !== -1) { |
|||
var title = query.substr(0, query.indexOf('#')); |
|||
var sect = query.substr(query.indexOf('#') + 1); |
|||
if (sectCache[title]) { |
|||
var normSect = normaliseAnchor(sect); |
|||
$uiTarget.suggestions('suggestions', |
|||
sectCache[title].filter(function (item) { |
|||
var norm = normaliseAnchor(item.anchor); |
|||
return norm.substr(0, normSect.length) === normSect; |
|||
}) |
|||
); |
|||
return; |
|||
} |
|||
api.get({ |
|||
action: 'parse', |
|||
page: title, |
|||
prop: 'sections|properties', |
|||
redirects: '1' |
|||
}).then(function (result) { |
|||
if (result.parse.redirects && result.parse.redirects.length) { |
|||
// XXX |
|||
return; |
|||
} |
|||
var disambig = false; // XXX |
|||
var normSect = normaliseAnchor(sect); |
|||
sectCache[title] = result.parse.sections.map(function (item) { |
|||
return { |
|||
anchor: item.anchor, |
|||
title: title + '#' + decodeURIComponent(item.anchor.replace(/_/g, ' ').replace(/\.([0-9A-Fa-f][0-9A-Fa-f])/g, '%')), // XXX: hack |
|||
disambig: disambig, |
|||
toString: function () { |
|||
return this.title; |
|||
} |
|||
}; |
|||
}); |
|||
$uiTarget.suggestions('suggestions', |
|||
sectCache[title].filter(function (item) { |
|||
var norm = normaliseAnchor(item.anchor); |
|||
return norm.substr(0, normSect.length) === normSect; |
|||
}) |
|||
); |
|||
}); |
|||
return; |
|||
} |
|||
api.get({ |
api.get({ |
||
action: ' |
action: 'query', |
||
generator: 'allpages', |
|||
gapprefix: query, |
|||
gaplimit: 16, |
|||
prop: 'info|pageprops', |
|||
}).then(function (result) { |
}).then(function (result) { |
||
var pglist = []; |
|||
if (result.parse.redirects && result.parse.redirects.length) { |
|||
for (var pgid in result.query.pages) { |
|||
// XXX |
|||
var page = result.query.pages[pgid]; |
|||
return; |
|||
pglist.push({ |
|||
title: page.title, |
|||
pageid: page.pageid, |
|||
var disambig = false; // XXX |
|||
disambig: page.pageprops && ('disambiguation' in page.pageprops), |
|||
redirect: 'redirect' in page, |
|||
var normSect = normaliseAnchor(sect); |
|||
sectCache[title] = result.parse.sections.map(function (item) { |
|||
return { |
|||
anchor: item.anchor, |
|||
title: title + '#' + decodeURIComponent(item.anchor.replace(/_/g, ' ').replace(/\.([0-9A-Fa-f][0-9A-Fa-f])/g, '%')), // XXX: hack |
|||
disambig: disambig, |
|||
toString: function () { |
toString: function () { |
||
return this.title; |
return this.title; |
||
} |
} |
||
}; |
}); |
||
} |
} |
||
$uiTarget.suggestions('suggestions', pglist); |
|||
$uiTarget.suggestions('suggestions', |
|||
sectCache[title].filter(function (item) { |
|||
var norm = normaliseAnchor(item.anchor); |
|||
return norm.substr(0, normSect.length) === normSect; |
|||
}) |
|||
); |
|||
}); |
}); |
||
return; |
|||
} |
|||
api.get({ |
|||
action: 'query', |
|||
generator: 'allpages', |
|||
gapprefix: query, |
|||
gaplimit: 16, |
|||
prop: 'info|pageprops', |
|||
}).then(function (result) { |
|||
var pglist = []; |
|||
for (var pgid in result.query.pages) { |
|||
var page = result.query.pages[pgid]; |
|||
pglist.push({ |
|||
title: page.title, |
|||
pageid: page.pageid, |
|||
disambig: page.pageprops && ('disambiguation' in page.pageprops), |
|||
redirect: 'redirect' in page, |
|||
toString: function () { |
|||
return this.title; |
|||
} |
|||
}); |
|||
} |
|||
$uiTarget.suggestions('suggestions', pglist); |
|||
}); |
|||
}, |
|||
result: { |
|||
render: function (item, content) { |
|||
var elm = this[0]; |
|||
elm.appendChild(el('span', [item.title], { |
|||
style: item.redirect ? 'font-style: italic' : '' |
|||
})); |
|||
if (item.disambig) |
|||
elm.appendChild(el('small', [' (disambiguation page)'])); |
|||
if (item.redirect) |
|||
elm.appendChild(el('small', [' (redirect)'])); |
|||
}, |
}, |
||
result: { |
|||
render: function (item, content) { |
|||
var |
var elm = this[0]; |
||
elm.appendChild(el('span', [item.title], { |
|||
var textbox = $textbox[0]; |
|||
style: item.redirect ? 'font-style: italic' : '' |
|||
})); |
|||
textbox.value = item.title; |
|||
if (item. |
if (item.disambig) |
||
elm.appendChild(el('small', [' (disambiguation page)'])); |
|||
api.get({ |
|||
if (item.redirect) |
|||
elm.appendChild(el('small', [' (redirect)'])); |
|||
pageids: item.pageid, |
|||
}, |
|||
redirects: '1' |
|||
}).then(function (result) { |
|||
select: function ($textbox) { |
|||
var redir = result.query.redirects.pop(); |
|||
var item = this.data('text'); |
|||
textbox.value = redir.to + (redir.tofragment ? '#' + redir.tofragment : ''); |
|||
var textbox = $textbox[0]; |
|||
}); |
|||
textbox.value = item.title; |
|||
if (item.redirect) { |
|||
api.get({ |
|||
action: 'query', |
|||
pageids: item.pageid, |
|||
redirects: '1' |
|||
}).then(function (result) { |
|||
var redir = result.query.redirects.pop(); |
|||
textbox.value = redir.to + (redir.tofragment ? '#' + redir.tofragment : ''); |
|||
}); |
|||
} |
|||
return true; |
|||
} |
} |
||
return true; |
|||
} |
} |
||
} |
}); |
||
ui.doCheck = function (callback) { |
|||
var that = this; |
|||
ui.doCheck = function (callback) { |
|||
var that = this; |
|||
if (!/^\s*[^\|{}[\]]+\s*$/.test(mblob.target)) { |
|||
setStatus(['Error: the target page name is invalid.']); |
|||
if (!/^\s*[^\|{}[\]]+\s*$/.test(mblob.target)) { |
|||
setStatus(['Error: the target page name is invalid.']); |
|||
return; |
|||
} |
|||
if (needsCheck) { |
|||
var oldTarget = mblob.target; |
|||
var normTarget; |
|||
try { |
|||
normTarget = new mw.Title(oldTarget); |
|||
} catch (e) { |
|||
setStatus(['"', oldTarget, '" is not a valid page name. Try again to proceed anyway.']); |
|||
return; |
return; |
||
} |
} |
||
if (needsCheck) { |
|||
setStatus(['Checking target validity...']); |
|||
var oldTarget = mblob.target; |
|||
var normTarget; |
|||
try { |
|||
normTarget = new mw.Title(oldTarget); |
|||
action: 'parse', |
|||
} catch (e) { |
|||
page: oldTarget = mblob.target, |
|||
setStatus(['"', oldTarget, '" is not a valid page name. Try again to proceed anyway.']); |
|||
prop: 'sections', |
|||
return; |
|||
} |
} |
||
success: function (result) { |
|||
setStatus(['Checking target validity...']); |
|||
var m; |
|||
needsCheck = false; |
|||
if (result.error) { |
|||
if (result.error.code === 'missingtitle') { |
|||
api.get({ |
|||
action: 'parse', |
|||
page: oldTarget = mblob.target, |
|||
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { "class": "new" })), |
|||
prop: 'sections', |
|||
'" does not exist. Try again to proceed anyway.' |
|||
redirects: '1' |
|||
}, { |
|||
success: function (result) { |
|||
setStatus([ |
|||
var m; |
|||
if (result.error) { |
|||
if (result.error.code === 'missingtitle') { |
|||
setStatus([ |
|||
'Error: The target page "', |
|||
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { "class": "new" })), |
|||
'" does not exist. Try again to proceed anyway.' |
|||
]); |
|||
} else { |
|||
setStatus([ |
|||
'API error: "', |
|||
result.error.info, |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
]); |
|||
} |
|||
return; |
|||
} |
} |
||
return; |
|||
if (result.parse.redirects && result.parse.redirects[0]) { |
|||
} |
|||
var newTarget = result.parse.redirects[0].to + (result.parse.redirects[0].tofragment ? "#" + result.parse.redirects[0].tofragment : ""); |
|||
if (result.parse.redirects && result.parse.redirects[0]) { |
|||
var newTarget = result.parse.redirects[0].to + (result.parse.redirects[0].tofragment ? "#" + result.parse.redirects[0].tofragment : ""); |
|||
setStatus([ |
|||
'Error: The target page "', |
|||
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { redirect: "no" })), |
|||
'" is already a redirect to "', |
|||
link([newTarget], mw.util.getUrl(newTarget, { redirect: "no" })), |
|||
'". Try again to proceed anyway, or ', |
|||
link(['retarget this redirect to point there directly'], function () { |
|||
uiTarget.value = mblob.target = newTarget + |
|||
((!result.parse.redirects[0].tofragment && normTarget.fragment) ? '#' + normTarget.fragment : ''); |
|||
needsCheck = true; |
|||
}), |
|||
'.' |
|||
]); |
|||
return; |
|||
} |
|||
if (normTarget.fragment) { // we have a section link |
|||
var sect = normaliseAnchor(normTarget.fragment); |
|||
var isValidSect = false; |
|||
var sectlist = result.parse.sections; |
|||
for (var j = 0; j < sectlist.length; ++j) { |
|||
if (sectlist[j].anchor === sect) |
|||
isValidSect = true; |
|||
} |
|||
if (!isValidSect) { |
|||
setStatus([ |
setStatus([ |
||
'Error: The target page "', |
'Error: The target page "', |
||
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { redirect: "no" })), |
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { redirect: "no" })), |
||
'" |
'" is already a redirect to "', |
||
link([newTarget], mw.util.getUrl(newTarget, { redirect: "no" })), |
|||
normTarget.fragment, |
|||
'". Try again to proceed anyway |
'". Try again to proceed anyway, or ', |
||
link(['retarget this redirect to point there directly'], function () { |
|||
uiTarget.value = mblob.target = newTarget + |
|||
((!result.parse.redirects[0].tofragment && normTarget.fragment) ? '#' + normTarget.fragment : ''); |
|||
needsCheck = true; |
|||
}), |
|||
'.' |
|||
]); |
]); |
||
return; |
return; |
||
} |
} |
||
if (normTarget.fragment) { // we have a section link |
|||
var sect = normaliseAnchor(normTarget.fragment); |
|||
var isValidSect = false; |
|||
var sectlist = result.parse.sections; |
|||
for (var j = 0; j < sectlist.length; ++j) { |
|||
if (sectlist[j].anchor === sect) |
|||
isValidSect = true; |
|||
} |
|||
if (!isValidSect) { |
|||
setStatus([ |
|||
'Error: The target page "', |
|||
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { redirect: "no" })), |
|||
'" does not have a a section called "', |
|||
normTarget.fragment, |
|||
'". Try again to proceed anyway.' |
|||
]); |
|||
return; |
|||
} |
|||
} |
|||
callback(setStatus); |
|||
} |
} |
||
}); |
|||
callback(setStatus); |
|||
return; |
|||
} |
|||
callback(setStatus); |
|||
}; |
|||
return ui; |
|||
} |
|||
function setSummary(current,orig) { |
|||
var summary; |
|||
if (orig === current) { |
|||
summary= "Modifying [[WP:RCAT|redirect categories]] using [[User:Wugapodes/Capricorn|Capricorn ♑]]"; |
|||
} else { |
|||
summary = 'Redirecting to [[' + current + ']] ([[User:Wugapodes/Capricorn|♑]])' |
|||
} |
|||
return summary |
|||
} |
|||
if ((mw.config.get('wgAction') === 'view') && (mw.config.get('wgArticleId') === 0)) { // nonexistent page. |
|||
uiWrapper.appendChild(el('div', [ |
|||
link(['Create a redirect'], function () { |
|||
while (uiWrapper.hasChildNodes()) |
|||
uiWrapper.removeChild(uiWrapper.firstChild); |
|||
var mblob = new MarkupBlob(); |
|||
var ui = buildEditingUI(mblob, function (setStatus) { |
|||
setStatus(['Saving...']); |
|||
var summary = setSummary(mblob.target,ui.origTarget) |
|||
api.post({ |
|||
action: 'edit', |
|||
title: mw.config.get('wgPageName'), |
|||
createonly: 1, |
|||
summary: summary, |
|||
text: mblob.toString(), |
|||
token: mw.user.tokens.get('csrfToken') |
|||
}, { |
|||
success: function (result) { |
|||
if (result.error) { |
|||
setStatus([ |
|||
'API error: "', |
|||
result.error.info, |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
]); |
|||
return; |
|||
} |
|||
setStatus(['Saved. Reloading page...']); |
|||
if (/redirect=no/.test(location.href)) // XXX |
|||
location.reload(); |
|||
else |
|||
location.search = location.search ? location.search + '&redirect=no' : '?redirect=no'; |
|||
} |
|||
}); |
|||
}); |
|||
ui.statusLine.insertBefore(el('input', null, { |
|||
type: 'submit', |
|||
value: 'Save' |
|||
}), ui.statusLine.firstChild); |
|||
uiWrapper.appendChild(ui); |
|||
}), ' from this page with Capricorn' |
|||
], { |
|||
"class": "kephir-sagittarius-invite" |
|||
})); |
|||
contentText.parentNode.insertBefore(uiWrapper, contentText); |
|||
} else if ((mw.config.get('wgAction') === 'view') && mw.config.get('wgIsRedirect') && redirMsg) { |
|||
// start editor immediately |
|||
uiWrapper.appendChild(el('div', ['Loading page source…'], { |
|||
"class": "kephir-sagittarius-loading" |
|||
})); |
|||
contentText.insertBefore(uiWrapper, contentText.firstChild); |
|||
api.get({ |
|||
action: 'query', |
|||
prop: 'revisions', |
|||
rvprop: 'timestamp|content', |
|||
pageids: mw.config.get('wgArticleId'), |
|||
rvstartid: mw.config.get('wgRevisionId'), |
|||
rvlimit: 1, |
|||
rvdir: 'older' |
|||
}, { |
|||
success: function (result) { |
|||
if (result.error) { |
|||
uiWrapper.appendChild(el('div', [ |
|||
'API error: "', |
|||
result.error.info, |
|||
'" [code: ', el('code', [result.error.code]), ']. Reload to try again.' |
|||
], { |
|||
"class": "kephir-sagittarius-error" |
|||
})); |
|||
return; |
|||
} |
} |
||
while (uiWrapper.hasChildNodes()) |
|||
}); |
|||
uiWrapper.removeChild(uiWrapper.firstChild); |
|||
var page = result.query.pages[mw.config.get('wgArticleId')]; |
|||
return; |
|||
var mblob; |
|||
} |
|||
var token = mw.user.tokens.get('csrfToken') |
|||
try { |
|||
callback(setStatus); |
|||
mblob = new MarkupBlob(page.revisions[0]['*']); |
|||
}; |
|||
} catch(e) { |
|||
uiWrapper.appendChild(el('div', ['Error: unable to parse page. Edit the source manually.'], { |
|||
return ui; |
|||
"class": "kephir-sagittarius-error" |
|||
} |
|||
})); |
|||
return; |
|||
function setSummary(current,orig) { |
|||
} |
|||
var summary; |
|||
redirMsg.parentNode.removeChild(redirMsg); |
|||
if (orig === current) { |
|||
var ui = buildEditingUI(mblob, function (setStatus) { |
|||
summary= "Modifying [[WP:RCAT|redirect categories]] using [[User:Wugapodes/Capricorn|Capricorn ♑]]"; |
|||
setStatus(['Saving...']); |
|||
} else { |
|||
var summary = setSummary(mblob.target,ui.origTarget) |
|||
summary = 'Redirecting to [[' + current + ']] ([[User:Wugapodes/Capricorn|♑]])' |
|||
api.post({ |
|||
} |
|||
action: 'edit', |
|||
return summary |
|||
title: mw.config.get('wgPageName'), |
|||
} |
|||
basetimestamp: page.revisions[0].timestamp, |
|||
summary: summary, |
|||
if ((mw.config.get('wgAction') === 'view') && (mw.config.get('wgArticleId') === 0)) { // nonexistent page. |
|||
text: mblob.toString(), |
|||
uiWrapper.appendChild(el('div', [ |
|||
token: mw.user.tokens.get('csrfToken') |
|||
link(['Create a redirect'], function () { |
|||
}, { |
|||
while (uiWrapper.hasChildNodes()) |
|||
success: function (result) { |
|||
uiWrapper.removeChild(uiWrapper.firstChild); |
|||
if (result.error) { |
|||
var mblob = new MarkupBlob(); |
|||
setStatus([ |
|||
var ui = buildEditingUI(mblob, function (setStatus) { |
|||
'API error: "', |
|||
setStatus(['Saving...']); |
|||
result.error.info, |
|||
var summary = setSummary(mblob.target,ui.origTarget) |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
api.post({ |
|||
]); |
|||
return; |
|||
title: mw.config.get('wgPageName'), |
|||
} |
|||
setStatus(['Saved. Reloading page...']); |
|||
summary: summary, |
|||
if (/redirect=no/.test(location.href)) // XXX |
|||
text: mblob.toString(), |
|||
location.reload(); |
|||
token: mw.user.tokens.get('csrfToken') |
|||
else |
|||
location.search = location.search ? location.search + '&redirect=no' : '?redirect=no'; |
|||
success: function (result) { |
|||
} |
|||
}); |
|||
}); |
|||
'API error: "', |
|||
var userName = mw.user.getName(); |
|||
result.error.info, |
|||
api.get({ |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
"action": "query", |
|||
"format": "json", |
|||
"list": "users", |
|||
"usprop": "groups", |
|||
"ususers": userName |
|||
}, { success: function(result) { |
|||
var groups = result["query"]["users"][0]["groups"] |
|||
if (groups.includes("patroller")) { |
|||
ui.patrolLine.insertBefore(el('label', [ |
|||
el('input', [], { |
|||
'class': 'checkbox', |
|||
'type': 'checkbox', |
|||
'id': 'patrol', |
|||
'value': 'patrol' |
|||
}), 'Mark as patrolled?']),null); |
|||
} |
} |
||
setStatus(['Saved. Reloading page...']); |
|||
if (/redirect=no/.test(location.href)) // XXX |
|||
location.reload(); |
|||
else |
|||
location.search = location.search ? location.search + '&redirect=no' : '?redirect=no'; |
|||
} |
} |
||
}); |
}); |
||
ui.statusLine.insertBefore(el('input', null, { |
|||
}); |
|||
ui.statusLine.insertBefore(el('input', null, { |
|||
type: 'submit', |
type: 'submit', |
||
value: 'Save' |
value: 'Save' |
||
}), ui.statusLine.firstChild); |
}), ui.statusLine.firstChild); |
||
uiWrapper.appendChild(ui); |
uiWrapper.appendChild(ui); |
||
}), ' from this page with Capricorn' |
|||
], { |
|||
"class": "kephir-sagittarius-invite" |
|||
})); |
|||
contentText.parentNode.insertBefore(uiWrapper, contentText); |
|||
} else if ((mw.config.get('wgAction') === 'view') && mw.config.get('wgIsRedirect') && redirMsg) { |
|||
// start editor immediately |
|||
uiWrapper.appendChild(el('div', ['Loading page source…'], { |
|||
"class": "kephir-sagittarius-loading" |
|||
})); |
|||
contentText.insertBefore(uiWrapper, contentText.firstChild); |
|||
api.get({ |
|||
action: 'query', |
|||
prop: 'info|revisions', |
|||
rvprop: 'timestamp|content', |
|||
pageids: mw.config.get('wgArticleId'), |
|||
rvstartid: mw.config.get('wgRevisionId'), |
|||
rvlimit: 1, |
|||
rvdir: 'older', |
|||
intoken: 'edit', |
|||
}, { |
|||
success: function (result) { |
|||
if (result.error) { |
|||
uiWrapper.appendChild(el('div', [ |
|||
'API error: "', |
|||
result.error.info, |
|||
'" [code: ', el('code', [result.error.code]), ']. Reload to try again.' |
|||
], { |
|||
"class": "kephir-sagittarius-error" |
|||
})); |
|||
return; |
|||
} |
} |
||
}); |
|||
while (uiWrapper.hasChildNodes()) |
|||
} else if ((mw.config.get('wgPageContentModel') === 'wikitext') && ((mw.config.get('wgAction') === 'edit') || (mw.config.get('wgAction') === 'submit'))) { |
|||
uiWrapper.removeChild(uiWrapper.firstChild); |
|||
if (mw.util.getParamValue('section')) |
|||
var page = result.query.pages[mw.config.get('wgArticleId')]; |
|||
return; |
|||
var editform = document.getElementById('editform'); |
|||
if (!editform || !editform.wpTextbox1 || editform.wpTextbox1.readOnly) |
|||
return; |
|||
var uiPivot = document.getElementsByClassName('wikiEditor-ui')[0]; |
|||
var ui, mblob; |
|||
firstHeading.appendChild(document.createTextNode(' ')); |
|||
firstHeading.appendChild(link(['♑'], function () { |
|||
if (ui && ui.parentNode) |
|||
ui.parentNode.removeChild(ui); |
|||
try { |
try { |
||
mblob = new MarkupBlob( |
mblob = new MarkupBlob(editform.wpTextbox1.value); |
||
} catch(e) { |
} catch (e) { |
||
alert("Error: unable to parse page. This page is probably not a redirect."); |
|||
"class": "kephir-sagittarius-error" |
|||
})); |
|||
return; |
return; |
||
} |
} |
||
redirMsg.parentNode.removeChild(redirMsg); |
|||
currentTarget = mblob.target |
|||
var ui = buildEditingUI(mblob, function (setStatus) { |
|||
setStatus(['Saving...']); |
|||
ui = buildEditingUI(mblob, function () { |
|||
editform.wpSummary.value = 'Redirecting to [[' + mblob.target + ']] ([[User:Wugapodes/Capricorn|♑]])'; |
|||
api.post({ |
|||
editform.wpTextbox1.value = mblob.toString(); |
|||
action: 'edit', |
|||
mblob = null; |
|||
title: mw.config.get('wgPageName'), |
|||
ui.style.display = 'none'; |
|||
basetimestamp: page.revisions[0].timestamp, |
|||
uiPivot.style.display = ''; |
|||
summary: summary, |
|||
text: mblob.toString(), |
|||
token: mw.user.tokens.get('csrfToken') |
|||
}, { |
|||
success: function (result) { |
|||
if (result.error) { |
|||
setStatus([ |
|||
'API error: "', |
|||
result.error.info, |
|||
'" [code: ', el('code', [result.error.code]), ']' |
|||
]); |
|||
return; |
|||
} |
|||
setStatus(['Saved. Reloading page...']); |
|||
if (/redirect=no/.test(location.href)) // XXX |
|||
location.reload(); |
|||
else |
|||
location.search = location.search ? location.search + '&redirect=no' : '?redirect=no'; |
|||
} |
|||
}); |
|||
}); |
}); |
||
ui.style.display = 'none'; |
|||
var userName = mw.user.getName(); |
|||
ui.statusLine.insertBefore(el('input', null, { |
|||
api.get({ |
|||
type: "button", |
|||
value: "Cancel", |
|||
}, { |
|||
"list": "users", |
|||
click: function () { |
|||
mblob = null; |
|||
ui.style.display = 'none'; |
|||
}, { success: function(result) { |
|||
uiPivot.style.display = ''; |
|||
var groups = result["query"]["users"][0]["groups"] |
|||
if (groups.includes("patroller")) { |
|||
ui.patrolLine.insertBefore(el('label', [ |
|||
el('input', [], { |
|||
'class': 'checkbox', |
|||
'type': 'checkbox', |
|||
'id': 'patrol', |
|||
'value': 'patrol' |
|||
}), 'Mark as patrolled?']),null); |
|||
} |
|||
} |
} |
||
}), ui.statusLine.firstChild); |
|||
}); |
|||
ui.statusLine.insertBefore(el('input', null, { |
ui.statusLine.insertBefore(el('input', null, { |
||
type: |
type: "submit", |
||
value: |
value: "Check" |
||
}), ui.statusLine.firstChild); |
}), ui.statusLine.firstChild); |
||
uiPivot.parentNode.insertBefore(ui, uiPivot); |
|||
uiWrapper.appendChild(ui); |
|||
uiPivot.style.display = 'none'; |
|||
ui.style.display = ''; |
|||
}, { |
|||
"class": "kephir-sagittarius-editlink", |
|||
"title": "Edit this redirect with Capricorn" |
|||
})); |
|||
var submitButton; |
|||
var inputs = editform.getElementsByTagName('input'); |
|||
for (var i = 0; i < inputs.length; ++i) { |
|||
inputs[i].addEventListener('click', function (ev) { |
|||
submitButton = this; |
|||
}, false); |
|||
} |
} |
||
editform.addEventListener('submit', function (ev) { |
|||
} else if ((mw.config.get('wgPageContentModel') === 'wikitext') && ((mw.config.get('wgAction') === 'edit') || (mw.config.get('wgAction') === 'submit'))) { |
|||
if (submitButton !== editform.wpSave) |
|||
if (mw.util.getParamValue('section')) |
|||
return; |
return; |
||
if (mblob) { |
|||
var editform = document.getElementById('editform'); |
|||
ev.preventDefault(); |
|||
ev.stopImmediatePropagation(); |
|||
ui.doCheck(function (setStatus) { |
|||
setStatus(['Proceeding with saving...']); |
|||
var summary = setSummary(currentTarget,ui.origTarget) |
|||
editform.wpTextbox1.value = mblob.toString(); |
|||
editform.wpSummary.value = summary; |
|||
mblob = null; |
|||
editform.submit(); |
|||
}); |
|||
} |
|||
}, false); |
|||
} |
|||
if (!window.kephirSagittariusFollowCategoryRedirects) |
|||
if ((mw.config.get('wgAction') === 'view') && (mw.config.get('wgNamespaceNumber') === wgNamespaceIds.category)) { |
|||
var pagesList = document.getElementById('mw-pages').getElementsByClassName('mw-redirect'); |
|||
for (var i = 0; i < pagesList.length; ++i) { |
|||
pagesList[i].href += '?redirect=no'; |
|||
} |
|||
} |
|||
} |
|||
function abortConditions() { |
|||
if (!editform || !editform.wpTextbox1 || editform.wpTextbox1.readOnly) |
|||
if (window.location.href.includes('&diff=')) { |
|||
return; |
|||
throw new Error('Viewing page diff. Please revert before editing redirect.'); |
|||
} |
|||
if (mw.config.get('wgNamespaceNumber') < 0) { |
|||
throw new Error('Page is in a virtual namespace. Capricorn aborts.'); |
|||
} |
|||
} |
|||
function Capricorn() { |
|||
var uiPivot = document.getElementsByClassName('wikiEditor-ui')[0]; |
|||
$.getJSON("https://en.wikipedia.org/w/index.php?title=User:Wugapodes/Capricorn/RedirectAliases.json&action=raw&ctype=application/json", function(aliasJSON) { |
|||
$.getJSON("https://en.wikipedia.org/w/index.php?title=User:Wugapodes/Capricorn/RedirectTemplates.json&action=raw&ctype=application/json",function(templateJSON) { |
|||
mw.loader.using(['jquery.suggestions', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.action.view.redirectPage'], function () { |
|||
mainCallback(aliasJSON,templateJSON); |
|||
}); |
|||
}); |
|||
}); |
|||
} |
|||
var api = new mw.Api(); |
|||
firstHeading.appendChild(document.createTextNode(' ')); |
|||
firstHeading.appendChild(link(['♑'], function () { |
|||
if (ui && ui.parentNode) |
|||
ui.parentNode.removeChild(ui); |
|||
api.get({ |
|||
action: "query", |
|||
format: "json", |
|||
prop: "info", |
|||
formatversion: 2, |
|||
titles: mw.config.get('wgPageName') |
|||
}, { |
|||
success: function (result) { |
|||
try { |
try { |
||
abortConditions(); |
|||
mblob = new MarkupBlob(editform.wpTextbox1.value); |
|||
} catch |
} catch(error) { |
||
console.info(error) |
|||
alert("Error: unable to parse page. This page is probably not a redirect."); |
|||
return; |
return; |
||
} |
} |
||
if (result.query.pages[0].redirect) { |
|||
Capricorn(); |
|||
currentTarget = mblob.target |
|||
} else { |
|||
console.debug('Page is not a redirect.') |
|||
ui = buildEditingUI(mblob, function () { |
|||
editform.wpSummary.value = 'Redirecting to [[' + mblob.target + ']] ([[User:Wugapodes/Capricorn|♑]])'; |
|||
editform.wpTextbox1.value = mblob.toString(); |
|||
mblob = null; |
|||
ui.style.display = 'none'; |
|||
uiPivot.style.display = ''; |
|||
}); |
|||
ui.style.display = 'none'; |
|||
ui.statusLine.insertBefore(el('input', null, { |
|||
type: "button", |
|||
value: "Cancel", |
|||
}, { |
|||
click: function () { |
|||
mblob = null; |
|||
ui.style.display = 'none'; |
|||
uiPivot.style.display = ''; |
|||
} |
|||
}), ui.statusLine.firstChild); |
|||
ui.statusLine.insertBefore(el('input', null, { |
|||
type: "submit", |
|||
value: "Check" |
|||
}), ui.statusLine.firstChild); |
|||
uiPivot.parentNode.insertBefore(ui, uiPivot); |
|||
uiPivot.style.display = 'none'; |
|||
ui.style.display = ''; |
|||
}, { |
|||
"class": "kephir-sagittarius-editlink", |
|||
"title": "Edit this redirect with Capricorn" |
|||
})); |
|||
var submitButton; |
|||
var inputs = editform.getElementsByTagName('input'); |
|||
for (var i = 0; i < inputs.length; ++i) { |
|||
inputs[i].addEventListener('click', function (ev) { |
|||
submitButton = this; |
|||
}, false); |
|||
} |
|||
editform.addEventListener('submit', function (ev) { |
|||
if (submitButton !== editform.wpSave) |
|||
return; |
return; |
||
if (mblob) { |
|||
ev.preventDefault(); |
|||
ev.stopImmediatePropagation(); |
|||
ui.doCheck(function (setStatus) { |
|||
setStatus(['Proceeding with saving...']); |
|||
var summary = setSummary(currentTarget,ui.origTarget) |
|||
editform.wpTextbox1.value = mblob.toString(); |
|||
editform.wpSummary.value = summary; |
|||
mblob = null; |
|||
editform.submit(); |
|||
}); |
|||
} |
} |
||
}, false); |
|||
} |
|||
if (!window.kephirSagittariusFollowCategoryRedirects) |
|||
if ((mw.config.get('wgAction') === 'view') && (mw.config.get('wgNamespaceNumber') === wgNamespaceIds.category)) { |
|||
var pagesList = document.getElementById('mw-pages').getElementsByClassName('mw-redirect'); |
|||
for (var i = 0; i < pagesList.length; ++i) { |
|||
pagesList[i].href += '?redirect=no'; |
|||
} |
} |
||
} |
|||
}); |
|||
}); |
|||
}); |
}); |
||
/*</source> |
/*</source> |
Revision as of 23:23, 7 June 2021
// <nowiki>
// This is a modified version of [[User:Sam Sailor/Scripts/Sagittarius+.js]] ([[Special:PermaLink/899463476]])
// Docs: [[User:Wugapodes/Capricorn]]
/*jshint undef:true, latedef:true, shadow:true, loopfunc:true, scripturl:true, undef:true */
/*globals jQuery, mw, importStylesheet */
////////////////////////////////////////////////////////////////////////////////
// Helper function definitions
function encodeCodePoint(c) {
if (c === 0x20)
return '_';
if (c < 0x80) {
return '.' + c.toString(16).toUpperCase();
} else if (c < 0x800) {
return '.' + (0xc0 | (c >>> 6) ).toString(16).toUpperCase() +
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase();
} else if (c < 0x10000) {
return '.' + (0xe0 | (c >>> 12) ).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase();
} else if (c < 0x200000) {
return '.' + (0xf0 | (c >>> 18) ).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase();
} else if (c < 0x4000000) {
return '.' + (0xf8 | (c >>> 24) ).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 18) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase();
} else if (c < 0x80000000) {
return '.' + (0xfc | (c >>> 30) ).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 24) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 18) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 12) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ((c >>> 6) & 0x3f)).toString(16).toUpperCase() +
'.' + (0x80 | ( c & 0x3f)).toString(16).toUpperCase();
}
}
function normaliseAnchor(anchor) {
// "." is not escaped!
return anchor.replace(/[^0-9A-Za-z_:\.]/g, function (m) { /* [\ud800-\udbff][\udc00-\dfff]| */
if (m.length === 2) { // surrogate pair
return encodeCodePoint((m.charCodeAt(0) & 0x3ff) << 10 | m.charCodeAt(1) & 0x3ff);
} else {
return encodeCodePoint(m.charCodeAt(0));
}
});
}
function normaliseTitle(title) {
try {
var t = new mw.Title(title);
return t.getPrefixedText();
} catch (e) {
return null;
}
}
function el(tag, child, attr, events) {
var node = document.createElement(tag);
if (child) {
if ((typeof child === 'string') || (typeof child.length !== 'number'))
child = [child];
for (var i = 0; i < child.length; ++i) {
var ch = child[i];
if ((ch === void(null)) || (ch === null))
continue;
else if (typeof ch !== 'object')
ch = document.createTextNode(String(ch));
node.appendChild(ch);
}
}
if (attr) for (var key in attr) {
if ((attr[key] === void(0)) || (attr[key] === null))
continue;
node.setAttribute(key, String(attr[key]));
}
if (events) for (var key in events) {
var handler = events[key];
if ((key === 'input') && (window.oninput === void(0))) {
key = 'change';
}
node.addEventListener(key, handler, false);
}
return node;
}
function link(child, href, attr, ev) {
attr = attr || {};
ev = ev || {};
if (typeof attr === 'string') {
attr = { "title": attr };
}
if (typeof href === 'string')
attr.href = href;
else {
attr.href = 'javascript:void(null);';
ev.click = href;
}
return el('a', child, attr, ev);
}
var templateGroups = {
"fromRelatedInfo": "Related information, From",
"toRelatedInfo": "Related information, To",
"fromPartOfSpeech": "Parts of speech, From",
"fromEngVar": "English variant spelling, From",
"fromOrthographicModification": "Orthographic difference, From",
"toOrthographicModification": "Orthographic difference, To",
"fromAlt": "Alternative names, From",
"fromDisambiguation": "Ambiguity, From",
//"toDisambiguation": "Ambiguity, To",
//"fromSpecificity": "Specificity, From",
"fromAnthroponym": "Anthroponym, From",
"fromFiction": "Fiction, From",
"fromWork": "Works of art and works generally, From",
"toWork": "Works of art and works generally, To",
"fromLocationOrInfrastructure": "Geographic location or infrastructure, From",
"fromFormerName": "Former names, From",
"toFormerName": "Former names, To",
"fromSystematicName": "Systematic name, From",
"toSystematicName": "Systematic name, To",
"fromPostal": "From postal information",
"fromOrganization": "From organization",
"fromMath": "From mathematical topic",
"fromComic": "Comics, From",
"toComic": "Comics, To",
"fromMiddleEarth": "Middle-earth topic, From",
"toMiddleEarth": "Middle-earth topic, To",
"fromMisc": "From miscellaneous information",
"fromMeta": "Meta information, From",
"toMeta": "Meta information, To",
"fromProtected": "Protection level, From",
"toNameSpace": "Namespaces, To",
"fromPrintworthiness":"Printworthiness"
};
////////////////////////////////////////////////////////////////////////////////
// Callback functions
function mainCallback(aliasJSON, templateJSON) {
var templateAliases = aliasJSON;
var redirectTemplates = templateJSON;
//console.log(templateAliases);
//console.log(redirectTemplates);
// <nowiki>
'use strict';
importStylesheet('User:Wugapodes/Capricorn.css');
var wgNamespaceIds = mw.config.get('wgNamespaceIds');
var contentText = document.getElementById('mw-content-text');
var firstHeading = document.getElementById('firstHeading');
var redirMsg = contentText.getElementsByClassName('redirectMsg')[0];
var uiWrapper = el('div');
var edittoken = null;
function MarkupBlob(markup) {
if (!markup) {
this.target = '';
this.rcatt = {};
this.tail = '';
} else
this.parse(markup);
}
MarkupBlob.prototype.parse = function (markup) {
var rdrx = /^#REDIRECT:?\s*\[\[\s*([^\|{}[\]]+?)\s*]]\s*/i;
var tprx = /^\s*{{([A-Za-z ]+)((?:\|(?:[^|{}]*|{{[^|}]*}})+)*)}}\s*/i;
var m;
m = rdrx.exec(markup)
markup = markup.substr(m[0].length);
this.target = m[1];
this.rcatt = {};
out: while ((m = tprx.exec(markup))) {
var alias = normaliseTitle(m[1]);
while (templateAliases[alias])
alias = templateAliases[alias]; // hopefully there are no loops.
if (alias === "This is a redirect") {
var params = m[2].split('|');
for (var j = 0; j < params.length; ++j) {
if (!params[j])
continue;
if (params[j].indexOf('=') !== -1)
break out;
alias = normaliseTitle("R " + params[j]);
while (templateAliases[alias])
alias = templateAliases[alias]; // hopefully there are still no loops.
if (alias in redirectTemplates)
this.rcatt[alias] = true;
else
break out;
}
} else if (alias === "Redirect category shell") {
var mm, rr = /{{(.*?)}}/g;
while (mm = rr.exec(m[2])) {
alias = normaliseTitle(mm[1]);
while (templateAliases[alias])
alias = templateAliases[alias];
if (alias in redirectTemplates)
this.rcatt[alias] = true;
}
} else if (alias in redirectTemplates) {
if (m[2]) // TODO
break;
this.rcatt[alias] = true;
} else {
break;
}
markup = markup.substr(m[0].length);
}
this.tail = markup;
};
MarkupBlob.prototype.toString = function () {
var markup = '#REDIRECT [[' + this.target + ']]\n';
var tail = '';
var wrapped = [];
for (var key in this.rcatt) {
if (this.rcatt[key])
if ((wrapped.length < 6) && /^R\s+/.test(key))
wrapped.push('{{' + key + '}}\n');
else
tail += '{{' + key + '}}\n';
}
if (wrapped.length)
markup += "\n{{Redirect category shell|\n" + wrapped.join("") + "}}\n";
markup += tail + '\n';
markup += this.tail;
return markup;
};
function buildTagList(rcatt) {
function makeCheckBox(key) {
return el('label', [
el('input', null, {
type: "checkbox",
checked: (key in rcatt) ? "checked" : null,
}, {
change: function (ev) {
rcatt[key] = this.checked;
}
}),
' ',
redirectTemplates[key].label
], {
"title": redirectTemplates[key].tooltip
});
}
var list = el('dl', null, { "class": "tag-list" });
var group = {};
for (var key in templateGroups) {
list.appendChild(el('dt', templateGroups[key]));
list.appendChild(el('dd', group[key] = el('ul')));
}
for (var key in redirectTemplates) {
var label = makeCheckBox(key);
group[redirectTemplates[key].group].appendChild(el('li', label));
}
var collapsibleContent = el('div', list, {
"class": "mw-collapsible-content",
"id": "capricorn-toggle-content"
})
return collapsibleContent;
}
//
// Interface creation
//
function buildEditingUI(mblob, saveCallback) {
var statusbar;
var needsCheck = true;
var doSave;
var uiLink, uiTarget;
mblob = mblob || new MarkupBlob();
// Change text of status bar
function setStatus(status) {
while (statusbar.firstChild) // Remove previous statuses
statusbar.removeChild(statusbar.firstChild);
if (status) { // If status is a string, add it
if (typeof status === 'string')
statusbar.appendChild(document.createTextNode(status));
else { // Otherwise, loop through list and add statuses
for (var j = 0; j < status.length; ++j) {
if (typeof status[j] === 'string')
statusbar.appendChild(document.createTextNode(status[j]));
else
statusbar.appendChild(status[j]);
}
}
}
}
// Check if the target has changed??
// Not actually sure what this does yet 21 Oct 2019
function inputChanged(ev) {
/*jshint validthis:true */
try {
mblob.target = this.value;
var t = new mw.Title(this.value);
var frag = t.getFragment() ? '#' + normaliseAnchor(t.getFragment()) : '';
if (uiLink) uiLink.href = mw.util.getUrl(t.getPrefixedDb(), { redirect: "no" }) + frag;
setStatus();
} catch (e) {
setStatus('Invalid title.');
if (uiLink) uiLink.href = 'javascript:void(0);';
}
needsCheck = true;
}
var uiStatusLine;
var patrolLine;
var origTarget = mblob.target
var ui = el('form', [
el('div', [
el('ul', [
el('li', [
uiTarget = el('input', null, {
'type': 'text',
'class': 'redirectText',
'value': mblob.target
}, {
'input': inputChanged,
'change': inputChanged,
'blur': function (ev) { // i would not have to write this, if it were not for jQuery. seriously.
if (mblob.target === this.value)
return;
inputChanged.call(this, ev);
}
})
])
], { 'class': 'redirectText' }),
el('input', null, {
"type": "button",
"class":"capricorn-toggle",
"id": "capricorn-toggle-button",
"value": "Hide rcat list"
}, {
'click': function() {
$( "#capricorn-toggle-content" ).toggle();
var buttonText = $("#capricorn-toggle-button")[0].value;
if (buttonText === "Hide rcat list") {
$("#capricorn-toggle-button")[0].value = "Show rcat list"
} else {
$("#capricorn-toggle-button")[0].value = "Hide rcat list"
};
}
})
], { 'class': 'redirectMsg' }),
buildTagList(mblob.rcatt),
uiStatusLine = el('p', [
patrolLine = el('span', [], {}),
statusbar = el('span', [], {
'class': 'status-line'
}),
el('span', [
link(["Statistics for this page"], 'https://tools.wmflabs.org/pageviews?project=en.wikipedia.org&pages=' + encodeURIComponent(mw.config.get('wgPageName'))),
' • ',
link(["WP:TMR"], mw.util.getUrl("Wikipedia:Template messages/Redirect pages")),
' • ',
link(["About Capricorn"], mw.util.getUrl("User:Wugapodes/Capricorn"))
], {
'style': 'float: right;'
})
])
], {
'action': 'javascript:void(0)',
'class': 'kephir-sagittarius-editor'
}, {
'submit': function (ev) {
ev.preventDefault();
if (uiStatusLine.childNodes[1].childNodes[0]) {
var patrolVal = uiStatusLine.childNodes[1].childNodes[0].childNodes[0].checked;
if (patrolVal) {
api.get({
"action": "query",
"format": "json",
"prop": "revisions",
"meta": "tokens",
"titles": mw.config.get('wgPageName'),
"rvprop": "ids",
"rvslots": "",
"rvlimit": "1",
"rvdir": "newer",
"type": "patrol"
}, {
success: function (result) {
//console.log(mw.config.get('wgPageName'))
var patrolToken = result["query"]["tokens"]["patroltoken"];
var revIDpart = result["query"]["pages"];
var revID = null;
for (var page in revIDpart) {
revID = revIDpart[page]["revisions"][0]["revid"];
}
//console.log(revID)
api.post({
"action": 'patrol',
"revid": revID,
"token": patrolToken
}, {
success: function (result) {
if (result.error) {
console.log(result.error);
setStatus([
'API error: "',
result.error.info,
'" [code: ', el('code', [result.error.code]), ']'
]);
console.log(result.error)
return;
}
}
});
}
});
}
}
ui.doCheck(saveCallback);
}
});
ui.statusLine = uiStatusLine;
ui.patrolLine = patrolLine;
ui.origTarget = origTarget
var sectCache = {};
var $uiTarget = jQuery(uiTarget);
$uiTarget.suggestions({
submitOnClick: false,
delay: 500,
fetch: function (query) {
$uiTarget.suggestions('suggestions', []);
if (query.indexOf('#') !== -1) {
var title = query.substr(0, query.indexOf('#'));
var sect = query.substr(query.indexOf('#') + 1);
if (sectCache[title]) {
var normSect = normaliseAnchor(sect);
$uiTarget.suggestions('suggestions',
sectCache[title].filter(function (item) {
var norm = normaliseAnchor(item.anchor);
return norm.substr(0, normSect.length) === normSect;
})
);
return;
}
api.get({
action: 'parse',
page: title,
prop: 'sections|properties',
redirects: '1'
}).then(function (result) {
if (result.parse.redirects && result.parse.redirects.length) {
// XXX
return;
}
var disambig = false; // XXX
var normSect = normaliseAnchor(sect);
sectCache[title] = result.parse.sections.map(function (item) {
return {
anchor: item.anchor,
title: title + '#' + decodeURIComponent(item.anchor.replace(/_/g, ' ').replace(/\.([0-9A-Fa-f][0-9A-Fa-f])/g, '%')), // XXX: hack
disambig: disambig,
toString: function () {
return this.title;
}
};
});
$uiTarget.suggestions('suggestions',
sectCache[title].filter(function (item) {
var norm = normaliseAnchor(item.anchor);
return norm.substr(0, normSect.length) === normSect;
})
);
});
return;
}
api.get({
action: 'query',
generator: 'allpages',
gapprefix: query,
gaplimit: 16,
prop: 'info|pageprops',
}).then(function (result) {
var pglist = [];
for (var pgid in result.query.pages) {
var page = result.query.pages[pgid];
pglist.push({
title: page.title,
pageid: page.pageid,
disambig: page.pageprops && ('disambiguation' in page.pageprops),
redirect: 'redirect' in page,
toString: function () {
return this.title;
}
});
}
$uiTarget.suggestions('suggestions', pglist);
});
},
result: {
render: function (item, content) {
var elm = this[0];
elm.appendChild(el('span', [item.title], {
style: item.redirect ? 'font-style: italic' : ''
}));
if (item.disambig)
elm.appendChild(el('small', [' (disambiguation page)']));
if (item.redirect)
elm.appendChild(el('small', [' (redirect)']));
},
select: function ($textbox) {
var item = this.data('text');
var textbox = $textbox[0];
textbox.value = item.title;
if (item.redirect) {
api.get({
action: 'query',
pageids: item.pageid,
redirects: '1'
}).then(function (result) {
var redir = result.query.redirects.pop();
textbox.value = redir.to + (redir.tofragment ? '#' + redir.tofragment : '');
});
}
return true;
}
}
});
ui.doCheck = function (callback) {
var that = this;
if (!/^\s*[^\|{}[\]]+\s*$/.test(mblob.target)) {
setStatus(['Error: the target page name is invalid.']);
return;
}
if (needsCheck) {
var oldTarget = mblob.target;
var normTarget;
try {
normTarget = new mw.Title(oldTarget);
} catch (e) {
setStatus(['"', oldTarget, '" is not a valid page name. Try again to proceed anyway.']);
return;
}
setStatus(['Checking target validity...']);
needsCheck = false;
api.get({
action: 'parse',
page: oldTarget = mblob.target,
prop: 'sections',
redirects: '1'
}, {
success: function (result) {
var m;
if (result.error) {
if (result.error.code === 'missingtitle') {
setStatus([
'Error: The target page "',
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { "class": "new" })),
'" does not exist. Try again to proceed anyway.'
]);
} else {
setStatus([
'API error: "',
result.error.info,
'" [code: ', el('code', [result.error.code]), ']'
]);
}
return;
}
if (result.parse.redirects && result.parse.redirects[0]) {
var newTarget = result.parse.redirects[0].to + (result.parse.redirects[0].tofragment ? "#" + result.parse.redirects[0].tofragment : "");
setStatus([
'Error: The target page "',
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { redirect: "no" })),
'" is already a redirect to "',
link([newTarget], mw.util.getUrl(newTarget, { redirect: "no" })),
'". Try again to proceed anyway, or ',
link(['retarget this redirect to point there directly'], function () {
uiTarget.value = mblob.target = newTarget +
((!result.parse.redirects[0].tofragment && normTarget.fragment) ? '#' + normTarget.fragment : '');
needsCheck = true;
}),
'.'
]);
return;
}
if (normTarget.fragment) { // we have a section link
var sect = normaliseAnchor(normTarget.fragment);
var isValidSect = false;
var sectlist = result.parse.sections;
for (var j = 0; j < sectlist.length; ++j) {
if (sectlist[j].anchor === sect)
isValidSect = true;
}
if (!isValidSect) {
setStatus([
'Error: The target page "',
link([normTarget.getPrefixedText()], mw.util.getUrl(normTarget.getPrefixedText(), { redirect: "no" })),
'" does not have a a section called "',
normTarget.fragment,
'". Try again to proceed anyway.'
]);
return;
}
}
callback(setStatus);
}
});
return;
}
callback(setStatus);
};
return ui;
}
function setSummary(current,orig) {
var summary;
if (orig === current) {
summary= "Modifying [[WP:RCAT|redirect categories]] using [[User:Wugapodes/Capricorn|Capricorn ♑]]";
} else {
summary = 'Redirecting to [[' + current + ']] ([[User:Wugapodes/Capricorn|♑]])'
}
return summary
}
if ((mw.config.get('wgAction') === 'view') && (mw.config.get('wgArticleId') === 0)) { // nonexistent page.
uiWrapper.appendChild(el('div', [
link(['Create a redirect'], function () {
while (uiWrapper.hasChildNodes())
uiWrapper.removeChild(uiWrapper.firstChild);
var mblob = new MarkupBlob();
var ui = buildEditingUI(mblob, function (setStatus) {
setStatus(['Saving...']);
var summary = setSummary(mblob.target,ui.origTarget)
api.post({
action: 'edit',
title: mw.config.get('wgPageName'),
createonly: 1,
summary: summary,
text: mblob.toString(),
token: mw.user.tokens.get('csrfToken')
}, {
success: function (result) {
if (result.error) {
setStatus([
'API error: "',
result.error.info,
'" [code: ', el('code', [result.error.code]), ']'
]);
return;
}
setStatus(['Saved. Reloading page...']);
if (/redirect=no/.test(location.href)) // XXX
location.reload();
else
location.search = location.search ? location.search + '&redirect=no' : '?redirect=no';
}
});
});
ui.statusLine.insertBefore(el('input', null, {
type: 'submit',
value: 'Save'
}), ui.statusLine.firstChild);
uiWrapper.appendChild(ui);
}), ' from this page with Capricorn'
], {
"class": "kephir-sagittarius-invite"
}));
contentText.parentNode.insertBefore(uiWrapper, contentText);
} else if ((mw.config.get('wgAction') === 'view') && mw.config.get('wgIsRedirect') && redirMsg) {
// start editor immediately
uiWrapper.appendChild(el('div', ['Loading page source…'], {
"class": "kephir-sagittarius-loading"
}));
contentText.insertBefore(uiWrapper, contentText.firstChild);
api.get({
action: 'query',
prop: 'revisions',
rvprop: 'timestamp|content',
pageids: mw.config.get('wgArticleId'),
rvstartid: mw.config.get('wgRevisionId'),
rvlimit: 1,
rvdir: 'older'
}, {
success: function (result) {
if (result.error) {
uiWrapper.appendChild(el('div', [
'API error: "',
result.error.info,
'" [code: ', el('code', [result.error.code]), ']. Reload to try again.'
], {
"class": "kephir-sagittarius-error"
}));
return;
}
while (uiWrapper.hasChildNodes())
uiWrapper.removeChild(uiWrapper.firstChild);
var page = result.query.pages[mw.config.get('wgArticleId')];
var mblob;
var token = mw.user.tokens.get('csrfToken')
try {
mblob = new MarkupBlob(page.revisions[0]['*']);
} catch(e) {
uiWrapper.appendChild(el('div', ['Error: unable to parse page. Edit the source manually.'], {
"class": "kephir-sagittarius-error"
}));
return;
}
redirMsg.parentNode.removeChild(redirMsg);
var ui = buildEditingUI(mblob, function (setStatus) {
setStatus(['Saving...']);
var summary = setSummary(mblob.target,ui.origTarget)
api.post({
action: 'edit',
title: mw.config.get('wgPageName'),
basetimestamp: page.revisions[0].timestamp,
summary: summary,
text: mblob.toString(),
token: mw.user.tokens.get('csrfToken')
}, {
success: function (result) {
if (result.error) {
setStatus([
'API error: "',
result.error.info,
'" [code: ', el('code', [result.error.code]), ']'
]);
return;
}
setStatus(['Saved. Reloading page...']);
if (/redirect=no/.test(location.href)) // XXX
location.reload();
else
location.search = location.search ? location.search + '&redirect=no' : '?redirect=no';
}
});
});
var userName = mw.user.getName();
api.get({
"action": "query",
"format": "json",
"list": "users",
"usprop": "groups",
"ususers": userName
}, { success: function(result) {
var groups = result["query"]["users"][0]["groups"]
if (groups.includes("patroller")) {
ui.patrolLine.insertBefore(el('label', [
el('input', [], {
'class': 'checkbox',
'type': 'checkbox',
'id': 'patrol',
'value': 'patrol'
}), 'Mark as patrolled?']),null);
}
}
});
ui.statusLine.insertBefore(el('input', null, {
type: 'submit',
value: 'Save'
}), ui.statusLine.firstChild);
uiWrapper.appendChild(ui);
}
});
} else if ((mw.config.get('wgPageContentModel') === 'wikitext') && ((mw.config.get('wgAction') === 'edit') || (mw.config.get('wgAction') === 'submit'))) {
if (mw.util.getParamValue('section'))
return;
var editform = document.getElementById('editform');
if (!editform || !editform.wpTextbox1 || editform.wpTextbox1.readOnly)
return;
var uiPivot = document.getElementsByClassName('wikiEditor-ui')[0];
var ui, mblob;
firstHeading.appendChild(document.createTextNode(' '));
firstHeading.appendChild(link(['♑'], function () {
if (ui && ui.parentNode)
ui.parentNode.removeChild(ui);
try {
mblob = new MarkupBlob(editform.wpTextbox1.value);
} catch (e) {
alert("Error: unable to parse page. This page is probably not a redirect.");
return;
}
currentTarget = mblob.target
ui = buildEditingUI(mblob, function () {
editform.wpSummary.value = 'Redirecting to [[' + mblob.target + ']] ([[User:Wugapodes/Capricorn|♑]])';
editform.wpTextbox1.value = mblob.toString();
mblob = null;
ui.style.display = 'none';
uiPivot.style.display = '';
});
ui.style.display = 'none';
ui.statusLine.insertBefore(el('input', null, {
type: "button",
value: "Cancel",
}, {
click: function () {
mblob = null;
ui.style.display = 'none';
uiPivot.style.display = '';
}
}), ui.statusLine.firstChild);
ui.statusLine.insertBefore(el('input', null, {
type: "submit",
value: "Check"
}), ui.statusLine.firstChild);
uiPivot.parentNode.insertBefore(ui, uiPivot);
uiPivot.style.display = 'none';
ui.style.display = '';
}, {
"class": "kephir-sagittarius-editlink",
"title": "Edit this redirect with Capricorn"
}));
var submitButton;
var inputs = editform.getElementsByTagName('input');
for (var i = 0; i < inputs.length; ++i) {
inputs[i].addEventListener('click', function (ev) {
submitButton = this;
}, false);
}
editform.addEventListener('submit', function (ev) {
if (submitButton !== editform.wpSave)
return;
if (mblob) {
ev.preventDefault();
ev.stopImmediatePropagation();
ui.doCheck(function (setStatus) {
setStatus(['Proceeding with saving...']);
var summary = setSummary(currentTarget,ui.origTarget)
editform.wpTextbox1.value = mblob.toString();
editform.wpSummary.value = summary;
mblob = null;
editform.submit();
});
}
}, false);
}
if (!window.kephirSagittariusFollowCategoryRedirects)
if ((mw.config.get('wgAction') === 'view') && (mw.config.get('wgNamespaceNumber') === wgNamespaceIds.category)) {
var pagesList = document.getElementById('mw-pages').getElementsByClassName('mw-redirect');
for (var i = 0; i < pagesList.length; ++i) {
pagesList[i].href += '?redirect=no';
}
}
}
function abortConditions() {
if (window.location.href.includes('&diff=')) {
throw new Error('Viewing page diff. Please revert before editing redirect.');
}
if (mw.config.get('wgNamespaceNumber') < 0) {
throw new Error('Page is in a virtual namespace. Capricorn aborts.');
}
}
function Capricorn() {
$.getJSON("https://en.wikipedia.org/w/index.php?title=User:Wugapodes/Capricorn/RedirectAliases.json&action=raw&ctype=application/json", function(aliasJSON) {
$.getJSON("https://en.wikipedia.org/w/index.php?title=User:Wugapodes/Capricorn/RedirectTemplates.json&action=raw&ctype=application/json",function(templateJSON) {
mw.loader.using(['jquery.suggestions', 'mediawiki.api', 'mediawiki.Title', 'mediawiki.action.view.redirectPage'], function () {
mainCallback(aliasJSON,templateJSON);
});
});
});
}
var api = new mw.Api();
api.get({
action: "query",
format: "json",
prop: "info",
formatversion: 2,
titles: mw.config.get('wgPageName')
}, {
success: function (result) {
try {
abortConditions();
} catch(error) {
console.info(error)
return;
}
if (result.query.pages[0].redirect) {
Capricorn();
} else {
console.debug('Page is not a redirect.')
return;
}
}
});
/*</source>
[[Category:Wikipedia scripts]]
*/
// </nowiki>