User:Md gilbert/vte.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:Md gilbert/vte. |
// global variables, as required
var vte = {
// initialize - application constructor
initialize: function() {
// Create the VTE button
var $btn = $(
"<div class='vectorMenu' id='p-vte'>" +
" <h3><span>VTE</span></h3>" +
"</div>"
).attr("title", "Open the Virtual Team Explorer");
// Add the button to the left of the search box
$("#p-search").before($btn);
// Define our click action
$("#p-vte").on("click", function() {
console.log("opening vte");
vte.renderOverlay();
});
}, // end initialize
// renderOverlay - draws the initial vte lightbox
renderOverlay: function() {
// If the window already exists, just display it
if ( $("#vte-window").length > 0 ) {
$("#vte-window").show();
return;
}
// Otherwise, create the vte window
var $vteWindow = $(
"<div id='vte-window'>" +
" <div id='vte-window-left'>" +
" <div id='vte-window-left-project' />" +
" <div id='vte-window-left-nav' />" +
" </div>" +
" <div id='vte-window-right'> " +
" <div id='vte-window-right-title' />" +
" <div id='vte-window-right-tool' />" +
" <div id='vte-window-right-content' />" +
" </div>" +
" <div style='clear: both;'></div>" +
"</div>"
);
// Create and style the main vte window
$vteWindow.css(s_vteWindow);
$("#content").append($vteWindow);
$("#vte-window-left").css(s_vteWindowLeft);
$("#vte-window-left-project").css(s_vteWindowLeftProject);
$("#vte-window-left-nav").css(s_vteWindowLeftNav);
$("#vte-window-right").css(s_vteWindowRight);
$("#vte-window-right-title").css(s_vteWindowRightTitle);
$("#vte-window-right-tool").css(s_vteWindowRightTool);
$("#vte-window-right-content").css(s_vteWindowRightContent);
// Fill in vte elements
vte.populateTitle();
vte.populateTool();
vte.populateProject();
vte.populateNav();
vte.populateContent();
// Add external libraries (d3)
// Add to head either https://raw.githubusercontent.com/mbostock/d3/master/d3.min.js or
// https://rawgit.com/mbostock/d3/master/d3.min.js ???
// http://alahele.ischool.uw.edu/d3.min.js
var head = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://alahele.ischool.uw.edu/d3.min.js';
head.appendChild(script);
},
// populateTitle - draws title bar content
populateTitle: function() {
var $vteTitle = $(
"<div id='vte-title'>Virtual Team Explorer</div>" +
"<div id='vte-title-actions'>" +
" <div id='vte-title-action-user' title='View user information'>" +
" <img src='/media/wikipedia/commons/0/0a/Gnome-stock_person.svg' width='15' height='15' style='padding: 5px;'/>" +
" </div>" +
" <div id='vte-title-action-settings' title='View VTE settings'>" +
" <img src='/media/wikipedia/commons/7/77/Gear_icon.svg' width='25' height='25'/>" +
" </div>" +
" <div id='vte-title-action-close' title='Close the VTE'>" +
" <img src='/media/wikipedia/commons/6/60/Close_icon.svg' width='25' height='25'/>" +
" </div>" +
"</div>"
);
// Attributions, via Wikimedia Commons:
// User: By GNOME icon artists (GNOME download / GNOME FTP) [GPL (http://www.gnu.org/licenses/gpl.html)]
// Gear: By MGalloway (WMF) (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)]
// Close: By MGalloway (WMF) (Own work) [CC-BY-SA-3.0 (http://creativecommons.org/licenses/by-sa/3.0)]
// Add the title and style the elements
$("#vte-window-right-title").html($vteTitle);
$("#vte-title").css(s_vteTitle);
$("#vte-title-actions").css(s_vteTitleActions);
$("#vte-title-action-user").css(s_vteTitleAction);
$("#vte-title-action-settings").css(s_vteTitleAction);
$("#vte-title-action-close").css(s_vteTitleAction);
// Add the actions
$("#vte-title-action-user").on("click", function() {
});
$("#vte-title-action-settings").on("click", function() {
});
$("#vte-title-action-close").on("click", function() {
console.log("closing the vte (will maintain current view).");
$("#vte-window").hide();
});
},
// populateTool - draws tool bar content
populateTool: function(tool) {
},
// populateProject - draws the project browser content
populateProject: function() {
// Fetch all projects or load from previous request
// TODO: allow cookies before deploying
var projects = []; // $.cookie( 'vte-projects' );
if (projects.length > 0) {
vte.drawProjectSelect(projects);
} else {
// Add loading message/icon
var $projectSelect = $(
"<div id='vte-project-select-label'>Enter a WikiProject to explore:</div>" +
"<div id='vte-project-select'>" +
" <input id='vte-project-select-input' type='text' placeholder='Loading WikiProject data...'/>" +
"</div>" +
"<div id='vte-project-select-multi' />"
);
// Add it
$("#vte-window-left-project").html($projectSelect);
// Style it
$("#vte-project-select").css(s_vteProjectSelect);
$("#vte-project-select-label").css(s_vteProjectSelectLabel);
$("#vte-project-select-input").css(s_vteProjectSelectInput);
// Make the request
//var url = 'http://tools.wmflabs.org/catscan2/catscan2.php?depth=10&categories=Active_WikiProjects&ns%5B4%5D=1&doit=1&format=json';
//var url = 'http://tools.wmflabs.org/catscan2/catscan2.php?depth=2&categories=Active_WikiProjects&ns%5B4%5D=1&topcats_no_talk=1&format=json&doit=1';
var url = 'http://alahele.ischool.uw.edu:8999/api/getProjects';
$.ajax({
url: url,
dataType: "json",
success: function(data, stat, xhr) {
//var projects = data["*"][0]["*"];
var projects = data["result"];
// TODO: Allow cookies before deploying
/*
$.cookie('vte-projects', projects, {
expires: 7, // expire in 7 days
path: '/' // domain-wide, entire wiki
});
*/
vte.drawProjectSelect(projects);
},
error: function(xhr, stat, err) {
console.error("Failed to request project data from catscan2: " + JSON.stringify(xhr));
$("#vte-window-left-project").html("Failed to request project data from catscan2: " + JSON.stringify(xhr));
},
complete: function() {
$("#vte-project-loading").remove();
},
});
}
},
// drawProjectSelect - called by populateProject after successfully requesting project data.
// Draws project select box
drawProjectSelect: function(projects) {
// Removing loading placeholder
$("#vte-project-select-input").attr("placeholder", "");
// Add the actions (everytime there's a key-up, update a box of matching projects)
$("#vte-project-select-input").on("keyup", function() {
// Empty the project selection div
$("#vte-project-select-multi").html("");
// Then for each project add to the dropdown if it matches the input text
$.each(projects, function(i,v) {
// Make sure the div exists
if ($("#vte-project-select-multi").length === 0) {
$("#vte-project-select").after("<div id='vte-project-select-multi' />");
}
$("#vte-project-select-multi").show();
//var t = projects[i]['a']['title'].toLowerCase().replace(/_/g, " ");
var t = projects[i]['p_title'].toLowerCase().replace(/_/g, " ");
var v = $("#vte-project-select-input").val().toLowerCase();
var ind = t.indexOf(v);
if (t.indexOf(v) != -1) {
//console.log("matches: " + projects[i]['a']['title'].replace("_", " "));
$("#vte-project-select-multi").append(
"<div class='vte-project-select-multi-proj' vte-p-id='" + projects[i]['p_id'] + "' " +
" vte-p-title='" + projects[i]['p_title'] + "' vte-p-seen='0' " +
" vte-p-touched='0' vte-p-created='" + projects[i]['p_created'] + "' >" +
projects[i]['p_title'].replace(/_/g, " ") +
"</div>"
);
}
});
if ($("#vte-project-select-multi").html() == "") {
$("#vte-project-select-multi").append(
"<div class='vte-project-select-multi-proj' style='color: #848484;'>No matching projects found</div>"
);
}
// Style the container and projects
$("#vte-project-select-multi").css(s_vteProjectSelectMulti);
$(".vte-project-select-multi-proj").css(s_vteProjectSelectMultiProj);
// Add hover color for project
$(".vte-project-select-multi-proj").hover(
function() {
$( this ).css("color", "#3B0B0B");
}, function() {
$( this ).css("color", "#000");
}
);
// Add click action to hide the list
$("body").on("click", function(evt) {
$("#vte-project-select-multi").hide();
});
// Add click action to load project summary
$(".vte-project-select-multi-proj").on("click", function(evt) {
var id = $(evt.currentTarget).attr("vte-p-id");
var title = $(evt.currentTarget).attr("vte-p-title");
var seen = $(evt.currentTarget).attr("vte-p-seen");
var touched = $(evt.currentTarget).attr("vte-p-touched");
var created = $(evt.currentTarget).attr("vte-p-created");
// Clear the project selection div
$("#vte-project-select-multi").remove();
$("#vte-project-select-input").val($(evt.currentTarget).html());
// Load the project summary
console.log("loading summary for project " + title + ", id: " + id);
$("#vte-window").data("vte-project", title);
$("#vte-window").data("vte-project-id", id);
vte.populateNav();
vte.drawProjectSummary(title, id, created);
});
});
},
// drawProjectSummary - draws summary information for the project once it is selected
// from the vte-project-select-multi dropdown
drawProjectSummary: function(title, id, created) {
// First clear any existing data in the content window and add summary divs
$("#vte-window-right-content").html(
"<div id='vte-window-right-content-summary'>" +
" <div id='vte-window-right-content-summary-title'>" +
$("#vte-window").data("vte-project") + " - Summary" +
" </div>" +
" <div id='vte-window-right-content-summary-p-edits'>" +
" Edits to Project (blue) and Project Talk (grey) pages" +
" <div style='height: 10px; width: 100%; border-bottom: 1px solid #000;'></div>" +
" <div id='vte-loading-edits' class='vte-loading'>Loading project edit data...</div>" +
" </div>" +
" <div id='vte-window-right-content-summary-pages'>" +
" Summary of pages in project (pages per namespace)" +
" <div style='height: 10px; width: 100%; border-bottom: 1px solid #000;'></div>" +
" <div id='vte-loading-pages' class='vte-loading'>Loading project pages...</div>" +
" </div>" +
" <div id='vte-window-right-content-summary-new'>" +
" Latest articles created in project" +
" <div style='height: 10px; width: 100%; border-bottom: 1px solid #000;'></div>" +
" <div id='vte-loading-new' class='vte-loading'>Loading project pages...</div>" +
" </div>" +
"</div>"
);
$("#vte-window-right-content-summary").css(s_vteWindowRightContentSummary);
$(".vte-loading").css(s_vteLoadingText);
$("#vte-window-right-content-summary-p-edits").css(s_vteWindowRightContentSummaryGraph);
$("#vte-window-right-content-summary-pages").css(s_vteWindowRightContentSummaryPages);
$("#vte-window-right-content-summary-new").css(s_vteWindowRightContentSummaryNew);
// Request summary data from our backend
var t = title.replace(/ /g, "_");
var sd = created.substr(0, 8);
var sw = vte.convertDateToWikiWeek(sd);
var url = "http://alahele.ischool.uw.edu:8999/api/getEdits?page=" + t + "&namespace=4|5&group=page|user|date&sd=" + sd;
$.ajax({
url: url,
dataType: "json",
success: function(data, stat, xhr) {
vte.drawProjectEdits(data, sw);
},
error: function(xhr, stat, err) {
console.error("Failed to request project edits: " + JSON.stringify(xhr));
$("#vte-window-right-content-summary").append("Failed to request project edits: " + JSON.stringify(xhr));
},
complete: function() {
$("#vte-loading-edits").remove();
},
});
// Request project pages
url = "http://alahele.ischool.uw.edu:8999/api/getProjectPages?project=" + t;
$.ajax({
url: url,
dataType: "json",
success: function(data, stat, xhr) {
vte.drawProjectPages(data);
// Once we've got project pages, also grab edit histories for the most recent pages created
var latest = {};
for (var p in data["result"]) {
for (var i in data["result"][p]) {
if (data["result"][p][i].tp_namespace != 1) continue;
latest[ data["result"][p][i].pp_id ] = data["result"][p][i].tp_title;
}
}
var keys = Object.keys(latest);
keys.sort( function(a,b) { return b-a; });
var aLatest = [];
for (var i in keys) {
if (i > 20) continue;
$("#vte-window-right-content-summary-new").append(
keys[i] + " - <a href='http://en.wikipedia.org/wiki/" + latest[ keys[i] ] + "'>" + latest[ keys[i] ] + "</a><br/>"
);
}
},
error: function(xhr, stat, err) {
console.error("Failed to request project pages: " + JSON.stringify(xhr));
$("#vte-window-right-content-summary").append("Failed to request project pages: " + JSON.stringify(xhr));
},
complete: function() {
$("#vte-loading-pages").remove();
$("#vte-loading-new").remove();
},
});
},
// drawProjectPages - draws a summary of pages in a project
drawProjectPages: function(data) {
// Structure the pages for vis
var pages = Array(16);
for (var i = 0; i < pages.length; i++) pages[i] = { "namespace": i, "count": 0 };
for (var p in data["result"]) {
for (var i in data["result"][p]) {
if (data["result"][p][i].tp_namespace > 15) continue;
pages[ data["result"][p][i].tp_namespace ].count += 1;
}
}
// D3 bar graph
var margin = {top: 10, right: 20, bottom: 30, left: 60},
w = $("#vte-window-right-content").width() - 30 - margin.right - margin.left,
h = 100 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, w], .1);
var y = d3.scale.linear()
.range([h, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(16, "");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(4, "");
var vis = d3.select("#vte-window-right-content-summary-pages")
.append("svg:svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(pages.map(function(d) { return d.namespace; }));
y.domain([0, d3.max(pages, function(d) { return d.count; })]);
vis.append("g")
.attr("transform", "translate(0," + h + ")")
.call(xAxis)
.append("text")
.attr("y", h-10)
.attr("x", w / 2)
.attr("dy", ".71em")
.style("text-anchor", "center")
.text("Namespace");
vis.append("g")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("# Pages");
vis.selectAll(".bar")
.data(pages)
.enter().append("rect")
.attr("x", function(d) { return x(d.namespace); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.count); })
.attr("height", function(d) { return h - y(d.count); });
},
// drawProjectEdits - draws summary edit information for a project and its corresponding Talk page
drawProjectEdits: function(data, sw) {
// Structure the edits
var ew = vte.convertDateToWikiWeek() - 2;
var talk_edits = Array(ew - sw);
var page_edits = Array(ew - sw);
for (var i = 0; i < talk_edits.length; i++) talk_edits[i] = 0;
for (var i = 0; i < page_edits.length; i++) page_edits[i] = 0;
for (var i in data["result"]) {
if (data["result"][i].rc_page_namespace % 2 == 0) page_edits[ data["result"][i].rc_wikiweek - sw ] += data["result"][i].rc_edits;
if (data["result"][i].rc_page_namespace % 2 == 1) talk_edits[ data["result"][i].rc_wikiweek - sw ] += data["result"][i].rc_edits;
}
// D3 sparkline graph
var w = $("#vte-window-right-content").width() - 20,
h = 80;
var t_max = d3.max(talk_edits);
var p_max = d3.max(page_edits);
var maxy = t_max > p_max ? t_max : p_max;
var y = d3.scale.linear()
.domain([0, maxy])
.range([0, h]);
var x = d3.scale.linear()
.domain([0, page_edits.length])
.range([0, w]);
var vis = d3.select("#vte-window-right-content-summary-p-edits")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
var g1 = vis.append("svg:g").attr("transform", "translate(2, " + h + ")");
var g2 = vis.append("svg:g").attr("transform", "translate(2, " + h + ")");
var line = d3.svg.line()
.x(function(d, i) {
return x(i);
})
.y(function(d) {
return -1 * y(d);
});
g1.append("svg:path").attr("d", line(page_edits)).style({"stroke": "#0000FF", "fill": "transparent"});
g2.append("svg:path").attr("d", line(talk_edits)).style({"stroke": "#545454", "fill": "transparent"});
// Add the legend text
var count_text = [
{ "cx": 10, "cy": 12, "text": maxy + " edits" },
{ "cx": 10, "cy": h-5, "text": "0" }
];
var date_text = [
{ "cx": w / 3, "text": vte.convertWikiWeekToDate( ((ew - sw) / 3) + sw ) },
{ "cx": w * 2 / 3, "text": vte.convertWikiWeekToDate( ((ew - sw) * 2 / 3) + sw) }
];
var text_c = vis.selectAll("text.count")
.data(count_text)
.enter().append("text")
.attr("x", function(d) { return d.cx; })
.attr("y", function(d) { return d.cy; })
.text( function(d) { return d.text; })
.attr("font-family", s_wpFont)
.attr("font-size", "10px")
.attr("fill", "#000000");
var text_d = vis.selectAll("text.date")
.data(date_text)
.enter().append("text")
.attr("x", function(d) { return d.cx; })
.attr("y", function(d) { return 12; })
.text( function(d) { return d.text.substring(0,4) + "/"+d.text.substring(4,6) + "/"+d.text.substring(6,8); })
.attr("font-family", s_wpFont)
.attr("font-size", "10px")
.attr("text-anchor", "middle")
.attr("fill", "#848484");
},
// populateNav - draws the navigation content
populateNav: function() {
if ($("#vte-window").data("vte-project")) {
$("#vte-window-left-nav").html(
"<div id='vte-members' class='vte-nav-link'>Members</div>" +
"<div id='vte-roles' class='vte-nav-link'>Roles</div>" +
"<div id='vte-tasks' class='vte-nav-link'>Tasks</div>" +
"<div id='vte-communication' class='vte-nav-link'>Communication</div>"
);
$(".vte-nav-link").css(s_vteNavLink);
// Add the click actions for the links
$(".vte-nav-link").click(function(e) {
var id = $(e.currentTarget).attr("id");
if (id == "vte-members") {
vte.clickMembers();
} else if (id == "vte-roles") {
vte.clickRoles();
} else if (id == "vte-tasks") {
vte.clickTasks();
} else if (id == "vte-communication") {
vte.clickCommunication();
} else {
console.error("Unknown vte action: " + id);
}
});
}
},
// Functions to populate the primary vte systems (ie, members, tasks, etc)
clickMembers: function() {
console.log("vte - drawing member content");
// Load the Members page for the current project (should be Wikipedia:<project name>/Members
var project = $("#vte-window").data("vte-project");
$.getJSON(
mw.util.wikiScript('api'),
{
format: 'json',
action: 'query',
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
titles: 'Wikipedia:' + project + "/Members",
}
)
.done(function(data) {
var page, text;
try {
// This should only return one page...
for ( page in data.query.pages) {
text = data.query.pages[page].revisions[0]['*'];
}
} catch( e ) {
console.error("Failed to request members page for project " + project);
}
vte.drawMembers(text);
})
.fail(function() {
console.error("Failed to request members page for project " + project);
});
},
clickRoles: function() {
},
clickTasks: function() {
},
clickCommunication: function() {
},
drawMembers: function(data) {
// Clear the current content window
$("#vte-window-right-content").html(
"<div id='vte-window-right-content-members-title'>" +
$("#vte-window").data("vte-project") + " - Members" +
"</div>"
);
$("#vte-window-right-content-members-title").css(s_vteWindowRightContentTitle);
// Grab current project users from the Members page text
var obj = vte.parseMemberPage(data);
var pre = obj.pre; var post = obj.post; var struc = obj.struc;
// Once we've parsed all the users from the Members page, draw the VTE members content
$("#vte-window-right-content").append(
"<div id='vte-window-right-content-members-add'>" +
" <form id='vte-member-submit' action='javascript();'>" +
" Add Member: <input type='text' id='vte-members-add-name' />" +
" Project Role: <input type='text' id='vte-members-add-comment' />" +
" <input type='submit' value='Add' />" +
" </form>" +
"</div>"
);
$("#vte-window-right-content-members-add").css(s_vteWindowRightContentMembersAdd);
// Display existing users (header on top)
$("#vte-window-right-content").append(
"<div class='vte-members-name' style='font-weight: bold; text-align: center;'>User name</div>" +
"<div class='vte-members-date' style='font-weight: bold; text-align: center;'>Member since</div>" +
"<div class='vte-members-comment' style='font-weight: bold; text-align: center;'>Project roles</div>" +
"<div class='vte-members-actions' style='font-weight: bold; text-align: center;'>Actions</div>" +
"<div style='clear: both;'/>"
);
var action =
"<svg height='10' width='10'>" +
" <polygon points='0,0 10,0 5,10' style='fill:black;stroke:black;stroke-width:1' />" +
" Sorry, your browser does not support inline SVG." +
"</svg>";
for (var i in struc) {
var n = struc[i].name;
if (n == "dwmc") struc[i].date = "today";
try {
var d = vte.getDateStr(struc[i].date)
} catch(err) {
var d = struc[i].date;
}
$("#vte-window-right-content").append(
"<div id='vte-members-name-" + n + "' class='vte-members-name'>" + n + "</div>" +
"<div id='vte-members-date-" + n + "' class='vte-members-date'>" + d + "</div>" +
"<div id='vte-members-comment-" + n + "' class='vte-members-comment'>" + struc[i].comment_str + "</div>" +
"<div class='vte-members-actions' vte-name='" + n + "' " +
" id='action_" + struc[i].name + "'>" + action + "</div>" +
"<div style='clear: both;'/>"
);
// Add action to open Actions menu on click
$("#action_" + n).click(vte.clickMemberActions);
}
$(".vte-members-name").css(s_vteMembersName);
$(".vte-members-date").css(s_vteMembersDate);
$(".vte-members-comment").css(s_vteMembersComment);
$(".vte-members-actions").css(s_vteMembersAction);
// Action to add new member
$("#vte-member-submit").submit(function(e) {
e.preventDefault();
console.log("Adding user to members list");
// TODO: Verify that the user actually exists, potentially?
var d = new Date();
var n = $("#vte-members-add-name").val();
struc.push({
name: n,
name_str: "[[User:"+n+"|"+n+"]] • [[User_talk:"+n+"|Talk]] • [[Special:Contributions/"+n+"|Contribs]]",
date: d,
date_str: "15:31, 8 October 2014 (UTC)",
comment_str: $("#vte-members-add-comment").val(),
});
// Build the member string
var members_str = pre + "\n";
for (var i in struc) {
members_str += "|-\n" +
"| " + struc[i].name_str + "\n" +
"| " + struc[i].date_str + "\n" +
"| " + struc[i].comment_str + "\n";
}
members_str += post;
// Make the request to update the wikitext for the Members page
$.ajax({
url: mw.util.wikiScript( 'api' ),
type: 'POST',
dataType: 'json',
data: {
format: 'json',
action: 'edit',
title: "Wikipedia:" + $("#vte-window").data("vte-project") + "/Members",
text: members_str, // will replace entire page content
summary: "[VTE] Adding member to project: " + $("#vte-members-add-name").val(),
token: mw.user.tokens.get( 'editToken' )
}
})
.done( function(data) {
// Add the user to the members list
console.log("Added member: " + n);
$("#vte-window-right-content").append(
"<div id='vte-members-name-" + n + "' class='vte-members-name'>" + n + "</div>" +
"<div id='vte-members-date-" + n + "' class='vte-members-date'>" + vte.getDateStr(d) + "</div>" +
"<div id='vte-members-comment-" + n + "' class='vte-members-comment'>" + $("#vte-members-add-comment").val() + "</div>" +
"<div class='vte-members-actions' vte-name='" + n + "' id='action_" + n + "'>" + action + "</div>" +
"<div style='clear: both;'/>"
);
// Add action to open Actions menu on click
$("#action_" + n).click(vte.clickMemberActions);
$(".vte-members-name").css(s_vteMembersName);
$(".vte-members-date").css(s_vteMembersDate);
$(".vte-members-comment").css(s_vteMembersComment);
$(".vte-members-actions").css(s_vteMembersAction);
// And clear out the member inputs
$("#vte-members-add-name").val("");
$("#vte-members-add-comment").val("");
})
.fail( function(xhr) {
console.error("Failed to update Members page: " + JSON.stringify(xhr));
});
});
},
parseMemberPage: function(data) {
// Grab current project users from the Members page text
var m = data.match(/([\s\S]*\<\!-- START MEMBER LIST --\>)([\s\S]*)(\<\!-- END MEMBER LIST --\>[\s\S]*)/);
if (m === null) {
console.error("Failed to find member list on members page (between MEMBER LIST comments)");
console.error("Page contains: " + data);
return false;
}
var pre = m[1];
var post = m[3];
var users = m[2].replace(/\n/g, "[[User:Md gilbert|Md gilbert]] ([[User talk:Md gilbert|talk]])").split(/\|\-\~\~\~/);
//console.log("Found users: " + users.join(" --- "));
// Go through all members and add to member struc
var struc = [];
for (var i in users) {
if (users[i] == "[[User:Md gilbert|Md gilbert]] ([[User talk:Md gilbert|talk]])") continue;
// Name, date, and comments each on their own line
var user = users[i].split(/\~\~\~/);
if (user.length != 4) { // Includes each element plus newline at the end
console.error("Failed to parse user line: ");
console.error(user);
}
// Remove leading pipe from each element
user[0] = user[0].match(/^\| (.*)/)[1];
user[1] = user[1].match(/^\| (.*)/)[1];
user[2] = user[2].match(/^\| (.*)/)[1];
var name = user[0].match(/\[\[User:([^\|]+)\|/)[1];
var m1 = user[1].match(/(\d+):(\d+), (\d+) (\S+) (\d+)/);
var date = m1 === null ? user[1] : new Date(Date.UTC(m1[5], vte.getMonth(m1[4]), m1[3], m1[2], m1[1], 0));
struc.push({
name: name,
name_str: user[0],
date: date,
date_str: user[1],
comment_str: user[2].replace(/\~\~\~/g, ""),
});
}
// Save members so we can update more easily
var obj = {pre: pre, post: post, struc: struc};
$("#vte-window").data("members", obj);
return obj;
},
clickMemberActions: function(e) {
var name = $(e.currentTarget).attr("vte-name");
console.log("opening actions for user " + name);
// Draw the actions window, should support posting to user talk page, viewing contributions, and removing
//$("#action_" + name).append(
$("#vte-window").append(
"<div class='vte-members-actions-div'>" +
" <div id='vte-action-message' class='vte-members-actions-action' vte-name='" + name + "'>Post to user talk</div>" +
" <div id='vte-action-role' class='vte-members-actions-action' vte-name='" + name + "'>Edit user roles</div>" +
" <div id='vte-action-user' class='vte-members-actions-action' vte-name='" + name + "'>View user contributions</div>" +
" <div id='vte-action-remove' class='vte-members-actions-action' vte-name='" + name + "'>Remove from member list</div>" +
"</div>"
);
$(".vte-members-actions-div").css(s_vteMembersActionsDiv);
$(".vte-members-actions-action").css(s_vteMembersActionsAction);
// Position the div by the cursor, relative to parent, considering the scroll
var x = (e.pageX - $('#vte-window').offset().left) - 150;
var y = (e.pageY - $('#vte-window').offset().top) + 10;
$(".vte-members-actions-div").css({ "left": x + "px", "top": y + "px" });
// Close the actions window on hitting escape or clicking outside the actions window
var t = setTimeout(function() {
$(document).on('keyup.hide_member_actions', function(e) {
if (e.keyCode == 27) {
$(".vte-members-actions-div").remove();
$(document).unbind('keyup.hide_member_actions');
}
});
$(document).on('click.hide_member_actions', function(e) {
$(".vte-members-actions-div").remove();
$(document).unbind('click.hide_member_actions');
});
}, 100);
// Add the post to user talk page action
$("#vte-action-message").on("click", function(e) {
// Remove the actions div
console.log("Removing the action div box");
$(".vte-members-actions-div").remove();
// Open the message box, should contain space for subject and the message
var name = $(e.currentTarget).attr("vte-name");
$("#vte-window-right-content").append(
"<div class='vte-members-actions-message'>" +
" <form id='vte-member-message' action='javascript();'>" +
" <div class='vte-members-actions-message-subject'>" +
" Subject: <input type='text' id='vte-message-subject' />" +
" </div>" +
" <div class='vte-members-actions-message-text'>" +
" Message: <textarea rows='10' cols='50' id='vte-message-text' />" +
" </div>" +
" <input type='submit' value='Send' />" +
" </form>" +
"</div>"
);
$(".vte-members-actions-message").css(s_vteMembersActionsMessage);
// Close the message window on hitting escape or (TODO) clicking the close button
$(document).on('keyup.hide_member_message', function(e) {
if (e.keyCode == 27) {
$(".vte-members-actions-message").remove();
$(document).unbind('keyup.hide_member_message');
}
});
// Add action to post to the talk page
$("#vte-member-message").submit(function(e) {
e.preventDefault();
console.log("Posting a message to user talk page: " + name);
// Pull the text from the message box
var text = "\n== " + $("#vte-message-subject").val() + " ==\n\n" + $("#vte-message-text").val() + "\n";
// Ensure the post is signed
if (text.match(/\~\~\~\~/) == null) text += "[[User:Md gilbert|Md gilbert]] ([[User talk:Md gilbert|talk]]) 15:31, 8 October 2014 (UTC)\n";
$.ajax({
url: mw.util.wikiScript( 'api' ),
type: 'POST',
dataType: 'json',
data: {
format: 'json',
action: 'edit',
title: "User_talk:" + name,
appendtext: text,
summary: "[VTE] Posting directed talk page message - " + $("#vte-message-subject").val(),
token: mw.user.tokens.get( 'editToken' )
}
})
.done( function(data) {
console.log("Successfully posted to user's talk page");
$(".vte-members-actions-message").remove();
})
.fail( function(xhr) {
console.error("Failed to post to user talk page: " + JSON.stringify(xhr));
});
});
}); // End vte-action-message click
// Add the update user role action
$("#vte-action-role").on("click", function(e) {
// Remove the actions div
console.log("Removing the action div box");
$(".vte-members-actions-div").remove();
// Open the role update dialogue, prepopulate with this member's current roles
var name = $(e.currentTarget).attr("vte-name");
var v = $("#vte-members-comment-" + name).html();
$("#vte-window-right-content").append(
"<div class='vte-members-actions-role'>" +
" <form id='vte-member-role' action='javascript();'>" +
" <div class='vte-role'>" +
" Project roles: <input type='text' id='vte-roles-input' value='" + v + "' />" +
" </div>" +
" <input type='submit' value='Update role' />" +
" </form>" +
"</div>"
);
$(".vte-members-actions-role").css(s_vteMembersActionsMessage); // TODO: Could clean this up
// Close the message window on hitting escape or TODO: clicking outside the window
var t = setTimeout(function() {
$(document).on('keyup.hide_role', function(e) {
if (e.keyCode == 27) {
$(".vte-members-actions-role").remove();
$(document).unbind('keyup.hide_role');
}
});
/*
$(document).on('click.hide_role', function(e) {
$(".vte-members-actions-role").remove();
$(document).unbind('click.hide_role');
});
*/
}, 100);
$("#vte-member-role").submit(function(e) {
e.preventDefault();
// Update the Members page first, then the VTE if we're successful.
var obj = $("#vte-window").data("members");
var members_str = obj.pre + "\n";
for (var i in obj.struc) {
if (obj.struc[i].name == name) obj.struc[i].comment_str = $("#vte-roles-input").val();
members_str += "|-\n" +
"| " + obj.struc[i].name_str + "\n" +
"| " + obj.struc[i].date_str + "\n" +
"| " + obj.struc[i].comment_str + "\n";
}
members_str += obj.post;
// Make the request to update the wikitext for the Members page
$.ajax({
url: mw.util.wikiScript( 'api' ),
type: 'POST',
dataType: 'json',
data: {
format: 'json',
action: 'edit',
title: "Wikipedia:" + $("#vte-window").data("vte-project") + "/Members",
text: members_str, // will replace entire page content
summary: "[VTE] Updating roles for user " + name +" in project: "+ $("#vte-window").data("vte-project"),
token: mw.user.tokens.get( 'editToken' )
}
})
.done( function(data) {
console.log("Successfully updated member roles for " + name);
// Just update the roles for the current user
$("#vte-members-comment-" + name).html($("#vte-roles-input").val());
// And remove the roles dialogue
$(".vte-members-actions-role").remove();
// And save the members struc
$("#vte-window").data("members", obj);
})
.fail( function(xhr) {
console.error("Failed to update member roles for " + name + ": " + JSON.stringify(xhr));
});
});
}); // End vte-action-role click
// Add the view user contributions action
$("#vte-action-user").on("click", function(e) {
e.preventDefault();
// Draw the lightbox that user stats will be placed within
var name = $(e.currentTarget).attr("vte-name");
var alt_name = name.replace(/_/g, " ");
$("#vte-window").append(
"<div id='vte-members-contribution'>" +
" <div id='vte-members-contribution-title'>" + name + " - User Contributions</div>" +
" <div id='vte-members-contribution-close'>" +
" <img src='/media/wikipedia/commons/6/60/Close_icon.svg' width='25' height='25'>"+
" </div>" +
" <div style='clear: both;'/>" +
" <div id='vte-members-contribution-edits'>" +
" Edits by namespace over time" +
" <div style='height: 10px; width: 100%; border-bottom: 1px solid #000;'></div>" +
" <div id='vte-loading-edits' class='vte-loading'>Loading user edits...</div>" +
" </div>" +
"</div>"
);
$("#vte-members-contribution").css(s_vteMembersContribution);
$("#vte-members-contribution-title").css({"float": "left"});
$("#vte-members-contribution-close").css({"float": "right", "cursor": "pointer"});
$(".vte-loading").css(s_vteLoadingText);
$("#vte-members-contribution-edits").css(s_vteMembersContributionEdits);
// Add action to close the window
$("#vte-members-contribution-close").click(function(e) {
$("#vte-members-contribution").remove();
});
// Add line graph of user edits, separated by namespace
var url = "http://alahele.ischool.uw.edu:8999/api/getEdits?user=" + alt_name + "&namespace=0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15&group=page|user|date";
$.ajax({
url: url,
dataType: "json",
success: function(data, stat, xhr) {
if (data.errostatus == "fail") {
console.error("Error: " + data.message);
return false;
}
console.log("Sucessfully fetched user edits.");
$("#vte-loading-edits").remove();
vte.drawUserEdits(data);
},
error: function(xhr, stat, err) {
console.error("Failed to request user edits: " + JSON.stringify(xhr));
},
complete: function() {
$("#vte-loading-edits").remove();
},
});
}); // End vte-action-user click
// Add the remove user member action
$("#vte-action-remove").on("click", function(e) {
e.preventDefault();
// Update the Members page first, then the VTE if we're successful.
var name = $(e.currentTarget).attr("vte-name");
var obj = $("#vte-window").data("members");
var members_str = obj.pre + "\n";
for (var i in obj.struc) {
// If this is the user we're removing, remove from the struc and continue
if (obj.struc[i].name == name) {
obj.struc.splice(i, 1);
continue;
}
members_str += "|-\n" +
"| " + obj.struc[i].name_str + "\n" +
"| " + obj.struc[i].date_str + "\n" +
"| " + obj.struc[i].comment_str + "\n";
}
members_str += obj.post;
// Make the request to update the wikitext for the Members page
$.ajax({
url: mw.util.wikiScript( 'api' ),
type: 'POST',
dataType: 'json',
data: {
format: 'json',
action: 'edit',
title: "Wikipedia:" + $("#vte-window").data("vte-project") + "/Members",
text: members_str, // will replace entire page content
summary: "[VTE] Removing user " + name +" from project members for project: "+ $("#vte-window").data("vte-project"),
token: mw.user.tokens.get( 'editToken' )
}
})
.done( function(data) {
console.log("Successfully removed project member " + name);
// Then remove the row for this member
$("#vte-members-name-" + name).remove();
$("#vte-members-date-" + name).remove();
$("#vte-members-comment-" + name).remove();
$("#action_" + name).remove();
// And save the new version of the members struc
$("#vte-window").data("members", obj);
})
.fail( function(xhr) {
console.error("Failed to remove project member - " + name + ": " + JSON.stringify(xhr));
});
}); // End vte-action-remove click
},
drawRoles: function(data) {
},
drawTasks: function(data) {
},
drawCommunication: function(data) {
},
// drawUserEdits: Will structure and graph user edits over time, separated by namespace
drawUserEdits: function(data) {
// Structure the data for the graph
var sw = ew = vte.convertDateToWikiWeek();
for (var i in data["result"]) if (data["result"][i].rc_wikiweek < sw) sw = data["result"][i].rc_wikiweek;
var edits = Array(ew - sw);
for (var i = 0; i < edits.length; i++) edits[i] = {
date: vte.convertWikiWeekToDate(i), 0:0, 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0,
8:0, 9:0, 10:0, 11:0, 12:0, 13:0, 14:0, 15:0
};
var y_max = 0;
for (var i in data["result"]) {
edits[ data["result"][i].rc_wikiweek - sw ][ data["result"][i].rc_page_namespace ] +=
data["result"][i]["rc_edits"];
if (data["result"][i].rc_edits > y_max) y_max = data["result"][i].rc_edits;
}
// Draw with d3
var margin = {top: 20, right: 80, bottom: 50, left: 50};
var w = $("#vte-members-contribution").width() - margin.left - margin.right - 20,
h = 230 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y%m%d").parse;
var x = d3.time.scale()
.range([0, w]);
var y = d3.scale.linear()
.range([h, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.count); });
//.attr("shape-rendering", "crispEdges");
var svg = d3.select("#vte-members-contribution-edits").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
color.domain(d3.keys(edits[0]).filter( function(key) { return key !== "date"; }));
edits.forEach(function(d) {
d.date = parseDate(d.date);
});
var namespaces = color.domain().map(function(ns) {
return {
namespace: vte.convertIdToNamespace(ns),
values: edits.map(function(d) {
return {date: d.date, count: +d[ns]};
})
};
});
x.domain(d3.extent(edits, function(d) { return d.date; }));
y.domain([
d3.min(namespaces, function(c) { return d3.min(c.values, function(v) { return v.count; }); }),
d3.max(namespaces, function(c) { return d3.max(c.values, function(v) { return v.count; }); })
]);
svg.append("g")
.style("fill", "none")
.style("stroke", "#000")
.style("shape-rendering", "crispEdges")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
svg.append("g")
.style("fill", "none")
.style("stroke", "#000")
.style("shape-rendering", "crispEdges")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".70em")
.style("text-anchor", "end")
.text("Edits");
var ns = svg.selectAll(".ns")
.data(namespaces)
.enter().append("g")
.attr("class", "ns");
ns.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "1.5px")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.namespace); });
ns.append("text")
.datum(function(d) {
// Return null string if the last value was 0 (to avoid overlap)
if (d.values[d.values.length -1].count == 0) {
return { namespace: "", value: d.values[d.values.length - 1] };
} else {
return { namespace: d.namespace, value: d.values[d.values.length - 1]};
}
})
.attr("transform", function(d) {
return "translate(" + x(d.value.date) + "," + y(d.value.count) + ")";
})
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.namespace; });
// And then fix the labels on the axes (needed since the ticks and text are defined at the same time above)
$("#vte-members-contribution-edits > svg text").css({"stroke": "none", "fill": "#000"});
},
// populateContent - draws the main content for the given tool/project
populateContent: function(project, tool) {
},
//
// HELPER FUNCTIONS
//
// getDateStr - Given a date object, returns a string like YYYY/mm/dd hh:mm:ss. If no date
// is given will return the string for the current time.
getDateStr: function(d) {
if (typeof(d) === 'undefined') {
d = new Date();
}
return String(d.getFullYear()) + "/" + String(vte.pad( parseInt(d.getMonth()) + 1, 2)) + "/" + String(vte.pad(d.getDate(), 2)) + " " + String(vte.pad(d.getHours(), 2)) + ":" + String(vte.pad(d.getMinutes(), 2)) + ":" + String(vte.pad(d.getSeconds(), 2));
},
getMonth: function(m) {
var months = { "January": 1, "February": 2, "March": 3, "April": 4,
"May": 5, "June": 6, "July": 7, "August": 8, "September": 9,
"October": 10, "November": 11, "December": 12
};
if (! (m in months)) {
console.error("Invalid month: " + m);
}
return months[m];
},
// convertDateToWikiWeek - helper function to convert a date of the form YYYYmmdd to wikiweek
convertDateToWikiWeek: function(d) {
if (typeof(d) === 'undefined') {
var date = new Date();
d = String(date.getFullYear()) + String(vte.pad( parseInt(date.getMonth()) + 1, 2)) + String(vte.pad(date.getDate(), 2));
}
var ms = new Date(d.substring(0,4) + '/' + d.substring(4,6) + '/' + d.substring(6,8) + ' 00:00:00').getTime();
var originMs = new Date('2001/01/01 00:00:00').getTime();
var msDiff = ms - originMs;
// milliseconds in a week
var week = 7 * 24 * 60 * 60 * 1000;
// weeks in the millisecond range
return Math.floor(msDiff / week);
},
pad: function(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
},
convertWikiWeekToDate: function(ww) {
// milliseconds in wiki weeks
var ms = ww * 7 * 24 * 60 * 60 * 1000;
// Add milliseconds since the epoch to week ms value
var mil = new Date('2001/01/01 00:00:00').getTime() + ms;
var date = new Date(mil);
// Date will be of form YYYYmmdd
return String(date.getFullYear()) + String(vte.pad( parseInt(date.getMonth()) + 1, 2)) + String(vte.pad(date.getDate(), 2));
},
convertIdToNamespace: function(id) {
var ns = {
0: "Article", 1: "Article talk", 2: "User", 3: "User talk",
4: "Wikipedia", 5: "Wikipedia talk", 6: "File", 7: "File talk",
8: "MediaWiki", 9: "MediaWiki talk", 10: "Template", 11: "Template talk",
12: "Help", 13: "Help talk", 14: "Category", 15: "Category talk",
100: "Portal", 101: "Portal talk", 108: "Book", 109: "Book talk",
118: "Draft", 119: "Draft talk"
};
return ns[id];
},
};
/**** Styles ****/
var s_wpFont = 'Verdana, "Verdana Ref", Corbel, "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "DejaVu Sans", "Bitstream Vera Sans", "Liberation Sans", sans-serif';
var s_vteNavLink = {
"margin": "5px 0px 0px 10px",
"cursor": "pointer",
"color": "#0B0B61"
};
var s_vteWindow = {
"position": "fixed",
"width": "80%",
"height": "80%",
"background-color": "#FFFFFF",
"top": "50px",
"left": "10%",
"box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"-moz-box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"-webkit-box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"z-index": "5"
};
var s_vteMembersContribution = {
"font-family": s_wpFont,
"position": "absolute",
"top": "5%",
"left": "5%",
"width": "80%",
"height": "80%",
"background-color": "rgba(255,255,255,.95)",
"padding": "20px",
"box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"-moz-box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"-webkit-box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"border-radius": "10px",
"-moz-border-radius": "10px",
"overflow-y": "auto",
};
var s_vteWindowRightContentTitle = {
"font-family": s_wpFont,
"font-size": "13px",
"padding": "10px 0px 10px 0px",
"color": "#151515",
};
var s_vteMembersActionsMessage = {
"font-family": s_wpFont,
"position": "absolute",
"top": "100px",
"left": "25%",
"background-color": "rgba(255,255,255,.95)",
"padding": "20px",
"box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"-moz-box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
"-webkit-box-shadow": "0 1px 6px rgba(0, 0, 0, 0.2)",
};
var s_vteMembersActionsDiv = {
"position": "absolute",
"background-color": "#F5DA81", // yellow-orange
"padding": "10px",
"border-radius": "10px",
"-moz-border-radius": "10px",
};
var s_vteMembersActionsAction = {
"font-family": s_wpFont,
"font-size": "10px",
"color": "#424242",
"text-align": "left",
"cursor": "pointer",
"margin": "3px 0px 3px 5px",
};
var s_vteWindowRightContentMembersAdd = {
"font-family": s_wpFont,
"font-size": "12px",
"padding": "10px 0px 20px 0px",
"color": "#424242",
};
var s_vteMembersName = {
"display": "inline",
"font-family": s_wpFont,
"font-size": "12px",
"color": "#424242",
"float": "left",
"width": "20%",
"padding-top": "5px",
};
var s_vteMembersDate = {
"display": "inline",
"font-family": s_wpFont,
"font-size": "12px",
"color": "#424242",
"float": "left",
"width": "20%",
"padding-top": "5px",
};
var s_vteMembersComment = {
"display": "inline",
"font-family": s_wpFont,
"font-size": "12px",
"color": "#424242",
"float": "left",
"width": "50%",
"text-align": "center",
"padding-top": "5px",
};
var s_vteMembersAction = {
"display": "inline",
"font-family": s_wpFont,
"font-size": "12px",
"color": "#424242",
"float": "left",
"width": "5%",
"text-align": "center",
"cursor": "pointer",
"padding-top": "5px",
};
var s_vteWindowLeft = {
"float": "left",
"padding": "5px 5px 5px 5px",
"border-right": "1px solid #EEE",
// Set width as 20% minus padding, borders, etc
"width": "-moz-calc(20% - 11px)", // Firefox
"width": "-webkit-calc(20% - 11px)", // Webkit
"width": "-o-calc(20% - 11px)", // Opera
"width": "calc(20% - 11px)", // Standard
// Same as width, height is 100% minus border, padding, etc
"height": "-moz-calc(100% - 11px)",
"height": "-webkit-calc(100% - 11px)",
"height": "-o-calc(100% - 11px)",
"height": "calc(100% - 11px)",
};
var s_vteWindowRight = {
"float": "right",
"padding": "5px 5px 5px 5px",
// Set width as 80% minus padding, borders, etc
"width": "79%",
"width": "-moz-calc(80% - 10px)", // Firefox
"width": "-webkit-calc(80% - 10px)", // Webkit
"width": "-o-calc(80% - 10px)", // Opera
"width": "calc(80% - 10px)", // Standard
// Same as width, height is 100% minus border, padding, etc
"height": "-moz-calc(100% - 21px)",
"height": "-webkit-calc(100% - 21px)",
"height": "-o-calc(100% - 21px)",
"height": "calc(100% - 21px)",
};
var s_vteWindowLeftProject = {
"float": "left",
"width": "100%",
"height": "15%",
"background-color": "#F9F9F9"
};
var s_vteWindowLeftNav = {
"float": "left",
"width": "100%",
"height": "80%",
"background-color": "#FFFFFF",
"font-family": s_wpFont,
"font-size": "12px",
"padding": "10px 0px",
};
var s_vteWindowRightTitle = {
"float": "left",
"width": "100%",
"min-height": "10px",
"background-color": "#F9F9F9",
"border-bottom": "1px solid #EEE"
};
var s_vteWindowRightTool = {
"float": "left",
"width": "100%",
"background-color": "#F9F9F9",
"border-bottom": "1px solid #000"
};
var s_vteWindowRightContent = {
"float": "left",
"width": "100%",
"height": "95%",
"background-color": "#FFFFFF",
"overflow-y": "auto",
//"padding": "10px"
};
var s_vteWindowRightContentSummary = {
"font-family": s_wpFont,
"font-size": "13px",
};
var s_vteWindowRightContentSummaryGraph = {
"font-family": s_wpFont,
"margin": "8px",
"border": "1px solid #EEEEEE",
"height": "112px",
};
var s_vteWindowRightContentSummaryPages = {
"font-family": s_wpFont,
"margin": "8px",
"border": "1px solid #EEEEEE",
"height": "130px",
};
var s_vteWindowRightContentSummaryNew = {
"font-family": s_wpFont,
"margin": "8px",
"border": "1px solid #EEEEEE",
};
var s_vteMembersContributionEdits = {
"font-family": s_wpFont,
"font-size": "10px",
"margin": "8px",
"border": "1px solid #EEEEEE",
"height": "250px",
};
var s_vteLoadingText = {
"margin-top": "20px",
"color": "#848484",
"-webkit-animation-name": "glow",
"-webkit-animation-duration": "1s",
"-webkit-animation-iteration-count": "infinite",
"-webkit-animation-direction": "alternate",
"-webkit-animation-timing-function": "ease-in-out",
"-moz-animation-name": "glow",
"-moz-animation-duration": "1s",
"-moz-animation-iteration-count": "infinite",
"-moz-animation-direction": "alternate",
"-moz-animation-timing-function": "ease-in-out",
"-o-animation-name": "glow",
"-o-animation-duration": "1s",
"-o-animation-iteration-count": "infinite",
"-o-animation-direction": "alternate",
"-o-animation-timing-function": "ease-in-out",
"animation-name": "glow",
"animation-duration": "1s",
"animation-iteration-count": "infinite",
"animation-direction": "alternate",
"animation-timing-function": "ease-in-out"
};
var s_vteTitle = {
"font-family": s_wpFont,
"font-size": "20px",
"font-weight": "normal",
"float": "left",
"padding": "5px 0px 5px 10px"
};
var s_vteTitleActions = {
"float": "right",
"padding": "0px 10px 0px 0px",
};
var s_vteTitleAction = {
"float": "left",
"font-family": s_wpFont,
"font-size": "12px",
"cursor": "pointer",
"padding": "5px 0px 0px 5px",
};
var s_vteProjectSelect = {
"display": "block",
"width": "-moz-calc(100% - 12px)", // Firefox
"width": "-webkit-calc(100% - 12px)", // Webkit
"width": "-o-calc(100% - 12px)", // Opera
"width": "calc(100% - 12px)", // Standard
"height": "1.4em",
"position": "relative",
"border": "1px solid #AAA",
"background-color": "#FFF",
"margin": "5px 5px 0px 5px",
};
var s_vteProjectSelectLabel = {
"font-family": s_wpFont,
"font-size": "12px",
"padding": "5px 0px 0px 7px",
};
var s_vteProjectSelectInput = {
"position": "absolute",
"margin": "0",
"border": "0",
"height": "1.4em",
"background-color": "transparent",
"color": "#000",
"outline": "none",
"font-family": s_wpFont,
"font-size": "12px",
"padding": "2px",
};
var s_vteProjectSelectMulti = {
"position": "absolute",
"width": "250px",
"max-height": "80%",
"overflow-y": "auto",
"margin-left": "5px",
"padding": "7px 10px",
"background-color": "#EEE",
"border-bottom-left-radius": "10px",
"border-bottom-right-radius": "10px",
"-moz-border-bottom-left-radius": "10px",
"-moz-border-bottom-right-radius": "10px",
};
var s_vteProjectSelectMultiProj = {
"font-family": s_wpFont,
"font-size": "12px",
"cursor": "pointer",
"padding-left": "1em",
"text-indent": "-1em",
"padding-bottom": "4px",
};
// Only load vte on the Wikipedia namespace (may limit to project pages later)
//if (mw.config.get('wgCanonicalNamespace') === 'Wikipedia') {
console.log("Loading VTE")
mw.loader.using( ["mediawiki.api"], function() {
$(vte.initialize);
});
//}