Skip to content

Commit

Permalink
feat: initial stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Sv443 committed Oct 15, 2023
1 parent 3941e12 commit c88b353
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 248 deletions.
2 changes: 1 addition & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
RING_BELL=false

# HTTP port of the dev server where the userscript will be served (when using `npm run watch`) - defaults to 8710 if empty, invalid (NaN or <1024) or unset
DEV_SERVER_PORT=8710
DEV_SERVER_PORT=12122

# whether to log dev server requests to the console - defaults to false if empty, invalid or unset
DEV_SERVER_LOG=false
26 changes: 17 additions & 9 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
MIT License

Copyright (C) 2023 Sv443
Copyright (c) 2023 Sven Fehler (Sv443)

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

0. You just DO WHAT THE FUCK YOU WANT TO.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
79 changes: 7 additions & 72 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,81 +1,16 @@
<div style="text-align:center;" align="center">

<h1><img alt="icon" src="./assets/icon.png"><br>Userscript.ts</h1>
<h1><img alt="icon" src="./assets/icon.png"><br>UserUtils-Test</h1>

Typescript ESM template for making [userscripts](https://en.wikipedia.org/wiki/Userscript) that supports importing and parsing HTML, CSS, Markdown and misc. files directly in code, packing it all up with webpack and applying custom injections for the userscript header and more.
It also offers ESLint to lint and auto-fix the code and GitHub Actions with ESLint to lint the code in pull requests and CodeQL to check it for vulnerabilities on every push.

Like this template? Please consider [supporting the development ❤️](https://github.com/sponsors/Sv443)

---
#### [Installation](#installation) &bull; [First&nbsp;steps](#first-steps) &bull; [Commands](#commands) &bull; [Development&nbsp;tips&nbsp;&&nbsp;notes](#development-tips-and-notes)
Test userscript for [UserUtils](https://github.com/Sv443-Network/UserUtils) based on my [TypeScript userscript template](https://github.com/Sv443/Userscript.ts)

</div>
<br>

## Installation:
1. Make sure [Node.js](https://nodejs.org) and a userscript manager are installed (I recommend [ViolentMonkey](https://violentmonkey.github.io/))
2. [Click here](https://github.com/Sv443/Userscript.ts/generate) to create a repository on GitHub using this template
3. [Clone](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) the repository you created
4. Open a terminal in the root of the folder and use `npm i` to install dependencies
5. Refer to [first steps](#first-steps)

<br>

## First steps:
1. Copy `.env.template` to `.env` and change the values inside if needed
2. Inside `package.json`, update the properties `name`, `userscriptName`, `description`, `homepage`, `author`, `license` and `repository.url`
3. Replace the icon at `assets/icon.png` with your own or use [Google's or DuckDuckGo's favicon API](https://codepen.io/djekl/pen/QWKNNjv) in the userscript header
4. Replace the LICENSE.txt file with your own license or remove it if you want your code to be "all rights reserved"
5. Modify the variables and userscript header inside `src/tools/post-build.ts` to whatever you need (see also [GM header reference](https://wiki.greasespot.net/Metadata_Block))
6. The eslint configuration at `.eslintrc.cjs` is what I use, feel free to remove rules if there are too many or modify them to your preferences
7. Add your own initialization functions to `init()` and `onLoad()` inside the entrypoint file at `src/index.ts` (read the comments for more info)
8. Remove the example HTML, CSS and TS files
9. Refer to [commands](#commands) and [development](#development-tips-and-notes)

<br>

## Commands:
### Commands
| Command | Description |
| --- | --- |
| `npm i` | Run once to install dependencies |
| `npm run lint` | Lints the userscript with ESLint |
| `npm run build-dev` | Builds the userscript in development mode (sourcemaps enabled) |
| `npm run build-prod` | Builds the userscript in production mode (optimized code, sourcemaps disabled) |
| `npm run dev` | Watches, rebuilds and serves the userscript so it can be updated live ([more info below](#development-tips-and-notes)) |
<!-- first column uses non-breaking space U+00A0 (' ') -->

<br>

## Development tips and notes:
- If you're using the [ViolentMonkey extension](https://violentmonkey.github.io/) (which I recommend), after running the command `npm run watch`, you may open the URL shown in the console in your browser and select the `Track local file` option in the installation dialog.
This makes it so the userscript automatically updates when the code changes (reloading the website is still necessary).
Note: the tab needs to stay open on Firefox or the script won't keep updating itself.
- My library [UserUtils](https://github.com/Sv443-Network/UserUtils) is already included as a dependency. It offers lots of utilities for userscripts like registering listeners for when CSS selectors exist, intercepting events, managing persistent user configurations, modifying the DOM more easily, various math and array functions and more. You can find the full list of features and its documentation [here.](https://github.com/Sv443-Network/UserUtils#table-of-contents)
- Libraries that are required at runtime should be declared inside `dependencies.json`, as long as they are hosted on a CDN and expose a global variable.
This way, they will be loaded using the `@require` directive and will be exempt from [minification rules](https://greasyfork.org/en/help/code-rules) on platforms like GreasyFork.
You may use a service like [jsDelivr](https://www.jsdelivr.com/) to include any npm library this way.
You will still be able to import and use the libraries as usual in your code.
- The final bundled userscript file in the `dist/` folder should be committed and pushed to GitHub.
This way, the `@downloadURL` and `@updateURL` directives make it so the script is automatically updated from that same file.
For this to work properly, don't forget to bump the version in `package.json` before building, so that every user of your userscript may receive the update.
- The name of the emitted bundle inside `dist/` is bound to `userscriptName` in `package.json`
You may want to hard-code it or create a separate property for it if the userscript name contains characters that aren't allowed in a file path.
- If you want other people to use your userscript, I recommend publishing it to [GreasyFork](https://greasyfork.org) and/or [OpenUserJS.](https://openuserjs.org)
Make sure to check out and follow their rules and guidelines before publishing.
- Use an IDE like [VS Code](https://code.visualstudio.com/) so Intellisense and Typescript can work together to give you really awesome code completion and warn you about potential runtime errors before you even build the code.
- If you are using VS Code, install the ESLint extension ([`dbaeumer.vscode-eslint`](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)) and bind a hotkey for the `ESLint: Fix all auto-fixable problems` command so you can quickly format the currently active file according to the rules in `.eslintrc.cjs`
- Try to get familiar with the [webpack config](https://webpack.js.org/configuration/) at `webpack.config.js`
In there you may add and configure webpack plugins and configure the build process.
- To see an example of how the code in `src/index.ts` will be packed in production mode, check out the file at [`dist/EXAMPLE.user.js`](./dist/EXAMPLE.user.js)

<br><br><br>

<div align="center" style="text-align: center;">

Made with ❤️ by [Sv443](https://github.com/Sv443)
If you like this template, please consider [supporting me](https://github.com/sponsors/Sv443)

© 2023 Sv443 - [WTFPL license](./LICENSE.txt)

</div>
| `npm run dev` | Watch the code for changes, then build the userscript in development mode and serve it locally |
| `npm run build-dev` | Build the userscript in development mode |
| `npm run build-prod` | Build the userscript in production mode |
| `npm link @sv443-network/userutils` | Symlink the local version of UserUtils (after running `npm link` and `npm run dev` in that project's root) |
7 changes: 1 addition & 6 deletions dependencies.json
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
{
"@sv443-network/userutils": {
"url": "https://greasyfork.org/scripts/472956-userutils/code/UserUtils.js",
"global": "UserUtils"
}
}
{}
6 changes: 6 additions & 0 deletions dependencies.old.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"@sv443-network/userutils": {
"url": "https://greasyfork.org/scripts/472956-userutils/code/UserUtils.js",
"global": "UserUtils"
}
}
92 changes: 0 additions & 92 deletions dist/EXAMPLE.user.js

This file was deleted.

12 changes: 5 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
{
"name": "userscript.ts",
"name": "userutils-test",
"version": "0.1.0",
"userscriptName": "CHANGE_ME",
"userscriptName:de": "REMOVE_IF_NOT_NEEDED (example for localization - see also src/tools/post-build.ts)",
"description": "CHANGE_ME_TOO",
"description:de": "REMOVE_IF_NOT_NEEDED (example for localization - see also src/tools/post-build.ts)",
"homepage": "https://github.com/Sv443/Userscript.ts",
"userscriptName": "UserUtils-Test",
"description": "Test userscript for UserUtils: https://github.com/Sv443-Network/UserUtils",
"homepage": "https://github.com/Sv443-Network/UserUtils-Test",
"main": "./src/index.ts",
"type": "module",
"scripts": {
Expand All @@ -28,7 +26,7 @@
"name": "Sv443",
"url": "https://github.com/Sv443"
},
"license": "WTFPL",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/Sv443/Userscript.ts.git"
Expand Down
11 changes: 0 additions & 11 deletions src/example.css

This file was deleted.

4 changes: 0 additions & 4 deletions src/example.html

This file was deleted.

23 changes: 0 additions & 23 deletions src/example.ts

This file was deleted.

5 changes: 2 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { addGlobalStyle } from "@sv443-network/userutils";
import { insertExampleElements } from "./example";
import { selectorObserverTest } from "./selectorObserver";

/**
* Called whenever the script is initialized, depending on the value of `@run-at` inside the userscript header.
Expand All @@ -23,8 +23,7 @@ function onLoad() {
if(!globalStyle.match(/^{{.+}}$/))
addGlobalStyle(globalStyle);

// go to this function's definition in `example.ts` for an example on how to import HTML, CSS and markdown
insertExampleElements();
selectorObserverTest();
}

init();
29 changes: 29 additions & 0 deletions src/selectorObserver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { SelectorObserver } from "@sv443-network/userutils";

export async function selectorObserverTest() {
const bodyObs = new SelectorObserver(document.body);

bodyObs.addListener("#selector-observer-cont", {
listener: (cont1) => {
console.log("container 1 available");

const subcont1Obs = new SelectorObserver(cont1);

subcont1Obs.addListener("#selector-observer-subcont1", {
listener: (subcont1) => {
console.log("subcontainer 1 available");

const subcont1ItemsObs = new SelectorObserver(subcont1);

subcont1ItemsObs.addListener(".selector-observer-subcont", {
all: true,
continuous: true,
listener: (subcont1Items) => {
console.log("subcontainer 1 items:", subcont1Items);
},
});
},
});
},
});
}
Loading

0 comments on commit c88b353

Please sign in to comment.