Skip to content

Olivki/userskripter

Repository files navigation

userskripter

Maven Central Gradle Plugin Portal

userskripter is a Kotlin library built to make it easy to create and distribute userscripts created with Kotlin/JS.

userskripter is split up into two parts, the library (you are here), which provides declarations for engine specific functions and some general utility functions, and the gradle plugin, which handles the actual "gluing" of the different parts required to create a single userscript distribution file. The library part is designed to be used alongside the gradle plugin and vice versa, they can be used standalone, but no support will be given for any problems that arise when doing so.

The goal is to create something akin to a framework for creating more advanced userscripts in the future, but at the moment the library is very lightweight.

Setup

build.gradle.kts
plugins {
    // ...
    id("net.ormr.userskripter.plugin") version "${USERSKRIPTER-GRADLE-VERSION}"
}

repositories {
    mavenCentral()
}

dependencies {
    // ...
    implementation("net.ormr.userskripter:userskripter:${USERSKRIPTER-VERSION}")
}

Supported Script Engines

Currently two script engines are supported; GreaseMonkey and TamperMonkey.

If the engine you want to use isn’t supported, falling back to GreaseMonkey is the best choice, as all engines will most likely have some sort of backwards compatibility with GreaseMonkey.

Examples

There exists 2 example projects to showcase how a simple userscript could look when created with userskripter.

It’s recommended to develop userscripts for TamperMonkey whenever possible, for various reasons, GreaseMonkey should be considered legacy.

Usage

Creating a userscript is very similar to how one creates a normal Kotlin/JS project, the major difference being that we’re going to go through the userskripter-gradle plugin to get our .js files rather than the standard compileKotlin task.

To create the *.user.js and *.meta.js files invoke the generateUserscript task, which will output the files to the /build/userskripter/ directory. To only generate a specific file, there’s the generateMetaFile and generateUserFile tasks.

Gradle Plugin

How the userscript is built can be changed via the userskript function, the most important parts being the id and scriptEngine properties. Unless specified otherwise userskripter will assume you’re creating a script to be used with GreaseMonkey and GreaseMonkey compatible engines (Which should be almost all script engines).

metadata

To change the metadata block of the userscript, invoke metadata inside of the userskript function. Type-safe functions and properties are provided for the supported engines. Unsupported values can be added using the extra function. Most properties and functions are documented if needed, if unsure about a certain property, consult the documentation for the engine you’re using.

Note that the plugin currently does not verify whether the value you’ve set in the metadata block is actually supported by the engine you’re using. It is mentioned in the kdoc of some properties/functions, but defining connect for a GreaseMonkey project will not fail the build. This may be changed in the future, so it’s recommended to not rely on this lenient behavior for anything.

To see how the metadata block will be serialized, invoke the printUserscriptMetadata task and the metadata block will be printed to the terminal.

metadataTranspiler

userskripter has support for generating Kotlin code containing the values specified inside of the metadata block by invoking the generateUserscriptKotlinFile task.

This feature allows you to access useful metadata values at runtime without having the go through the engine object, as that can be somewhat painful and verbose. For example, to get the description of the userscript (by default) one only needs to invoke UserscriptMetadata.description instead of GreaseMonkey.info.scriptMetadata.description. It’s also useful for accessing values that may not be properly represented in the info object returned by the currently used engine.

To configure how the Kotlin code is generated, invoke the metadataTranspiler function inside the userskript function. All properties for the extension are documented, so no explanation will be provided here.

By default the metadataTranspiler will be ran every time generateUserscript is ran. To disable this behavior set runOnGenerate to false in the metadataTranspiler block.

metadataTranspiler allows you to filter exactly what properties to include in the Kotlin code, by default this is set to only include the following values: name, description, version, author and id. To change this, pass in a new predicate to propertyFilter inside of the metadataTranspiler block.

*.user.js vs *.meta.js

The *.user.js file is the actual userscript file, it contains the metadata block and the actual script code.

The *.meta.js file contains only the metadata block, the purpose of this file is to be hosted somewhere so that versions of your userscript that are currently being used can check against it, and see if there’s a new version. How version resolution is resolved and how updates are handled are specific to each engine and is therefore not specified here.

Note that if you want to support auto-updates for your script, you’ll need to define the hostedAt value in the metadata block. You can also manually define the updateUrl and downloadUrl values yourself, but it’s recommended to use the hostedAt function as it handles it all for you.

For normal script usage the only file you’ll care about is the *.user.js file.

Runtime

Currently the runtime environment of userskripter is very barebones and simple, all that needs to be done to get up and running is to just invoke the userskript function inside of main:

suspend fun main() = userskript {
    // do something
}

To use engine specific functions in your script, just call the appropriate engine object (GreaseMonkey or TamperMonkey) and use any of the functions defined there. Note that all functions require the use of a unique opt-in annotation, you SHOULD NOT just mark your function with the annotation, and should instead do what the annotation tells you and add a grant for the function to your metadata block. This is very important, as otherwise while your code will compile, it will not actually run properly as a userscript.

For example, if we want to use the GreaseMonkey.notification function we will get an error stating Specify 'GM.notification' for 'grant' in userskripter.metadata in Gradle, so to fix this we should adapt our userskript block to look like this:

userskript {
    metadata {
        grant("GM.notification")
    }
}

After doing this and then loading our Gradle changes, you’ll see that the error is now gone, and you can now use the notifcation function anywhere we want in the code and it will compile and run like it should.

About

Kotlin/JS library for easily creating userscripts

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Languages