Aliexpress Plus Fixed and more...

View Search Results by list automatically & Sorts search results by item price properly with shipping costs included, Lets you search your wishlish, Shows related wishlist items in search and item pages, Adds search default options.

질문, 리뷰하거나, 이 스크립트를 신고하세요.
// ==UserScript==
// @name        Aliexpress Plus Fixed and more...
// @namespace   Mikhoul
// @description View Search Results by list automatically & Sorts search results by item price properly with shipping costs included, Lets you search your wishlish, Shows related wishlist items in search and item pages, Adds search default options.
// @include     http*://*aliexpress.com/wishlist*
// @include     http*://*alibaba.com/wishlist*
// @include     http*://*aliexpress.com/*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require     https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js?version=115012
// @require     https://greasyfork.org/scripts/6217-gm-config/code/GM_config.js?version=23537
// @version     1.7.2
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_log
// @grant       GM_registerMenuCommand
// @grant       GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

waitForKeyElements ("#view-list", triggerMostButtons);   /* Choose List View */

function triggerMostButtons (jNode) {
    triggerMouseEvent (jNode[0], "mouseover");
    triggerMouseEvent (jNode[0], "mousedown");
    triggerMouseEvent (jNode[0], "mouseup");
    triggerMouseEvent (jNode[0], "click");
}


function triggerMouseEvent (node, eventType) {
    var clickEvent = document.createEvent('MouseEvents');
    clickEvent.initEvent (eventType, true, true);
    node.dispatchEvent (clickEvent);
}


if (window.top != window.self)
	return;
var orders = new Array();
var cstoken = '';
var doneLoading = 0;
var currentPage = 1;
var ListingRanks = new Array();
var ListingsRows = [];
var price = /\$([\d\,]*.\d\d)/;
var searchel = document.getElementById('form-search') || document.getElementById('form-searchbar');
var uls;
var args = {
	SortType : ["price_asc", "price_dsc"],
	groupsort : ["0", "1"],
	CatId : ["0"],
	ltype : ["wholesale"],
	isUnitPrice : ["y", "n"],
	minQuantity : ["", "0", "1", "2", "5", "10", "20", "50", "100", "200"],
	maxQuantity : ["", "0", "1", "2", "5", "10", "20", "50", "100", "200"],
	isFreeShip : ["", "y", "n"]
};
var frame = document.createElement('div');
document.body.appendChild(frame);
var fields = {
	'Mode' : {
		'label' : 'Wishlist Search Mode',
		'type' : 'select',
		'options' : ['Relative', 'Contains Text', 'Exact'],
		'default' : 'Contains Text'
	}
};
if (searchel) {
	getsrcvars();
}

GM_config.init({
	'id' : 'GM_config',
	'fields' : fields,
	'frame' : frame
});

if (searchel) {
	for (key in args) {
		//if(document.getElementsByName(key)[0] != undefined){
		//	document.getElementsByName(key)[0].value = GM_config.get(key);
		//}
		//else{
		var extras = document.createElement('input');
		extras.type = 'hidden';
		extras.name = key;
		extras.value = GM_config.get(key);
		searchel.appendChild(extras);
		//}
	}
	try {
		uls = document.getElementById('list-items') || document.getElementById('hs-below-list-items') || document.getElementById('hs-list-items');
	} catch (e) {}
	FindAllRows();
}

GM_registerMenuCommand('Aliexpress Plus Options', opengmcf);

function getsrcvars() {
	for (key in args) {
		fields[key] = {
			'label' : key,
			'type' : 'select',
			'options' : args[key],
			'default' : args[key][0]
		};
	}
}

function opengmcf() {
	GM_config.open();
}

