https://github.com/perry-mitchell/slyfox
Restore overwritten methods on the window.
https://github.com/perry-mitchell/slyfox
Last synced: 3 months ago
JSON representation
Restore overwritten methods on the window.
- Host: GitHub
- URL: https://github.com/perry-mitchell/slyfox
- Owner: perry-mitchell
- License: mit
- Created: 2015-12-25T20:45:54.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2023-12-07T11:10:37.000Z (over 2 years ago)
- Last Synced: 2026-04-01T02:44:55.559Z (3 months ago)
- Language: TypeScript
- Size: 262 KB
- Stars: 19
- Watchers: 2
- Forks: 4
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# SlyFox
> Restore overwritten methods on the window and document... **Like a fox**.
[](https://www.npmjs.com/package/slyfox)  
## About
It's entirely possible, during the execution of a web page, for JavaScript to override many of the core functions providing access to the DOM. This is generally a terrible idea - core functions like `document.createElement` have very broad use, and overriding them can be dangerous. Why would someone override such a method? There's a number of reasons apparently:
* **PrototypeJS** (some versions) thought it was necessary to provide improved support
* Companies like **Osano** believe it's their right when protecting their clients from scripts that don't properly check for data transmission consent
* Some website owners believe that every element passing through such a method should be manipulated or scanned
Whatever the reason it's simply a **bad idea**.
**SlyFox** (formerly `archetype`) is a restoration library aimed at retrieving non-tampered-with method originals through the use of a "safe" iframe it embeds. Copies of these unaltered functions are pulled from the iframe and provided to the caller.
Unlike this library's predecessor, SlyFox does _not_ write these functions over the altered versions. There's ultimately no point fighting like that. This is more of a ponyfill approach rather than a polyfill.
## Installation
Install using `npm install slyfox --save-dev`.
SlyFox provides both an ESM (primary) entry and a UMD build that can be directly injected into browsers. The UMD script is located at `dist/umd/index.js`. Both builds provide types.
## Usage
When using the default (ESM) entry, import the `createSession` helper to create a new `RestoreSession` instance. From there you can immediately fetch restored native methods:
```typescript
import { createSession } from "slyfox";
async function program() {
const session = await createSession();
const createEl = session.getNativeMethod("document.createElement");
const div = createEl("div");
}
```
`getNativeMethod`'s only argument is the global path to the method you want to process.
While `getNativeMethod` provides easy access to top-level methods, it doesn't suit prototype-based methods that appear on elements as they're created. For that, you can use `getNativePrototypeMethod` (though note that it does _not_ support caching like `getNativeMethod`):
```typescript
import { createSession } from "slyfox";
async function program() {
const session = await createSession();
const createEl = session.getNativeMethod("document.createElement");
const child = createEl("div");
const targetElement = document.getElementById("root");
const targetAppend = session.getNativePrototypeMethod(
targetElement,
"appendChild",
"window.Element.prototype.appendChild"
);
targetAppend(child);
}
```
`getNativePrototypeMethod` takes 3 arguments:
1. The element or instance to process as the context
2. The name of the instance's method to process
3. The path to the global prototype
Keep the `RestoreSession` instance around and call it when needed. It caches fetched/bound methods so it doesn't have to reproduce them again every call.
You can also pre-cache some function lookups so you might potentially capture the un-modified versions if you're early enough:
```typescript
session.precacheMethods([
"document.createElement",
"document.body.appendChild"
]);
```
### Caveats
Remember that the returned functions from `getNativeMethod` are _not_ identical to the original function that was overwritten. That original is either lost or not provided via this library. What is returned is either:
* The original function, but bound to its parent. Eg. `document.querySelector.bind(document)`.
* A recovered copy from another _iframe_, bound to the parent of the top/target frame.
In any case, the elements you interact with, potentially, might not function in the way you'd expect them too with normal calls. Never use `instanceof` as this might return unexpected values when using this library.