bNj / Amazon CamelCamelCamel Graphs & Shoptimate prices

// ==UserScript==
// @name         Amazon CamelCamelCamel Graphs & Shoptimate prices
// @version      0.8
// @description  Include CamelCamelCamel graphs & Shoptimate prices directly on Amazon products webpage
// @author       bNj
// @namespace    https://openuserjs.org/users/bNj
// @include      /^https?://www\.amazon\..*$/
// @include      http*://*.camelcamelcamel.com/*
// @include      http*://camelcamelcamel.com/*
// @include      http*://toolbar.shoptimate.com/*
// @grant        GM_xmlhttpRequest
// @require      https://code.jquery.com/jquery-latest.min.js
// @icon         https://www.amazon.com/favicon.ico
// ==/UserScript==

function init(){
    var $head = $('head');
    var $target = $("#price_feature_div");
    var country = document.domain.split(".")[document.domain.split(".").length - 1];
    var asin = $.trim($(':input[id="ASIN"]').attr("value"));

    $head.append('<script src="//code.jquery.com/jquery-latest.min.js"></script>');
    $head.append($('<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">'));
    $head.append('<style><style style="text/css">#shoptimate{width:100%;border-collapse:collapse;}#shoptimate td{padding:4px;}#shoptimate tr{background: none;}#shoptimate tr:hover {background-color: #f1f1f1;cursor:pointer;}.textalignmiddle {text-align:center;vertical-align:middle;line-height:250px;} #camelcamelcamel {width:450px;} #shoptimate {overflow:auto;height:250px;} small {font-size:11px !important;} #shoptimate > tr {height: 38px !important;} #bnj {font-size:11px !important; border: 1px solid #f1f1f1;padding:5px;border-radius:5px;background-color:rgb(252, 252, 252);box-shadow: 2px 2px 4px 0px #959595;margin-bottom:10px;display: table;}</style>');
    $target.append('<div id="bnj"><table><td width="40%"><div id="camelcamelcamel" class="textalignmiddle"><i class="fa fa-circle-o-notch fa-spin fa-fw"></i> Fetching Camelcamelcamel...</div></td><td width="60%"><div id="shoptimate" class="textalignmiddle"><i class="fa fa-circle-o-notch fa-spin fa-fw"></i> Fetching Shoptimate...</div></td></tr></table></div>');

    function loadShoptimateprices($div){
        var url = 'https://toolbar.shoptimate.com/v1/fr/fr/amazon_fr/' + asin + '/chrome.html?extensionversion=1.1.2&v=1.1.2';

        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function(res) {
                var parser = new DOMParser();
                var html = parser.parseFromString(res.responseText, "text/html");
                var list = $(html).find('#offerslist tr:gt(0)');
                /*list.each(function(){
                    $(this).attr('onclick',$(this).attr('onclick').replace('http://www.shoptimate.com/redirect?url=', ''));
                    while(isEncoded($(this).attr('onclick'))){
                        $(this).attr('onclick',decodeURIComponent($(this).attr('onclick')));
                    }
                });*/
                if(list.length > 0) {
                    $div.removeClass('textalignmiddle').hide().html(list).fadeIn();
                } else {
                    $div.hide().html('<i class="fa fa-ban" aria-hidden="true"></i> No data available').fadeIn();
                }
            },
            onerror: function(res) {
                xmlhttpRequest_error(res);
            }
        });
    }
    loadShoptimateprices($('#shoptimate'));

    function loadCamelCamelCamelgraph($div){
        var chart = {
            width : 450,
            height : 250,
            category : 'amazon-new'
        };

        var url = 'https://' + country + '.camelcamelcamel.com/product/' + asin;
        var graph = "<a target='blank' href='//" + country + ".camelcamelcamel.com/product/" + asin + "'><img src='//charts.camelcamelcamel.com/" + country + "/" + asin + "/" + chart.category + ".png?force=1&zero=0&w=" + chart.width + "&h=" + chart.height + "&desired=false&legend=1&ilt=1&tp=all&fo=0' /></a>";

        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function(res) {
                var parser = new DOMParser();
                var html = parser.parseFromString(res.responseText, "text/html");
                $div.html(graph);
            },
            onerror: function(res) {
                $div.hide().html('<i class="fa fa-ban" aria-hidden="true"></i> Unable to retrieve data.').fadeIn();
                xmlhttpRequest_error(res);
            }
        });
    }
    loadCamelCamelCamelgraph($('#camelcamelcamel'));
}

init();
function urlHandler(){
    this.orlUrl = window.location.href;
    this.check = {};
    var that = this;
    var detect = function(){
        if(that.orlUrl!=window.location.href){
            init();
            that.orlUrl = window.location.href;
        }
    };
    this.check = setInterval(function(){detect();},1000);
}
var ulrDetection = new urlHandler();

function xmlhttpRequest_error(res){
    var msg = [
        "An error occurred.",
        "responseText: " + res.responseText,
        "readyState: " + res.readyState,
        "responseHeaders: " + res.responseHeaders,
        "status: " + res.status,
        "statusText: " + res.statusText,
        "finalUrl: " + res.finalUrl].join('\n');
    console.log(msg);
}

function isEncoded(str) {
    return typeof str == "string" && decodeURIComponent(str) !== str;
}