[HFR] SFBA descriptor

Copie la description de l'article lorsque une url appropriée est présente dans le presse papier

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         [HFR] SFBA descriptor
// @namespace    sfba.hfr
// @version      1.3
// @description  Copie la description de l'article lorsque une url appropriée est présente dans le presse papier
// @include       https://forum.hardware.fr/message.php*
// @include       https://forum.hardware.fr/forum2.php*
// @include       https://forum.hardware.fr/hfr/*
// @icon          http://reho.st/self/40f387c9f48884a57e8bbe05e108ed4bd59b72ce.png
// @connect       *
// @require            https://openuserjs.org/src/libs/sizzle/GM_config.js
// @grant         GM_info
// @grant         GM_deleteValue
// @grant         GM_getValue
// @grant         GM_listValues
// @grant         GM_setValue
// @grant         GM_getResourceText
// @grant         GM_getResourceURL
// @grant         GM_addStyle
// @grant         GM_log
// @grant         GM_openInTab
// @grant         GM_registerMenuCommand
// @grant         GM_setClipboard
// @grant         GM_xmlhttpRequest
// @require       http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
// ==/UserScript==

function init_throbber(){
  GM_addStyle("#hiu_throbber_sfba{position:fixed;left:0;top:0;background-color:#242424;z-index:1001;" +
              "display:none;opacity:0;transition:opacity 0.7s ease 0s;}");
  GM_addStyle("#hiu_throbber_img_sfba{position:fixed;left:calc(50% - 64px);top:calc(50% - 64px);width:128px;height:128px;z-index:1002;" +
              "display:none;opacity:0;transition:opacity 0.7s ease 0s;border:0;padding:0;}");
  GM_addStyle(".hfr_apercu_nope{display:none !important;}");
  var throbber_image_url = "https://reho.st/self/30271dc1b7cac925aeabb89fa70e1e17cf5e1840.png";
  var hiu_throbber_img_sfba = new Image();
  hiu_throbber_img_sfba.src = throbber_image_url;
  hiu_throbber_img_sfba.setAttribute("id", "hiu_throbber_img_sfba");
  var hiu_throbber_sfba = document.createElement("div");
  hiu_throbber_sfba.setAttribute("id", "hiu_throbber_sfba");
  hiu_throbber_sfba.appendChild(hiu_throbber_img_sfba);
  hiu_throbber_sfba.addEventListener("transitionend", throbber_transitionend, false);
  document.body.appendChild(hiu_throbber_sfba);


}


function init_config(){
    GM_config.init(
    {
         'id': 'SFBAconfig', // The id used for this instance of GM_config
         'title': 'SFBA descriptor configuration', // Panel Title
         'fields': // Fields object
         {
             'amazon': // This is the id of the field
             {
                  'label': 'Amazon', // Appears next to field
                  'type': 'checkbox', // Makes this setting a checkbox input
                  'default': true // Default value if user doesn't change it
             },
             'aliexpress': // This is the id of the field
             {
                  'label': 'Aliexpress', // Appears next to field
                  'type': 'checkbox', // Makes this setting a checkbox input
                  'default': true // Default value if user doesn't change it
             },
             'dealabs': // This is the id of the field
             {
                  'label': 'Dealabs', // Appears next to field
                  'type': 'checkbox', // Makes this setting a checkbox input
                  'default': true // Default value if user doesn't change it
             },
             'gearbest': // This is the id of the field
             {
                  'label': 'Gearbest', // Appears next to field
                  'type': 'checkbox', // Makes this setting a checkbox input
                  'default': true // Default value if user doesn't change it
             },
             'banggood': // This is the id of the field
             {
                  'label': 'Banggood', // Appears next to field
                  'type': 'checkbox', // Makes this setting a checkbox input
                  'default': true // Default value if user doesn't change it
             },
             'thingiverse': // This is the id of the field
             {
                  'label': 'Thingiverse', // Appears next to field
                  'type': 'checkbox', // Makes this setting a checkbox input
                  'default': true // Default value if user doesn't change it
             }
         },
         css: '#SFBAconfig { background-color: #d0e0ff; }',
    });
    GM_registerMenuCommand("[HFR] SFBA descriptor -> configuration", function(){GM_config.open();});
}

