User:Zeal/tooltip.js

From Warcraft Wiki
Jump to navigation Jump to search

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)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// Global Variables
 var ttOn = true;
 var ttDebug = false;
 var ttItem = true;
 var ttChar = false;
 var ttMap = false;
 var ttLink = "tthook"; // Hover Tooltip class name
 
 // Sub-Global Variables (L2OOP)
 var ttRequest = false;
 var ttActive = false;
 var ttType = "";
 var ttElement = "";
 var ttDebugHTML = "";
 var ttMousePos = null;
 var ttWindowSize = null;

// Regular Expressions
 var ttRegexCRLF = new RegExp("\r\n", "g");
 var ttRegexItem = new RegExp('<div[^>]*class="itemtooltip".*?>.*?</ul></div>');
 var ttRegexItem2 = new RegExp("1em; float: right; width:", "g");
 var ttRegexItem3 = new RegExp("#fff; background-color: #111; border:", "g");
 var ttRegexItem4 = new RegExp('<li[^>]*class="setdesc".*?>.*?<li[^>]*class="setdesc".*?>.*?<li[^>]*class="setdesc".*?>.*?<li', "g");
 var ttRegexItem5 = new RegExp('<li[^>]*class="setdesc".*?>.*?<li[^>]*class="setdesc".*?>.*?<li', "g");
 var ttRegexSet = new RegExp('<div[^>]*class="settip".*?>.*?</ul></div>');
 var ttRegexComp = new RegExp('.*<li[^>]*class="ttslot-(.*?)">.*');

// Prototype bind method
 function $A(a)
 {
  var r = [];
  for (var i = 0, len = a.length; i < len; ++i)
   r.push(a[i]);
  return r;
 }
 Function.prototype.bind = function()
 {
  var __method = this, args = $A(arguments), object = args.shift();
  return function()
  {
   return __method.apply(object, args.concat($A(arguments)));
  }
 }

// Tooltip mouse event handlers
 function ttShow(spanID)
 {
  var span = document.getElementById(spanID);
  var parent = span.parentNode;
  // Check it's not on it's own page
  if (parent.getAttribute("class") != "selflink")
  {
   var articleObject = document.getElementById( spanID + "-article" );
   var typeObject = document.getElementById( spanID + "-type" );
   var article = articleObject.getAttribute("title");
   var type = typeObject.getAttribute("title");
   if (ttDebug)
   {
    ttDebugHTML = "<br><small>" + article + "</small>";
   }
   else
   {
    ttDebugHTML = "";
   }
   var elem = "ttCache-" + type + "-" + article;
   var ttCache = document.getElementById(elem);
   if (ttCache.innerHTML == null || ttCache.innerHTML == "")
   {
    ttGet('http://www.wowwiki.com/index.php?title=' + article,type,elem);
   }
   else
   {
    ttMove(elem);
    ttCache.style.display = "block";

   }
  }
 }
 function ttHide(elem)
 {
  if (ttActive)
  {
   ttAbort();
   var tt = document.getElementById(elem);
   if (tt.innerHTML == null || tt.innerHTML == "" || hasClass(tt,"loading") || hasClass(tt,"error"))
   {
    tt.innerHTML = "";
   }
   tt.style.display = "none";
  }
 }
 function ttMove(elem)
 {
  if (ttActive)
  {
   var tt = document.getElementById(elem);
   tt.style.left = (ttMousePos.x - 150) + "px";
   tt.style.top = (ttMousePos.y - 30) + "px";
  }
 }

// Mouse tracking
 function ttMouseMove(ev)
 {
  ev = ev || window.event;
  ttMousePos = ttMouseCoords(ev);
 }
 function ttMouseCoords(ev)
 {
  if (document.documentElement && document.documentElement.scrollTop)
  {
   // IE6 +4.01 and user has scrolled
   var dbSleft = document.documentElement.scrollLeft;
   var dbStop = document.documentElement.scrollTop;
   var dbCleft = document.documentElement.clientLeft;
   var dbCtop = document.documentElement.clientTop;
  }
  else
  {
   // IE5 or DTD 3.2
   var dbSleft = document.body.scrollLeft;
   var dbStop = document.body.scrollTop;
   var dbCleft = document.body.clientLeft;
   var dbCtop = document.body.clientTop;
  }
  if (ev.pageX || ev.pageY)
  {
   return {x:ev.pageX, y:ev.pageY};
  }
  return {x:ev.clientX + dbSleft - dbCleft, y:ev.clientY + dbStop - dbCtop};
 }
 function ttWindowResize()
 {
  if (document.documentElement && document.documentElement.clientWidth)
  {
   // IE6 +4.01
   var dbCwidth = document.documentElement.clientWidth;
   var dbCheight = document.documentElement.clientHeight;
  }
  else
  {
   // IE5 or DTD 3.2
   var dbCwidth = document.body.clientWidth;
   var dbCheight = document.body.clientHeight;
  }
  ttWindowSize = {x: ( dbCwidth ) ? dbCwidth : window.innerWidth, y: ( dbCheight ) ? dbCheight : window.innerHeight }
 }

