MediaWiki:Common.js: Difference between revisions

From PRS
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
/* Any JavaScript here will be loaded for all users on every page load. */
/* Any JavaScript here will be loaded for all users on every page load. */


/* ── Force TMH video to preload and keep native controls ── */
/* ── DIAGNOSTIC: Watch what TMH does to the video element ── */
$(function () {
$(function () {
     if ($('.training-video-wrap').length === 0) return;
     if ($('.training-video-wrap').length === 0) return;


     function fixVideo() {
     function startWatching() {
         var video = document.querySelector('.mw-file-element');
         var video = document.querySelector('.mw-file-element');
         if (video) {
         if (!video) {
             video.removeAttribute('disabled');
             setTimeout(startWatching, 100);
            video.setAttribute('controls', 'controls');
             return;
            video.setAttribute('playsinline', 'true');
            video.preload = 'auto';
            video.load();
             return true;
         }
         }
        return false;
    }


    /* Try immediately */
        console.log('=== TMH DIAGNOSTIC STARTED ===');
    if (!fixVideo()) {
         console.log('Initial video attributes:');
         /* If video not ready yet, keep trying */
         for (var i = 0; i < video.attributes.length; i++) {
         var checkInterval = setInterval(function () {
             console.log('  ' + video.attributes[i].name + '="' + video.attributes[i].value + '"');
             if (fixVideo()) clearInterval(checkInterval);
         }
         }, 100);
    }


    /* Keep re-applying every 500ms for 5 seconds to beat Video.js */
        /* Watch for any attribute changes on the video element */
    var count = 0;
        var observer = new MutationObserver(function (mutations) {
    var forceInterval = setInterval(function () {
            mutations.forEach(function (mutation) {
        fixVideo();
                if (mutation.type === 'attributes') {
        count++;
                    console.log('ATTR CHANGED: ' + mutation.attributeName + ' = "' + mutation.target.getAttribute(mutation.attributeName) + '" (was: "' + mutation.oldValue + '")');
        if (count > 10) clearInterval(forceInterval);
                }
    }, 500);
                if (mutation.type === 'childList') {
});
                    console.log('CHILD ADDED/REMOVED on: ' + mutation.target.className);
                }
            });
        });


/* ============================================================
        observer.observe(video, {
  Training Video – Synced Transcript Sidebar
            attributes: true,
  ============================================================ */
            attributeOldValue: true,
$(function () {
            childList: true,
    /* Only run on pages that contain a training video wrapper */
            subtree: true
    if ($('.training-video-wrap').length === 0) return;
        });
 
    /* ── Find elements ── */
    var $video      = $('.training-video-wrap video');
    var $entries    = $('.ts-entry');
    var $body      = $('.ts-scroll-body');
    var $markers    = $('.ts-progress-marker');
    var $fill      = $('.ts-progress-fill');
    var $timeDisp  = $('.ts-time-display');
 
    if ($video.length === 0) return; // no video on this page


    var videoEl = $video[0];
        /* Also watch the parent container */
 
         var parent = document.querySelector('.mw-tmh-player');
    /* ── Format seconds → m:ss ── */
         if (parent) {
    function fmt(s) {
             observer.observe(parent, {
         s = Math.floor(s);
                attributes: true,
        return Math.floor(s / 60) + ':' + ('0' + (s % 60)).slice(-2);
                attributeOldValue: true,
    }
                childList: true,
 
                 subtree: false
    /* ── Collect timestamp data from DOM ── */
            });
    var timestamps = [];
    $entries.each(function () {
        timestamps.push(parseInt($(this).data('time'), 10));
    });
 
    /* ── Highlight the active transcript entry ── */
    function highlightActive() {
        var cur = videoEl.currentTime;
        var activeIdx = 0;
         for (var i = 0; i < timestamps.length; i++) {
            if (cur >= timestamps[i]) activeIdx = i;
        }
        $entries.each(function (i) {
             $(this).toggleClass('ts-active', i === activeIdx);
        });
        /* Auto-scroll transcript panel to keep active line visible */
        var $active = $entries.eq(activeIdx);
        if ($active.length && $body.length) {
            var entryTop      = $active.position().top;
            var bodyScrollTop = $body.scrollTop();
            var bodyHeight    = $body.height();
            if (entryTop < 0 || entryTop > bodyHeight - 60) {
                 $body.animate({ scrollTop: bodyScrollTop + entryTop - 60 }, 200);
            }
         }
         }
    }


    /* ── Update progress bar ── */
         console.log('=== NOW WATCHING FOR CHANGES ===');
    function updateProgress() {
         if (!videoEl.duration) return;
        var pct = (videoEl.currentTime / videoEl.duration) * 100;
        $fill.css('width', pct + '%');
        $timeDisp.text(fmt(videoEl.currentTime) + ' / ' + fmt(videoEl.duration));
     }
     }


     /* ── Bind native video events ── */
     startWatching();
    $video.on('timeupdate', function () {
        highlightActive();
        updateProgress();
    });
 
    $video.on('loadedmetadata', function () {
        $timeDisp.text('0:00 / ' + fmt(videoEl.duration));
        /* Position progress bar markers once duration is known */
        $markers.each(function () {
            var t = parseInt($(this).data('time'), 10);
            $(this).css('left', ((t / videoEl.duration) * 100) + '%');
        });
    });
 
    /* ── Transcript entry click → seek video ── */
    $entries.on('click', function () {
        var t = parseInt($(this).data('time'), 10);
        videoEl.currentTime = t;
        if (videoEl.paused) videoEl.play();
        highlightActive();
    });
 
    /* ── Progress bar click → seek ── */
    $('.ts-progress-track').on('click', function (e) {
        var rect  = this.getBoundingClientRect();
        var ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
        videoEl.currentTime = ratio * videoEl.duration;
    });
 
    /* ── Marker click → seek ── */
    $markers.on('click', function (e) {
        e.stopPropagation();
        var t = parseInt($(this).data('time'), 10);
        videoEl.currentTime = t;
        if (videoEl.paused) videoEl.play();
    });
 
});
});
/* ============================================================ */

Revision as of 08:18, 22 April 2026

/* Any JavaScript here will be loaded for all users on every page load. */

/* ── DIAGNOSTIC: Watch what TMH does to the video element ── */
$(function () {
    if ($('.training-video-wrap').length === 0) return;

    function startWatching() {
        var video = document.querySelector('.mw-file-element');
        if (!video) {
            setTimeout(startWatching, 100);
            return;
        }

        console.log('=== TMH DIAGNOSTIC STARTED ===');
        console.log('Initial video attributes:');
        for (var i = 0; i < video.attributes.length; i++) {
            console.log('  ' + video.attributes[i].name + '="' + video.attributes[i].value + '"');
        }

        /* Watch for any attribute changes on the video element */
        var observer = new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                if (mutation.type === 'attributes') {
                    console.log('ATTR CHANGED: ' + mutation.attributeName + ' = "' + mutation.target.getAttribute(mutation.attributeName) + '" (was: "' + mutation.oldValue + '")');
                }
                if (mutation.type === 'childList') {
                    console.log('CHILD ADDED/REMOVED on: ' + mutation.target.className);
                }
            });
        });

        observer.observe(video, {
            attributes: true,
            attributeOldValue: true,
            childList: true,
            subtree: true
        });

        /* Also watch the parent container */
        var parent = document.querySelector('.mw-tmh-player');
        if (parent) {
            observer.observe(parent, {
                attributes: true,
                attributeOldValue: true,
                childList: true,
                subtree: false
            });
        }

        console.log('=== NOW WATCHING FOR CHANGES ===');
    }

    startWatching();
});