Greasy Fork镜像 支持简体中文。

Amazon a Pesos Argentinos

Mostrar precios en pesos argentinos a la cotización del momento

  1. // ==UserScript==
  2. // @name Amazon a Pesos Argentinos
  3. // @namespace sharkiller-amazon-dolar-tarjeta
  4. // @description Mostrar precios en pesos argentinos a la cotización del momento
  5. // @version 7.0
  6. // @copyright 2019 - Sharkiller
  7. // @homepage http://foros.3dgames.com.ar/threads/909283-comprar-en-amazon-europa-a-la-puerta-de-tu-casa-con-amazonglobal-ver-post-1-y-2
  8. // @supportURL http://foros.3dgames.com.ar/private.php?do=newpm&u=534083
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js#sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=
  10. // @require https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js#sha256-iaqfO5ue0VbSGcEiQn+OeXxnxAMK2+QgHXIDA5bWtGI=
  11. // @include *amazon.tld/*
  12. // @connect amazon.com
  13. // @connect amazon.co.uk
  14. // @connect amazon.ca
  15. // @connect amazon.es
  16. // @connect amazon.de
  17. // @connect amazon.fr
  18. // @connect amazon.it
  19. // @connect europa.eu
  20. // @connect mercadolibre.com
  21. // @connect esapi.isthereanydeal.com
  22. // @grant GM_getValue
  23. // @grant GM_setValue
  24. // @grant GM_addStyle
  25. // @grant GM_log
  26. // @grant GM_setClipboard
  27. // @grant GM_xmlhttpRequest
  28. // @run-at document-start
  29. // @noframes
  30. // ==/UserScript==
  31.  
  32. (function() {
  33. if( typeof jQuery === 'undefined' ){
  34. console.log('jQuery not found');
  35. return false;
  36. }
  37.  
  38. GM_addStyle('.price-ars{color:green;display:inline-block;margin:0 8px;background:linear-gradient(to bottom,#add8e6,#fff,#add8e6);border-radius:8px;padding:0 6px}'+
  39. '#sc-buy-box .price-ars{font-size:12px;display:block;padding:0;margin:0;background:0 0}div#sc-buy-box{margin-bottom:-14px}#orderDetails{width: 1200px;}#od-subtotals{width: 350px!important;margin-right:-350px!important;}');
  40. GM_addStyle('#snoop-icon{margin-left:4px;width:30px;height:20px}#snoop-placeholder{width:32px}div.snoop-loader{width:13px;height:13px}div.snoop-tooltip,div.snoop-tooltip-ml{display:none;font-size:13px;border-image:none;letter-spacing:0}'+
  41. 'div.snoop-tooltip div.entry,div.snoop-tooltip-ml div.entry{padding-top:5px}span.snoop-price{color:#900;font-size:1em;font-weight:700}span.snoop-warning{color:#C60!important}.snoop-not-found{text-decoration:line-through}'+
  42. 'span.snoop-on{color:#000;font-weight:400}span.back-link{line-height:0;margin-left:1px;top:-10px;position:relative}'+
  43. 'span.back-link>img{top:1;position:relative}span.back-link>a{font-size:1em;text-decoration:none!important}#snoop-icon-ml{margin-left:10px}');
  44. GM_addStyle('#pesos-carrito-html{width:400px;min-height:34px;margin:0 auto;left:calc(80% - 200px);top:150px;background:white;position: fixed;z-index:1000000;padding:20px;border:1px solid black;border-radius:8px;box-shadow: 0px 0px 40px black;}#pesos-carrito-html .price-ars{text-align: right; margin: 0;}');
  45.  
  46. String.prototype.endsWith = function (pattern) {
  47. var d = this.length - pattern.length;
  48. return d >= 0 && this.lastIndexOf(pattern) === d;
  49. };
  50.  
  51. var domain = document.domain.substr(document.domain.lastIndexOf('.') + 1);
  52. var domainData = {
  53. parseLinks: false, //GM_getValue('parseLink', true),
  54. com: {
  55. amazonSeller: "ATVPDKIKX0DER",
  56. withVAT: false,
  57. vat: 0,
  58. tag: "r0f34-20",
  59. symbol: "$",
  60. priceRegex: /\$\s*([\d,.]+\d)/,
  61. currencyFrom: "USD"
  62. },
  63. ca: {
  64. amazonSeller: "A3DWYIK6Y9EEQB",
  65. withVAT: false,
  66. vat: 0,
  67. tag: "",
  68. symbol: "CDN$ ",
  69. priceRegex: /CDN\$\s*([\d,.]+\d)/,
  70. currencyFrom: "CAD"
  71. },
  72. uk: {
  73. amazonSeller: "A3P5ROKL5A1OLE",
  74. withVAT: true,
  75. vat: 1.20,
  76. tag: "r0f340c-21",
  77. symbol: "£",
  78. priceRegex: /£\s*([\d,.]+\d)/,
  79. currencyFrom: "GBP"
  80. },
  81. es: {
  82. amazonSeller: "A1AT7YVPFBWXBL",
  83. withVAT: true,
  84. vat: 1.21,
  85. tag: "r0f340fc-21",
  86. symbol: "EUR ",
  87. priceRegex: /(?:EUR\s*|€)([\s\d,.]+\d)/,
  88. currencyFrom: "EUR"
  89. },
  90. de: {
  91. amazonSeller: "A3JWKAKR8XB7XF",
  92. withVAT: true,
  93. vat: 1.19,
  94. tag: "r0f3409-21",
  95. symbol: "EUR ",
  96. priceRegex: /(?:EUR\s*|€)([\s\d,.]+\d)/,
  97. currencyFrom: "EUR"
  98. },
  99. fr: {
  100. amazonSeller: "A1X6FK5RDHNB96",
  101. withVAT: true,
  102. vat: 1.20,
  103. tag: "r0f340a-21",
  104. symbol: "EUR ",
  105. priceRegex: /(?:EUR\s*|€)([\s\d,.]+\d)/,
  106. currencyFrom: "EUR"
  107. },
  108. it: {
  109. amazonSeller: "A11IL2PNWYJU7H",
  110. withVAT: true,
  111. vat: 1.22,
  112. tag: "r0f3401-21",
  113. symbol: "EUR ",
  114. priceRegex: /(?:EUR\s*|€)([\s\d,.]+\d)/,
  115. currencyFrom: "EUR"
  116. }
  117. };
  118.  
  119. // Various currencies' rates to EUR
  120. window.Rates = {
  121. timestamp: new Date(),
  122. 'EUR': 1,
  123. 'USD': 0,
  124. 'GBP': 0
  125. };
  126. refreshRates();
  127.  
  128. var LAST_RUN = "last_run";
  129. var CURRENCY_RATE = "currency_rate";
  130.  
  131. var decimalPlaces = 2;
  132. var prefixCurrencySymbol = true;
  133. var taxPorcentage = 3.6;
  134.  
  135. var rounding = Math.pow(10, decimalPlaces);
  136.  
  137. var rate = GM_getValue(CURRENCY_RATE);
  138. var lastRun = GM_getValue(LAST_RUN, "01/01/0001");
  139. var showVAT = GM_getValue('show_vat', true);
  140. var currencyTo = 'ARS';
  141. var todayDate = new Date();
  142. var todayString = todayDate.getDate() + "/" + (todayDate.getMonth()+1) + "/" + todayDate.getFullYear();
  143. var currencyToSymbol = 'ARS $';
  144.  
  145. rate = tryParseJSON(rate);
  146. if( rate == false ) {
  147. lastRun = "01/01/0001";
  148. }else{
  149. rate = rate[domainData[domain].currencyFrom][currencyTo];
  150. }
  151.  
  152. function tryParseJSON(jsonString){
  153. try {
  154. var obj = JSON.parse(jsonString);
  155. if (obj && typeof obj === "object") {
  156. return obj;
  157. }
  158. }
  159. catch (e) {}
  160. return false;
  161. }
  162.  
  163. function regularPriceParser(price, currency) {
  164. price = price.replace(/\s/g, '');
  165.  
  166. var regex = /^[\d.]+,[\d]{2}$/;
  167. var needProperPrice = regex.exec(price);
  168. if(needProperPrice) {
  169. price = price.replace(/\./g, '').replace(/,/, '.');
  170. }else{
  171. price = price.replace(/\,/g, '');
  172. }
  173.  
  174. return parseFloat(price);
  175. }
  176.  
  177. function fetchCurrencyData(coin, callback) {
  178. GM_xmlhttpRequest({
  179. method: "GET",
  180. url: "https://esapi.isthereanydeal.com/v01/rates/?to="+coin,
  181. onload: function(responseDetails) {
  182. var rateTry = tryParseJSON(responseDetails.responseText);
  183. if(rateTry !== false && rateTry.result == "success"){
  184. GM_setValue(CURRENCY_RATE, JSON.stringify(rateTry.data));
  185. GM_setValue(LAST_RUN, todayString);
  186. callback();
  187. }else{
  188. alert("Error fetching currency data for " + coin);
  189. }
  190. },
  191. onerror: function(responseDetails) {
  192. alert("Error fetching currency data for " + coin);
  193. }
  194. });
  195. }
  196.  
  197. function appendConversionNoVAT(price, matched, offset, string) {
  198. return appendConversion(price, matched, offset, string, true);
  199. }
  200.  
  201. function appendConversion(price, matched, offset, string, novat, customvat) {
  202.  
  203. var originalPrice = regularPriceParser(matched, domainData[domain].currencyFrom);
  204.  
  205. if (isNaN(originalPrice)) {
  206. return price;
  207. }
  208.  
  209. if(novat !== true){
  210. if(customvat > 1){
  211. originalPrice /= customvat;
  212. }else if(customvat === undefined && domainData[domain].withVAT){
  213. originalPrice /= domainData[domain].vat;
  214. }
  215. }
  216.  
  217. var converted = formatCurrency(originalPrice * (rate * (taxPorcentage / 100 + 1)), rounding, currencyToSymbol, prefixCurrencySymbol);
  218.  
  219. if(showVAT && novat !== true && (customvat > 1 || (customvat === undefined && domainData[domain].withVAT)) ){
  220. originalPrice = formatCurrency(originalPrice, rounding, domainData[domain].symbol, prefixCurrencySymbol);
  221.  
  222. return '<span title="Original: ' + price + (customvat > 1?' - VAT: ' + Math.round((customvat-1)*100)+'%':'') + '">' + originalPrice + '<div class="price-ars">' + converted + '</div></span>';
  223. }else{
  224. return price + '<div class="price-ars">' + converted + '</div>';
  225. }
  226.  
  227. }
  228.  
  229. function formatCurrency(num, rounding, symbol, prefix) {
  230. sign = (num == (num = Math.abs(num)));
  231. num = Math.floor(num * rounding + 0.50000000001);
  232. cents = num % rounding;
  233.  
  234. num = Math.floor(num / rounding).toString();
  235.  
  236. if (cents < 10) {
  237. cents = "0" + cents;
  238. }
  239.  
  240. for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
  241. num = num.substring(0, num.length - (4 * i + 3)) + ',' +
  242. num.substring(num.length-(4*i+3));
  243. }
  244.  
  245. if (prefix) {
  246. return (symbol + ((sign)?'':'-') + num + '.' + cents);
  247. } else {
  248. return (((sign)?'':'-') + num + '.' + cents + symbol);
  249. }
  250. }
  251.  
  252. convertCurrency = function(carrito, vat) {
  253. switch(carrito){
  254. case 1:
  255. if( $('.a-size-base.a-text-bold:contains(Order summary)').length === 0 &&
  256. $('.a-size-base.a-text-bold:contains(Récapitulatif de commande)').length === 0 &&
  257. $('.a-size-base.a-text-bold:contains(Riepilogo ordine)').length === 0 &&
  258. $('.a-size-base.a-text-bold:contains(Resumen del pedido)').length === 0 &&
  259. $('.a-size-base.a-text-bold:contains(Zusammenfassung der Bestellung)').length === 0 &&
  260. $('.ap_popover.ap_popover_sprited.snoop-tooltip').length === 0
  261. ){
  262. return false;
  263. }else{
  264. if($('#sc-buy-box.price-ars-cart').length === 0){
  265. $('#sc-buy-box').addClass('price-ars-cart');
  266. }else{
  267. return false;
  268. }
  269. }
  270. break;
  271. case 2:
  272. if( $('.entry.snoop-price:not(.snoop-warning):not(.price-ars-cart)').length === 0 ){
  273. return false;
  274. }
  275. break;
  276. default:
  277. break;
  278. }
  279.  
  280. //console.log('Cambiando precios', carrito);
  281.  
  282. $('.a-column.a-span3.a-text-right.a-span-last.sc-value').removeClass('a-span3').addClass('a-span4');
  283. $('.a-column.a-span9.sc-text').removeClass('a-span9').addClass('a-span8');
  284. $('a.a-popover-trigger.a-declarative:contains(Estimated)').html('Shipping & handling <i class="a-icon a-icon-popover"></i>');
  285.  
  286. if(carrito == 2){
  287. $('.entry.snoop-price:not(.snoop-warning)').each(function(){
  288. var text = jQuery(this).text();
  289. if( $(this).children().length === 0 && text.indexOf(domainData[domain].symbol) != -1 && text.indexOf('ARS') == -1){
  290. $(this).addClass('price-ars-cart').html( text.replace(domainData[domain].priceRegex, appendConversion) );
  291. }
  292. });
  293. }else{
  294. //console.log($('span:not(:has(*))'));
  295. $('span:not(:has(*))').each(function(){
  296. var parent = false;
  297. var text = $(this).text();
  298. if( $(this).hasClass('a-price-symbol') ){
  299. parent = true;
  300. text = $(this).parent().text();
  301. }
  302. if( $(this).children().length === 0 && domainData[domain].priceRegex.test(text) && text.indexOf('ARS') == -1){
  303. if( $(this).parents('#sc-buy-box').length == 1 ||
  304. $(this).parents('#pesos-carrito-html').length == 1 ||
  305. window.location.href.indexOf("/gp/css/summary/") > -1 ||
  306. window.location.href.indexOf("/order-details") > -1 ||
  307. window.location.href.indexOf("/order-history") > -1 ||
  308. window.location.href.indexOf("/shipoptionselect/") > -1
  309. ){
  310. if(parent){
  311. $(this).closest('.a-price').html( text.replace(domainData[domain].priceRegex, appendConversionNoVAT) );
  312. }else{
  313. $(this).html( text.replace(domainData[domain].priceRegex, appendConversionNoVAT) );
  314. }
  315. }else{
  316. var customVAT = function(price, matched, offset, string){
  317. return appendConversion(price, matched, offset, string, false, vat);
  318. };
  319. if(parent){
  320. $(this).closest('.a-price').html( text.replace(domainData[domain].priceRegex, customVAT) );
  321. }else{
  322. $(this).html( text.replace(domainData[domain].priceRegex, customVAT) );
  323. }
  324. }
  325. }
  326. });
  327. }
  328. };
  329.  
  330. function parseLinks(){
  331. $('head').append('<meta name="referrer" content="no-referrer">');
  332. $('a[href*="/dp/"]:not([href*="?tag="])').each(function(i,item){
  333. $(item).attr('href', $(item).attr('href').replace('?','?tag='+domainData[domain].tag+'&'));
  334. });
  335. }
  336.  
  337. var running_convert_1 = false;
  338. var running_convert_2 = false;
  339. $( document ).ready(function(){
  340.  
  341. console.log('Page ready!');
  342.  
  343. //$('#nav-tools').prepend('<a href="javascript:void(0)" id="pesos-carrito" class="nav-a nav-a-2 nav-truncate"><span class="nav-line-1">Carrito</span><span class="nav-line-2"><img src="https://i.imgur.com/qa5ZXdT.png" width="95"></span></a>');
  344. $('#nav-tools').prepend('<a href="javascript:void(0)" class="nav-a nav-a-2 nav-cart" id="pesos-carrito"><span class="nav-line-1">Calcular</span><span class="nav-line-2">Carrito<span class="nav-icon nav-arrow"></span></span><span class="nav-cart-icon nav-sprite"></span><span class="nav-cart-count nav-cart-1">$</span></a>');
  345.  
  346. $('#pesos-carrito').click(function(){
  347. $('body').append('<div id="pesos-carrito-html"><img src="https://i.imgur.com/Dp92MjH.gif" /> Cargando...</div>');
  348. P.when("LUXController").execute(function(LUXController){
  349. var addressId = LUXController.getLocationData().obfuscatedId;
  350. if(addressId !== undefined){
  351. //GM_setClipboard(addressId+(16*8),"text");
  352. console.log(addressId);
  353. $.get("/gp/cart/view.html/ref=nav_cart", function(){
  354. $.getJSON("/gp/cart/ajax-load-flc.html/ref=flc-for-enable-flc",{addressId: addressId, flcExpanded: 1}, function(result){
  355. var cartTotal = jQuery(result.features["buy-box"].featurehtml).find('#a-popover-vat_breakdown,.sc-subtotal-detail');
  356. $('#pesos-carrito-html').html(cartTotal.html());
  357. $('#pesos-carrito-html span').removeClass("a-nowrap");
  358. $('#pesos-carrito-html span.sc-importfee').addClass("a-spacing-small");
  359. convertCurrency();
  360. });
  361. });
  362. }
  363. });
  364. });
  365.  
  366. if(domainData.parseLinks) parseLinks();
  367.  
  368. if (rate === undefined || todayString !== lastRun) {
  369. fetchCurrencyData(currencyTo, function() {
  370. rate = GM_getValue(CURRENCY_RATE);
  371. rate = tryParseJSON(rate);
  372. if( rate != false ) {
  373. rate = rate[domainData[domain].currencyFrom][currencyTo];
  374. convertCurrency();
  375. }
  376. });
  377. } else {
  378. console.log('Currency rate: ', rate);
  379. convertCurrency();
  380. }
  381.  
  382. $('.a-fixed-right-grid-col.a-col-right').bind("DOMSubtreeModified",function(e){
  383. if(running_convert_1 === false){
  384. console.log('Auto 1');
  385. running_convert_1 = true;
  386. setTimeout(function(){convertCurrency(1); running_convert_1=false;}, 1000);
  387. }
  388. });
  389.  
  390. $('#priceblock_ourprice').bind("DOMSubtreeModified",function(e){
  391. if(running_convert_2 === false){
  392. console.log('Auto 2');
  393. running_convert_2 = true;
  394. setTimeout(function(){convertCurrency(2); running_convert_2=false;}, 1000);
  395. }
  396. });
  397.  
  398. /*
  399. ////////////////////////////////////////////////////////////////
  400. PRECIOS DE OTRAS TIENDAS
  401. ////////////////////////////////////////////////////////////////
  402. */
  403.  
  404. var asin = $('#ASIN').val();
  405. if (asin === undefined)
  406. return;
  407. snoop.initialize(asin, domainData, domain);
  408.  
  409. });
  410. })();
  411.  
  412. function refreshRates() {
  413. var cachedRates = JSON.parse(localStorage.getItem("conversionRates"));
  414. //console.log(cachedRates);
  415. if (cachedRates !== null && cachedRates.timestamp !== undefined) {
  416. cachedRates.timestamp = new Date(cachedRates.timestamp);
  417. Rates = cachedRates;
  418. var ageInHours = (new Date() - cachedRates.timestamp) / 1000 / 60 / 60;
  419. if (ageInHours < 7)
  420. return;
  421. }
  422. console.log('Refreshing conversion rates...');
  423. GM_xmlhttpRequest({
  424. method: "GET",
  425. url: 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml',
  426. onload: function(responseDetails) {
  427. var $document = $(responseDetails.responseText);
  428. for (var rate in Rates) {
  429. if (typeof rate !== 'string' || rate === 'EUR')
  430. continue;
  431. Rates[rate] = parseFloat($document.find('Cube[currency="' + rate + '"]').attr('rate'));
  432. }
  433. Rates.timestamp = new Date();
  434. localStorage.conversionRates = JSON.stringify(Rates);
  435. },
  436. onerror: function(responseDetails) {
  437. alert("Error fetching currency rates.");
  438. }
  439. });
  440. }
  441.  
  442. var Money = function (amount, currency, currency_symbol, extraAmount) {
  443. this.amount = amount;
  444. this.extraAmount = extraAmount;
  445. this.currency = currency;
  446. this.currency_symbol = currency_symbol;
  447. //console.log('Money', this);
  448. };
  449. Money.prototype.for = function (currency, currency_symbol) {
  450. var rate = Rates[currency] / Rates[this.currency];
  451. var convertedAmount = this.amount * rate;
  452. var convertedExtraAmount = this.extraAmount !== undefined ? this.extraAmount * rate : undefined;
  453. //console.log('Conversion\n', this.currency, '->', currency,
  454. // '\n', Rates[this.currency], '->', Rates[currency],
  455. // '\n', this.amount, '->', convertedAmount);
  456. return new Money(convertedAmount, currency, currency_symbol, convertedExtraAmount);
  457. };
  458. Money.prototype.toString = function () {
  459. if (this.extraAmount === undefined)
  460. return this.currency_symbol+(this.amount.toFixed(2));
  461. else
  462. return this.currency_symbol+(this.amount.toFixed(2)) + ' - ' + this.currency_symbol+(this.extraAmount.toFixed(2));
  463. };
  464.  
  465. var Shop = function (id, title, domain, base_url, currency, currency_symbol, vat, seller) {
  466. this.id = id;
  467. this.title = title;
  468. this.domain = domain;
  469. this.base_url = base_url;
  470. this.url = this.base_url;
  471. this.currency = currency;
  472. this.currency_symbol = currency_symbol;
  473. this.vat = vat;
  474. this.seller = seller;
  475. this.setAsin = function (asin) {
  476. this.url = this.urlFor(asin);
  477. };
  478. this.urlFor = function (asin) {
  479. return this.base_url.replace('{asin}', asin);
  480. };
  481. this.moneyFrom = function (amount) {
  482. var culture = this.culture;
  483. if (amount.indexOf('-') == -1) {
  484. var sanitizedAmount = amount.replace(/[^\d^,^.]/g, '');
  485. var regex = /^[\d.]+,[\d]{2}$/;
  486. var needProperPrice = regex.exec(sanitizedAmount);
  487. if(needProperPrice) {
  488. sanitizedAmount = sanitizedAmount.replace(/\./g, '').replace(/,/, '.');
  489. }else{
  490. sanitizedAmount = sanitizedAmount.replace(/\,/g, '');
  491. }
  492. return new Money(sanitizedAmount, this.currency);
  493. }
  494. var sanitizedAmounts = amount.split('-').map(function (a) {
  495. return a.replace(/[^\d^,^.]/g, '');
  496. });
  497. return new Money(sanitizedAmounts[0], this.currency, sanitizedAmounts[1]);
  498. };
  499. };
  500.  
  501. var Settings = function (asin, domainData, domain) {
  502. this.asin = asin;
  503. this.shops = [
  504. new Shop(1, 'amazon.co.uk', 'www.amazon.co.uk', 'https://www.amazon.co.uk/dp/{asin}?smid=A3P5ROKL5A1OLE'+(domainData.parseLinks?'&tag='+domainData.uk.tag:''), 'GBP', '£', domainData.uk.vat, 'Dispatched from and sold by Amazon|Dispatched and sold by Amazon'),
  505. new Shop(2, 'amazon.de', 'www.amazon.de', 'https://www.amazon.de/dp/{asin}?smid=A3JWKAKR8XB7XF'+(domainData.parseLinks?'&tag='+domainData.de.tag:''), 'EUR', 'EUR ', domainData.de.vat, 'Verkauf und Versand durch Amazon|Versandt und verkauft von Amazon|Dispatched from and sold by Amazon|Dispatched and sold by Amazon'),
  506. new Shop(3, 'amazon.es', 'www.amazon.es', 'https://www.amazon.es/dp/{asin}?smid=A1AT7YVPFBWXBL'+(domainData.parseLinks?'&tag='+domainData.es.tag:''), 'EUR', 'EUR ', domainData.es.vat, 'Vendido y enviado por Amazon'),
  507. new Shop(4, 'amazon.fr', 'www.amazon.fr', 'https://www.amazon.fr/dp/{asin}?smid=A1X6FK5RDHNB96'+(domainData.parseLinks?'&tag='+domainData.fr.tag:''), 'EUR', 'EUR ', domainData.fr.vat, 'Expédié et vendu par Amazon'),
  508. new Shop(5, 'amazon.it', 'www.amazon.it', 'https://www.amazon.it/dp/{asin}?smid=A11IL2PNWYJU7H'+(domainData.parseLinks?'&tag='+domainData.it.tag:''), 'EUR', 'EUR ', domainData.it.vat, 'Venduto e spedito da Amazon'),
  509. new Shop(6, 'amazon.com', 'www.amazon.com', 'https://www.amazon.com/dp/{asin}?smid=ATVPDKIKX0DER'+(domainData.parseLinks?'&tag='+domainData.com.tag:''), 'USD', '$', domainData.com.vat, 'Ships from and sold by Amazon.com'),
  510. new Shop(7, 'amazon.ca', 'www.amazon.ca', 'https://www.amazon.ca/dp/{asin}?smid=ATVPDKIKX0DER'+(domainData.parseLinks?'&tag='+domainData.ca.tag:''), 'CAD', 'CDN$', domainData.ca.vat, 'Ships from and sold by Amazon.ca')
  511. ];
  512. this.shops.forEach(function (shop) {
  513. shop.setAsin(asin);
  514. });
  515.  
  516. this.currentShop = this.shops.filter(function (shop) {
  517. return shop.domain == document.domain;
  518. })[0];
  519.  
  520. this.desiredCurrency = this.currentShop.currency;
  521.  
  522. if (this.currentShop.currency != this.desiredCurrency) {
  523. this.filteredShops = this.shops;
  524. }
  525. else {
  526. this.filteredShops = this.shops.filter(function (shop) {
  527. return shop.domain != document.domain;
  528. });
  529. }
  530. this.shop = function (id) {
  531. var shopById = this.shops.filter(function (shop) {
  532. return shop.id == id;
  533. });
  534. if (shopById.length == 1)
  535. return shopById[0];
  536. return null;
  537. };
  538. };
  539.  
  540. var pageScraper = {
  541. warning: {
  542. networkError: 'Error al consultar',
  543. unavailable: 'No disponible',
  544. wrongSeller: 'No vendido por Amazon',
  545. notFound: 'No encontrado',
  546. multipleOptions: 'Opciones multiples'
  547. },
  548. getPriceOn: function (shop, displayPrice, displayWarning) {
  549. var serverUrl = shop.url;
  550. var sellerText = shop.seller;
  551. GM_xmlhttpRequest({
  552. method: "GET",
  553. url: serverUrl,
  554. onload: function(data) {
  555. var regex = /[nb]\s*?id="priceblock_[\w]*?price".*?>(.*?)</img;
  556. var price = regex.exec(data.responseText);
  557. if (price === null || price.length != 2) {
  558. displayWarning(pageScraper.warning.unavailable, false);
  559. return;
  560. }
  561. regex = new RegExp(sellerText);
  562. var seller = regex.exec(data.responseText);
  563. if (seller === null) {
  564. displayWarning(pageScraper.warning.wrongSeller, false);
  565. return;
  566. }
  567. displayPrice(price[1]);
  568. },
  569. onerror: function(data) {
  570. if (data.status == 404)
  571. displayWarning(pageScraper.warning.notFound, true);
  572. else
  573. displayWarning(pageScraper.warnings.networkError, false);
  574. }
  575. });
  576. }
  577. };
  578.  
  579. var tooltip = {
  580. _mouseIsOnIcon: false,
  581. _mouseIsOnTooltip: false,
  582. registerShowHideHandlers: function () {
  583. this._genericRegisterShowHideHandlers($('.snoop-tooltip'), function (on) {
  584. tooltip._mouseIsOnTooltip = on;
  585. });
  586. this._genericRegisterShowHideHandlers($('#snoop-icon'), function (on) {
  587. tooltip._mouseIsOnIcon = on;
  588. });
  589. },
  590. _genericRegisterShowHideHandlers: function ($selector, isOn) {
  591. $selector.mouseenter(function () {
  592. $('.snoop-tooltip').show();
  593. isOn(true);
  594. }).mouseleave(function () {
  595. isOn(false);
  596. setTimeout(function () {
  597. if (!tooltip._mouseIsOnIcon && !tooltip._mouseIsOnTooltip)
  598. $('.snoop-tooltip').hide();
  599. }, 100);
  600. });
  601. }
  602. };
  603. var tooltipML = {
  604. _mouseIsOnIcon: false,
  605. _mouseIsOnTooltip: false,
  606. registerShowHideHandlers: function () {
  607. this._genericRegisterShowHideHandlers($('.snoop-tooltip-ml'), function (on) {
  608. tooltipML._mouseIsOnTooltip = on;
  609. });
  610. this._genericRegisterShowHideHandlers($('#snoop-icon-ml'), function (on) {
  611. tooltipML._mouseIsOnIcon = on;
  612. });
  613. },
  614. _genericRegisterShowHideHandlers: function ($selector, isOn) {
  615. $selector.mouseenter(function () {
  616. $('.snoop-tooltip-ml').show();
  617. isOn(true);
  618. }).mouseleave(function () {
  619. isOn(false);
  620. setTimeout(function () {
  621. if (!tooltipML._mouseIsOnIcon && !tooltipML._mouseIsOnTooltip)
  622. $('.snoop-tooltip-ml').hide();
  623. }, 100);
  624. });
  625. }
  626. };
  627. var tooltipSettings = {
  628. _mouseIsOnIcon: false,
  629. _mouseIsOnTooltip: false,
  630. registerShowHideHandlers: function () {
  631. this._hookSettings();
  632. this._genericRegisterShowHideHandlers($('.snoop-tooltip-settings'), function (on) {
  633. tooltipSettings._mouseIsOnTooltip = on;
  634. });
  635. this._genericRegisterShowHideHandlers($('#pesos-config'), function (on) {
  636. tooltipSettings._mouseIsOnIcon = on;
  637. });
  638. },
  639. _genericRegisterShowHideHandlers: function ($selector, isOn) {
  640. $selector.mouseenter(function () {
  641. $('.snoop-tooltip-settings').show();
  642. isOn(true);
  643. }).mouseleave(function () {
  644. isOn(false);
  645. setTimeout(function () {
  646. if (!tooltipSettings._mouseIsOnIcon && !tooltipSettings._mouseIsOnTooltip)
  647. $('.snoop-tooltip-settings').hide();
  648. }, 100);
  649. });
  650. },
  651. _hookSettings: function(){
  652. var showVAT = GM_getValue('show_vat', true);
  653. var parseLinks = GM_getValue('parseLinks', true);
  654. $('#pesos-config-vat').prop('checked', showVAT);
  655. $('#pesos-config-parse').prop('checked', !parseLinks);
  656. $('#pesos-config-vat').change(function(){
  657. GM_setValue('show_vat', $('#pesos-config-vat').is(':checked'));
  658. location.reload();
  659. });
  660. $('#pesos-config-parse').change(function(){
  661. GM_setValue('parseLinks', !$('#pesos-config-parse').is(':checked'));
  662. location.reload();
  663. });
  664. }
  665. };
  666.  
  667. var tooltipTemplate = '<div class="ap_popover ap_popover_sprited snoop-tooltip" surround="6,16,18,16" tabindex="0" style="z-index: 200; width: 375px;"><div class="ap_header"><div class="ap_left"></div>'+
  668. '<div class="ap_middle"></div><div class="ap_right"></div></div><div class="ap_body"><div class="ap_left"></div><div class="ap_content" style="padding-left: 17px; padding-right: 17px; padding-bottom: 8px; ">'+
  669. '<div class="tmm_popover" >{{#shops}}<div class="entry title" style=""><span id="snoop-shop-{{id}}" class="entry snoop-price"><img class="snoop-loader" src="{{loader_url}}" /></span>'+
  670. '<span class="snoop-on"> en </span><a href="{{base_url}}&snoop-from={{from_shop}}&snoop-from-asin={asin}" class="snoop-link">{{title}}</a></div>{{/shops}}</div></div><div class="ap_right"></div></div>'+
  671. '<div class="ap_footer"><div class="ap_left"></div><div class="ap_middle"></div><div class="ap_right"></div></div></div>';
  672.  
  673. var page = {
  674. addTooltipToPage: function (tooltipMarkup) {
  675. var $placeholderMarkup = $('<img id="snoop-placeholder" src="https://i.imgur.com/7vqGfyT.png" alt="Placeholder" />');
  676. var $imageMarkup = $('<img id="snoop-icon" src="https://i.imgur.com/lTWMEoH.png" />');
  677. var $imageMarkupMELI = $('<img id="snoop-icon-ml" src="https://i.imgur.com/mxQjoLn.png" />');
  678. var $container = this.findAppropriateTooltipContainer();
  679. var $settings = '<a href="javascript:void(0)" id="pesos-config" class="nav-a nav-a-2 nav-truncate"><span class="nav-line-1">Configurar Script</span><span class="nav-line-2"><img src="https://i.imgur.com/qa5ZXdT.png" width="95"></span></a>';
  680. var $containerHeader = $('#nav-tools');
  681. var tooltipTemplateML = '<div class="ap_popover ap_popover_sprited snoop-tooltip-ml" surround="6,16,18,16" tabindex="0" style="z-index: 200; width: 700px;"><div class="ap_header"><div class="ap_left"></div>'+
  682. '<div class="ap_middle"></div><div class="ap_right"></div></div><div class="ap_body"><div class="ap_left"></div><div class="ap_content" style="padding-left: 17px; padding-right: 17px; padding-bottom: 8px; ">'+
  683. '<div class="tmm_popover"><img class="snoop-loader" src="https://i.imgur.com/Dp92MjH.gif" /> Cargando...</div></div><div class="ap_right"></div></div><div class="ap_footer"><div class="ap_left"></div><div class="ap_middle"></div><div class="ap_right"></div></div></div>';
  684. var tooltipTemplateSettings = '<div class="ap_popover ap_popover_sprited snoop-tooltip-settings" surround="6,16,18,16" tabindex="0" style="z-index: 200; width: 350px; margin-top: 50px; display: none"><div class="ap_header"><div class="ap_left"></div>'+
  685. '<div class="ap_middle"></div><div class="ap_right"></div></div><div class="ap_body"><div class="ap_left"></div><div class="ap_content" style="padding-left: 17px; padding-right: 17px; padding-bottom: 8px; ">'+
  686. '<div class="tmm_popover">'+
  687. '<div class="a-checkbox"><label for="pesos-config-vat"><input type="checkbox" id="pesos-config-vat" style="vertical-align: 0%;"><span class="a-label a-checkbox-label">Restar VAT de los precios automáticamente<span></label></div><br>'+
  688. '<div class="a-checkbox"><label for="pesos-config-parse"><input type="checkbox" id="pesos-config-parse" style="vertical-align: 0%;"><span class="a-label a-checkbox-label">Deshabilitar referidos del script<span></label></div>'+
  689. '</div></div><div class="ap_right"></div></div><div class="ap_footer"><div class="ap_left"></div><div class="ap_middle"></div><div class="ap_right"></div></div></div>';
  690. if( $('#merchant-info').text().trim().replace(/\s\s+/g, ' ').match(new RegExp(settings.currentShop.seller, 'i')) === null && $('#olp_feature_div').length > 0 ){
  691. var merchant_expected = settings.currentShop.base_url.match(/smid=([A-Z0-9]+)/);
  692. var merchant_current = window.location.href.match(/smid=([A-Z0-9]+)/);
  693. if(merchant_expected && merchant_current && merchant_expected[1] == merchant_current[1]){
  694. $container.after(' &nbsp; <span class="a-color-error"><b>[Este producto no lo vende Amazon]</b></span> &nbsp; ');
  695. }else{
  696. $container.after(' &nbsp; <a href="'+settings.currentShop.base_url.replace('{asin}', $('#ASIN').val())+'"><b>[Cambiar al vendido por Amazon]</b></a> &nbsp; ');
  697. }
  698. }else{
  699. $('#ddmDeliveryMessage .a-color-error').css('text-decoration','line-through');
  700. }
  701. $container.after($imageMarkupMELI);
  702. $container.after(tooltipTemplateML);
  703. $container.after($imageMarkup);
  704. $container.after(tooltipMarkup);
  705. if($('#pesos-config').length === 0){
  706. $containerHeader.prepend($settings);
  707. $containerHeader.prepend(tooltipTemplateSettings);
  708. tooltipSettings.registerShowHideHandlers();
  709. }
  710. tooltip.registerShowHideHandlers();
  711. tooltipML.registerShowHideHandlers();
  712. convertCurrency();
  713. },
  714. findAppropriateTooltipContainer: function () {
  715. var $tries = [
  716. $('table.product .priceLarge:first', $('#priceBlock')),
  717. $('#priceblock_ourprice'),
  718. $('#priceblock_saleprice'),
  719. $('#priceblock_dealprice'),
  720. $('#availability_feature_div > #availability > .a-color-price'),
  721. $('div.buying span.availGreen', $('#handleBuy')),
  722. $('div.buying span.availRed:nth-child(2)', $('#handleBuy'))
  723. ];
  724. for (var i = 0; i < $tries.length; i++) {
  725. if ($tries[i].length > 0)
  726. return $tries[i];
  727. }
  728. throw new Error('Unable to find the price section.');
  729. },
  730. displayPrice: function ($shopInfo, price, vat) {
  731. var convertedPrice = price.for(settings.currentShop.currency, settings.currentShop.currency_symbol);
  732. $shopInfo.text(convertedPrice.toString());
  733. convertCurrency(0, vat);
  734. },
  735. displayWarning: function ($shopInfo, warning, addNotFoundClass) {
  736. $shopInfo.text(warning).addClass('snoop-warning');
  737. if (addNotFoundClass)
  738. $shopInfo.parent().addClass('snoop-not-found');
  739. },
  740. registerInitializationHandler: function (shops) {
  741. $('#snoop-icon').mouseover(function () {
  742. if (window.snoop_tooltipInitialized !== undefined && window.snoop_tooltipInitialized !== false)
  743. return;
  744. window.snoop_tooltipInitialized = true;
  745. $.each(shops, function (index, shop) {
  746. var $shopInfo = $('#snoop-shop-' + shop.id);
  747. pageScraper.getPriceOn(shop, function (price) {
  748. page.displayPrice($shopInfo, shop.moneyFrom(price), shop.vat);
  749. }, function (warning, addNotFoundClass) {
  750. page.displayWarning($shopInfo, warning, addNotFoundClass);
  751. });
  752. });
  753. });
  754. $('#snoop-icon-ml').mouseover(function () {
  755. if (window.snoopML_tooltipInitialized !== undefined && window.snoopML_tooltipInitialized !== false)
  756. return;
  757. window.snoopML_tooltipInitialized = true;
  758. var productName = decodeURI(jQuery('#productTitle').html().replace('&nbsp;', ' ').replace(/[^\w\d\s\.]/g, ' ').trim());
  759. meli.showPrices(productName);
  760. });
  761. }
  762. };
  763.  
  764. var settings;
  765. var snoop = {
  766. tooltip: null,
  767. asin: null,
  768. _startMonitoringAsin: function (domainData, domain) {
  769. var observer = new MutationObserver(function (mutations) {
  770. var asinHasProbablyChanged = mutations.some(function (mutation) {
  771. return mutation.addedNodes.length > 0;
  772. });
  773. if (!asinHasProbablyChanged)
  774. return;
  775. var newAsin = $('#ASIN').val();
  776. if (snoop.asin == newAsin)
  777. return;
  778. snoop.run(newAsin, domainData, domain);
  779. });
  780. if($('#buybox_feature_div').get(0)){
  781. observer.observe($('#buybox_feature_div').get(0), { attributes: true, subtree: true, childList: true, characterData: true });
  782. }
  783. },
  784. initialize: function (asin, domainData, domain) {
  785. this.asin = asin;
  786. this._startMonitoringAsin(domainData, domain);
  787. settings = new Settings(asin, domainData, domain);
  788. snoop.tooltip = Mustache.to_html(tooltipTemplate, {
  789. shops: settings.filteredShops,
  790. from_shop: settings.currentShop.id,
  791. from_asin: settings.asin,
  792. loader_url: 'https://i.imgur.com/Dp92MjH.gif'
  793. });
  794. snoop.run(asin, domainData, domain);
  795. },
  796. run: function (asin, domainData, domain) {
  797. this.asin = asin;
  798. settings = new Settings(asin, domainData, domain);
  799. window.snoop_tooltipInitialized = false;
  800. window.snoopML_tooltipInitialized = false;
  801. var ensureTooltipHasBeenLoaded = function () {
  802. if (snoop.tooltip === null) {
  803. setTimeout(ensureTooltipHasBeenLoaded, 50);
  804. }
  805. else {
  806. var tooltipMarkup = snoop.tooltip.replace(/{asin}/gm, settings.asin);
  807. page.addTooltipToPage(tooltipMarkup);
  808. page.registerInitializationHandler(settings.filteredShops);
  809. }
  810. };
  811. ensureTooltipHasBeenLoaded();
  812. }
  813. };
  814.  
  815. Number.prototype.formatMoney = function(c, d, t){
  816. var n = this;
  817. c = isNaN(c = Math.abs(c)) ? 2 : c;
  818. d = d === undefined ? "." : d;
  819. t = t === undefined ? "," : t;
  820. var s = n < 0 ? "-" : "",
  821. i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
  822. j = (j = i.length) > 3 ? j % 3 : 0;
  823. return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
  824. };
  825.  
  826. var meli = {
  827. showPrices: function(productName) {
  828. meli.fetchApiData(productName, meli.showProducts);
  829. },
  830. showProducts: function (data){
  831. var meliProducts = $('.snoop-tooltip-ml .tmm_popover');
  832. meliProducts.html('<div class="entry title" style="font-size:10px"><b>Buscando por:</b> '+data.query+'</div>');
  833. //console.log(data);
  834. if(data.results.length === 0){
  835. meliProducts.append('<div class="entry title">No se encontraron productos en MercadoLibre con esta búsqueda.</div>');
  836. }
  837. data.results.forEach(function(product) {
  838. meliProducts.append('<div class="entry title"><div class="snoop-price" style="width:130px;display:inline-block;text-align:right;"><div class="price-ars">ARS $'+product.price.formatMoney(2)+'</div></div><span class="snoop-on"> &raquo; </span><a href="'+product.permalink+'" target="_blank" class="snoop-link">'+product.title+'</a></div>');
  839. });
  840. },
  841. fetchApiData: function (productName, callback) {
  842. GM_xmlhttpRequest({
  843. method: "GET",
  844. url: "https://api.mercadolibre.com/sites/MLA/search?q=" + encodeURI(productName) + "&condition=new",
  845. onload: function(responseDetails) {
  846. var api = JSON.parse(responseDetails.responseText);
  847. callback(api);
  848. },
  849. onerror: function(responseDetails) {
  850. alert("Error fetching API from MELI");
  851. }
  852. });
  853. }
  854. };

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址