2014年1月13日星期一

Feedly Duplicate Filter 2014

轉至Feedly後,依然還要經常應付Google Reader時的1000+問題,即時超過1000條Feed未看,這還是最常出現在Delicious當中。

之前介紹過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;
 }
}

3 則留言:

  1. how can i use this on cards view mode?

    回覆刪除
    回覆
    1. It support the title view (like Google Reader) only. Due to i suppose this temporary solution and feedly should do it soon...

      刪除
  2. 火狐31、油猴子2.1。
    腳本好像對臉書粉絲團無效,對新聞網站有效。

    回覆刪除