function grabOrders(doc) {
	var tags = doc.getElementsByTagName('tbody')[0].getElementsByTagName('tr');
	for (var i = 0; i < tags.length; i++) {
		var oblink;
		var obprice;
		var ob;
		try {
			ob = tags[i].getElementsByClassName('main-info-hd')[0].getElementsByTagName('a')[0];
			oblink = ob.href;
			obprice = tags[i].getElementsByClassName('price price-m')[0].getElementsByClassName('value')[0].textContent.replace(/\s+/g, "").replace("$", "");
			//obprice = obprice.substring(obprice.indexOf('$') + 1);
			//obprice = obprice.substring(0, obprice.indexOf('/') - 1);
			obtitle = ob.innerHTML;
		} catch (e) {}
		if (oblink) {
			orders.push({
				title : obtitle,
				price : obprice,
				href : oblink,
				el : escape(tags[i].innerHTML.toString().replace("img-src", "src").replace("image-src", "src").replace(/<null[^>]/g, "<img "))
			});
		}
	}

	tags = doc.getElementsByTagName('input');
	for (var i = 0; i < tags.length; i++) {
		if (tags[i].name.startsWith('_csrf_token')) {
			cstoken = tags[i].value;
			break;
		}
	}
}

function loadAPage() {
	var parameters = "_csrf_token=" + cstoken + "&page=" + currentPage;
	page_request.open('POST', 'wish_list_product_list.htm?rand=' + Math.random(), true);
	page_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

	page_request.send(parameters);
}

(function () {
	var default_floor = 0.5;

	function pairs(str) {
		var pairs = [],
		length = str.length - 1,
		pair;
		for (var i = 0; i < length; i++) {
			pair = str.substr(i, 2);
			if (!/\s/.test(pair)) {
				pairs.push(pair);
			}
		}
		return pairs;
	}

	function similarity(pairs1, pairs2) {
		var union = pairs1.length + pairs2.length,
		hits = 0;

		for (var i = 0; i < pairs1.length; i++) {
			for (var j = 0; j < pairs1.length; j++) {
				if (pairs1[i] == pairs2[j]) {
					pairs2.splice(j--, 1);
					hits++;
					break;
				}
			}
		}
		return 2 * hits / union || 0;
	}

	String.prototype.fuzzy = function (strings, floor) {
		var str1 = this,
		pairs1 = pairs(this);

		floor = typeof floor == 'number' ? floor : default_floor;

		if (typeof(strings) == 'string') {
			return str1.length > 1 && strings.length > 1 && similarity(pairs1, pairs(strings)) >= floor || str1 == strings;
		} else if (strings instanceof Array) {
			var scores = {};

			strings.map(function (str2) {
				scores[str2] = str1.length > 1 ? similarity(pairs1, pairs(str2)) : 1 * (str1 == str2);
			});

			return strings.filter(function (str) {
				return scores[str] >= floor;
			}).sort(function (a, b) {
				return scores[b] - scores[a];
			});
		}
	};
})();

function lookup(arr) {
	var newarr = [];
	for (var i = 0; i < arr.length; i++) {
		newarr.push(arr[i].title);
	}
	return newarr;
}

function searchfunc(q, similarity) {
	var qval = q.fuzzy(ulist, similarity);
	if (qval.length > 0) {
		return qval;
	} else {
		return false;
	}
}

function searchin(q) {
	var qval = [];
	for (var i = 0; i < ulist.length; i++) {
		if (ulist[i].indexOf(q) != -1) {
			qval.push(i);
		}
	}
	if (qval.length > 0) {
		return qval;
	} else {
		return false;
	}
}

