Greasy Fork

stream4chan

Click the button to stream all webms in a 4chan thread

目前为 2016-10-21 提交的版本。查看 最新版本

// ==UserScript==
// @name         stream4chan
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Click the button to stream all webms in a 4chan thread
// @author       Lauchlan105
// @match        http://boards.4chan.org/*/thread/*
// @grant        none
// ==/UserScript==

//Main
(function() {
    createElements();
    initElements();
    startEvents();
})();

function createElements(){
    //Script Settings
    countStep = 1; //Duration step
    debugOn = false;
    hiddenPrints = [];
    var checked = 'checked';
    var notChecked = '';
    var autoPlayDefault = checked;
    var playWebmsDefault = checked;
    var playGifsDefault = checked;
    var loopThreadDefault = checked;
    var randomDefault = notChecked;
    var durationDefault = '3'; //seconds
    


    //Settings Header
    var modalSettings_auto = '<li class="SFC-li"><input id="stream4chan-auto?" class="SFC-input" type="checkbox" ' + autoPlayDefault + '> Play Automatically</li>';
    var modalSettings_webms = '<li class="SFC-li"><input id="stream4chan-webms?" class="SFC-input" type="checkbox" ' + playWebmsDefault + '> Play Webms</li>';
    var modalSettings_gifs = '<li class="SFC-li"><input id="stream4chan-gifs?" class="SFC-input" type="checkbox" ' + playGifsDefault + '> Play Gifs</li>';
    var modalSettings_loopAll = '<li class="SFC-li"><input id="stream4chan-loopAll?" class="SFC-input" type="checkbox" ' + loopThreadDefault + '> Loop whole thread</li>';
    var modalSettings_shuffle = '<li class="SFC-li"><input id="stream4chan-shuffle?" class="SFC-input" type="button" value=" shuffle "></li>';
    var modalSettings_random = '<li class="SFC-li"><input id="stream4chan-random?" class="SFC-input" type="checkbox" ' + randomDefault + '> Random</li>';
    var modalSettings_duration = '<li class="SFC-li"><input id="stream4chan-duration?" class="SFC-input" type="number" min="' + countStep + '" max="60" value="' + durationDefault + '" step="' + countStep + '"> Gif Duration (Seconds)</li>';
    var modalSettings = '<ul id="stream4chan-settings" class="SFC-settings">' + modalSettings_auto + modalSettings_webms + modalSettings_gifs + modalSettings_loopAll + modalSettings_shuffle + modalSettings_random + modalSettings_duration + '</ul>';

    //Content Table
    var modalContent = '<div id="stream4chan-content" class="SFC-content"></div>';
    var modalContent_Left = '<th id="stream4chan-prev" class="SFC_th_left SFC_arrow"></th>';
    var modalContent_Right = '<th id="stream4chan-next" class="SFC_th_right SFC_arrow"></th>';
    var modalContent_Mid = '<th class="SFC_th_mid">' + modalSettings + modalContent + '</th>';
    var modalTable = '<table id="stream4chan-table" class="SFC_table"><tr class="SFC_table_row">' + modalContent_Left + modalContent_Mid + modalContent_Right + '</tr></table>';

    //Main Div
    var startBtn = '<input id="stream4chan-start" style="margin-left:1em;" type="button" value="Run Slideshow" >';
    var resumeBtn = '<input id="stream4chan-resume" style="margin-left:1em;" type="button" value="Resume Slideshow" >';
    var modalMain = '<div id="stream4chan-modal" class="SFC-modal">' + modalTable + '</div>';

    //CSS
    var settingsCSS = '.SFC-settings { opacity: 0.35; display: inline-block; list-style-type: none; width:100%; top: 0; height: 25px; margin: 0em; padding: 0em } .SFC-settings:hover { opacity: 1; }';
    var settingsLiCSS = '.SFC-li { display: inline-block; padding-left: 1em; color:#9d9393;}';
    var settingsInputCSS = '.SFC-input { margin: 0em; padding: 0em; padding-top: 0.3em; width: auto;  }';
    var AllSettingsCSS = settingsCSS + settingsLiCSS + settingsInputCSS;

    //table
    var tableCSS = '.SFC_table { max-height: 100vh; min-height: 100vh; max-width: 100vw; min-width: 100vw; } ';
    var tableRowCSS = '.SFC_table_row { vertical-align: top; }';
    var arrowCSS = '.SFC_arrow { width: 15px; padding: 15px; height: 100%; background-image: url("http://www.dsetechnology.co.uk/images/disclose-arrow.png"); background-repeat: no-repeat; background-position: center; background-color: rgba(255, 255, 255, 0); background-size: contain; }';
    var leftCSS = '.SFC_th_left { transform: rotate(180deg); }' + '.SFC_th_left:hover { background-color:rgba(255, 255, 255, 0.6); }';
    var rightCSS = '.SFC_th_right {  }' + '.SFC_th_right:hover { background-color:rgba(255, 255, 255, 0.6); }';
    var midCSS = '.SFC_th_mid { height: 100vh;  }';
    var allTableCSS = tableCSS + tableRowCSS + arrowCSS + leftCSS + rightCSS + midCSS;

    var mediaCSS = '.SFC-media { width: 100%; }';
    var contentCSS = '.SFC-content { display: block; color: white; }';
    var modalCSS = ' .SFC-modal { display: none; height: 100vh; width: 100vw; position: fixed; z-index: 1; left: 0; top: 0; background-color: rgba(0,0,0,0.75); -webkit-box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75); -moz-box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75); box-shadow: inset 0px 0px 71px 41px rgba(0,0,0,0.75);}';
    var allModalCSS = mediaCSS + contentCSS + modalCSS;
    var allCSS = '<style>' + allModalCSS + allTableCSS + AllSettingsCSS + '</style>';


    //Add start and resume buttons
    var nav = document.getElementsByClassName('navLinks desktop');
    for(var i = 0; i < nav.length; i++){
        debug('adding button to nav ' + i);

        var span = document.createElement('span');

        span.innerHTML = startBtn + resumeBtn;
        span.className = 'stream4chan-start';
        span.style.display = nav[i].style.display;

        nav[i].parentNode.insertBefore(span, nav[i]);
        nav[i].parentNode.insertBefore(document.getElementById('op'), nav[i]);
    }

    //add the modal to start of thread
    var target = document.getElementsByClassName('thread');
    for(i = 0; i < target.length; i++){
        target[i].innerHTML = (modalMain + allCSS) + target[i].innerHTML;
    }
}

