// ==UserScript==
// @name SteamGifts Filter
// @description Giveaway filter
// @author No Body
// @include http://www.steamgifts.com/
// @include http://www.steamgifts.com/giveaways*
// @include http://www.steamgifts.com/user/*
// @include https://www.steamgifts.com/
// @include https://www.steamgifts.com/giveaways*
// @include https://www.steamgifts.com/user/*
// @version 0.1
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
// Keys for persistent settings, the keys for different views also represent "page keys" used as certain parameters to make things more simple
var KEY_EXCLUDE_GROUP_GIVEAWAYS = "excludeGroupGiveaways";
var KEY_EXCLUDE_WHITELIST_GIVEAWAYS = "excludeWhitelistGiveaways";
var KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS = "excludeRegionalGiveaways"
var KEY_EXCLUDE_PINNED_GIVEAWAYS = "excludePinnedGiveaways";
var KEY_ENABLE_FILTERING_BY_ENTRY_COUNT = "enableFilteringByEntryCount";
var KEY_MAX_NUMBER_OF_ENTRIES = "maxNumberOfEntries";
var KEY_MIN_LEVEL_TO_DISPLAY = "minLevelToDisplay";
var KEY_MAX_LEVEL_TO_DISPLAY = "maxLevelToDisplay";
var KEY_MIN_POINTS_TO_DISPLAY = "minPointsToDisplay";
var KEY_MAX_POINTS_TO_DISPLAY = "maxPointsToDisplay";
var KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW = "applyToAllGiveawaysView";
var KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW = "applyToGroupGiveawaysView";
var KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW = "applyToWishlistGiveawaysView";
var KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW = "applyToNewGiveawaysView";
var KEY_APPLY_TO_USER_PROFILE_VIEW = "applyToUserProfileView";
var KEY_APPLY_TO_SEARCH_RESULTS_VIEW = "applyToSearchResultsView";
var KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW = "applyToRecommendedGiveawaysView";
var KEY_REMOVE_PAGINATION = "removePagination";
var KEY_HIDE_ENTERED_GIVEAWAYS = "hideEnteredGiveaways_2";
var HIDE_ENTERED_GIVEAWAYS_CONSTANTS = ["No", "Yes", "Always"];
// Default values of persistent settings
var DEFAULT_EXCLUDE_GROUP_GIVEAWAYS = true;
var DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS = true;
var DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS = false;
var DEFAULT_EXCLUDE_PINNED_GIVEAWAYS = false;
var DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT = true;
var DEFAULT_MAX_NUMBER_OF_ENTRIES = 200;
var DEFAULT_MIN_LEVEL_TO_DISPLAY = 0;
var DEFAULT_MAX_LEVEL_TO_DISPLAY = 10;
var DEFAULT_MIN_POINTS_TO_DISPLAY = 0;
var DEFAULT_MAX_POINTS_TO_DISPLAY = 150;
var DEFAULT_APPLY_TO_ALL_GIVEAWAYS_VIEW = true;
var DEFAULT_APPLY_TO_GROUP_GIVEAWAYS_VIEW = false;
var DEFAULT_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW = false;
var DEFAULT_APPLY_TO_NEW_GIVEAWAYS_VIEW = true;
var DEFAULT_APPLY_TO_USER_PROFILE_VIEW = false;
var DEFAULT_APPLY_TO_SEARCH_RESULTS_VIEW = false;
var DEFAULT_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW = false;
var DEFAULT_REMOVE_PAGINATION = true;
var DEFAULT_HIDE_ENTERED_GIVEAWAYS = HIDE_ENTERED_GIVEAWAYS_CONSTANTS[0];
// IDs of filter UI elements
var FILTER_CONTROLS_ID = "filterControls";
var FILTER_CAPTION_ID = "filterCaption";
var FILTER_DETAILS_ID = "filterDetails";
var FILTER_HIDE_ID = "filterHide";
// Does all the filtering
function filterGiveaways() {
if (!isFilteringEnabledOnCurrentPage()) {
// Since it's not enabled, remove any possible filtering
var giveaways = getGiveaways();
for ( i = 0; i < giveaways.length; i++) {
removeFiltering(giveaways[i]);
}
handlePinnedBlock();
return;
}
// Dirty hack to "fix" endless scrolling in SG++ when a lot of GAs on the same page got removed
window.scrollBy(0, 1);
window.scrollBy(0, -1);
var minLevelToDisplay = GM_getValue(KEY_MIN_LEVEL_TO_DISPLAY, DEFAULT_MIN_LEVEL_TO_DISPLAY);
var maxLevelToDisplay = GM_getValue(KEY_MAX_LEVEL_TO_DISPLAY, DEFAULT_MAX_LEVEL_TO_DISPLAY);
var minPointsToDisplay = GM_getValue(KEY_MIN_POINTS_TO_DISPLAY, DEFAULT_MIN_POINTS_TO_DISPLAY);
var maxPointsToDisplay = GM_getValue(KEY_MAX_POINTS_TO_DISPLAY, DEFAULT_MAX_POINTS_TO_DISPLAY);
var excludeWhitelistGiveaways = GM_getValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS);
var excludeGroupGiveaways = GM_getValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, DEFAULT_EXCLUDE_GROUP_GIVEAWAYS);
var excludeRegionRestrictedGiveaways = GM_getValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS);
var excludePinnedGiveaways = GM_getValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, DEFAULT_EXCLUDE_PINNED_GIVEAWAYS);
var enableFilteringByEntryCount = GM_getValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT);
var maxNumberOfEntries = GM_getValue(KEY_MAX_NUMBER_OF_ENTRIES, DEFAULT_MAX_NUMBER_OF_ENTRIES);
var hideEnteredGiveaways = GM_getValue(KEY_HIDE_ENTERED_GIVEAWAYS, DEFAULT_HIDE_ENTERED_GIVEAWAYS);
var giveawaysToRemove = [];
var giveaways = getGiveaways();
for ( i = 0; i < giveaways.length; i++) {
// Remove the filtering
removeFiltering(giveaways[i]);
// Handle entered giveaways - ALWAYS option
if (hideEnteredGiveaways === HIDE_ENTERED_GIVEAWAYS_CONSTANTS[2]) {
if (isGiveawayEntered(giveaways[i])) {
giveawaysToRemove.push(giveaways[i]);
continue;
}
}
// Handle whitelist giveaways
if (excludeWhitelistGiveaways) {
if (isGiveawayFromWhitelist(giveaways[i])) {
continue;
}
}
// Handle group giveaways
if (excludeGroupGiveaways) {
if (isGiveawayFromGroup(giveaways[i])) {
continue;
}
}
// Handle pinned giveaways
if (excludePinnedGiveaways) {
if (isGiveawayPinned(giveaways[i])) {
continue;
}
}
// Handle region-restricted giveaways
if (excludeRegionRestrictedGiveaways) {
if (isGiveawayRegionRestricted(giveaways[i])) {
continue;
}
}
// Handle entered giveaways - YES option
if (hideEnteredGiveaways === HIDE_ENTERED_GIVEAWAYS_CONSTANTS[1]) {
if (isGiveawayEntered(giveaways[i])) {
giveawaysToRemove.push(giveaways[i]);
continue;
}
}
// Evaluate the contributor level
var contributorLevel = getContributorLevel(giveaways[i]);
if (contributorLevel < minLevelToDisplay || contributorLevel > maxLevelToDisplay) {
giveawaysToRemove.push(giveaways[i]);
continue;
}
// Evaluate the points
var points = getPoints(giveaways[i]);
if (points < minPointsToDisplay || points > maxPointsToDisplay) {
giveawaysToRemove.push(giveaways[i]);
continue;
}
// Handle entry-count filtering
if (enableFilteringByEntryCount) {
var numberOfEntries = getNumberOfEntries(giveaways[i]);
if (numberOfEntries > maxNumberOfEntries) {
giveawaysToRemove.push(giveaways[i]);
continue;
}
}
}
// Remove the giveaways
for ( i = 0; i < giveawaysToRemove.length; i++) {
giveawaysToRemove[i].style.display = "none";
}
// Handle the pinned giveaways block
handlePinnedBlock();
handlePagination();
// Dirty hack to "fix" endless scrolling in SG++ when a lot of GAs on the same page got removed
window.scrollBy(0, 1);
window.scrollBy(0, -1);
}
// Parses the giveaway elements from the whole page
function getGiveaways() {
var giveawaysSgpp = document.getElementsByClassName("SGPP__gridTile");
var giveaways = document.getElementsByClassName("giveaway__row-outer-wrap");
var allGiveaways = [];
allGiveaways.push.apply(allGiveaways, giveawaysSgpp);
allGiveaways.push.apply(allGiveaways, giveaways);
return allGiveaways;
}
// Returns true if the giveaway is for a whitelist, false otherwise
function isGiveawayFromWhitelist(giveaway) {
return giveaway.getElementsByClassName("giveaway__column--whitelist").length > 0;
}
// Returns true if the giveaway is for a group, false otherwise
function isGiveawayFromGroup(giveaway) {
return giveaway.getElementsByClassName("giveaway__column--group").length > 0;
}
// Returns true if the giveaway is region-restricted, false otherwise
function isGiveawayRegionRestricted(giveaway) {
return giveaway.getElementsByClassName("giveaway__column--region-restricted").length > 0;
}
// Returns true if the giveaway is pinned, false otherwise
function isGiveawayPinned(giveaway) {
var outerParent = giveaway.parentElement.parentElement;
return outerParent.className === "pinned-giveaways__outer-wrap";
}
function isGiveawayEntered(giveaway) {
return giveaway.getElementsByClassName("giveaway__row-inner-wrap is-faded").length > 0 ||
giveaway.className === "SGPP__gridTile is-faded";
}
// Returns the contributor level of a giveaway, return 0 if no level is specified
function getContributorLevel(giveaway) {
var contributorLevels = [];
var contributorLevelsPositive = giveaway.getElementsByClassName("giveaway__column--contributor-level giveaway__column--contributor-level--positive");
var contributorLevelsNegative = giveaway.getElementsByClassName("giveaway__column--contributor-level giveaway__column--contributor-level--negative");
contributorLevels.push.apply(contributorLevels, contributorLevelsPositive);
contributorLevels.push.apply(contributorLevels, contributorLevelsNegative);
if (contributorLevels.length === 0) {
return 0;
}
var contributorLevel = contributorLevels[0].innerHTML;
var substringStart = 0;
// Remove the "Level " at the start of the string, if present (SG++ grid view doesn't have it)
if (contributorLevel.indexOf("Level ") === 0) {
substringStart = 6;
}
// Parse the level, remove the "+" from the end
var level = contributorLevel.substring(substringStart, contributorLevel.length - 1);
return parseInt(level);
}
// Returns the points of a giveaway
function getPoints(giveaway) {
var pointsEle = giveaway.getElementsByClassName("giveaway__heading__thin");
// Since the points are the last element in a giveaway, just take the last item if available
if (pointsEle.length > 0) {
var pointsTxt = pointsEle[pointsEle.length-1].innerHTML;
var substringStart = 0;
// Remove the "(" at the start of the string, if present (SG++ grid view doesn't have it)
if (pointsTxt.indexOf("(") === 0) {
substringStart = 1;
}
// Parse the points, remove the "P)" from the end
var points = pointsTxt.substring(substringStart, pointsTxt.length - 2);
return parseInt(points);
}
// SG++ GridView
pointsEle = giveaway.getElementsByClassName("SGPP__gridTileInfo global__image-outer-wrap");
if (pointsEle.length > 0) {
// Go through the element and find the points part, can't really find it any easier since the elements have no IDs and no classes
var pointsTxt = pointsEle[0].children[2].children[1].children[0].innerHTML;
// Parse the points, remove the "P" from the end
var points = pointsTxt.substring(0, pointsTxt.length - 1);
return parseInt(points);
}
// If nothing could be parsed, return 0
return 0;
}
// Parses the number of entries for a giveaway
function getNumberOfEntries(giveaway) {
// Parse from SGv2 layout
var spanElements = giveaway.getElementsByTagName("span");
for ( j = 0; j < spanElements.length; j++) {
if (spanElements[j].innerHTML.indexOf("entr") != -1) {
return parseInt(spanElements[j].innerHTML.substring(0, spanElements[j].innerHTML.indexOf(" ")).replace(",", ""));
}
}
// Parse from SG++ grid layout
var divElements = giveaway.getElementsByTagName("div");
for ( j = 0; j < divElements.length; j++) {
if (divElements[j].style.cssFloat == "left" && divElements[j].innerHTML.indexOf("ntr") != -1) {
var strongElements = divElements[j].getElementsByTagName("strong");
// Just pick first, there is only one anyway
if (strongElements.length > 0) {
return parseInt(strongElements[0].innerHTML.replace(",", ""));
}
}
}
}
// Removes filtering from a given giveaway
function removeFiltering(giveaway) {
giveaway.style.display = "";
}
// Hides the pinned block completely if all the giveaways got filtered, shows it if it contains at least one giveaway
function handlePinnedBlock() {
var pinnedBlocks = document.getElementsByClassName("pinned-giveaways__outer-wrap");
// No pinned giveaways
if (pinnedBlocks.length === 0) {
return;
}
var pinnedGiveaways = pinnedBlocks[0].getElementsByClassName("giveaway__row-outer-wrap");
var giveawayRemaining = false;
for ( i = 0; i < pinnedGiveaways.length; i++) {
if (pinnedGiveaways[i].style.display !== "none") {
giveawayRemaining = true;
break;
}
}
if (giveawayRemaining) {
pinnedBlocks[0].style.display = "";
} else {
pinnedBlocks[0].style.display = "none";
}
}
var giveawayOrder = 1;
// Handles the pagination. Moves the GAs in SG++ grid layout into one grid if pagination should be removed
function handlePagination() {
var removePagination = GM_getValue(KEY_REMOVE_PAGINATION, DEFAULT_REMOVE_PAGINATION);
// Handle the pagination itself, leave the last pagination element in place (the magical -2 in the loop condition)
var paginationDivs = document.getElementsByClassName("table__heading");
for ( i = 0; i < paginationDivs.length - 2; i++) {
if (removePagination) {
paginationDivs[i].style.display = "none";
} else {
paginationDivs[i].style.display = "";
}
}
// GAs should be moved to the first gridview if using the SG++ GA grid view
var sgppGridviews = document.getElementsByClassName("SGPP__gridView");
if (sgppGridviews.length > 0) {
// Tag the giveaways
for ( i = 0; i < sgppGridviews.length; i++) {
var sgppGiveawayDivs = sgppGridviews[i].getElementsByClassName("SGPP__gridTile");
var pageNumber = getSgppPageNumber(sgppGridviews[i]);
for ( j = 0; j < sgppGiveawayDivs.length; j++) {
if (sgppGiveawayDivs[j].dataset.originalPage === undefined) {
sgppGiveawayDivs[j].dataset.originalPage = pageNumber;
}
if (sgppGiveawayDivs[j].dataset.order === undefined) {
sgppGiveawayDivs[j].dataset.order = giveawayOrder++;
}
}
}
var sgppFirstGridview = sgppGridviews[0];
for ( i = 0; i < sgppGridviews.length; i++) {
if(getSgppPageNumber(sgppGridviews[i]) === 1) {
sgppFirstGridview = sgppGridviews[i];
break;
}
}
if (removePagination) {
// Move the GAs in SG++ grid layout to the first grid
for ( i = 1; i < sgppGridviews.length; i++) {
var currentGridview = sgppGridviews[i];
var sgppGiveawayDivs = currentGridview.getElementsByClassName("SGPP__gridTile");
for ( j = 0; j < sgppGiveawayDivs.length; j++) {
var sgppGiveawayDiv = sgppGiveawayDivs[j];
currentGridview.removeChild(sgppGiveawayDiv);
insertGiveawayIntoGridview(sgppGiveawayDiv, sgppFirstGridview);
}
}
} else {
// Move the GAs back from the first grid to their respective page grids
var sgppGiveawayDivs = sgppFirstGridview.getElementsByClassName("SGPP__gridTile");
for ( i = 0; i < sgppGiveawayDivs.length; i++) {
var sgppGiveawayDiv = sgppGiveawayDivs[i];
var originalPage = parseInt(sgppGiveawayDiv.dataset.originalPage);
if (originalPage > 1) {
sgppFirstGridview.removeChild(sgppGiveawayDiv);
for ( j = 0; j < sgppGridviews.length; j++) {
var pageNumber = getSgppPageNumber(sgppGridviews[j]);
if (pageNumber === originalPage) {
insertGiveawayIntoGridview(sgppGiveawayDiv, sgppGridviews[j]);
break;
}
}
}
}
}
}
}
// Determines the page number from SG++ grid view
function getSgppPageNumber(sgppGridview) {
var currentPage = sgppGridview.previousElementSibling.getElementsByClassName("endless_page")[0].innerHTML;
var pageNumber = parseInt(currentPage.substring(5, currentPage.indexOf(" ", 6)));
return pageNumber;
}
// Inserts a GA into specified gridview based on its dataset.order value
function insertGiveawayIntoGridview(giveaway, gridview) {
var sgppSortedGiveawayDivs = gridview.getElementsByClassName("SGPP__gridTile");
var inserted = false;
for ( i = 0; i < sgppSortedGiveawayDivs.length; i++) {
if (parseInt(sgppSortedGiveawayDivs[i].dataset.order) > parseInt(giveaway.dataset.order)) {
gridview.insertBefore(giveaway, sgppSortedGiveawayDivs[i]);
inserted = true;
break;
}
}
if (!inserted) {
gridview.appendChild(giveaway);
}
}
// Returns true if filtering is enabled on the current page, false otherwise
function isFilteringEnabledOnCurrentPage() {
var applyToAllGiveawaysView = GM_getValue(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_ALL_GIVEAWAYS_VIEW);
var applyToGroupGiveawaysView = GM_getValue(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_GROUP_GIVEAWAYS_VIEW);
var applyToWishlistGiveawaysView = GM_getValue(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW);
var applyToNewGiveawaysView = GM_getValue(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_NEW_GIVEAWAYS_VIEW);
var applyToUserProfileView = GM_getValue(KEY_APPLY_TO_USER_PROFILE_VIEW, DEFAULT_APPLY_TO_USER_PROFILE_VIEW);
var applyToSearchResultsView = GM_getValue(KEY_APPLY_TO_SEARCH_RESULTS_VIEW, DEFAULT_APPLY_TO_SEARCH_RESULTS_VIEW);
var applyToRecommendedView = GM_getValue(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW);
if (applyToAllGiveawaysView && isCurrentPage(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW)) {
return true;
}
if (applyToGroupGiveawaysView && isCurrentPage(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW)) {
return true;
}
if (applyToWishlistGiveawaysView && isCurrentPage(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW)) {
return true;
}
if (applyToUserProfileView && isCurrentPage(KEY_APPLY_TO_USER_PROFILE_VIEW)) {
return true;
}
if (applyToNewGiveawaysView && isCurrentPage(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW)) {
return true;
}
if (applyToSearchResultsView && isCurrentPage(KEY_APPLY_TO_SEARCH_RESULTS_VIEW)) {
return true;
}
if (applyToRecommendedView && isCurrentPage(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW)) {
return true;
}
return false;
}
function isCurrentPage(pageKey) {
var currentPage = window.location.href;
if (pageKey === KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW) {
return (currentPage.indexOf("https://www.steamgifts.com/giveaways/search?page=") === 0
|| currentPage === "https://www.steamgifts.com" || currentPage === "https://www.steamgifts.com/"
|| currentPage === "https://www.steamgifts.com/giveaways"
|| currentPage.indexOf("http://www.steamgifts.com/giveaways/search?page=") === 0
|| currentPage === "http://www.steamgifts.com" || currentPage === "https://www.steamgifts.com/"
|| currentPage === "http://www.steamgifts.com/giveaways");
}
if (pageKey === KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW) {
return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=group") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=group") === 0);
}
if (pageKey === KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW) {
return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=wishlist") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=wishlist") === 0);
}
if (pageKey === KEY_APPLY_TO_USER_PROFILE_VIEW) {
return (currentPage.indexOf("http://www.steamgifts.com/user/") === 0 || currentPage.indexOf("https://www.steamgifts.com/user/") === 0);
}
if (pageKey === KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW) {
return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=new") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=new") === 0);
}
if (pageKey === KEY_APPLY_TO_SEARCH_RESULTS_VIEW) {
return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?q") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?q") === 0);
}
if (pageKey === KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW) {
return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=recommended") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=recommended") === 0);
}
return false;
}
// Draws the filter UI into the SG page
(function drawUi() {
// Create the filter details element and add content to it
var detailsContentDiv = document.createElement("div");
detailsContentDiv.setAttribute("class", 'pinned-giveaways__inner-wrap filterDetails');
detailsContentDiv.appendChild(createFilterUiFilterOptionsRow());
detailsContentDiv.appendChild(createFilterUiExcludeOptionsRow());
detailsContentDiv.appendChild(createFilterUiEnabledPagesRow());
detailsContentDiv.appendChild(createFilterUiOtherOptionsRow());
var detailsDiv = document.createElement("div");
detailsDiv.id = FILTER_DETAILS_ID;
detailsDiv.style.display = "none";
detailsDiv.appendChild(detailsContentDiv);
detailsDiv.appendChild(createFilterUiHideFilterDetailsRow());
// Create the filter UI element
var controlsDiv = document.createElement("div");
controlsDiv.setAttribute("id", FILTER_CONTROLS_ID);
controlsDiv.setAttribute("class", 'pinned-giveaways__inner-wrap');
controlsDiv.appendChild(createFilterUiCaptionRow());
controlsDiv.appendChild(detailsDiv);
// Add the filter UI to the correct place on the current page
insertFilterUi(controlsDiv);
updateFilterCaptionTextColor();
// Append Stylesheet
var filterCss = '.giveaway__row-outer-wrap[data-gridview*="sgpp_gridview"] {display: none;}\
.filterDetails {margin: -1px -14px !important; border-radius: 0px !important;}\
#filterDetails span {padding: 0 5px; font-size: 12px;}\
#filterCaption {cursor: pointer; display: flex; border-top-left-radius: 4px; border-top-right-radius: 4px; font:700 14px/22px "Open Sans",sans-serif !important; margin: 0px -13px; padding: 5px 10px; border: none;}\
#filterHide {border-top-right-radius: 0px; border-top-left-radius: 0px; margin: 1px -14px -1px; padding: 5px 0px; justify-content: center; cursor: pointer;}\
#filterControls {margin-bottom: 5px; background-image: none;}\
#filterControls select, #filterControls input {padding: 2px 4px;}\
#filterHide.sidebar__navigation__item__link, #filterHide.sidebar__navigation__item__link:hover {border-top: none;}\
.filterCheckbox {width: 13px; margin: 5px;}\
.filterNumberInput {margin: 5px 0;}\
.enableContainer, .excludeContainer {margin-top: 3px;}\
.enableContainer.markdown hr, .excludeContainer.markdown hr, .filteringContainer.markdown hr {margin: 0px;}\
.otherContainer {padding: 5px 0;}\
.filteringContainer{padding-top: 1px;}\
.flexLeft {display: flex; align-items: center; justify-content: flex-start; flex-grow: 1; flex-basis: 0px;}\
.flexCenter {display: flex; align-items: center; justify-content: center; flex-grow: 1; flex-basis: 0px; margin-top: -1px;}\
.flexRight {display: flex; align-items: center; justify-content: flex-end; flex-grow: 1; flex-basis: 0px;}\
.help-tip {text-align: center; border-style: dotted; border-width: 1px; margin-left: 2px; margin-right: -5px; padding: 1px; cursor: help;}\
.sidebar__shortcut-tooltip-absolute.tooltip {display: none; box-shadow: none; padding: 8px !important; margin-left: -275px; margin-top: 10px; width: 406px; line-height: 16px; -webkit-filter: saturate(0); filter: saturate(0); }\
.sidebar__shortcut-tooltip-absolute, .table__row-outer-wrap {color:inherit;}\
.help-tip:hover .sidebar__shortcut-tooltip-absolute.tooltip {display: block;}';
var style = document.createElement('style');
if (style.styleSheet) {
style.styleSheet.cssText = filterCss;
} else {
style.appendChild(document.createTextNode(filterCss));
}
document.getElementsByTagName('head')[0].appendChild(style);
})();
// Creates the top-level caption that is visible all the time on a giveaway page
function createFilterUiCaptionRow() {
var filterOptionsCaption = document.createElement("div");
filterOptionsCaption.id = FILTER_CAPTION_ID;
filterOptionsCaption.appendChild(document.createTextNode(getFilterCaption()));
filterOptionsCaption.onclick = function() {
// Clicking on the caption opens/closes the filter details UI
var detailsDiv = document.getElementById(FILTER_DETAILS_ID);
if (detailsDiv.style.display === "") {
detailsDiv.style.display = "none";
} else {
detailsDiv.style.display = "";
}
};
return filterOptionsCaption;
}
// Creates the row with filtering options (level, number of entries, ...)
function createFilterUiFilterOptionsRow() {
var minLevelToDisplay = GM_getValue(KEY_MIN_LEVEL_TO_DISPLAY, DEFAULT_MIN_LEVEL_TO_DISPLAY);
var maxLevelToDisplay = GM_getValue(KEY_MAX_LEVEL_TO_DISPLAY, DEFAULT_MAX_LEVEL_TO_DISPLAY);
var minPointsToDisplay = GM_getValue(KEY_MIN_POINTS_TO_DISPLAY, DEFAULT_MIN_POINTS_TO_DISPLAY);
var maxPointsToDisplay = GM_getValue(KEY_MAX_POINTS_TO_DISPLAY, DEFAULT_MAX_POINTS_TO_DISPLAY);
var enableFilteringByEntryCount = GM_getValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT);
var maxNumberOfEntries = GM_getValue(KEY_MAX_NUMBER_OF_ENTRIES, DEFAULT_MAX_NUMBER_OF_ENTRIES);
// The "minimal level to display" number input
var minLevelToDisplayInput = document.createElement("input");
minLevelToDisplayInput.setAttribute("type", "number");
minLevelToDisplayInput.setAttribute("maxLength", "2");
minLevelToDisplayInput.setAttribute("class", "filterNumberInput");
minLevelToDisplayInput.style.width = "55px";
minLevelToDisplayInput.value = minLevelToDisplay;
minLevelToDisplayInput.onchange = function() {
// Filter out invalid values
var minLevelToDisplayInputValue = parseInt(minLevelToDisplayInput.value);
if (minLevelToDisplayInputValue < DEFAULT_MIN_LEVEL_TO_DISPLAY) {
minLevelToDisplayInput.value = DEFAULT_MIN_LEVEL_TO_DISPLAY;
} else if (minLevelToDisplayInputValue > maxLevelToDisplay) {
minLevelToDisplayInput.value = maxLevelToDisplay;
}
// If the value changed, save it and update the UI
if (minLevelToDisplay != minLevelToDisplayInput.value) {
GM_setValue(KEY_MIN_LEVEL_TO_DISPLAY, minLevelToDisplayInput.value);
minLevelToDisplay = minLevelToDisplayInput.value;
updateFilterCaption();
filterGiveaways();
}
};
// Accept only digits
minLevelToDisplayInput.onkeypress = function(event) {
return isDigit(event.charCode);
};
// The "maximal level to display" number input
var maxLevelToDisplayInput = document.createElement("input");
maxLevelToDisplayInput.setAttribute("type", "number");
maxLevelToDisplayInput.setAttribute("maxLength", "2");
maxLevelToDisplayInput.style.width = "55px";
maxLevelToDisplayInput.value = maxLevelToDisplay;
maxLevelToDisplayInput.onchange = function() {
// Filter out invalid values
var maxLevelToDisplayInputValue = parseInt(maxLevelToDisplayInput.value);
if (maxLevelToDisplayInputValue > DEFAULT_MAX_LEVEL_TO_DISPLAY) {
maxLevelToDisplayInput.value = DEFAULT_MAX_LEVEL_TO_DISPLAY;
} else if (maxLevelToDisplayInputValue < minLevelToDisplay) {
maxLevelToDisplayInput.value = minLevelToDisplay;
}
// If the value changed, save it and update the UI
if (maxLevelToDisplay != maxLevelToDisplayInput.value) {
GM_setValue(KEY_MAX_LEVEL_TO_DISPLAY, maxLevelToDisplayInput.value);
maxLevelToDisplay = maxLevelToDisplayInput.value;
updateFilterCaption();
filterGiveaways();
}
};
// Accept only digits
maxLevelToDisplayInput.onkeypress = function(event) {
return isDigit(event.charCode);
};
// Create and add the level filter
var showLevelSpan = document.createElement("span");
showLevelSpan.appendChild(document.createTextNode("Show level:"));
var levelDashSpan = document.createElement("span");
levelDashSpan.appendChild(document.createTextNode("-"));
var flexGrowLeftDiv = document.createElement("div");
flexGrowLeftDiv.setAttribute("class", "flexLeft");
flexGrowLeftDiv.appendChild(showLevelSpan);
flexGrowLeftDiv.appendChild(minLevelToDisplayInput);
flexGrowLeftDiv.appendChild(levelDashSpan);
flexGrowLeftDiv.appendChild(maxLevelToDisplayInput);
// The "minimal points to display" number input
var minPointsToDisplayInput = document.createElement("input");
minPointsToDisplayInput.setAttribute("type", "number");
minPointsToDisplayInput.setAttribute("maxLength", "3");
minPointsToDisplayInput.style.width = "62px";
minPointsToDisplayInput.value = minPointsToDisplay;
minPointsToDisplayInput.onchange = function() {
// Filter out invalid values
var minPointsToDisplayInputValue = parseInt(minPointsToDisplayInput.value);
if (minPointsToDisplayInputValue < DEFAULT_MIN_POINTS_TO_DISPLAY) {
minPointsToDisplayInput.value = DEFAULT_MIN_POINTS_TO_DISPLAY;
} else if (minPointsToDisplayInputValue > maxPointsToDisplay) {
minPointsToDisplayInput.value = maxPointsToDisplay;
}
// If the value changed, save it and update the UI
if (minPointsToDisplay != minPointsToDisplayInput.value) {
GM_setValue(KEY_MIN_POINTS_TO_DISPLAY, minPointsToDisplayInput.value);
minPointsToDisplay = minPointsToDisplayInput.value;
updateFilterCaption();
filterGiveaways();
}
};
// Accept only digits
minPointsToDisplayInput.onkeypress = function(event) {
return isDigit(event.charCode);
};
// The "maximal level to display" number input
var maxPointsToDisplayInput = document.createElement("input");
maxPointsToDisplayInput.setAttribute("type", "number");
maxPointsToDisplayInput.setAttribute("maxLength", "3");
maxPointsToDisplayInput.style.width = "62px";
maxPointsToDisplayInput.value = maxPointsToDisplay;
maxPointsToDisplayInput.onchange = function() {
// Filter out invalid values
var maxPointsToDisplayInputValue = parseInt(maxPointsToDisplayInput.value);
if (maxPointsToDisplayInputValue > DEFAULT_MAX_POINTS_TO_DISPLAY) {
maxPointsToDisplayInput.value = DEFAULT_MAX_POINTS_TO_DISPLAY;
} else if (maxPointsToDisplayInputValue < minPointsToDisplay) {
maxPointsToDisplayInput.value = minPointsToDisplay;
}
// If the value changed, save it and update the UI
if (maxPointsToDisplay != maxPointsToDisplayInput.value) {
GM_setValue(KEY_MAX_POINTS_TO_DISPLAY, maxPointsToDisplayInput.value);
maxPointsToDisplay = maxPointsToDisplayInput.value;
updateFilterCaption();
filterGiveaways();
}
};
// Accept only digits
maxPointsToDisplayInput.onkeypress = function(event) {
return isDigit(event.charCode);
};
// Create and add the points filter
var showPointsSpan = document.createElement("span");
showPointsSpan.appendChild(document.createTextNode("Points to enter:"));
var pointsDashSpan = document.createElement("span");
pointsDashSpan.appendChild(document.createTextNode("-"));
var flexGrowCenterDiv = document.createElement("div");
flexGrowCenterDiv.setAttribute("class", "flexCenter");
flexGrowCenterDiv.appendChild(showPointsSpan);
flexGrowCenterDiv.appendChild(minPointsToDisplayInput);
flexGrowCenterDiv.appendChild(pointsDashSpan);
flexGrowCenterDiv.appendChild(maxPointsToDisplayInput);
// The "enable filtering by entry count" input checkbox
var enableFilteringByEntryCountInput = document.createElement("input");
enableFilteringByEntryCountInput.setAttribute("type", "checkbox");
enableFilteringByEntryCountInput.setAttribute("class", "filterCheckbox");
enableFilteringByEntryCountInput.checked = enableFilteringByEntryCount;
enableFilteringByEntryCountInput.onclick = function() {
// Upon value change, enable and recolor the entry count input
GM_setValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, enableFilteringByEntryCountInput.checked);
maxNumberOfEntriesInput.disabled = !enableFilteringByEntryCountInput.checked;
maxNumberOfEntriesInput.readOnly = !enableFilteringByEntryCountInput.checked;
if (!enableFilteringByEntryCountInput.checked) {
maxNumberOfEntriesInput.style.opacity = "0.4";
} else {
maxNumberOfEntriesInput.style.opacity = maxNumberOfEntriesInputOriginalOpacity;
maxNumberOfEntriesInput.style.opacity = "1";
}
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
// The "maximal number of entries" number input
var maxNumberOfEntriesInput = document.createElement("input");
maxNumberOfEntriesInput.setAttribute("type", "number");
maxNumberOfEntriesInput.setAttribute("maxLength", "6");
maxNumberOfEntriesInput.style.width = "90px";
maxNumberOfEntriesInput.disabled = !enableFilteringByEntryCount;
maxNumberOfEntriesInput.value = maxNumberOfEntries;
maxNumberOfEntriesInput.readOnly = !enableFilteringByEntryCount;
maxNumberOfEntriesInput.onchange = function() {
// Limit the entry count filter to 1000000, should be enough for a while
if (maxNumberOfEntriesInput.value < 0 || maxNumberOfEntriesInput.value > 1000000) {
maxNumberOfEntriesInput.value = maxNumberOfEntries;
} else if (maxNumberOfEntries != maxNumberOfEntriesInput.value) {
// If the value changed, save it and update the UI
GM_setValue(KEY_MAX_NUMBER_OF_ENTRIES, maxNumberOfEntriesInput.value);
maxNumberOfEntries = maxNumberOfEntriesInput.value;
updateFilterCaption();
filterGiveaways();
return;
}
};
// Accept only digits
maxNumberOfEntriesInput.onkeypress = function(event) {
return isDigit(event.charCode);
};
var maxNumberOfEntriesInputOriginalOpacity = maxNumberOfEntriesInput.style.opacity;
// Gray out the input text if disabled
if (!enableFilteringByEntryCount) {
maxNumberOfEntriesInput.style.opacity = "0.4";
}
// Create and add the entry count filter
var entryFilteringEnabledSpan = document.createElement("span");
entryFilteringEnabledSpan.appendChild(document.createTextNode("Entry count filtering"));
var entryFilteringCountSpan = document.createElement("span");
entryFilteringCountSpan.appendChild(document.createTextNode("Max # of entries:"));
var flexGrowRightDiv = document.createElement("div");
flexGrowRightDiv.setAttribute("class", "flexRight");
flexGrowRightDiv.appendChild(entryFilteringEnabledSpan);
flexGrowRightDiv.appendChild(enableFilteringByEntryCountInput);
flexGrowRightDiv.appendChild(entryFilteringCountSpan);
flexGrowRightDiv.appendChild(maxNumberOfEntriesInput);
// Create the row itself
var firstRow = document.createElement("div");
firstRow.setAttribute("class", "flexCenter");
firstRow.appendChild(flexGrowLeftDiv);
firstRow.appendChild(flexGrowCenterDiv);
firstRow.appendChild(flexGrowRightDiv);
var row = document.createElement("div");
var hr = document.createElement("hr");
row.setAttribute("class", 'filteringContainer markdown');
row.appendChild(firstRow);
row.appendChild(hr);
return row;
}
// Creates a row with the "exclude" options
function createFilterUiExcludeOptionsRow() {
var excludeWhitelistGiveaways = GM_getValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS);
var excludeGroupGiveaways = GM_getValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, DEFAULT_EXCLUDE_GROUP_GIVEAWAYS);
var excludePinnedGiveaways = GM_getValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, DEFAULT_EXCLUDE_PINNED_GIVEAWAYS);
var excludeRegionRestrictedGiveaways = GM_getValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS);
// The "exlude group GAs" input checkbox
var excludeGroupGiveawaysInput = document.createElement("input");
excludeGroupGiveawaysInput.setAttribute("type", "checkbox");
excludeGroupGiveawaysInput.setAttribute("class", "filterCheckbox");
excludeGroupGiveawaysInput.checked = excludeGroupGiveaways;
excludeGroupGiveawaysInput.onclick = function() {
// Save the change and update the UI
GM_setValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, excludeGroupGiveawaysInput.checked);
updateFilterCaption();
filterGiveaways();
};
var excludeGroupGiveawaysSpan = document.createElement("span");
excludeGroupGiveawaysSpan.appendChild(document.createTextNode("Exclude group giveaways"));
// Create and add the group GAs exclusion element
var flexGrowLeftDiv = document.createElement("div");
flexGrowLeftDiv.setAttribute("class", "flexLeft");
flexGrowLeftDiv.appendChild(excludeGroupGiveawaysSpan);
flexGrowLeftDiv.appendChild(excludeGroupGiveawaysInput);
// The "exlude whitelist GAs" input checkbox
var excludeWhitelistGiveawaysInput = document.createElement("input");
excludeWhitelistGiveawaysInput.setAttribute("type", "checkbox");
excludeWhitelistGiveawaysInput.setAttribute("class", "filterCheckbox");
excludeWhitelistGiveawaysInput.checked = excludeWhitelistGiveaways;
excludeWhitelistGiveawaysInput.onclick = function() {
// If the value changed, save it and update the UI
GM_setValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, excludeWhitelistGiveawaysInput.checked);
updateFilterCaption();
filterGiveaways();
};
var excludeWhitelistGiveawaysSpan = document.createElement("span");
excludeWhitelistGiveawaysSpan.appendChild(document.createTextNode("Exclude whitelist giveaways"));
// Create and add the whitelist GAs exclusion element
var flexGrowCenterDiv = document.createElement("div");
flexGrowCenterDiv.setAttribute("class", "flexCenter");
flexGrowCenterDiv.appendChild(excludeWhitelistGiveawaysSpan);
flexGrowCenterDiv.appendChild(excludeWhitelistGiveawaysInput);
// The "exclude pinned giveaways" input checkbox
var excludePinnedGiveawaysInput = document.createElement("input");
excludePinnedGiveawaysInput.setAttribute("type", "checkbox");
excludePinnedGiveawaysInput.setAttribute("class", "filterCheckbox");
excludePinnedGiveawaysInput.checked = excludePinnedGiveaways;
excludePinnedGiveawaysInput.onclick = function() {
// Upon value change
GM_setValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, excludePinnedGiveawaysInput.checked);
excludePinnedGiveaways = excludePinnedGiveawaysInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
var excludePinnedGiveawaysSpan = document.createElement("span");
excludePinnedGiveawaysSpan.appendChild(document.createTextNode('Exclude pinned giveaways'));
// Create and add the "exclude pinned giveaways" text
var flexGrowRightDiv = document.createElement("div");
flexGrowRightDiv.setAttribute("class", "flexRight");
flexGrowRightDiv.appendChild(excludePinnedGiveawaysSpan);
flexGrowRightDiv.appendChild(excludePinnedGiveawaysInput);
// Create the first row
var firstRow = document.createElement("div");
firstRow.setAttribute("class", "flexCenter");
firstRow.appendChild(flexGrowLeftDiv);
firstRow.appendChild(flexGrowCenterDiv);
firstRow.appendChild(flexGrowRightDiv);
// The "exclude region-restricted giveaways" input checkbox
var excludeRegionRestrictedGiveawaysInput = document.createElement("input");
excludeRegionRestrictedGiveawaysInput.setAttribute("type", "checkbox");
excludeRegionRestrictedGiveawaysInput.setAttribute("class", "filterCheckbox");
excludeRegionRestrictedGiveawaysInput.checked = excludeRegionRestrictedGiveaways;
excludeRegionRestrictedGiveawaysInput.onclick = function() {
// Upon value change
GM_setValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, excludeRegionRestrictedGiveawaysInput.checked);
excludeRegionRestrictedGiveaways = excludeRegionRestrictedGiveawaysInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
// Create and add the "exclude region-restricted giveaways" text
var excludeRegionRestrictedGiveawaysSpan = document.createElement("span");
excludeRegionRestrictedGiveawaysSpan.appendChild(document.createTextNode("Exclude region-restricted giveaways"));
// Create the "exclude region-restricted giveaways" element itself
flexGrowLeftDiv = document.createElement("div");
flexGrowLeftDiv.setAttribute("class", "flexCenter");
flexGrowLeftDiv.appendChild(excludeRegionRestrictedGiveawaysSpan);
flexGrowLeftDiv.appendChild(excludeRegionRestrictedGiveawaysInput);
// Create the second row in the filter details
var secondRow = document.createElement("div");
secondRow.setAttribute("class", "flexCenter");
secondRow.appendChild(flexGrowLeftDiv);
// Create the row itself
var row = document.createElement("div");
var hr = document.createElement("hr");
row.setAttribute("class", 'excludeContainer markdown');
row.appendChild(firstRow);
row.appendChild(secondRow);
row.appendChild(hr);
return row;
}
// Creates the row with "enabled pages" settings
function createFilterUiEnabledPagesRow() {
var applyToAllGiveawaysView = GM_getValue(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_ALL_GIVEAWAYS_VIEW);
var applyToGroupGiveawaysView = GM_getValue(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_GROUP_GIVEAWAYS_VIEW);
var applyToWishlistGiveawaysView = GM_getValue(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW);
var applyToNewGiveawaysView = GM_getValue(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_NEW_GIVEAWAYS_VIEW);
var applyToUserProfileView = GM_getValue(KEY_APPLY_TO_USER_PROFILE_VIEW, DEFAULT_APPLY_TO_USER_PROFILE_VIEW);
var applyToSearchResultsView = GM_getValue(KEY_APPLY_TO_SEARCH_RESULTS_VIEW, DEFAULT_APPLY_TO_SEARCH_RESULTS_VIEW);
var applyToRecommendedGiveawaysView = GM_getValue(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW);
// Create and add the "enable filtering on the main page" text
var flexGrowLeftDiv = document.createElement("div");
flexGrowLeftDiv.setAttribute("class", "flexLeft");
var enableFilteringOnTheMainPageSpan = document.createElement("span");
enableFilteringOnTheMainPageSpan.appendChild(document.createTextNode("Enable on the main page"));
if (isCurrentPage(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW)) {
enableFilteringOnTheMainPageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowLeftDiv.appendChild(enableFilteringOnTheMainPageSpan);
// The "enable filtering on the main page" input checkbox
var enableFilteringOnTheMainPageInput = document.createElement("input");
enableFilteringOnTheMainPageInput.setAttribute("type", "checkbox");
enableFilteringOnTheMainPageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheMainPageInput.checked = applyToAllGiveawaysView;
enableFilteringOnTheMainPageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW, enableFilteringOnTheMainPageInput.checked);
applyToAllGiveawaysView = enableFilteringOnTheMainPageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowLeftDiv.appendChild(enableFilteringOnTheMainPageInput);
// Create and add the "enable filtering on the new giveaways page" text
var flexGrowCenterDiv = document.createElement("div");
flexGrowCenterDiv.setAttribute("class", "flexCenter");
var enableFilteringOnTheNewGiveawaysPageSpan = document.createElement("span");
enableFilteringOnTheNewGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "new giveaways" page'));
if (isCurrentPage(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW)) {
enableFilteringOnTheNewGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowCenterDiv.appendChild(enableFilteringOnTheNewGiveawaysPageSpan);
// The "enable filtering on the new giveaways page" input checkbox
var enableFilteringOnTheNewGiveawaysPageInput = document.createElement("input");
enableFilteringOnTheNewGiveawaysPageInput.setAttribute("type", "checkbox");
enableFilteringOnTheNewGiveawaysPageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheNewGiveawaysPageInput.checked = applyToNewGiveawaysView;
enableFilteringOnTheNewGiveawaysPageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW, enableFilteringOnTheNewGiveawaysPageInput.checked);
applyToNewGiveawaysView = enableFilteringOnTheNewGiveawaysPageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowCenterDiv.appendChild(enableFilteringOnTheNewGiveawaysPageInput);
// Create and add the "enable filtering on the search results" text
var flexGrowRightDiv = document.createElement("div");
flexGrowRightDiv.setAttribute("class", "flexRight");
var enableFilteringOnTheSearchResultsPageSpan = document.createElement("span");
enableFilteringOnTheSearchResultsPageSpan.appendChild(document.createTextNode('Enable on the "search results" page'));
if (isCurrentPage(KEY_APPLY_TO_SEARCH_RESULTS_VIEW)) {
enableFilteringOnTheSearchResultsPageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowRightDiv.appendChild(enableFilteringOnTheSearchResultsPageSpan);
// The "enable filtering on the search results" input checkbox
var enableFilteringOnTheSearchResultsPageInput = document.createElement("input");
enableFilteringOnTheSearchResultsPageInput.setAttribute("type", "checkbox");
enableFilteringOnTheSearchResultsPageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheSearchResultsPageInput.checked = applyToSearchResultsView;
enableFilteringOnTheSearchResultsPageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_SEARCH_RESULTS_VIEW, enableFilteringOnTheSearchResultsPageInput.checked);
applyToSearchResultsView = enableFilteringOnTheSearchResultsPageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowRightDiv.appendChild(enableFilteringOnTheSearchResultsPageInput);
// Create the first row in the filter details
var firstRow = document.createElement("div");
firstRow.setAttribute("class", "flexCenter");
firstRow.appendChild(flexGrowLeftDiv);
firstRow.appendChild(flexGrowCenterDiv);
firstRow.appendChild(flexGrowRightDiv);
// Create and add the "enable filtering on the wishlist giveaways page" text
flexGrowLeftDiv = document.createElement("div");
flexGrowLeftDiv.setAttribute("class", "flexLeft");
var enableFilteringOnTheWishlistGiveawaysPageSpan = document.createElement("span");
enableFilteringOnTheWishlistGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "wishlist giveaways" page'));
if (isCurrentPage(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW)) {
enableFilteringOnTheWishlistGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowLeftDiv.appendChild(enableFilteringOnTheWishlistGiveawaysPageSpan);
// The "enable filtering on the wishlist giveaways page" input checkbox
var enableFilteringOnTheWishlistGiveawaysPageInput = document.createElement("input");
enableFilteringOnTheWishlistGiveawaysPageInput.setAttribute("type", "checkbox");
enableFilteringOnTheWishlistGiveawaysPageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheWishlistGiveawaysPageInput.checked = applyToWishlistGiveawaysView;
enableFilteringOnTheWishlistGiveawaysPageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW, enableFilteringOnTheWishlistGiveawaysPageInput.checked);
applyToWishlistGiveawaysView = enableFilteringOnTheWishlistGiveawaysPageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowLeftDiv.appendChild(enableFilteringOnTheWishlistGiveawaysPageInput);
// Create and add the "enable filtering on the "group giveaways" page" text
flexGrowCenterDiv = document.createElement("div");
flexGrowCenterDiv.setAttribute("class", "flexCenter");
var enableFilteringOnTheGroupGiveawaysPageSpan = document.createElement("span");
enableFilteringOnTheGroupGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "group giveaways" page'));
if (isCurrentPage(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW)) {
enableFilteringOnTheGroupGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowCenterDiv.appendChild(enableFilteringOnTheGroupGiveawaysPageSpan);
// The "enable filtering on the "group giveaways" page" page" input checkbox
var enableFilteringOnTheGroupGiveawaysPageInput = document.createElement("input");
enableFilteringOnTheGroupGiveawaysPageInput.setAttribute("type", "checkbox");
enableFilteringOnTheGroupGiveawaysPageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheGroupGiveawaysPageInput.checked = applyToGroupGiveawaysView;
enableFilteringOnTheGroupGiveawaysPageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW, enableFilteringOnTheGroupGiveawaysPageInput.checked);
applyToGroupGiveawaysView = enableFilteringOnTheGroupGiveawaysPageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowCenterDiv.appendChild(enableFilteringOnTheGroupGiveawaysPageInput);
// Create and add the "enable filtering on the user profile page" text
flexGrowRightDiv = document.createElement("div");
flexGrowRightDiv.setAttribute("class", "flexRight");
var enableFilteringOnTheUserProfilePageSpan = document.createElement("span");
enableFilteringOnTheUserProfilePageSpan.appendChild(document.createTextNode('Enable on the "user profile" page'));
if (isCurrentPage(KEY_APPLY_TO_USER_PROFILE_VIEW)) {
enableFilteringOnTheUserProfilePageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowRightDiv.appendChild(enableFilteringOnTheUserProfilePageSpan);
// The "enable filtering on the user profile page" input checkbox
var enableFilteringOnTheUserProfilePageInput = document.createElement("input");
enableFilteringOnTheUserProfilePageInput.setAttribute("type", "checkbox");
enableFilteringOnTheUserProfilePageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheUserProfilePageInput.checked = applyToUserProfileView;
enableFilteringOnTheUserProfilePageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_USER_PROFILE_VIEW, enableFilteringOnTheUserProfilePageInput.checked);
applyToUserProfileView = enableFilteringOnTheUserProfilePageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowRightDiv.appendChild(enableFilteringOnTheUserProfilePageInput);
// Create the second row in the filter details
var secondRow = document.createElement("div");
secondRow.setAttribute("class", "flexCenter");
secondRow.appendChild(flexGrowLeftDiv);
secondRow.appendChild(flexGrowCenterDiv);
secondRow.appendChild(flexGrowRightDiv);
// Create and add the "enable filtering on the wishlist giveaways page" text
flexGrowCenterDiv = document.createElement("div");
flexGrowCenterDiv.setAttribute("class", "flexCenter");
var enableFilteringOnTheRecommendedGiveawaysPageSpan = document.createElement("span");
enableFilteringOnTheRecommendedGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "recommended giveaways" page'));
if (isCurrentPage(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW)) {
enableFilteringOnTheRecommendedGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
}
flexGrowCenterDiv.appendChild(enableFilteringOnTheRecommendedGiveawaysPageSpan);
// The "enable filtering on the wishlist giveaways page" input checkbox
var enableFilteringOnTheRecommendedGiveawaysPageInput = document.createElement("input");
enableFilteringOnTheRecommendedGiveawaysPageInput.setAttribute("type", "checkbox");
enableFilteringOnTheRecommendedGiveawaysPageInput.setAttribute("class", "filterCheckbox");
enableFilteringOnTheRecommendedGiveawaysPageInput.checked = applyToRecommendedGiveawaysView;
enableFilteringOnTheRecommendedGiveawaysPageInput.onclick = function() {
// Upon value change
GM_setValue(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW, enableFilteringOnTheRecommendedGiveawaysPageInput.checked);
applyToRecommendedGiveawaysView = enableFilteringOnTheRecommendedGiveawaysPageInput.checked;
// Update the main UI
updateFilterCaption();
filterGiveaways();
};
flexGrowCenterDiv.appendChild(enableFilteringOnTheRecommendedGiveawaysPageInput);
// Create the third row in the filter details
var thirdRow = document.createElement("div");
thirdRow.setAttribute("class", "flexCenter");
thirdRow.appendChild(flexGrowCenterDiv);
// Create the row itself
var row = document.createElement("div");
var hr = document.createElement("hr");
row.setAttribute("class", "enableContainer markdown");
row.appendChild(firstRow);
row.appendChild(secondRow);
row.appendChild(thirdRow);
row.appendChild(hr);
return row;
}
// Creates a row with other options
function createFilterUiOtherOptionsRow() {
var removePagination = GM_getValue(KEY_REMOVE_PAGINATION, DEFAULT_REMOVE_PAGINATION);
var hideEnteredGiveaways = GM_getValue(KEY_HIDE_ENTERED_GIVEAWAYS, DEFAULT_HIDE_ENTERED_GIVEAWAYS);
// The "remove pagination" input checkbox
var removePaginationInput = document.createElement("input");
removePaginationInput.setAttribute("type", "checkbox");
removePaginationInput.setAttribute("class", "filterCheckbox");
removePaginationInput.checked = removePagination;
removePaginationInput.onclick = function() {
// Save the change and update the UI
GM_setValue(KEY_REMOVE_PAGINATION, removePaginationInput.checked);
filterGiveaways();
};
var removePaginationSpan = document.createElement("span");
removePaginationSpan.appendChild(document.createTextNode("Remove pagination"));
// Create and add the group GAs exclusion element
var flexGrowLeftDiv = document.createElement("div");
flexGrowLeftDiv.setAttribute("class", "flexCenter");
flexGrowLeftDiv.appendChild(removePaginationSpan);
flexGrowLeftDiv.appendChild(removePaginationInput);
// The "hide entered giveaways" input checkbox
var hideEnteredGiveawaysSelect = document.createElement("select");
for ( i = 0; i < HIDE_ENTERED_GIVEAWAYS_CONSTANTS.length; i++ ) {
var option = document.createElement('option');
option.value = option.textContent = HIDE_ENTERED_GIVEAWAYS_CONSTANTS[i];
hideEnteredGiveawaysSelect.appendChild(option);
}
hideEnteredGiveawaysSelect.value = hideEnteredGiveaways;
hideEnteredGiveawaysSelect.style.width = "75px";
hideEnteredGiveawaysSelect.style.marginLeft = "9px";
hideEnteredGiveawaysSelect.onchange = function() {
// Save the change and update the UI
var selectedValue = hideEnteredGiveawaysSelect.options[hideEnteredGiveawaysSelect.selectedIndex].value;
GM_setValue(KEY_HIDE_ENTERED_GIVEAWAYS, selectedValue);
filterGiveaways();
};
var hideEnteredGiveawaysSpan = document.createElement("span");
hideEnteredGiveawaysSpan.appendChild(document.createTextNode("Hide entered giveaways"));
var helpTooltip = document.createElement("div");
var tooltip = document.createElement("span");
tooltip.setAttribute("class", "sidebar__shortcut-tooltip-absolute tooltip");
tooltip.appendChild(document.createTextNode('"Yes" hides entered giveaways, although exclusions still apply. "Always" hides entered giveaways no matter the other filter options.'));
helpTooltip.setAttribute("class", "help-tip");
helpTooltip.appendChild(document.createTextNode("?"));
helpTooltip.appendChild(tooltip);
// Create and add the group GAs exclusion element
var flexGrowCenterDiv = document.createElement("div");
flexGrowCenterDiv.setAttribute("class", "flexCenter");
flexGrowCenterDiv.appendChild(hideEnteredGiveawaysSpan);
flexGrowCenterDiv.appendChild(helpTooltip);
flexGrowCenterDiv.appendChild(hideEnteredGiveawaysSelect);
// Create the row itself
var row = document.createElement("div");
row.setAttribute("class", "otherContainer flexCenter");
row.appendChild(flexGrowLeftDiv);
row.appendChild(flexGrowCenterDiv);
return row;
}
// Creates a row that hides the filter details
function createFilterUiHideFilterDetailsRow() {
var hideControlsDiv = document.createElement("div");
hideControlsDiv.id = FILTER_HIDE_ID;
hideControlsDiv.setAttribute("class", 'pinned-giveaways__inner-wrap sidebar__navigation__item__link');
hideControlsDiv.appendChild(document.createTextNode("Hide filter options"));
hideControlsDiv.onclick = function() {
// Hide the filter details
var filterDetails = document.getElementById(FILTER_DETAILS_ID);
if (filterDetails !== null) {
filterDetails.style.display = "none";
}
};
return hideControlsDiv;
}
function insertFilterUi(filterUi) {
// Insert into main giveaway UI
var elements = document.getElementsByClassName("pinned-giveaways__outer-wrap");
if (elements.length > 0) {
var parent = elements[0].parentElement;
parent.insertBefore(filterUi, parent.childNodes[2]);
return;
}
// Insert into the main giveaway UI if there are no pinned GAs
elements = document.getElementsByClassName("page__heading");
// Since "page__heading" is on multiple pages, a check needs to be done that user is on the correct page
if (document.getElementsByClassName("featured__container").length > 0 && elements.length > 0) {
var parent = elements[0].parentElement;
parent.insertBefore(filterUi, parent.childNodes[1]);
return;
}
// Insert into profile
elements = document.getElementsByClassName("page__heading");
// Since "page__heading" is on multiple pages, a check needs to be done that user is on the profile page
if (isCurrentPage(KEY_APPLY_TO_USER_PROFILE_VIEW) && elements.length > 0) {
var parent = elements[0].parentElement;
parent.insertBefore(filterUi, parent.childNodes[2]);
return;
}
}
// Updates filter caption in the UI
function updateFilterCaption() {
var filterCaptionDiv = document.getElementById(FILTER_CAPTION_ID);
filterCaptionDiv.innerHTML = getFilterCaption();
filterCaptionDiv.setAttribute("class", 'sidebar__navigation__item__name pinned-giveaways__inner-wrap sidebar__navigation__item__link');
updateFilterCaptionTextColor();
}
// Updates filter caption text color based on the current filtering status
function updateFilterCaptionTextColor() {
var filterCaptionDiv = document.getElementById(FILTER_CAPTION_ID);
if (isFilteringEnabledOnCurrentPage()) {
filterCaptionDiv.setAttribute("class", 'sidebar__navigation__item__name pinned-giveaways__inner-wrap sidebar__navigation__item__link');
} else {
filterCaptionDiv.setAttribute("class", 'sidebar__heading pinned-giveaways__inner-wrap sidebar__navigation__item__link');
}
}
// Creates the text for the filter caption
function getFilterCaption() {
var filterCaption = "Giveaway Filter";
if (!isFilteringEnabledOnCurrentPage()) {
return filterCaption;
}
// Add the level range to the caption
var minLevelToDisplay = GM_getValue(KEY_MIN_LEVEL_TO_DISPLAY, DEFAULT_MIN_LEVEL_TO_DISPLAY);
var maxLevelToDisplay = GM_getValue(KEY_MAX_LEVEL_TO_DISPLAY, DEFAULT_MAX_LEVEL_TO_DISPLAY);
filterCaption += " (Level " + minLevelToDisplay + "-" + maxLevelToDisplay;
// Add the maximal amount of entries to the caption
var enableFilteringByEntryCount = GM_getValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT);
if (enableFilteringByEntryCount) {
var maxNumberOfEntries = GM_getValue(KEY_MAX_NUMBER_OF_ENTRIES, 200);
filterCaption += ", Max " + maxNumberOfEntries + " entries";
}
// Add the points range to the caption
var minPointsToDisplay = GM_getValue(KEY_MIN_POINTS_TO_DISPLAY, DEFAULT_MIN_POINTS_TO_DISPLAY);
var maxPointsToDisplay = GM_getValue(KEY_MAX_POINTS_TO_DISPLAY, DEFAULT_MAX_POINTS_TO_DISPLAY);
filterCaption += ", " + minPointsToDisplay + "-" + maxPointsToDisplay + " Points";
// Add the excluded information to the caption
var excludeWhitelistGiveaways = GM_getValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS);
var excludeGroupGiveaways = GM_getValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, DEFAULT_EXCLUDE_GROUP_GIVEAWAYS);
var excludeRegionRestrictedGiveaways = GM_getValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS);
var excludePinnedGiveaways = GM_getValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, DEFAULT_EXCLUDE_PINNED_GIVEAWAYS);
var excluded = "";
if (excludeGroupGiveaways) {
excluded += "Group";
}
if (excludeWhitelistGiveaways) {
if (excluded !== "") {
excluded += "/";
}
excluded += "Whitelist";
}
if (excludePinnedGiveaways) {
if (excluded !== "") {
excluded += "/";
}
excluded += "Pinned";
}
if (excludeRegionRestrictedGiveaways) {
if (excluded !== "") {
excluded += "/";
}
excluded += "Regional";
}
if (excluded !== "") {
excluded = ", " + excluded + " GAs excluded";
}
filterCaption += excluded;
// Close it up and return
filterCaption += ")";
return filterCaption;
}
// Returns true if the character (its code) is a digit, false otherwise
function isDigit(charCode) {
return charCode >= 48 && charCode <= 57;
}
// Function handling execution after DOM has been changed - makes the filtering work in endless scrolling of SG++
var observeDOM = (function() {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
eventListenerSupported = window.addEventListener;
return function(obj, callback) {
if (MutationObserver) {
// Define a new observer
var obs = new MutationObserver(function(mutations, observer) {
if (mutations[0].addedNodes.length || mutations[0].removedNodes.length)
callback();
});
// Have the observer observe the registered element for changes in its children
obs.observe(obj, {
childList : true,
subtree : true
});
} else if (eventListenerSupported) {
obj.addEventListener('DOMNodeInserted', callback, false);
obj.addEventListener('DOMNodeRemoved', callback, false);
}
};
})();
// Register the filtering upon any changes on the whole page
observeDOM(document, function() {
filterGiveaways();
});
filterGiveaways();