function search(mode = '', rel = 0.7) {
	var q = document.getElementById('q').value.toLowerCase();
	if (mode == '') {
		mode = GM_config.get('Mode');
	}
	if (!window.orders) {
		//window.orders = wishdata;
		window.orders = JSON.parse(document.getElementById('qh').value);
		document.getElementById('qh').value = "";
	}
	if (!window.ulist) {
		//window.ulist = lookup(orders);
		window.ulist = JSON.parse(document.getElementById('qh2').value);
		document.getElementById('qh2').value = "";
	}
	if (mode == 'Exact') {
		var sq = window.ulist[q];
		if (window.ulist.indexOf(sq) != -1) {
			document.getElementById('wishlist-tbody').innerHTML = "";
			document.getElementById('wishlist-tbody').innerHTML = document.getElementById('wishlist-tbody').innerHTML + unescape(window.orders[sq].el);
		} else {
			document.getElementById('wishlist-tbody').innerHTML = "No results found.";
		}
	} else if (mode == 'Contains Text') {
		var sq = searchin(q);
		if (sq) {
			document.getElementById('wishlist-tbody').innerHTML = "";
			for (var i = 0; i < window.ulist.length; i++) {
				if (window.ulist[i].indexOf(q) != -1) {
					document.getElementById('wishlist-tbody').innerHTML = document.getElementById('wishlist-tbody').innerHTML + unescape(window.orders[i].el);
				}
			}
		} else {
			document.getElementById('wishlist-tbody').innerHTML = "No results found.";
		}
	} else if (mode == 'Relative') {
		var sq = searchfunc(q, rel);
		if (sq) {
			document.getElementById('wishlist-tbody').innerHTML = "";
			for (var i = 0; i < sq.length; i++) {
				document.getElementById('wishlist-tbody').innerHTML = document.getElementById('wishlist-tbody').innerHTML + unescape(window.orders[window.ulist.indexOf(sq[i])].el);
			}
		} else {
			document.getElementById('wishlist-tbody').innerHTML = "No results found.";
		}
	}
}

function loadsearch() {
	document.getElementById('qt').innerHTML = 'Loading search data.. please wait...';
	document.getElementById('qh').value = GM_getValue('wishdata');
	document.getElementById('qh2').value = GM_getValue('titledata');
	document.getElementById('qb').removeAttribute("disabled");
	document.getElementById('q').removeAttribute("disabled");
	document.getElementById('qb').addEventListener("click", function () {
		search()
	}, false);
	document.getElementById('qt').innerHTML = 'Search Wishlist: ';
}

function finalProcessing() {
	document.getElementById('qt').innerHTML = 'Saving wishlist data.. please wait.';
	for (var i = 0; i < orders.length; ++i) {
		orders.sort(function (a, b) {
			return a.price - b.price;
		});
	}
	GM_setValue('wishdata', JSON.stringify(orders));
	document.getElementById('qt').innerHTML = 'Saved wishlist data.';
	GM_setValue('titledata', JSON.stringify(lookup(orders)).toLowerCase());
	document.getElementById('qt').innerHTML = 'Saved wishlist title data.';
	loadsearch();
}

function FindAllRows() {
	var allElements = document.getElementsByTagName('li');
	for (var i = 0; i < allElements.length; ++i) {
		if (allElements[i].className.indexOf('list-item') != -1) {
			ListingsRows.push(allElements[i]);
		}
	}

	total = ListingsRows.length;
	if (ListingsRows.length > 0) {
		for (var i = 0; i < ListingsRows.length; ++i) {
			WorkOnRow(ListingsRows[i]);
		}
		SortRows(0);
		SortRows(1);
		var sortdiv = document.createElement('div');
		sortdiv.className = 'narrow-down-bg';
		var sortspan = document.createElement('div');
		sortspan.className = 'narrow-down-bg';
		var sortspan2 = document.createElement('div');
		sortspan2.className = 'narrow-down-bg';
		var sortspan3 = document.createElement('div');
		sortspan3.className = 'narrow-down-bg';
		var sortspan4 = document.createElement('div');
		sortspan4.className = 'narrow-down-bg';
		var sortchange = document.createElement('a');
		sortchange.id = 'sortchange';
		sortchange.innerHTML = "Unit Price";
		sortchange.addEventListener("click", function () {SortRows(1, this)}, false);
		var sortchange2 = document.createElement('a');
		sortchange2.id = 'sortchange2';
		sortchange2.innerHTML = "Price";
		sortchange2.addEventListener("click", function () {SortRows(0, this)}, false);
		var sortchange3 = document.createElement('a');
		sortchange3.id = 'sortchange3';
		sortchange3.innerHTML = "Total Price";
		sortchange3.addEventListener("click", function () {SortRows(2, this)}, false);
		var sortchange4l = document.createElement('label');
		sortchange4l.innerHTML = 'Max Price: ';
		var sortchange4t = document.createElement('input');
		sortchange4t.id = 'sortchange4t';
		sortspan2.appendChild(sortchange2);
		sortspan.appendChild(sortchange);
		sortspan3.appendChild(sortchange3);
		sortspan4.appendChild(sortchange4l);
		sortspan4.appendChild(sortchange4t);
		sortdiv.appendChild(sortspan2);
		sortdiv.appendChild(sortspan);
		sortdiv.appendChild(sortspan3);
		sortdiv.appendChild(sortspan4);
		uls.appendChild(document.createElement('br'));
		uls.appendChild(document.createElement('br'));
		document.getElementById('view-filter').appendChild(sortdiv);
		document.getElementById('sortchange').setAttribute('style', 'font-weight: bold');
	}
}