function initElements(){
    modal = document.getElementById('stream4chan-modal');
    if(!modal){ debug('Modal not found!'); }

    table = document.getElementById('stream4chan-table');
    if(!table){ debug('Table not found!'); }

    settings = document.getElementById('stream4chan-settings');
    if(!settings){ debug('Settings not found!'); }

    content = document.getElementById('stream4chan-content');
    if(!content){ debug('Content not found!'); }

    //Interactable Elements
    prevButton = document.getElementById('stream4chan-prev');
    if(!prevButton){ debug('Previous Button not found!'); }

    nextButton = document.getElementById('stream4chan-next');
    if(!nextButton){ debug('Next Button not found!'); }

    startButton = document.getElementById('stream4chan-start');
    if(!startButton){ debug('Start Button could not be found!');}

    resumeButton = document.getElementById('stream4chan-resume');
    if(!resumeButton){ debug('Resume Button could not be found!');}

    autoplay = document.getElementById('stream4chan-auto?');
    if(!autoplay){ debug('Autoplay checkbox not found!');}

    playWebms = document.getElementById('stream4chan-webms?');
    if(!playWebms){ debug('Player Webms input not found!');}

    playGifs = document.getElementById('stream4chan-gifs?');
    if(!playGifs){ debug('Player Gifs input not found!');}

    loop = document.getElementById('stream4chan-loopAll?');
    if(!loop){ debug('"loopAll" could not be found!'); }

    random = document.getElementById('stream4chan-random?');
    if(!random){ debug('"random" could not be found!'); }

    shuffle = document.getElementById('stream4chan-shuffle?');
    if(!shuffle){ debug('"shuffle" could not be found!'); }

    duration = document.getElementById('stream4chan-duration?');
    if(!duration){ debug('Gif duration input not found!');}

    currentVideo = 'start';
    currentTime = 0;
    currentTimeout = setTimeout(0);
    modalOn = false;
    shuffled = false;

    //hrefs = document.getElementsByClassName('fileThumb');
    hrefs = [];
    backup = [];
    preload(hrefs);
}

