e-dostavka/e-dostavka.user.js
2019-07-20 10:21:20 +03:00

79 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==UserScript==
// @name [e-dostavka.by, gipermall.by] price comparison
// @namespace http://tampermonkey.net/
// @version 2.0
// @description Show prices per kilo, compare between sites
// @author fulloftsars
// @match https://e-dostavka.by/*
// @match https://gipermall.by/*
// @grant unsafeWindow
// @grant GM.xmlHttpRequest
// @require https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js
// @require https://unpkg.com/ohm-js@0.14.0/dist/ohm.min.js
// ==/UserScript==
(function () {
'use strict';
const price = (() => {
const float = n => parseFloat(n.sourceString)
const priceG = ohm.grammar(`Price { Price = digit+ "р." digit+ "к." Price? }`)
const priceS = priceG.createSemantics().addOperation('val', {
Price: (rub, _2, kop, _4, _5) => float(rub) * 100 + float(kop),
})
const weightG = ohm.grammar(`Weight {
Exp = BS* AnyWeight BS* AnyWeight? BS*
AnyWeight = MulWeight | Weight
Weight = float (OneUnit | ThUnit)
OneUnit = Dot<"г"> | Dot<"мл"> | Dot<"шт"> | Dot<"см">
ThUnit = Dot<"кг"> | Dot<"л"> | Dot<"м">
Dot<R> = R "."*
MulWeight = float ("x" | "х" | "*") Weight
BS = ~AnyWeight any
float = (digit digit* "." digit) -- fl
| digit+
}`)
const weightS = weightG.createSemantics().addOperation('val', {
Exp: (_, weight, __, ___, _____) => weight.val(),
Weight: (n, u) => float(n) * u.val(),
OneUnit: _ => 1, ThUnit: _ => 1000,
MulWeight: (d, _, w) => float(d) * w.val(),
})
const interpret = (g, s) => (text) => s(g.match(text))
return (price, weight) => (interpret(priceG, priceS)(price).val() / interpret(weightG, weightS)(weight).val() / 100 * 1000)
})()
const $ = unsafeWindow.jQuery; // somehow, when @including jquery, infinite scroll stops working.
const template = $("<a/>").css({
'background-color': '#fbba00',
'color': 'black', // default is #cb4f2b
'padding': '2px',
'border-radius': '5px',
'font-size': '14px',
'font-family': 'MyriadProCondencedBoldItalic',
'position': 'absolute',
'right': '5px'
}).attr('target', '_blank')
$(document).arrive(".products_card", { existing: true }, div => {
const normalizedPrice = price(
$(div).find('div > form > div.prices__wrapper > div > div.prices_block > div > div.price').text(),
$(div).find('a.fancy_ajax').text()
)
const button = template.clone()
const url = (R.test(/e-dostavka/, location.host) ? R.identity : R.flip)(R.replace)('e-dostavka', 'gipermall', $(div).find('a.fancy_ajax').attr('href'))
$(div).find('a.fa').replaceWith(button)
button.text(normalizedPrice.toFixed(2))
GM.xmlHttpRequest({
method: 'GET', url, onload: page => {
try {
const html = $($.parseHTML(page.responseText))
const competingPrice = price(
html.find('div.services_wrap:nth-child(3) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1)').text(),
html.find('.template_1_columns > h1:nth-child(2)').text()
)
const difference = Math.abs(1 - competingPrice / normalizedPrice) * 100
button.text((i, _) => `${_} (${competingPrice >= normalizedPrice ? '>' : '<'}${difference.toFixed(0)}%)`).prop('href', url)
} catch (e) { }
}
});
});
})();