// Ajax functionality.
 function ajaxCreate()
 {
  try // Firefox, Opera, Safari
  {
   request = new XMLHttpRequest();
   if (request.overrideMimeType)
   {
    request.overrideMimeType('text/xml');
   }
   return request;
  }
  catch (e)
  {
   try // IE MSXML
   {
    request = new ActiveXObject("Msxml2.XMLHTTP");
    return request;
   }
   catch (e)
   {
    try // IE XML
    {
     request = new ActiveXObject("Microsoft.XMLHTTP");
     return request;
    }
    catch (e) // UAs that suck
    {
     alert("Your browser does not support AJAX.");
     ttActive = false;
     return false;
    }
   }
  }
 }
 function ttAbort()
 {
  // Checks to see if ttRequest needs aborting.
  if (ttRequest.readyState != 0)
  {
   // Abort and disconnect ready state handler
   ttType = "";
   ttElement = "";
   ttRequest.onreadystatechange = null;
   ttRequest.abort();
  }
 }
 function ttGet(url,type,elem)
 {
  // Abort any still active requests first
  ttAbort();
  ttRequest.open("GET", url, true);
  ttType = type;
  ttElement = elem;
  ttRequest.onreadystatechange = ttStateHandler;
  ttRequest.send();
  ttDisplay("loading",elem);
 }
 function ttStateHandler()
 {
  if (ttRequest.readyState == 4)
  {
   if (request.status == 200)
   {
    ttDisplay("update",ttElement,ttType);
   }
   else
   {
    ttDisplay("error",ttElement);
   }
   ttType = "";
  }
 }

// Tooltip display
 function ttDisplay(method,elem,type)
 {
  var tt = document.getElementById(elem);
  switch (method)
  {
   case "error":
    tt.className = "ttfloat error";
    tt.innerHTML = '<div style="font-size:1em; width: auto; min-width: 15em; padding: 0.3em; margin: 5px; color: #fff; background: url(http://images1.wikia.nocookie.net/wowwiki/images/thumb/c/c0/Ttbackground.svg/275px-Ttbackground.svg.png); border: 1px #bbb solid; -moz-border-radius: 0.75ex;" class="itemtooltip"><b>Error:</b>' + ttRequest.statusText + ttDebugHTML + '</div>';
    break;
   case "loading":
    tt.className = "ttfloat loading";
    tt.innerHTML = '<div style="font-size:1em; width: auto; min-width: 15em; padding: 0.3em; margin: 5px; color: #fff; background: url(http://images1.wikia.nocookie.net/wowwiki/images/thumb/c/c0/Ttbackground.svg/275px-Ttbackground.svg.png); border: 1px #bbb solid; -moz-border-radius: 0.75ex;" class="itemtooltip">Loading..' + ttDebugHTML + '</div>';
    break;
   case "update":
    if (ttRequest.responseText)
    {
     tt.className = "ttfloat loading";
     tt.innerHTML = '<div style="font-size:1em; width: auto; min-width: 15em; padding: 0.3em; margin: 5px; color: #fff; background: url(http://images1.wikia.nocookie.net/wowwiki/images/thumb/c/c0/Ttbackground.svg/275px-Ttbackground.svg.png); border: 1px #bbb solid; -moz-border-radius: 0.75ex;" class="itemtooltip">Loading...' + ttDebugHTML + '</div>';
    }
    else
    {
     tt.className = "ttfloat error";
     tt.innerHTML = '<div style="font-size:1em; width: auto; min-width: 15em; padding: 0.3em; margin: 5px; color: #fff; background: url(http://images1.wikia.nocookie.net/wowwiki/images/thumb/c/c0/Ttbackground.svg/275px-Ttbackground.svg.png); border: 1px #bbb solid; -moz-border-radius: 0.75ex;" class="itemtooltip"><b>Error:</b> No tooltip found.' + ttDebugHTML + '</div>';
    }
    break;
   default:
  }
  ttMove(elem);
  tt.style.display = "block";
  // Check this last to remove laggy behaviour on mouseout because of slow parsing.
  if (method == "update")
  {
   var content = ttParse(ttRequest.responseText,type);
   if (content)
   {
    tt.className = "ttfloat";
    tt.innerHTML = content;
   }
   else
   {
    tt.className = "ttfloat error";
    tt.innerHTML = '<div style="font-size:1em; width: auto; min-width: 15em; padding: 0.3em; margin: 5px; color: #fff; background: url(http://images1.wikia.nocookie.net/wowwiki/images/thumb/c/c0/Ttbackground.svg/275px-Ttbackground.svg.png); border: 1px #bbb solid; -moz-border-radius: 0.75ex;" class="itemtooltip"><b>Error:</b> No tooltip found.' + ttDebugHTML + '</div>';
   }
  }
 }
 
