User:Polygnotus/Scripts/NamespaceFilter.js: Difference between revisions

Content deleted Content added
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 1:
// Very janky and not intended for real world use, does not make API calls just filters whatever is there on the page (so use limit=5000).
// <nowiki>
// I have requested something better:
// ==UserScript==
// https://meta.wikimedia.org/wiki/Community_Wishlist/Wishes/Add_Namespace_filter_to_all_Special:_pages_(where_applicable)
// @name Wikipedia Namespace Filter
// @namespace http://tampermonkey.net/
// @version 0.2
// @description Filter special page results by namespace, including mainspace
// @match https://*.wikipedia.org/w/index.php?title=Special:LinkSearch*
// @grant none
// ==/UserScript==
 
(function() {
'use strict';
 
const STORAGE_KEY = 'wikipediaNamespaceFilter';
const ARTICLE_NAMES_ONLY_KEY = 'wikipediaArticleNamesOnly';
 
function addStyles() {
Line 24 ⟶ 21:
margin-right: 10px;
display: inline-block;
// @grant none }
#all-none-options, #display-options {
margin-bottom: 10px;
}
#all-none-options button {
margin-right: 10px;
}
.article-name-only .external {
display: none;
}
`;
Line 50 ⟶ 56:
filterDiv.id = 'namespace-filter';
filterDiv.innerHTML = '<h4>Filter by namespace:</h4>';
 
// Add All/None options
const allNoneDiv = document.createElement('div');
allNoneDiv.id = 'all-none-options';
const allButton = document.createElement('button');
allButton.textContent = 'Select All';
allButton.addEventListener('click', () => setAllCheckboxes(true));
const noneButton = document.createElement('button');
noneButton.textContent = 'Select None';
noneButton.addEventListener('click', () => setAllCheckboxes(false));
allNoneDiv.appendChild(allButton);
allNoneDiv.appendChild(noneButton);
filterDiv.appendChild(allNoneDiv);
 
// Add Article Names Only option
const displayOptionsDiv = document.createElement('div');
displayOptionsDiv.id = 'display-options';
const articleNamesOnlyLabel = document.createElement('label');
const articleNamesOnlyCheckbox = document.createElement('input');
articleNamesOnlyCheckbox.type = 'checkbox';
articleNamesOnlyCheckbox.id = 'article-names-only';
articleNamesOnlyCheckbox.checked = localStorage.getItem(ARTICLE_NAMES_ONLY_KEY) === 'true';
articleNamesOnlyCheckbox.addEventListener('change', toggleArticleNamesOnly);
articleNamesOnlyLabel.appendChild(articleNamesOnlyCheckbox);
articleNamesOnlyLabel.appendChild(document.createTextNode('Show Article Names Only'));
displayOptionsDiv.appendChild(articleNamesOnlyLabel);
filterDiv.appendChild(displayOptionsDiv);
 
const savedFilters = getSavedFilters();
 
namespaces.forEach(namespace => {
Line 56 ⟶ 91:
checkbox.type = 'checkbox';
checkbox.value = namespace;
checkbox.checked = savedFilters ? savedFilters.includes(namespace) : true;
checkbox.addEventListener('change', filterResults(); => {
filterResults();
saveFilters();
});
label.appendChild(checkbox);
label.appendChild(document.createTextNode(namespace));
Line 65 ⟶ 103:
const ol = document.querySelector('ol.special');
ol.parentNode.insertBefore(filterDiv, ol);
 
// Apply initial article names only setting
toggleArticleNamesOnly();
}
 
function setAllCheckboxes(checked) {
document.querySelectorAll('#namespace-filter input[type="checkbox"]').forEach(cb => {
if (cb.id !== 'article-names-only') {
cb.checked = checked;
}
});
filterResults();
saveFilters();
}
 
function filterResults() {
const checkedNamespaces = Array.from(document.querySelectorAll('#namespace-filter input:checked:not(#article-names-only)')).map(cb => cb.value);
document.querySelectorAll('ol.special li').forEach(li => {
const link = li.querySelector('a:nth-child(2)');
Line 80 ⟶ 131:
}
});
}
 
function toggleArticleNamesOnly() {
const isChecked = document.getElementById('article-names-only').checked;
document.querySelector('ol.special').classList.toggle('article-name-only', isChecked);
localStorage.setItem(ARTICLE_NAMES_ONLY_KEY, isChecked);
}
 
function saveFilters() {
const checkedNamespaces = Array.from(document.querySelectorAll('#namespace-filter input:checked:not(#article-names-only)')).map(cb => cb.value);
localStorage.setItem(STORAGE_KEY, JSON.stringify(checkedNamespaces));
}
 
function getSavedFilters() {
const savedFilters = localStorage.getItem(STORAGE_KEY);
return savedFilters ? JSON.parse(savedFilters) : null;
}
 
Line 87 ⟶ 154:
addStyles();
createFilterUI(namespaces);
filterResults(); // Apply filters on initial load
}
}