FANDOM


//
/*jshint browser:true jquery:true curly:false laxbreak:true smarttabs:true bitwise:false */
 
/*global mediaWiki UserTagsJS */
 
 
 
 
//
 
// MODULE: New Users
 
// Tags users who have not met a minimum threshold
 
//
 
// Editcount is broken (Sep-2012). It returns nonsense values.
 
// Using the Special:Editcount page is more flexible (namespace filtering) and accurate.
 
// Unfortunately, the AJAX is manual since Sledge can't handle non-queries.
 
// NOTE: Parse produces *localised* HTML so you get stuff like "<p>1,000\n</p>"
 
//
 
// By user request: We accept a custom computation function for this so that they can do
 
// stuff like "edits < 30 || days < 14 || (days < 7 && edits < 10)". Also transitively
 
// enables AND instead of just OR.
 
//
 
UserTagsJS.extensions.newuser = (function($, mw, Date) {
 
"use strict";
 
return {
 
start: function(config, username, logger/*, lang*/) {
 
// Anonymous users don't work with Special:Editcount, it returns blank
 
if (mw.util.isIPv4Address(username) || mw.util.isIPv6Address(username)) return;
 
 
 
 
// The 10/4 default matches Wikia's config for autoconfirmed
 
config = $.extend({ edits: 10, days: 4 }, config);
 
 
 
 
// Convert to a computation function if there isn't one
 
if (typeof(config.computation) !== 'function') {
 
var minEdits = config.edits | 0;
 
var minDays = config.days | 0;
 
// Sanity. Give up if both days and edits are zero.
 
if (minEdits < 1 && minDays < 1) return;
 
 
 
 
config.computation = function(days, edits) {
 
return days < minDays || edits < minEdits;
 
};
 
}
 
this._logger = logger;
 
 
 
 
// Our promises for the async data we need to do this calculation
 
var daysPromise = this._daysPromise = $.Deferred(),
 
 editsPromise = this._editsPromise = $.Deferred();
 
 
 
 
// Sanity, convert namespace string to number.
 
var namespace = config.namespace;
 
if (namespace && typeof(namespace) !== 'number') {
 
namespace = mw.config.get('wgNamespaceIds')[namespace];
 
if (typeof(namespace) !== 'number') {
 
logger.err('Invalid namespace:', config.namespace);
 
namespace = null;
 
}
 
}
 
 
 
 
// Performance optimising the common case.
 
// In Oasis, with no namespace configuration, we can just scrape the DOM contributions
 
// counter instead of AJAXing which is WAY faster (especially since we're manually
 
// AJAXing instead of using Sledge)
 
if ((typeof(namespace) === 'number' && namespace === namespace) // n === n is false for NaN
 
|| ({oasis:1, wikia:1})[mw.config.get('skin')] !== 1
 
) {
 
this._doCustomAjax(username, namespace);
 
} else {
 
$($.proxy(this._onDomReady, this, username));
 
}
 
 
 
 
// Start the core AJAX if needed and return the promise to delay further
 
// processing until we're ready.
 
return {
 
ajax: {
 
type: 'contributions',
 
limit: 1,
 
dir: 'newer',
 
prop: ['timestamp']
 
},
 
promise: $.when(daysPromise, editsPromise).then(function(a, b) {
 
try {
 
return config.computation(a, b) && ['newuser'];
 
} catch(e) {
 
logger.err('Custom Computation function exploded!', e, e.stack);
 
return $.Deferred().reject();
 
}
 
})
 
};
 
},
 
_onDomReady: function(username, $) {
 
var $node = $('#UserProfileMasthead .masthead-info .tally > em');
 
if ($node.length) {
 
var num = $node.text().replace(/[^\d]/g, '');
 
if (num) {
 
return this._editsPromise.resolve(+num);
 
}
 
// WTF?
 
this._logger.err('Oasis masthead gave us junk instead of a number:', $node.text(), '(Falling back to AJAX)');
 
} else {
 
// Er... crap
 
this._logger.err('Cannot find Oasis masthead to scrape counter! Falling back to AJAX');
 
}
 
return this._doCustomAjax(username, null);
 
},
 
_doCustomAjax: function(username, namespace) {
 
// Construct the wikitext fragment to invoke the Special:Editcount pseudo-template
 
var text = '{{Special:Editcount/' + username;
 
if (typeof(namespace) === 'number') {
 
text += '/' + namespace;
 
}
 
text += '}}';
 
 
 
 
// Issue our AJAX to run the parser.
 
// I'm not using .then() as we need to wait for the generate() callback before
 
// we can actually issue a response.
 
var editsPromise = this._editsPromise, logger = this._logger;
 
this._selfajax = $.ajax({
 
url: mw.util.wikiScript('api'),
 
data: {
 
action: 'parse',
 
format: 'json',
 
uselang: 'en', // Force English so we don't have to deal with non-English digit chars
 
text: text,
 
prop: 'text',
 
disablepp: 1 // Disable the preprocessor report (HTML comment at end)
 
},
 
dataType: 'json'
 
})
 
.done(function(json) {
 
if (json && json.parse && json.parse.text) {
 
var num = $(document.createElement('div')).html(json.parse.text['*']).text().replace(/[^\d]/g, '');
 
if (num) {
 
editsPromise.resolve(+num);
 
return;
 
}
 
}
 
logger.err('Got a bad response from Special:Editcount:', json);
 
editsPromise.reject();
 
})
 
.fail(function(xhr, status, exception) {
 
logger.err('AJAX fail:', xhr.status, status, exception);
 
editsPromise.reject();
 
})
 
;
 
},
 
generate: function(json) {
 
json = json.query.usercontribs[0];
 
if (!json) return this.generateFailed();
 
// Calculate days since their oldest (i.e. first) edit was made
 
this._daysPromise.resolve((Date.now() - Date.parseISO8601(json.timestamp)) / 864e5);
 
},
 
generateFailed: function() {
 
if (this._selfajax) this._selfajax.abort();
 
this._daysPromise.reject();
 
}
 
};
 
})(jQuery, mediaWiki, Date);
 
 
 
 
//