Snapchat Unbreaker

Improve the Snapchat web experience by disabling screenshot prevention features that harm usability.

  1. // ==UserScript==
  2. // @name Snapchat Unbreaker
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.3
  5. // @description Improve the Snapchat web experience by disabling screenshot prevention features that harm usability.
  6. // @match https://web.snapchat.com/*
  7. // @match https://www.snapchat.com/web/*
  8. // @icon http://snapchat.com/favicon.ico
  9. // @license MIT
  10. // @run-at document-idle
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. function unblockControlKeyEvents() {
  18. const events = ["keydown", "keyup", "keypress"];
  19. const modifyKeys = ["Control", "Meta", "Alt", "Shift"];
  20. for (const event_type of events) {
  21. document.addEventListener(
  22. event_type,
  23. function (e) {
  24. if (modifyKeys.includes(e.key)) {
  25. e.preventDefault();
  26. e.stopPropagation();
  27. console.log(`'${event_type}' event for '${e.key}' received and prevented:`, e);
  28. e.stopImmediatePropagation();
  29. }
  30. },
  31. true
  32. );
  33. }
  34. }
  35.  
  36. function unblockEvent() {
  37. for (const event_type of arguments) {
  38. document.addEventListener(
  39. event_type,
  40. function (e) {
  41. e.stopPropagation();
  42. console.log(`'${event_type}' event received and prevented:`, e);
  43. },
  44. true
  45. );
  46. }
  47. }
  48.  
  49. function fixConsole() {
  50. const iframe = document.createElement("iframe");
  51. iframe.style.display = "none";
  52. document.body.appendChild(iframe);
  53. const nativeConsole = iframe.contentWindow.console;
  54. window.console = nativeConsole;
  55. }
  56.  
  57. function setupUnblocker() {
  58. fixConsole();
  59. unblockControlKeyEvents();
  60.  
  61. // Allow right-click without losing focus
  62. unblockEvent("contextmenu");
  63. }
  64.  
  65. console.dir("Snapchat unbreaker running!");
  66. setupUnblocker();
  67. // Run a few extra times to ensure event listeners take priority.
  68. setTimeout(setupUnblocker, 1000);
  69. setTimeout(setupUnblocker, 5000);
  70. setTimeout(setupUnblocker, 10000);
  71.  
  72. // Ensure focus is always true.
  73. document.hasFocus = function() { return true; }
  74.  
  75. })();