Greasy Fork is available in English.

Pikabu download video helper

Helpers for display direct url for video

Versão de: 23/10/2022. Veja: a última versão.

  1. // ==UserScript==
  2. // @name Pikabu download video helper
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3
  5. // @description Helpers for display direct url for video
  6. // @author Apkawa
  7. // @license MIT
  8. // @icon https://www.google.com/s2/favicons?domain=pikabu.ru
  9. // @match https://pikabu.ru/*
  10. // @homepage https://github.com/Apkawa/userscripts
  11. // @homepageUrl https://github.com/Apkawa/userscripts
  12. // @supportUrl https://github.com/Apkawa/userscripts/issues
  13. // @downloadUrl https://github.com/Apkawa/userscripts/raw/master/dist/pikabu.ru/video_url.user.js
  14. // @updateUrl https://github.com/Apkawa/userscripts/raw/master/dist/pikabu.ru/video_url.user.js
  15. // ==/UserScript==
  16. (function() {
  17. "use strict";
  18. function waitElement(match, callback) {
  19. const observer = new MutationObserver((mutations => {
  20. let matchFlag = false;
  21. mutations.forEach((mutation => {
  22. if (!mutation.addedNodes) return;
  23. for (let i = 0; i < mutation.addedNodes.length; i++) {
  24. const node = mutation.addedNodes[i];
  25. matchFlag = match(node);
  26. }
  27. }));
  28. if (matchFlag) {
  29. _stop();
  30. callback();
  31. _start();
  32. }
  33. }));
  34. let isStarted = false;
  35. function _start() {
  36. if (isStarted) return;
  37. observer.observe(document.body, {
  38. childList: true,
  39. subtree: true,
  40. attributes: true,
  41. characterData: false
  42. });
  43. isStarted = true;
  44. }
  45. function _stop() {
  46. observer.disconnect();
  47. isStarted = false;
  48. }
  49. _start();
  50. return () => {
  51. _stop();
  52. };
  53. }
  54. function isFunction(x) {
  55. return "function" === typeof x;
  56. }
  57. function matchLocation(...patterns) {
  58. const s = document.location.href;
  59. for (const p of patterns) {
  60. if (isFunction(p) && p(s)) return true;
  61. if (RegExp(p).test(s)) return true;
  62. }
  63. return false;
  64. }
  65. Object.keys;
  66. Object.entries;
  67. (function() {
  68. "use strict";
  69. if (!matchLocation("^https://pikabu.ru/.*")) return;
  70. function addDownloadButtonsForVideo(el) {
  71. var _a, _b, _c;
  72. if (el.getAttribute("linked")) return;
  73. const source = null === (_a = el.dataset.source) || void 0 === _a ? void 0 : _a.replace(/\.\w{3,4}$/, "");
  74. el.setAttribute("linked", "1");
  75. if (!(null === source || void 0 === source ? void 0 : source.match("pikabu.ru"))) return;
  76. const name = source.split("/").pop();
  77. const container = document.createElement("div");
  78. container.setAttribute("style", `display: flex; width: 100%; height: 25px; \n align-items: center; justify-content: flex-start`);
  79. let html = "";
  80. const extensions = [ "mp4", "webm" ];
  81. if (null === (_b = el.dataset.source) || void 0 === _b ? void 0 : _b.endsWith(".gif")) extensions.unshift("gif");
  82. for (const ext of extensions) {
  83. const s = (null === (_c = el.dataset) || void 0 === _c ? void 0 : _c[ext]) || `${source}.${ext}`;
  84. html += `<a \n href="${s}" \n style="padding: 5px; margin-right: 5px; \n border: gray 1px solid; border-radius: 3px; height: 20px"\n download="${name || "download"}.${ext}"\n target="_blank"\n >${ext}</a>`;
  85. }
  86. container.innerHTML = html;
  87. el.parentNode && el.parentNode.insertBefore(container, el.nextSibling);
  88. }
  89. waitElement((el => {
  90. const _el = el;
  91. return Boolean(_el.querySelectorAll && _el.querySelectorAll(".player"));
  92. }), (() => {
  93. document.querySelectorAll && document.querySelectorAll(".player").forEach((el => addDownloadButtonsForVideo(el)));
  94. }));
  95. })();
  96. })();