Wednesday, March 8, 2017

My script for blocking GIF

I cannot find a good animation block extension for Opera and Yandex which are my current favorite browsers for Windows and Android, respectively. GIF Jam jams loading of a page while jamming GIF. So is GIF Blocker, although faster. Stop Animations does not block GIF by default; so you have to press ESC key all the time - quite a hassle and no ESC key on a phone.

Therefore I had to make one. I found a script that does what is similar to Stop Animations. I changed it to block GIF by default. I also added a transparent "GIF" button to unblock (or block) GIF on the fly and save the option to the site via cookie (Opera does not support GM_setValue, code is from here).


This button is located at the bottom right corner. On the phone, this button might be a little hard to find if you zoom the page. The button label is gray if blocking is enabled (default) and, if one or more GIF images got blocked, it becomes red, or green if disabled (not blocking). So you'll know if you are missing something. This script does not add obvious slowdown and other side effects.

Related article: KoT's Dynamic Content BlockerMy ad-block script

This script has been (on 03/09/2017) and will be updated without notice

// ==UserScript==
// @name         KoT's Content Blocker
// @namespace    http://www.kots.us
// @grant        none
// @exclude      https://xfinity.nnu.com/xfinitywifi/main
// @exclude      https://www.blogger.com/*
// @exclude      https://groups.google.com/forum/*
// ==/UserScript==

/* add your items not to be blocked */

var NOT_TO_REMOVE = 
    ':not([src*=\'youtu\'])' +
    ':not([src*=\'dailymotion\'])' +
    ':not([src*=\'youku\'])' +
    ':not([src*=\'tudou\'])' +
    ':not([src*=\'powermv\'])' +
    ':not([src*=\'dramafever\'])' +
    ':not([src*=\'vimeo\'])' +
    ':not([src*=\'liveguidestationplayer\'])' +
    ':not([src*=\'RoutePositionET\'])' +
    ':not([src*=\'blogger.com\'])' +
    ':not([src*=\'chase.com\'])' +
    ':not([src*=\'/tob/live/usp-core\'])'   
;

/* add your items to be blocked */

var TO_REMOVE = 'div[id*=\'carousel\']' +
    ',div[id*=\'Carousel\']' +
    ',iframe[src^=\'/news/index.php?act=getiframe\']' +
    ',iframe[src^=\'javascript\']'
;

/* add special items to be blocked */

function blockSpecialItems() {
  var m = document.getElementById('scrollWrap');
  if (m !== null) {
    m.id = 'scrollWrap_';
    m = document.getElementById('scrollMsg');
    if (m !== null) {
      m.parentNode.removeChild(m);
    }
  }
}

/* no need to change below */

function getCookie(w){
cName = "";
pCOOKIES = new Array();
pCOOKIES = document.cookie.split('; ');
for(bb = 0; bb < pCOOKIES.length; bb++){
NmeVal  = new Array();
NmeVal  = pCOOKIES[bb].split('=');
if(NmeVal[0] == w){
cName = unescape(NmeVal[1]);
}
}
return cName;
}

function setCookie(name, value, expires, path, domain, secure){
cookieStr = name + "=" + escape(value) + "; ";

if(expires){
expires = setExpiration(expires);
cookieStr += "expires=" + expires + "; ";
}
if(path){
cookieStr += "path=" + path + "; ";
}
if(domain){
cookieStr += "domain=" + domain + "; ";
}
if(secure){
cookieStr += "secure; ";
}

document.cookie = cookieStr;
}

function setExpiration(cookieLife){
    var today = new Date();
    var expr = new Date(today.getTime() + 
                        cookieLife * 24 * 60 * 60 * 1000);
    return  expr.toGMTString();
}

function is_gif_image(i) {
  return /^(?!data:).*\.gif/i.test(i.src);
}

function freeze_gif(i) {

  hasGIF = true;
  
  var c = document.createElement('canvas');
  var w = c.width = i.width;
  var h = c.height = i.height;
  c.getContext('2d').drawImage(i, 0, 0, w, h);
  try {
    // if possible, retain all css aspects
    i.src = c.toDataURL("image/gif");
  } catch(e) {
    // cross-domain -- mimic original with all its tag attribs
    for (var j = 0, a; a = i.attributes[j]; j++)
      c.setAttribute(a.name, a.value);
    i.parentNode.replaceChild(c, i);
  }
}

function blockMarquee() {
  var m = document.getElementsByTagName('marquee');
  while( m.length > 0) {
    var p = document.createElement('div');
    p.innerHTML = m[0].innerHTML;
    var wth = (m[0].style.width == "") ? "350" : m[0].style.width;
    var stl = "clear: both; white-space: nowrap; overflow: hidden;" +
        "text-overflow: ellipsis; width:" + wth + ";";
    p.setAttribute('style', stl);
    m[0].parentNode.insertBefore(p, m[0]);
    m[0].parentNode.removeChild(m[0]);
  }
}

function blockContents(elements) {
  for (var i = 0; i < elements.length; i++) {
    hasIframe = true;
    var frm = document.createElement("iframe");
    frm.width = elements[i].width;
    frm.height = elements[i].height;
    frm.style.border = "none";
    frm.style.float = elements[i].style.float;
    frm.style.position = elements[i].style.position;
    elements[i].parentNode.replaceChild(frm, elements[i]);
  } 
}

function createButton(label) {
  if(label == 'GiF') {
    var rt = '1%';
    var ck = 'blockGIF';
    var hs = hasGIF;
  }
  else {
    rt = '7%';
    ck = 'blockIframe';
    hs = hasIframe;
  }
  var btn = document.createElement( 'input' );
  with( btn ) {
    onclick = function() {
      if (getCookie(ck) !== 'No') {
        setCookie(ck, 'No', 3650);
      }
      else { 
        setCookie(ck, '', -1); 
        setCookie(ck, '', -1, '/'); 
      }  
      location.reload();
    };
    setAttribute( 'value', label );
    setAttribute( 'type', 'button' );
    var stl = "font-size: 18px; position: fixed;bottom: 1%;" +
        "background-color: Transparent; background-repeat:" + 
        "no-repeat; cursor: pointer; overflow: hidden;" + 
        "right:" + rt + ";" + "color:";
    if (getCookie(ck) !== "No")
      if (hs)
        stl += "red;";
      else
        stl += "gray;";
    else
      stl += "green;";
   setAttribute( 'style', stl );
  }
  document.body.appendChild(btn);  
}

function doBlock() {

  if (getCookie('blockIframe') !== 'No') {
    blockContents(document.querySelectorAll(NOT_TO_REMOVE));
    blockContents(document.querySelectorAll(TO_REMOVE)); 
  }
  
  if (getCookie('blockGIF') !== 'No')
    [].slice.apply(document.images).filter(is_gif_image)
      .map(freeze_gif);
  
  createButton ('GiF');
  createButton ('FrM'); 
  
}

//for main frame only:
if (window.top !== window.self)
  return;

var hasGIF = false;
var hasIframe = false;

NOT_TO_REMOVE = 'iframe:not([src])' + NOT_TO_REMOVE + 
  ',iframe[src^=\'http\']' + NOT_TO_REMOVE;

blockSpecialItems();
blockMarquee();

doBlock();
  
//some items are delayed to show up
window.addEventListener ('load', function(){ 
  doBlock();
  window.setTimeout(doBlock, 4000);

}, false);

No comments:

Post a Comment