Created
September 9, 2023 14:46
-
-
Save spetterman66/7d3758cc104a6b9375f587b56615b50c to your computer and use it in GitHub Desktop.
Make Gartic Phone work on Legacy UXP (TenFourFox/IWPPC/Serpent/FX52esr/etc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Gartic Phone | |
// @namespace https://garticphone.com/* | |
// @include https://garticphone.com/* | |
// @run-at document-start | |
// @version 1 | |
// @grant none | |
// ==/UserScript== | |
(function (factory) { | |
typeof define === 'function' && define.amd ? define(factory) : | |
factory(); | |
})((function () { 'use strict'; | |
function _classCallCheck(instance, Constructor) { | |
if (!(instance instanceof Constructor)) { | |
throw new TypeError("Cannot call a class as a function"); | |
} | |
} | |
function _defineProperties(target, props) { | |
for (var i = 0; i < props.length; i++) { | |
var descriptor = props[i]; | |
descriptor.enumerable = descriptor.enumerable || false; | |
descriptor.configurable = true; | |
if ("value" in descriptor) descriptor.writable = true; | |
Object.defineProperty(target, descriptor.key, descriptor); | |
} | |
} | |
function _createClass(Constructor, protoProps, staticProps) { | |
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | |
if (staticProps) _defineProperties(Constructor, staticProps); | |
Object.defineProperty(Constructor, "prototype", { | |
writable: false | |
}); | |
return Constructor; | |
} | |
function _inherits(subClass, superClass) { | |
if (typeof superClass !== "function" && superClass !== null) { | |
throw new TypeError("Super expression must either be null or a function"); | |
} | |
subClass.prototype = Object.create(superClass && superClass.prototype, { | |
constructor: { | |
value: subClass, | |
writable: true, | |
configurable: true | |
} | |
}); | |
Object.defineProperty(subClass, "prototype", { | |
writable: false | |
}); | |
if (superClass) _setPrototypeOf(subClass, superClass); | |
} | |
function _getPrototypeOf(o) { | |
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { | |
return o.__proto__ || Object.getPrototypeOf(o); | |
}; | |
return _getPrototypeOf(o); | |
} | |
function _setPrototypeOf(o, p) { | |
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { | |
o.__proto__ = p; | |
return o; | |
}; | |
return _setPrototypeOf(o, p); | |
} | |
function _isNativeReflectConstruct() { | |
if (typeof Reflect === "undefined" || !Reflect.construct) return false; | |
if (Reflect.construct.sham) return false; | |
if (typeof Proxy === "function") return true; | |
try { | |
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
function _assertThisInitialized(self) { | |
if (self === void 0) { | |
throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); | |
} | |
return self; | |
} | |
function _possibleConstructorReturn(self, call) { | |
if (call && (typeof call === "object" || typeof call === "function")) { | |
return call; | |
} else if (call !== void 0) { | |
throw new TypeError("Derived constructors may only return object or undefined"); | |
} | |
return _assertThisInitialized(self); | |
} | |
function _createSuper(Derived) { | |
var hasNativeReflectConstruct = _isNativeReflectConstruct(); | |
return function _createSuperInternal() { | |
var Super = _getPrototypeOf(Derived), | |
result; | |
if (hasNativeReflectConstruct) { | |
var NewTarget = _getPrototypeOf(this).constructor; | |
result = Reflect.construct(Super, arguments, NewTarget); | |
} else { | |
result = Super.apply(this, arguments); | |
} | |
return _possibleConstructorReturn(this, result); | |
}; | |
} | |
function _superPropBase(object, property) { | |
while (!Object.prototype.hasOwnProperty.call(object, property)) { | |
object = _getPrototypeOf(object); | |
if (object === null) break; | |
} | |
return object; | |
} | |
function _get() { | |
if (typeof Reflect !== "undefined" && Reflect.get) { | |
_get = Reflect.get.bind(); | |
} else { | |
_get = function _get(target, property, receiver) { | |
var base = _superPropBase(target, property); | |
if (!base) return; | |
var desc = Object.getOwnPropertyDescriptor(base, property); | |
if (desc.get) { | |
return desc.get.call(arguments.length < 3 ? target : receiver); | |
} | |
return desc.value; | |
}; | |
} | |
return _get.apply(this, arguments); | |
} | |
var Emitter = /*#__PURE__*/function () { | |
function Emitter() { | |
_classCallCheck(this, Emitter); | |
Object.defineProperty(this, 'listeners', { | |
value: {}, | |
writable: true, | |
configurable: true | |
}); | |
} | |
_createClass(Emitter, [{ | |
key: "addEventListener", | |
value: function addEventListener(type, callback, options) { | |
if (!(type in this.listeners)) { | |
this.listeners[type] = []; | |
} | |
this.listeners[type].push({ | |
callback: callback, | |
options: options | |
}); | |
} | |
}, { | |
key: "removeEventListener", | |
value: function removeEventListener(type, callback) { | |
if (!(type in this.listeners)) { | |
return; | |
} | |
var stack = this.listeners[type]; | |
for (var i = 0, l = stack.length; i < l; i++) { | |
if (stack[i].callback === callback) { | |
stack.splice(i, 1); | |
return; | |
} | |
} | |
} | |
}, { | |
key: "dispatchEvent", | |
value: function dispatchEvent(event) { | |
if (!(event.type in this.listeners)) { | |
return; | |
} | |
var stack = this.listeners[event.type]; | |
var stackToCall = stack.slice(); | |
for (var i = 0, l = stackToCall.length; i < l; i++) { | |
var listener = stackToCall[i]; | |
try { | |
listener.callback.call(this, event); | |
} catch (e) { | |
Promise.resolve().then(function () { | |
throw e; | |
}); | |
} | |
if (listener.options && listener.options.once) { | |
this.removeEventListener(event.type, listener.callback); | |
} | |
} | |
return !event.defaultPrevented; | |
} | |
}]); | |
return Emitter; | |
}(); | |
var AbortSignal = /*#__PURE__*/function (_Emitter) { | |
_inherits(AbortSignal, _Emitter); | |
var _super = _createSuper(AbortSignal); | |
function AbortSignal() { | |
var _this; | |
_classCallCheck(this, AbortSignal); | |
_this = _super.call(this); // Some versions of babel does not transpile super() correctly for IE <= 10, if the parent | |
// constructor has failed to run, then "this.listeners" will still be undefined and then we call | |
// the parent constructor directly instead as a workaround. For general details, see babel bug: | |
// https://github.com/babel/babel/issues/3041 | |
// This hack was added as a fix for the issue described here: | |
// https://github.com/Financial-Times/polyfill-library/pull/59#issuecomment-477558042 | |
if (!_this.listeners) { | |
Emitter.call(_assertThisInitialized(_this)); | |
} // Compared to assignment, Object.defineProperty makes properties non-enumerable by default and | |
// we want Object.keys(new AbortController().signal) to be [] for compat with the native impl | |
Object.defineProperty(_assertThisInitialized(_this), 'aborted', { | |
value: false, | |
writable: true, | |
configurable: true | |
}); | |
Object.defineProperty(_assertThisInitialized(_this), 'onabort', { | |
value: null, | |
writable: true, | |
configurable: true | |
}); | |
Object.defineProperty(_assertThisInitialized(_this), 'reason', { | |
value: undefined, | |
writable: true, | |
configurable: true | |
}); | |
return _this; | |
} | |
_createClass(AbortSignal, [{ | |
key: "toString", | |
value: function toString() { | |
return '[object AbortSignal]'; | |
} | |
}, { | |
key: "dispatchEvent", | |
value: function dispatchEvent(event) { | |
if (event.type === 'abort') { | |
this.aborted = true; | |
if (typeof this.onabort === 'function') { | |
this.onabort.call(this, event); | |
} | |
} | |
_get(_getPrototypeOf(AbortSignal.prototype), "dispatchEvent", this).call(this, event); | |
} | |
}]); | |
return AbortSignal; | |
}(Emitter); | |
var AbortController = /*#__PURE__*/function () { | |
function AbortController() { | |
_classCallCheck(this, AbortController); | |
// Compared to assignment, Object.defineProperty makes properties non-enumerable by default and | |
// we want Object.keys(new AbortController()) to be [] for compat with the native impl | |
Object.defineProperty(this, 'signal', { | |
value: new AbortSignal(), | |
writable: true, | |
configurable: true | |
}); | |
} | |
_createClass(AbortController, [{ | |
key: "abort", | |
value: function abort(reason) { | |
var event; | |
try { | |
event = new Event('abort'); | |
} catch (e) { | |
if (typeof document !== 'undefined') { | |
if (!document.createEvent) { | |
// For Internet Explorer 8: | |
event = document.createEventObject(); | |
event.type = 'abort'; | |
} else { | |
// For Internet Explorer 11: | |
event = document.createEvent('Event'); | |
event.initEvent('abort', false, false); | |
} | |
} else { | |
// Fallback where document isn't available: | |
event = { | |
type: 'abort', | |
bubbles: false, | |
cancelable: false | |
}; | |
} | |
} | |
var signalReason = reason; | |
if (signalReason === undefined) { | |
if (typeof document === 'undefined') { | |
signalReason = new Error('This operation was aborted'); | |
signalReason.name = 'AbortError'; | |
} else { | |
try { | |
signalReason = new DOMException('signal is aborted without reason'); | |
} catch (err) { | |
// IE 11 does not support calling the DOMException constructor, use a | |
// regular error object on it instead. | |
signalReason = new Error('This operation was aborted'); | |
signalReason.name = 'AbortError'; | |
} | |
} | |
} | |
this.signal.reason = signalReason; | |
this.signal.dispatchEvent(event); | |
} | |
}, { | |
key: "toString", | |
value: function toString() { | |
return '[object AbortController]'; | |
} | |
}]); | |
return AbortController; | |
}(); | |
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { | |
// These are necessary to make sure that we get correct output for: | |
// Object.prototype.toString.call(new AbortController()) | |
AbortController.prototype[Symbol.toStringTag] = 'AbortController'; | |
AbortSignal.prototype[Symbol.toStringTag] = 'AbortSignal'; | |
} | |
function polyfillNeeded(self) { | |
if (self.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) { | |
console.log('__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill'); | |
return true; | |
} // Note that the "unfetch" minimal fetch polyfill defines fetch() without | |
// defining window.Request, and this polyfill need to work on top of unfetch | |
// so the below feature detection needs the !self.AbortController part. | |
// The Request.prototype check is also needed because Safari versions 11.1.2 | |
// up to and including 12.1.x has a window.AbortController present but still | |
// does NOT correctly implement abortable fetch: | |
// https://bugs.webkit.org/show_bug.cgi?id=174980#c2 | |
return typeof self.Request === 'function' && !self.Request.prototype.hasOwnProperty('signal') || !self.AbortController; | |
} | |
/** | |
* Note: the "fetch.Request" default value is available for fetch imported from | |
* the "node-fetch" package and not in browsers. This is OK since browsers | |
* will be importing umd-polyfill.js from that path "self" is passed the | |
* decorator so the default value will not be used (because browsers that define | |
* fetch also has Request). One quirky setup where self.fetch exists but | |
* self.Request does not is when the "unfetch" minimal fetch polyfill is used | |
* on top of IE11; for this case the browser will try to use the fetch.Request | |
* default value which in turn will be undefined but then then "if (Request)" | |
* will ensure that you get a patched fetch but still no Request (as expected). | |
* @param {fetch, Request = fetch.Request} | |
* @returns {fetch: abortableFetch, Request: AbortableRequest} | |
*/ | |
function abortableFetchDecorator(patchTargets) { | |
if ('function' === typeof patchTargets) { | |
patchTargets = { | |
fetch: patchTargets | |
}; | |
} | |
var _patchTargets = patchTargets, | |
fetch = _patchTargets.fetch, | |
_patchTargets$Request = _patchTargets.Request, | |
NativeRequest = _patchTargets$Request === void 0 ? fetch.Request : _patchTargets$Request, | |
NativeAbortController = _patchTargets.AbortController, | |
_patchTargets$__FORCE = _patchTargets.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL, | |
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL = _patchTargets$__FORCE === void 0 ? false : _patchTargets$__FORCE; | |
if (!polyfillNeeded({ | |
fetch: fetch, | |
Request: NativeRequest, | |
AbortController: NativeAbortController, | |
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL | |
})) { | |
return { | |
fetch: fetch, | |
Request: Request | |
}; | |
} | |
var Request = NativeRequest; // Note that the "unfetch" minimal fetch polyfill defines fetch() without | |
// defining window.Request, and this polyfill need to work on top of unfetch | |
// hence we only patch it if it's available. Also we don't patch it if signal | |
// is already available on the Request prototype because in this case support | |
// is present and the patching below can cause a crash since it assigns to | |
// request.signal which is technically a read-only property. This latter error | |
// happens when you run the main5.js node-fetch example in the repo | |
// "abortcontroller-polyfill-examples". The exact error is: | |
// request.signal = init.signal; | |
// ^ | |
// TypeError: Cannot set property signal of #<Request> which has only a getter | |
if (Request && !Request.prototype.hasOwnProperty('signal') || __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL) { | |
Request = function Request(input, init) { | |
var signal; | |
if (init && init.signal) { | |
signal = init.signal; // Never pass init.signal to the native Request implementation when the polyfill has | |
// been installed because if we're running on top of a browser with a | |
// working native AbortController (i.e. the polyfill was installed due to | |
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our | |
// fake AbortSignal to the native fetch will trigger: | |
// TypeError: Failed to construct 'Request': member signal is not of type AbortSignal. | |
delete init.signal; | |
} | |
var request = new NativeRequest(input, init); | |
if (signal) { | |
Object.defineProperty(request, 'signal', { | |
writable: false, | |
enumerable: false, | |
configurable: true, | |
value: signal | |
}); | |
} | |
return request; | |
}; | |
Request.prototype = NativeRequest.prototype; | |
} | |
var realFetch = fetch; | |
var abortableFetch = function abortableFetch(input, init) { | |
var signal = Request && Request.prototype.isPrototypeOf(input) ? input.signal : init ? init.signal : undefined; | |
if (signal) { | |
var abortError; | |
try { | |
abortError = new DOMException('Aborted', 'AbortError'); | |
} catch (err) { | |
// IE 11 does not support calling the DOMException constructor, use a | |
// regular error object on it instead. | |
abortError = new Error('Aborted'); | |
abortError.name = 'AbortError'; | |
} // Return early if already aborted, thus avoiding making an HTTP request | |
if (signal.aborted) { | |
return Promise.reject(abortError); | |
} // Turn an event into a promise, reject it once `abort` is dispatched | |
var cancellation = new Promise(function (_, reject) { | |
signal.addEventListener('abort', function () { | |
return reject(abortError); | |
}, { | |
once: true | |
}); | |
}); | |
if (init && init.signal) { | |
// Never pass .signal to the native implementation when the polyfill has | |
// been installed because if we're running on top of a browser with a | |
// working native AbortController (i.e. the polyfill was installed due to | |
// __FORCE_INSTALL_ABORTCONTROLLER_POLYFILL being set), then passing our | |
// fake AbortSignal to the native fetch will trigger: | |
// TypeError: Failed to execute 'fetch' on 'Window': member signal is not of type AbortSignal. | |
delete init.signal; | |
} // Return the fastest promise (don't need to wait for request to finish) | |
return Promise.race([cancellation, realFetch(input, init)]); | |
} | |
return realFetch(input, init); | |
}; | |
return { | |
fetch: abortableFetch, | |
Request: Request | |
}; | |
} | |
(function (self) { | |
if (!polyfillNeeded(self)) { | |
return; | |
} | |
if (!self.fetch) { | |
console.warn('fetch() is not available, cannot install abortcontroller-polyfill'); | |
return; | |
} | |
var _abortableFetch = abortableFetchDecorator(self), | |
fetch = _abortableFetch.fetch, | |
Request = _abortableFetch.Request; | |
self.fetch = fetch; | |
self.Request = Request; | |
Object.defineProperty(self, 'AbortController', { | |
writable: true, | |
enumerable: false, | |
configurable: true, | |
value: AbortController | |
}); | |
Object.defineProperty(self, 'AbortSignal', { | |
writable: true, | |
enumerable: false, | |
configurable: true, | |
value: AbortSignal | |
}); | |
})(typeof self !== 'undefined' ? self : global); | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment