MediaWiki:Gadget-TemplateContentArticleHeader.js

From WikiMLT
Revision as of 15:11, 20 July 2022 by Spas (talk | contribs) (Text replacement - "<spas.z.spasov@gmail.com>" to "<spas.z.spasov@metalevel.tech>")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: Af­ter pub­lish­ing, you may have to by­pass your browser's cache to see the changes.

  • Fire­fox / Sa­fari: Hold Shift while click­ing Re­load, or press ei­ther Ctrl-F5 or Ctrl‑R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift‑R (⌘-Shift‑R on a Mac)
  • In­ter­net Ex­plor­er / Edge: Hold Ctrl while click­ing Re­fresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
 * @author    Spas Z. Spasov <spas.z.spasov@metalevel.tech>
 * @copyright 2022 Spas Z. Spasov
 * @license   https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License, version 3 (or later)
 * @home      https://wiki.szs.space/wiki/Template:ContentArticleHeader
 */
// console.log('mlw:MediaWiki:TemplateContentArticleHeader.js is active!');

/**
 * Lazy loading background images
 * - https://imagekit.io/blog/lazy-loading-images-complete-guide/
 * - https://codepen.io/imagekit_io/pen/RBXVrW
 *
// mw.hook('wikipage.categories').add(function () {
(function() {
    let lazyloadImages;

    if ("IntersectionObserver" in window) {
    	// console.log(3);
        lazyloadImages = document.querySelectorAll(".lazy");
        const imageObserver = new IntersectionObserver(function (entries, observer) {
            entries.forEach(function (entry) {
                if (entry.isIntersecting) {
                    const image = entry.target;
                    image.classList.remove("lazy");
                    imageObserver.unobserve(image);
                }
            });
        });

        lazyloadImages.forEach(function (image) {
            imageObserver.observe(image);
        });
    } else {
        let lazyloadThrottleTimeout;
        lazyloadImages = document.querySelectorAll(".lazy");

        document.addEventListener("scroll", lazyload);
        window.addEventListener("resize", lazyload);
        window.addEventListener("orientationChange", lazyload);
    }
    
    function lazyload() {
        if (lazyloadThrottleTimeout) {
            clearTimeout(lazyloadThrottleTimeout);
        }

        lazyloadThrottleTimeout = setTimeout(function () {
            const scrollTop = window.pageYOffset;
            lazyloadImages.forEach(function (img) {
                if (img.offsetTop < (window.innerHeight + scrollTop)) {
                    img.src = img.dataset.src;
                    img.classList.remove('lazy');
                }
            });
            if (lazyloadImages.length == 0) {
                document.removeEventListener("scroll", lazyload);
                window.removeEventListener("resize", lazyload);
                window.removeEventListener("orientationChange", lazyload);
            }
        }, 20);
    }
})();
// });
**/
 
/**
 * Expand the CategoryTree's tree by click on the header container.
 * - Should be loaded via Gadget in order to work properly...
 * - https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.hook
 */
mw.hook('wikipage.categories').add(function () {
	const pageName = document.querySelector('h1#firstHeading').textContent;
	const headerContainers = document.querySelectorAll('.article-header-style');
	let lock = false;
	
	// Set Cookie Function 
	function setCookie() {
		if (headerContainers.length !== 1 || lock) return;
		
		lcock = true;
		setTimeout(()=>{ lock = false }, 1000);
		
		if (localStorage.getItem('mlwTemplateContentArticleHeader') === 'clicked') {
			localStorage.setItem('mlwTemplateContentArticleHeader', 'not-clicked');
		} else if (localStorage.getItem('mlwTemplateContentArticleHeader') !== 'clicked') {
			localStorage.setItem('mlwTemplateContentArticleHeader', 'clicked');
		}
		
		console.log(localStorage.getItem('mlwTemplateContentArticleHeader'));
	}
	
	// Fuction to highlight the current item (page/category) and remove the link.
    function highlightCurrentTitle(attemptCounter = 0, headerContainer = null) {
	    let pagesInCat = headerContainer.querySelectorAll('.CategoryTreeItem a');
	    
    	if (pagesInCat.length > 1) {
	    	pagesInCat.forEach(item => {
		        if (item.title === pageName) {
		        	if (item.dataset.currentArticle !== 'true') {
			            const newItem = document.createElement('span');
			            newItem.style.fontWeight = '500';
			            newItem.textContent = item.textContent;
			            item.parentNode.replaceChild(newItem, item);
			            item.dataset.currentArticle === 'true';
		        	}
		        }
		    });
    	} else {
    		// We deal with the CategoryTrees script and the API fetch lag
    		if (attemptCounter < 100 ) {
	    		setTimeout(() => {
	    			attemptCounter++;
		    		highlightCurrentTitle(attemptCounter, headerContainer);
		    	}, 10);	
    		}
    	}
    }

	// Process each article headers
	headerContainers.forEach((headerContainer, index) => {
		// Deal with the first and last child
		if (index === 0) headerContainer.classList.add('first-header');
		if (index === headerContainers.length - 1) headerContainer.classList.add('last-header');
		
	    // Select the first toggle
		const firstToggle = headerContainer.querySelector('.CategoryTreeTag .CategoryTreeBullet .CategoryTreeToggle');
		if (!firstToggle) return;
		
	    // Extend CategoryTree First Toggle functions
	    firstToggle.addEventListener('click', (e) => { 
	    	highlightCurrentTitle(0, headerContainer); 
	    });
	    
	    firstToggle.addEventListener('mouseup', (e) => { 
	    	highlightCurrentTitle(0, headerContainer); setCookie(); 
	    });
	    
    	// Check the cookie and expand the list when it is needed
	    if (localStorage.getItem('mlwTemplateContentArticleHeader') === 'clicked' && headerContainers.length === 1) {
			setTimeout(() => {
				firstToggle.click();
			}, 10);
		}
		
	    // 'mousedown' becouse 'click' is the same event as firstToggle.click()
	    // and as result we have two clicks and the cookie is not set...
	    headerContainer.addEventListener('mousedown', (e) => {
	    	if (e.target.tagName === 'DIV' && e.target.classList.contains('article-header-style') ) {
				setCookie();
				firstToggle.click();
				
				// Higlight the selected article header - it is nice when there are more than one
				if (headerContainers.length > 1) {
					headerContainers.forEach(container => { 
						if (container === e.target) return;
						
						const firstToggle = container.querySelector('.CategoryTreeTag .CategoryTreeBullet .CategoryTreeToggle');
						
						container.classList.remove('selected-header'); 
						
						if (container.classList.contains('toggled-header')) {
							container.classList.remove('toggled-header'); 
							firstToggle.click();
						}
					});
					
	    			e.target.classList.toggle('selected-header'); 
					e.target.classList.toggle('toggled-header'); 
					
					if (e.target.classList.contains('selected-header') && 
						e.target.classList.contains('toggled-header') &&
						headerContainers.length > 3)
					{
						e.target.scrollIntoView({ behavior: "smooth", block: "start" });
					}
					
				}
	    	}
	    });
    });
});