//<pre>wpPicmark.js
//By Gracenotes (http://en.wikipedia.org/wiki/User:Gracenotes)
//Released under the GPL
//Marks an image on Wikipedia (English) for something.
//If you have suggestions for more templates, talk to Gracenotes
//Alpha version finished 21 April 2007
//global variables
var templateCase = 0; //which item was selected from drop-down
var templateStage = 0; //which page editing
var cpost; //asyncPost object
var uploader; //uploader of the image, scratched from page
var imForm; //abstract object representing pseudo-form
var imMessage = ''; //current message
//global array
var tempDate = new Date();
var tempDateString = tempDate.getUTCFullYear() + ' ' + ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][tempDate.getUTCMonth()] + ' ' + tempDate.getUTCDate();
var templateArray = {
1: ['{{subst:nld}} No information on copyright', ' {{subst:nld}}', '{{subst:Image copyright request|Image:__IMAGE__}} ~~~~'],
2: ['{{subst:nsd}} No source information', '{{subst:nsd}}', '{{subst:image source|Image:__IMAGE__}} ~~~~'],
3: ['{{subst:nld}} + {{subst:nsd}}', '{{subst:nld}}\n{{subst:nsd}}', '{{subst:Image copyright request|Image:__IMAGE__}} ~~~~'],
4: ['{{subst:ifd}} Nominate image for deletion', '{{subst:ifd}}', '{{subst:idw|1=Image:__IMAGE__}}', 'Wikipedia:Images and media for deletion/' + tempDateString, '{{subst:ifd2|__IMAGE__|Uploader=__AUTHOR__|Reason=<<Reason for deletion>>}} — ~~~~'],
5: ['{{subst:orfud}} Orphaned fair use, not replaced', '{{subst:orfud}}', '{{subst:Orphaned|Image:__IMAGE__}} ~~~~'],
6: ['{{subst:orfur}} Orphaned fair use, replaced', '{{subst:orfur|Image:<<Replaced by Image>>}}', '{{subst:Orphaned|Image:__IMAGE__}} ~~~~'],
7: ['{{subst:rfu}} Fair use image considered replaceable', '{{subst:rfu}}', '{{subst:replaceable|__IMAGE__}} ~~~~'],
8: ['{{copyrighted}} Used with permission, not including third party use', '{{copyrighted}}'],
9: ['{{Db-redundantimage}} Reundant to another image (I1)', '{{Db-redundantimage|1=<<Redudant to Image>>}}'],
10:['{{Db-noimage}} Corrupted or empty image (I2)', '{{Db-noimage}}'],
11:['{{Db-attack}} Attack image (G10)', '{{Db-attack}}', '{{subst:uw-upload2|1=Image:__IMAGE__|subst=subst:}}'],
12:['{{Db-vandalism}} Image meant for vandalism (G3)', '{{Db-vandalism}}', '{{subst:uw-upload2|1=Image:__IMAGE__|subst=subst:}}'],
13:['{{PUIdisputed}} Information on source/license disputed', '{{PUIdisputed}}', '{{subst:idw-pui|1=Image:__IMAGE__}}', 'Wikipedia:Possibly unfree images', '*[[:Image:__IMAGE__]] <<Explanation>> ~~~~'],
14:['{{PUInonfree}} Only available non-free', '{{PUInonfree}}', '{{subst:idw-pui|1=Image:__IMAGE__}}', 'Wikipedia:Possibly unfree images', '*[[:Image:__IMAGE__]] <<Explanation>> ~~~~'],
15:['{{bsr}} Direct link to source, but no license context', '{{bsr}}', '{{subst:bsr-user|Image:__IMAGE__}} ~~~~']
}
var picmark = new Object();
picmark.popupBox = true;
picmark.minorEdit = [false, false, false];
picmark.watchThis = [false, false, false];
picmark.loadAll = true;
var imForm = new Object();
imForm.setEnabled = function(enable) {
var elems = ['imTextbox', 'imSummary', 'imWatchthis', 'imMinoredit', 'imSubmit', 'imSkip', 'imPageChange'];
var enText = enable ? "" : "true";
for (var i = 0; i < elems.length; i++)
this[elems[i]].disabled = enText;
}
imForm.set = function(tb, sm, wl, me, pg) {
this.imSummary.value = sm.imReplace();
this.imWatchthis.checked = wl;
this.imMinoredit.checked = me;
this.imPage.firstChild.nodeValue = pg.replace(/_/g, ' ');
this.imPage.title = 'Phase ' + (templateStage + 1);
this.imPage.href = '/wiki/' + encodeURIComponent(pg.replace(/\s/g, '_'))
this.imTextbox.value = fillInVars(tb.imReplace());
}
imForm.syncWithSync = function(sync) {
sync.text = this.imTextbox.value.imReplace();
sync.summary = this.imSummary.value.imReplace();
sync.minor = this.imWatchthis.checked;
sync.watch = this.imMinoredit.checked;
}
imForm.status = function(message) {
var temp = imMessage.length == 0;
imMessage += '...' + message;
if (temp) {
this.scroll();
}
}
imForm.scroll = function() {
var me = this;
if (me.imStatus.nodeValue.length < 85)
me.imStatus.nodeValue += imMessage.substring(0, 1);
else
me.imStatus.nodeValue = me.imStatus.nodeValue.substring(1) + imMessage.substring(0, 1);
if (imMessage.length > 0) {
imMessage = imMessage.substring(1);
var temp = window.setTimeout('imForm.scroll()', 30);
}
}
imForm.finish = function() {
imMessage = '';
this.imStatus.nodeValue = 'Done with application';
//a more specific implementation of set()
this.imTextbox.value = '';
this.imSummary.value = '';
this.imWatchthis.checked = false;
this.imMinoredit.checked = false;
imForm.imPage.parentNode.innerHTML = '(done)';
this.setEnabled(false);
}
function imInit() {
if (wgNamespaceNumber == 6 && document.getElementById('filehistory')) {
var templateSelect = document.createElement('form');
templateSelect.setAttribute("name", "templateSelect")
//templateSelect using innerHTML: not elegant, but fast
var templateString = ['<select name="imagetemp" onchange="imMain()">\n<option value="0" selected="selected">(Select a template)</option>'];
for (var i in templateArray) {
templateString.push('<option value="'+i+'">' + templateArray[i][0] + '</option>');
}
templateString.push('</select></form>');
templateSelect.innerHTML = templateString.join('\n');
document.getElementById('file').appendChild(templateSelect);
imForm.form = templateSelect;
uploader = getElementsByClassName(getElementsByClassName(document, 'table', 'filehistory')[0], 'a', 'mw-userlink')[0].firstChild.nodeValue;
}
}
function imMain() {
templateCase = document.forms.templateSelect.imagetemp.selectedIndex;
document.forms.templateSelect.imagetemp.disabled = true;
if (templateCase == 0) return false;
var imDiv = document.createElement('div');
imDiv.setAttribute('style', 'border:solid red 2px; padding: 5px;');
imDiv.setAttribute('id', 'imBox');
//convert text to DOM, and /then/ attach
imDiv.innerHTML = '<span id="imStatus" style="color: brown; text-align:center;"> </span><br />Post the following to <span id="imPage" style="background-color: lightgray; font-family: monospace; font-size:120%; font-weight: bold;"><a href="#" title="">Page name</a></span> <input type="button" value="(change)" name="imPageChange" id="imPageChange" onClick="var k = prompt(\'Enter the page name.\', cpost.page); cpost.page = k; cpost.stage = 0; imUpdate();" />\n\n<textarea cols="80" rows="10" name="imTextbox" id="imTextbox" >Text to send</textarea><br /><label for="imSummary">Edit summary (__IMAGE__ → image name, __AUTHOR__ → uploader username):</label><input type="text" size="30" maxlength="250" name="imSummary" id="imSummary" value="" /><br /><input type="checkbox" name="imMinoredit" id="imMinoredit" /><label for="imMinoredit">Minor edit</label><input type="checkbox" name="imWatchthis" id="imWatchthis" /><label for="imWatchthis">Watch this page</label> <input type="button" value="Submit" name="imSubmit" id="imSubmit" onClick="cpost.stage++; imForm.syncWithSync(cpost); imForm.setEnabled(false); imUpdate();" /> <input type="button" value="Skip" name="imSkip" id="imSkip" onClick="cpost = new asyncPost(); templateStage++; imUpdate();" />';
document.forms.templateSelect.appendChild(imDiv);
imForm.imBox = document.getElementById('imDiv');
imForm.imTextbox = document.getElementById('imTextbox');
imForm.imSummary = document.getElementById('imSummary');
imForm.imWatchthis = document.getElementById('imWatchthis');
imForm.imMinoredit = document.getElementById('imMinoredit');
imForm.imSubmit = document.getElementById('imSubmit');
imForm.imSkip = document.getElementById('imSkip');
imForm.imPageChange = document.getElementById('imPageChange');
imForm.imStatus = document.getElementById('imStatus').firstChild;
imForm.imPage = document.getElementById('imPage').getElementsByTagName('a')[0];
imForm.setEnabled(false);
cpost = new asyncPost();
imUpdate();
}
function imUpdate() {
switch (cpost.stage) {
case 0:
switch(templateStage) {
case 0:
if (!cpost.page) cpost.page = wgPageName;
imForm.set(templateArray[templateCase][1], 'Tagging [[Image:__IMAGE__]]', picmark.watchThis[0], picmark.minorEdit[0], cpost.page)
break;
case 1:
if (templateArray[templateCase][2]) {
if (!cpost.page) cpost.page = 'User talk:' + uploader;
imForm.set(templateArray[templateCase][2], 'Notifying uploader', picmark.watchThis[1], picmark.minorEdit[1], cpost.page);
}
else {
templateStage = 3;
}
break;
case 2:
if (templateArray[templateCase][3]) {
if (!cpost.page) cpost.page = templateArray[templateCase][3];
imForm.set(templateArray[templateCase][4], 'Posting to process page', picmark.watchThis[2], picmark.minorEdit[2], cpost.page);
}
else {
templateStage = 3;
}
break;
}
if (templateStage < 3) {
imForm.status('Getting edit box');
imForm.setEnabled(false);
cpost.getFormbox();
}
else
imForm.finish();
break;
case 1:
cpost.setFormbox();
break;
case 2:
cpost.submitFormbox();
break;
case 3:
if (templateStage < 3) {
cpost = new asyncPost();
imUpdate();
}
else {
imForm.finish();
}
break;
}
}
//we'll be needing 3 of these
//possible: add parameter for minor edit or not
function asyncPost(page, text, summary, minor, watch) {
//properties: may change with methods
this.page = page || '';
this.text = text || '';
this.summary = summary || '';
this.minor = minor || false;
this.watch = watch || false;
this.stage = 0;
this.formbox = undefined;
//adapted from code by Quarl
this.getFormbox = function() {
var me = this;
var req = sajax_init_object();
req.open("GET", mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title='+encodeURIComponent(this.page.replace(/\s/g, '_'))+'&action=edit', true);
req.overrideMimeType('text/xml');
req.onload = function(event) {
var req = event.target;
if (req.readyState == 4) {
if (req.status != 200) {
alert('Can\'t download page!');
return;
}
me.formbox = req.responseXML.getElementById('editform');
imForm.status('Form received');
var temp = me.formbox['wpTextbox1'].value;
if (picmark.loadAll) {
imForm.imTextbox.value = temp + imForm.imTextbox.value;
if (imForm.imTextbox.setSelectionRange)
imForm.imTextbox.setSelectionRange(temp.length - 1, imForm.imTextbox.value.length);
}
imForm.setEnabled(true);
//basic regexes from [[User:Quarl/redirector.js]], but some altered
if (new RegExp('^[\\s\\n]*$').test(temp)) {
alert('Note: page is empty; this could mean that it doesn\'t exist.');
}
if (temp.match(/^\s*#REDIRECT \[\[([^\]]+)\]\]/i)) {
var temp2 = RegExp.$1;
var temp3 = confirm(me.page + ' redirects to ' + temp2 + '. Edit that page instead?');
if(temp3) {
me.page = temp2;
me.stage = 0;
imUpdate();
}
}
};
};
req.send(null);
return req;
};
this.setFormbox = function() {
imForm.status('Setting text');
if (picmark.loadAll)
this.formbox['wpTextbox1'].value = this.text;
else
this.formbox['wpTextbox1'].value += this.text;
this.formbox['wpSummary'].value = this.summary;
this.formbox['wpMinoredit'].checked = this.minor;
this.formbox['wpWatchthis'].checked = this.watch;
this.stage++;
imUpdate();
};
this.submitFormbox = function() {
var fields = [
'wpSection', 'wpStarttime', 'wpEdittime', 'wpScrolltop',
'wpTextbox1', 'wpSummary', 'wpMinoredit', 'wpWatchthis',
'wpEditToken' ];
var e;
var contquery = '';
for (var i in fields) {
e = this.formbox[fields[i]];
if (e && (e.type != 'checkbox' || e.checked)) {
contquery += '&' + fields[i] + '=' + encodeURIComponent(e.value);
}
}
contquery = contquery.substring(1) + '&wpIgnoreBlankSummary';
var url = this.formbox.action;
var req = sajax_init_object();
var me = this;
imForm.status('Submitting form');
req.open("POST", url, true);
req.overrideMimeType('text/xml');
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", contquery.length);
req.setRequestHeader("Connection", "close");
req.onload = function(event) {
var req = event.target;
if (req.readyState == 4) {
imForm.status('Edit has been made');
me.stage++;
templateStage++;
imUpdate();
}
};
req.send(contquery);
};
}
//getTemplateText() and getConfirmedText() removed from here
//former was too complicated
//latter was replaced by the form, textbox and such
function fillInVars(text) {
var tickerArr = [];
var tickerText;
while (true) {
tickerArr = [text.indexOf('<<'), text.indexOf('>>')];
if (tickerArr[0] == -1 || tickerArr[1] == -1) {
break;
}
else {
tickerText = text.substring(tickerArr[0], tickerArr[1] + 2)
if (picmark.popupBox) {
text = text.replace(tickerText, prompt(tickerText.substring(2, tickerText.length - 2) + ':', '') || '')
}
else {
text = text.replace(tickerText, '');
}
}
}
return text;
}
String.prototype.imReplace = function(message) {
return this.replace('__IMAGE__', wgTitle).replace('__AUTHOR__', uploader)
}
addOnloadHook(imInit);
//necessary so templates don't subst in source → </pre>