// Tooltip parsing
 function ttParse(text,type)
 {
  var content = false;
  switch (type)
  {
   case "item":
    text = text.replace(ttRegexCRLF, "");
    text = text.replace(ttRegexItem2, "1em; width:").replace(ttRegexItem3, "#fff; background: url(http://www.wowwiki.com/images/8/8b/Ttbackground.png); border:").replace(ttRegexItem4, "<li").replace(ttRegexItem5, "<li");
    content = ttRegexItem.exec(text);
    break;
   case "char":
    break;
   case "map":
    break;
   default:
    text = text.replace(ttRegexCRLF, "");
    text = text.replace(ttRegexItem2, "1em; width:").replace(ttRegexItem3, "#fff; background: url(http://images1.wikia.nocookie.net/wowwiki/images/thumb/c/c0/Ttbackground.svg/275px-Ttbackground.svg.png); border:").replace(ttRegexItem4, "<li").replace(ttRegexItem5, "<li");
    content = ttRegexItem.exec(text);
  }
  return content;
 }

// Loader
 function ttHasLink(x)
 {
  if (hasClass(x,ttLink))
  {
   return true;
  }
 }
 function ttLoad()
 {
  var spans = document.getElementsByTagName( "span" );
  var parent = null;
  for ( var i = 0; i < spans.length; i++ )
  {
   if ( ttHasLink(spans[i]) )
   {
    // if not item page, hook events and ids.
    if (spans[i].innerHTML.indexOf("<b>") == -1)
    {
     ttActive = true;
     var spanID = "ttSpan-" + i;
     spans[i].setAttribute("id", spanID);
     spans[i].removeAttribute("title");
     parent = spans[i].parentNode;
     if (parent.getAttribute("title"))
     {
      var article = parent.getAttribute("title");
      parent.removeAttribute("title");
      if (hasClass(spans[i],"item-link") || hasClass(spans[i],"item-vendor"))
      {
       var type = "item";
      }
      else if (hasClass(spans[i],"char-link"))
      {
       var type = "char";
      }
      else if (hasClass(spans[i],"map-link"))
      {
       var type = "map";
      }
      else
      {
       var type = "item";
      }

      var elem = "ttCache-" + type + "-" + article;

      var newArticle = document.createElement("span");
      newArticle.setAttribute("id", spanID + "-article");
      newArticle.setAttribute("title",article);
      var newType = document.createElement("span");
      newType.setAttribute("id", spanID + "-type");
      newType.setAttribute("title",type);
      spans[i].appendChild(newArticle);
      spans[i].appendChild(newType);
      newArticle.style.display = "none";
      newType.style.display = "none";
      
      var cache = document.createElement("div");
      cache.setAttribute("id", elem);
      cache.setAttribute("class", "ttfloat");
      cache.style.display = "none";
      cache.style.position = "absolute";
      cache.style.zIndex = "999";
      var contentstart = document.getElementById("content");
      contentstart.insertBefore(cache,contentstart.childNodes[0]);
      
      spans[i].onmouseover = ttShow.bind(spans[i], spanID);
      spans[i].onmouseout = ttHide.bind(spans[i], elem);
      spans[i].onmousemove = ttMove.bind(spans[i], elem);
     }
    }
   }
  }
  if (ttActive)
  {
   ttRequest = ajaxCreate();
   // Global Events
   ttWindowResize();
   document.onmousemove = ttMouseMove;
   window.onresize = ttWindowResize;
  }
 }
 addOnloadHook(ttLoad);