User:Canadabonk/common.js: Difference between revisions

From TestWiki
Content deleted Content added
Canadabonk (talk | contribs)
No edit summary
Canadabonk (talk | contribs)
No edit summary
 
(17 intermediate revisions by the same user not shown)
Line 1: Line 1:
defaultCategoryView = 'Dynamic'; // Choose from 'Classic' , 'Dynamic' or 'Gallery' --- First letter capital, with single quotes
/*
canada's cosmostweaks
last updated: 3 july 2024


galleryCatStyle = 'Compacter'; // 'Normal' , 'Compact' or 'Compacter'
refer to [[CosmosTweaks]] on dev.miraheze.org
*/


catlistAlphabets = true; // true or false. Whether you want the menu of navigation alphabets above the category list
// sidetools
enableTOC = true;
enableEditButton = true;
enableFullwide = true;
defaultFullwide = false;


//--------------------------------------------------------------------------
// dark mode
enableDarkMode = true;
defaultDarkMode = false;


$(function () {
// misc
if ($('body').is('.ns-14')) {
enableBannerNav = true;
mw.util.addCSS(`
enableBackToTop = true;
#mw-pages .mw-category, .dynamic-catlist, .gallery-catlist {
enableHideRail = true;
display:none;
}
#mw-pages.catview-Classic .mw-category, .catview-Dynamic .dynamic-catlist, .catview-Gallery .gallery-catlist {
display:block;
}


//-------------------------------------------------
/*----------- dynamic ---------*/


.dynamic-catlist {
const
column-count:3;
$body = $('body'),
column-width:24em;
$html = $('html');
column-gap:2em;
}


.dynamic-catlist ul{
if (localStorage.ctDarkMode == 'true') {
list-style:none;
document.documentElement.classList.add('cosmostweaks-darkmode');
margin-left:0;
}
}

if (localStorage.ctFullwide == 'true') {
.dynamic-catlist h3 {
document.documentElement.classList.add('fullwide');
border-bottom: 1px solid #ccc;
}
}

if (localStorage.ctRailHidden == 'true') {
.dynamic-catlist li {
$('.cosmos-articleContainer').addClass('ct-railhidden');
display:flex;
align-items:center;
gap:1em;
margin:5px 0;
break-inside:avoid;
}
}

if (!enableDarkMode) {
.dynamic-catlist .catlink-thumb {
localStorage.removeItem('ctDarkMode');
width:4em;
aspect-ratio: 1;
}
img.catlink-thumb {
object-fit:cover;
object-position:center top;
border:1px solid #ccc;
}
div.catlink-thumb {
display:flex;
align-items:center;
justify-content: center;
}
}
if (!enableFullwide) {
.catlink-thumb svg {
localStorage.removeItem('ctFullwide');
width:40%;
height:auto;
fill:currentcolor;
}
}


/*----------- gallery ---------*/
$(document).ready(function () {
// desktop/tablet only
if ($(window).width() > 850 && mw.config.get('skin') == 'cosmos') {


.gallery-catlist ul {
//add sidetools wrapper
list-style:none;
$('#mw-content').prepend('<div class="ct-sidetools-wrapper"><div class="ct-sidetools"></div></div>');
margin-left:0;
const sidetools = $('.ct-sidetools');
margin-top:1em;
display:grid;
$(window).resize(function(){
gap:1.5em;
if ($(window).width() < 850) {
row-gap:2.5em;
sidetools.hide();
grid-template-columns: repeat(auto-fill, 10em);
} else {
grid-template-rows: auto;
sidetools.show();
justify-content:center;
}
}
});


.gallery-catlist li {
// toc start ------------------------------------------------------------------------------------------------------
display:contents;
if ($('#toc').length && enableTOC) {
}
//add button html
const tocbuttonhtml = '<div class="ct-toc"><span class="ct-sidetools-button"></span></div>';
sidetools.append(tocbuttonhtml);


.gallery-catlist li a {
// add fontawesome list ul icon to toc button
position:relative;
const tocbutton = $('.ct-toc').find('.ct-sidetools-button');
transition:opacity 0.2s;
const listIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M64 144a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zM64 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm48-208a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z"/></svg>';
}
tocbutton.html(listIcon);
.gallery-catlist li a:hover {
tocbutton.attr('title', 'Contents');
opacity:0.8;
}


.gallery-catlist .catgallery-thumb {
// get contents of toc
width:100%;
const sidetoc = $('.ct-toc');
aspect-ratio:1;
$('#toc').find('ul').first().clone().appendTo('.ct-toc, #CosmosRail');
border:1px solid #ccc;
sidetoc.find('ul').first().wrap('<div class="ct-stickytoc"></div>');
object-fit:cover;
object-position:center top;
box-sizing:border-box;
}


.catgallery-noimg .catgallery-thumb {
const stickytoc = $('.ct-stickytoc');
background-color:rgba(150,150,150,0.4);
stickytoc.prepend('<div><h3>Contents</h3><span class="ct-toc-move">Move to rail</span></div>');
display:flex;
stickytoc.hide();
justify-content:center;
align-items:center;
}


.catgallery-noimg svg {
tocbutton.click(function () {
width:30%;
stickytoc.fadeToggle(200);
height:fit-content;
});
fill:#888;
}


/*----------- compact gallery ---------*/
stickytoc.find('a').click(function () {
stickytoc.fadeOut(200);
});


div.gallery-compact ul {
hideOnClickOutside('.ct-toc', '.ct-stickytoc');
gap:1em;
}
div.gallery-compacter ul {
gap:2px;
grid-template-columns: repeat(auto-fill, minmax(8em,1fr));
}


.gallery-compact .catgallery-text, .gallery-compacter .catgallery-text {
// siderail toc
line-height:1.2em;
$('#CosmosRail').find('ul').first().wrap('<section class="module ct-railtoc"></section>');
position:absolute;
const railtoc = $('.ct-railtoc');
color:#fff;
railtoc.prepend('<div><h3>Contents</h3><span class="ct-toc-move">Move to sidetools</span></div>');
width:100%;
height:100%;
box-sizing:border-box;
padding:5px 10px;
bottom:0;
left:0;
display:flex;
align-items:flex-end;
background-image: linear-gradient(7deg, rgba(0,0,0,0.7), transparent 50%);
text-shadow: 0 0 10px black;
word-break:break-word;
}


.gallery-compact .catgallery-noimg .catgallery-text, .gallery-compacter .catgallery-noimg .catgallery-text {
if (localStorage.tocInRail) {
background-image:unset;
sidetoc.hide();
background-color:rgba(0,0,0,0.4);
railtoc.show();
}
} else {
railtoc.hide();
}


.gallery-compacter .catgallery-thumb, .gallery-compacter .catgallery-blank {
$('.ct-toc-move').click(function () {
border:unset;
if (sidetoc.is(':visible')) {
}
sidetoc.hide();
railtoc.show();
localStorage.tocInRail = true;
} else {
railtoc.hide();
sidetoc.show();
stickytoc.hide();
localStorage.removeItem('tocInRail');
}
});
} //end toc ------------------------------------------------------------------------------------------------------
//edit button begin
if ($('#ca-viewsource, #ca-edit').length && enableEditButton) {
sidetools.append('<div class="ct-edit"><a class="ct-sidetools-button"></a></div>');
const
pencilIcon = '<svg class="cosmos-button-icon" viewBox="0 0 28 28"><path d="M 20 2 L 26 8 L 8 26 L 2 26 L 2 20 Z M 16 6 L 22 12"></path></svg>',
lockIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"/></svg>',
cosmosEditButton = $('.cosmos-actions-edit').first(),
editButtonHref = cosmosEditButton.parent().attr('href'),
editButtonText = cosmosEditButton.find('.cosmos-button-text').text(),
sidetoolsEditButton = $('.ct-edit .ct-sidetools-button');
sidetoolsEditButton.attr({
'href': editButtonHref,
'title': editButtonText
});
if (cosmosEditButton.attr('id') == 'ca-viewsource') {
sidetoolsEditButton.html(lockIcon);
} else {
sidetoolsEditButton.html(pencilIcon);
}
} // end edit button ------------------------------------------------------------------------------------------------------
//fullwide button begin
if (enableFullwide && $(window).width() > 1083) {
sidetools.prepend('<div class="ct-fullwide"><span class="ct-sidetools-button"></span></div>');
const fullwideButton = $('.ct-fullwide .ct-sidetools-button');
const fullwideIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.5.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M32 32C14.3 32 0 46.3 0 64v96c0 17.7 14.3 32 32 32s32-14.3 32-32V96h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7 14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V352zM320 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h64v64c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H320zM448 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32V352z"/></svg>';
fullwideButton.html(fullwideIcon);
fullwideButton.attr('title', 'Fullscreen');
if (defaultFullwide && localStorage.ctFullwide == null) {
localStorage.ctFullwide = true;
$html.addClass('fullwide');
}
fullwideButton.click(function(){
$html.addClass('fullwide-animate').toggleClass('fullwide');
if ($html.is('.fullwide')) {
localStorage.ctFullwide = true;
} else {
localStorage.ctFullwide = false;
}
});
} // end fullwide button ------------------------------------------------------------------------------------------------------
// banner navigation
if (enableBannerNav) {
$('#p-cosmos-navigation').clone().prependTo('#cosmos-banner-content');
$('#cosmos-banner-content #p-cosmos-navigation').attr('id', 'ct-bannernav');
const bannerNav = $('#ct-bannernav');
bannerNav.css('transform', 'translateY(-100%)');
$(window).scroll(function(){
if (window.scrollY > 200) {
bannerNav.css('transform', 'unset');
} else {
bannerNav.css('transform', 'translateY(-100%)');
}
});
}// end banner navigation ------------------------------------------------------------------------------------------------------
if (enableHideRail) {
$('#CosmosRailWrapper').prepend('<div class="ct-railtoggle"></div>');
const railToggle = $('.ct-railtoggle');
railToggle.click(function(){
$('.cosmos-articleContainer').toggleClass('ct-railhidden');
if ($('.cosmos-articleContainer').is('.ct-railhidden')) {
localStorage.ctRailHidden = true;
} else {
localStorage.removeItem('ctRailHidden');
$('#CosmosRail').css('display', 'none').fadeIn(500);
}
});
} // end hide rail ------------------------------------------------------------------------------------------------------
// toolbar dropups -----------------------------------------------------------------------------
const toolbar = $('#cosmos-toolbar .cosmos-tools-list > ul');
toolbar.find('[id=t-createredirect]').eq(1).remove(); // remove 2nd "create redirect" in toolbar. this shows up for some reason idk why
toolbar.append('<li id="ct-toolbar-pagetools" class="toolbar-dropup">Page tools<ul></ul></li>');
if ($('#t-contributions').length) {toolbar.append('<li id="ct-toolbar-usertools" class="toolbar-dropup">User tools<ul></ul></li>');}
toolbar.find('#t-whatlinkshere, #t-recentchangeslinked, #t-print, #t-permalink, #t-info, #t-cite, #t-urlshortener, #t-createredirect').appendTo('#ct-toolbar-pagetools > ul');
toolbar.find('#t-contributions, #t-log, #t-emailuser, #t-mute, #t-userrights').appendTo('#ct-toolbar-usertools > ul');
} //end desktop ------------------------------------------------------------------------------------------------------


/*----------- menu buttons ---------*/
// back to top button
if (enableBackToTop) {
$('#mw-content-container').append('<div class="ct-top"><div class="ct-top-arrow"></div></div>');
const backToTop = $('.ct-top');
backToTop.attr('title', 'Back to top');
backToTop.click(function(){
window.scrollTo(0,0);
});
backToTop.hide().css({
'opacity': '0',
'transform': 'translateY(100%)'
});
$(window).scroll(function(){
if (window.scrollY > 200) {
backToTop.show().css({
'opacity': 'unset',
'transform': 'unset'
});
} else {
backToTop.css({
'opacity': '0',
'transform': 'translateY(100%)'
});
backToTop.hide("slow");
}
});
} // end back to top---------------------------------------------------------------
// dark mode
if (enableDarkMode) {
const
moonIcon = '<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278zM4.858 1.311A7.269 7.269 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.316 7.316 0 0 0 5.205-2.162c-.337.042-.68.063-1.029.063-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286z"></path> </svg>',
sunIcon = '<svg fill="white" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"></path> </svg>';
drkmodebtn = document.createElement('a');
drkmodebtn.classList.add('wds-button', 'wds-is-secondary', 'ct-darkmode');
drkmodebtn.id = 'ct-darkmode';
const dropdown = document.getElementById('p-more');
const buttonGroup = document.getElementsByClassName('cosmos-header__wiki-buttons')[0];
buttonGroup.insertBefore(drkmodebtn, dropdown);
$('#cosmos-notifsButton-icon').append('<li><a id="ct-darkmode" class="ct-darkmode"></a></li>');


.catlist-menu {
const darkModeButton = $('.ct-darkmode');
display:flex;
gap:10px;
if (defaultDarkMode && localStorage.ctDarkMode == null) {
justify-content:right;
localStorage.ctDarkMode = true;
flex-flow:row wrap;
}
margin:10px 0;
darkModeIconToggle();
}
darkModeButton.click(function(){
$html.toggleClass('cosmostweaks-darkmode');
darkModeIconToggle();
if ($html.is('.cosmostweaks-darkmode')) {
localStorage.ctDarkMode = true;
} else {
localStorage.ctDarkMode = false;
}
});
function darkModeIconToggle(){
if ($html.is('.cosmostweaks-darkmode')) {
darkModeButton.html(sunIcon);
darkModeButton.attr('title', 'Switch to light mode');
} else {
darkModeButton.html(moonIcon);
darkModeButton.attr('title', 'Switch to dark mode');
}
}
}// end dark mode ------------------------------------------------------------------------------------------------------
if ($('.cosmos-mobile-navigation').length) {
$('.cosmos-mobile-menu-button').click(function(){
$('.wds-tabs').css('left', '0');
});
window.onclick = function(e) {
const $target = $(e.target);
if (!$target.closest('.cosmos-mobile-navigation').length && $('.wds-tabs').is(':visible')) {
$('.wds-tabs').css('left','').fadeout(200);
}
};
}
function hideOnClickOutside(container, hiddenitem) {
window.onclick = function (event) {
const $target = $(event.target);
if (!$target.closest(container).length && $(hiddenitem).is(':visible')) {
$(hiddenitem).fadeOut(200);
}
};
}


.catlist-selector, .catlist-nav, .catlist-alphabet {
}); //end document ready
display:flex;
gap:10px;
}


.catlist-nav {
mw.loader.load("https://publictestwiki.com/wiki/User:Canadabonk/sandbox.js?action=raw&ctype=text/javascript");
flex: 1 0 500px;
justify-content:space-between;
max-width:100%;
}
.catlist-alphabet {
overflow:scroll;
gap:5px;
}

#mw-pages > .catlist-nav {
margin-top:10px;
}

.catbtn {
border: 1px solid #ccc;
padding:8px;
user-select:none;
cursor:pointer;
border-radius:6px;
transition:background-color 0.2s;
position:relative;
display:flex;
justify-content:center;
align-items:center;
}

.catlist-selector .catbtn {
line-height:0;
}

.catbtn.active, .catbtn:hover {
background-color: rgba(200,200,200,0.6);
}

.catlist-selector .catbtn::before {
content: attr(title);
position:absolute;
top:-35px;
left:50%;
transform:translateX(-50%);
border: inherit;
display:none;
line-height:1.2em;
padding:5px 8px;
background-color:white;
z-index:1;
}
.catlist-selector .catbtn:hover::before {
display:block;
}

.catbtn svg {
width:1.5em;
height:1.5em;
fill:currentcolor;
}

.catlist-nav span.catbtn {
background-color:rgba(200,200,200,0.6);
opacity: 0.5;
cursor:unset;
}

.redirect-in-category {
display:contents;
}

@media screen and (max-width:500px) {
.gallery-catlist ul {
grid-template-columns: repeat(3, 1fr);
gap:0.5em;
}
}
`);

$('#mw-pages > :not(a)').appendTo($('#mw-pages').clone().empty().insertBefore('#mw-pages'));
$('[id=mw-pages]').eq(1).attr('id', 'mw-pages-extra');

const mwPages = $('#mw-pages');

if (!localStorage.categoryView) {
localStorage.categoryView = defaultCategoryView;
}

// Apply class to #mw-pages based on localStorage

mwPages.attr('class', 'catview-' + localStorage.categoryView);

// Check for magic word in page content, apply class if present

catMagicWords('__CLASSICCAT__', 'catview-Classic');
catMagicWords('__DYNAMICCAT__', 'catview-Dynamic');
catMagicWords('__GALLERYCAT__', 'catview-Gallery');

const
iconClassic = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"/></svg>',
iconDynamic = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M40 48C26.7 48 16 58.7 16 72l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24L40 48zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L192 64zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-288 0zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-288 0zM16 232l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24l-48 0c-13.3 0-24 10.7-24 24zM40 368c-13.3 0-24 10.7-24 24l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24l-48 0z"/></svg>',
iconGallery = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M384 96l0 128-128 0 0-128 128 0zm0 192l0 128-128 0 0-128 128 0zM192 224L64 224 64 96l128 0 0 128zM64 288l128 0 0 128L64 416l0-128zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32z"/></svg>',
iconEmpty = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M384 336l-192 0c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l140.1 0L400 115.9 400 320c0 8.8-7.2 16-16 16zM192 384l192 0c35.3 0 64-28.7 64-64l0-204.1c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1L192 0c-35.3 0-64 28.7-64 64l0 256c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64L0 448c0 35.3 28.7 64 64 64l192 0c35.3 0 64-28.7 64-64l0-32-48 0 0 32c0 8.8-7.2 16-16 16L64 464c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l32 0 0-48-32 0z"/></svg>';

// Make menu buttons

$('#mw-pages > p:first-of-type').after(`<div class="catlist-menu"><div class="catlist-selector"><span class="catbtn" title="Classic">${iconClassic}</span><span class="catbtn" title="Dynamic">${iconDynamic}</span><span class="catbtn" title="Gallery">${iconGallery}</span></div></div>`);

$('.catlist-menu').prepend('<div class="catlist-nav"></div>');

if (catlistAlphabets) {

$('.catlist-nav').prepend('<div class="catlist-alphabet"></div>');

const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
alphabetlist = $('.catlist-alphabet');

for (x in alphabet) {
alphabetlist.append(`<a class="catbtn" href="?pagefrom=${alphabet[x]}">${alphabet[x]}</a>`);
}

alphabetlist.prepend(`<a class="catbtn" href="?">#</a>`);

}

if ($('#mw-pages-extra > a').length > 0) {
$('.catlist-nav').prepend('<span class="catbtn catlist-prev">Previous</span>').append('<span class="catbtn catlist-next">Next</span>');
$('#mw-pages').append('<div class="catlist-nav"><span class="catbtn catlist-prev">Previous</span><span class="catbtn catlist-next">Next</span></div>');

if ($('#mw-pages-extra > a').eq(0).text() == 'previous page') {
$('.catlist-prev').replaceWith(`<a class="catbtn catlist-prev" href="${$('#mw-pages-extra > a').eq(0).attr('href')}">Previous</a>`);
} else {
$('.catlist-next').replaceWith(`<a class="catbtn catlist-next" href="${$('#mw-pages-extra > a').eq(0).attr('href')}">Next</a>`);
}

if ($('#mw-pages-extra > a').eq(1).text() != $('#mw-pages-extra > a').eq(0).text()) {
$('.catlist-next').replaceWith(`<a class="catbtn catlist-next" href="${$('#mw-pages-extra > a').eq(1).attr('href')}">Next</a>`);
}
}

const iconPrev = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"/></svg>',
iconNext = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>';

$('.catlist-prev').prepend(iconPrev);
$('.catlist-next').append(iconNext);
$('#mw-pages-extra').remove();

// Make button active based on category view

$('.catlist-selector .catbtn[title=' + mwPages.attr('class').slice(8) + ']').addClass('active');

$('.catlist-selector .catbtn').click($.proxy(catSelect, null));

// Make Dynamic and Gallery view wrappers

$('#mw-pages .mw-category').after('<div class="gallery-catlist"><ul></ul></div>');
$('#mw-pages .mw-category li').clone().appendTo('.gallery-catlist ul');
$('#mw-pages .mw-category').clone().removeClass().addClass('dynamic-catlist').insertAfter('#mw-pages .mw-category');

switch (galleryCatStyle) {
case 'Compact':
$('.gallery-catlist').addClass('gallery-compact');
break;
case 'Compacter':
$('.gallery-catlist').addClass('gallery-compacter');
}

api = new mw.Api(),
pages = [],
pageslice = [];

// pages is array of all category pages on current page, in order

$('#mw-pages .mw-category li a').each(function () {
pages.push($(this).attr('title'));
});

// slice array into chunks of 50 (page limit by default is 200, and pageimages api max query is 50)

for (i = 0; pages.length > i * 50; i++) {
pageslice[i] = pages.slice(i * 50, (i + 1) * 50);
}

// get pageimages

Promise.all(pageslice.map(function (value) {
const pageimagesparams = {
action: 'query',
format: 'json',
prop: 'pageimages',
pithumbsize: '200',
titles: value
};

return new Promise((resolve, reject) => {
api.get(pageimagesparams).done(function (data) {
resolve(Object.values(data.query.pages));
});
});

}))
.then(function (values) {
// combine all api results into one array and sort based on the 'pages' array
imageslist = values.flatMap(a => a);
imageslist.sort((a, b) => pages.indexOf(a.title) - pages.indexOf(b.title));

// Add images to Gallery and Dynamic

$('.gallery-catlist li a').each(function (index) {
$(this).wrapInner('<div class="catgallery-text"><span></span></div>');
$(this).find('span').html($(this).find('span').text().replaceAll(/(:|\/)/g, "$1<wbr>"));
try { $(this).prepend(`<img class="catgallery-thumb catgallery-img" src="${imageslist[index].thumbnail.source}">`) }
catch (err) { $(this).addClass('catgallery-noimg').prepend(`<div class="catgallery-thumb">${iconEmpty}</div>`) }
});

$('.dynamic-catlist li a').each(function (index) {
try { $(this).before(`<a title="${$(this).attr('title')}" href="${$(this).attr('href')}"><img class="catlink-thumb" src="${imageslist[index].thumbnail.source}"></a>`) }
catch (err) { $(this).before(`<div class="catlink-thumb">${iconEmpty}</div>`) }
});

});
}
});

