Skip to content

Instantly share code, notes, and snippets.

@JenieX
Created August 22, 2023 02:47
Show Gist options
  • Save JenieX/f325c5b61165c5b9987cba133a65ac13 to your computer and use it in GitHub Desktop.
Save JenieX/f325c5b61165c5b9987cba133a65ac13 to your computer and use it in GitHub Desktop.
Userscript: Safeguard — Unbreak the web by preventing sites from blocking default browser behavior such as copy-paste, context menus, text selection, etc.
// ==UserScript==
// @name Safeguard
// @description Unbreak the web by preventing sites from blocking default browser behavior such as copy-paste, context menus, text selection, etc.
// @match <all_urls>
// @run-at document-start
// @version 2023.08.21.1
// @downloadURL https://gist.github.com/msanders/76923c70348086108ca47e7b46ffc97c/raw/safeguard.user.js
// @updateURL https://gist.github.com/msanders/76923c70348086108ca47e7b46ffc97c/raw/safeguard.user.js
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEwAAABMCAMAAADwSaEZAAAARVBMVEVHcEzZOy8AAAAAAADfTz4AAAAAAAAAAAAAAAABAQElFxY0NDNwcG+mpaRSUlLPzs27urnqWkeSkpGuLCRxIhvSLyfDSzsFvPdkAAAACXRSTlMA+eU8+8J0G6R5tfGAAAACbElEQVR4Xu2X25bqMAxD6b1yrr3A/3/qwfFAVsmcJpm+okcoG0l2utrbmb766qupG8dxHp/qpkuccWhxUDuM3Z9Is4BAygYpggDnWl43MEdp412U80arwBtrXDFKrf7NWNdINZZxxe5GADaQvJZwIlL651MAcxlrBhSjvCUkop+vgKHQl2ZUaIf2R98vS3N/atv2QCfGrWXehKWZ9OgX0f2tjXlWaPneBtCTpRi1vMTOogjhEp0POgHeOQvsgonWojZAOeeBKbdgQLhuY8QJbXUO6EpgCrR8qD/QdraWdzYxDOC+Tq0R27/9EXZPYAZtwWYYl1bWpLC1YG0HaKewJ40lnemCrR3DdXQWkmHWWYxZWBcS0LkzYvsMywlwnmFnNCl2KoRhOZvAJtcUHfQ1sxtxmFnNsOk4l6Z2mHECOplAdf/xDJjP0pL+vfRfeAYeSchD/3KY8hrS0prM/hevbUoDtCOurLA0D/RpaTGlVFaiNvzz/r9x7oVbJhqR5uyrU8ac3n/Msz5lzGmdBf0+AOJZSsrieRqxlg4T8A4xZdlhl1VLjaW3//zt9mjteCsj2djyERinQOkwCST1V2gWa9tn0I0bU1x/pbXjQF8hVbUxseaA/eiMAOeIjdVaW936Dtq/QhpOX8mSM+UsTzT2D1i2O9+qFX6pgP4dEgDz21u9Os7kKNAiy8tTWbVmDurBtObFcpD269VCCe3R3DdhUQxZH1QHAPbXQ3FuxfKvBBbxcX1MADW09QkxRCZ5kajXHGiiVcq/RtPC0sK6SrPMstcyxt7IGJLuL6trEV9XL2uak4iXcPlV/eqrr/4BhvZnD6AVFs0AAAAASUVORK5CYII=
// ==/UserScript==
// Tested on Greasemonkey and Violentmonkey for Firefox, and Userscripts for
// Safari.
//
// When using Violentmonkey, the Synchronous page mode or Alternative page mode
// in Firefox setting is recommended for earlier injection.
(() => {
"use strict";
const BLOCKED_EVENT_TYPES = new Set([
// Protect text selection.
"selectstart",
"selectionchange",
// Protect copy, cut and paste.
"copy",
"cut",
"paste",
]);
const BLOCKED_META_EVENT_TYPES = new Set([
// Protect command-click.
"mousedown",
"mouseup",
"click",
]);
const BLOCKED_ALT_EVENT_TYPES = new Set([
// Protect contextual menus with option key.
// Protect option-click.
"contextmenu",
"mousedown",
]);
const BLOCKED_META_ALT_CTRL_EVENT_TYPES = new Set([
// Protect command-key, option-key, and control-key shortcuts.
"keydown",
"keyup",
"keypress",
]);
const DRAG_EVENT_TYPES = new Set([
// Protect drag.
"dragstart",
"drag",
]);
const DROP_EVENT_TYPES = new Set([
// Protect drop.
"dragenter",
"dragexit",
"dragleave",
"drop",
]);
const blockEvent = event => {
event.stopImmediatePropagation();
};
const blockMetaEvent = event => {
if (event.metaKey) {
blockEvent(event);
}
};
const blockAltEvent = event => {
if (event.altKey) {
blockEvent(event);
}
};
const blockMetaAltCtrlEvent = event => {
if (event.metaKey || event.altKey || event.ctrlKey) {
blockEvent(event);
}
};
const protectDragEvent = event => {
const selectionNode = window.getSelection().anchorNode;
// Preserve default drag behavior for links, images, and selected text.
if (
(event.target.nodeName === "A" && !event.target.isContentEditable) ||
event.target.nodeName === "IMG" ||
selectionNode === event.target ||
selectionNode?.parentNode === event.target
) {
blockEvent(event);
}
};
const protectDropEvent = event => {
// Preserve default drop behavior onto <input> and <textarea> except for
// file uploads.
if (
event.target.nodeName === "INPUT" ||
(event.target.nodeName === "TEXTAREA" &&
(event.dataTransfer === null || event.dataTransfer.files.length === 0))
) {
blockEvent(event);
}
};
// Significantly faster than GM.addStyle and compatible with Greasemonkey.
const addStyle = code => {
const style = document.createElement("style");
style.textContent = code;
document.head.appendChild(style);
};
// From
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
const difference = (setA, setB) => {
const _difference = new Set(setA);
for (const elem of setB) {
_difference.delete(elem);
}
return _difference;
};
const afterLoad = () => {
const cssProperties = ["user-drag", "user-select"];
const cssPropertyValue = "unset";
const supportedCSSProperties = cssProperties.filter(property =>
CSS.supports(property, cssPropertyValue)
);
const vendoredCSSProperties = [
...difference(cssProperties, supportedCSSProperties),
]
.map(x => "-webkit-" + x)
.filter(x => CSS.supports(x, cssPropertyValue));
const formattedCSSRules = supportedCSSProperties
.concat(vendoredCSSProperties)
.map(x => `${x}:${cssPropertyValue} !important`)
.join(";");
addStyle(`*{${formattedCSSRules}}`);
};
const beforeLoad = () => {
for (const name of BLOCKED_ALT_EVENT_TYPES) {
window.addEventListener(name, blockAltEvent, true);
}
for (const name of BLOCKED_META_EVENT_TYPES) {
window.addEventListener(name, blockMetaEvent, true);
}
for (const name of BLOCKED_META_ALT_CTRL_EVENT_TYPES) {
window.addEventListener(name, blockMetaAltCtrlEvent, true);
}
for (const name of BLOCKED_EVENT_TYPES) {
window.addEventListener(name, blockEvent, true);
}
for (const name of DRAG_EVENT_TYPES) {
window.addEventListener(name, protectDragEvent, true);
}
for (const name of DROP_EVENT_TYPES) {
window.addEventListener(name, protectDropEvent, true);
}
if (document.readyState === "complete") {
afterLoad();
} else {
window.addEventListener("load", afterLoad);
}
};
beforeLoad();
})();
/* ==UserStyle==
@name Substitute Web Fonts
@description Replace Arial and Courier New with Helvetica and Courier.
@version 2023.08.21
@downloadURL https://gist.github.com/msanders/76923c70348086108ca47e7b46ffc97c/raw/substitute-web-fonts.user.js
@updateURL https://gist.github.com/msanders/76923c70348086108ca47e7b46ffc97c/raw/substitute-web-fonts.user.js
@match <all_urls>
==/UserStyle== */
/* From https://underpassapp.com/news/2022-11-3.html
* NOTE: Currently only compatible with Safari. */
@font-face {
font-family: "Arial";
font-stretch: 50% 200%;
font-style: normal;
font-weight: 1 1000;
src: local("Helvetica");
}
@font-face {
font-family: "Arial";
font-stretch: 50% 200%;
font-style: italic;
font-weight: 1 1000;
src: local("Helvetica");
}
@font-face {
font-family: "Arial";
font-stretch: 50% 200%;
font-style: oblique;
font-weight: 1 1000;
src: local("Helvetica");
}
@font-face {
font-family: "Courier New";
font-stretch: 50% 200%;
font-style: normal;
font-weight: 1 1000;
src: local("Courier");
}
@font-face {
font-family: "Courier New";
font-stretch: 50% 200%;
font-style: italic;
font-weight: 1 1000;
src: local("Courier");
}
@font-face {
font-family: "Courier New";
font-stretch: 50% 200%;
font-style: oblique;
font-weight: 1 1000;
src: local("Courier");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment