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="https://en.wikipedia.org/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.wikipedia.org/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 );
}