austindh / Learning Suite proxy shortcut

// ==UserScript==
// @name         Learning Suite proxy shortcut
// @namespace    
// @version      0.1
// @description  Add icon to click to enter proxy
// @author       You
// @match        https://learningsuite-dev.byu.edu/*
// @match        https://learningsuite-stg.byu.edu/*
// @match	     http://localhost/*
// @require http://code.jquery.com/jquery-latest.js
// ==/UserScript==

	//Define base URL, depending on test server
	var BASE_URL = "https://learningsuite-dev.byu.edu/";
	if ( location.href.match( /localhost/gi ) ) {
        BASE_URL = "http://localhost/";
    }
    else if ( location.href.match( /learningsuite-stg/gi ) ) {
    	BASE_URL = "https://learningsuite-stg.byu.edu/";
    }
	
	//Number of most recent netIDs to show in recent menu
	var NUM_RECENT = 5;
	var NUM_PROXIES_TO_STORE = 20;
	var NET_ID = "";
	
	//Define index to go over, based on whether in student view, or instructor view
	var index = 2;
    if ( $( '.tabbar' ).children().length < 3 ) {
    	index = 1;    
    }

	var topOffset = 0; //for recent proxies box
    if ( !$( '#change-view' ).is( ':visible' ) ) { //student view
		index = $(".tabbar").children().length - 1;
        topOffset = 26;
    }
  
    //Add <a> tag for 5 most recent proxies
    $( '.tabbar' ).children().eq( index ).after( '<a class=\"proxy2\">Recent</a>' );
	//Add <a> tag for netID prompt
	$( '.proxy2' ).before( '<a class=\"proxy1\">Proxy</a>' );

	//Styling
	GM_addStyle('.proxy1 			{float:right!important;}');
    GM_addStyle('.proxy2 			{float:right!important;}');
    GM_addStyle('.goToProxy 		{padding: 4px;color: #001948;text-align: center;overflow-x: hidden;}');
    GM_addStyle('.goToProxy:hover 	{cursor: pointer;background: linear-gradient(#d1e4f6, #9ebddb);margin-left: -14px;margin-right: -14px;}');
    GM_addStyle('.hover				{cursor: pointer;background: linear-gradient(#d1e4f6, #9ebddb);margin-left: -14px;margin-right: -14px;}');

	function proxyHTML ( netID ) {
   		return "<div class=\"goToProxy\">" + netID + "</div>";
    }

    function addProxy ( netID ) {
    	//Check if already in proxies list
        var recentProxies = JSON.parse( localStorage.recentProxies );
        var index = recentProxies.indexOf( netID );
        if ( index !== -1 ) { //NetID is in array
        	recentProxies.splice( index, 1 );
            recentProxies.push( netID );
        } else { //not in array
            recentProxies.push( netID );
        }
        
        //Check if we're too long
        var len = recentProxies.length;
        if ( len > NUM_PROXIES_TO_STORE ) {
        	recentProxies = recentProxies.splice( len - NUM_PROXIES_TO_STORE ); //Take most recent
        }
        
        localStorage.recentProxies = JSON.stringify( recentProxies );
    }
	
    function go ( netID ) {
    	//Check for localstorage array
        if ( !localStorage.recentProxies ) {
            localStorage.recentProxies = JSON.stringify( [] );
        }
        //Add to recent proxies
        addProxy( netID );
        location.href = BASE_URL + "admin.0?proxyTo=" + netID;
    }

    //Click event for net ID prompt
    $( ".proxy1" ).on( "click", function () {
        var netID = prompt("Enter Net ID to proxy to:");
        if ( netID ) {
            go( netID );
        }
    });

	//Click event for recent proxies
    $( '.proxy2' ).on( 'click', function (e) {
        e.stopPropagation();
    	
        //See if box is already visible, and remove if it is
        if ( $( '.proxyBox' ).is( ':visible' ) ) {
        	$( '.proxyBox' ).remove();
            return;
        }
        
        //Check for localstorage array
        if ( !localStorage.recentProxies ) {
        	localStorage.recentProxies = JSON.stringify( [] );
        }
		var recentProxies = JSON.parse( localStorage.recentProxies );
        var HTMLstring = "<div class=\"proxyBox\"><div class=\"noEntries\">No recent proxies</div></div>";
        
		//Generate HTML
        if ( recentProxies.length > 0 ) {
            HTMLstring = "<div class=\"proxyBox\">";
            var i = recentProxies.length - 1;
            for ( var n = 0; n < NUM_RECENT; n++ ) {
                if ( recentProxies[i] !== undefined ) {
                	HTMLstring += proxyHTML( recentProxies[i] ); //Add in reverse order, since one added to array last is most recent one
                }
                i--;
            }
            
            HTMLstring += "</div>";
        }
        
        //console.log(HTMLstring);
        
        //Add box to page
        //Figure out coordinates of "Recent" div
        var recCoor = $( '.proxy2' ).position();
        var top = recCoor.top + 99 + topOffset;
        var left = Math.round( recCoor.left ) - 30;
        $( document.body ).append( HTMLstring );
        
        //Click event to hide proxy box
        $( document.body ).on( 'click', function (e) {
            if ( !$(e.target).hasClass('proxyBox') && !$(e.target).hasClass('noEntries') && !$(e.target).hasClass('goToProxy') ) {
            	$( '.proxyBox' ).remove();
                $( '.remove' ).remove();
            }
        });
        
        //Click event to go to proxy
        $( '.goToProxy' ).on( 'click', function	()	{
            $( '.proxyBox' ).remove();
            go( $(this).text() );
        });
        
        //Click event to remove netID from recent proxy list
        $( document.body ).on( 'mousedown', function (e) {
            //Disable context menu right click only for our "goToProxy" class
            if ( $(e.target).hasClass('goToProxy') ) {
            	$(document.body).attr('oncontextmenu','return false;');
            } else {
            	$(document.body).attr('oncontextmenu','return true;');
            }
            //If right click
            if ( e.button === 2 && $(e.target).hasClass( 'goToProxy' ) ) {
                NET_ID = $(e.target).html();
                var $target = $(e.target);
                $target.addClass( 'hover' );
                var topOffset = e.clientY + 5;
                var leftOffset = e.clientX;
                $( '.remove' ).remove();	
            	$( document.body ).append( "<div class=\"remove\">remove from list</div>" );
                GM_addStyle( '.remove {position: fixed; z-index: 1501; top:' + topOffset + 'px; left:' + leftOffset + 'px;background: rgb(233, 233, 233);padding: 3px;padding-left: 5px; padding-right: 5px;border-radius: 9px;border: 1px solid rgb(183, 180, 180);}' );
                GM_addStyle('.remove:hover {cursor: pointer; background: white;}');
                
                $( document.body ).off( 'mousemove' );
                
                //Event to hide when you move away from the popup
                $( document.body ).on( 'mousemove', function (e) {
                	var x = e.clientX;
                    var y = e.clientY;
                    var xDist = ( leftOffset - x ) * ( leftOffset - x );
                    var yDist = ( topOffset - y ) * ( topOffset - y );
                    if ( xDist + yDist > 15000 ) {
                   		
                        $target.removeClass( 'hover' );
                        $( '.remove' ).remove();
                    }
                });
                
                //Event to remove from recent proxies
                $( '.remove' ).on( 'click', function () {
                    if ( recentProxies.indexOf( NET_ID ) !== -1 ) { //If in recent proxies list, remove
                    	recentProxies.splice( recentProxies.indexOf( NET_ID ), 1 );
                        localStorage.recentProxies = JSON.stringify( recentProxies );
                    }
                });
                
            }
            
        });
        
        GM_addStyle('.proxyBox {position: fixed;top:' + top + 'px;left:' + left + 'px;background: #EAEAEA;padding: 14px;z-index: 1500;width: 75px;border: solid 1px lightgray;}');

        
    });