function SortRows(SortMode, elem = null) {
	if(arguments.length > 1){
		var butar = ['sortchange','sortchange2','sortchange3'];
		for (var i = 0; i < butar.length; i++) {
			document.getElementById(butar[i]).setAttribute('style', 'font-weight: none');
		}
		elem.setAttribute('style', 'font-weight: bold');
	}
	uls.innerHTML = "";
	setTimeout(function(){insertItems(SortMode)}, 100);
}

function updatecheapest(elchange){
		var uns = ListingRanks[0].units;
		if(uns == 0){
			uns = 1;
		}
		var prcs = (ListingRanks[0].price * uns).toFixed(2);
		elchange.innerHTML = 'Cheapest Unit Price ($' + prcs + ' for ' + uns + ')';
}

function insertItems(SortMode) {
	if(SortMode == 0){
		ListingRanks.sort(function (a, b) {
			return a.price - b.price;
		});
		updatecheapest(document.getElementById('sortchange'));
		ListingRanks.sort(function (a, b) {
			return a.units - b.units;
		});
		updatecheapest(document.getElementById('sortchange2'));
	}
	else if(SortMode == 1){
		ListingRanks.sort(function (a, b) {
			return a.units - b.units;
		});
		ListingRanks.sort(function (a, b) {
			return a.price - b.price;
		});
	}
	else if(SortMode == 2){
		ListingRanks.sort(function (a, b) {
			return a.units - b.units;
		});
		ListingRanks.sort(function (a, b) {
			return a.totalprice - b.totalprice;
		});
	}
	var maxprice = document.getElementById('sortchange4t').value;
	if(maxprice != ""){
		for (var nj = 0; nj < ListingRanks.length; nj++) {
			if(ListingRanks[nj].totalprice < parseFloat(maxprice)){
				uls.appendChild(ListingRanks[nj].el);
			}
		}
	}
	else{
		for (var nj = 0; nj < ListingRanks.length; nj++) {
			uls.appendChild(ListingRanks[nj].el);
		}
	}
}

