Venipa / Coub-Bridge

// ==UserScript==
// @name         Coub-Bridge
// @namespace    https://github.com/Venipa/coubdl-bridge
// @copyright    2021, coubdownload-bridge-userscript (https://github.com/Venipa/coubdl-bridge)
// @version      0.2.3
// @description  Bridge between the desktop and webbrowser to download and merge video & audio from coub
// @author       Venipa
// @match        https://*.coub.com/*
// @match        https://coub.com/*
// @grant        none
// @license      MIT
// ==/UserScript==
// ==OpenUserJS==
// @author Venipa
// ==/OpenUserJS==
(()=>{"use strict";const r=function(r,e){for(var n=-1,t=e.length,o=r.length;++n<t;)r[o+n]=e[n];return r};const e="object"==typeof global&&global&&global.Object===Object&&global;var n="object"==typeof self&&self&&self.Object===Object&&self;const t=(e||n||Function("return this")()).Symbol;var o=Object.prototype,a=o.hasOwnProperty,c=o.toString,i=t?t.toStringTag:void 0;const l=function(r){var e=a.call(r,i),n=r[i];try{r[i]=void 0;var t=!0}catch(r){}var o=c.call(r);return t&&(e?r[i]=n:delete r[i]),o};var u=Object.prototype.toString;const d=function(r){return u.call(r)};var s=t?t.toStringTag:void 0;const f=function(r){return null==r?void 0===r?"[object Undefined]":"[object Null]":s&&s in Object(r)?l(r):d(r)};const b=function(r){return null!=r&&"object"==typeof r};const p=function(r){return b(r)&&"[object Arguments]"==f(r)};var g=Object.prototype,v=g.hasOwnProperty,y=g.propertyIsEnumerable;const h=p(function(){return arguments}())?p:function(r){return b(r)&&v.call(r,"callee")&&!y.call(r,"callee")};const m=Array.isArray;var w=t?t.isConcatSpreadable:void 0;const x=function(r){return m(r)||h(r)||!!(w&&r&&r[w])};const A=function e(n,t,o,a,c){var i=-1,l=n.length;for(o||(o=x),c||(c=[]);++i<l;){var u=n[i];t>0&&o(u)?t>1?e(u,t-1,o,a,c):r(c,u):a||(c[c.length]=u)}return c};const S=function(r){return(null==r?0:r.length)?A(r,1):[]};function O(r){return function(r){if(Array.isArray(r))return j(r)}(r)||function(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}(r)||function(r,e){if(!r)return;if("string"==typeof r)return j(r,e);var n=Object.prototype.toString.call(r).slice(8,-1);"Object"===n&&r.constructor&&(n=r.constructor.name);if("Map"===n||"Set"===n)return Array.from(r);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return j(r,e)}(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function j(r,e){(null==e||e>r.length)&&(e=r.length);for(var n=0,t=new Array(e);n<e;n++)t[n]=r[n];return t}function k(r,e,n){var t,o,a=document.createElement(r);(Object.assign(a.style,n),null==e?void 0:e.class)&&(o=a.classList).add.apply(o,O(S([e.class])));return a.id=null==e?void 0:e.id,(null===(t=null==e?void 0:e.children)||void 0===t?void 0:t.length)&&e.children.every((function(r){return a.appendChild(r)})),a}function _(r,e){var n=document.createElement("a");return r&&(n.innerText=r),n.classList.add("coubdl-button"),Object.assign(n.style,e),n}function E(){var r=document.createElement("div");r.classList.add("coubdl-button-group");for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];return n.length>0&&n.forEach((function(e,n){e.classList.contains("coubdl-seperator")||e.classList.add("coubdl-button-group-item"),r.appendChild(e)})),r}function L(r,e){for(var n=0;n<e.length;n++){var t=e[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,t.key,t)}}var q=function(){function r(e){!function(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}(this,r),this.name=e}var e,n,t;return e=r,n=[{key:"debug",value:function(r){}},{key:"info",value:function(r){for(var e,n=arguments.length,t=new Array(n>1?n-1:0),o=1;o<n;o++)t[o-1]=arguments[o];(e=console).log.apply(e,["".concat(this.name),r].concat(t))}},{key:"warn",value:function(r){for(var e,n=arguments.length,t=new Array(n>1?n-1:0),o=1;o<n;o++)t[o-1]=arguments[o];(e=console).warn.apply(e,["".concat(this.name),r].concat(t))}},{key:"error",value:function(r){for(var e,n=arguments.length,t=new Array(n>1?n-1:0),o=1;o<n;o++)t[o-1]=arguments[o];(e=console).error.apply(e,["".concat(this.name),r].concat(t))}},{key:"tag",value:function(r,e){for(var n,t=arguments.length,o=new Array(t>2?t-2:0),a=2;a<t;a++)o[a-2]=arguments[a];(n=console).log.apply(n,["[".concat(r,"] ").concat(this.name),e].concat(o))}}],n&&L(e.prototype,n),t&&L(e,t),Object.defineProperty(e,"prototype",{writable:!1}),r}();function C(r){return function(r){if(Array.isArray(r))return I(r)}(r)||function(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}(r)||function(r,e){if(!r)return;if("string"==typeof r)return I(r,e);var n=Object.prototype.toString.call(r).slice(8,-1);"Object"===n&&r.constructor&&(n=r.constructor.name);if("Map"===n||"Set"===n)return Array.from(r);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return I(r,e)}(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function I(r,e){(null==e||e>r.length)&&(e=r.length);for(var n=0,t=new Array(e);n<e;n++)t[n]=r[n];return t}var N=function(r,e){var n={};for(var t in r)Object.prototype.hasOwnProperty.call(r,t)&&e.indexOf(t)<0&&(n[t]=r[t]);if(null!=r&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(t=Object.getOwnPropertySymbols(r);o<t.length;o++)e.indexOf(t[o])<0&&Object.prototype.propertyIsEnumerable.call(r,t[o])&&(n[t[o]]=r[t[o]])}return n};function T(r){var e=r.env,n=e.dev,t=e.name,o=e.version,a=N(e,["dev","name","version"]),c=new q("[".concat(t,", v").concat(o,"]").concat(n?"(dev)":""));c.debug("boot",{name:"coubdownload-bridge-userscript",description:"Bridge between the desktop and webbrowser to download and merge video & audio from coub",repository:"https://github.com/Venipa/coubdl-bridge",production:!0,version:"0.2.3",style:".coubdl-button {\r\n  padding: 8px 12px;\r\n  color: #fff;\r\n  background: #000;\r\n  line-height: 1;\r\n  font-size: 0.875rem;\r\n  align-self: center;\r\n  border-radius: 4px;\r\n  position: relative;\r\n}\r\n.coubdl-button:hover,\r\n.coubdl-button:active,\r\n.coubdl-button:focus {\r\n  color: #e0e0e0;\r\n  text-decoration: none;;\r\n\r\n}\r\n.coubdl-button-group {\r\n  color: #fff;\r\n  background: #000;\r\n  line-height: 1;\r\n  font-size: 0.875rem;\r\n  display: flex;\r\n  align-self: center;\r\n  border-radius: 4px;\r\n  flex-direction: row;\r\n  align-items: center;\r\n  overflow: hidden;\r\n  box-shadow: 0.7px 3px 0.8px rgba(0, 0, 0, 0.071),\r\n    1px 4.4px 2.7px rgba(0, 0, 0, 0.065), 2px 9px 12px rgba(0, 0, 0, 0.07);\r\n}\r\n\r\n.coubdl-button-group-item {\r\n  margin: 0 0.125rem;\r\n}\r\n.coubdl-seperator {\r\n  width: 2px;\r\n  background-color: rgba(255, 255, 255, 0.185);\r\n  border-radius: 18px;\r\n  height: 18px;\r\n}\r\n"});var i="coubdl-download",l=function(r){r.filter((function(r){return r.querySelectorAll&&r.querySelector(".description__controls")})).forEach((function(r){var e,n=r.querySelector(".description__controls"),t=r;if(!(t=t.querySelector("div#coub_dl_controls"))){var o,a,c=null===(e=n.findAncestor(".coub"))||void 0===e?void 0:e.dataset.permalink;t=k("div",{id:"coub_dl_controls",children:[E.apply(void 0,C(function(){var r=_("Download");r.href="coubdl-bridge://"+c;var e=_("Looped");return e.href="coubdl-bridge://"+c+"/full",[r,e]}()).concat([(a=document.createElement("div"),a.classList.add("coubdl-seperator"),a),(o=_("GIF"),o.href="coubdl-bridge://"+c+"/gif",o),function(){var r=_("Audio");return r.href="coubdl-bridge://"+c+"/audio",r}()]))]},{height:"48px",display:"flex",flex:"1 1 auto",justifyContent:"flex-end"}),r.querySelector(".coub__description").prepend(t)}}))},u=function(r){r.filter((function(r){return r.querySelectorAll})).map((function(r){return Array.from(r.querySelectorAll(".suggest__item"))})).filter((function(r){return r.length>0})).reduce((function(r,e){return[].concat(C(r),C(e))}),[]).forEach((function(r){if(r&&r.querySelectorAll&&0===r.querySelectorAll("#"+i).length){var e=r.getAttribute("data-permalink"),n=_("Download",{padding:"4px 6px",position:"absolute",top:"0",right:"0",marginTop:"8px",marginRight:"8px",zIndex:"9999"});n.id=i,n.href="coubdl-bridge://"+e,r.prepend(n)}}))},d=new MutationObserver((function(r){var e;if((e=r.filter((function(r){return r.addedNodes&&r.addedNodes.length>0})).map((function(r){return r.addedNodes})).reduce((function(r,e){return[].concat(C(r),C(e))}),[])).length>0&&e){console.log(e);var n=e.filter((function(r){return["coub","coub-page","viewer__video","page","coub--normal-card"].filter((function(e){var n;return null===(n=r.classList)||void 0===n?void 0:n.contains(e)}))}));n.length>0&&(l(n),u(b))}})),s=new MutationObserver((function(r){d.disconnect();var e=Array.from(document.querySelectorAll(".coub.coub--page-card,.coub.coub--timeline,.coubs-list__inner .page, .cobb-page .suggests--page"));l(e),u(e),r.filter((function(r){var e;return null===(e=r.addedNodes)||void 0===e?void 0:e.length})).map((function(r){return Array.from(r.addedNodes)})).reduce((function(r,e){return[].concat(C(r),C(e))}),[]).forEach((function(r){d.observe(r,{attributes:!0,characterData:!0,childList:!0,subtree:!0})}))}));s.observe(document.documentElement,{attributes:!0,characterData:!0,childList:!0,subtree:!0});var f,b=Array.from(document.querySelectorAll(".coub.coub--page-card,.coub.coub--timeline,.coubs-list__inner .page"));l(b),u(b),window.addEventListener("keydown",(function(r){var e,n,t,o;if(r.ctrlKey&&"s"===r.key.toLowerCase()&&(null===(e=getSelection())||void 0===e?void 0:e.anchorNode)&&(n=document.querySelector(".coubs-list .coub.active[data-id][data-permalink]"))&&n.dataset.permalink){r.preventDefault();var a=n.dataset.permalink;t="coubdl-bridge://"+a+"/video",(o=document.createElement("a")).href=t,o.style.height="0",o.style.width="0",o.style.position="fixed",o.click(),o.remove()}})),f=function(){var r,e;c.debug("style add",a.style),r=a.style,(e=k("style")).innerText=r,e.dataset.type="coubdl_bridge.custom_style",document.head.appendChild(e)},c.debug("ready",document.readyState),"loading"!==document.readyState?f():window.addEventListener("DOMContentLoaded",f)}var P={name:"coubdownload-bridge-userscript",description:"Bridge between the desktop and webbrowser to download and merge video & audio from coub",repository:"https://github.com/Venipa/coubdl-bridge",production:!0,version:"0.2.3",style:".coubdl-button {\r\n  padding: 8px 12px;\r\n  color: #fff;\r\n  background: #000;\r\n  line-height: 1;\r\n  font-size: 0.875rem;\r\n  align-self: center;\r\n  border-radius: 4px;\r\n  position: relative;\r\n}\r\n.coubdl-button:hover,\r\n.coubdl-button:active,\r\n.coubdl-button:focus {\r\n  color: #e0e0e0;\r\n  text-decoration: none;;\r\n\r\n}\r\n.coubdl-button-group {\r\n  color: #fff;\r\n  background: #000;\r\n  line-height: 1;\r\n  font-size: 0.875rem;\r\n  display: flex;\r\n  align-self: center;\r\n  border-radius: 4px;\r\n  flex-direction: row;\r\n  align-items: center;\r\n  overflow: hidden;\r\n  box-shadow: 0.7px 3px 0.8px rgba(0, 0, 0, 0.071),\r\n    1px 4.4px 2.7px rgba(0, 0, 0, 0.065), 2px 9px 12px rgba(0, 0, 0, 0.07);\r\n}\r\n\r\n.coubdl-button-group-item {\r\n  margin: 0 0.125rem;\r\n}\r\n.coubdl-seperator {\r\n  width: 2px;\r\n  background-color: rgba(255, 255, 255, 0.185);\r\n  border-radius: 18px;\r\n  height: 18px;\r\n}\r\n"};Node.prototype.findAncestor=function(r){for(var e=this;(e=e.parentElement)&&!e.matches.call(e,r););return e},T({env:Object.assign({dev:!P.production},P)})})();