User:Rillke/MwJSBot.SVGXmlNSFixer.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 User:Rillke/MwJSBot.SVGXmlNSFixer. |
/*global jQuery:false, mediaWiki:false, MwJSBot:false, SVGXmlNSFixer:false */
/*jshint curly:false */
/// JSHint valid
(function($, mw) {
"use strict";
if (null === mw.loader.getState('mediawiki.commons.MwJSBot')) mw.loader.implement('mediawiki.commons.MwJSBot', [
"//commons.wikimedia.org/w/index.php?action=raw&ctype=text/javascript&title=User:Rillke/MwJSBot.js"
], { /*no styles*/ }, { /*no messages*/ });
try {
mw.loader.register('mediawiki.commons.MwJSBot.SVGXmlNSFixer', '2013-04-03', ['mediawiki.commons.MwJSBot', 'ext.gadget.libAPI', 'mediawiki.user',
'json'
]); //
} catch (ex) { /* previously registerd */ }
mw.loader.implement('mediawiki.commons.MwJSBot.SVGXmlNSFixer', function() {
var jsb = new MwJSBot(),
sxnf = function(myContinueStore, myLogStore) {
this.lastQuery = {};
this.cycleCounter = 0;
this.myContinueStore = myContinueStore || "User:Rillke/botXMLNSfixer.js";
this.myLogStore = myLogStore || "User:Rillke/botXMLNSfixer/log";
jsb.log("Hello! I am your MwJSBot.SVGXmlNSFixer object.");
};
sxnf.fn = sxnf.prototype;
$.extend(true, sxnf.fn, {
query: {
action: 'query',
list: 'allimages',
rawcontinue: 1,
aiprop: 'mime|url|size',
//aimime: 'image/svg+xml', // disabled in miser mode
ailimit: 500
},
install: function() {
var s = this;
$(mw.util.addPortletLink('p-tb', '#', "Start bot", 't-startbot')).click(function(e) {
e.preventDefault();
s.start();
});
},
start: function() {
var s = this;
jsb.$loadContinue(this.myContinueStore).done(function(r) {
s.lastQueryContinue = s.loadedQueryContinue = JSON.parse(r);
jsb.$continueQuery(s.query, {
'query-continue': s.loadedQueryContinue
}).done($.proxy(s.gotImages, s));
}).fail($.proxy(s.run, s));
},
// First time the bot starts only
run: function() {
mw.libs.commons.api.query(this.query, {
method: 'POST',
cache: false,
cb: $.proxy(this.gotImages, this),
// r-result, query, text
errCb: function(t, r, q) {
jsb.fail("Failed starting query.");
}
});
},
gotImages: function(r, q) {
this.svgList = $.grep(r.query.allimages, function(el) {
return el.mime === 'image/svg+xml' && el.size < 9437184; // skip files bigger than 9MB (this will freeze the broser while parsing)
});
this.result = r;
this.processedImageList();
this.cycleCounter += this.svgList.length;
if (this.cycleCounter > 400) {
this.cycleCounter = 0;
if (this.lastQueryContinue) jsb.$saveContinue(this.myContinueStore, JSON.stringify(this.lastQueryContinue));
this.lastQueryContinue = r['query-continue'];
}
},
processedImageList: function() {
if (0 === this.svgList.length) {
return jsb.$continueQuery(this.query, this.result).done($.proxy(this.gotImages, this));
}
var svgInfo = this.svgInfo = this.svgList.pop(),
title = this.title = svgInfo.title,
url = this.url = svgInfo.url;
jsb.log("Downloading", title, " from ", url);
jsb.$downloadXMLFile(url).done($.proxy(this.gotSVGRawData, this)).fail($.proxy(jsb.fail, jsb));
},
gotSVGRawData: function(xml) {
if ('object' !== typeof xml) {
jsb.$addLogline(this.myLogStore, "Invalid XML. Can't parse! [[:" + this.title + ']]', 'invalidxmlerror');
jsb.fail("Invalid XML. Not an object! But ", typeof xml, this.title, " from ", this.url);
return this.processedImageList();
}
var $xml = $(xml),
$svg = $xml.find('svg').first();
if (0 === $svg.length) $svg = $xml.find("svg:svg").first();
if (0 === $svg.length) {
jsb.warn(this.title, " does not contain an SVG elem. ", this.url);
jsb.$addLogline(this.myLogStore, "No SVG root! [[:" + this.title + ']] [' + this.url + ' file]', 'nosvgrooterror');
return this.processedImageList();
}
if (!$svg.attr("xmlns") && !$svg.attr("xmlns:svg")) {
// default namespace/Null-namespace is not SVG!!!
this.fixXMLNS($svg, $xml);
} else {
this.processedImageList();
}
},
fixXMLNS: function($svg, $xml) {
var s = this;
// Firefox prevents retargeting the namespace when serializing the XML-DOM
$svg.attr('randomstupidattribute', 'randomstupidvalue');
// Why not also adding the xlink-namespace if it is not there?
if (!$svg.attr('xmlns:xlink')) $svg.attr('xmlns:xlink', 'http://www.w3.org/1999/xlink');
var xml = jsb.stringFrom$xml($xml)
.replace('randomstupidattribute', 'xmlns')
.replace('randomstupidvalue', 'http://www.w3.org/2000/svg');
jsb.log(this.title, ' is being uploaded: ', xml);
jsb.multipartMessageForUTF8Files()
.appendPart('format', 'json')
.appendPart('action', 'upload')
.appendPart('filename', this.title)
.appendPart('comment', 'MW-JS-BOT: Adding XMLNS attribute to <svg> node to ensure it is rendered in all browsers.')
.appendPart('file', xml, this.title)
.appendPart('ignorewarnings', 1)
.appendPart('token', mw.user.tokens.get('csrfToken'))
.$send().done(function(r) {
s.processedImageList();
if ('string' === typeof r) r = JSON.parse(r);
if ('object' === typeof r) {
if (r.upload && 'Success' === r.upload.result) {
jsb.$addLogline(s.myLogStore, "SUCCESS: [[:" + s.title + ']].', 'success');
} else {
jsb.$addLogline(s.myLogStore, "Failed to re-upload [[:" + s.title + ']]. API response type error.', 'uploadnosuccesserror');
}
} else {
jsb.$addLogline(s.myLogStore, "Failed to re-upload [[:" + s.title + ']]. API response type error.', 'uploadresponseerror');
}
}).fail(function(x) {
jsb.fail(x);
jsb.$addLogline(s.myLogStore, "Failed to re-upload [[:" + s.title + ']]. Server error.', 'uploadservererror');
});
}
});
window.SVGXmlNSFixer = sxnf;
// Instantiate our new class right away
var sxnfInst = new SVGXmlNSFixer();
sxnfInst.install();
}, { /*no styles*/ }, { /*no messages*/ });
// And finally load ourself
mw.loader.load('mediawiki.commons.MwJSBot.SVGXmlNSFixer');
}(jQuery, mediaWiki));