function WorkOnRow(RowElement) {
	var buyItNowPrice = -1;
	var buyItNowPriceB = -1;
	var shippingPrice = -1;
	var buyItNow;
	var buyItNowB;
	var shipping;
	var unitPrice = 0;
	var shiptext;
	var shipsep;
	var allElements = RowElement.getElementsByTagName('div');

	for (var i = 0; i < allElements.length; ++i) {
		if (allElements[i].className.indexOf("infoprice") != -1) {
			if (allElements[i].innerHTML.indexOf('class="original-price') != -1) {
				allElements[i].removeChild(allElements[i].getElementsByClassName('original-price')[0]);
			}
			var spans = allElements[i].getElementsByTagName('span');
			if (spans.length > 0) {
				for (var j = 0; j < spans.length; ++j) {
					if (spans[j].className.indexOf('lot-price') != -1) {
						buyItNowB = spans[j].getElementsByClassName('value')[0];
						if (spans[j].getElementsByClassName('unit').length > 0) {
							unitPrice = spans[j].getElementsByClassName('unit')[0].textContent;
							unitPrice = unitPrice.substring(unitPrice.indexOf('(') + 1);
							unitPrice = unitPrice.substring(0, unitPrice.indexOf(' '));
							unitPrice = parseFloat(unitPrice);
							var tc = buyItNowB.textContent;
							buyItNowPriceB = tc.match(price)[1].replace(',', '');
						}
					} else if (spans[j].className.indexOf('price-m') != -1) {
						buyItNow = spans[j].getElementsByClassName('value')[0];
						var tc = buyItNow.textContent;
						buyItNowPrice = tc.match(price)[1].replace(',', '');
					}
				}
			}
			if (allElements[i].innerHTML.indexOf('strong class="free-s') == -1) {
				var dl = allElements[i].getElementsByTagName('dl');
				for (var k = 0; k < dl.length; ++k) {
					if (dl[k].className.indexOf("pnl-shipping") != -1) {
						var tc = dl[k].getElementsByClassName('value')[0].textContent;
						shiptext = dl[k].getElementsByTagName('dt')[0];
						shipsep = dl[k].getElementsByClassName('separator')[0];
						shipping = dl[k].getElementsByClassName('value')[0];
						if (price.test(tc)) {
							shippingPrice = tc.match(price)[1].replace(',', '');
							if (unitPrice != 0) {
								shippingPrice = shippingPrice * unitPrice;
							}
						}
					}
				}
			} else {
				shipping = allElements[i].getElementsByTagName('strong')[0];
				shippingPrice = 0;
			}

			var buyItNowTotal;
			if (buyItNowPrice != -1 && shippingPrice != -1) {
				buyItNowTotal = (parseFloat(buyItNowPrice) + parseFloat(shippingPrice));
				if (unitPrice != 0 && buyItNowPriceB != -1) {
					buyItNowTotal = (buyItNowTotal + parseFloat(buyItNowPriceB)) - buyItNowPrice;
				}
				buyItNowTotal = buyItNowTotal.toFixed(2);
				if (buyItNowB) {
					buyItNow.innerHTML = buyItNowB.innerHTML.substring(0, buyItNowB.innerHTML.indexOf('$') + 1) + buyItNowTotal;
					buyItNow.parentNode.getElementsByClassName('unit')[0].innerHTML = buyItNowB.parentNode.getElementsByClassName('unit')[0].innerHTML;
					buyItNowB.parentNode.parentNode.removeChild(buyItNowB.parentNode);
				} else {
					buyItNow.innerHTML = buyItNow.innerHTML.substring(0, buyItNow.innerHTML.indexOf('$') + 1) + buyItNowTotal;
				}
				if (shipsep) {
					shipsep.innerHTML = 'shipping / ';
				}
				var indivTotal;
				if (shippingPrice == 0) {
					if(unitPrice > 1){
						indivTotal = (parseFloat(parseFloat(buyItNowPriceB) / unitPrice) + parseFloat(shippingPrice)).toFixed(2);
					}
					else{
						indivTotal = buyItNowTotal;
					}
					shipping.innerHTML = '$' + indivTotal + ' each + FREE SHIPPING';
				} else {
					if(unitPrice > 1){
						indivTotal = (parseFloat(parseFloat(buyItNowPrice) / unitPrice) + parseFloat(shippingPrice)).toFixed(2);
						var indt2 = parseFloat(parseFloat(buyItNowTotal) / parseFloat(unitPrice));
						if(indivTotal > indt2){
							indivTotal = indt2.toFixed(2);
						}
					}
					else{
						indivTotal = buyItNowTotal;
					}
					shipping.innerHTML = '$' + indivTotal + ' each, including ' + shipping.innerHTML.substring(shipping.innerHTML.indexOf('$'));
				}
				if (shiptext) {
					shiptext.parentNode.removeChild(shiptext);
				}
			}
			ListingRanks.push({
				totalprice : buyItNowTotal,
				price : indivTotal,
				units : unitPrice,
				el : RowElement
			});
		}
	}
}

