givemegoo / Serienplaner-Quickview

// ==UserScript==
// @name         Serienplaner-Quickview
// @namespace    http://www.serienjunkies.de/docs/serienplaner.html
// @version      1.3
// @description  Quickview of serienjunkies.de description with imdb score added on serienplaner page 
// @author       givemegoo
// @match        http://www.serienjunkies.de/docs/serienplaner.html
// @updateURL    https://openuserjs.org/meta/givemegoo/Serienplaner-Quickview.meta.js
// ==/UserScript==

// givemegoo 201611201842

(function() {
    'use strict';

    // Your code here...

    var a1 = document.createElement("script");
    a1.type = "text/javascript";
    a1.innerHTML = `
setTimeout(killtopad,100);
function killtopad()
{
  var spans = document.getElementsByTagName("span");
  for (var j = 0; j < spans.length; j++)
  {
      var span=spans[j];
      if(span.innerHTML == "Anzeige")
      {
          span.parentNode.remove();
          break;
      }
  }
}
`;
    document.getElementsByTagName("body")[0].appendChild(a1);



  window.grabit = null;
  window.showit = null;
  window.hasfocus = null;
  window.mouseisover = null;

  var imgs = document.getElementsByTagName("img");
  for (var i = 0; i < imgs.length; i++)
  {
    var img=imgs[i];
    var onclick = img.getAttribute('onclick');
    var x;
    if (onclick !== null && (x=onclick.match("document.location='/([^/]+)/'")) !== null)
    {
      img.parentNode.id = x[1];
      img.parentNode.loadabort = 0;
      img.parentNode.timeoutid = null;
      img.parentNode.loadittimer = null;
      img.myurl = x[1];
      img.onmouseenter = function() {loaditwithdelay(this.myurl, this.alt);};
      img.onmouseleave = function() {closeitwithdelay(this.myurl);};
    }
  }

})();

// -- functions below

function loaditwithdelay(it, alt)
{
    var s4 = document.getElementById(it);
    // we want to load, clear loadabort
    s4.loadabort = 0;

    if(s4.loadittimer !== null) // if loadittimer for it is already running, remove it so new one can be set below. 
    {
        clearTimeout(s4.loadittimer);
        s4.loadittimer = null;
    }
    if(window.mouseisover !== null) // should not happen, but may happen if events get lost or are scheduled in wrong order
    {
        console.log("loaditwithdelay warn: loaditwithdelay called while already mouseisover someit",it, window.mouseisover);
        // TODO: cleanup
    }
    window.mouseisover = it; // mouse is now over it
    s4.loadittimer = setTimeout(loadit,500,it,alt); 
}

function loadit(it, alt)
{
    var s4 = document.getElementById(it);
    s4.loadittimer = null; // load is now running, mark old load timer as null
    
    if((s4.loadabort == 1) || (window.mouseisover !== null && window.mouseisover != it))  // if either (a loadabort for this it was triggered before) or (the mouse is already over other it), abort this load now. 
    {
        s4.loadabort = 0;
        unsetclosetimer(it);
        if(window.grabit == it) window.grabit = null; // if we are the current grab, also clear grabit while we abort. 
        return;
    }

    // so now: mouse is still over our img and no closing was requested. make us the only one to continue
    
    unsetallclosetimers(it);
    abortallloadsexcept(it);

    if(window.grabit == it || window.showit == it) // if already grabbing or showing it, no need to do anything, just return. should probably never happen.
    {
        return;
    }

    if(window.showit !== null && window.showit != it) // if there is a stale other it showing, remove it and continue.
    {
        hideit(window.showit);
    }


    window.grabit = it; // it is now official the current grabber

    var request = new XMLHttpRequest();
    request.myid = it;
    request.myalt = alt;
    request.open("GET","/"+it+"/");
    request.addEventListener('load', function(event)
    {
        if (this.status >= 200 && this.status < 300) {
            loadit2(this.myid, this.myalt, this.responseText);
        } else {
            console.warn(this.statusText, this.responseText);
        }
    });
    request.send();
}


function loadit2(it,alt, text1)
{
    var s4 = document.getElementById(it);

    if((s4.loadabort == 1) || (window.mouseisover !== null && window.mouseisover != it)) // if either (a loadabort for this it was triggered before) or (the mouse is already over other it), abort this load now. 
    {
        s4.loadabort = 0;
        unsetclosetimer(it);
        if(window.grabit == it) window.grabit = null; // if we are the current grab, also clear grabit while we abort. 
        return;
    }
    
    // continue loading
    var request2 = new XMLHttpRequest();
    request2.myid = it;
    request2.myalt = alt;
    request2.text1 = text1;
    var x = null;
    var year = "";
    var yearquery = "";
    if((x=text1.match(/Die Serie ist aus dem Jahr ([0-9]{4})\./)) !== null)
    {
        yearquery="&y="+x[1];
        year=x[1];
    }

    request2.open("GET","http://www.omdbapi.com/?type=series"+yearquery+"&t="+encodeURIComponent(alt));
    request2.addEventListener('load', function(event)
    {
        if (this.status >= 200 && this.status < 300) {
            showit(this.myid, this.myalt, this.text1,this.responseText,year);
        } else {
            console.warn(this.statusText, this.responseText);
        }
    });
    request2.send();
}


