SteamGifts script


SUBMITTED BY: Djarid

DATE: May 14, 2016, 9:45 p.m.

FORMAT: JavaScript

SIZE: 63.6 kB

HITS: 416

  1. // ==UserScript==
  2. // @name SteamGifts Filter
  3. // @description Giveaway filter
  4. // @author No Body
  5. // @include http://www.steamgifts.com/
  6. // @include http://www.steamgifts.com/giveaways*
  7. // @include http://www.steamgifts.com/user/*
  8. // @include https://www.steamgifts.com/
  9. // @include https://www.steamgifts.com/giveaways*
  10. // @include https://www.steamgifts.com/user/*
  11. // @version 0.1
  12. // @grant GM_getValue
  13. // @grant GM_setValue
  14. // ==/UserScript==
  15. // Keys for persistent settings, the keys for different views also represent "page keys" used as certain parameters to make things more simple
  16. var KEY_EXCLUDE_GROUP_GIVEAWAYS = "excludeGroupGiveaways";
  17. var KEY_EXCLUDE_WHITELIST_GIVEAWAYS = "excludeWhitelistGiveaways";
  18. var KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS = "excludeRegionalGiveaways"
  19. var KEY_EXCLUDE_PINNED_GIVEAWAYS = "excludePinnedGiveaways";
  20. var KEY_ENABLE_FILTERING_BY_ENTRY_COUNT = "enableFilteringByEntryCount";
  21. var KEY_MAX_NUMBER_OF_ENTRIES = "maxNumberOfEntries";
  22. var KEY_MIN_LEVEL_TO_DISPLAY = "minLevelToDisplay";
  23. var KEY_MAX_LEVEL_TO_DISPLAY = "maxLevelToDisplay";
  24. var KEY_MIN_POINTS_TO_DISPLAY = "minPointsToDisplay";
  25. var KEY_MAX_POINTS_TO_DISPLAY = "maxPointsToDisplay";
  26. var KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW = "applyToAllGiveawaysView";
  27. var KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW = "applyToGroupGiveawaysView";
  28. var KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW = "applyToWishlistGiveawaysView";
  29. var KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW = "applyToNewGiveawaysView";
  30. var KEY_APPLY_TO_USER_PROFILE_VIEW = "applyToUserProfileView";
  31. var KEY_APPLY_TO_SEARCH_RESULTS_VIEW = "applyToSearchResultsView";
  32. var KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW = "applyToRecommendedGiveawaysView";
  33. var KEY_REMOVE_PAGINATION = "removePagination";
  34. var KEY_HIDE_ENTERED_GIVEAWAYS = "hideEnteredGiveaways_2";
  35. var HIDE_ENTERED_GIVEAWAYS_CONSTANTS = ["No", "Yes", "Always"];
  36. // Default values of persistent settings
  37. var DEFAULT_EXCLUDE_GROUP_GIVEAWAYS = true;
  38. var DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS = true;
  39. var DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS = false;
  40. var DEFAULT_EXCLUDE_PINNED_GIVEAWAYS = false;
  41. var DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT = true;
  42. var DEFAULT_MAX_NUMBER_OF_ENTRIES = 200;
  43. var DEFAULT_MIN_LEVEL_TO_DISPLAY = 0;
  44. var DEFAULT_MAX_LEVEL_TO_DISPLAY = 10;
  45. var DEFAULT_MIN_POINTS_TO_DISPLAY = 0;
  46. var DEFAULT_MAX_POINTS_TO_DISPLAY = 150;
  47. var DEFAULT_APPLY_TO_ALL_GIVEAWAYS_VIEW = true;
  48. var DEFAULT_APPLY_TO_GROUP_GIVEAWAYS_VIEW = false;
  49. var DEFAULT_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW = false;
  50. var DEFAULT_APPLY_TO_NEW_GIVEAWAYS_VIEW = true;
  51. var DEFAULT_APPLY_TO_USER_PROFILE_VIEW = false;
  52. var DEFAULT_APPLY_TO_SEARCH_RESULTS_VIEW = false;
  53. var DEFAULT_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW = false;
  54. var DEFAULT_REMOVE_PAGINATION = true;
  55. var DEFAULT_HIDE_ENTERED_GIVEAWAYS = HIDE_ENTERED_GIVEAWAYS_CONSTANTS[0];
  56. // IDs of filter UI elements
  57. var FILTER_CONTROLS_ID = "filterControls";
  58. var FILTER_CAPTION_ID = "filterCaption";
  59. var FILTER_DETAILS_ID = "filterDetails";
  60. var FILTER_HIDE_ID = "filterHide";
  61. // Does all the filtering
  62. function filterGiveaways() {
  63. if (!isFilteringEnabledOnCurrentPage()) {
  64. // Since it's not enabled, remove any possible filtering
  65. var giveaways = getGiveaways();
  66. for ( i = 0; i < giveaways.length; i++) {
  67. removeFiltering(giveaways[i]);
  68. }
  69. handlePinnedBlock();
  70. return;
  71. }
  72. // Dirty hack to "fix" endless scrolling in SG++ when a lot of GAs on the same page got removed
  73. window.scrollBy(0, 1);
  74. window.scrollBy(0, -1);
  75. var minLevelToDisplay = GM_getValue(KEY_MIN_LEVEL_TO_DISPLAY, DEFAULT_MIN_LEVEL_TO_DISPLAY);
  76. var maxLevelToDisplay = GM_getValue(KEY_MAX_LEVEL_TO_DISPLAY, DEFAULT_MAX_LEVEL_TO_DISPLAY);
  77. var minPointsToDisplay = GM_getValue(KEY_MIN_POINTS_TO_DISPLAY, DEFAULT_MIN_POINTS_TO_DISPLAY);
  78. var maxPointsToDisplay = GM_getValue(KEY_MAX_POINTS_TO_DISPLAY, DEFAULT_MAX_POINTS_TO_DISPLAY);
  79. var excludeWhitelistGiveaways = GM_getValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS);
  80. var excludeGroupGiveaways = GM_getValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, DEFAULT_EXCLUDE_GROUP_GIVEAWAYS);
  81. var excludeRegionRestrictedGiveaways = GM_getValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS);
  82. var excludePinnedGiveaways = GM_getValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, DEFAULT_EXCLUDE_PINNED_GIVEAWAYS);
  83. var enableFilteringByEntryCount = GM_getValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT);
  84. var maxNumberOfEntries = GM_getValue(KEY_MAX_NUMBER_OF_ENTRIES, DEFAULT_MAX_NUMBER_OF_ENTRIES);
  85. var hideEnteredGiveaways = GM_getValue(KEY_HIDE_ENTERED_GIVEAWAYS, DEFAULT_HIDE_ENTERED_GIVEAWAYS);
  86. var giveawaysToRemove = [];
  87. var giveaways = getGiveaways();
  88. for ( i = 0; i < giveaways.length; i++) {
  89. // Remove the filtering
  90. removeFiltering(giveaways[i]);
  91. // Handle entered giveaways - ALWAYS option
  92. if (hideEnteredGiveaways === HIDE_ENTERED_GIVEAWAYS_CONSTANTS[2]) {
  93. if (isGiveawayEntered(giveaways[i])) {
  94. giveawaysToRemove.push(giveaways[i]);
  95. continue;
  96. }
  97. }
  98. // Handle whitelist giveaways
  99. if (excludeWhitelistGiveaways) {
  100. if (isGiveawayFromWhitelist(giveaways[i])) {
  101. continue;
  102. }
  103. }
  104. // Handle group giveaways
  105. if (excludeGroupGiveaways) {
  106. if (isGiveawayFromGroup(giveaways[i])) {
  107. continue;
  108. }
  109. }
  110. // Handle pinned giveaways
  111. if (excludePinnedGiveaways) {
  112. if (isGiveawayPinned(giveaways[i])) {
  113. continue;
  114. }
  115. }
  116. // Handle region-restricted giveaways
  117. if (excludeRegionRestrictedGiveaways) {
  118. if (isGiveawayRegionRestricted(giveaways[i])) {
  119. continue;
  120. }
  121. }
  122. // Handle entered giveaways - YES option
  123. if (hideEnteredGiveaways === HIDE_ENTERED_GIVEAWAYS_CONSTANTS[1]) {
  124. if (isGiveawayEntered(giveaways[i])) {
  125. giveawaysToRemove.push(giveaways[i]);
  126. continue;
  127. }
  128. }
  129. // Evaluate the contributor level
  130. var contributorLevel = getContributorLevel(giveaways[i]);
  131. if (contributorLevel < minLevelToDisplay || contributorLevel > maxLevelToDisplay) {
  132. giveawaysToRemove.push(giveaways[i]);
  133. continue;
  134. }
  135. // Evaluate the points
  136. var points = getPoints(giveaways[i]);
  137. if (points < minPointsToDisplay || points > maxPointsToDisplay) {
  138. giveawaysToRemove.push(giveaways[i]);
  139. continue;
  140. }
  141. // Handle entry-count filtering
  142. if (enableFilteringByEntryCount) {
  143. var numberOfEntries = getNumberOfEntries(giveaways[i]);
  144. if (numberOfEntries > maxNumberOfEntries) {
  145. giveawaysToRemove.push(giveaways[i]);
  146. continue;
  147. }
  148. }
  149. }
  150. // Remove the giveaways
  151. for ( i = 0; i < giveawaysToRemove.length; i++) {
  152. giveawaysToRemove[i].style.display = "none";
  153. }
  154. // Handle the pinned giveaways block
  155. handlePinnedBlock();
  156. handlePagination();
  157. // Dirty hack to "fix" endless scrolling in SG++ when a lot of GAs on the same page got removed
  158. window.scrollBy(0, 1);
  159. window.scrollBy(0, -1);
  160. }
  161. // Parses the giveaway elements from the whole page
  162. function getGiveaways() {
  163. var giveawaysSgpp = document.getElementsByClassName("SGPP__gridTile");
  164. var giveaways = document.getElementsByClassName("giveaway__row-outer-wrap");
  165. var allGiveaways = [];
  166. allGiveaways.push.apply(allGiveaways, giveawaysSgpp);
  167. allGiveaways.push.apply(allGiveaways, giveaways);
  168. return allGiveaways;
  169. }
  170. // Returns true if the giveaway is for a whitelist, false otherwise
  171. function isGiveawayFromWhitelist(giveaway) {
  172. return giveaway.getElementsByClassName("giveaway__column--whitelist").length > 0;
  173. }
  174. // Returns true if the giveaway is for a group, false otherwise
  175. function isGiveawayFromGroup(giveaway) {
  176. return giveaway.getElementsByClassName("giveaway__column--group").length > 0;
  177. }
  178. // Returns true if the giveaway is region-restricted, false otherwise
  179. function isGiveawayRegionRestricted(giveaway) {
  180. return giveaway.getElementsByClassName("giveaway__column--region-restricted").length > 0;
  181. }
  182. // Returns true if the giveaway is pinned, false otherwise
  183. function isGiveawayPinned(giveaway) {
  184. var outerParent = giveaway.parentElement.parentElement;
  185. return outerParent.className === "pinned-giveaways__outer-wrap";
  186. }
  187. function isGiveawayEntered(giveaway) {
  188. return giveaway.getElementsByClassName("giveaway__row-inner-wrap is-faded").length > 0 ||
  189. giveaway.className === "SGPP__gridTile is-faded";
  190. }
  191. // Returns the contributor level of a giveaway, return 0 if no level is specified
  192. function getContributorLevel(giveaway) {
  193. var contributorLevels = [];
  194. var contributorLevelsPositive = giveaway.getElementsByClassName("giveaway__column--contributor-level giveaway__column--contributor-level--positive");
  195. var contributorLevelsNegative = giveaway.getElementsByClassName("giveaway__column--contributor-level giveaway__column--contributor-level--negative");
  196. contributorLevels.push.apply(contributorLevels, contributorLevelsPositive);
  197. contributorLevels.push.apply(contributorLevels, contributorLevelsNegative);
  198. if (contributorLevels.length === 0) {
  199. return 0;
  200. }
  201. var contributorLevel = contributorLevels[0].innerHTML;
  202. var substringStart = 0;
  203. // Remove the "Level " at the start of the string, if present (SG++ grid view doesn't have it)
  204. if (contributorLevel.indexOf("Level ") === 0) {
  205. substringStart = 6;
  206. }
  207. // Parse the level, remove the "+" from the end
  208. var level = contributorLevel.substring(substringStart, contributorLevel.length - 1);
  209. return parseInt(level);
  210. }
  211. // Returns the points of a giveaway
  212. function getPoints(giveaway) {
  213. var pointsEle = giveaway.getElementsByClassName("giveaway__heading__thin");
  214. // Since the points are the last element in a giveaway, just take the last item if available
  215. if (pointsEle.length > 0) {
  216. var pointsTxt = pointsEle[pointsEle.length-1].innerHTML;
  217. var substringStart = 0;
  218. // Remove the "(" at the start of the string, if present (SG++ grid view doesn't have it)
  219. if (pointsTxt.indexOf("(") === 0) {
  220. substringStart = 1;
  221. }
  222. // Parse the points, remove the "P)" from the end
  223. var points = pointsTxt.substring(substringStart, pointsTxt.length - 2);
  224. return parseInt(points);
  225. }
  226. // SG++ GridView
  227. pointsEle = giveaway.getElementsByClassName("SGPP__gridTileInfo global__image-outer-wrap");
  228. if (pointsEle.length > 0) {
  229. // 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
  230. var pointsTxt = pointsEle[0].children[2].children[1].children[0].innerHTML;
  231. // Parse the points, remove the "P" from the end
  232. var points = pointsTxt.substring(0, pointsTxt.length - 1);
  233. return parseInt(points);
  234. }
  235. // If nothing could be parsed, return 0
  236. return 0;
  237. }
  238. // Parses the number of entries for a giveaway
  239. function getNumberOfEntries(giveaway) {
  240. // Parse from SGv2 layout
  241. var spanElements = giveaway.getElementsByTagName("span");
  242. for ( j = 0; j < spanElements.length; j++) {
  243. if (spanElements[j].innerHTML.indexOf("entr") != -1) {
  244. return parseInt(spanElements[j].innerHTML.substring(0, spanElements[j].innerHTML.indexOf(" ")).replace(",", ""));
  245. }
  246. }
  247. // Parse from SG++ grid layout
  248. var divElements = giveaway.getElementsByTagName("div");
  249. for ( j = 0; j < divElements.length; j++) {
  250. if (divElements[j].style.cssFloat == "left" && divElements[j].innerHTML.indexOf("ntr") != -1) {
  251. var strongElements = divElements[j].getElementsByTagName("strong");
  252. // Just pick first, there is only one anyway
  253. if (strongElements.length > 0) {
  254. return parseInt(strongElements[0].innerHTML.replace(",", ""));
  255. }
  256. }
  257. }
  258. }
  259. // Removes filtering from a given giveaway
  260. function removeFiltering(giveaway) {
  261. giveaway.style.display = "";
  262. }
  263. // Hides the pinned block completely if all the giveaways got filtered, shows it if it contains at least one giveaway
  264. function handlePinnedBlock() {
  265. var pinnedBlocks = document.getElementsByClassName("pinned-giveaways__outer-wrap");
  266. // No pinned giveaways
  267. if (pinnedBlocks.length === 0) {
  268. return;
  269. }
  270. var pinnedGiveaways = pinnedBlocks[0].getElementsByClassName("giveaway__row-outer-wrap");
  271. var giveawayRemaining = false;
  272. for ( i = 0; i < pinnedGiveaways.length; i++) {
  273. if (pinnedGiveaways[i].style.display !== "none") {
  274. giveawayRemaining = true;
  275. break;
  276. }
  277. }
  278. if (giveawayRemaining) {
  279. pinnedBlocks[0].style.display = "";
  280. } else {
  281. pinnedBlocks[0].style.display = "none";
  282. }
  283. }
  284. var giveawayOrder = 1;
  285. // Handles the pagination. Moves the GAs in SG++ grid layout into one grid if pagination should be removed
  286. function handlePagination() {
  287. var removePagination = GM_getValue(KEY_REMOVE_PAGINATION, DEFAULT_REMOVE_PAGINATION);
  288. // Handle the pagination itself, leave the last pagination element in place (the magical -2 in the loop condition)
  289. var paginationDivs = document.getElementsByClassName("table__heading");
  290. for ( i = 0; i < paginationDivs.length - 2; i++) {
  291. if (removePagination) {
  292. paginationDivs[i].style.display = "none";
  293. } else {
  294. paginationDivs[i].style.display = "";
  295. }
  296. }
  297. // GAs should be moved to the first gridview if using the SG++ GA grid view
  298. var sgppGridviews = document.getElementsByClassName("SGPP__gridView");
  299. if (sgppGridviews.length > 0) {
  300. // Tag the giveaways
  301. for ( i = 0; i < sgppGridviews.length; i++) {
  302. var sgppGiveawayDivs = sgppGridviews[i].getElementsByClassName("SGPP__gridTile");
  303. var pageNumber = getSgppPageNumber(sgppGridviews[i]);
  304. for ( j = 0; j < sgppGiveawayDivs.length; j++) {
  305. if (sgppGiveawayDivs[j].dataset.originalPage === undefined) {
  306. sgppGiveawayDivs[j].dataset.originalPage = pageNumber;
  307. }
  308. if (sgppGiveawayDivs[j].dataset.order === undefined) {
  309. sgppGiveawayDivs[j].dataset.order = giveawayOrder++;
  310. }
  311. }
  312. }
  313. var sgppFirstGridview = sgppGridviews[0];
  314. for ( i = 0; i < sgppGridviews.length; i++) {
  315. if(getSgppPageNumber(sgppGridviews[i]) === 1) {
  316. sgppFirstGridview = sgppGridviews[i];
  317. break;
  318. }
  319. }
  320. if (removePagination) {
  321. // Move the GAs in SG++ grid layout to the first grid
  322. for ( i = 1; i < sgppGridviews.length; i++) {
  323. var currentGridview = sgppGridviews[i];
  324. var sgppGiveawayDivs = currentGridview.getElementsByClassName("SGPP__gridTile");
  325. for ( j = 0; j < sgppGiveawayDivs.length; j++) {
  326. var sgppGiveawayDiv = sgppGiveawayDivs[j];
  327. currentGridview.removeChild(sgppGiveawayDiv);
  328. insertGiveawayIntoGridview(sgppGiveawayDiv, sgppFirstGridview);
  329. }
  330. }
  331. } else {
  332. // Move the GAs back from the first grid to their respective page grids
  333. var sgppGiveawayDivs = sgppFirstGridview.getElementsByClassName("SGPP__gridTile");
  334. for ( i = 0; i < sgppGiveawayDivs.length; i++) {
  335. var sgppGiveawayDiv = sgppGiveawayDivs[i];
  336. var originalPage = parseInt(sgppGiveawayDiv.dataset.originalPage);
  337. if (originalPage > 1) {
  338. sgppFirstGridview.removeChild(sgppGiveawayDiv);
  339. for ( j = 0; j < sgppGridviews.length; j++) {
  340. var pageNumber = getSgppPageNumber(sgppGridviews[j]);
  341. if (pageNumber === originalPage) {
  342. insertGiveawayIntoGridview(sgppGiveawayDiv, sgppGridviews[j]);
  343. break;
  344. }
  345. }
  346. }
  347. }
  348. }
  349. }
  350. }
  351. // Determines the page number from SG++ grid view
  352. function getSgppPageNumber(sgppGridview) {
  353. var currentPage = sgppGridview.previousElementSibling.getElementsByClassName("endless_page")[0].innerHTML;
  354. var pageNumber = parseInt(currentPage.substring(5, currentPage.indexOf(" ", 6)));
  355. return pageNumber;
  356. }
  357. // Inserts a GA into specified gridview based on its dataset.order value
  358. function insertGiveawayIntoGridview(giveaway, gridview) {
  359. var sgppSortedGiveawayDivs = gridview.getElementsByClassName("SGPP__gridTile");
  360. var inserted = false;
  361. for ( i = 0; i < sgppSortedGiveawayDivs.length; i++) {
  362. if (parseInt(sgppSortedGiveawayDivs[i].dataset.order) > parseInt(giveaway.dataset.order)) {
  363. gridview.insertBefore(giveaway, sgppSortedGiveawayDivs[i]);
  364. inserted = true;
  365. break;
  366. }
  367. }
  368. if (!inserted) {
  369. gridview.appendChild(giveaway);
  370. }
  371. }
  372. // Returns true if filtering is enabled on the current page, false otherwise
  373. function isFilteringEnabledOnCurrentPage() {
  374. var applyToAllGiveawaysView = GM_getValue(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_ALL_GIVEAWAYS_VIEW);
  375. var applyToGroupGiveawaysView = GM_getValue(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_GROUP_GIVEAWAYS_VIEW);
  376. var applyToWishlistGiveawaysView = GM_getValue(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW);
  377. var applyToNewGiveawaysView = GM_getValue(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_NEW_GIVEAWAYS_VIEW);
  378. var applyToUserProfileView = GM_getValue(KEY_APPLY_TO_USER_PROFILE_VIEW, DEFAULT_APPLY_TO_USER_PROFILE_VIEW);
  379. var applyToSearchResultsView = GM_getValue(KEY_APPLY_TO_SEARCH_RESULTS_VIEW, DEFAULT_APPLY_TO_SEARCH_RESULTS_VIEW);
  380. var applyToRecommendedView = GM_getValue(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW);
  381. if (applyToAllGiveawaysView && isCurrentPage(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW)) {
  382. return true;
  383. }
  384. if (applyToGroupGiveawaysView && isCurrentPage(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW)) {
  385. return true;
  386. }
  387. if (applyToWishlistGiveawaysView && isCurrentPage(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW)) {
  388. return true;
  389. }
  390. if (applyToUserProfileView && isCurrentPage(KEY_APPLY_TO_USER_PROFILE_VIEW)) {
  391. return true;
  392. }
  393. if (applyToNewGiveawaysView && isCurrentPage(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW)) {
  394. return true;
  395. }
  396. if (applyToSearchResultsView && isCurrentPage(KEY_APPLY_TO_SEARCH_RESULTS_VIEW)) {
  397. return true;
  398. }
  399. if (applyToRecommendedView && isCurrentPage(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW)) {
  400. return true;
  401. }
  402. return false;
  403. }
  404. function isCurrentPage(pageKey) {
  405. var currentPage = window.location.href;
  406. if (pageKey === KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW) {
  407. return (currentPage.indexOf("https://www.steamgifts.com/giveaways/search?page=") === 0
  408. || currentPage === "https://www.steamgifts.com" || currentPage === "https://www.steamgifts.com/"
  409. || currentPage === "https://www.steamgifts.com/giveaways"
  410. || currentPage.indexOf("http://www.steamgifts.com/giveaways/search?page=") === 0
  411. || currentPage === "http://www.steamgifts.com" || currentPage === "https://www.steamgifts.com/"
  412. || currentPage === "http://www.steamgifts.com/giveaways");
  413. }
  414. if (pageKey === KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW) {
  415. return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=group") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=group") === 0);
  416. }
  417. if (pageKey === KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW) {
  418. return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=wishlist") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=wishlist") === 0);
  419. }
  420. if (pageKey === KEY_APPLY_TO_USER_PROFILE_VIEW) {
  421. return (currentPage.indexOf("http://www.steamgifts.com/user/") === 0 || currentPage.indexOf("https://www.steamgifts.com/user/") === 0);
  422. }
  423. if (pageKey === KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW) {
  424. return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=new") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=new") === 0);
  425. }
  426. if (pageKey === KEY_APPLY_TO_SEARCH_RESULTS_VIEW) {
  427. return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?q") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?q") === 0);
  428. }
  429. if (pageKey === KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW) {
  430. return (currentPage.indexOf("http://www.steamgifts.com/giveaways/search?type=recommended") === 0 || currentPage.indexOf("https://www.steamgifts.com/giveaways/search?type=recommended") === 0);
  431. }
  432. return false;
  433. }
  434. // Draws the filter UI into the SG page
  435. (function drawUi() {
  436. // Create the filter details element and add content to it
  437. var detailsContentDiv = document.createElement("div");
  438. detailsContentDiv.setAttribute("class", 'pinned-giveaways__inner-wrap filterDetails');
  439. detailsContentDiv.appendChild(createFilterUiFilterOptionsRow());
  440. detailsContentDiv.appendChild(createFilterUiExcludeOptionsRow());
  441. detailsContentDiv.appendChild(createFilterUiEnabledPagesRow());
  442. detailsContentDiv.appendChild(createFilterUiOtherOptionsRow());
  443. var detailsDiv = document.createElement("div");
  444. detailsDiv.id = FILTER_DETAILS_ID;
  445. detailsDiv.style.display = "none";
  446. detailsDiv.appendChild(detailsContentDiv);
  447. detailsDiv.appendChild(createFilterUiHideFilterDetailsRow());
  448. // Create the filter UI element
  449. var controlsDiv = document.createElement("div");
  450. controlsDiv.setAttribute("id", FILTER_CONTROLS_ID);
  451. controlsDiv.setAttribute("class", 'pinned-giveaways__inner-wrap');
  452. controlsDiv.appendChild(createFilterUiCaptionRow());
  453. controlsDiv.appendChild(detailsDiv);
  454. // Add the filter UI to the correct place on the current page
  455. insertFilterUi(controlsDiv);
  456. updateFilterCaptionTextColor();
  457. // Append Stylesheet
  458. var filterCss = '.giveaway__row-outer-wrap[data-gridview*="sgpp_gridview"] {display: none;}\
  459. .filterDetails {margin: -1px -14px !important; border-radius: 0px !important;}\
  460. #filterDetails span {padding: 0 5px; font-size: 12px;}\
  461. #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;}\
  462. #filterHide {border-top-right-radius: 0px; border-top-left-radius: 0px; margin: 1px -14px -1px; padding: 5px 0px; justify-content: center; cursor: pointer;}\
  463. #filterControls {margin-bottom: 5px; background-image: none;}\
  464. #filterControls select, #filterControls input {padding: 2px 4px;}\
  465. #filterHide.sidebar__navigation__item__link, #filterHide.sidebar__navigation__item__link:hover {border-top: none;}\
  466. .filterCheckbox {width: 13px; margin: 5px;}\
  467. .filterNumberInput {margin: 5px 0;}\
  468. .enableContainer, .excludeContainer {margin-top: 3px;}\
  469. .enableContainer.markdown hr, .excludeContainer.markdown hr, .filteringContainer.markdown hr {margin: 0px;}\
  470. .otherContainer {padding: 5px 0;}\
  471. .filteringContainer{padding-top: 1px;}\
  472. .flexLeft {display: flex; align-items: center; justify-content: flex-start; flex-grow: 1; flex-basis: 0px;}\
  473. .flexCenter {display: flex; align-items: center; justify-content: center; flex-grow: 1; flex-basis: 0px; margin-top: -1px;}\
  474. .flexRight {display: flex; align-items: center; justify-content: flex-end; flex-grow: 1; flex-basis: 0px;}\
  475. .help-tip {text-align: center; border-style: dotted; border-width: 1px; margin-left: 2px; margin-right: -5px; padding: 1px; cursor: help;}\
  476. .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); }\
  477. .sidebar__shortcut-tooltip-absolute, .table__row-outer-wrap {color:inherit;}\
  478. .help-tip:hover .sidebar__shortcut-tooltip-absolute.tooltip {display: block;}';
  479. var style = document.createElement('style');
  480. if (style.styleSheet) {
  481. style.styleSheet.cssText = filterCss;
  482. } else {
  483. style.appendChild(document.createTextNode(filterCss));
  484. }
  485. document.getElementsByTagName('head')[0].appendChild(style);
  486. })();
  487. // Creates the top-level caption that is visible all the time on a giveaway page
  488. function createFilterUiCaptionRow() {
  489. var filterOptionsCaption = document.createElement("div");
  490. filterOptionsCaption.id = FILTER_CAPTION_ID;
  491. filterOptionsCaption.appendChild(document.createTextNode(getFilterCaption()));
  492. filterOptionsCaption.onclick = function() {
  493. // Clicking on the caption opens/closes the filter details UI
  494. var detailsDiv = document.getElementById(FILTER_DETAILS_ID);
  495. if (detailsDiv.style.display === "") {
  496. detailsDiv.style.display = "none";
  497. } else {
  498. detailsDiv.style.display = "";
  499. }
  500. };
  501. return filterOptionsCaption;
  502. }
  503. // Creates the row with filtering options (level, number of entries, ...)
  504. function createFilterUiFilterOptionsRow() {
  505. var minLevelToDisplay = GM_getValue(KEY_MIN_LEVEL_TO_DISPLAY, DEFAULT_MIN_LEVEL_TO_DISPLAY);
  506. var maxLevelToDisplay = GM_getValue(KEY_MAX_LEVEL_TO_DISPLAY, DEFAULT_MAX_LEVEL_TO_DISPLAY);
  507. var minPointsToDisplay = GM_getValue(KEY_MIN_POINTS_TO_DISPLAY, DEFAULT_MIN_POINTS_TO_DISPLAY);
  508. var maxPointsToDisplay = GM_getValue(KEY_MAX_POINTS_TO_DISPLAY, DEFAULT_MAX_POINTS_TO_DISPLAY);
  509. var enableFilteringByEntryCount = GM_getValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT);
  510. var maxNumberOfEntries = GM_getValue(KEY_MAX_NUMBER_OF_ENTRIES, DEFAULT_MAX_NUMBER_OF_ENTRIES);
  511. // The "minimal level to display" number input
  512. var minLevelToDisplayInput = document.createElement("input");
  513. minLevelToDisplayInput.setAttribute("type", "number");
  514. minLevelToDisplayInput.setAttribute("maxLength", "2");
  515. minLevelToDisplayInput.setAttribute("class", "filterNumberInput");
  516. minLevelToDisplayInput.style.width = "55px";
  517. minLevelToDisplayInput.value = minLevelToDisplay;
  518. minLevelToDisplayInput.onchange = function() {
  519. // Filter out invalid values
  520. var minLevelToDisplayInputValue = parseInt(minLevelToDisplayInput.value);
  521. if (minLevelToDisplayInputValue < DEFAULT_MIN_LEVEL_TO_DISPLAY) {
  522. minLevelToDisplayInput.value = DEFAULT_MIN_LEVEL_TO_DISPLAY;
  523. } else if (minLevelToDisplayInputValue > maxLevelToDisplay) {
  524. minLevelToDisplayInput.value = maxLevelToDisplay;
  525. }
  526. // If the value changed, save it and update the UI
  527. if (minLevelToDisplay != minLevelToDisplayInput.value) {
  528. GM_setValue(KEY_MIN_LEVEL_TO_DISPLAY, minLevelToDisplayInput.value);
  529. minLevelToDisplay = minLevelToDisplayInput.value;
  530. updateFilterCaption();
  531. filterGiveaways();
  532. }
  533. };
  534. // Accept only digits
  535. minLevelToDisplayInput.onkeypress = function(event) {
  536. return isDigit(event.charCode);
  537. };
  538. // The "maximal level to display" number input
  539. var maxLevelToDisplayInput = document.createElement("input");
  540. maxLevelToDisplayInput.setAttribute("type", "number");
  541. maxLevelToDisplayInput.setAttribute("maxLength", "2");
  542. maxLevelToDisplayInput.style.width = "55px";
  543. maxLevelToDisplayInput.value = maxLevelToDisplay;
  544. maxLevelToDisplayInput.onchange = function() {
  545. // Filter out invalid values
  546. var maxLevelToDisplayInputValue = parseInt(maxLevelToDisplayInput.value);
  547. if (maxLevelToDisplayInputValue > DEFAULT_MAX_LEVEL_TO_DISPLAY) {
  548. maxLevelToDisplayInput.value = DEFAULT_MAX_LEVEL_TO_DISPLAY;
  549. } else if (maxLevelToDisplayInputValue < minLevelToDisplay) {
  550. maxLevelToDisplayInput.value = minLevelToDisplay;
  551. }
  552. // If the value changed, save it and update the UI
  553. if (maxLevelToDisplay != maxLevelToDisplayInput.value) {
  554. GM_setValue(KEY_MAX_LEVEL_TO_DISPLAY, maxLevelToDisplayInput.value);
  555. maxLevelToDisplay = maxLevelToDisplayInput.value;
  556. updateFilterCaption();
  557. filterGiveaways();
  558. }
  559. };
  560. // Accept only digits
  561. maxLevelToDisplayInput.onkeypress = function(event) {
  562. return isDigit(event.charCode);
  563. };
  564. // Create and add the level filter
  565. var showLevelSpan = document.createElement("span");
  566. showLevelSpan.appendChild(document.createTextNode("Show level:"));
  567. var levelDashSpan = document.createElement("span");
  568. levelDashSpan.appendChild(document.createTextNode("-"));
  569. var flexGrowLeftDiv = document.createElement("div");
  570. flexGrowLeftDiv.setAttribute("class", "flexLeft");
  571. flexGrowLeftDiv.appendChild(showLevelSpan);
  572. flexGrowLeftDiv.appendChild(minLevelToDisplayInput);
  573. flexGrowLeftDiv.appendChild(levelDashSpan);
  574. flexGrowLeftDiv.appendChild(maxLevelToDisplayInput);
  575. // The "minimal points to display" number input
  576. var minPointsToDisplayInput = document.createElement("input");
  577. minPointsToDisplayInput.setAttribute("type", "number");
  578. minPointsToDisplayInput.setAttribute("maxLength", "3");
  579. minPointsToDisplayInput.style.width = "62px";
  580. minPointsToDisplayInput.value = minPointsToDisplay;
  581. minPointsToDisplayInput.onchange = function() {
  582. // Filter out invalid values
  583. var minPointsToDisplayInputValue = parseInt(minPointsToDisplayInput.value);
  584. if (minPointsToDisplayInputValue < DEFAULT_MIN_POINTS_TO_DISPLAY) {
  585. minPointsToDisplayInput.value = DEFAULT_MIN_POINTS_TO_DISPLAY;
  586. } else if (minPointsToDisplayInputValue > maxPointsToDisplay) {
  587. minPointsToDisplayInput.value = maxPointsToDisplay;
  588. }
  589. // If the value changed, save it and update the UI
  590. if (minPointsToDisplay != minPointsToDisplayInput.value) {
  591. GM_setValue(KEY_MIN_POINTS_TO_DISPLAY, minPointsToDisplayInput.value);
  592. minPointsToDisplay = minPointsToDisplayInput.value;
  593. updateFilterCaption();
  594. filterGiveaways();
  595. }
  596. };
  597. // Accept only digits
  598. minPointsToDisplayInput.onkeypress = function(event) {
  599. return isDigit(event.charCode);
  600. };
  601. // The "maximal level to display" number input
  602. var maxPointsToDisplayInput = document.createElement("input");
  603. maxPointsToDisplayInput.setAttribute("type", "number");
  604. maxPointsToDisplayInput.setAttribute("maxLength", "3");
  605. maxPointsToDisplayInput.style.width = "62px";
  606. maxPointsToDisplayInput.value = maxPointsToDisplay;
  607. maxPointsToDisplayInput.onchange = function() {
  608. // Filter out invalid values
  609. var maxPointsToDisplayInputValue = parseInt(maxPointsToDisplayInput.value);
  610. if (maxPointsToDisplayInputValue > DEFAULT_MAX_POINTS_TO_DISPLAY) {
  611. maxPointsToDisplayInput.value = DEFAULT_MAX_POINTS_TO_DISPLAY;
  612. } else if (maxPointsToDisplayInputValue < minPointsToDisplay) {
  613. maxPointsToDisplayInput.value = minPointsToDisplay;
  614. }
  615. // If the value changed, save it and update the UI
  616. if (maxPointsToDisplay != maxPointsToDisplayInput.value) {
  617. GM_setValue(KEY_MAX_POINTS_TO_DISPLAY, maxPointsToDisplayInput.value);
  618. maxPointsToDisplay = maxPointsToDisplayInput.value;
  619. updateFilterCaption();
  620. filterGiveaways();
  621. }
  622. };
  623. // Accept only digits
  624. maxPointsToDisplayInput.onkeypress = function(event) {
  625. return isDigit(event.charCode);
  626. };
  627. // Create and add the points filter
  628. var showPointsSpan = document.createElement("span");
  629. showPointsSpan.appendChild(document.createTextNode("Points to enter:"));
  630. var pointsDashSpan = document.createElement("span");
  631. pointsDashSpan.appendChild(document.createTextNode("-"));
  632. var flexGrowCenterDiv = document.createElement("div");
  633. flexGrowCenterDiv.setAttribute("class", "flexCenter");
  634. flexGrowCenterDiv.appendChild(showPointsSpan);
  635. flexGrowCenterDiv.appendChild(minPointsToDisplayInput);
  636. flexGrowCenterDiv.appendChild(pointsDashSpan);
  637. flexGrowCenterDiv.appendChild(maxPointsToDisplayInput);
  638. // The "enable filtering by entry count" input checkbox
  639. var enableFilteringByEntryCountInput = document.createElement("input");
  640. enableFilteringByEntryCountInput.setAttribute("type", "checkbox");
  641. enableFilteringByEntryCountInput.setAttribute("class", "filterCheckbox");
  642. enableFilteringByEntryCountInput.checked = enableFilteringByEntryCount;
  643. enableFilteringByEntryCountInput.onclick = function() {
  644. // Upon value change, enable and recolor the entry count input
  645. GM_setValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, enableFilteringByEntryCountInput.checked);
  646. maxNumberOfEntriesInput.disabled = !enableFilteringByEntryCountInput.checked;
  647. maxNumberOfEntriesInput.readOnly = !enableFilteringByEntryCountInput.checked;
  648. if (!enableFilteringByEntryCountInput.checked) {
  649. maxNumberOfEntriesInput.style.opacity = "0.4";
  650. } else {
  651. maxNumberOfEntriesInput.style.opacity = maxNumberOfEntriesInputOriginalOpacity;
  652. maxNumberOfEntriesInput.style.opacity = "1";
  653. }
  654. // Update the main UI
  655. updateFilterCaption();
  656. filterGiveaways();
  657. };
  658. // The "maximal number of entries" number input
  659. var maxNumberOfEntriesInput = document.createElement("input");
  660. maxNumberOfEntriesInput.setAttribute("type", "number");
  661. maxNumberOfEntriesInput.setAttribute("maxLength", "6");
  662. maxNumberOfEntriesInput.style.width = "90px";
  663. maxNumberOfEntriesInput.disabled = !enableFilteringByEntryCount;
  664. maxNumberOfEntriesInput.value = maxNumberOfEntries;
  665. maxNumberOfEntriesInput.readOnly = !enableFilteringByEntryCount;
  666. maxNumberOfEntriesInput.onchange = function() {
  667. // Limit the entry count filter to 1000000, should be enough for a while
  668. if (maxNumberOfEntriesInput.value < 0 || maxNumberOfEntriesInput.value > 1000000) {
  669. maxNumberOfEntriesInput.value = maxNumberOfEntries;
  670. } else if (maxNumberOfEntries != maxNumberOfEntriesInput.value) {
  671. // If the value changed, save it and update the UI
  672. GM_setValue(KEY_MAX_NUMBER_OF_ENTRIES, maxNumberOfEntriesInput.value);
  673. maxNumberOfEntries = maxNumberOfEntriesInput.value;
  674. updateFilterCaption();
  675. filterGiveaways();
  676. return;
  677. }
  678. };
  679. // Accept only digits
  680. maxNumberOfEntriesInput.onkeypress = function(event) {
  681. return isDigit(event.charCode);
  682. };
  683. var maxNumberOfEntriesInputOriginalOpacity = maxNumberOfEntriesInput.style.opacity;
  684. // Gray out the input text if disabled
  685. if (!enableFilteringByEntryCount) {
  686. maxNumberOfEntriesInput.style.opacity = "0.4";
  687. }
  688. // Create and add the entry count filter
  689. var entryFilteringEnabledSpan = document.createElement("span");
  690. entryFilteringEnabledSpan.appendChild(document.createTextNode("Entry count filtering"));
  691. var entryFilteringCountSpan = document.createElement("span");
  692. entryFilteringCountSpan.appendChild(document.createTextNode("Max # of entries:"));
  693. var flexGrowRightDiv = document.createElement("div");
  694. flexGrowRightDiv.setAttribute("class", "flexRight");
  695. flexGrowRightDiv.appendChild(entryFilteringEnabledSpan);
  696. flexGrowRightDiv.appendChild(enableFilteringByEntryCountInput);
  697. flexGrowRightDiv.appendChild(entryFilteringCountSpan);
  698. flexGrowRightDiv.appendChild(maxNumberOfEntriesInput);
  699. // Create the row itself
  700. var firstRow = document.createElement("div");
  701. firstRow.setAttribute("class", "flexCenter");
  702. firstRow.appendChild(flexGrowLeftDiv);
  703. firstRow.appendChild(flexGrowCenterDiv);
  704. firstRow.appendChild(flexGrowRightDiv);
  705. var row = document.createElement("div");
  706. var hr = document.createElement("hr");
  707. row.setAttribute("class", 'filteringContainer markdown');
  708. row.appendChild(firstRow);
  709. row.appendChild(hr);
  710. return row;
  711. }
  712. // Creates a row with the "exclude" options
  713. function createFilterUiExcludeOptionsRow() {
  714. var excludeWhitelistGiveaways = GM_getValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS);
  715. var excludeGroupGiveaways = GM_getValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, DEFAULT_EXCLUDE_GROUP_GIVEAWAYS);
  716. var excludePinnedGiveaways = GM_getValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, DEFAULT_EXCLUDE_PINNED_GIVEAWAYS);
  717. var excludeRegionRestrictedGiveaways = GM_getValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS);
  718. // The "exlude group GAs" input checkbox
  719. var excludeGroupGiveawaysInput = document.createElement("input");
  720. excludeGroupGiveawaysInput.setAttribute("type", "checkbox");
  721. excludeGroupGiveawaysInput.setAttribute("class", "filterCheckbox");
  722. excludeGroupGiveawaysInput.checked = excludeGroupGiveaways;
  723. excludeGroupGiveawaysInput.onclick = function() {
  724. // Save the change and update the UI
  725. GM_setValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, excludeGroupGiveawaysInput.checked);
  726. updateFilterCaption();
  727. filterGiveaways();
  728. };
  729. var excludeGroupGiveawaysSpan = document.createElement("span");
  730. excludeGroupGiveawaysSpan.appendChild(document.createTextNode("Exclude group giveaways"));
  731. // Create and add the group GAs exclusion element
  732. var flexGrowLeftDiv = document.createElement("div");
  733. flexGrowLeftDiv.setAttribute("class", "flexLeft");
  734. flexGrowLeftDiv.appendChild(excludeGroupGiveawaysSpan);
  735. flexGrowLeftDiv.appendChild(excludeGroupGiveawaysInput);
  736. // The "exlude whitelist GAs" input checkbox
  737. var excludeWhitelistGiveawaysInput = document.createElement("input");
  738. excludeWhitelistGiveawaysInput.setAttribute("type", "checkbox");
  739. excludeWhitelistGiveawaysInput.setAttribute("class", "filterCheckbox");
  740. excludeWhitelistGiveawaysInput.checked = excludeWhitelistGiveaways;
  741. excludeWhitelistGiveawaysInput.onclick = function() {
  742. // If the value changed, save it and update the UI
  743. GM_setValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, excludeWhitelistGiveawaysInput.checked);
  744. updateFilterCaption();
  745. filterGiveaways();
  746. };
  747. var excludeWhitelistGiveawaysSpan = document.createElement("span");
  748. excludeWhitelistGiveawaysSpan.appendChild(document.createTextNode("Exclude whitelist giveaways"));
  749. // Create and add the whitelist GAs exclusion element
  750. var flexGrowCenterDiv = document.createElement("div");
  751. flexGrowCenterDiv.setAttribute("class", "flexCenter");
  752. flexGrowCenterDiv.appendChild(excludeWhitelistGiveawaysSpan);
  753. flexGrowCenterDiv.appendChild(excludeWhitelistGiveawaysInput);
  754. // The "exclude pinned giveaways" input checkbox
  755. var excludePinnedGiveawaysInput = document.createElement("input");
  756. excludePinnedGiveawaysInput.setAttribute("type", "checkbox");
  757. excludePinnedGiveawaysInput.setAttribute("class", "filterCheckbox");
  758. excludePinnedGiveawaysInput.checked = excludePinnedGiveaways;
  759. excludePinnedGiveawaysInput.onclick = function() {
  760. // Upon value change
  761. GM_setValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, excludePinnedGiveawaysInput.checked);
  762. excludePinnedGiveaways = excludePinnedGiveawaysInput.checked;
  763. // Update the main UI
  764. updateFilterCaption();
  765. filterGiveaways();
  766. };
  767. var excludePinnedGiveawaysSpan = document.createElement("span");
  768. excludePinnedGiveawaysSpan.appendChild(document.createTextNode('Exclude pinned giveaways'));
  769. // Create and add the "exclude pinned giveaways" text
  770. var flexGrowRightDiv = document.createElement("div");
  771. flexGrowRightDiv.setAttribute("class", "flexRight");
  772. flexGrowRightDiv.appendChild(excludePinnedGiveawaysSpan);
  773. flexGrowRightDiv.appendChild(excludePinnedGiveawaysInput);
  774. // Create the first row
  775. var firstRow = document.createElement("div");
  776. firstRow.setAttribute("class", "flexCenter");
  777. firstRow.appendChild(flexGrowLeftDiv);
  778. firstRow.appendChild(flexGrowCenterDiv);
  779. firstRow.appendChild(flexGrowRightDiv);
  780. // The "exclude region-restricted giveaways" input checkbox
  781. var excludeRegionRestrictedGiveawaysInput = document.createElement("input");
  782. excludeRegionRestrictedGiveawaysInput.setAttribute("type", "checkbox");
  783. excludeRegionRestrictedGiveawaysInput.setAttribute("class", "filterCheckbox");
  784. excludeRegionRestrictedGiveawaysInput.checked = excludeRegionRestrictedGiveaways;
  785. excludeRegionRestrictedGiveawaysInput.onclick = function() {
  786. // Upon value change
  787. GM_setValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, excludeRegionRestrictedGiveawaysInput.checked);
  788. excludeRegionRestrictedGiveaways = excludeRegionRestrictedGiveawaysInput.checked;
  789. // Update the main UI
  790. updateFilterCaption();
  791. filterGiveaways();
  792. };
  793. // Create and add the "exclude region-restricted giveaways" text
  794. var excludeRegionRestrictedGiveawaysSpan = document.createElement("span");
  795. excludeRegionRestrictedGiveawaysSpan.appendChild(document.createTextNode("Exclude region-restricted giveaways"));
  796. // Create the "exclude region-restricted giveaways" element itself
  797. flexGrowLeftDiv = document.createElement("div");
  798. flexGrowLeftDiv.setAttribute("class", "flexCenter");
  799. flexGrowLeftDiv.appendChild(excludeRegionRestrictedGiveawaysSpan);
  800. flexGrowLeftDiv.appendChild(excludeRegionRestrictedGiveawaysInput);
  801. // Create the second row in the filter details
  802. var secondRow = document.createElement("div");
  803. secondRow.setAttribute("class", "flexCenter");
  804. secondRow.appendChild(flexGrowLeftDiv);
  805. // Create the row itself
  806. var row = document.createElement("div");
  807. var hr = document.createElement("hr");
  808. row.setAttribute("class", 'excludeContainer markdown');
  809. row.appendChild(firstRow);
  810. row.appendChild(secondRow);
  811. row.appendChild(hr);
  812. return row;
  813. }
  814. // Creates the row with "enabled pages" settings
  815. function createFilterUiEnabledPagesRow() {
  816. var applyToAllGiveawaysView = GM_getValue(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_ALL_GIVEAWAYS_VIEW);
  817. var applyToGroupGiveawaysView = GM_getValue(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_GROUP_GIVEAWAYS_VIEW);
  818. var applyToWishlistGiveawaysView = GM_getValue(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW);
  819. var applyToNewGiveawaysView = GM_getValue(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_NEW_GIVEAWAYS_VIEW);
  820. var applyToUserProfileView = GM_getValue(KEY_APPLY_TO_USER_PROFILE_VIEW, DEFAULT_APPLY_TO_USER_PROFILE_VIEW);
  821. var applyToSearchResultsView = GM_getValue(KEY_APPLY_TO_SEARCH_RESULTS_VIEW, DEFAULT_APPLY_TO_SEARCH_RESULTS_VIEW);
  822. var applyToRecommendedGiveawaysView = GM_getValue(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW, DEFAULT_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW);
  823. // Create and add the "enable filtering on the main page" text
  824. var flexGrowLeftDiv = document.createElement("div");
  825. flexGrowLeftDiv.setAttribute("class", "flexLeft");
  826. var enableFilteringOnTheMainPageSpan = document.createElement("span");
  827. enableFilteringOnTheMainPageSpan.appendChild(document.createTextNode("Enable on the main page"));
  828. if (isCurrentPage(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW)) {
  829. enableFilteringOnTheMainPageSpan.appendChild(document.createTextNode(" (this page)"));
  830. }
  831. flexGrowLeftDiv.appendChild(enableFilteringOnTheMainPageSpan);
  832. // The "enable filtering on the main page" input checkbox
  833. var enableFilteringOnTheMainPageInput = document.createElement("input");
  834. enableFilteringOnTheMainPageInput.setAttribute("type", "checkbox");
  835. enableFilteringOnTheMainPageInput.setAttribute("class", "filterCheckbox");
  836. enableFilteringOnTheMainPageInput.checked = applyToAllGiveawaysView;
  837. enableFilteringOnTheMainPageInput.onclick = function() {
  838. // Upon value change
  839. GM_setValue(KEY_APPLY_TO_ALL_GIVEAWAYS_VIEW, enableFilteringOnTheMainPageInput.checked);
  840. applyToAllGiveawaysView = enableFilteringOnTheMainPageInput.checked;
  841. // Update the main UI
  842. updateFilterCaption();
  843. filterGiveaways();
  844. };
  845. flexGrowLeftDiv.appendChild(enableFilteringOnTheMainPageInput);
  846. // Create and add the "enable filtering on the new giveaways page" text
  847. var flexGrowCenterDiv = document.createElement("div");
  848. flexGrowCenterDiv.setAttribute("class", "flexCenter");
  849. var enableFilteringOnTheNewGiveawaysPageSpan = document.createElement("span");
  850. enableFilteringOnTheNewGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "new giveaways" page'));
  851. if (isCurrentPage(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW)) {
  852. enableFilteringOnTheNewGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
  853. }
  854. flexGrowCenterDiv.appendChild(enableFilteringOnTheNewGiveawaysPageSpan);
  855. // The "enable filtering on the new giveaways page" input checkbox
  856. var enableFilteringOnTheNewGiveawaysPageInput = document.createElement("input");
  857. enableFilteringOnTheNewGiveawaysPageInput.setAttribute("type", "checkbox");
  858. enableFilteringOnTheNewGiveawaysPageInput.setAttribute("class", "filterCheckbox");
  859. enableFilteringOnTheNewGiveawaysPageInput.checked = applyToNewGiveawaysView;
  860. enableFilteringOnTheNewGiveawaysPageInput.onclick = function() {
  861. // Upon value change
  862. GM_setValue(KEY_APPLY_TO_NEW_GIVEAWAYS_VIEW, enableFilteringOnTheNewGiveawaysPageInput.checked);
  863. applyToNewGiveawaysView = enableFilteringOnTheNewGiveawaysPageInput.checked;
  864. // Update the main UI
  865. updateFilterCaption();
  866. filterGiveaways();
  867. };
  868. flexGrowCenterDiv.appendChild(enableFilteringOnTheNewGiveawaysPageInput);
  869. // Create and add the "enable filtering on the search results" text
  870. var flexGrowRightDiv = document.createElement("div");
  871. flexGrowRightDiv.setAttribute("class", "flexRight");
  872. var enableFilteringOnTheSearchResultsPageSpan = document.createElement("span");
  873. enableFilteringOnTheSearchResultsPageSpan.appendChild(document.createTextNode('Enable on the "search results" page'));
  874. if (isCurrentPage(KEY_APPLY_TO_SEARCH_RESULTS_VIEW)) {
  875. enableFilteringOnTheSearchResultsPageSpan.appendChild(document.createTextNode(" (this page)"));
  876. }
  877. flexGrowRightDiv.appendChild(enableFilteringOnTheSearchResultsPageSpan);
  878. // The "enable filtering on the search results" input checkbox
  879. var enableFilteringOnTheSearchResultsPageInput = document.createElement("input");
  880. enableFilteringOnTheSearchResultsPageInput.setAttribute("type", "checkbox");
  881. enableFilteringOnTheSearchResultsPageInput.setAttribute("class", "filterCheckbox");
  882. enableFilteringOnTheSearchResultsPageInput.checked = applyToSearchResultsView;
  883. enableFilteringOnTheSearchResultsPageInput.onclick = function() {
  884. // Upon value change
  885. GM_setValue(KEY_APPLY_TO_SEARCH_RESULTS_VIEW, enableFilteringOnTheSearchResultsPageInput.checked);
  886. applyToSearchResultsView = enableFilteringOnTheSearchResultsPageInput.checked;
  887. // Update the main UI
  888. updateFilterCaption();
  889. filterGiveaways();
  890. };
  891. flexGrowRightDiv.appendChild(enableFilteringOnTheSearchResultsPageInput);
  892. // Create the first row in the filter details
  893. var firstRow = document.createElement("div");
  894. firstRow.setAttribute("class", "flexCenter");
  895. firstRow.appendChild(flexGrowLeftDiv);
  896. firstRow.appendChild(flexGrowCenterDiv);
  897. firstRow.appendChild(flexGrowRightDiv);
  898. // Create and add the "enable filtering on the wishlist giveaways page" text
  899. flexGrowLeftDiv = document.createElement("div");
  900. flexGrowLeftDiv.setAttribute("class", "flexLeft");
  901. var enableFilteringOnTheWishlistGiveawaysPageSpan = document.createElement("span");
  902. enableFilteringOnTheWishlistGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "wishlist giveaways" page'));
  903. if (isCurrentPage(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW)) {
  904. enableFilteringOnTheWishlistGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
  905. }
  906. flexGrowLeftDiv.appendChild(enableFilteringOnTheWishlistGiveawaysPageSpan);
  907. // The "enable filtering on the wishlist giveaways page" input checkbox
  908. var enableFilteringOnTheWishlistGiveawaysPageInput = document.createElement("input");
  909. enableFilteringOnTheWishlistGiveawaysPageInput.setAttribute("type", "checkbox");
  910. enableFilteringOnTheWishlistGiveawaysPageInput.setAttribute("class", "filterCheckbox");
  911. enableFilteringOnTheWishlistGiveawaysPageInput.checked = applyToWishlistGiveawaysView;
  912. enableFilteringOnTheWishlistGiveawaysPageInput.onclick = function() {
  913. // Upon value change
  914. GM_setValue(KEY_APPLY_TO_WISHLIST_GIVEAWAYS_VIEW, enableFilteringOnTheWishlistGiveawaysPageInput.checked);
  915. applyToWishlistGiveawaysView = enableFilteringOnTheWishlistGiveawaysPageInput.checked;
  916. // Update the main UI
  917. updateFilterCaption();
  918. filterGiveaways();
  919. };
  920. flexGrowLeftDiv.appendChild(enableFilteringOnTheWishlistGiveawaysPageInput);
  921. // Create and add the "enable filtering on the "group giveaways" page" text
  922. flexGrowCenterDiv = document.createElement("div");
  923. flexGrowCenterDiv.setAttribute("class", "flexCenter");
  924. var enableFilteringOnTheGroupGiveawaysPageSpan = document.createElement("span");
  925. enableFilteringOnTheGroupGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "group giveaways" page'));
  926. if (isCurrentPage(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW)) {
  927. enableFilteringOnTheGroupGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
  928. }
  929. flexGrowCenterDiv.appendChild(enableFilteringOnTheGroupGiveawaysPageSpan);
  930. // The "enable filtering on the "group giveaways" page" page" input checkbox
  931. var enableFilteringOnTheGroupGiveawaysPageInput = document.createElement("input");
  932. enableFilteringOnTheGroupGiveawaysPageInput.setAttribute("type", "checkbox");
  933. enableFilteringOnTheGroupGiveawaysPageInput.setAttribute("class", "filterCheckbox");
  934. enableFilteringOnTheGroupGiveawaysPageInput.checked = applyToGroupGiveawaysView;
  935. enableFilteringOnTheGroupGiveawaysPageInput.onclick = function() {
  936. // Upon value change
  937. GM_setValue(KEY_APPLY_TO_GROUP_GIVEAWAYS_VIEW, enableFilteringOnTheGroupGiveawaysPageInput.checked);
  938. applyToGroupGiveawaysView = enableFilteringOnTheGroupGiveawaysPageInput.checked;
  939. // Update the main UI
  940. updateFilterCaption();
  941. filterGiveaways();
  942. };
  943. flexGrowCenterDiv.appendChild(enableFilteringOnTheGroupGiveawaysPageInput);
  944. // Create and add the "enable filtering on the user profile page" text
  945. flexGrowRightDiv = document.createElement("div");
  946. flexGrowRightDiv.setAttribute("class", "flexRight");
  947. var enableFilteringOnTheUserProfilePageSpan = document.createElement("span");
  948. enableFilteringOnTheUserProfilePageSpan.appendChild(document.createTextNode('Enable on the "user profile" page'));
  949. if (isCurrentPage(KEY_APPLY_TO_USER_PROFILE_VIEW)) {
  950. enableFilteringOnTheUserProfilePageSpan.appendChild(document.createTextNode(" (this page)"));
  951. }
  952. flexGrowRightDiv.appendChild(enableFilteringOnTheUserProfilePageSpan);
  953. // The "enable filtering on the user profile page" input checkbox
  954. var enableFilteringOnTheUserProfilePageInput = document.createElement("input");
  955. enableFilteringOnTheUserProfilePageInput.setAttribute("type", "checkbox");
  956. enableFilteringOnTheUserProfilePageInput.setAttribute("class", "filterCheckbox");
  957. enableFilteringOnTheUserProfilePageInput.checked = applyToUserProfileView;
  958. enableFilteringOnTheUserProfilePageInput.onclick = function() {
  959. // Upon value change
  960. GM_setValue(KEY_APPLY_TO_USER_PROFILE_VIEW, enableFilteringOnTheUserProfilePageInput.checked);
  961. applyToUserProfileView = enableFilteringOnTheUserProfilePageInput.checked;
  962. // Update the main UI
  963. updateFilterCaption();
  964. filterGiveaways();
  965. };
  966. flexGrowRightDiv.appendChild(enableFilteringOnTheUserProfilePageInput);
  967. // Create the second row in the filter details
  968. var secondRow = document.createElement("div");
  969. secondRow.setAttribute("class", "flexCenter");
  970. secondRow.appendChild(flexGrowLeftDiv);
  971. secondRow.appendChild(flexGrowCenterDiv);
  972. secondRow.appendChild(flexGrowRightDiv);
  973. // Create and add the "enable filtering on the wishlist giveaways page" text
  974. flexGrowCenterDiv = document.createElement("div");
  975. flexGrowCenterDiv.setAttribute("class", "flexCenter");
  976. var enableFilteringOnTheRecommendedGiveawaysPageSpan = document.createElement("span");
  977. enableFilteringOnTheRecommendedGiveawaysPageSpan.appendChild(document.createTextNode('Enable on the "recommended giveaways" page'));
  978. if (isCurrentPage(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW)) {
  979. enableFilteringOnTheRecommendedGiveawaysPageSpan.appendChild(document.createTextNode(" (this page)"));
  980. }
  981. flexGrowCenterDiv.appendChild(enableFilteringOnTheRecommendedGiveawaysPageSpan);
  982. // The "enable filtering on the wishlist giveaways page" input checkbox
  983. var enableFilteringOnTheRecommendedGiveawaysPageInput = document.createElement("input");
  984. enableFilteringOnTheRecommendedGiveawaysPageInput.setAttribute("type", "checkbox");
  985. enableFilteringOnTheRecommendedGiveawaysPageInput.setAttribute("class", "filterCheckbox");
  986. enableFilteringOnTheRecommendedGiveawaysPageInput.checked = applyToRecommendedGiveawaysView;
  987. enableFilteringOnTheRecommendedGiveawaysPageInput.onclick = function() {
  988. // Upon value change
  989. GM_setValue(KEY_APPLY_TO_RECOMMENDED_GIVEAWAYS_VIEW, enableFilteringOnTheRecommendedGiveawaysPageInput.checked);
  990. applyToRecommendedGiveawaysView = enableFilteringOnTheRecommendedGiveawaysPageInput.checked;
  991. // Update the main UI
  992. updateFilterCaption();
  993. filterGiveaways();
  994. };
  995. flexGrowCenterDiv.appendChild(enableFilteringOnTheRecommendedGiveawaysPageInput);
  996. // Create the third row in the filter details
  997. var thirdRow = document.createElement("div");
  998. thirdRow.setAttribute("class", "flexCenter");
  999. thirdRow.appendChild(flexGrowCenterDiv);
  1000. // Create the row itself
  1001. var row = document.createElement("div");
  1002. var hr = document.createElement("hr");
  1003. row.setAttribute("class", "enableContainer markdown");
  1004. row.appendChild(firstRow);
  1005. row.appendChild(secondRow);
  1006. row.appendChild(thirdRow);
  1007. row.appendChild(hr);
  1008. return row;
  1009. }
  1010. // Creates a row with other options
  1011. function createFilterUiOtherOptionsRow() {
  1012. var removePagination = GM_getValue(KEY_REMOVE_PAGINATION, DEFAULT_REMOVE_PAGINATION);
  1013. var hideEnteredGiveaways = GM_getValue(KEY_HIDE_ENTERED_GIVEAWAYS, DEFAULT_HIDE_ENTERED_GIVEAWAYS);
  1014. // The "remove pagination" input checkbox
  1015. var removePaginationInput = document.createElement("input");
  1016. removePaginationInput.setAttribute("type", "checkbox");
  1017. removePaginationInput.setAttribute("class", "filterCheckbox");
  1018. removePaginationInput.checked = removePagination;
  1019. removePaginationInput.onclick = function() {
  1020. // Save the change and update the UI
  1021. GM_setValue(KEY_REMOVE_PAGINATION, removePaginationInput.checked);
  1022. filterGiveaways();
  1023. };
  1024. var removePaginationSpan = document.createElement("span");
  1025. removePaginationSpan.appendChild(document.createTextNode("Remove pagination"));
  1026. // Create and add the group GAs exclusion element
  1027. var flexGrowLeftDiv = document.createElement("div");
  1028. flexGrowLeftDiv.setAttribute("class", "flexCenter");
  1029. flexGrowLeftDiv.appendChild(removePaginationSpan);
  1030. flexGrowLeftDiv.appendChild(removePaginationInput);
  1031. // The "hide entered giveaways" input checkbox
  1032. var hideEnteredGiveawaysSelect = document.createElement("select");
  1033. for ( i = 0; i < HIDE_ENTERED_GIVEAWAYS_CONSTANTS.length; i++ ) {
  1034. var option = document.createElement('option');
  1035. option.value = option.textContent = HIDE_ENTERED_GIVEAWAYS_CONSTANTS[i];
  1036. hideEnteredGiveawaysSelect.appendChild(option);
  1037. }
  1038. hideEnteredGiveawaysSelect.value = hideEnteredGiveaways;
  1039. hideEnteredGiveawaysSelect.style.width = "75px";
  1040. hideEnteredGiveawaysSelect.style.marginLeft = "9px";
  1041. hideEnteredGiveawaysSelect.onchange = function() {
  1042. // Save the change and update the UI
  1043. var selectedValue = hideEnteredGiveawaysSelect.options[hideEnteredGiveawaysSelect.selectedIndex].value;
  1044. GM_setValue(KEY_HIDE_ENTERED_GIVEAWAYS, selectedValue);
  1045. filterGiveaways();
  1046. };
  1047. var hideEnteredGiveawaysSpan = document.createElement("span");
  1048. hideEnteredGiveawaysSpan.appendChild(document.createTextNode("Hide entered giveaways"));
  1049. var helpTooltip = document.createElement("div");
  1050. var tooltip = document.createElement("span");
  1051. tooltip.setAttribute("class", "sidebar__shortcut-tooltip-absolute tooltip");
  1052. tooltip.appendChild(document.createTextNode('"Yes" hides entered giveaways, although exclusions still apply. "Always" hides entered giveaways no matter the other filter options.'));
  1053. helpTooltip.setAttribute("class", "help-tip");
  1054. helpTooltip.appendChild(document.createTextNode("?"));
  1055. helpTooltip.appendChild(tooltip);
  1056. // Create and add the group GAs exclusion element
  1057. var flexGrowCenterDiv = document.createElement("div");
  1058. flexGrowCenterDiv.setAttribute("class", "flexCenter");
  1059. flexGrowCenterDiv.appendChild(hideEnteredGiveawaysSpan);
  1060. flexGrowCenterDiv.appendChild(helpTooltip);
  1061. flexGrowCenterDiv.appendChild(hideEnteredGiveawaysSelect);
  1062. // Create the row itself
  1063. var row = document.createElement("div");
  1064. row.setAttribute("class", "otherContainer flexCenter");
  1065. row.appendChild(flexGrowLeftDiv);
  1066. row.appendChild(flexGrowCenterDiv);
  1067. return row;
  1068. }
  1069. // Creates a row that hides the filter details
  1070. function createFilterUiHideFilterDetailsRow() {
  1071. var hideControlsDiv = document.createElement("div");
  1072. hideControlsDiv.id = FILTER_HIDE_ID;
  1073. hideControlsDiv.setAttribute("class", 'pinned-giveaways__inner-wrap sidebar__navigation__item__link');
  1074. hideControlsDiv.appendChild(document.createTextNode("Hide filter options"));
  1075. hideControlsDiv.onclick = function() {
  1076. // Hide the filter details
  1077. var filterDetails = document.getElementById(FILTER_DETAILS_ID);
  1078. if (filterDetails !== null) {
  1079. filterDetails.style.display = "none";
  1080. }
  1081. };
  1082. return hideControlsDiv;
  1083. }
  1084. function insertFilterUi(filterUi) {
  1085. // Insert into main giveaway UI
  1086. var elements = document.getElementsByClassName("pinned-giveaways__outer-wrap");
  1087. if (elements.length > 0) {
  1088. var parent = elements[0].parentElement;
  1089. parent.insertBefore(filterUi, parent.childNodes[2]);
  1090. return;
  1091. }
  1092. // Insert into the main giveaway UI if there are no pinned GAs
  1093. elements = document.getElementsByClassName("page__heading");
  1094. // Since "page__heading" is on multiple pages, a check needs to be done that user is on the correct page
  1095. if (document.getElementsByClassName("featured__container").length > 0 && elements.length > 0) {
  1096. var parent = elements[0].parentElement;
  1097. parent.insertBefore(filterUi, parent.childNodes[1]);
  1098. return;
  1099. }
  1100. // Insert into profile
  1101. elements = document.getElementsByClassName("page__heading");
  1102. // Since "page__heading" is on multiple pages, a check needs to be done that user is on the profile page
  1103. if (isCurrentPage(KEY_APPLY_TO_USER_PROFILE_VIEW) && elements.length > 0) {
  1104. var parent = elements[0].parentElement;
  1105. parent.insertBefore(filterUi, parent.childNodes[2]);
  1106. return;
  1107. }
  1108. }
  1109. // Updates filter caption in the UI
  1110. function updateFilterCaption() {
  1111. var filterCaptionDiv = document.getElementById(FILTER_CAPTION_ID);
  1112. filterCaptionDiv.innerHTML = getFilterCaption();
  1113. filterCaptionDiv.setAttribute("class", 'sidebar__navigation__item__name pinned-giveaways__inner-wrap sidebar__navigation__item__link');
  1114. updateFilterCaptionTextColor();
  1115. }
  1116. // Updates filter caption text color based on the current filtering status
  1117. function updateFilterCaptionTextColor() {
  1118. var filterCaptionDiv = document.getElementById(FILTER_CAPTION_ID);
  1119. if (isFilteringEnabledOnCurrentPage()) {
  1120. filterCaptionDiv.setAttribute("class", 'sidebar__navigation__item__name pinned-giveaways__inner-wrap sidebar__navigation__item__link');
  1121. } else {
  1122. filterCaptionDiv.setAttribute("class", 'sidebar__heading pinned-giveaways__inner-wrap sidebar__navigation__item__link');
  1123. }
  1124. }
  1125. // Creates the text for the filter caption
  1126. function getFilterCaption() {
  1127. var filterCaption = "Giveaway Filter";
  1128. if (!isFilteringEnabledOnCurrentPage()) {
  1129. return filterCaption;
  1130. }
  1131. // Add the level range to the caption
  1132. var minLevelToDisplay = GM_getValue(KEY_MIN_LEVEL_TO_DISPLAY, DEFAULT_MIN_LEVEL_TO_DISPLAY);
  1133. var maxLevelToDisplay = GM_getValue(KEY_MAX_LEVEL_TO_DISPLAY, DEFAULT_MAX_LEVEL_TO_DISPLAY);
  1134. filterCaption += " (Level " + minLevelToDisplay + "-" + maxLevelToDisplay;
  1135. // Add the maximal amount of entries to the caption
  1136. var enableFilteringByEntryCount = GM_getValue(KEY_ENABLE_FILTERING_BY_ENTRY_COUNT, DEFAULT_ENABLE_FILTERING_BY_ENTRY_COUNT);
  1137. if (enableFilteringByEntryCount) {
  1138. var maxNumberOfEntries = GM_getValue(KEY_MAX_NUMBER_OF_ENTRIES, 200);
  1139. filterCaption += ", Max " + maxNumberOfEntries + " entries";
  1140. }
  1141. // Add the points range to the caption
  1142. var minPointsToDisplay = GM_getValue(KEY_MIN_POINTS_TO_DISPLAY, DEFAULT_MIN_POINTS_TO_DISPLAY);
  1143. var maxPointsToDisplay = GM_getValue(KEY_MAX_POINTS_TO_DISPLAY, DEFAULT_MAX_POINTS_TO_DISPLAY);
  1144. filterCaption += ", " + minPointsToDisplay + "-" + maxPointsToDisplay + " Points";
  1145. // Add the excluded information to the caption
  1146. var excludeWhitelistGiveaways = GM_getValue(KEY_EXCLUDE_WHITELIST_GIVEAWAYS, DEFAULT_EXCLUDE_WHITELIST_GIVEAWAYS);
  1147. var excludeGroupGiveaways = GM_getValue(KEY_EXCLUDE_GROUP_GIVEAWAYS, DEFAULT_EXCLUDE_GROUP_GIVEAWAYS);
  1148. var excludeRegionRestrictedGiveaways = GM_getValue(KEY_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS, DEFAULT_EXCLUDE_REGION_RESTRICTED_GIVEAWAYS);
  1149. var excludePinnedGiveaways = GM_getValue(KEY_EXCLUDE_PINNED_GIVEAWAYS, DEFAULT_EXCLUDE_PINNED_GIVEAWAYS);
  1150. var excluded = "";
  1151. if (excludeGroupGiveaways) {
  1152. excluded += "Group";
  1153. }
  1154. if (excludeWhitelistGiveaways) {
  1155. if (excluded !== "") {
  1156. excluded += "/";
  1157. }
  1158. excluded += "Whitelist";
  1159. }
  1160. if (excludePinnedGiveaways) {
  1161. if (excluded !== "") {
  1162. excluded += "/";
  1163. }
  1164. excluded += "Pinned";
  1165. }
  1166. if (excludeRegionRestrictedGiveaways) {
  1167. if (excluded !== "") {
  1168. excluded += "/";
  1169. }
  1170. excluded += "Regional";
  1171. }
  1172. if (excluded !== "") {
  1173. excluded = ", " + excluded + " GAs excluded";
  1174. }
  1175. filterCaption += excluded;
  1176. // Close it up and return
  1177. filterCaption += ")";
  1178. return filterCaption;
  1179. }
  1180. // Returns true if the character (its code) is a digit, false otherwise
  1181. function isDigit(charCode) {
  1182. return charCode >= 48 && charCode <= 57;
  1183. }
  1184. // Function handling execution after DOM has been changed - makes the filtering work in endless scrolling of SG++
  1185. var observeDOM = (function() {
  1186. var MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
  1187. eventListenerSupported = window.addEventListener;
  1188. return function(obj, callback) {
  1189. if (MutationObserver) {
  1190. // Define a new observer
  1191. var obs = new MutationObserver(function(mutations, observer) {
  1192. if (mutations[0].addedNodes.length || mutations[0].removedNodes.length)
  1193. callback();
  1194. });
  1195. // Have the observer observe the registered element for changes in its children
  1196. obs.observe(obj, {
  1197. childList : true,
  1198. subtree : true
  1199. });
  1200. } else if (eventListenerSupported) {
  1201. obj.addEventListener('DOMNodeInserted', callback, false);
  1202. obj.addEventListener('DOMNodeRemoved', callback, false);
  1203. }
  1204. };
  1205. })();
  1206. // Register the filtering upon any changes on the whole page
  1207. observeDOM(document, function() {
  1208. filterGiveaways();
  1209. });
  1210. filterGiveaways();

comments powered by Disqus