User:Most2dot0/common.js

From Angelina Jordan Wiki

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
//syntax highlighter
mw.loader.load('//www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-DotsSyntaxHighlighter.js&action=raw&ctype=text/javascript');
syntaxHighlighterConfig = { parameterColor: "#FFDD99" }

// embedded YouTube player implementation 
// Use like this, where "&t=" designates an optional start, and "&end=" an optional stop time:
// <div class="youtube-player-placeholder" data-videos="VIDEO_ID_1&t=45&end=135,VIDEO_ID_2,VIDEO_ID_3&end=20"></div>
// It can also be configured by enclosing text that contains YouTube video urls:
// <div class="youtube-player-placeholder">
//   <ul>
//     <li><a url="https://www.youtube.com/watch?v=VIDEO_ID_1&t=45&end=135">Titel 1</a></li>
//     <li><a url="https://www.youtube.com/watch?v=VIDEO_ID_2">Titel 2</a></li>
//     <li><a url="https://www.youtube.com/watch?v=VIDEO_ID_3&end=20"></a></li>
//   </ul>
// </div>
// There can be multiple players on a page, but only one will play at a time, the others will get stopped automatically

function insertYouTubePlayers() {
    var placeholders = document.querySelectorAll('.youtube-player-placeholder');

    // Load the YouTube IFrame API if not already loaded
    if (!document.getElementById('youtube-iframe-api')) {
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        tag.id = 'youtube-iframe-api';
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }

    var videoLists = [];
    var currentVideoIndices = [];
    var checkIntervals = [];

    function parseVideosFromPlaceholder(placeholder) {
        var videoDataList = [];
        var links = placeholder.querySelectorAll('a');

        links.forEach(function(link) {
            var href = link.getAttribute('href');
            var match = href.match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)([^\s]*)/);
            if (match) {
                var videoId = match[2];
                var urlParams = match[3];
                var params = new URLSearchParams(urlParams);
                var start = params.get('t') ? parseInt(params.get('t')) : 0;
                var end = params.get('end') ? parseInt(params.get('end')) : null;
                videoDataList.push({ videoId: videoId, start: start, end: end });
            }
        });

        // If no URLs found, fall back to data-videos attribute
        if (videoDataList.length === 0) {
            var dataVideos = placeholder.getAttribute('data-videos').split(',');
            dataVideos.forEach(function(videoData) {
                var parts = videoData.split('&');
                var videoId = parts[0];
                var start = 0;
                var end = null;
                parts.forEach(function(part) {
                    if (part.startsWith('t=')) {
                        start = parseInt(part.substring(2)) || 0;
                    } else if (part.startsWith('end=')) {
                        end = parseInt(part.substring(4)) || null;
                    }
                });
                videoDataList.push({ videoId: videoId, start: start, end: end });
            });
        }

        return videoDataList;
    }

    function onYouTubeIframeAPIReady() {
        var observer = new IntersectionObserver(function(entries) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    var index = entry.target.getAttribute('data-index');
                    if (!entry.target.getAttribute('data-loaded')) {
                        entry.target.setAttribute('data-loaded', 'true');
                        loadYouTubePlayer(entry.target, index);
                    }
                }
            });
        });

        placeholders.forEach(function(placeholder, index) {
            placeholder.setAttribute('data-index', index);
            observer.observe(placeholder);
        });
    }

    window.onYouTubeIframeAPIReady = onYouTubeIframeAPIReady;

    function loadYouTubePlayer(placeholder, index) {
        var videoDataList = parseVideosFromPlaceholder(placeholder);

        videoLists[index] = videoDataList;
        currentVideoIndices[index] = 0;
        checkIntervals[index] = null;

        var playerDiv = document.createElement('div');
        playerDiv.id = 'youtube-player-' + index;
        placeholder.appendChild(playerDiv);

        var controlsDiv = document.createElement('div');
        controlsDiv.className = 'youtube-player-controls';
        controlsDiv.innerHTML = '<button class="prev-button" data-index="' + index + '">Previous</button>' +
                                '<button class="next-button" data-index="' + index + '">Next</button>';
        placeholder.appendChild(controlsDiv);

        window['youtube-player-' + index] = new YT.Player('youtube-player-' + index, {
            height: '270',
            width: '480',
            videoId: videoLists[index][currentVideoIndices[index]].videoId,
            playerVars: {
                start: videoLists[index][currentVideoIndices[index]].start
            },
            events: {
                'onStateChange': onPlayerStateChange(index),
                'onReady': onPlayerReady(index)
            }
        });

        // Add click event listeners to the YouTube links in the placeholder's text
        var links = placeholder.querySelectorAll('a');
        links.forEach(function(link) {
            var href = link.getAttribute('href');
            var match = href.match(/https?:\/\/(www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)([^\s]*)/);
            if (match) {
                var videoId = match[2];
                var urlParams = match[3];
                var params = new URLSearchParams(urlParams);
                var start = params.get('t') ? parseInt(params.get('t')) : 0;
                var end = params.get('end') ? parseInt(params.get('end')) : null;

                link.addEventListener('click', function(event) {
                    event.preventDefault();

                    var videoIndex = videoLists[index].findIndex(function(video) {
                        return video.videoId === videoId && 
                               video.start === start && 
                               video.end === end;
                    });

                    if (videoIndex !== -1) {
                        currentVideoIndices[index] = videoIndex;
                        window['youtube-player-' + index].loadVideoById({
                            videoId: videoLists[index][currentVideoIndices[index]].videoId,
                            startSeconds: videoLists[index][currentVideoIndices[index]].start
                        });
                    }
                });
            }
        });
    }

    function onPlayerReady(index) {
        return function(event) {
            var placeholder = placeholders[index];
            var originalHTML = placeholder.querySelector('.youtube-placeholder-text');
            originalHTML.style.display = ''; // Ensure the original text is displayed correctly
        };
    }

    function onPlayerStateChange(index) {
        return function(event) {
            clearInterval(checkIntervals[index]);
            if (event.data == YT.PlayerState.PLAYING) {
                // Pause all other players except the current one
                for (var i = 0; i < placeholders.length; i++) {
                    if (i !== parseInt(index) && window['youtube-player-' + i] && window['youtube-player-' + i].getPlayerState() === YT.PlayerState.PLAYING) {
                        window['youtube-player-' + i].pauseVideo();
                    }
                }

                if (videoLists[index][currentVideoIndices[index]].end) {
                    checkIntervals[index] = setInterval(function() {
                        var currentTime = window['youtube-player-' + index].getCurrentTime();
                        if (currentTime >= videoLists[index][currentVideoIndices[index]].end) {
                            playVideo(index, 1); // Play next video
                        }
                    }, 1000); // Check every second
                }
            } else if (event.data == YT.PlayerState.ENDED) {
                playVideo(index, 1); // Play next video
            }
        };
    }

    function playVideo(index, direction) {
        clearInterval(checkIntervals[index]);
        currentVideoIndices[index] += direction;
        if (currentVideoIndices[index] >= videoLists[index].length) {
            currentVideoIndices[index] = 0;
        } else if (currentVideoIndices[index] < 0) {
            currentVideoIndices[index] = videoLists[index].length - 1;
        }
        window['youtube-player-' + index].loadVideoById({
            videoId: videoLists[index][currentVideoIndices[index]].videoId,
            startSeconds: videoLists[index][currentVideoIndices[index]].start
        });
    }

    document.addEventListener('click', function(event) {
        if (event.target.classList.contains('next-button')) {
            var index = event.target.getAttribute('data-index');
            playVideo(index, 1); // Next video
        } else if (event.target.classList.contains('prev-button')) {
            var index = event.target.getAttribute('data-index');
            playVideo(index, -1); // Previous video
        }
    });
}

