MediaWiki:Vector.js: Difference between revisions

From Forklift Certified Video Games
Jump to navigation Jump to search
Line 138: Line 138:
/* Page Forms Image Sync Fix. Automatically "clicks" and focuses the image field after an upload to ensure the data is synced and recognized by the form. */
/* Page Forms Image Sync Fix. Automatically "clicks" and focuses the image field after an upload to ensure the data is synced and recognized by the form. */
(function($) {
(function($) {
     /**
     var observer = new MutationObserver(function(mutations) {
    * Universal Page Forms Input Sync
         mutations.forEach(function(mutation) {
    * Wakes up ANY field after an upload by simulating the physical interaction
             // Only trigger if the actual value of an input was changed
    * required to trigger internal extension events.
             if (mutation.type === "attributes" && mutation.attributeName === "value") {
    */
                 var target = mutation.target;
    $(document).on('pfUploadComplete', function(event) {
         // Short delay to ensure the extension has finished injecting the filename
        setTimeout(function() {
             // Target all form controls that could hold the filename
             $('input, select, textarea').each(function() {
                 var $el = $(this);
                  
                  
                 // Only act on fields that have content (the newly uploaded filename)
                 // Only act if the field is not empty (it just received a filename)
                 if ($el.val() && $el.val().length > 0) {
                 if (target.value !== "" && target.tagName === 'INPUT') {
                      
                      
                     // 1. Simulate a REAL hardware-level mouse click
                     // 1. Simulate a real hardware-level click
                     // This bypasses many JS library restrictions
                     // This is what 'wakes up' the Select2/Combobox library
                     var el = $el[0];
                     target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
                     var clickEvent = new MouseEvent('click', {
                     target.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
                        view: window,
                     target.dispatchEvent(new MouseEvent('click', { bubbles: true }));
                        bubbles: true,
                        cancelable: true
                    });
                     el.dispatchEvent(clickEvent);


                     // 2. Force the cursor into the field
                     // 2. Force cursor focus
                     $el.focus();
                    target.focus();
 
                    // 3. Dispatch the internal events Page Forms listens for
                     target.dispatchEvent(new Event('input', { bubbles: true }));
                    target.dispatchEvent(new Event('change', { bubbles: true }));
                      
                      
                     // 3. Fire every event that Select2, OOUI, or Page Forms might be watching
                     console.log("PF Sync: Field activated for value: " + target.value);
                    $el.trigger('change');
                    $el.trigger('input');
                    $el.trigger('blur');
                   
                    // 4. Specifically target Select2 if it's detected on the field
                    if ($el.data('select2')) {
                        $el.trigger('change.select2');
                    }
                 }
                 }
             });
             }
         }, 150);
        });
    });
 
    // Start watching all inputs as soon as the form is ready
    $(document).ready(function() {
        $('input').each(function() {
            observer.observe(this, { attributes: true });
         });
     });
     });
})(jQuery);
})(jQuery);

Revision as of 15:07, 25 April 2026

/* All JavaScript here will be loaded for users of the Vector skin */

/* Redirect ALL red links to the "Create Page" page */
$('.new').on('click', function(e) {
    e.preventDefault();
    window.location.href = mw.util.getUrl('Fork:Create_Page');
});

/* Accelerate native Vector collapsible tabs */
( function () {
    var triggerNativeTabs = function () {
        if ( mw.config.get( 'skin' ) === 'vector' ) {
            // Forces the native script to recalculate and move links into the "More" menu
            $( window ).trigger( 'resize' );
        }
    };
    // Run as soon as the basic page structure is ready
    $( triggerNativeTabs );
}() );

// Force immediate check for collapsible tabs in Vector Legacy
mw.loader.using( 'mediawiki.util' ).done( function () {
    $( function () {
        if ( mw.config.get( 'skin' ) === 'vector' ) {
            // Trigger the resize event immediately on load
            $( window ).trigger( 'resize' );
        }
    } );
} );