function display_throbber(){
  if(document.querySelector("div#apercu_reponse")){
    document.querySelector("div#apercu_reponse").classList.add("hfr_apercu_nope");
  }
  hiu_throbber_img_sfba.style.display = "block";
  hiu_throbber_sfba.style.display = "block";
  hiu_throbber_sfba.style.width = document.documentElement.scrollWidth + "px";
  hiu_throbber_sfba.style.height = document.documentElement.scrollHeight + "px";
  hiu_throbber_img_sfba.style.opacity = "1";
  hiu_throbber_sfba.style.opacity = "0.8";
}

function throbber_transitionend() {
  if(hiu_throbber_sfba.style.opacity === "0") {
    hiu_throbber_img_sfba.style.display = "none";
    hiu_throbber_sfba.style.display = "none";
    if(document.querySelector("div#apercu_reponse")){
      document.querySelector("div#apercu_reponse").classList.remove("hfr_apercu_nope");
    }
  }
}

function hide_throbber(){
  hiu_throbber_img_sfba.style.opacity = "0";
  hiu_throbber_sfba.style.opacity = "0";
}

function insert_text_at_cursor (textarea, text) {
	var start = textarea.selectionStart;
	var end = textarea.selectionEnd;
	textarea.value = textarea.value.substr (0, start) + text + textarea.value.substr (end);
	textarea.setSelectionRange (start + text.length, start + text.length);
}

function isUrlValid(url) {
    var valid = /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url.href);

    var parsable = false;
    
    if (valid)
    {
        if ( (url.host.indexOf("amazon") !== -1) && (GM_config.get('amazon')))
        {
            parsable = true;
        }
        else if ( (url.host.indexOf("aliexpress") !== -1)  && (GM_config.get('aliexpress')))
        {
            parsable = true;
        }
        else if ( (url.host.indexOf("dealabs") !== -1) && (GM_config.get('dealabs')))
        {
            parsable = true;
        }
        else if ( (url.host.indexOf("gearbest") !== -1) && (GM_config.get('gearbest')))
        {
            parsable = true;
        }
        else if ( (url.host.indexOf("banggood") !== -1) && (GM_config.get('banggood')))
        {
            parsable = true;
        }
        else if ( (url.host.indexOf("thingiverse") !== -1) && (GM_config.get('thingiverse')))
        {
            parsable = true;
        }
    }
    
    return (valid & parsable);
}

function extractHostname(url) {
    var hostname;
    //find & remove protocol (http, ftp, etc.) and get hostname

    if (url.indexOf("://") > -1) {
        hostname = url.split('/')[2];
    }
    else {
        hostname = url.split('/')[0];
    }

    //find & remove port number
    hostname = hostname.split(':')[0];
    //find & remove "?"
    hostname = hostname.split('?')[0];

    return hostname;
}

function parseAmazon(doc, raw = false)
{
    var img = "";
    var title = doc.find("#productTitle").text().trim();    
    var imgJson = doc.find("#imgTagWrapperId").children().attr('data-a-dynamic-image');
    if (imgJson)
        img = Object.keys(JSON.parse(imgJson))[0];
    var price = doc.find(".a-size-medium.a-color-price").eq(0).text();
    if (price)
        price = price.trim();

    if (title && img && price)
    {
        if (raw)
        {
            return [img, title + " - " + price];
        }
        else
        {
            return title + " - " + price + "[/url]\n[img]http://reho.st/preview/" + img + "[/img]";
        }
    }
    else
        return "";
}

function parseAli(doc, raw = false)
{
    var title = doc.find(".product-name").text().trim();
    var img = doc.find(".ui-image-viewer-thumb-frame").children().attr('src');
    var price = doc.find("#j-sku-discount-price").text().trim() + doc.find(".p-symbol").text()[0];
    if (price)
        price = price.trim();

    if (title && img && price)
    {
        if (raw)
        {
            return [img, title + " - " + price];
        }
        else
        {
            return title + " - " + price + "[/url]\n[img]http://reho.st/preview/" + img + "[/img]";
        }
    }
    else
        return "";
}

