Advertisement
abhisekp

[GM Script] LongURL Mobile Expander GreaseMonkey Script

Aug 7th, 2014
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // LongURL Mobile Expander
  2.  
  3. // version 2.0
  4.  
  5. // 2009-06-02
  6.  
  7. // Copyright (c) 2008, Sean Murphy
  8.  
  9. // Released under the GPL license
  10.  
  11. // http://www.gnu.org/copyleft/gpl.html
  12.  
  13. //
  14.  
  15. // --------------------------------------------------------------------
  16.  
  17. //
  18.  
  19. // This is a Greasemonkey user script.  To install it, you need
  20.  
  21. // Greasemonkey 0.3 or later: http://greasemonkey.mozdev.org/
  22.  
  23. // Then restart Firefox and revisit this script.
  24.  
  25. // Under Tools, there will be a new menu item to "Install User Script".
  26.  
  27. // Accept the default configuration and install.
  28.  
  29. //
  30.  
  31. // To uninstall, go to Tools/Manage User Scripts,
  32.  
  33. // select "LongURL Mobile Expander", and click Uninstall.
  34.  
  35. //
  36.  
  37. // --------------------------------------------------------------------
  38.  
  39. //
  40.  
  41. // ==UserScript==
  42.  
  43. // @name          LongURL Mobile Expander
  44.  
  45. // @namespace     http://IamSeanMurphy.com
  46.  
  47. // @description   Expand shortened URLs wherever you go by harnessing the power of LongURL.org.
  48.  
  49. // @author        Sean Murphy
  50.  
  51. // @homepage      http://LongURL.org
  52.  
  53. // @include       *
  54.  
  55. // ==/UserScript==
  56.  
  57.  
  58.  
  59. (function() {
  60.  
  61.    
  62.  
  63.     // URL for the LongURL API
  64.  
  65.     this.api_endpoint = 'http://api.longurl.org/v2/';
  66.  
  67.     this.script_version = '2.0';
  68.  
  69.     this.known_services = {};
  70.  
  71.     this.link_cache = [];
  72.  
  73.     this.ajax_queue = [];
  74.  
  75.     this.tooltip_node;
  76.     this.tooltip_timout;
  77.     this.modlinks_timeout;
  78.     this.current_link;
  79.  
  80.    
  81.  
  82.     getServicesFromAPI = function() {
  83.  
  84.         ajaxRequest({
  85.  
  86.             method: "GET",
  87.  
  88.             url: this.api_endpoint + 'services?format=json',
  89.  
  90.             headers: {
  91.                 'User-Agent': 'LongURL Mobile Expander/'+this.script_version+' (Greasemonkey)'
  92.             },
  93.  
  94.             onload: function(response) {
  95.  
  96.                 saveSupportedServices(response);
  97.  
  98.                 modifyShortLinks();
  99.  
  100.             }
  101.  
  102.         });
  103.  
  104.     };
  105.  
  106.    
  107.  
  108.     saveSupportedServices = function(response) {
  109.  
  110.         var data = jsonToObject(response);
  111.  
  112.         if (typeof(data.messages) !== 'undefined') { // There was an error
  113.  
  114.             return;
  115.  
  116.         }
  117.  
  118.        
  119.  
  120.         this.known_services = data;
  121.  
  122.        
  123.  
  124.         // Store the list of supported services locally
  125.  
  126.         if (setValue('longurl_services', response.responseText)) {
  127.  
  128.             alert('LongURL Mobile Expander requires Greasemokey 0.3 or higher.');
  129.  
  130.         }
  131.  
  132.        
  133.  
  134.         var date = new Date();
  135.  
  136.         date.setTime(date.getTime() + (1000 * 60 * 60 * 24 * 1));
  137.  
  138.         setValue('longurl_expire_services', date.toUTCString());
  139.  
  140.     };
  141.  
  142.    
  143.  
  144.     modifyShortLinks = function() {
  145.         var links = document.evaluate("//a[@href]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  146.  
  147.        
  148.         var current_domain = document.location.href.match(/^https?:\/\/(?:www\.)?([^\.]+\.[^\/]+)/i);
  149.        
  150.  
  151.         for (var x = 0; x < links.snapshotLength; x++) {
  152.  
  153.             var a = links.snapshotItem(x);
  154.  
  155.             var href = a.href;
  156.  
  157.             var domain = href.match(/^http:\/\/(?:(?:www\.)?(?:[^\.]+\.(notlong\.com|qlnk\.net|ni\.to|lu\.to|zzang\.kr)|([^\.]+\.[^\/]+)))/i);
  158.  
  159.             if (domain) {
  160.                 domain = domain[1] || domain[2] || false;
  161.             }
  162.            
  163.             // Check if link domain is in list
  164.  
  165.             if ((domain !== current_domain[1]) && (typeof(this.known_services[domain]) !== 'undefined')) {
  166.                
  167.                 // Check link URL against domain regex
  168.                 var regex = new RegExp(this.known_services[domain]['regex'], 'i');
  169.                 if (!this.known_services[domain]['regex'] || href.match(regex)) {
  170.  
  171.                     a.addEventListener('mouseover', function(e) {
  172.                         showTooltip();
  173.  
  174.                         expandLink(e.target, e);
  175.  
  176.                     }, true);
  177.  
  178.                     a.addEventListener('mouseout', function(e) {
  179.  
  180.                         hideTooltip();
  181.  
  182.                     }, true);
  183.                 }
  184.  
  185.             }
  186.  
  187.         }
  188.  
  189.     };
  190.  
  191.    
  192.  
  193.     expandLink = function(anchor, e) {
  194.  
  195.         if (typeof(anchor.href) === 'undefined') return;
  196.        
  197.         this.current_link = anchor.href;
  198.  
  199.        
  200.  
  201.         // Check cache
  202.  
  203.         if (getCache(anchor.href) !== false) {
  204.  
  205.             tooltip(getCache(anchor.href), e);
  206.  
  207.             return;
  208.  
  209.         }
  210.  
  211.        
  212.  
  213.         tooltip('Expanding...', e);
  214.  
  215.        
  216.  
  217.         if (enqueue(anchor.href)) {
  218.  
  219.             ajaxRequest({
  220.  
  221.                 method: "GET",
  222.  
  223.                 url: this.api_endpoint + 'expand?format=json&title=1&url=' + encodeURIComponent(anchor.href),
  224.  
  225.                 headers: {
  226.                     'User-Agent': 'LongURL Mobile Expander/'+this.script_version+' (Greasemonkey)'
  227.                 },
  228.  
  229.                 onload: function(response) {
  230.  
  231.                     var data = jsonToObject(response);
  232.  
  233.                    
  234.  
  235.                     // cache response
  236.  
  237.                     if (typeof(data.messages) !== 'undefined') { // There was an error
  238.  
  239.                         setCache(anchor.href, 'LongURL Error: ' + data.messages[0].message);
  240.  
  241.                     } else {
  242.                         var result = data['long-url'];
  243.                         if (typeof(data['title']) !== 'undefined') {
  244.                             result = '<strong style="font-weight: bold;">'+data['title']+'</strong><br />'+result;
  245.                         }
  246.                         result += ' <a href="http://longurl.org/expand?url='+encodeURIComponent(anchor.href)+'&amp;src=lme_gm" title="Get more information about this link" style="color:#00f;">[more]</a>';
  247.  
  248.                         setCache(anchor.href, result);
  249.  
  250.                     }
  251.  
  252.                    
  253.  
  254.                     //Remove from queue
  255.  
  256.                     dequeue(anchor.href);
  257.  
  258.  
  259.                     // Make sure user is still hovering over this link before updating tooltip
  260.                     if (getCurrent() === anchor.href) {
  261.                         tooltip(getCache(anchor.href));
  262.                     }
  263.  
  264.                 }
  265.  
  266.             });
  267.  
  268.         }
  269.  
  270.     };
  271.    
  272.     getCurrent = function() {
  273.         return this.current_link;
  274.     };
  275.    
  276.  
  277.     setCache = function(key, value) {
  278.  
  279.         this.link_cache[escape(key)] = value;
  280.  
  281.     };
  282.    
  283.     getCache = function(key) {
  284.         if (typeof(this.link_cache[escape(key)]) !== 'undefined') {
  285.             return this.link_cache[escape(key)];
  286.         }
  287.         return false;
  288.     };
  289.  
  290.    
  291.     enqueue = function(short_url) {
  292.         if (typeof(this.ajax_queue[escape(short_url)]) === 'undefined') {
  293.             this.ajax_queue[escape(short_url)] = true;
  294.             return true;
  295.         }
  296.         return false;
  297.     };
  298.    
  299.  
  300.     dequeue = function(short_url) {
  301.  
  302.         this.ajax_queue.splice(this.ajax_queue.indexOf(escape(short_url)), 1);
  303.  
  304.     };
  305.  
  306.    
  307.  
  308.     tooltip = function(text, e) {
  309.  
  310.         if (typeof(this.tooltip_node) === 'undefined') {
  311.  
  312.             // Create the tooltip element
  313.  
  314.             this.tooltip_node = document.createElement('span');
  315.             this.tooltip_node.id = 'longurlme_tooltip';
  316.  
  317.             this.tooltip_node.style.display = 'none';
  318.  
  319.             this.tooltip_node.style.position = 'absolute';
  320.             this.tooltip_node.style.overflow = 'hidden';
  321.  
  322.             this.tooltip_node.style.maxWidth = '300px';
  323.  
  324.             this.tooltip_node.style.backgroundColor = '#ffffc9';
  325.  
  326.             this.tooltip_node.style.border = '1px solid #c9c9c9';
  327.  
  328.             this.tooltip_node.style.padding = '3px';
  329.  
  330.             this.tooltip_node.style.fontSize = '10px';
  331.             this.tooltip_node.style.letterSpacing = '0px';
  332.             this.tooltip_node.style.color = '#000';
  333.  
  334.             this.tooltip_node.style.zIndex = '5000';
  335.  
  336.             this.tooltip_node.style.textAlign = 'left';
  337.  
  338.            
  339.  
  340.             document.body.appendChild(this.tooltip_node);
  341.            
  342.             this.tooltip_node.addEventListener('mouseover', function(e) {
  343.                 showTooltip();
  344.  
  345.             }, true);
  346.  
  347.             this.tooltip_node.addEventListener('mouseout', function(e) {
  348.  
  349.                 hideTooltip();
  350.  
  351.             }, true);
  352.  
  353.         }
  354.  
  355.        
  356.  
  357.         if (text === false) {
  358.  
  359.             this.tooltip_node.style.display = 'none';
  360.  
  361.         } else {
  362.  
  363.             this.tooltip_node.innerHTML = text;
  364.  
  365.         }
  366.  
  367.        
  368.  
  369.         if (typeof(e) !== 'undefined') {
  370.             showTooltip();
  371.  
  372.             this.tooltip_node.style.display = 'inline';
  373.  
  374.            
  375.  
  376.             var pos = (e) ? cursorPosition(e):cursorPosition();
  377.  
  378.             this.tooltip_node.style.top = (pos.y + 15) + 'px';
  379.  
  380.             this.tooltip_node.style.left = (pos.x) + 'px';
  381.  
  382.         }
  383.  
  384.     };
  385.    
  386.     showTooltip = function() {
  387.         clearTimeout(this.tooltip_timeout);
  388.     };
  389.    
  390.     hideTooltip = function() {
  391.         clearTimeout(this.tooltip_timeout);
  392.         this.tooltip_timeout = setTimeout(function() {tooltip(false);}, 1000);
  393.     };
  394.  
  395.    
  396.  
  397.     // cursorPosition written by Beau Hartshorne
  398.  
  399.     cursorPosition = function(e) {
  400.  
  401.         e = e || window.event;
  402.  
  403.         var position = {x:0, y:0};
  404.  
  405.         if (e.pageX || e.pageY) {
  406.  
  407.             position.x = e.pageX;
  408.  
  409.             position.y = e.pageY;
  410.  
  411.         }
  412.  
  413.         else {
  414.  
  415.             position.x = e.clientX +
  416.  
  417.                 (document.documentElement.scrollLeft ||
  418.  
  419.                 document.body.scrollLeft) -
  420.  
  421.                 document.documentElement.clientLeft;
  422.  
  423.             position.y = e.clientY +
  424.  
  425.                 (document.documentElement.scrollTop ||
  426.  
  427.                 document.body.scrollTop) -
  428.  
  429.                 document.documentElement.clientTop;
  430.  
  431.         }
  432.  
  433.         return position;
  434.  
  435.     }
  436.  
  437.    
  438.  
  439.     // Greasekit did away with the GM_* functions, so for
  440.  
  441.     // compatability I have to use wrapper functions and
  442.  
  443.     // implement alternative functionality.
  444.  
  445.     setValue = function(key, value) {
  446.  
  447.         if (typeof(GM_setValue) !== 'undefined') {
  448.  
  449.             return GM_setValue(key, value);
  450.  
  451.         } else {   
  452.  
  453.             document.cookie = key+'='+encodeURIComponent(value);
  454.  
  455.         }
  456.  
  457.     };
  458.  
  459.    
  460.  
  461.     getValue = function(key, default_val) {
  462.  
  463.         if (typeof(GM_getValue) !== 'undefined') {
  464.  
  465.             return GM_getValue(key, default_val);
  466.  
  467.         } else {
  468.  
  469.             if (document.cookie && document.cookie != '') {
  470.  
  471.                 var cookies = document.cookie.split(';');
  472.  
  473.                 for(var x = 0; x < cookies.length; x++) {
  474.  
  475.                     var cookie = new String(cookies[x]).strip();
  476.  
  477.                     if (cookie.substring(0, key.length + 1) == (key + '=')) {
  478.  
  479.                         return decodeURIComponent(cookie.substring(key.length + 1));
  480.  
  481.                     }
  482.  
  483.                 }
  484.  
  485.             }
  486.  
  487.             return default_val;
  488.  
  489.         }
  490.  
  491.     };
  492.  
  493.    
  494.  
  495.     ajaxRequest = function(details) {
  496.  
  497.         if (typeof(GM_xmlhttpRequest) !== 'undefined') {
  498.  
  499.             return GM_xmlhttpRequest(details);
  500.  
  501.         } else {
  502.  
  503.             json_callback = details.onload;
  504.  
  505.             var script = document.createElement('script');
  506.  
  507.             script.src = details.url + '&callback=json_callback';
  508.  
  509.             document.body.appendChild(script);
  510.  
  511.         }
  512.  
  513.     };
  514.  
  515.    
  516.  
  517.     jsonToObject = function(response) {
  518.  
  519.         if (typeof(response.responseText) === 'undefined') {
  520.  
  521.             return response;
  522.  
  523.         } else {
  524.  
  525.             return eval('(' + response.responseText + ')');
  526.  
  527.         }
  528.  
  529.     };
  530.    
  531.     modifiedDOMCallback = function(e) {
  532.         if (e.relatedNode.id === 'longurlme_tooltip') return;
  533.            
  534.         clearTimeout(this.tooltip_timeout);
  535.         this.tooltip_timeout = setTimeout(function() {modifyShortLinks();}, 500);
  536.     };
  537.  
  538.    
  539.  
  540.     init = function() {
  541.  
  542.         var now = new Date();
  543.  
  544.         var serialized_services = getValue('longurl_services', false);
  545.  
  546.         var services_expire = Date.parse(getValue('longurl_expire_services', now.toUTCString()));
  547.  
  548.        
  549.  
  550.         if (serialized_services && services_expire > now.getTime()) {
  551.  
  552.             this.known_services = eval('(' + serialized_services + ')');
  553.  
  554.             modifyShortLinks();
  555.  
  556.         } else {
  557.  
  558.             getServicesFromAPI();
  559.  
  560.         }
  561.        
  562.         window.addEventListener('load', function(e) {
  563.             if (typeof(document.body) === 'undefined') return;
  564.            
  565.             document.body.addEventListener('DOMNodeInserted', function(e) {
  566.                 if (e.relatedNode.id === 'longurlme_tooltip') return;
  567.                    
  568.                 clearTimeout(this.tooltip_timeout);
  569.                 this.tooltip_timeout = setTimeout(function() {modifyShortLinks();}, 500);
  570.             }, false);
  571.         }, true);
  572.     };
  573.    
  574.     init();
  575.  
  576. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement