navchandar / Twitter HQ Photo Downloader

// ==UserScript==
// @name            Twitter HQ Photo Downloader
// @version         1.0
// @description     Click button to download HQ photo from twitter.com.
// @author          navchandar
// @homepage        https://github.com/navchandar
// @copyright       2020, navchandar (https://openuserjs.org/users/navchandar)
// @grant           GM_openInTab
// @grant           GM_download
// @grant           GM_addStyle
// @match           *://*.twitter.com/*
// @run-at          document-end
// @require         http://code.jquery.com/jquery-3.4.1.min.js
// @updateURL       https://openuserjs.org/meta/navchandar/Twitter_HQ_Photo_Downloader.meta.js
// @downloadURL     https://openuserjs.org/install/navchandar/Twitter_HQ_Photo_Downloader.user.js
// @icon            data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABTVBMVEUdofIcofIaoPIboPIvqfNHs/RCsPQnpfMfovIho/I7rvQeofIjo/J4x/fU7f3w+f7s9/7A5ftYuvU6rfRyxPdEsfQ5rfTJ6Pxmv/Z/yvj4/P/////t+P7j8/204PtAsPROtfX0+v57yPclpPI4rPTd8f3J6fxuw/ceovJDsfTr9/624ftXufUlpfIWnvL5/f+S0vkmpfMkpPK24Pvy+v7B5fuHzfhcu/Z9yfj6/f/h8/01q/MuqPN3x/fm9f71+/7+///Z7/1GsvTe8f3z+v7C5vy64vuY1PlJs/XS7Pz2+/9kvvbO6vz+/v/F5/wqpvP2+/5nwPYopvOe1/mj2fpbu/a54vv9/v+84/syqvMgovKFzPj7/f+x3/s2q/NUuPWh2PrM6vyAyvgppvNNtfXH6Pzv+P7y+f7c8f18yPdHsvRLtPUzqvMio/IcoPJuec6iAAAAAWJLR0QbAmDUpAAAAAd0SU1FB+IEAxMjDa4VD/IAAAEXSURBVDjLY2AYpoCRiZkRU5QZLs3MwsrGzszMzIEiz8nFDZXn4eXjFxAUEhYRZUbWLyYuATGXUVJKGghkZOXkkY1gUlAUUFJmYmRgVlGVBgMpNXUNZBM0taSltHV0mfR0pCAK9A0MkV3KaGQMFDQxNTO3sIQosLJGdgIDo42tHUSjvQNEgSMLileZnJxdpFGAqxFq2Bi6ocpLu6PYAHSlh6cDsryXORN6+Hr7+CIp8PNHD21m2wAk+YBAdAMYGIOCkVSE8GBGFzNnaFg4VD4ikhldmjOKXTPaGSIdExuHIc8Rn5AoA/FGuGpSMoY8AwNPikGqbFq6QEZYphi25AIMS2ZDlaxszZxcJmYGHICRmYmJOY9heAIA9ZQq6UkXW+AAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTgtMDQtMDNUMTk6MzU6MTMrMDI6MDAxgFSMAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE4LTA0LTAzVDE5OjM1OjEzKzAyOjAwQN3sMAAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAABXelRYdFJhdyBwcm9maWxlIHR5cGUgaXB0YwAAeJzj8gwIcVYoKMpPy8xJ5VIAAyMLLmMLEyMTS5MUAxMgRIA0w2QDI7NUIMvY1MjEzMQcxAfLgEigSi4A6hcRdPJCNZUAAAAASUVORK5CYII=
// @license         MIT
// ==/UserScript==

function getElementsByXPath(xpath, parent) {
  let results = [];
  let query = document.evaluate(xpath, parent || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  for (let i = 0, length = query.snapshotLength; i < length; ++i) {
    results.push(query.snapshotItem(i));
  }
  return results
};

function has(String, search) {
  try {
    if (String.indexOf(search) > -1) {
      return true;
    }
  }
  catch (err) {}
  return false;
}

function saveStory(zEvent) {
  let parent = document.elementFromPoint(innerWidth / 2, innerHeight / 2).parentNode.parentNode.parentNode.parentNode,
    video = parent.querySelector("video source"),
    image = parent.querySelector("img");
  if (!video && !image) {
    parent = document.elementFromPoint(innerWidth / 2, innerHeight / 2).parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
    video = parent.querySelector("video source");
    image = parent.querySelector("img");
  }
  if (video) {
    GM_download(video.getAttribute("src"), "Twitter_vid.mp4");
  }
  else if (image) {
    GM_download(image.getAttribute("src").replace('format=jpg', 'format=png').replace('name=small', 'name=large'), "Twitter_img.png");
  }
  else {
    console.log("Nothing img/video found to save.")
  }
}

function openStory(zEvent) {
  let parent = document.elementFromPoint(innerWidth / 2, innerHeight / 2).parentNode.parentNode.parentNode.parentNode,
    video = parent.querySelector("video source"),
    image = parent.querySelector("img");
  if (!video && !image) {
    parent = document.elementFromPoint(innerWidth / 2, innerHeight / 2).parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
    video = parent.querySelector("video source");
    image = parent.querySelector("img");
  }
  if (video) {
    GM_openInTab(video.getAttribute("src"), "Twitter_vid.mp4");
  }
  else if (image) {
    GM_openInTab(image.getAttribute("src").replace('format=jpg', 'format=png').replace('name=small', 'name=large'), "Twitter_img.png");
  }
  else {
    console.log("Nothing img/video found to open.")
  }
}

function AddButton() {
  // Add a button element on div
  var zNode = document.createElement('div');
  zNode.innerHTML = '<button id="openButton" title="Click to open this photo" type="button">Open</button>';
  zNode.setAttribute('id', 'myContainer1');
  document.body.appendChild(zNode);
  zNode = document.createElement('div');
  zNode.innerHTML = '<button id="saveButton" title="Click to download this photo" type="button">Save</button>';
  zNode.setAttribute('id', 'myContainer2');
  document.body.appendChild(zNode);

  //--- Activate the newly added button.
  document.getElementById("saveButton").addEventListener("click", saveStory, false);
  document.getElementById("openButton").addEventListener("click", openStory, false);

  //--- Style our newly added element using CSS.
  GM_addStyle(`
#myContainer1{position:fixed;bottom:.25em;left:51%;right:48%;margin:0;width:5%;height:6%;text-align:center}
#myContainer2{position:fixed;bottom:.25em;left:47%;right:48%;margin:0;width:5%;height:6%;text-align:center}
#openButton{opacity:.55;cursor:pointer;background-color:#262626;color:White;font-size:12px;border-radius:7px;padding:2.5px}
#saveButton{opacity:.55;cursor:pointer;background-color:#262626;color:White;font-size:12px;border-radius:7px;padding:2.5px}
#saveButton:hover,#openButton:hover{color:White;opacity:1}
`);
}

function HideBtn() {
  document.getElementById('openButton').style.visibility = 'hidden';
  document.getElementById('saveButton').style.visibility = 'hidden';
}

function UnHideBtn() {
  document.getElementById('openButton').style.visibility = 'visible';
  document.getElementById('saveButton').style.visibility = 'visible';
}

(function () {
  'use strict';
  AddButton();
  HideBtn();

  // call this every 2 seconds to update according to page load
  setInterval(function () {
    var hostURL = window.location.href;
    if (has(hostURL, 'twitter.com') && has(hostURL, 'photo')) {
      UnHideBtn();
    }
    else {
      HideBtn();
    }
  }, 2000);

})();