function parseDealabs(doc, raw = false)
{
    var title = doc.find("h1.thread-title").text().trim();
    var img = doc.find("a.threadItem-imgFrame").children().attr('src');
    var price = "";
    var oldPrice = "";
    try 
    {
        price = doc.find("span.thread-price").first().text().trim();
        oldPrice = doc.find("span.text--lineThrough").text().trim();
    }
    catch(err){}
    
    if (title && img && price)
    {
        if (oldPrice)
        {
            if (raw)
            {
                return [img, title + " - " + price + oldPrice];
            }
            else
            {
                return title + "[/url]\n[img]http://reho.st/preview/" + img + "[/img]\n[b][#FF0000]" + price + "[/#FF0000][/b] [strike]" + oldPrice + "[/strike]";
            }
        }
        else
        {
            if (raw)
            {
                return [img, title + " - " + price];
            }
            else
            {
                return title + "[/url]\n[img]http://reho.st/preview/" + img + "[/img]\n[b][#FF0000]" + price + "[/#FF0000][/b]";
            }
        }
    }
    else
    {
        return "";
    }
}

function parseGearbest(doc, raw= false)
{
    var title = doc.find("h1").text().trim();
    var img = doc.find("#js-goodsNormalImg").attr('src');
    var price = doc.find(".goodsIntro_price.js-currency.js-panelIntroPrice").text();
    if (price)
        price = price.trim();
    
    if (title && img && price)
    {
        if (raw)
        {
           return [img, title + " - " + price];
        }
        else
        {
            return title + " - " + price + "[/url]\n[img]" + img + "[/img]";
        }
    }
    else
        return ""; 
}

function parseBanggood(doc, raw = false)
{
    var title = doc.find("h1").text().trim();
    var img = doc.find(".left_largerView_image_20161213").children().attr('src');
    var price = doc.find(".now").text().trim() + doc.find(".top_price_datalist_20161213").children().first().text().trim();
    if (price)
        price = price.trim();

    if (title && img && price)
    {
        if (raw)
        {
            return [img, title + " - " + price];
        }
        else
        {
            return title + " - " + price + "[/url]\n[img]" + img + "[/img]";
        }
    }
    else
        return "";
}

function parseThingiverse(doc, raw = false)
{
    var title = doc.find("h1").first().text().trim();
    var img = doc.find(".gallery-slider").children().attr('data-medium');

    if (title && img)
    {
        if (raw)
        {
            return [img, title];
        }
        else
        {
            return title + "[/url]\n[img]" + img + "[/img]";
        }
    }
}

function displayContent(link)
{
    var container;

    link.addEventListener("mouseover", function()
    {
        container = document.createElement("div");
        container.style.position = "fixed";
        container.style.background = "#dedfdf";
        container.style.width = "auto";
        container.style.padding = "5px";
        container.style.border = "1px solid black";
        container.style.top = "10px";
        container.style.right = "10px";
        container.style.maxWidth = "450px";

        document.body.appendChild(container);

        let text = document.createElement("p");
        text.style.fontFamily = "arial,sans-serif";
        text.style.fontWeight = "bold";
        text.innerHTML = "Chargement";
        container.appendChild(text);

        let img = new Image();
        img.style.display = "block";
        img.style.margin = "auto";
        img.style.maxWidth = "450px";
        img.style.maxHeight = parseInt((document.documentElement.clientHeight - 20 - 12), 10) + "px";

        getData(link.href, img, text);

        container.appendChild(img);
    });

    link.addEventListener("mouseout", function()
    {
        if(container && container.parentNode)
        {
            let elts = container.querySelectorAll("p, img");
            for(let elt of elts)
            {
                elt.parentNode.removeChild(elt);
            }
            container.parentNode.removeChild(container);
        }
    }, false);

}