function startEvents(){

    window.onresize = function(){ setDimensions(contentExists()); };
    window.onclick = function(event){if (event.target.id == 'stream4chan-content'){ stop(); }};
    window.onkeydown = function(event){
        event.target.blur();
        if(!toggleDebug(event)){
            //up arrow
            if(event.keyCode == 38 && modalOn){
                val = parseInt(duration.value, 10);
                max = parseInt(duration.max, 10);
                val += countStep;
                if(val > max){ val = max; }
                duration.value = val;
            }

            //Down arrow
            if(event.keyCode == 40 && modalOn){
                val = parseInt(duration.value, 10);
                min = parseInt(duration.min, 10);
                val -= countStep;
                if(val < min){ val = min; }
                duration.value = val;
            }
        }
    };
    window.onkeyup = function(event){
        event.target.blur();
        if(modalOn){
            //left arrow
            if(event.keyCode == 37){
                previousVideo();
            }

            //right arrow
            if(event.keyCode == 39){
                nextVideo();
            }

            //Escape key
            if(event.keyCode == 27){
                stop();
            }

            //W key
            if(event.keyCode == 87){
                playWebms.checked = !playWebms.checked;
            }

            //G key
            if(event.keyCode == 71){
                playGifs.checked = !playGifs.checked;
            }

            //A key
            if(event.keyCode == 65){
                autoplay.checked = !autoplay.checked;
                applyAutoplay();
            }

            //L key
            if(event.keyCode == 76){
                loopAll.checked = !loopAll.checked;
            }

            //R key
            if(event.keyCode == 82){
                random.checked = !random.checked;
                if(random.checked){
                    shuffleArr();
                }else{
                    unshuffleArr();
                }
            }

            //S key
            if(event.keyCode == 83){
                if(shuffle.value === ' shuffle '){
                    shuffleArr();
                }else{
                    unshuffleArr();
                }
            }

            //Space key
            if(event.keyCode == 32){
                if(contentExists()){
                    pauseContent();
                }else{
                    start(currentVideo, currentTime);
                }
            }
        }
    };

    startButton.onclick = function(){ start(); };
    resumeButton.onclick = function(){ start(currentVideo, currentTime); };
    autoplay.onclick = function(){ applyAutoplay(); };
    random.onclick = function(){
        if(random.checked){
            shuffleArr();
        }else{
            unshuffleArr();
        }
    };
    prevButton.onclick = function(){ previousVideo(); };
    nextButton.onclick = function(){ nextVideo(); };
    shuffle.onclick = function(){
        if(shuffle.value === ' unshuffle '){
            unshuffleArr();
        }else{
            shuffleArr();
        }
    };

}

function displayModal(state){
    var body = document.getElementsByTagName('body');
    if(state === true){
        debug('Show Modal');
        modalOn = state;
        modal.style.display = 'block';

        //removes scoll bar
        for(i = 0; i < body.length; i++){
            if(body[i]){ body[i].style.overflow = "hidden"; }
        }
    }else if(state === false){
        debug('Hide Modal');
        modalOn = state;
        modal.style.display = 'none';

        //removes scoll bar
        for(i = 0; i < body.length; i++){
            if(body[i]){ body[i].style.overflow = "scroll"; }
        }
    }else{
        if(modalOn){
            debug('Hide Modal');
            modal.style.display = 'none';

            //removes scoll bar
            for(i = 0; i < body.length; i++){
                if(body[i]){ body[i].style.overflow = "scroll"; }
            }
        }else{
            debug('Show Modal');
            modal.style.display = 'block';

            //removes scoll bar
            for(i = 0; i < body.length; i++){
                if(body[i]){ body[i].style.overflow = "hidden"; }
            }
        }
        modalOn = !modalOn;
    }
}

