// ==UserScript== // @name Reddit Filter Plus // @license GPL version 2 http://www.gnu.org/licenses/gpl-2.0.html // @description Hide or highlight links by user, title, url or subreddit. Preferences are found on the regular reddit preferences page. Highlight colors may be entered as HTML colors (#123456) or with simple names. // @include https://ssl.reddit.com/prefs/ // @include http://www.reddit.com/prefs/ // @include http://www.reddit.com/* // @exclude http://www.reddit.com/user/* // @exclude http://www.reddit.com/info/* // @exclude http://www.reddit.com/r/*/comments/* // ==/UserScript== var hidden_headlines = []; if (typeof GM_log === "undefined") { GM_log = function (msg) {}; } if (typeof GM_setValue === "undefined") { GM_setValue = function (name, value) { var expdate = new Date(); expdate.setTime(expdate.getTime() + 64800000000);//~2 years var expires = "; expires=" + expdate.toGMTString(); document.cookie = name+"="+value+expires+"; path=/"; } } if (typeof GM_getValue === "undefined") { GM_getValue = function (name) { var regex = new RegExp(';?\s*'+escape(name)+'=([^;]+)'); return document.cookie.match(regex); } } rf_foreach=function(seq, callback){ for(var i=0;i 0) { json += ', '; } json += '{ ' + "'titles' : '" + filter.titles + "', " + "'urls' : '" + filter.urls + "'," + "'users' : '" + filter.users + "'," + "'subreddits' : '" + filter.subreddits + "', " + "'highlight' : " + filter.highlight + ", " + "'color' : '" + filter.color + "'" + ' }'; } json += ']'; GM_log('Saving filters: ' + json); GM_setValue('rf_filters', json); } rf_buildPatterns = function(filters) { var patternTable = []; for (var i = 0; i < filters.length; ++i) { var filter = filters[i]; var filterPatterns = { 'user' : [], 'subreddit' : [], 'url' : [], 'title' : [], 'highlight' : false, 'color' : 'yellow' }; if (filter.titles) { // add title matches rf_foreach(filter.titles.split(/\s*,\s*/),function(pattern){ filterPatterns.title.push(new RegExp(pattern, 'i')); }); } if (filter.urls) { // add url matches rf_foreach(filter.urls.split(/\s*,\s*/),function(pattern){ filterPatterns.url.push(new RegExp(pattern, 'i')); }); } if (filter.users) { // add user patterns rf_foreach(filter.users.split(/\s*,\s*/),function(pattern){ filterPatterns.user.push('http://www.reddit.com/user/' + pattern.toLowerCase() + '/'); }); } if (filter.subreddits) { // add subreddit patterns rf_foreach(filter.subreddits.split(/\s*,\s*/),function(pattern){ filterPatterns.subreddit.push('http://www.reddit.com/r/' + pattern.toLowerCase() + '/'); }); } filterPatterns.highlight = filter.highlight; filterPatterns.color = filter.color; patternTable.push(filterPatterns); } return patternTable; } rf_highlight = function(elem, color) { elem.style.backgroundColor = color; } rf_hide = function(elem) { elem.style.display = 'none'; hidden_headlines.push(elem); } rf_doFilter = function() { var filters = rf_buildPatterns(rf_loadFilters()); var divs = document.getElementsByTagName('div'); for (var i = 0; i < divs.length; ++i) { var div = divs[i]; if (!(/thing/.test(div.className))) continue; var match = false; var links = div.getElementsByTagName('a'); for (var j = 0; !match && j < links.length; ++j) { var link = links[j]; for (var k = 0; k < filters.length; ++k) { var filter = filters[k]; if (/^title/.test(link.className)) { // title match for (var l = 0; !match && l < filter.title.length; ++l) { var pattern = filter.title[l]; if (pattern.test(link.innerHTML)) { match = true; break; } }// [end]for each title // url match for (var l = 0; !match && l < filter.url.length; ++l) { var pattern = filter.url[l]; if (pattern.test(link.href)) { match = true; break; } }// [end]for each url } else if (/\/domain\//.test(link.href)) { // domain match for (var l = 0; !match && l < filter.url.length; ++l) { var pattern = filter.url[l]; if (pattern.test(link.href)) { match = true; break; } }// [end]for each url } else if (link.className == 'author') { // user match for (var l = 0; !match && l < filter.user.length; ++l) { var pattern = filter.user[l]; if (pattern == link.href.toLowerCase()) { match = true; break; } }// [end]for each user } else if (/^subreddit/.test(link.className)) { // subreddit match for (var l = 0; !match && l < filter.subreddit.length; ++l) { var pattern = filter.subreddit[l]; if (pattern == link.href.toLowerCase()) { match = true; break; } }// [end]for each subreddit } if (match) { rf_highlight(div, filter.color); if (!filter.highlight) { rf_hide(div); } break; } }// [end]for each filter }// [end]for each link }// [end]for each div rf_report(hidden_headlines.length); } rf_reSerialize = function() { var filters = []; var container = document.getElementById('rf_filters'); for (var i = 0; i < container.childNodes.length; ++i) { var node = container.childNodes[i]; var filter = {'titles' : '', 'urls' : '', 'users' : '', 'subreddits' : '', 'highlight' : false, 'color' : 'yellow'}; var subnodes = node.getElementsByTagName('input'); for (var j = 0; j < subnodes.length; ++j) { var input = subnodes[j]; if (input.type == 'text' && input.value) { if (input.className == 'rf_titles') { filter.titles = input.value; } else if (input.className == 'rf_urls') { filter.urls = input.value; } else if (input.className == 'rf_users') { filter.users = input.value; } else if (input.className == 'rf_subreddits') { filter.subreddits = input.value; } else if (input.className == 'rf_color') { filter.color = input.value; } } else if (input.type == 'checkbox') { filter.highlight = input.checked; } } filters.push(filter); } return filters; } rf_deSerialize = function(filters) { for (var i = 0; i < filters.length; ++i) { var filter = filters[i]; rf_prefsAddFilter(filter.titles, filter.urls, filter.users, filter.subreddits, filter.highlight, filter.color); } } rf_doPrefs = function() { var newForm = document.createElement('form'); newForm.className = 'pretty-form'; newForm.innerHTML = '

