之前介紹過Feedly Duplicate Remover以及後來的Chrome Extension - Reader Filter。
前者已經失效而且沒有更新,後者有效但只限Chrome,而且hidden後的feeds,會保留空白,很愚蠢的設計。
持續多個月,實在忍無可忍,還是又要自己出手寫個小品程式去一己私慾。
這個Userscript很簡單,以標題對比方法找出重複的,你可以選擇以Hide方式還是Highlight方式去標示。
打開Config方法是在Greasemonkey的圖示下會找到按鈕。
我測試過Chrome+Tampermonkey都可以完美運作的。
大家可以由此下載Feedly Duplicate Filter 2014
https://dl.dropboxusercontent.com/u/19160547/Files/Feedly_Duplicate_Filter.user.js
Source Code:
// ==UserScript== // @name Feedly Duplicate Filter 2014 // @version 1.0.4 // @description Remove the Feedly duplicate entry. For more detail please visit http://tatmingstudio.blogspot.com/2014/01/Feedly-Duplicate-Filter-2014.html // @require https://raw.github.com/sizzlemctwizzle/GM_config/master/gm_config.js // @grant GM_getValue // @grant GM_setValue // @grant GM_log // @grant GM_registerMenuCommand // @icon https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUXiOFwqPSFXDJ6xU1SE4hHUwfwA4-s3FnIfRGTxKKKIBygT-m238M11Ze5-2bvehSMaxqtwleaEBAEEp1u4RzN7C9AC2MoQ5vuyRal_eYHVE5asjvgC2gZoROeUtC-3iDIcpb3kVuuFSw/s800/feedly-icon.png // @include http*://*feedly.com/* // @namespace http://tatmingstudio.blogspot.com/2014/01/Feedly-Duplicate-Filter-2014.html // @run-at document-end // @downloadURL https://dl.dropboxusercontent.com/u/19160547/Files/Feedly_Duplicate_Filter.user.js // @updateURL https://dl.dropboxusercontent.com/u/19160547/Files/Feedly_Duplicate_Filter.user.js // ==/UserScript== /* Version History: 2012-01-29 v1.0.4 Fix Bug: The snuggled duplicate items not filtering.. 2012-01-29 v1.0.3 Improve performace. Fix regex match accidentally. Add Threshold setting, the number of items to compare, reduce the number will improve memory usage but also reduce accuracy. Add GM_config save() event. 2012-01-23 v1.0.2 Add regex support with default value: match all title only contain domain name. 2014-01-20 v1.0.1 Fixed memory leak because uncomment console.log() accidentally. 2014-01-13 v1.0 Initial release. */ // Add config style function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } addGlobalStyle('#GM_config_Feedly_Duplicate_Filter { width: 450px ! important; height: 330px ! important; }'); GM_config.init( { 'id': 'GM_config_Feedly_Duplicate_Filter', // The id used for this instance of GM_config 'title': 'Feedly Duplicate Filter Settings', // Panel Title 'fields': // Fields object { 'FilterMode': { 'label': 'Filter Mode :', // Appears next to field 'type': 'radio', // Makes this setting a series of radio elements 'options': ['Hide', 'Highlight'], // Possible choices 'default': 'Hide' // Default value if user doesn't change it }, 'Threshold': { 'label': 'Threshold :', // Appears next to field 'type': 'text', // Makes this setting a series of radio elements 'title': 'Number of items to compare, reduce the number will improve memory usage but also reduce accuracy.', // Add a tooltip (hover over text) 'size': 5, // Limit length of input (default is 25) 'default': '200' // Default value if user doesn't change it }, 'HighlightBackgroundColor': { 'label': 'Highlight Background Color :', // Appears next to field 'type': 'text', // Makes this setting a text input 'title': 'Color HEX format. (e.g. #3366AA)', // Add a tooltip (hover over text) 'size': 8, // Limit length of input (default is 25) 'default': '#EBCBCB' // Default value if user doesn't change it }, 'HighlightFontColor': { 'label': 'Highlight Font Color :', // Appears next to field 'type': 'text', // Makes this setting a text input 'title': 'Color HEX format. (e.g. #3366AA)', // Add a tooltip (hover over text) 'size': 8, // Limit length of input (default is 25) 'default': '#797979' // Default value if user doesn't change it }, 'Regex': { 'label': 'Match by Regular expressions :', // Appears next to field 'type': 'textarea', // Makes this setting a text input 'title': 'Please be careful to use this field, if you don\'t sure, just leave it blank.', // Add a tooltip (hover over text) 'default': '' // Please be careful to use this. } }, 'events': { 'open': function (doc) { var config = this; doc.getElementById(config.id + '_field_Regex').cols = 65; doc.getElementById(config.id + '_field_Regex').rows = 5; doc.getElementById(config.id + '_field_Regex').style = "font-size:12px;"; }, 'save': function(values) { GM_config.close(); } } }); GM_registerMenuCommand( "Open Config", function(){ GM_config.open(); }); var box = document.getElementById("box"); box.addEventListener("DOMNodeInserted", function(){ var filtermode = GM_config.get('FilterMode').toUpperCase(); var threshold = GM_config.get('Threshold'); var bgcolor = GM_config.get('HighlightBackgroundColor'); var fontcolor = GM_config.get('HighlightFontColor'); var regex = GM_config.get('Regex'); var a=document.getElementsByClassName("u0Entry"); var uEntry=a.length>0?a:null; var arr = new Array(); var idx = new Array(); var endto = (uEntry.length >= threshold ? (uEntry.length - threshold) : 0); for(var y=uEntry.length-1; y>=endto; y--) { //Comment for v1.0.4 fix. /*if (uEntry[y].style.display == 'none' || uEntry[y].style.backgroundColor == bgcolor) { arr.push("[Filtered]"); idx.push(""); } else {*/ arr.push(uEntry[y].attributes["data-title"].value);/*data-alternate-link*/ idx.push(y); //} } var i = arr.length, j, val; while (i--) { val = arr[i]; j = i; while (j--) { if (arr[j] === val || (regex != '' && regexMatch(val, regex)) ) { //console.log("[Duplicate found] " + "Reference : " + val + " | " + "Value : " + arr[j]); if (filtermode == 'HIDE') uEntry[idx[i]].setAttribute("style","display:none"); /*To hide the duplicate.*/ else if (filtermode == 'HIGHLIGHT') { /* Or you may want to highlight the duplicate instead of hide. */ uEntry[idx[i]].setAttribute("style","background-color: " + bgcolor); uEntry[idx[i]].getElementsByTagName("div")[4].getElementsByTagName("a")[0].setAttribute("style","color: " + fontcolor); } } } } }, false); function replaceAll(find, replace, str) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); } function regexMatch(str, regex) { if (regex == '') return false; try{ return (str.match(regex) != null); } catch (ex) { return false; } }
how can i use this on cards view mode?
回覆刪除It support the title view (like Google Reader) only. Due to i suppose this temporary solution and feedly should do it soon...
刪除火狐31、油猴子2.1。
回覆刪除腳本好像對臉書粉絲團無效,對新聞網站有效。