function start(crntVid, crntTime){
    var newStart = (!crntVid && (crntVid !== 0));
    currentVideo = !newStart ? crntVid-1 : 'start';
    currentTime = crntTime ? crntTime : 0;

    //resume if starting from the beginning
    if(newStart){ unshuffleArr(); }

    displayModal(true);
    nextVideo();
}

function stop(){
    if(contentExists()){
        currentTime = contentExists('webm') ? contentExists('webm').currentTime : 0;
        pauseContent();
    }
    content.innerHTML = '';
    displayModal(false);
}

function nextVideo(){

    pauseContent();
    if(currentVideo === 'start'){ currentVideo = -1; }

    //While the href can't be played
    do{
        currentVideo++;
        if(loop.checked){
            currentVideo = currentVideo % hrefs.length;
        }

        var temp = noContentToDisplay();
        if(temp){
            stop();
            displayModal(true);
            content.innerHTML = temp;
            return;
        }
    }while(!canPlay(hrefs[currentVideo]));

    playContent(hrefs[currentVideo]);

    //add events for next video
    applyAutoplay();
}

function previousVideo(){
    debug('Function: previousVideo');

    pauseContent();
    if(currentVideo === 'start'){ currentVideo = 0; }

    //While the href can't be played
    do{
        currentVideo--;
        if(loop.checked){
            if(currentVideo === -1){ currentVideo = hrefs.length -1;}
        }

        var temp = noContentToDisplay();
        if(temp){
            stop();
            displayModal(true);
            content.innerHTML = temp;
            return;
        }
    }while(!canPlay(hrefs[currentVideo]));

    playContent(hrefs[currentVideo]);

    //add events for next video
    applyAutoplay();
}

function playContent(currentContent){
    debug('Function: playContent');
    content.innerHTML = '';
    if(random.checked){ shuffleArr(); }
    content.appendChild(currentContent);
    setDimensions(contentExists());
    if(contentExists('webm')){
        contentExists('webm').currentTime = currentTime;
        currentTime = 0;
        contentExists('webm').play();
    }
    //if(contentExists('gif')){ setTimeout(function(){}, duration.value); }
}

function pauseContent(){
    debug('Function: pauseContent');
    var x = contentExists('webm');
    if(x){
        x.removeEventListener('ended', nextVideo, false);
        x.loop = true;
        x.pause();
    }
    clearTimeout(currentTimeout);
    content.innerHTML = 'Paused';
}

function canPlay(currentContent){
    return ( (playGifs.checked && (getFileExt(currentContent.src) === 'gif')) || (playWebms.checked && (getFileExt(currentContent.src) === 'webm')) );
}

function getFileExt(input){
    temp = input.toString();
    return temp.substr(temp.lastIndexOf('.') + 1);
}

function preload(arr){
    debug('Function: preload');
    var temp = document.getElementsByClassName('fileThumb');
    var x = null;
    for (i = 0; i < temp.length; i++){
        debug('    intitializing element: ' + temp[i]);
        if(getFileExt(temp[i]) == 'gif'){
            x = document.createElement('img');
            x.setAttribute("id", "stream4chan-gif");
        }else if (getFileExt(temp[i]) == 'webm'){
            x = document.createElement('video');
            x.setAttribute("id", "stream4chan-webm");
            x.setAttribute("controls","");

            x.setAttribute("loop","");
            x.loop = true;

            x.setAttribute("autoplay","");
            x.autoplay = false;

            x.setAttribute("ended","");
            x.ended = false;
        }
        x.setAttribute("src",temp[i]);
        x.setAttribute("style", "height: 100%; width: auto;");
        arr.push(x);
        backup.push(x);
    }
}

function debug(text){
    if(debugOn){
        console.log(text);
    }else{
        hiddenPrints.push(text);
    }
}