function getData(url, img, txt)
{
    var content = "";

    GM_xmlhttpRequest({
		method : "GET",
		url : url,
        anonymous: true,
        context : {
			textarea : this
		},
		onabort : hide_throbber,
		onerror : hide_throbber,
		ontimeout : hide_throbber,
		onload : function (response) {
			// fin du chargement
			hide_throbber();

            if (extractHostname(url).indexOf("amazon") !== -1)
            {
                content = parseAmazon($(response.responseText), true);
            }
            else if (extractHostname(url).indexOf("aliexpress") !== -1)
            {
                content = parseAli($(response.responseText), true);
            }
            else if (extractHostname(url).indexOf("dealabs") !== -1)
            {
                content = parseDealabs($(response.responseText), true);
            }
            else if (extractHostname(url).indexOf("gearbest") !== -1)
            {
                content = parseGearbest($(response.responseText), true);
            }
            else if (extractHostname(url).indexOf("banggood") !== -1)
            {
                content = parseBanggood($(response.responseText), true);
            }
            else if (extractHostname(url).indexOf("thingiverse") !== -1)
            {
                content = parseThingiverse($(response.responseText), true);
            }
            img.src = content[0];
            txt.innerHTML = content[1];
        }
    });
}

init_throbber();
init_config();

function pasting (event) {
    var url = "";
    var bbcode = "";
	if (event.clipboardData.files.length < 1)
    {
		var str = event.clipboardData.getData("text/plain");
		if ( (str.length === 0) || (!isUrlValid(str)) )
			return;
        else
            url = str;
	}
    else
    {
        return;
    }
	
	// chargement
	display_throbber();
	
	GM_xmlhttpRequest({
		method : "GET",
		url : url,
        context : {
			textarea : this
		},
		onabort : hide_throbber,
		onerror : hide_throbber,
		ontimeout : hide_throbber,
		onload : function (response) {
			// fin du chargement
			hide_throbber();

            if (extractHostname(url).indexOf("amazon") !== -1)
            {
                bbcode = parseAmazon($(response.responseText));
            }
            else if (extractHostname(url).indexOf("aliexpress") !== -1)
            {
                bbcode = parseAli($(response.responseText));
            }
            else if (extractHostname(url).indexOf("dealabs") !== -1)
            {
                bbcode = parseDealabs($(response.responseText));
            }
            else if (extractHostname(url).indexOf("gearbest") !== -1)
            {
                bbcode = parseGearbest($(response.responseText));
            }
            else if (extractHostname(url).indexOf("banggood") !== -1)
            {
                bbcode = parseBanggood($(response.responseText));
            }
            else if (extractHostname(url).indexOf("thingiverse") !== -1)
            {
                bbcode = parseThingiverse($(response.responseText));
            }
            
            if (bbcode)
                insert_text_at_cursor(this.context.textarea, "[url=" + url + "]" + bbcode);
            else
                insert_text_at_cursor(this.context.textarea, "[url]" + url + "[/url]");
		}
	});
	return event.preventDefault();
	
}

var content_form = document.querySelector("#content_form");
if (content_form !== null)
	content_form.addEventListener('paste', pasting);




var observer=new MutationObserver(function(mutations, observer){ 
  var textareas=document.querySelectorAll("textarea[id^=\"rep_editin_\"]" ); 
  if(textareas.length){ 
    for(var textarea of textareas) { 
      textarea.removeEventListener('paste', pasting, false); 
      textarea.addEventListener('paste', pasting, false); 
    } 
  } 
}); 
observer.observe(document, {attributes: false, childList: true, characterData: false, subtree: true});

var links = document.getElementById("mesdiscussions").querySelectorAll(
  "table.messagetable td.messCase2 div[id^='para'] > span:not(.signature) a.cLink, " +
  "table.messagetable td.messCase2 div[id^='para'] > div:not(.edited) a.cLink, " +
  "table.messagetable td.messCase2 div[id^='para'] > *:not(span):not(div) a.cLink");
for(let link of links)
{
  if (isUrlValid(link))
  {
      displayContent(link);
  }
}