Tophness / Facebook Old Meme Blocker

// ==UserScript==
// @name        Facebook Old Meme Blocker
// @namespace   fboldmemeblocker
// @include     *://www.facebook.com/*
// @description Removes old memes from newsfeed by rescaling the images and creating a database of MD5 hashes.
// @version     1
// @require https://greasyfork.org/scripts/6217-gm-config/code/GM_config.js?version=23537
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// @require https://raw.githubusercontent.com/sytelus/CryptoJS/master/rollups/md5.js
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_deleteValue
// @grant       GM_listValues
// @grant       GM_log
// @grant       GM_registerMenuCommand
// @run-at       document-idle
// ==/UserScript==
var mutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var streamSelector = 'div[id^="stream_pagelet"]';
var streamSelectorB = 'div[id^="content_container"]';
var storiesSelector = 'div[id^="topnews_main_stream"]';
var storiesSelectorB = 'div[id^="pagelet_timeline_main_column"]';
var storySelector = 'div[id^="hyperfeed_story_id"]';
var storySelectorB = 'div[class^="fbUserContent"]';
GM_config.init('Facebook Blocker Options', {
  'reset':
  {
    'label': 'Reset',
    'type': 'checkbox',
    'default': false
  },
  'weeks':
  {
    'label': 'How many weeks old can the meme be?',
    'type': 'text',
    'default': '2'
  }
});
function opengmcf() {
  GM_config.open();
}
GM_registerMenuCommand('Facebook Meme Blocker Options', opengmcf);
function toDataURL(src, callback, outputFormat) {
  var img = new Image();
  img.crossOrigin = 'Anonymous';
  img.onload = function () {
    var canvas = document.createElement('CANVAS');
    var ctx = canvas.getContext('2d');
    var dataURL;
    canvas.height = this.height / 8;
    canvas.width = this.width / 8;
    ctx.drawImage(this, 0, 0);
    dataURL = canvas.toDataURL(outputFormat);
    callback(dataURL, src);
  };
  img.src = src;
  if (img.complete || img.complete === undefined) {
    img.src = 'data:image/png;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
    img.src = src;
  }
}
function remove(story) {
  if (!story) {
    return;
  }
  story.remove();
}
var iconurl = [
  'emoji.php',
  'external.',
  'rsrc.php'
];
var mins = 60000;
var hours = mins * 60;
var days = hours * 24;
var weeks = days * 7;
var d = new Date();
var t = d.getTime();
var w = Math.round(t / weeks);


if(GM_config.get('reset')){
  var keys = GM_listValues();
  for (var i=0, key=null; key=keys[i]; i++) {
    GM_deleteValue(key);
  }
  GM_config.set('reset', false);
}

function block(story) {
  if (!story) {
    return;
  }
  if(story.getElementsByTagName('img').length == 0){
    setTimeout(function(){ block(story); }, 1000);
  }

  for (var links of story.getElementsByTagName('img')) {    
    if (links.parentNode.parentNode.attributes['rel'] && links.parentNode.parentNode.rel == 'theater') {
      toDataURL(links.src, function (dataUrl, src) {
        dataUrl = CryptoJS.MD5(dataUrl).toString();
        var names = GM_getValue(dataUrl);
        if (names) {
          var parsedar = JSON.parse(names);
          if (w - parsedar[0] > GM_config.get('weeks')) {
            remove(story);
          }
        } 
        else {
          GM_setValue(dataUrl, JSON.stringify([w]));
        }
      });
    }
  }
}
var storieslist = [];
function processB() {
  var stream = document.querySelector(streamSelectorB);
  if (!stream) {
    return;
  }
  var stories = stream.querySelectorAll(storiesSelectorB);
  if (!stories.length) {
    return;
  }
  for (var i = 0; i < stories.length; i++) {
    var story = stories[i].querySelectorAll(storySelectorB);
    if (!story.length) {
      return;
    }
    for (var i2 = 0; i2 < story.length; i2++) {
      var addcommentid = story[i2].querySelector('div[id^="addComment_"]');
      if (addcommentid) {
        addcommentid = addcommentid.id;
        if (storieslist.indexOf(addcommentid) == - 1) {
          storieslist.push(addcommentid);
          block(story[i2]);
        }
      }
    }
  }
}
function process() {
  // Locate the stream every iteration to allow for FB SPA navigation which
  // replaces the stream element
  var stream = document.querySelector(streamSelector);
  if (!stream) {
    processB();
    return;
  }
  var stories = stream.querySelectorAll(storiesSelector);
  if (!stories.length) {
    return;
  }
  for (var i = 0; i < stories.length; i++) {
    var story = stories[i].querySelectorAll(storySelector);
    if (!story.length) {
      return;
    }
    for (var i2 = 0; i2 < story.length; i2++) {
      if (story[i2] && storieslist.indexOf(story[i2].id) == -1) {
        storieslist.push(story[i2].id);
        block(story[i2]);
      }
    }
  }
}
var observer = new mutationObserver(process);
observer.observe(document.querySelector('body'), {
  'childList': true,
  'subtree': true
});