Reddit Filter Plus



return to main'; // append the filter preferences in an appropriate spot var forms = document.getElementsByTagName('form'); for (var i = 0; i < forms.length; ++i) { var form = forms[i]; if (form.className == 'pretty-form short-text') { form.parentNode.insertBefore(newForm, form.nextSibling); } } document.getElementById('rf_addfilter').addEventListener('click', function() {rf_prefsAddFilter('', '', '', '', true, 'yellow');}, false); document.getElementById('rf_savefilters').addEventListener('click', function() { rf_saveFilters(rf_reSerialize()); window.setTimeout(function() { document.getElementById('rf_savestatus').style.display = 'none'; }, 4000); document.getElementById('rf_savestatus').style.display = ''; document.getElementById('rf_savestatus').innerHTML = 'saved';}, false); rf_deSerialize(rf_loadFilters()); } rf_prefsAddFilter = function(titles, urls, users, subreddits, highlight, color) { var container = document.getElementById('rf_filters'); var newFilter = document.createElement('div'); var removeButton = document.createElement('input'); newFilter.style.border = '1px solid black'; newFilter.innerHTML = '' + '' + '' + '' + '' + '' + '' + '
title filters
url filters
user filters
subreddit filters
highlight (if unchecked, anything matching this filter will be hidden)
highlight color
'; removeButton.type = 'button'; removeButton.class = 'btn'; removeButton.value = 'remove this filter'; removeButton.addEventListener('click', function() {container.removeChild(newFilter);}, false); newFilter.appendChild(removeButton); container.appendChild(newFilter); } rf_unhide = function() { for (var i = 0; i < hidden_headlines.length; ++i) { hidden_headlines[i].style.display = ''; } document.getElementById('rf_report').style.display = 'none'; } rf_report = function(num) { var msg = num + ' headlines filtered'; GM_log(msg); if (num > 0) { var div = document.createElement('div'); div.innerHTML = '

' + msg + ': [unhide]

'; var siteTable = document.getElementById('siteTable'); if (typeof(siteTable) == "undefined") siteTable = document.getElementById('siteTable_organic'); if (!siteTable) return; siteTable.parentNode.insertBefore(div, siteTable.nextSibling); document.getElementById('rf_unhide').addEventListener('click', rf_unhide, false); } } // do stuff if (/\/prefs\//.test(window.location.href)) { rf_doPrefs(); } else { rf_doFilter(); }