MediaWiki:QIhelperNew.js
Jump to navigation
Jump to search
Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
![]() |
Documentation for this user script can be added at MediaWiki:QIhelperNew. |
- Report page listing warnings and errors.
function qihelper2() {
var tempRE = /\{\{QICbotMove\|([^\}]+)\}\}/,
imfileRE = /^\s*([Ii]mage:|[Ff]ile:)(.*)$/,
lastCat = null,
QIHVersion = 2,
categories = [
'- select -',
'Subject/Amoeboids',
'Subject/Animals/Amphibians',
'Subject/Animals/Annelida',
'Subject/Animals/Platyhelminthes',
'Subject/Animals/Arthropods/Spiders, Mites, Horseshoe crabs (Chelicerata)',
'Subject/Animals/Arthropods/Dragonflies and Damselflies (Odonata)',
'Subject/Animals/Arthropods/Grasshoppers, Crickets, Mantis, Bugs etc (Hemipterodea)',
'Subject/Animals/Arthropods/Beetles (Coleoptera)',
'Subject/Animals/Arthropods/Ants, Bees & Wasps (Hymenoptera)',
'Subject/Animals/Arthropods/Butterflies and Moths (Lepidoptera)',
'Subject/Animals/Arthropods/Flies & Mosquitoes (Diptera)',
'Subject/Animals/Arthropods/Mayflies (Ephemeroptera)',
'Subject/Animals/Arthropods/Mecoptera',
'Subject/Animals/Arthropods/Raphidioptera',
'Subject/Animals/Arthropods/Other insects',
'Subject/Animals/Arthropods/Myriapoda',
'Subject/Animals/Arthropods/Crustaceans',
'Subject/Animals/Birds',
'Subject/Animals/Cnidaria',
'Subject/Animals/Echinoderms',
'Subject/Animals/Fish',
'Subject/Animals/Mammals/Domesticated',
'Subject/Animals/Mammals/Wild',
'Subject/Animals/Mammals/Zoo',
'Subject/Animals/Molluscs',
'Subject/Animals/Reptiles',
'Subject/Animated',
'Subject/Architecture/Agricultural and Industrial',
'Subject/Architecture/Cityscapes',
'Subject/Architecture/Close-ups',
'Subject/Architecture/Feudal (Castles, Palaces)',
'Subject/Architecture/Interior',
'Subject/Architecture/Other',
'Subject/Architecture/Public Buildings',
'Subject/Architecture/Religious/Churches',
'Subject/Architecture/Religious/Other',
'Subject/Architecture/Residential Buildings',
'Subject/Architecture/Ruins',
'Subject/Architecture/Towers and Masts',
'Subject/Architecture/Transport Infrastructure/Bridges',
'Subject/Architecture/Transport Infrastructure/Other',
'Subject/Astronomy',
'Subject/Events',
'Subject/Food and drink',
'Subject/Fungi/Fungi',
'Subject/Fungi/Lichen',
'Subject/Microscopic',
'Subject/Natural phenomena',
'Subject/Non photographic media',
'Subject/Objects/Cameras, Optics and Microscopes',
'Subject/Objects/Closeups of Structures',
'Subject/Objects/Electronics & electrical',
'Subject/Objects/Geological objects',
'Subject/Objects/Geological objects/Fossils',
'Subject/Objects/Geological objects/Rocks, Minerals, Elements',
'Subject/Objects/Household Items',
'Subject/Objects/Industrial',
'Subject/Objects/Other',
'Subject/Objects/Statues, Monuments and Plaques',
'Subject/Objects/Transport and Vehicles/Aerial Trams',
'Subject/Objects/Transport and Vehicles/Automobiles',
'Subject/Objects/Transport and Vehicles/Balloons, Aeroplanes, Helicopters etc',
'Subject/Objects/Transport and Vehicles/Boats and Ships',
'Subject/Objects/Transport and Vehicles/Cycles and Motorcycles',
'Subject/Objects/Transport and Vehicles/Other vehicles',
'Subject/Objects/Transport and Vehicles/Railway',
'Subject/Objects/Transport and Vehicles/Steam Powered',
'Subject/People',
'Subject/People/Concerts',
'Subject/Places/Man made structures',
'Subject/Places/Man made structures/Panorama',
'Subject/Places/Mixed',
'Subject/Places/Mixed/Panorama',
'Subject/Places/Natural structures',
'Subject/Places/Natural structures/Panorama',
'Subject/Plant life/Ferns and Horsetails',
'Subject/Plant life/Flowers',
'Subject/Plant life/Foliage etc',
'Subject/Plant life/Fruit, berries, seeds etc',
'Subject/Plant life/Mosses and Liverworts',
'Subject/Plant life/Trees',
'Subject/Sports',
'Subject/Sunsets',
'Subject/Works of art',
'Technical/Color',
'Technical/Composition',
'Technical/Depth of field',
'Technical/Exposure',
'Technical/Movement control',
'Technical/Perspective',
'Technical/Proportion'
],
dropdown = $('<select></select>').css('width','100%'),
ls = 'localStorage' in window ? window.localStorage : null,
currSel = {},
savedSel = {},
found = {};
// restore last categorization selections
if (ls) {
try {
currSel = JSON.parse(ls.getItem('QIHelper_selections')) || {};
} catch(e) {
ls.removeItem('QIHelper_selections');
}
}
// build the dropdown menu prototype
for( var key in categories ) {
dropdown.append( $('<option></option>').text(categories[key]).attr('name',categories[key]) );
}
dropdown.change(function(e) {
// remember lat used category
lastCat = $(e.target).val();
$('#lastCat').text(lastCat);
// store the selected index of the current dropdown in localStorage
if (ls) {
var name = $(e.target).parent().data('qi_image') || null;
currSel[name] = $('option:selected',$(e.target)).index();
ls.setItem('QIHelper_selections', JSON.stringify(currSel));
}
});
// Generate the User Interface to replace the textbox
function buildGallery() {
var textbox = $('#wpTextbox1').hide(),
wppreview = $('#wikiPreview');
if( wppreview.length === 0 ) return;
$('#editpage-copywarn').hide();
$('#toolbar').hide();
$('#wpPreview').hide();
var preview = $('<div id="qigallery"></div>')
.insertAfter(wppreview),
advanced = $('<div class="qihelper2adv"></div>')
.insertAfter(wppreview);
var wikitext = textbox.text(),
lines = wikitext.split( "\n" ),
line, lline, pipe, file, desc, img, div, link, select,
inGallery = false,
versionTag = '<!-- QIHELPER_VERSION='+QIHVersion+' ', versionOk = false,
m, filematch;
for (var key in lines) {
line = lines[key];
lline = line.toLowerCase();
// check needed version
versionOk |= line.substr(0,versionTag.length) == versionTag;
if (lline.search('<gallery') > -1)
inGallery = true;
else if (lline.search('</gallery>') > -1)
inGallery = false;
else if (inGallery) {
m = imfileRE.exec(line);
if (m !== null && m.length == 3) {
filematch = m[2];
pipe = filematch.indexOf('|');
if( pipe > 0 ) {
file = filematch.substring(0, pipe);
desc = filematch.substring(pipe + 1);
} else {
file = filematch;
desc = '';
}
// register all seen files on the page so we can prune the cache
found[file] = true;
select = dropdown.clone(true);
div = $('<div></div>')
.append(
$('<a></a>').attr('href', '//commons.wikimedia.org/wiki/File:' + file)
.append($('<img>').attr('src', '//commons.wikimedia.org/wiki/Special:Redirect/file/' + encodeURIComponent(file) + '?width=150'))
)
.append($('<br>'))
.append(select)
.click(function(e) {
if (e.ctrlKey || e.metaKey) {
if (lastCat)
$(e.currentTarget).find('select').val(lastCat);
e.preventDefault();
}
});
var savedCat = null;
if (tempRE.test(desc)) {
tempRE.exec( desc );
savedCat = RegExp.$1;
}
var cachedCat = file in currSel ? categories[currSel[file]] : null;
if (cachedCat) {
// restore category selection from cache
select.val(cachedCat);
if (cachedCat === savedCat) {
// the cache is up to date saved data
delete currSel[file];
div.addClass('qihelper2dne');
} else {
if (savedCat) {
// conflict between set and saved category
div.addClass('qihelper2con');
$('option[name="' + savedCat + '"]', select).css('font-weight', 'bold');
savedSel[file] = savedCat;
} else {
// no value saved yet
div.addClass('qihelper2rst');
}
}
}
else if (savedCat) {
// set category from saved version
select.val(savedCat);
div.addClass('qihelper2dne');
}
else {
div.addClass('qihelper2pnd');
}
div.data('qi_image', file);
preview.append(div);
}
}
}
// prune the cache and throw out irrelevant entries for old images
for (file in currSel) {
if (!(file in found)) {
delete currSel[file];
}
}
if (!versionOk) {
preview.text('Wrong QIHelper script version loaded. Please purge your browser cache!');
}
wppreview.css('display', 'block');
// Build advanced options menu
advanced
.append($('<input type="button" value="Hide processed images">').click(function(){$('div.qihelper2dne').hide()}))
.append($('<a href="//commons.wikimedia.org/wiki/MediaWiki_talk:QIhelperNew.js#Quick_Apply_Category" target="qahelp">Quick apply</a>: <span id="lastCat"><i>none</i></span>'));
}
// translate changes in the GUI back onto the wikitext of the page
function commitChanges() {
var divs = $('div.qihelper2dne,div.qihelper2pnd'),
textbox = $('#wpTextbox1'),
wikitext = textbox.text(),
newwikitext = '',
lines = wikitext.split('\n'),
line, lline, pipe, file, desc,
inGallery = false,
results = {},
cntDone=0, cntAll=0,
m, filematch;
divs.each(function(i, e) {
file=$(e).data('qi_image');
if (file) {
results[file] = $(e).find('select').val();
console.log(file, results[file]);
}
});
for (var key in lines) {
line = lines[key];
lline = line.toLowerCase();
if (lline.search('<gallery') > -1)
inGallery = true;
else if (lline.search('</gallery>') > -1)
inGallery = false;
else if (inGallery) {
m = imfileRE.exec(line);
if (m !== null && m.length == 3) {
filematch = m[2];
pipe = filematch.indexOf('|');
if (pipe > 0) {
file = filematch.substring(0, pipe);
desc = filematch.substring(pipe + 1);
} else {
file = filematch;
desc = '';
}
// already tagged?
if (results[file]) {
if (results[file] != '- select -' && results[file] != '-select-') {
// change tag
line = 'File:' + file.replace( /[\n\r]/, '' ) + '|' + '{{QICbotMove|' + results[file] + '}}' + desc.replace(tempRE, '');
cntDone++;
} else {
// remove tag
line = 'File:' + file.replace(/[\n\r]/, '');
}
}
cntAll++;
}
}
newwikitext += line + "\n";
}
textbox.text(newwikitext);
$('#wpSummary').val('Categorizing new QIs using [[MediaWiki:QIhelperNew.js]] (' + cntDone + '/' + cntAll + ' done)');
}
// add css classes
$('<style>div.qihelper2pnd { width:300px; float:left; text-align:center; margin:2px; padding:2px; border: 2px solid red }'+
' div.qihelper2dne { width:300px; float:left; text-align:center; margin:2px; padding:2px; border: 2px solid green }'+
' div.qihelper2rst { width:300px; float:left; text-align:center; margin:2px; padding:2px; border: 2px solid yellow }'+
' div.qihelper2con { width:300px; float:left; text-align:center; margin:2px; padding:2px; border: 2px solid orange }'+
' div.qihelper2adv { width:100%; padding:2px; border: 1px solid gray; background-color: lightblue }</style>')
.appendTo($('html > head'));
// set up everything
var editform = $('#editform');
if (editform.length === 0) return;
$('#wpSave,#wpDiff').click(commitChanges);
buildGallery();
}
if (mw.config.get('wgAction') == 'edit') $(qihelper2);