Jump to content

User:PSaxena (WMF)/info.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// See [[mw:Navigation Popups (Restyling and Enhancements)]], by Vibhabamba.
// This is still probably quite buggy.
// Licensed under GPLv2+, CC-BY-SA 3.0, GFDL, and anything else the WMF might find useful.
// from https://en.wikipedia.org/wiki/User:Yair_rand/NavPopupsRestyled.js

$( document ).ready( function( $ ){
  // Messages
  mw.messages.set( {
    "INFO-readmore" : "Read more" // this and the four below allow use of GENDER:$1.
  } );
  
  // Config
  var loadDelay = 150, // number of ms before sending the request
  displayDelay = 500, // minimum number of ms between sending request and displaying
  closeDelay = 800, // time between exiting box and it disappearing
  timer, currentLink, cache = {}, curRequest, 
  $marker = $( "<span>" ).css("vertical-align", "top"), 
  api = new mw.Api(), 
  $box = $( "<div>" ).addClass( "INFObox" ).on( { 
    mouseleave: leaveActive,
    mouseenter: function() {
      setTimeout( function(){ 
        timer && clearTimeout( timer );
      }, 16 ); // don't ask.
    }
  }).appendTo( document.body );
  
  // From https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_.28JavaScript.2FActionScript.2C_etc..29
  function lon2tile(lon,zoom1) { 
	tt = Number(lon);
	return (Math.floor((tt+180)/360*Math.pow(2,zoom1)));
  }

  function lat2tile(lat,zoom2)  { 
    return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom2))); 
  }
  
  // Get domain name
  function getDomainName(hostName){
  	if (!hostName) return hostName;
    return hostName.substring(hostName.lastIndexOf(".", hostName.lastIndexOf(".") - 1) + 1);
  }
  
  // Close box event handler
  function closeBox() {
    $( currentLink ).off( "mouseleave", leaveActive );
    $box.hide();
    timer && clearTimeout( timer );
    currentLink = timer = undefined;
  }
  
  // Leave box event handler
  function leaveActive() {
    timer = setTimeout( closeBox, closeDelay );
  }
  
  // Leave link event handler
  function leaveInactive() {
    $( currentLink ).off( "mouseleave", leaveInactive );
    clearTimeout( timer );
    curRequest && curRequest.abort();
    currentLink = timer = curRequest = undefined;
  }
  
  function createBox($this, href) {
    $marker.prependTo( $this );
    var offset, sploot = cache[ href ], thumbnail = sploot.thumbnail,
    sOffset = $marker.offset(),
    eOffset = $marker.appendTo( $this ).offset(),
    tall = thumbnail && thumbnail.height > thumbnail.width, // todo: fix duplication.
    boxWidth = tall ? 450 : 300;
    if( sOffset.left > eOffset.left ) {
      if( event.pageX > sOffset.left ) { // top half
        offset = sOffset;
      } else { // latter half
        offset = eOffset;
        offset.left += - 40;
      }
      offset.top += $marker.height() + 8;
    } else { // normal situations
      offset = sOffset;
      offset.top += $this.height() + 8;
      offset.left += ( $this.width() / 2 ) - ( 20 );
    }
    var flip = $( window ).width() < boxWidth + offset.left;
    $marker.remove();
    $box
    .children()
    .detach()
    .end()
    [ tall ? "addClass" : "removeClass" ]( "is-tall" )
    [ flip ? "addClass" : "removeClass" ]( "flipped" ) // needs a better class name.
    .css({ // avoid .empty() to keep event handlers
      top: offset.top,
      left: offset.left - ( flip && boxWidth - 40 ),
      "min-height": tall ? thumbnail.height : "initial"
    })
    .append( sploot.box )
    .show();
    $this.off( "mouseleave", leaveInactive ).on( "mouseleave", leaveActive );
  }
  
  // Setup box
  function setupBox($this, href, title) {
    if( cache[ href ] ) {
      timer = setTimeout( function () {
      	createBox($this,href);
      }, displayDelay );
    } else {
      curRequest = undefined;
      var ip = title.split('/')[1];
      var extract, timestamp, timetext, thumbnail, watched, 
      thumbnail = {
        width: 200,
        height: 290,
        source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/India_Karnataka_location_map.svg/200px-India_Karnataka_location_map.svg.png'
      };
      timestamp = +new Date;
      extract = 'testtest';
      
      var tall = thumbnail && thumbnail.height > thumbnail.width;
      var $bottommessage, $contentbox = $( "<div>" )
      .html( extract )
      .append( 
        $( "<a>" )
        .attr({ href: href, target: "_blank" })
        .text( mw.message( "INFO-readmore", mw.user ).text() ) 
      );
 
      fetch('https://ipinfo.io/'+ip+'/json').then(function(data){
      	return data.json();
      }).then(function(json){
      	var lat = json.loc.split(',')[0];
      	var lon = json.loc.split(',')[1];
      	
      	var x = lon2tile(lon,10);
      	var y = lat2tile(lat,10);
      	thumbnail.source = 'https://maps.wikimedia.org/osm-intl/10/'+x+'/'+y+'@2x.png';
      	
      	$contentbox.empty().append(
      		$("<img>").addClass('flag').attr('src', 'https://www.countryflags.io/'+json.country.toLowerCase()+'/flat/16.png'),
            $("<span>").addClass('shift').text( json.city + ' ' + json.postal ),
            $("<span>").addClass('shift').text( json.region + ', ' + json.country ),
            $("<a>").addClass('hostname').attr('href', 'http://'+getDomainName(json.hostname)).text(json.hostname),
            $("<span>").text(json.org)
      	);
      	
      	$bottommessage = $("<div>").addClass("INFOredirect").append('Source ipinfo.io')
      	
      	cache[ href ] = {
        box: $( "<div>" ).append( 
          thumbnail ? $( "<img>" ).addClass( tall ? "is-tall" : "is-not-tall" ).attr( "src", thumbnail.source ).css( {
            width: thumbnail.width,
            height: thumbnail.height
          } ) : $( "<span>" ), 
          $contentbox,
          $bottommessage
		),
        thumbnail: thumbnail
      };
      timer === undefined && createBox($this, href);
      });
        
      timer = setTimeout( function() {
        timer = undefined;
        cache[ href ] && createBox($this, href);
      }, displayDelay );
    }
  }
  
  // Setup hover event
  $("#mw-content-text").on("mouseenter", "a.mw-anonuserlink", function( event ){
    var $this = $( this ), href = this.href, 
    title = href && href.split("/wiki/")[ 1 ];
    if( !title || 
      $this.hasClass("extiw") || 
      $this.hasClass("image") || 
      $this.hasClass("new") || 
      href.indexOf("?") !== -1 || 
      href.indexOf( location.href.split("#")[ 0 ] + "#" ) === 0
    ) {
      return;
    }
    if( currentLink === this ) {
      clearTimeout( timer );
      return;
    }
    if( currentLink ) {
      closeBox();
    }
    currentLink = this;
    timer = setTimeout( function () {
      setupBox($this, href, title);
    }, loadDelay );
    $this.on( "mouseleave", leaveInactive ); 
  });
  
  // Remove title attribute from IP links
  $("a.mw-anonuserlink").attr('title','')
});