insertYouTubePlayers();




//
// New combined YouTube and Facebook player implementation
//




function insertFacebookPlayers() {
    var placeholders = document.querySelectorAll('.facebook-player-placeholder');

    if (!document.getElementById('facebook-jssdk')) {
        var tag = document.createElement('script');
        tag.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v10.0";
        tag.id = 'facebook-jssdk';
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }

    var videoLists = [];
    var currentVideoIndices = [];
    var checkIntervals = [];

    function parseVideosFromPlaceholder(placeholder) {
        var videoDataList = [];
        var links = placeholder.querySelectorAll('a');

        links.forEach(function(link) {
            var href = link.getAttribute('href');
            console.log("Parsing href: " + href);
            var match = href.match(/https?:\/\/(www\.)?facebook\.com\/.*\/videos\/([0-9]+)/);
            if (match) {
                var videoId = match[2];
                console.log("Found videoId: " + videoId);
                var urlParams = new URLSearchParams(new URL(href).search);
                var start = urlParams.get('t') ? parseInt(urlParams.get('t').replace('s', '')) : 0;
                var end = urlParams.get('end') ? parseInt(urlParams.get('end').replace('s', '')) : null;
                console.log("Parsed start: " + start + ", end: " + end);
                videoDataList.push({ videoId: videoId, start: start, end: end });
            }
        });

        return videoDataList;
    }

    function onFacebookSDKReady() {
        var observer = new IntersectionObserver(function(entries) {
            entries.forEach(function(entry) {
                if (entry.isIntersecting) {
                    var index = entry.target.getAttribute('data-index');
                    if (!entry.target.getAttribute('data-loaded')) {
                        entry.target.setAttribute('data-loaded', 'true');
                        loadFacebookPlayer(entry.target, index);
                    }
                }
            });
        });

        placeholders.forEach(function(placeholder, index) {
            placeholder.setAttribute('data-index', index);
            observer.observe(placeholder);
        });
    }

    window.fbAsyncInit = function() {
        FB.init({
            xfbml: true,
            version: 'v10.0'
        });
        onFacebookSDKReady();
    };

    function loadFacebookPlayer(placeholder, index) {
        var videoDataList = parseVideosFromPlaceholder(placeholder);
        console.log("Video data list for placeholder " + index + ": ", videoDataList);

        videoLists[index] = videoDataList;
        currentVideoIndices[index] = 0;
        checkIntervals[index] = null;

        var videoData = videoLists[index][currentVideoIndices[index]];
        console.log("Loading video for placeholder " + index + ": ", videoData);

        var playerDiv = document.createElement('div');
        playerDiv.id = 'facebook-player-' + index;
        placeholder.appendChild(playerDiv);

        var fbVideo = document.createElement('div');
        fbVideo.className = 'fb-video';
        fbVideo.setAttribute('data-href', 'https://www.facebook.com/facebook/videos/' + videoData.videoId + '/');
        fbVideo.setAttribute('data-width', '480');
        playerDiv.appendChild(fbVideo);

        // Add "Next Video" button
        var nextButton = document.createElement('button');
        nextButton.textContent = 'Next Video';
        nextButton.onclick = function() {
            console.log("Next video button clicked for placeholder " + index);
            loadNextVideo(index);
        };
        placeholder.appendChild(nextButton);

        // Parse the initial set of XFBML tags in the document
        FB.XFBML.parse(playerDiv, function() {
            console.log("Parsed XFBML for placeholder " + index);
            retryPlayerInit(index, videoData);
        });
    }

    function retryPlayerInit(index, videoData) {
        var attempts = 0;
        var maxAttempts = 20;

        function tryInitPlayer() {
            var videoPlayer = document.getElementById('facebook-player-' + index);
            if (videoPlayer && FB && FB.XFBML && FB.XFBML.parse) {
                try {
                    console.log("Attempting to initialize player for placeholder " + index);
                    FB.XFBML.parse(videoPlayer, function() {
                        handlePlayerReady(videoPlayer, videoData, index);
                    });
                } catch (e) {
                    console.log("Attempt " + attempts + " failed for placeholder " + index);
                    attempts++;
                    if (attempts < maxAttempts) {
                        setTimeout(tryInitPlayer, 200);
                    }
                }
            } else {
                console.log("Video player or FB XFBML not ready, retrying...");
                attempts++;
                if (attempts < maxAttempts) {
                    setTimeout(tryInitPlayer, 200);
                }
            }
        }

        tryInitPlayer();
    }

    function handlePlayerReady(videoPlayer, videoData, index) {
        var fbVideoElement = videoPlayer.querySelector('.fb-video');
        if (fbVideoElement && FB && FB.Event && fbVideoElement.fbPlayer) {
            console.log("Handling player ready for placeholder " + index);
            fbVideoElement.fbPlayer.seek(videoData.start);
            fbVideoElement.fbPlayer.play();

            checkIntervals[index] = setInterval(function() {
                var currentTime = fbVideoElement.fbPlayer.getCurrentPosition();
                console.log("Checking position for video in placeholder " + index + ": " + currentTime);
                if (currentTime >= videoData.end) {
                    fbVideoElement.fbPlayer.pause();
                    clearInterval(checkIntervals[index]);
                    console.log("Video in placeholder " + index + " reached end time and paused.");
                }
            }, 1000); // Check every second
        } else {
            console.log("Player not ready, retrying...");
            setTimeout(function() {
                handlePlayerReady(videoPlayer, videoData, index);
            }, 200);
        }
    }

    function loadNextVideo(index) {
        if (currentVideoIndices[index] + 1 < videoLists[index].length) {
            currentVideoIndices[index]++;
            clearInterval(checkIntervals[index]);
            var videoData = videoLists[index][currentVideoIndices[index]];
            console.log("Loading next video for placeholder " + index + ": ", videoData);

            var playerDiv = document.getElementById('facebook-player-' + index);
            playerDiv.innerHTML = ''; // Clear the previous video

            var fbVideo = document.createElement('div');
            fbVideo.className = 'fb-video';
            fbVideo.setAttribute('data-href', 'https://www.facebook.com/facebook/videos/' + videoData.videoId + '/');
            fbVideo.setAttribute('data-width', '480');
            playerDiv.appendChild(fbVideo);

            FB.XFBML.parse(playerDiv, function() {
                console.log("Parsed XFBML for next video in placeholder " + index);
                retryPlayerInit(index, videoData);
            });
        } else {
            console.log("No more videos in the list for placeholder " + index);
        }
    }

    var observer = new IntersectionObserver(function(entries) {
        entries.forEach(function(entry) {
            if (entry.isIntersecting) {
                var index = entry.target.getAttribute('data-index');
                if (!entry.target.getAttribute('data-loaded')) {
                    entry.target.setAttribute('data-loaded', 'true');
                    loadFacebookPlayer(entry.target, index);
                }
            }
        });
    });

    placeholders.forEach(function(placeholder, index) {
        placeholder.setAttribute('data-index', index);
        observer.observe(placeholder);
    });
}

insertFacebookPlayers();