User:IPLRecordsUpdateBot/Source/IPLRecordsUpdateBot UI.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:IPLRecordsUpdateBot/Source/IPLRecordsUpdateBot UI. This user script seems to have an accompanying .css page at User:IPLRecordsUpdateBot/Source/IPLRecordsUpdateBot UI.css. |
function setCSSProperty(element, name, value) {
// Parse the style attribute
var styleAttr = element.getAttribute('style');
// Prevent a missing style attribute throwing an exception
if ( ! styleAttr ) {
element.setAttribute('style', name + ': ' + value);
return;
}
var styleProperties = styleAttr.split(/\s*;\s*/);
for ( var i = 0; i < styleProperties.length; i++ ) {
var stylePropRegex = /^([a-z0-9\-]+)\s*\:\s*(.*)\s*$/i;
var stylePropParts = stylePropRegex.exec(styleProperties[i]);
styleProperties[stylePropParts[1]] = stylePropParts[2];
delete styleProperties[i];
}
styleProperties[name] = value;
// Change it back to an indexed array
var i = 0;
for ( var propName in styleProperties ) {
styleProperties[i] = propName + ': ' + styleProperties[propName];
i++;
delete styleProperties[propName];
}
element.setAttribute('style', styleProperties.join('; '));
}
// Show the edit failed box if the backup file exists
var backupFileRequest = new XMLHttpRequest();
backupFileRequest.open('GET', 'edit_failed_backup.txt', false);
backupFileRequest.send();
if ( backupFileRequest.status == 200 ) {
setCSSProperty(document.getElementById('lasteditfailed'), 'display', 'block');
}
function selectAllOptions() {
var checkboxes = document.getElementById('optionstable').getElementsByTagName('input');
for ( var i = 0; i < checkboxes.length; i++ ) {
checkboxes[i].checked = true;
}
}
function deselectAllOptions() {
var checkboxes = document.getElementById('optionstable').getElementsByTagName('input');
for ( var i = 0; i < checkboxes.length; i++ ) {
checkboxes[i].checked = false;
}
}
function submitForm() {
var checkboxes = document.getElementById('optionstable').getElementsByTagName('input');
var statusBox = document.getElementById('status');
var statsToUpdate = [];
for ( var i = 0; i < checkboxes.length; i++ ) {
if ( checkboxes[i].checked === true ) {
statsToUpdate.push(checkboxes[i].getAttribute('name'))
}
}
if ( statsToUpdate.length == 0 ) {
alert('No stats selected to update');
return;
}
// Change the status box
setCSSProperty(statusBox, 'border-color', '#FFB700');
setCSSProperty(statusBox, 'background-color', '#FFFFBB');
statusBox.getElementsByTagName('td')[1].innerHTML = 'Updating... 0 of ' + statsToUpdate.length + ' completed (0 succeeded, 0 failed)';
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Ambox_clock_yellow.svg');
// Remove any unselected checkboxes
for ( var i = 0; i < checkboxes.length; i++ ) {
if ( checkboxes[i].checked === false ) {
setCSSProperty(checkboxes[i].parentNode.parentNode, 'display', 'none');
}
}
// Disable the form buttons
for ( var i = 0; i < document.getElementById('formbuttons').getElementsByTagName('input').length; i++ ) {
document.getElementById('formbuttons').getElementsByTagName('input')[i].disabled = true;
}
// Hide the last edit failed box if any
setCSSProperty(document.getElementById('lasteditfailed'), 'display', 'none');
// Send the request to update.php
var updateXHR = new XMLHttpRequest();
updateXHR.onreadystatechange = function() {
if ( updateXHR.readyState == 4 ) {
// Run the update status function for the last time
updateStatus();
updateErrors();
clearInterval(updateStatusInterval);
// If the PHP script terminates befor the updating starts, it is most likely an error
if ( statsUpdateCounters.totalCountValue == 0 ) {
setCSSProperty(statusBox, 'border-color', '#FF0000');
setCSSProperty(statusBox, 'background-color', '#FF8585');
statusBox.getElementsByTagName('td')[1].innerHTML = 'Failed before update' + (updateXHR.responseText ? ('<br />Error: ' + updateXHR.responseText) : '');
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Crystal_128_error.svg');
}
else if ( updateXHR.responseText.charAt(0) == '#' ) { // Edit successful
var revisionIDRegex = /#(\d+)\|(\d+)/;
var revisionIDs = revisionIDRegex.exec(updateXHR.responseText);
setCSSProperty(statusBox, 'border-color', '#00CC00');
setCSSProperty(statusBox, 'background-color', '#85FF85');
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML.replace(/Committing edit\.\.\./, 'Edit successful (<a href="http://en.wiki.x.io/w/index.php?diff=' + revisionIDs[2] + '&oldid=' + revisionIDs[1] + '" target="_blank">diff</a>)');
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Dialog-apply.svg');
}
else { // Edit failed
setCSSProperty(statusBox, 'border-color', '#FF0000');
setCSSProperty(statusBox, 'background-color', '#FF8585');
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML.replace(/Committing edit\.\.\./, 'Edit failed');
statusMsg.innerHTML += (updateXHR.responseText ? ('<br />Error: ' + updateXHR.responseText) : '');
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Crystal_128_error.svg');
}
}
}
updateXHR.open('GET', 'update.php?stats=' + statsToUpdate.join('|'), true);
updateXHR.send();
var statsUpdateCounters = {
'totalCountValue': 0,
'successCountValue': 0,
'failedCountValue': 0,
set totalCount(x) {
this.totalCountValue = x;
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML.replace(/\d+ (of \d+ completed)/, x + ' $1');
if ( x == statsToUpdate.length ) {
statusMsg.innerHTML = statusMsg.innerHTML.replace(/Updating\.\.\. \d+ of \d+ completed \((.*?)\)/, 'All ' + x + ' updates completed ($1)<br />Committing edit...');
}
},
set successCount(x) {
this.successCountValue = x;
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML.replace(/\d+ succeeded\,/, x + ' succeeded,');
},
set failedCount(x) {
this.failedCountValue = x;
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML.replace(/\d+ failed\)/, x + ' failed)');
},
}
function updateStatus() {
var statusXHR = new XMLHttpRequest()
statusXHR.open('GET', 'status.txt', false);
statusXHR.send();
if ( statusXHR.responseText == '' || ! (statusXHR.status == 200 || statusXHR.status == 304) ) {
return;
}
var statusTable = statusXHR.responseText.split('\r\n');
statusTable.pop(); // Remove the last empty element caused by a trailing newline
statusTable = statusTable.map(
function(value, key, array) {
return value.split('|');
}
);
statsUpdateCounters.totalCount = statusTable.length;
statsUpdateCounters.successCount = statusTable.filter(
function(value, key, array) {
return value[1] == 1;
}
).length;
statsUpdateCounters.failedCount = statusTable.filter(
function(value, key, array) {
return value[1] == 0;
}
).length;
function markStatAsSuccess(name) {
var statRow = document.getElementById('stats__' + name);
statRow.setAttribute('class', 'success');
statRow.getElementsByTagName('td')[1].innerHTML = '<img src="Images/Dialog-apply.svg" style="height: 15px; vertical-align: middle; padding-right: 5px" />Success';
}
function markStatAsFailed(name) {
var statRow = document.getElementById('stats__' + name);
statRow.setAttribute('class', 'failed');
statRow.getElementsByTagName('td')[1].innerHTML = '<img src="Images/Crystal_128_error.svg" style="height: 15px; vertical-align: middle; padding-right: 5px" />Failed';
}
for ( var i = 0; i < statusTable.length; i++ ) {
if ( statusTable[i][1] == 0 ) {
markStatAsFailed(statusTable[i][0]);
}
else {
markStatAsSuccess(statusTable[i][0]);
}
}
}
function updateErrors() {
var errorsXHR = new XMLHttpRequest();
errorsXHR.open('GET', 'error_log.txt', false);
errorsXHR.send();
if ( errorsXHR.responseText == '' || ! (errorsXHR.status == 200 || errorsXHR.status == 304) ) {
return;
}
var errors = errorsXHR.responseText.split('\r\n');
errors.pop();
errors = errors.map(
function(value, key, array) {
return value.split('|');
}
);
var errorTable = document.getElementById('errortable');
function addErrorMessage(type, message, file, line) {
var newRow = document.createElement('tr');
newRow.innerHTML = '<td>' + type + '</td><td>' + message + '</td><td>' + file + '</td><td>' + line + '</td>';
errorTable.appendChild(newRow);
}
// Clear the error table before filling it
while ( errorTable.getElementsByTagName('tr').length > 1 ) {
errorTable.removeChild(errorTable.getElementsByTagName('tr')[1]); // Do not remove the header row
}
for ( var i = 0; i < errors.length; i++ ) {
addErrorMessage(errors[i][0], errors[i][1].replace(/|/g, '|').replace(/&/g, '&'), errors[i][2], errors[i][3]);
}
}
var updateStatusInterval = setInterval(
function() {
updateStatus();
updateErrors();
}, 5000);
}
function resumeEdit() {
setCSSProperty(document.getElementById('lasteditfailed'), 'display', 'none');
var statusBox = document.getElementById('status');
setCSSProperty(statusBox, 'border-color', '#FFB700');
setCSSProperty(statusBox, 'background-color', '#FFFFBB');
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Ambox_clock_yellow.svg');
statusBox.getElementsByTagName('td')[1].innerHTML = 'Resuming...';
for ( var i = 0; i < document.getElementById('formbuttons').getElementsByTagName('input').length; i++ ) {
document.getElementById('formbuttons').getElementsByTagName('input')[i].disabled = true;
}
// Send the request
var updateXHR = new XMLHttpRequest();
updateXHR.onreadystatechange = function() {
if ( updateXHR.readyState == 4 ) {
if ( updateXHR.responseText.charAt(0) == '#' ) { // Edit successful
var revisionIDRegex = /#(\d+)\|(\d+)/;
var revisionIDs = revisionIDRegex.exec(updateXHR.responseText);
setCSSProperty(statusBox, 'border-color', '#00CC00');
setCSSProperty(statusBox, 'background-color', '#85FF85');
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML = 'Edit successful (<a href="http://en.wiki.x.io/w/index.php?diff=' + revisionIDs[2] + '&oldid=' + revisionIDs[1] + '" target="_blank">diff</a>)';
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Dialog-apply.svg');
}
else { // Edit failed
setCSSProperty(statusBox, 'border-color', '#FF0000');
setCSSProperty(statusBox, 'background-color', '#FF8585');
var statusMsg = statusBox.getElementsByTagName('td')[1];
statusMsg.innerHTML = statusMsg.innerHTML = 'Edit failed' + (updateXHR.responseText ? ('<br />Error: ' + updateXHR.responseText) : '');
statusBox.getElementsByTagName('td')[0].getElementsByTagName('img')[0].setAttribute('src', 'Images/Crystal_128_error.svg');
}
}
}
updateXHR.open('GET', 'update.php?resume=1', true);
updateXHR.send();
function updateErrors() {
var errorsXHR = new XMLHttpRequest();
errorsXHR.open('GET', 'error_log.txt', false);
errorsXHR.send();
if ( errorsXHR.responseText == '' || ! (errorsXHR.status == 200 || errorsXHR.status == 304) ) {
return;
}
var errors = errorsXHR.responseText.split('\r\n');
errors.pop();
errors = errors.map(
function(value, key, array) {
return value.split('|');
}
);
var errorTable = document.getElementById('errortable');
function addErrorMessage(type, message, file, line) {
var newRow = document.createElement('tr');
newRow.innerHTML = '<td>' + type + '</td><td>' + message + '</td><td>' + file + '</td><td>' + line + '</td>';
errorTable.appendChild(newRow);
}
while ( errorTable.getElementsByTagName('tr').length > 1 ) {
errorTable.removeChild(errorTable.getElementsByTagName('tr')[1]); // Do not remove the header row
}
for ( var i = 0; i < errors.length; i++ ) {
addErrorMessage(errors[i][0], errors[i][1].replace(/|/g, '|').replace(/&/g, '&'), errors[i][2], errors[i][3]);
}
}
setInterval(
function() {
updateErrors();
}, 5000 );
}