User:YuviPanda/AssessmentBar.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | This user script seems to have a documentation page at User:YuviPanda/AssessmentBar and an accompanying .css page at User:YuviPanda/AssessmentBar.css. |
//<nowiki>
(function() {
var MONTH_NAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
// Only on mainspace articles and mainspace talk pages
if(mw.config.get('wgNamespaceNumber') > 1) {
return;
}
var requires = [
'jquery.ui',
'jquery.ui',
'jquery.ui',
'mediawiki.api',
'//wiki.riteme.site/w/index.php?title=User:YuviPanda/js-utils/underscore.js&action=raw&ctype=text/javascript',
'//wiki.riteme.site/w/index.php?title=User:YuviPanda/js-utils/ClientTemplate.js&action=raw&ctype=text/javascript'
];
var cssPath = '//wiki.riteme.site/w/index.php?title=User:YuviPanda/AssessmentBar.css&action=raw&ctype=text/css';
// Loaded in externally
var projectData = window.assBar.projectData;
function getArticleTitle(title) {
// If in a talk page, returns original page title
// Else returns title unmodified
return title.replace(/^Talk:/i, "");
}
function loadScripts(scripts) {
var deferreds = [];
$.each(scripts, function(i, script) {
if(script.match(/^(http:|https:|\/\/)/)) {
// External script, use $.getScript
deferreds.push($.getScript(script));
} else {
// Use mw.using, convert callbacks to deferreds
var d = $.Deferred();
mw.loader.using(script, function() {
d.resolve();
}, function(err) {
d.reject(err);
});
deferreds.push(d);
}
});
return $.when.apply($, deferreds);
}
var extractorRegex = new RegExp("{{(?:" + projectData.inputTemplates.join('|') + ")\\s*(?:\\s*\\|\\s*.*=?.*\\s*)*\\s*}}");
var ass = null; // Current assessment
var api = null; // API wrapper
var templates = null; // ClientTemplate instance
function Assessment(project, data, rawText, title) {
this.project = project;
this.data = data;
this.rawText = rawText;
this.title = title
}
Assessment.prototype.toTemplate = function() {
var template;
var curDate = new Date();
var dateString = MONTH_NAMES[curDate.getMonth()] + " " + curDate.getUTCFullYear();
this.data['assess-date'] = dateString;
template = "{{" + projectData.outputTemplate;
$.each(this.data, function(key, value) {
template += "|" + key + "=" + value;
});
template += "}}";
return template;
}
Assessment.prototype.getDisplayData = function() {
// Defaults in case they don't exist
var displayData = {
importance: "unassessed",
'class': "unassessed"
};
$.each(this.data, function(key, value) {
if(key === 'importance' || key === 'class') {
if(!$.trim(value)) {
value = 'unassessed';
}
}
if(value === 'yes' || value === 'y') {
value = 'unassessed';
}
displayData[key] = value;
});
return displayData;
}
Assessment.prototype.getSubProjects = function() {
var subProjects = {};
$.each(this.data, function(key, value) {
if(value.match(/y(es)?/i)) {
value = "unassessed";
}
if($.inArray(key.replace(/-importance$/, ''), projectData.subProjects) != -1 && value != "" && !subProjects[key]) {
subProjects[key.replace(/-importance$/, '')] = value;
}
});
return subProjects;
}
Assessment.prototype.getActionItems = function() {
var actionItems = {};
var that = this;
$.each(projectData.actionNeeded, function(i, action) {
actionItems[action] = (that.data[action] === "yes");
});
return actionItems;
}
Assessment.prototype.removeSubProject = function(subProject) {
delete this.data[subProject];
delete this.data[subProject + "-importance"];
}
Assessment.prototype.addSubProject = function(subProject, importance) {
this.data[subProject] = "yes";
this.data[subProject + "-importance"] = importance;
}
Assessment.prototype.save = function() {
var d = $.Deferred();
// Kill 'auto' fields
delete this.data['auto'];
var text = this.rawText.replace(extractorRegex, this.toTemplate());
api.post({
action: 'edit',
title: 'Talk:' + this.title,
summary: 'Changed assessment status for ' + projectData.name + ' (via [[User:YuviPanda/AssessmentBar|AssessmentBar]])',
text: text,
token: mw.user.tokens.get('csrfToken')
}, {
ok: function(data) {
d.resolve(data);
console.log('Success!');
}
});
return d;
}
Assessment.fromWikiText = function(text, title) {
var match = text.match(extractorRegex);
if(match === null) {
return null;
}
var cleanTemplate = match[0].replace(/{|}|\n/g, '');
var parts = cleanTemplate.split('|');
var tags = {};
for(var i = 1; i < parts.length; i++) {
console.log(parts[i]);
var tag = parts[i].split('=');
tags[$.trim(tag[0])] = $.trim(tag[1]).toLowerCase();
}
return new Assessment(parts[0], tags, text, title);
}
function bindAssBarEvents() {
$("#assbar-save").click(function() {
var that = this;
$(that).text("Saving...");
ass.save().done(function() {
$(that).text("Save");
if(mw.config.get('wgPageName').match(/^Talk/)) {
location.reload(true); // Hard refresh
}
});
return false;
});
$(".assbar-action-item").change(function() {
var action = $(this).parents(".assbar-item").attr('data-action');
if($(this).is(':checked')) {
ass.data[action] = 'yes';
} else {
delete ass.data[action];
}
});
$(".assbar-importance, .assbar-class").change(function() {
var project = $(this).parents(".assbar-item").attr('data-project');
var value = $(this).val().replace("unassessed", "");
if(project == projectData.name) {
// Main Project
var what = $(this).hasClass("assbar-importance") ? "importance" : "class";
ass.data[what] = value;
} else {
// One of the sub projects
ass.data[project] = "yes";
ass.data[project + "-importance"] = value;
}
});
$("#assbar-new-subproject-name").autocomplete({
source: projectData.subProjects,
autoFocus: true
});
$("#assbar-add-new-subproject").click(function() {
$("#assbar-new-subproject-dialog").dialog({
modal: true,
title: "Add new Sub Project",
buttons: {
"Add": function() {
var subProject = $("#assbar-new-subproject-name").val();
var importance = $("#assbar-new-subproject-importance").val();
if($.inArray(subProject, projectData.subProjects) === -1) {
alert("Invalid subproject chosen!");
return;
}
ass.addSubProject(subProject, importance.replace("unassessed", ""));
var dialog = this;
templates.getTemplate('NewSubProject').done(function(template) {
var displayData = {
project: projectData,
subProject: subProject,
importance: importance
};
$(template(displayData)).appendTo("#assbar-subprojects-list");
$(dialog).dialog("close");
});
}
}
});
return false;
});
$(".assbar-subproject-delete").click(function() {
var subProject = $(this).parents(".assbar-item").attr('data-project');
var sure = confirm("Do you want to delete the sub project " + subProject + "?");
if(sure) {
ass.removeSubProject(subProject);
$(this).parents(".assbar-item").fadeOut();
}
return false;
});
}
mw.loader.load(cssPath, 'text/css');
loadScripts(requires).done(function() {
api = new mw.Api();
templates = new ClientTemplate('User:YuviPanda/AssessmentBar');
$(function() {
var title = getArticleTitle(mw.config.get('wgPageName'));
api.get({
action: "parse",
page: 'Talk:' + title,
prop: 'wikitext'
}, {
ok: function(data) {
ass = Assessment.fromWikiText(data.parse.wikitext['*'], title);
if(!ass) {
return;
}
a = ass;
templates.getTemplate('Toolbar').done(function(template) {
var displayAss = {
project: projectData,
subProjects: ass.getSubProjects(),
actionItems: ass.getActionItems(),
data: ass.getDisplayData()
};
$(template(displayAss)).appendTo("body");
bindAssBarEvents();
});
}
});
});
});
})();
//</nowiki>