function showit(it,alt,text1,text2,year)
{
    let jsonObject = JSON.parse(text2);

    insertrating(it,"<br>"+"(<a href=http://www.imdb.com/title/"+jsonObject.imdbID+"/>IMDB</a>: "+jsonObject.imdbRating+" <a href=http://www.imdb.com/title/"+jsonObject.imdbID+"/reviews>User Reviews</a>)");
    
    unsetclosetimer(it); // remove possibly wainting close timer. Final show or close will be handled in here
    var s4 = document.getElementById(it);

    if((s4.loadabort == 1) || (window.mouseisover !== null && window.mouseisover != it)) // if either (a loadabort for this it was triggered before) or (the mouse is already over other it), abort this load now. 
    {
        s4.loadabort = 0;
        if(window.grabit == it) window.grabit = null; // if we are the current grab, also clear grabit while we abort. 
        return;
    }

    if(window.grabit !== null && window.grabit != it) // if another grab was triggered in the meantime, abort and return here
    {
        return;
    }

    window.grabit = null; // we made it, we now are the only legit grab, so clear grabit

    if(window.showit == it) // we are already showing, nothing to do, return
    {
        return;
    }

    if(window.showit !== null)  // if other div is showing, close it.
    {
        hideit(window.showit);
    }

    var myVal3 = alt+" ("+year+")<br>"+"<a href=http://www.imdb.com/title/"+jsonObject.imdbID+"/>IMDB</a>: "+jsonObject.imdbRating+" <a href=http://www.imdb.com/title/"+jsonObject.imdbID+"/reviews>User Reviews</a><br>"+jsonObject.Plot+" <a href=http://www.imdb.com/title/"+jsonObject.imdbID+"/plotsummary>Full Summary</a><br><br>Serienjunkies: ";

    var hidden = document.body.appendChild(document.createElement("div"));
    hidden.style.display = "none";
    hidden.innerHTML = text1.match(/<body[^>]*>([\s\S]+)<\/body>/i)[1];

    var myEl = hidden.querySelector("div.sgml");
    var myVal = myEl.innerHTML;
    var myEl2 = hidden.querySelector("div#serieninfo");
    var myVal2 = myEl2.innerHTML;

    hidden.remove();

    var s3 = document.createElement("div");
    s3.innerHTML = myVal3+myVal+myVal2;
    s3.id = "preview-"+it;
    s3.parentid = it;
    s3.style = "position:fixed;z-index:100000;border:16px solid orange;border-radius: 25px; padding: 20px; margin-left: 164px;top: 0;width: 600px;max-height: 85vh;overflow-y:auto;background-color: rgba(255, 255, 255, 1);";
    s3.onmouseenter = function() {lockit(this.parentid);};
    s3.onmouseleave = function() {unlockit(this.parentid);};

    
    if(window.mouseisover == it) // just paranoid, only show it if mouse is over it
    {
        s4.appendChild(s3);
        window.showit = it;
    }
}

function closeitwithdelay(it)
{
    window.mouseisover = null;
    var s4 = document.getElementById(it);
    if(s4.timeoutid !== null) // if it already has an active close timer, replace it (remove and set new)
    {
        unsetclosetimer(it);
    }
    s4.timeoutid = setTimeout(closeit,3000,it); // regularly close content div in 3 sec
}

function closeit(it)
{
    var s4 = document.getElementById(it);
    s4.timeoutid = null;

    s4.loadabort = 1;

    if(window.showit == it && window.grabit != it && window.hasfocus != it )
    {
        hideit(it); // regular close.
    }
}


function hideit(it)
{
    var s5 = document.getElementById("preview-"+it);
    if(s5 !== null)
    {
        s5.remove();
        window.showit = null;
        window.hasfocus = null;
    }
}

function lockit(it)
{
    if(window.hasfocus === null)
    {
        unsetallclosetimers(it);
        abortallloadsexcept(null);
        window.hasfocus = it;
    }
}

function unlockit(it)
{
    if(window.hasfocus == it)
    {
        hideit(it); // close content div
        unsetallclosetimers(it);
    }
    else
    {
        console.log("unlockit warn: should never happen: it != window.hasfocus", it, window.hasfocus);
    }
}


function unsetclosetimer(it)
{
    var s4 = document.getElementById(it);
    if(s4.timeoutid !== null)
    {
        clearTimeout(s4.timeoutid);
        s4.timeoutid = null;
    }
}

function unsetallclosetimers(it)
{
  var imgs = document.getElementsByTagName("img");
  for (var i = 0; i < imgs.length; i++)
  {
    var img=imgs[i];
    if (typeof img.parentNode.timeoutid !== 'undefined' && img.parentNode.timeoutid !== null)
    {
        clearTimeout(img.parentNode.timeoutid);
        img.parentNode.timeoutid = null;
    }
  }
}

function abortallloadsexcept(it)
{
  var imgs = document.getElementsByTagName("img");
  for (var i = 0; i < imgs.length; i++)
  {
    var img=imgs[i];
    if (typeof img.myurl !== 'undefined' && img.myurl !== null && img.myurl != it && img.parentNode.loadabort === 0) // all except it
    {
        img.parentNode.loadabort = 1;
    }
  }
}

function  insertrating(it,text)
{
    var s5 = document.getElementById("imdbmarker-"+it);
    if(s5 !== null)
    {
        return;
    }
    var s6 = document.createElement("span");
    s6.innerHTML = text;
    s6.id = "imdbmarker-"+it;

    document.getElementById(it).nextSibling.appendChild(s6);
}

//----------------------