var page_request = new XMLHttpRequest();
page_request.onreadystatechange = function () {
	if (page_request.readyState == 4 && page_request.status == 200) {
		var div = window.content.document.createElement('div');
		try {
			var prt = page_request.responseText;
			var rt = prt;
			rt = rt.substring(rt.indexOf('<tbody id="wishlist-tbody">') - 1);
			rt = rt.substring(0, rt.indexOf('</tbody>') + 9);
			rt = rt.replace(/<img[^>]/g, "<null ");
			div.innerHTML = '<html><head></head><body><table><thead><tr><th></th><th></th><th></th></tr></thead>' + rt + '</table></body></html>';
			var pnumel = prt;
			pnumel = pnumel.substring(pnumel.indexOf('<div class="page-number">') + 25);
			pnumel = pnumel.substring(0, pnumel.indexOf('</div>'));
			var cnum = pnumel.substring(pnumel.indexOf('Page') + 5);
			cnum = cnum.substring(0, cnum.indexOf(' '));
			var nnum = pnumel.substring(pnumel.indexOf('of ') + 3);
			if (cnum == nnum) {
				doneLoading = 1;
				finalProcessing();
				return;
			}
			grabOrders(div);
			div = null;
			currentPage++;
			loadAPage();
		} catch (e) {}
	}
};

if (location.href.indexOf('/item') != -1 || location.href.indexOf('/store/product') != -1 || location.href.indexOf('SearchText=') != -1) {
	var titledata = GM_getValue('titledata');
	if (titledata) {
		var wishb = document.createElement('div');
		var q = document.createElement('input');
		var qh = document.createElement('input');
		var qh2 = document.createElement('input');
		var qf = document.createElement('form');
		var title = document.createElement('h2');
		title.class = 'ui-box-title';
		title.innerHTML = 'Similar Wishlist Items';
		wishb.id = 'wishlist-tbody';
		wishb.setAttribute('style', 'align:top;position:absolute;width:18%');
		q.id = 'q';
		qh.id = 'qh';
		qh2.id = 'qh2';
		q.type = 'hidden';
		qh.type = 'hidden';
		qh2.type = 'hidden';
		qh.value = GM_getValue('wishdata');
		qh2.value = titledata;
		document.getElementById('header').appendChild(title);
		document.getElementById('header').appendChild(wishb);
		qf.appendChild(q);
		qf.appendChild(qh);
		qf.appendChild(qh2);
		document.getElementById('header').appendChild(qf);
		if (location.href.indexOf('SearchText=') != -1) {
			q.value = document.getElementById('search-key').value;
			search('Contains Text');
		} else {
			q.value = document.getElementsByClassName('product-name')[0].innerHTML;
			search('Relative', 0.4);
		}
	}
} else if (location.href.indexOf('/wishlist') != -1) {
	var cp = document.getElementsByClassName('page-number')[0].innerHTML;
	cp = cp.substring(cp.indexOf('Page') + 5);
	cp = cp.substring(0, cp.indexOf(' '));
	if (cp == 1) {
		currentPage = 2;
		grabOrders(document);
		//}
		var srchel = document.createElement('li');
		var qt = document.createElement('label');
		var qf = document.createElement('form');
		var qh = document.createElement('input');
		var qh2 = document.createElement('input');
		var q = document.createElement('input');
		var qb = document.createElement('input');
		qb.id = 'qb';
		qb.type = 'button';
		qb.value = 'Search';
		qb.disabled = true;
		qt.id = 'qt';
		qt.innerHTML = 'Loading search.. please wait.';
		q.disabled = true;
		qh.type = 'hidden';
		qh.id = 'qh';
		qh2.type = 'hidden';
		qh2.id = 'qh2';
		q.id = 'q';
		q.size = 20;
		qf.appendChild(qt);
		qf.appendChild(document.createElement('br'));
		qf.appendChild(qh);
		qf.appendChild(qh2);
		qf.appendChild(q);
		qf.appendChild(qb);
		srchel.appendChild(qf);
		document.getElementsByClassName('tabs')[0].appendChild(srchel);
		var titledata = GM_getValue('titledata');
		if (titledata) {
			var firsttitle = document.getElementsByTagName('tbody')[0].getElementsByTagName('tr')[0].getElementsByClassName('main-info-hd')[0].getElementsByTagName('a')[0].innerHTML;
			if (firsttitle && titledata.indexOf(firsttitle) != -1) {
				loadsearch();
			} else {
				loadAPage();
			}
		} else {
			loadAPage();
		}
	}
}