/* Move subcategories to the top on Category:Forklifts and Category:Video_Games */
if ( mw.config.get( 'wgPageName' ) === 'Category:Forklifts' || mw.config.get( 'wgPageName' ) === 'Category:Video_Games' ) {
    $( function() {
        var subcats = $( '#mw-subcategories' );
        var content = $( '.mw-parser-output' );
        if ( subcats.length && content.length ) {
            subcats.insertBefore( content );
            $( 'body' ).addClass( 'move-subcategories-up-active' );
            $( '#bodyContent' ).css( { 'display': 'flex', 'flex-direction': 'column' } );
            content.css( 'order', '2' );
            subcats.css( 'order', '1' );
        }
    } );
}

/* SHOW ALL BUTTON */
mw.loader.using(['mediawiki.util', 'jquery'], function() {
    $(function() {
        $('.cargo-show-all-btn').on('click', function() {
            var $this = $(this);
            var $grid = $this.siblings('.cargo-hidden-grid');

            // Toggle visibility
            $grid.toggleClass('grid-visible');
            
            // Dynamic text switching
            var isVisible = $grid.hasClass('grid-visible');
            var originalText = $this.text();
            
            if (isVisible) {
                $this.data('original-text', originalText);
                $this.text(originalText.replace('Show All', 'Hide')).addClass('btn-active');
            } else {
                $this.text($this.data('original-text')).removeClass('btn-active');
            }
        });
    });
});


/* NEWS SLIDESHOW */
mw.loader.using('mediawiki.util').then(function () {
    mw.hook('wikipage.content').add(function () {
        document.querySelectorAll('.news-slideshow-container').forEach(function (container) {
            var slides = container.querySelectorAll('.news-slideshow-slide');
            if (slides.length <= 1) return;

            var current = 0;
            var intervalId = null;
            var delay = 8000; // 8 seconds

            function showSlide(index) {
                slides.forEach(function (slide, i) {
                    slide.classList.toggle('active', i === index);
                });
            }

            function startSlideshow() {
                if (intervalId !== null) return;
                intervalId = setInterval(function () {
                    current = (current + 1) % slides.length;
                    showSlide(current);
                }, delay);
            }

            function stopSlideshow() {
                if (intervalId !== null) {
                    clearInterval(intervalId);
                    intervalId = null;
                }
            }

            // Initial state
            showSlide(current);
            startSlideshow();

            // Pause on hover
            container.addEventListener('mouseenter', stopSlideshow);
            container.addEventListener('mouseleave', startSlideshow);
        });
    });
});


/* FORM TABLE */
document.addEventListener('click', function (e) {
	const header = e.target.closest('.pf-collapsible');
	if (!header) return;

	const targetId = header.dataset.target;
	const section = document.getElementById(targetId);
	if (!section) return;

	const isOpen = section.style.display === 'block';
	section.style.display = isOpen ? 'none' : 'block';
});

/* CLICKABLE HOME BUTTON AT THE TOP IN MOBILE VIEW */
$(document).ready(function() {
    $('#left-navigation').on('click', function(e) {
        if (e.target === this || $(e.target).is('::before')) {
            window.location.href = mw.config.get('wgArticlePath').replace('$1', '');
        }
    });
});


/* Page Forms Image Sync Fix. Automatically "clicks" and focuses the image field after an upload to ensure the data is synced and recognized by the form. */
(function($) {
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            // Only trigger if the actual value of an input was changed
            if (mutation.type === "attributes" && mutation.attributeName === "value") {
                var target = mutation.target;
                
                // Only act if the field is not empty (it just received a filename)
                if (target.value !== "" && target.tagName === 'INPUT') {
                    
                    // 1. Simulate a real hardware-level click
                    // This is what 'wakes up' the Select2/Combobox library
                    target.dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
                    target.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }));
                    target.dispatchEvent(new MouseEvent('click', { bubbles: true }));

                    // 2. Force cursor focus
                    target.focus();

                    // 3. Dispatch the internal events Page Forms listens for
                    target.dispatchEvent(new Event('input', { bubbles: true }));
                    target.dispatchEvent(new Event('change', { bubbles: true }));
                    
                    console.log("PF Sync: Field activated for value: " + target.value);
                }
            }
        });
    });

    // Start watching all inputs as soon as the form is ready
    $(document).ready(function() {
        $('input').each(function() {
            observer.observe(this, { attributes: true });
        });
    });
})(jQuery);