User:WeWake/Add to TODO.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:WeWake/Add to TODO. |
/*
* Adds a "Add to TODO" link to the Tools menu to add the current page to a personal todo list.
* This version checks if the page exists to determine the wikilink format.
*/
(function () {
// --- Configuration ---
// The name of the subpage on your user page where the list is stored.
var todoSubpage = 'Todo';
// --- End Configuration ---
function addToTodo() {
var pageTitle = mw.config.get('wgTitle');
var fullPageName = mw.config.get('wgPageName');
var api = new mw.Api();
// Check if the current page exists
api.get({
action: 'query',
titles: fullPageName,
prop: 'info'
}).done(function (data) {
var pageId = Object.keys(data.query.pages)[0];
var pageExists = pageId > 0;
var wikilink;
if (pageExists) {
wikilink = '[[' + fullPageName + ']]';
} else {
var userName = mw.config.get('wgUserName');
wikilink = '[[User:' + userName + '/' + pageTitle + '|' + pageTitle + ']]';
}
// Format the current date.
var now = new Date();
var dateString = now.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric'
});
// Prompt for an optional comment.
var userComment = window.prompt('Add an optional comment for this entry:', '');
// Start building the text to be added to the todo list.
var newTodoText = '\n* ' + wikilink + ' - bookmarked on ' + dateString;
// If a comment was provided, append it.
if (userComment) {
newTodoText += ' (Comment: ' + userComment + ')';
}
// --- MediaWiki API Call to add to the TODO list ---
var userTodoPageTitle = 'User:' + mw.config.get('wgUserName') + '/' + todoSubpage;
api.get({
action: 'query',
titles: userTodoPageTitle
}).done(function (data) {
var todoPageId = Object.keys(data.query.pages)[0];
var editParams = {
action: 'edit',
title: userTodoPageTitle,
summary: 'Added ' + wikilink + ' to the todo list.',
format: 'json'
};
if (todoPageId > 0) {
// Page exists, so we append the text.
editParams.appendtext = newTodoText;
} else {
// Page does not exist, so we create it with the text.
editParams.text = newTodoText.trim();
editParams.summary = 'Creating TODO list and adding ' + wikilink + '.';
}
// Perform the edit (append or create).
api.postWithEditToken(editParams).done(function () {
mw.notify('Page successfully added to your TODO list.');
}).fail(function () {
mw.notify('An error occurred while trying to save the entry.', {
type: 'error'
});
});
});
});
}
// Function to manage TODO items when viewing the TODO page
function manageTodoItems() {
var currentPageTitle = mw.config.get('wgPageName');
var userName = mw.config.get('wgUserName');
var userTodoPageTitle = 'User:' + userName + '/' + todoSubpage;
// Check if we're on the user's TODO page
if (currentPageTitle === userTodoPageTitle.replace(/ /g, '_')) {
// Find all list items in the content
$('#mw-content-text ul li').each(function (index) {
var $listItem = $(this);
var itemText = $listItem.text();
// Skip items that already have management buttons or templates
if ($listItem.find('.todo-controls').length > 0 ||
itemText.includes('{{done}}') ||
itemText.includes('{{not done}}')) {
return;
}
// Create control buttons
var $controls = $('<span class="todo-controls" style="margin-left: 10px; font-size: smaller;"></span>');
var $removeBtn = $('<a href="#" style="color: red; margin-right: 5px;">(remove)</a>');
var $doneBtn = $('<a href="#" style="color: green; margin-right: 5px;">(done)</a>');
var $notDoneBtn = $('<a href="#" style="color: orange;">(not done)</a>');
$controls.append($removeBtn).append($doneBtn).append($notDoneBtn);
$listItem.append($controls);
// Bind click events
$removeBtn.on('click', function (e) {
e.preventDefault();
removeTodoItem(index, $listItem);
});
$doneBtn.on('click', function (e) {
e.preventDefault();
markTodoItem(index, $listItem, 'done');
});
$notDoneBtn.on('click', function (e) {
e.preventDefault();
markTodoItem(index, $listItem, 'not done');
});
});
}
}
// Function to remove a TODO item
function removeTodoItem(itemIndex, $listItem) {
if (!confirm('Are you sure you want to remove this item from your TODO list?')) {
return;
}
var api = new mw.Api();
var userTodoPageTitle = 'User:' + mw.config.get('wgUserName') + '/' + todoSubpage;
api.get({
action: 'query',
titles: userTodoPageTitle,
prop: 'revisions',
rvprop: 'content'
}).done(function (data) {
var pageId = Object.keys(data.query.pages)[0];
var content = data.query.pages[pageId].revisions[0]['*'];
// Split content into lines and remove the specific item
var lines = content.split('\n');
var listItemLines = lines.filter(line => line.trim().startsWith('*'));
if (itemIndex < listItemLines.length) {
// Find the actual line index in the full content
var targetLine = listItemLines[itemIndex];
var lineIndex = lines.indexOf(targetLine);
if (lineIndex !== -1) {
lines.splice(lineIndex, 1);
}
var newContent = lines.join('\n');
api.postWithEditToken({
action: 'edit',
title: userTodoPageTitle,
text: newContent,
summary: 'Removed item from TODO list',
format: 'json'
}).done(function () {
$listItem.fadeOut(300, function () {
$(this).remove();
});
mw.notify('Item removed from TODO list.');
}).fail(function () {
mw.notify('Failed to remove item.', { type: 'error' });
});
}
});
}
// Function to mark a TODO item as done or not done
function markTodoItem(itemIndex, $listItem, status) {
var template = status === 'done' ? '{{done}}' : '{{not done}}';
var api = new mw.Api();
var userTodoPageTitle = 'User:' + mw.config.get('wgUserName') + '/' + todoSubpage;
api.get({
action: 'query',
titles: userTodoPageTitle,
prop: 'revisions',
rvprop: 'content'
}).done(function (data) {
var pageId = Object.keys(data.query.pages)[0];
var content = data.query.pages[pageId].revisions[0]['*'];
// Split content into lines and modify the specific item
var lines = content.split('\n');
var listItemLines = lines.filter(line => line.trim().startsWith('*'));
if (itemIndex < listItemLines.length) {
var targetLine = listItemLines[itemIndex];
var lineIndex = lines.indexOf(targetLine);
if (lineIndex !== -1) {
lines[lineIndex] = targetLine + ' ' + template;
}
var newContent = lines.join('\n');
api.postWithEditToken({
action: 'edit',
title: userTodoPageTitle,
text: newContent,
summary: 'Marked item as ' + status,
format: 'json'
}).done(function () {
$listItem.find('.todo-controls').remove();
$listItem.append(' <span style="font-weight: bold; color: ' +
(status === 'done' ? 'green' : 'orange') + ';">' + template + '</span>');
mw.notify('Item marked as ' + status + '.');
}).fail(function () {
mw.notify('Failed to mark item as ' + status + '.', { type: 'error' });
});
}
});
}
// Add the "Add to TODO" link to the "Tools" menu after the page loads.
$(function () {
var link = mw.util.addPortletLink(
'p-tb', // The ID of the "Tools" portlet
'#', // The URL (handled by the click event)
'Add to TODO', // The display text of the link
't-add-to-todo', // The ID for this link
'Add this page to your personal TODO list' // The tooltip
);
// Bind the click event to our function.
$(link).on('click', function (e) {
e.preventDefault();
addToTodo();
});
// Initialize TODO item management if on the TODO page
manageTodoItems();
});
}());