// ==UserScript==
// @name Legacy GOG fixes
// @namespace ChrisSD_gog
// @description Fixes bugs on the older parts of the GOG.com website
// @include https://www.gog.com/*
// @include http://www.gog.com/*
// @version 1
// @grant none
// ==/UserScript==
// Match current pathname against a list of paths
function isPath() {
var path = window.location.pathname;
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] == path) { return true; }
}
return false;
}
if (isPath('/account', '/account/games', '/account/games/shelf',
'/account/games/list')) {
(function(){
window.shelfLinkHideClick = function() {
var b = $(this).parents('.shelf_details').attr('data-gameid');
var a = $(this).children('.dark_un').html();
$(this).toggleClass('hide unhide');
if (a == 'hide game') {
$(this).children('.dark_un').html('unhide game');
$('.shelf_game[data-gameid="' + b + '"]').addClass('hidden_game');
$.get(__ajax, {
a: 'gameHide',
h: 1,
g: b
})
} else {
$(this).children('.dark_un').html('hide game');
$('.shelf_game[data-gameid="' + b + '"]').removeClass('hidden_game');
$.get(__ajax, {
a: 'gameHide',
h: 0,
g: b
})
}
}
window.listLinkHideClick = function() {
alert('called!');
var b = $(this).attr('id').replace('hide_game_', '');
var a = $(this).children('.dark_un').html();
$(this).toggleClass('hide unhide');
if (a == 'hide game') {
$(this).children('.dark_un').html('unhide game');
$('#game_li_' + b).addClass('hidden_game');
$.get(__ajax, {
a: 'gameHide',
h: 1,
g: b
})
} else {
$(this).children('.dark_un').html('hide game');
$('#game_li_' + b).removeClass('hidden_game');
$.get(__ajax, {
a: 'gameHide',
h: 0,
g: b
})
}
}
function fixShelfView() {
var clickLock = false;
var timer = null;
$('.shelf_main').delegate('.shelf_game', 'click', function(event) {
event.stopPropagation();
if (timer !== null) {
clearTimeout(timer);
timer = null;
}
if (window.visibleDetails !== -1
&& event.target.parentNode.getAttribute('data-gameid') !== window.selectedGame[0].getAttribute('data-gameid')
&& event.target.parentNode.offsetTop != window.selectedGame[0].offsetTop) {
window.shelfDetailsClose();
timer = setTimeout(function() {
var click_event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'cancelable': true
});
event.target.dispatchEvent(click_event);
}, 1000);
}
else {
window.shelfGameClick.call(this, event);
}
});
}
fixShelfView();
}());
}
/** Section: search **/
var universe = document.querySelector('body > div.universe');
if (!universe) {
(function(){
var logout = document.querySelector('a[ng-click="logout()"]');
if (logout) {
logout.href = 'https://' + window.location.hostname + '/logout';
}
}());
(function(){
function clearResults() {
// remove the previous search results.
while (holder.firstChild) {
holder.removeChild(holder.firstChild);
}
removeCategoryItems();
}
function createCategoryItem(text, url) {
var element;
if (typeof(url) === 'undefined') {
element = document.createElement('div');
}
else {
element = document.createElement('a');
element.href = url;
element.className = 'product-row '; // for hover effect
}
element.className += 'top-nav-res__category top-nav-res__item top-nav-res__item--none';
element.appendChild(document.createTextNode(text));
categoryItems.push(element);
return element;
}
function removeCategoryItems() {
while (categoryItems.length > 0) {
var element = categoryItems.pop();
element.parentNode.removeChild(element);
}
}
function searchCallback(term, result) {
var products = result.products;
clearResults();
for (var i = 0; i < products.length; i++) {
var searchItem = search_item_template.cloneNode(true);
holder.appendChild(searchItem);
searchItem.querySelector('a.product-row__link').href = products[i].url;
searchItem.querySelector('div.product-title').appendChild(document.createTextNode(products[i].title));
searchItem.querySelector('span.price-btn__text > span').appendChild(document.createTextNode(products[i].price.amount));
searchItem.querySelector('span.curr-symbol').appendChild(document.createTextNode(products[i].price.symbol));
if (products[i].price.isDiscounted === true) {
var discountDiv = searchItem.querySelector('.product-row__discount');
discountDiv.classList.remove('ng-hide');
discountDiv.firstChild.appendChild(document.createTextNode(products[i].price.discountPercentage + '%'));
}
}
if (products.length === 0) {
var noResults = createCategoryItem('No results found');
search.appendChild(noResults);
var gamesLink = createCategoryItem('BROWSE ALL GAMES', '/games');
search.appendChild(gamesLink);
var moviesLink = createCategoryItem('BROWSE ALL MOVIES', '/movies');
search.appendChild(moviesLink);
} else if (result.totalPages > 1) {
if (result.totalGamesFound > 0) {
var gamesLink = createCategoryItem('ALL GAMES (' + result.totalGamesFound + ')',
'/games##search=' + term);
search.appendChild(gamesLink);
}
if (result.totalMoviesFound > 0) {
var moviesLink = createCategoryItem('ALL MOVIES (' + result.totalMoviesFound + ')',
'/movies##search=' + term);
search.appendChild(moviesLink);
}
}
}
function doSearch() {
var term = search_input.value;
if (term.length < 2) {
clearResults();
return;
}
var key = '£' + term;
if (savedSearches.hasOwnProperty(key)) {
searchCallback(term, savedSearches[key]);
} else {
var request = new XMLHttpRequest();
request.open('GET', search_url + term, true);
request.addEventListener('load', function() {
var result = JSON.parse(request.responseText);
savedSearches[key] = result;
searchCallback(term, result);
}, false);
request.send();
}
}
function isChildOf(child, parent) {
if (child === document.body) { return false; }
var elem = child.parentNode;
while (elem !== parent && elem !== document.body) {
elem = elem.parentNode;
}
return elem !== document.body;
}
var categoryItems = [];
var savedSearches = {};
var search_url = '/games/ajax/filtered?limit=4&search=';
var tempDiv = document.createElement('div'); // for parsing html strings
tempDiv.innerHTML = '<div class="product-row top-nav-res__item js-is-focusable product-row--micro"><div class="product-row__price product-row__alignment"><div class="price-btn price-btn--active"><span class="price-btn__text"><span class="ng-binding"><span class="curr-symbol"></span></span></span></div></div><a class="product-row__link"><div class="product-row__discount product-row__alignment ng-hide"><span class="price-text--discount"></span></div><div class="product-row__text"><div class="product-row__content"><div class="product-row__content-in"><div class="product-row__title"><div class="product-title ng-binding ng-scope"></div></div></div></div></div></a></div>';
var search_item_template = tempDiv.firstChild;
var tempDiv = document.createElement('div');
tempDiv.innerHTML = '<div class="_dropdown top-nav__results"><div class="top-nav-search-holder"><div class="top-nav-search _search"><input class="top-nav-search__input _search__input js-nav-serach-input" type="search"><i class="ic icon-search _search__icon top-nav-search__icon"></i><i class="ic icon-clear _search__clear no-hl top-nav-search__clear"></i><i class="spinner _search__spinner show-on-off-canvas"></i><i class="spinner _search__spinner hide-on-off-canvas"></i></div></div><div class="top-nav-res__category-holder"></div></div>';
search = tempDiv.firstChild;
search.style.display = 'none';
search.addEventListener('mouseup', function(event) {
event.stopPropagation();
}, false);
var holder = search.querySelector('.top-nav-res__category-holder');
var elem = document.querySelector('div.top-nav__container > .top-nav__items');
elem.parentNode.insertBefore(search, elem);
var search_input = search.querySelector('input[type="search"]');
var timer;
search_input.addEventListener('keyup', function(event) {
clearTimeout(timer);
timer = setTimeout(doSearch, 250);
}, false);
var searchButton = document.querySelector('nav .top-nav-extras-search-holder');
searchButton.addEventListener('mouseup', function(event) { event.stopPropagation()}, false);
searchButton.addEventListener('click', function(event) {
event.preventDefault();
if (search.style.display === 'none') {
search.style.display = 'block';
search_input.focus();
} else {
search.style.display = 'none';
}
}, false);
document.addEventListener('mouseup', function(event) {
if (!(event.which === 3 && isChildOf(event.target, search))) {
if (search.style.display !== 'none') {
search.style.display = 'none';
}
}
}, false);
}());
}
/** Section: wishlist **/
if (isPath('/account/wishlist')) {
(function(){
var priceClass = 'csd_price-set';
function getWishlistItems() {
var ids = [];
var nodes = [];
var query = document.querySelectorAll('#wishlistHolder > div.game-item');
for (i = 0; i < query.length; i++) {
if (query[i].classList.contains(priceClass)) {
continue;
}
query[i].classList.add(priceClass);
nodes.push(query[i]);
ids.push(parseInt(query[i].id.split('_').pop()));
}
return { ids: ids, nodes: nodes };
}
function getPrices(product_ids, callback) {
var payload = {
'data': {
'product_ids': product_ids,
'series_ids': false
}
}
var request = new XMLHttpRequest();
request.open('POST', '/userData.json', true);
request.onload = function() {
callback(JSON.parse(this.responseText)['personalizedProductPrices']);
};
request.send(JSON.stringify(payload));
}
function fix_wishlist_prices() {
var items = getWishlistItems();
getPrices(items.ids, function(prices) {
for (price_id in prices) {
if (prices.hasOwnProperty(price_id)) {
var price = prices[price_id];
var container = document.createElement('div');
container.className = 'gog-price';
var value = document.createElement('span');
value.className = 'price';
container.appendChild(value);
if (price.isFree === true) {
value.appendChild(document.createTextNode('Free'));
container.className += ' free';
} else {
value.appendChild(document.createTextNode(price.symbol + price.amount));
if (price.isDiscounted === true) {
container.className += ' promo';
}
}
var node = items.nodes[items.ids.indexOf(parseInt(price_id))];
node = node.querySelector('.game-item__inner');
node.insertBefore(container, node.firstChild);
}
}
});
}
var gog_newCallback = accountWishlistParams.loadNewCallback;
accountWishlistParams.loadNewCallback = function() {
gog_newCallback();
// Call this first and last times only
if (window.accountWishlistParams.complete || accountWishlistParams.page === 1) {
fix_wishlist_prices();
}
}
// main
fix_wishlist_prices();
}());
}
/** Section: mix **/
if (isPath('/mix') || window.location.pathname.lastIndexOf('/mix/', 0) === 0) {
(function(window, document){
var container = document.createElement('div');
container.setAttribute('style', 'float:right; position: relative; z-index:100;');
container.innerHTML = '<div id="up_" class="up"><span class="icon"></span></div><div id="down_" class="down"><span class="icon"></span></div><div id="remove_" class="edit_remove" style="display:none"><span class="icon"></span></div>'
function add_mix_buttons() {
if (!(document.body.classList.contains('edit_gogmix')
|| document.body.classList.contains('add_gogmix'))) {
return;
}
var nodes = document.querySelectorAll('#mainTemplateHolder div.game.edit');
for (var i = 0; i < nodes.length; i++) {
var gameid = nodes[i].getAttribute('data-gameid');
if (document.getElementById('up_' + gameid)) {
continue;
}
var buttons = container.cloneNode(true);
var children = buttons.childNodes;
for (var j = 0; j < children.length; j++) {
children[j].id += gameid;
}
var title = nodes[i].getElementsByTagName('h2')[0];
title.parentNode.insertBefore(buttons, title);
}
}
window.addEventListener('DOMContentLoaded', function() {
add_mix_buttons();
}, false);
var GogMixAfterLoad_click = window.GogMixAfterLoad.prototype.onClick;
window.GogMixAfterLoad.prototype.onClick = function (event) {
var type = event.data.type;
GogMixAfterLoad_click(event);
if (type === 'edit') {
add_mix_buttons();
}
}
var excludeGame = window.GogMixExcludeChosenGames.prototype.excludeFromDropDown;
window.GogMixExcludeChosenGames.prototype.excludeFromDropDown = function (a) {
excludeGame(a);
add_mix_buttons();
}
}(window, window.document));
}