function catSelect() {
$(this).addClass('active').siblings().removeClass('active');
localStorage.categoryView = $(this).attr('title');
$('#mw-pages').attr('class', 'catview-' + $(this).attr('title'));
}

function catMagicWords(magicword, addclass) {
if ($('.mw-parser-output').html().search(magicword) > -1) {
$('.mw-parser-output').html($('.mw-parser-output').html().replace(magicword, ''));
$('#mw-pages').attr('class', addclass);
}
}

Latest revision as of 18:40, 12 August 2024

defaultCategoryView = 'Dynamic'; // Choose from 'Classic' , 'Dynamic' or 'Gallery' --- First letter capital, with single quotes

galleryCatStyle = 'Compacter'; // 'Normal' , 'Compact' or 'Compacter'

catlistAlphabets = true; // true or false. Whether you want the menu of navigation alphabets above the category list

//--------------------------------------------------------------------------

$(function () {
    if ($('body').is('.ns-14')) {
        mw.util.addCSS(`
#mw-pages .mw-category, .dynamic-catlist, .gallery-catlist {
    display:none;
}
#mw-pages.catview-Classic .mw-category, .catview-Dynamic .dynamic-catlist, .catview-Gallery .gallery-catlist {
    display:block;
}

/*----------- dynamic ---------*/

.dynamic-catlist {
    column-count:3;
    column-width:24em;
    column-gap:2em;
}

.dynamic-catlist ul{
    list-style:none;
    margin-left:0;
}

.dynamic-catlist h3 {
    border-bottom: 1px solid #ccc;
}

.dynamic-catlist li {
    display:flex;
    align-items:center;
    gap:1em;
    margin:5px 0;
    break-inside:avoid;
}

.dynamic-catlist .catlink-thumb {
    width:4em;
    aspect-ratio: 1;
}
img.catlink-thumb {
    object-fit:cover;
    object-position:center top;
    border:1px solid #ccc;
}
div.catlink-thumb {
    display:flex;
    align-items:center;
    justify-content: center;
}
  
.catlink-thumb svg {
    width:40%;
    height:auto;
    fill:currentcolor;
}

/*----------- gallery ---------*/

.gallery-catlist ul {
    list-style:none;
    margin-left:0;
    margin-top:1em;
    display:grid;
    gap:1.5em;
    row-gap:2.5em;
    grid-template-columns: repeat(auto-fill, 10em);
    grid-template-rows: auto;
    justify-content:center;
}

.gallery-catlist li {
    display:contents;
}

.gallery-catlist li a {
    position:relative;
    transition:opacity 0.2s;
}
.gallery-catlist li a:hover {
    opacity:0.8;
}

.gallery-catlist .catgallery-thumb {
    width:100%;
    aspect-ratio:1;
    border:1px solid #ccc;
    object-fit:cover;
    object-position:center top;
    box-sizing:border-box;
}

.catgallery-noimg .catgallery-thumb {
    background-color:rgba(150,150,150,0.4);
    display:flex;
    justify-content:center;
    align-items:center;
}

.catgallery-noimg svg {
    width:30%;
    height:fit-content;
    fill:#888;
}

/*----------- compact gallery ---------*/

div.gallery-compact ul {
    gap:1em;
}
div.gallery-compacter ul {
    gap:2px;
    grid-template-columns: repeat(auto-fill, minmax(8em,1fr));
}

.gallery-compact .catgallery-text, .gallery-compacter .catgallery-text {
    line-height:1.2em;
    position:absolute;
    color:#fff;
    width:100%;
    height:100%;
    box-sizing:border-box;
    padding:5px 10px;
    bottom:0;
    left:0;
    display:flex;
    align-items:flex-end;
    background-image: linear-gradient(7deg, rgba(0,0,0,0.7), transparent 50%);
    text-shadow: 0 0 10px black;
    word-break:break-word;
}

.gallery-compact .catgallery-noimg .catgallery-text, .gallery-compacter .catgallery-noimg .catgallery-text {
    background-image:unset;
    background-color:rgba(0,0,0,0.4);
}

.gallery-compacter .catgallery-thumb, .gallery-compacter .catgallery-blank {
    border:unset;
}

/*----------- menu buttons ---------*/

.catlist-menu {
    display:flex;
    gap:10px;
    justify-content:right;
    flex-flow:row wrap;
    margin:10px 0;
}

.catlist-selector, .catlist-nav, .catlist-alphabet {
    display:flex;
    gap:10px;
}

.catlist-nav {
    flex: 1 0 500px;
    justify-content:space-between;
    max-width:100%;
}
.catlist-alphabet {
    overflow:scroll;
    gap:5px;
}

#mw-pages > .catlist-nav {
    margin-top:10px;
}

.catbtn {
    border: 1px solid #ccc;
    padding:8px;
    user-select:none;
    cursor:pointer;
    border-radius:6px;
    transition:background-color 0.2s;
    position:relative;
    display:flex;
    justify-content:center;
    align-items:center;
}

.catlist-selector .catbtn {
    line-height:0;
}

.catbtn.active, .catbtn:hover {
    background-color: rgba(200,200,200,0.6);
}

.catlist-selector .catbtn::before {
    content: attr(title);
    position:absolute;
    top:-35px;
    left:50%;
    transform:translateX(-50%);
    border: inherit;
    display:none;
    line-height:1.2em;
    padding:5px 8px;
    background-color:white;
    z-index:1;
}
.catlist-selector .catbtn:hover::before {
    display:block;
}

.catbtn svg {
    width:1.5em;
    height:1.5em;
    fill:currentcolor;
}

.catlist-nav span.catbtn {
    background-color:rgba(200,200,200,0.6);
    opacity: 0.5;
    cursor:unset;
}

.redirect-in-category {
    display:contents;
}

@media screen and (max-width:500px) {
    .gallery-catlist ul {
        grid-template-columns: repeat(3, 1fr);
        gap:0.5em;
    }
}
`);

        $('#mw-pages > :not(a)').appendTo($('#mw-pages').clone().empty().insertBefore('#mw-pages'));
        $('[id=mw-pages]').eq(1).attr('id', 'mw-pages-extra');

        const mwPages = $('#mw-pages');

        if (!localStorage.categoryView) {
            localStorage.categoryView = defaultCategoryView;
        }

        // Apply class to #mw-pages based on localStorage

        mwPages.attr('class', 'catview-' + localStorage.categoryView);

        // Check for magic word in page content, apply class if present

        catMagicWords('__CLASSICCAT__', 'catview-Classic');
        catMagicWords('__DYNAMICCAT__', 'catview-Dynamic');
        catMagicWords('__GALLERYCAT__', 'catview-Gallery');

        const
            iconClassic = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M0 96C0 78.3 14.3 64 32 64l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 128C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32l384 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 288c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32L32 448c-17.7 0-32-14.3-32-32s14.3-32 32-32l384 0c17.7 0 32 14.3 32 32z"/></svg>',
            iconDynamic = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M40 48C26.7 48 16 58.7 16 72l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24L40 48zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L192 64zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-288 0zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-288 0zM16 232l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24l-48 0c-13.3 0-24 10.7-24 24zM40 368c-13.3 0-24 10.7-24 24l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24l-48 0z"/></svg>',
            iconGallery = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M384 96l0 128-128 0 0-128 128 0zm0 192l0 128-128 0 0-128 128 0zM192 224L64 224 64 96l128 0 0 128zM64 288l128 0 0 128L64 416l0-128zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32z"/></svg>',
            iconEmpty = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M384 336l-192 0c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l140.1 0L400 115.9 400 320c0 8.8-7.2 16-16 16zM192 384l192 0c35.3 0 64-28.7 64-64l0-204.1c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1L192 0c-35.3 0-64 28.7-64 64l0 256c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64L0 448c0 35.3 28.7 64 64 64l192 0c35.3 0 64-28.7 64-64l0-32-48 0 0 32c0 8.8-7.2 16-16 16L64 464c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l32 0 0-48-32 0z"/></svg>';

        // Make menu buttons

        $('#mw-pages > p:first-of-type').after(`<div class="catlist-menu"><div class="catlist-selector"><span class="catbtn" title="Classic">${iconClassic}</span><span class="catbtn" title="Dynamic">${iconDynamic}</span><span class="catbtn" title="Gallery">${iconGallery}</span></div></div>`);

        $('.catlist-menu').prepend('<div class="catlist-nav"></div>');

        if (catlistAlphabets) {

            $('.catlist-nav').prepend('<div class="catlist-alphabet"></div>');

            const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                alphabetlist = $('.catlist-alphabet');

            for (x in alphabet) {
                alphabetlist.append(`<a class="catbtn" href="?pagefrom=${alphabet[x]}">${alphabet[x]}</a>`);
            }

            alphabetlist.prepend(`<a class="catbtn" href="?">#</a>`);

        }

        if ($('#mw-pages-extra > a').length > 0) {
            $('.catlist-nav').prepend('<span class="catbtn catlist-prev">Previous</span>').append('<span class="catbtn catlist-next">Next</span>');
            $('#mw-pages').append('<div class="catlist-nav"><span class="catbtn catlist-prev">Previous</span><span class="catbtn catlist-next">Next</span></div>');

            if ($('#mw-pages-extra > a').eq(0).text() == 'previous page') {
                $('.catlist-prev').replaceWith(`<a class="catbtn catlist-prev" href="${$('#mw-pages-extra > a').eq(0).attr('href')}">Previous</a>`);
            } else {
                $('.catlist-next').replaceWith(`<a class="catbtn catlist-next" href="${$('#mw-pages-extra > a').eq(0).attr('href')}">Next</a>`);
            }

            if ($('#mw-pages-extra > a').eq(1).text() != $('#mw-pages-extra > a').eq(0).text()) {
                $('.catlist-next').replaceWith(`<a class="catbtn catlist-next" href="${$('#mw-pages-extra > a').eq(1).attr('href')}">Next</a>`);
            }
        }

        const iconPrev = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"/></svg>',
            iconNext = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z"/></svg>';

        $('.catlist-prev').prepend(iconPrev);
        $('.catlist-next').append(iconNext);
        $('#mw-pages-extra').remove();

        // Make button active based on category view

        $('.catlist-selector .catbtn[title=' + mwPages.attr('class').slice(8) + ']').addClass('active');

        $('.catlist-selector .catbtn').click($.proxy(catSelect, null));

        // Make Dynamic and Gallery view wrappers

        $('#mw-pages .mw-category').after('<div class="gallery-catlist"><ul></ul></div>');
        $('#mw-pages .mw-category li').clone().appendTo('.gallery-catlist ul');
        $('#mw-pages .mw-category').clone().removeClass().addClass('dynamic-catlist').insertAfter('#mw-pages .mw-category');

        switch (galleryCatStyle) {
            case 'Compact':
                $('.gallery-catlist').addClass('gallery-compact');
                break;
            case 'Compacter':
                $('.gallery-catlist').addClass('gallery-compacter');
        }

        api = new mw.Api(),
            pages = [],
            pageslice = [];

        // pages is array of all category pages on current page, in order

        $('#mw-pages .mw-category li a').each(function () {
            pages.push($(this).attr('title'));
        });

        // slice array into chunks of 50 (page limit by default is 200, and pageimages api max query is 50)

        for (i = 0; pages.length > i * 50; i++) {
            pageslice[i] = pages.slice(i * 50, (i + 1) * 50);
        }

        // get pageimages

        Promise.all(pageslice.map(function (value) {
            const pageimagesparams = {
                action: 'query',
                format: 'json',
                prop: 'pageimages',
                pithumbsize: '200',
                titles: value
            };

            return new Promise((resolve, reject) => {
                api.get(pageimagesparams).done(function (data) {
                    resolve(Object.values(data.query.pages));
                });
            });

        }))
            .then(function (values) {
                // combine all api results into one array and sort based on the 'pages' array
                imageslist = values.flatMap(a => a);
                imageslist.sort((a, b) => pages.indexOf(a.title) - pages.indexOf(b.title));

                // Add images to Gallery and Dynamic

                $('.gallery-catlist li a').each(function (index) {
                    $(this).wrapInner('<div class="catgallery-text"><span></span></div>');
                    $(this).find('span').html($(this).find('span').text().replaceAll(/(:|\/)/g, "$1<wbr>"));
                    try { $(this).prepend(`<img class="catgallery-thumb catgallery-img" src="${imageslist[index].thumbnail.source}">`) }
                    catch (err) { $(this).addClass('catgallery-noimg').prepend(`<div class="catgallery-thumb">${iconEmpty}</div>`) }
                });

                $('.dynamic-catlist li a').each(function (index) {
                    try { $(this).before(`<a title="${$(this).attr('title')}" href="${$(this).attr('href')}"><img class="catlink-thumb" src="${imageslist[index].thumbnail.source}"></a>`) }
                    catch (err) { $(this).before(`<div class="catlink-thumb">${iconEmpty}</div>`) }
                });

            });
    }
});

function catSelect() {
    $(this).addClass('active').siblings().removeClass('active');
    localStorage.categoryView = $(this).attr('title');
    $('#mw-pages').attr('class', 'catview-' + $(this).attr('title'));
}

function catMagicWords(magicword, addclass) {
    if ($('.mw-parser-output').html().search(magicword) > -1) {
        $('.mw-parser-output').html($('.mw-parser-output').html().replace(magicword, ''));
        $('#mw-pages').attr('class', addclass);
    }
}