function toggleDebug(e) {
    var evtobj = window.event? event : e;
    if (!e || evtobj.keyCode == 68 && evtobj.ctrlKey && evtobj.altKey && evtobj.shiftKey){
        debug('Function: toggleDebug');
        if(debugOn){
            console.log('##Debug Off##');
            debugOn = false;
        }else{
            console.log('##Debug On##');
            debugOn = true;
            for(var i = 0; i < hiddenPrints.length; i++){
                debug(hiddenPrints[i]);
            }
            hiddenPrints = [];
        }
        return true;
    }
    return false;
}

function setDimensions(e){
    debug('Function: setDimensions');
    content.style.height = window.innerHeight - settings.offsetHeight + 'px';
    if(e){
        if(e.offsetHeight > (window.innerHeight - settings.offsetHeight)){
            debug('    Content was taller');
            e.style.height = '100%';
            e.style.width =  'auto';
        }

        if(e.offsetWidth > (window.innerWidth - (prevButton.offsetWidth + nextButton.offsetWidth))){
            debug('    Content was wider');
            e.style.height = 'auto';
            e.style.width =  '100%';
            e.style.margin = ((content.offsetHeight - e.offsetHeight - settings.offsetHeight)/2) + 'px 0px';
        }
    }
}

function contentExists(type){
    debug('Function: contentExists');
    if(type){
        return document.getElementById('stream4chan-' + type);
    }else{
        var div = document.getElementById('stream4chan-webm');
        if(!div){ div = document.getElementById('stream4chan-gif'); }
        return div;
    }
}

function thereAre(type){
    debug('Function: thereAre');
    if(type){
        for(i = 0; i < hrefs.length; i++){
            if(getFileExt(hrefs[i].src) === type){
                return true;
            }
        }
    }
    debug('    Error: argument not passed to function');
    return false;
}

function noContentToDisplay(){
    debug('Function: noContentToDisplay');
    var text = false;

    //End and display modal if nothing can play
    if(!playGifs.checked && !playWebms.checked){
        text = 'Nothing selected to play';
    }

    //End and display modal if nothing can play
    if(!thereAre('gif') && (playGifs.checked && !playWebms.checked)){
        text = 'No gifs!';
    }

    //End and display modal if nothing can play
    if(!thereAre('webm') && (!playGifs.checked && playWebms.checked)){
        text = 'No Webms!';
    }

    //End and display modal if nothing can play
    if(!thereAre('gif') && !thereAre('webm')){
        text = 'No Gifs or Webs';
    }

    //End and display modal if out of range
    if( 0 > currentVideo || currentVideo > hrefs.length-1){
        text = 'End of Thread';
        if(currentVideo < 0){ text = 'Start of thread'; }
    }
    if(text){ debug('    Returning: '+ text); }
    return text;
}

function applyAutoplay(){
    debug('Function: applyAutoplay');

    var x = contentExists();
    debug('    ' + getFileExt(x.src) + ' event listener is ' + autoplay.checked);
    clearTimeout();

    if(getFileExt(x.src) === 'webm'){
        x.loop = !autoplay.checked;
        x.removeEventListener('ended', nextVideo, false);
        if(autoplay.checked){
            x.addEventListener('ended', nextVideo, false);
        }
    }

    if(getFileExt(x.src) === 'gif' && autoplay.checked){
        currentTimeout = setTimeout(nextVideo, duration.value*1000);
    }
}

function shuffleArr() {
    debug('Function: shuffleArr');
    var j, x, i;
    for (i = hrefs.length; i; i--) {
        j = Math.floor(Math.random() * i);
        x = hrefs[i - 1];
        hrefs[i - 1] = hrefs[j];
        hrefs[j] = x;
    }
    shuffled = true;
    shuffle.value = ' unshuffle ';
}

function unshuffleArr() {
    debug('Function: unshuffleArr');
    hrefs = backup.slice();
    if(contentExists()){
        for(var i = 0; i < hrefs.length; i++){
            if(hrefs[i].src === contentExists().src){
                currentVideo = i;
                break;
            }
        }
    }
    shuffled = false;
    shuffle.value = ' shuffle ';
}