Chaturbate Advanced Filters

Adds more features to the chaturbate website filters such as age and keyword searching filtering. Look for these features under the normal options gear.

  1. // ==UserScript==
  2. // @name Chaturbate Advanced Filters
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.03
  5. // @description Adds more features to the chaturbate website filters such as age and keyword searching filtering. Look for these features under the normal options gear.
  6. // @author jepspile@yahoo.com
  7. // @match *chaturbate.com/*
  8. // @icon https://static-assets.highwebmedia.com/favicons/favicon.ico
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. const defaultHomepage = "https://chaturbate.com/tag/milf/female/"; //homepage redirect
  14. const minAgeDefault = '30'; //default min age
  15. const maxAgeDefault = ''; //default max age
  16. const keywordDefaults = '-squirt'; //list of keywords (or negative keywords) separated by commas
  17.  
  18. // Keep track of changes to the DOM and update as needed
  19. let timer;
  20. let targetNode = document.getElementsByClassName("roomlist_container")[0];
  21. let config = { attributes: true, childList: true, subtree: true };
  22. let callback = (mutationList, observer) => {
  23. if (timer) clearTimeout(timer);
  24. timer = setTimeout(() => { initialize(); }, 1000);
  25. };
  26. let observer = new MutationObserver(callback);
  27. observer.observe(targetNode, config);
  28.  
  29. homepageRedirect();
  30. addFilters();
  31.  
  32. function initialize(){
  33. showHideRoomCards();
  34. }
  35.  
  36. function addFilters(){
  37. const searchMenu = document.getElementsByClassName("advance-search-element")[0];
  38.  
  39. // Age filter
  40. // **************************************************
  41.  
  42. const ageFilter = document.createElement("div");
  43. const ageLabel = document.createElement("label");
  44. const ageMin = document.createElement("input");
  45. const ageMax = document.createElement("input");
  46. const ageSeparator = document.createElement("span");
  47.  
  48. ageFilter.id = "age-filter";
  49. ageLabel.innerHTML = "Age:   ";
  50.  
  51. ageMin.type = "text";
  52. ageMin.id = "age-min";
  53. ageMin.value = minAgeDefault;
  54.  
  55. ageSeparator.innerHTML = "  -  ";
  56.  
  57. ageMax.type = "text";
  58. ageMax.id = "age-max";
  59. ageMax.value = maxAgeDefault;
  60.  
  61. ageFilter.appendChild(ageLabel);
  62. ageFilter.appendChild(ageMin);
  63. ageFilter.appendChild(ageSeparator);
  64. ageFilter.appendChild(ageMax);
  65.  
  66. searchMenu.appendChild(ageFilter);
  67. searchMenu.insertBefore(addStyleBlock(), ageFilter);
  68.  
  69. ageMin.addEventListener("change", (event) => {
  70. showHideRoomCards();
  71. });
  72.  
  73. ageMax.addEventListener("change", (event) => {
  74. showHideRoomCards();
  75. });
  76.  
  77.  
  78. // Keyword filter
  79. // **************************************************
  80.  
  81. const keywordFilter = document.createElement("div");
  82. const keywordLabel = document.createElement("label");
  83. const keywordList = document.createElement("input");
  84.  
  85. keywordFilter.id = "keyword-filter";
  86. keywordLabel.innerHTML = "keywords:   ";
  87.  
  88. keywordList.type = "text";
  89. keywordList.id = "keyword-list";
  90. keywordList.value = keywordDefaults;
  91.  
  92. keywordFilter.appendChild(keywordLabel);
  93. keywordFilter.appendChild(keywordList);
  94.  
  95. searchMenu.appendChild(keywordFilter);
  96. searchMenu.insertBefore(addStyleBlock(), keywordFilter);
  97.  
  98. keywordList.addEventListener("change", (event) => {
  99. showHideRoomCards();
  100. });
  101.  
  102. keywordList.addEventListener("change", (event) => {
  103. showHideRoomCards();
  104. });
  105. }
  106.  
  107. function showHideRoomCards(){
  108. var minAge = document.getElementById("age-min").value;
  109. var maxAge = document.getElementById("age-max").value;
  110. var keywordList = document.getElementById("keyword-list").value;
  111.  
  112. var rooms = document.getElementsByClassName("roomCard");
  113. for (let i = 0; i < rooms.length; ++i) {
  114. // Age check
  115. var ages = rooms[i].getElementsByClassName("age");
  116. var age = (ages[0] !== undefined) ? ages[0].innerHTML : '';
  117. var showAge = false;
  118. if ((age >= minAge || minAge == "") && (age <= maxAge || maxAge == "")){ showAge = true; }
  119.  
  120. // Keyword check
  121. var subjects = rooms[i].getElementsByClassName("subject");
  122. var subject = (subjects[0] !== undefined) ? subjects[0].innerHTML : "";
  123.  
  124. var keywords = keywordList.split(",");
  125. var showKeyword = true;
  126.  
  127. if(subject != "" && keywords != ""){
  128. for (let k = 0; k < keywords.length; ++k) {
  129. if(keywords[k].startsWith("-") == true && subject.includes(keywords[k].substring(1).toLowerCase())){
  130. showKeyword = false;
  131. }
  132. if(keywords[k].startsWith("-") == false && !subject.includes(keywords[k].toLowerCase() in subject)){
  133. showKeyword = false;
  134. }
  135. }}
  136.  
  137. if(showAge == true && showKeyword == true){
  138. rooms[i].dataset.hide = false;
  139. rooms[i].style.display = "list-item";
  140. } else {
  141. rooms[i].dataset.hide = true;
  142. rooms[i].style.display = "none !important";
  143. }
  144. }
  145. }
  146.  
  147. function homepageRedirect(){
  148. if(window.location.href == "https://chaturbate.com/"){
  149. window.location.replace(defaultHomepage);
  150. return false;
  151. } else { return true; }
  152. }
  153.  
  154. function addStyleBlock(){
  155. var cssBlock = document.createElement("style");
  156. cssBlock.innerHTML = "" +
  157. "#improvedSearch { height: 50px; }" +
  158. "" +
  159. "#age-min,#age-max { width:20px; }" +
  160. "body li[data-hide='true'] {display:none !important; }" +
  161. "";
  162. return cssBlock;
  163. }
  164.  
  165. function insertAfter(referenceNode, newNode) {
  166. referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
  167. }
  168.