diff --git a/README.md b/README.md index e86021f..25f5232 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,18 @@ ![Witchcraft](docs/src/assets/title.png) -Think Greasemonkey (or Tampermonkey, Violentmonkey) for developers. - -Witchcraft is a Google Chrome extension for loading custom Javascript and CSS directly from a folder in your file system, injecting them into pages that match their files names. +Witchcraft is a Google Chrome extension for loading custom JavaScript and CSS directly from a folder on your local machine, injecting them into web pages that match specified URL patterns. It works by matching every page domain against script file names available in the scripts folder. For instance, if one navigates to `google.com`, Witchcraft will try to load and run `google.com.js` and `google.com.css`. For more information on how to install and use it, head to Witchcraft's [home page](//luciopaiva.com/witchcraft). -# Serving local files - -Chrome extensions cannot access local files directly for security reasons. To work around this, Witchcraft needs a local HTTP server to serve the scripts folder. - -There are many ways to accomplish this. For example, if you have Python installed, you can run the following command in the scripts folder: - - python3 -m http.server 5743 - -Alternatively, if you have Node.js installed, you can run: - - npx http-server -p 5743 - # Development See [here](./development.md). -# Technical notes - -Read it [here](./technical-notes.md). - # Credits -Witchcraft is my rendition of [defunkt](//github.com/defunkt)'s original extension, [dotjs](//github.com/defunkt/dotjs). Although I never got to actually use dotjs (it only worked on macOS and the installation process was not easy), I really wanted something like that. Thanks, defunkt, for having such a cool idea. +Witchcraft is my rendition of [defunkt](//github.com/defunkt)'s original extension, [dotjs](//github.com/defunkt/dotjs). Images in the logo were provided by [Freepik](//www.flaticon.com/authors/freepik). diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index e870825..848468c 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -79,12 +79,18 @@ export default defineConfig({ items: [ { label: 'Introduction', slug: 'introduction' }, { label: 'How to install', slug: 'how-to-install' }, - { label: 'How to use', slug: 'user-guide' }, + { label: 'How to use', slug: 'how-to-use' }, { label: 'New in version 3', slug: 'new-in-v3' }, { label: 'FAQ', slug: 'faq' }, { label: 'Credits', slug: 'credits' }, ] }, + { + label: 'Technical notes', + items: [ + { label: 'Architecture', slug: 'architecture' }, + ] + } // { // label: 'Cookbook', // autogenerate: { directory: 'cookbook' }, diff --git a/docs/src/content/docs/architecture.mdx b/docs/src/content/docs/architecture.mdx new file mode 100644 index 0000000..f64893f --- /dev/null +++ b/docs/src/content/docs/architecture.mdx @@ -0,0 +1,117 @@ +--- +title: Architecture +--- + +This technical documents talks a bit about the different architectures Witchcraft has had over time, the problems faced and how they were solved. + +## Version 2 + +Up until Witchcraft v2, the architecture was composed of a background script, a content script and the popup window. These are the relevant parts of the manifest file: + +```json title="manifest.json (excerpt)" + "content_scripts": [{ + "all_frames": true, + "run_at": "document_start", + "matches": ["http://*/*", "https://*/*"], + "js": ["content-script.js"] + }], + "background": { + "page": "background.html", + "persistent": false + }, + "content_security_policy": "script-src 'self'; object-src 'self'" +``` + +This is how it worked: + +1. The content script was injected into every frame of every tab (the `content_scripts.matches` property) + +2. at `document_start`, the content script sent a message to the background script passing `window.location` as argument: + + ```js title="content-script.js (excerpt)" + chrome.runtime.sendMessage(location); + ``` + +3. the background would listen for these messages (via `chrome.runtime.onMessage.addListener()`), receive the message and fetch all the scripts that could be applied to that URL + +4. the background script would then send each loaded script as text to the content script at, using `chrome.tabs.sendMessage()`, targeting the specific tab and frame + +5. the content script would then run the script like so: + + ```js title="content-script.js (excerpt, simplified version)" + chrome.runtime.onMessage.addListener(scriptContents => { + Function(scriptContents)(); + }); + ``` + + *(CSS worked similarly, but instead of using `Function()`, it would create a `