Tampermonkey® by Jan Biniok

Table of Contents

Userscript Header

@name

The name of the script.

Internationalization is done by adding an appendix naming the locale.

// @name    A test
// @name:de Ein Test

@namespace

The namespace of the script.

@version

The script version. This is used for the update check and needs to be increased at every update.

In this list the next entry is considered to be a higher version number, eg: Alpha-v1 < Alpha-v10 and 16.4 == 16.04

  • Alpha-v1
  • Alpha-v10
  • Alpha-v2
  • Beta
  • 0.5pre3
  • 0.5prelimiary
  • 0.6pre4
  • 0.6pre5
  • 0.7pre4
  • 0.7pre10
  • 1.-1
  • 1 == 1. == 1.0 == 1.0.0
  • 1.1a
  • 1.1aa
  • 1.1ab
  • 1.1b
  • 1.1c
  • 1.1.-1
  • 1.1 == 1.1.0 == 1.1.00
  • 1.1.1.1.1
  • 1.1.1.1.2
  • 1.1.1.1
  • 1.10
  • 2.0
  • 16.4 == 16.04

@description

A short significant description.

Internationalization is done by adding an appendix naming the locale.

// @description    This userscript does wonderful things
// @description:de Dieses Userscript tut wundervolle Dinge

@icon, @iconURL, @defaulticon

The script icon in low res.

@icon64, @icon64URL

This scripts icon in 64x64 pixels. If this tag, but @icon is given the @icon image will be scaled at some places at the options page.

@grant

@grant is used to whitelist GM_* functions, the unsafeWindow object and some powerful window functions.

// @grant GM_setValue
// @grant GM_getValue
// @grant GM_setClipboard
// @grant unsafeWindow
// @grant window.close
// @grant window.focus
// @grant window.onurlchange

Since closing and focusing tabs is a powerful feature this needs to be added to the @grant statements as well.

If a script runs on a single-page application, then it can use window.onurlchange to listen for URL changes:

// ==UserScript==
...
// @grant window.onurlchange
// ==/UserScript==

if (window.onurlchange === null) {
    // feature is supported
    window.addEventListener('urlchange', (info) => ...);
}

In case @grant is followed by none the sandbox is disabled. In this mode no GM_* function but the GM_info property will be available.

// @grant none

If no @grant tag is given an empty list is assumed. However this different from using none.

@author

The scripts author.

@homepage, @homepageURL, @website, @source

The authors homepage that is used at the options page to link from the scripts name to the given page. Please note that if the @namespace tag starts with http:// its content will be used for this too.

@antifeature

This tag allows script developers to disclose whether they monetize their scripts. It is for example required by GreasyFork.

Syntax: <tag> <type> <description>

<type> can have the following values:

  • ads
  • tracking
  • miner
// @antifeature       ads         We show you ads
// @antifeature:fr    ads         Nous vous montrons des publicités
// @antifeature       tracking    We have some sort of analytics included
// @antifeature       miner       We use your computer's resources to mine a crypto currency

Internationalization is done by adding an appendix naming the locale.

@require

Points to a JavaScript file that is loaded and executed before the script itself starts running. Note: the scripts loaded via @require and their "use strict" statements might influence the userscript's strict mode!

// @require https://code.jquery.com/jquery-2.1.4.min.js
// @require https://code.jquery.com/jquery-2.1.3.min.js#sha256=23456...
// @require https://code.jquery.com/jquery-2.1.2.min.js#md5=34567...,sha256=6789...
// @require tampermonkey://vendor/jquery.js
// @require tampermonkey://vendor/jszip/jszip.js

Please check the sub-resource integrity section for more information how to ensure integrity.

Multiple tag instances are allowed.

@resource

Preloads resources that can by accessed via GM_getResourceURL and GM_getResourceText by the script.

// @resource icon1       http://www.tampermonkey.net/favicon.ico
// @resource icon2       /images/icon.png
// @resource html        http://www.tampermonkey.net/index.html
// @resource xml         http://www.tampermonkey.net/crx/tampermonkey.xml
// @resource SRIsecured1 http://www.tampermonkey.net/favicon.ico#md5=123434...
// @resource SRIsecured2 http://www.tampermonkey.net/favicon.ico#md5=123434...;sha256=234234...

Please check the sub-resource integrity section for more information how to ensure integrity.

Multiple tag instances are allowed.

@include

The pages on that a script should run. Multiple tag instances are allowed. @include doesn't support the URL hash parameter. You have to match the path without the hash parameter and make use of window.onurlchange

// @include http://www.tampermonkey.net/*
// @include http://*
// @include https://*
// @include /^https:\/\/www\.tampermonkey\.net\/.*$/
// @include *

Note: When writing something like *://tmnk.net/* many script developers expect the script to run at tmnk.net only, but this is not the case. It also runs at https://example.com/?http://tmnk.net/ as well.

Therefore Tampermonkey interprets @includes that contain a :// a little bit like @match. Every * before :// only matches everything except : characters to makes sure only the URL scheme is matched. Also, if such an @include contains a / after ://, then everything between those strings is treat as host, matching everything except / characters. The same applies to * directly following ://.

@match

More or less equal to the @include tag. You can get more information here . Note: the <all_urls> statement is not yet supported and the scheme part also accepts http*://.

Multiple tag instances are allowed.

@exclude

Exclude URLs even it they are included by @include or @match.

Multiple tag instances are allowed.

@connect

This tag defines the domains (no top-level domains) including subdomains which are allowed to be retrieved by GM_xmlhttpRequest

// @connect <value>

<value> can have the following values:

  • domains like tampermonkey.net (this will also allow all sub-domains)
  • sub-domains i.e. safari.tampermonkey.net
  • self to whitelist the domain the script is currently running at
  • localhost to access the localhost
  • 1.2.3.4 to connect to an IP address
  • *

If it's not possible to declare all domains a userscript might connect to then it's a good practice to do the following: Declare all known or at least all common domains that might be connected by the script. This way the confirmation dialog can be avoided for most of the users.

Additionally add @connect * to the script. By doing so Tampermonkey will still ask the user whether the next connection to a not mentioned domain is allowed, but also offer a "Always allow all domains" button. If the user clicks at this button then all future requests will be permitted automatically.

Users can also whitelist all requests by adding * to the user domain whitelist at the script settings tab.

Notes:

  • both, the initial and the final URL will be checked!
  • for backward compatibility to Scriptish @domain tags are interpreted as well. Multiple tag instances are allowed.

@noframes

This tag makes the script running on the main pages, but not at iframes.

@run

Defines the moment the script is injected. In opposition to other script handlers, @run-at defines the first possible moment a script wants to run. This means it may happen, that a script that uses the @require tag may be executed after the document is already loaded, cause fetching the required script took that long. Anyhow, all DOMNodeInserted and DOMContentLoaded events that happended after the given injection moment are cached and delivered to the script when it is injected.

// @run-at document-start

The script will be injected as fast as possible.

// @run-at document-body

The script will be injected if the body element exists.

// @run-at document-end

The script will be injected when or after the DOMContentLoaded event was dispatched.

// @run-at document-idle

The script will be injected after the DOMContentLoaded event was dispatched. This is the default value if no @run-at tag is given.

// @run-at context-menu

The script will be injected if it is clicked at the browser context menu (desktop Chrome-based browsers only). Note: all @include and @exclude statements will be ignored if this value is used, but this may change in the future.

@updateURL

An update URL for the userscript. Note: a @version tag is required to make update checks work.

@downloadURL

Defines the URL where the script will be downloaded from when an update was detected. If the value none is used, then no update check will be done.

@supportURL

Defines the URL where the user can report issues and get personal support.

@unwrap

Injects the userscript without any wrapper and sandbox into the page, which might be useful for Scriptlets.

Application Programming Interface

unsafeWindow

The unsafeWindow object provides access to the window object of the page that Tampermonkey is running on, rather than the window object of the Tampermonkey extension. This can be useful in some cases, such as when a userscript needs to access a JavaScript library or variable that is defined on the page.

Subresource Integrity

Subresource Integrity (SRI) is a security feature that allows userscript developers to ensure that the external resources (such as JavaScript libraries and CSS files) that they include in their userscript have not been tampered with or modified. This is accomplished by generating a cryptographic hash of the resource and including it in @require and @resource tags. When the userscript is installed, Tampermonkey will calculate the hash of the resource and compare it to the included hash. If the two hashes do not match, Tampermonkey will refuse to load the resource, preventing attackers from injecting malicious code into your userscript.

The hash component of the URL of @resource and @require tags is used for this purpose.

// @resource SRIsecured1 http://example.com/favicon1.ico#md5=ad34bb...
// @resource SRIsecured2 http://example.com/favicon2.ico#md5=ac3434...,sha256=23fd34...
// @require              https://code.jquery.com/jquery-2.1.1.min.js#md5=45eef...
// @require              https://code.jquery.com/jquery-2.1.2.min.js#md5-ac56d...,sha256-6e789...
// @require              https://code.jquery.com/jquery-3.6.0.min.js#sha256-/xUj+3OJU...ogEvDej/m4=

Tampermonkey supports SHA-256 and MD5 hashes natively, all other (SHA-1, SHA-384 and SHA-512) depend on window.crypto.

In case multiple hashes (separated by comma or semicolon) are given the last currently supported one is used by Tampermonkey. All hashes need to be encoded in either hex or Base64 format.

GM_addElement(tag_name, attributes), GM_addElement(parent_node, tag_name, attributes)

GM_addElement allows Tampermonkey scripts to add new elements to the page that Tampermonkey is running on. This can be useful for a variety of purposes, such as adding script and img tags if the page limits these elements with a content security policy (CSP).

It creates an HTML element specified by "tag_name" and applies all given "attributes" and returns the injected HTML element. If a "parent_node" is given, then it is attached to it or to document head or body otherwise.

For suitable "attributes", please consult the appropriate documentation. For example:

GM_addElement('script', {
  textContent: 'window.foo = "bar";'
});

GM_addElement('script', {
  src: 'https://example.com/script.js',
  type: 'text/javascript'
});

GM_addElement(document.getElementsByTagName('div')[0], 'img', {
  src: 'https://example.com/image.png'
});

GM_addElement(shadowDOM, 'style', {
  textContent: 'div { color: black; };'
});

Note: this feature is experimental and the API may change.

GM_addStyle(css)

Adds the given style to the document and returns the injected style element.

GM_download(details), GM_download(url, name)

GM_download allows Tampermonkey scripts to download a file from a specified URL and save it to the user's local machine.

The GM_download function takes the following parameters:

details can have the following attributes:

  • url: The URL of the file to download. This must be a valid URL and must point to a file that is accessible to the user.
  • name: The name to use for the downloaded file. This should include the file's extension, such as .txt or .pdf. For security reasons the file extension needs to be whitelisted at Tampermonkey's options page
  • headers: An object containing HTTP headers to include in the download request. See GM_xmlhttpRequest for more details.
  • saveAs: A boolean value indicating whether to use the user's default download location, or to prompt the user to choose a different location.
  • onload: A function to call when the download has completed successfully.
  • onerror: A function to call if the download fails or is cancelled.
  • onprogress A callback to be executed if this download made some progress.
  • ontimeout A callback to be executed if this download failed due to a timeout.

The download argument of the onerror callback can have the following attributes:

  • error: error reason
    • not_enabled - the download feature isn't enabled by the user
    • not_whitelisted - the requested file extension is not whitelisted
    • not_permitted - the user enabled the download feature, but did not give the downloads permission
    • not_supported - the download feature isn't supported by the browser/version
    • not_succeeded - the download wasn't started or failed, the details attribute may provide more information
  • details: detail about that error

Returns an object with the following property:

  • abort: A function which can be called to cancel this download.

Depending on the download mode GM_info provides a property called downloadMode which is set to one of the following values: native, disabled or browser.

GM_download("http://example.com/file.txt", "file.txt");

const download = GM_download({
    url: "http://example.com/file.txt",
    name: "file.txt",
    saveAs: true
});

// cancel download after 5 seconds
window.setTimeout(() => download.abort(), 5000);

GM_getResourceText(name)

Allows userscripts to access the text of a resource (such as a JavaScript or CSS file) that has been included in a userscript via @resource.

The function takes a single parameter, which is the "name" of the resource to retrieve. It returns the text of the resource as a string.

Here is an example of how the function might be used:

const scriptText = GM_getResourceText("myscript.js");
const script = document.createElement("script");
script.textContent = scriptText;
document.body.appendChild(script);

GM_getResourceURL(name)

GM_getResourceURL allows userscripts to access the URL of a resource (such as a CSS or image file) that has been included in the userscript via a @resource tag at the script header.

The function takes a single parameter, which is the "name" of the resource to retrieve. It returns the URL of the resource as a string.

const imageUrl = GM_getResourceURL("myimage.png");
const image = document.createElement("img");
image.src = imageUrl;
document.body.appendChild(image);

GM_info

Get some info about the script and TM. The object might look like this:

type ScriptGetInfo = {
    scriptMetaStr: string | null,
    scriptWillUpdate: boolean,
    scriptUpdateURL: string | null,
    version?: string,
    scriptHandler: string,
    sandboxMode: SandboxMode,
    isIncognito: boolean,
    isFirstPartyIsolation?: boolean,
    downloadMode: string,
    script: {
        resources: Resource[],
        name: string,
        description: string,
        webRequest: WebRequestRule[] | null,
        version: string,
        icon: string | null,
        icon64: string | null,
        supportURL: string | null,
        fileURL: string | null,
        downloadURL: string | null,
        updateURL: string | null,
        namespace: string | null,
        homepage: string | null,
        author: string | null,
        copyright: string | null,
        antifeatures: { [antifeature: string]: string },
        name_i18n: { [locale: string]: string } | null,
        description_i18n: { [locale: string]: string } | null,
        uuid: string,
        system?: boolean | undefined,
        enabled: boolean,
        deleted?: number | undefined,
        position: number,
        blockers: string[],
        lastModified: number,
        sync?: { imported?: number | undefined,},
        grant: string[],
        options: {
            check_for_updates: boolean,
            comment: string | null,
            compatopts_for_requires: boolean,
            compat_wrappedjsobject: boolean,
            compat_metadata: boolean,
            compat_foreach: boolean,
            compat_powerful_this: boolean | null,
            sandbox: string | null,
            noframes: boolean | null,
            unwrap: boolean | null,
            run_at: string | null,
            tab_types: string | null,
            override: {
                use_includes: string[],
                orig_includes: string[],
                merge_includes: boolean,
                use_matches: string[],
                orig_matches: string[],
                merge_matches: boolean,
                use_excludes: string[],
                orig_excludes: string[],
                merge_excludes: boolean,
                use_connects: string[],
                orig_connects: string[],
                merge_connects: boolean,
                use_blockers: string[],
                orig_run_at: string | null,
                orig_noframes: boolean | null
            }
        },
        header: string | null,
        evilness?: number | undefined
    },
};

type SandboxMode = 'js' | 'raw' | 'dom';

type Resource = {
    name: string,
    url: string,
    error?: string,
    content?: string,
    meta?: string
};

type WebRequestRule = {
    selector: { include?: string | string[], match?: string | string[], exclude?: string | string[] } | string,
    action: string | {
        cancel?: boolean,
        redirect?: {
            url: string,
            from?: string,
            to?: string
        } | string
    }
};

GM_log(message)

Log a message to the console.

GM_notification(details, ondone), GM_notification(text, title, image, onclick)

GM_notification allows users to display notifications on the screen, using a provided message and other optional parameters.

The function takes several parameters. Either a details object or multiple parameters.

The details object can have the following attributes, from which some can also be used as direct parameter.

The available options include:

  • text: A string containing the message to display in the notification.
  • title: The title of the notification.
  • image: The URL of an image to display in the notification.
  • highlight: A boolean flag whether to highlight the tab that sends the notfication (required unless text is set)
  • silent: A boolean flag whether to not play a sound
  • timeout: The time, in milliseconds, after which the notification should automatically close.
  • onclick: A callback function that will be called when the user clicks on the notification.
  • ondone A callback function that will be called when the notification is closed (no matter if this was triggered by a timeout or a click) or the tab was highlighted

The function does not return a value.

Here is an example of how the function might be used:

GM_notification({
  text: "This is the notification message.",
  title: "Notification Title",
  onclick: () => alert('I was clicked!')
});

GM_openInTab(url, options), GM_openInTab(url, loadInBackground)

GM_openInTab allows userscripts to open a new tab in the browser and navigate to a specified URL.

The function takes two parameters:

A string names "url" containing the URL of the page to open in the new tab.

An optional options object that can be used to customize the behavior of the new tab. The available options include:

  • active: A boolean value indicating whether the new tab should be active (selected) or not. The default is false.
  • insert: An integer indicating the position at which the new tab should be inserted in the tab strip. The default is false, which means the new tab will be added to the end of the tab strip.
  • setParent: A boolean value indicating whether the new tab should be considered a child of the current tab. The default is false.
  • incognito A boolean value that makes the tab being opened inside a incognito mode/private mode window.
  • loadInBackground A boolean value has the opposite meaning of active and was added to achieve Greasemonkey 3.x compatibility.

The function returns an object with the function close, the listener onclose and a flag called closed.

Here is an example of how the function might be used:

// Open a new tab and navigate to the specified URL
GM_openInTab("https://www.example.com/");

GM_registerMenuCommand(name, callback, accessKey)

GM_registerMenuCommand allows userscripts to add a new entry to the userscript's menu in the browser, and specify a function to be called when the menu item is selected.

The function takes three parameters:

  • name: A string containing the text to display for the menu item.
  • callback: A function to be called when the menu item is selected. The function will be passed a single parameter, which is the currently active tab. As of Tampermonkey 4.14 a MouseEvent or KeyboardEvent is passed as function argument.
  • accessKey: An optional access key for the menu item. This can be used to create a shortcut for the menu item. For example, if the access key is "s", the user can select the menu item by pressing "s" when Tampermonkey's popup-menu is open.

The function return a menu entry ID that can be used to unregister the command.

Here is an example of how the function might be used:

const menu_command_id = GM_registerMenuCommand("Show Alert", function(event: MouseEvent | KeyboardEvent) {
  alert("Menu item selected");
}, "a");

GM_unregisterMenuCommand(menuCmdId)

GM_unregisterMenuCommand removes an existing entry from the userscript's menu in the browser.

The function takes a single parameter, which is the ID of the menu item to remove. It does not return a value.

Here is an example of how the function might be used:

const menu_command_id = GM_registerMenuCommand(...);
GM_unregisterMenuCommand(menu_command_id);

GM_setClipboard(data, info)

GM_setClipboard sets the text of the clipboard to a specified value.

The function takes a parameter "data", which is the string to set as the clipboard text and a parameter "info".

"info" can be just a string expressing the type text or html or an object like

{
    type: 'text',
    mimetype: 'text/plain'
}
GM_setClipboard("This is the clipboard text.", "text");

GM_getTab(callback)

The GM_getTab function takes a single parameter, a callback function that will be called with an object that is persistent as long as this tab is open.

GM_getTab((tab) => console.log(tab));

GM_saveTab(tab)

The GM_saveTab function allows a userscript to save information about a tab for later use.

The function takes a "tab" parameter, which is an object containing the information to be saved about the tab.

The GM_saveTab function saves the provided tab information, so that it can be retrieved later using the GM_getValue function.

Here is an example of how the GM_saveTab function might be used in a userscript:

GM_getTab(function(tab) {
    tab.newInfo = "new!";
    GM_saveTab(tab);
});

In this example, the GM_saveTab function is called with the tab object returned by the GM_getTab function, and a new key called "newInfo".

GM_getTabs(callback)

The GM_getTabs function takes a single parameter: a callback function that will be called with the information about the tabs.

The "tabs" object that is passed to the callback function contains objects, with each object representing the saved tab information stored by GM_saveTab.

GM_getTabs((tabs) => {
    for (const [tabId, tab] of Object.entries(tabs)) {
        console.log(`tab ${tabId}`, tab);
    }
});

GM_setValue(key, value)

The GM_setValue allows a userscript to set the value of a specific key in the userscript's storage.

The GM_setValue function takes two parameters:

  • A string specifying the key for which the value should be set.
  • The value to be set for the key. This value can be of any type (string, number, object, etc.).

The GM_setValue function does not return any value. Instead, it sets the provided value for the specified key in the userscript's storage.

Here is an example of how the GM_setValue function might be used in a userscript:

GM_setValue("someKey", "someData");

GM_getValue(key, defaultValue)

The GM_getValue function allows a userscript to retrieve the value of a specific key in the extension's storage. It takes two parameters:

  • A string specifying the key for which the value should be retrieved.
  • A default value to be returned if the key does not exist in the extension's storage. This default value can be of any type (string, number, object, etc.).

The GM_getValue function returns the value of the specified key from the extension's storage, or the default value if the key does not exist.

Here is an example of how the GM_getValue function might be used in a userscript:

const someKey = GM_getValue("someKey", null);

In this example, the GM_getValue function is called with the key "someKey" and a default value of null. If the "someKey" key exists in the extension's storage, its value will be returned and stored in the someKey variable. If the key does not exist, the default value of null will be returned and stored in the savedTab variable.

GM_deleteValue(key)

Deletes "key" from the userscript's storage.

GM_listValues()

The GM_listValues function takes a single parameter: a callback function that will be called with the list of keys of all stored data.

GM_listValues((keys) => console.log(keys));

GM_addValueChangeListener(key, function(key, old_value, new_value, remote) {})

The GM_addValueChangeListener function allows a userscript to add a listener for changes to the value of a specific key in the userscript's storage.

The function takes two parameters:

  • A string specifying the key for which changes should be monitored.
  • A callback function that will be called when the value of the key changes. The callback function should have the following signature:
      function(key, oldValue, newValue, remote) {
          // key is the key whose value has changed
          // oldValue is the previous value of the key
          // newValue is the new value of the key
          // remote is a boolean indicating whether the change originated from a different userscript instance
      }
    

The GM_addValueChangeListener function returns a "listenerId" value that can be used to remove the listener later using the GM_removeValueChangeListener function.

Here is an example of how the GM_addValueChangeListener function might be used in a userscript:

// Add a listener for changes to the "savedTab" key
var listenerId = GM_addValueChangeListener("savedTab", function(key, oldValue, newValue, remote) {
  // Print a message to the console when the value of the "savedTab" key changes
  console.log("The value of the '" + key + "' key has changed from '" + oldValue + "' to '" + newValue + "'");
});

GM_addValueChangeListener can be used by userscripts to communicate with other userscript instances at other tabs.

GM_removeValueChangeListener(listenerId)

GM_removeValueChangeListener get one argument called "listenerId" and removes the change listener with this ID.

GM_xmlhttpRequest(details)

The GM_xmlhttpRequest allows a userscripts to send an HTTP request and handle the response. The function takes a single parameter: an object containing the details of the request to be sent and the callback functions to be called when the response is received.

The object should have the following properties:

  • method one of GET, HEAD, POST
  • url the destination URL
  • headers ie. user-agent, referer, ... (some special headers are not supported by Safari and Android browsers)
  • data some string to send via a POST request
  • cookie a cookie to be patched into the sent cookie set
  • binary send the data string in binary mode
  • nocache don't cache the resource
  • revalidate revalidate maybe cached content
  • timeout a timeout in ms
  • context a property which will be added to the response object
  • responseType one of arraybuffer, blob, json or stream
  • overrideMimeType a MIME type for the request
  • anonymous don't send cookies with the requests (please see the fetch notes)
  • fetch (beta) use a fetch instead of a xhr request (at Chrome this causes details.timeout and xhr.onprogress to not work and makes xhr.onreadystatechange receive only readyState 4 events)
  • user a user name for authentication
  • password a password
  • onabort callback to be executed if the request was aborted
  • onerror callback to be executed if the request ended up with an error
  • onloadstart callback to be executed on load start, provides access to the stream object if responseType is set to "stream"
  • onprogress callback to be executed if the request made some progress
  • onreadystatechange callback to be executed if the request's ready state changed
  • ontimeout callback to be executed if the request failed due to a timeout
  • onload callback to be executed if the request was loaded.
      function(response) {
        // response is an object containing the details of the response
      }
    
    "response" has the following attributes:
    • finalUrl - the final URL after all redirects from where the data was loaded
    • readyState - the ready state
    • status - the request status
    • statusText - the request status text
    • responseHeaders - the request response headers
    • response - the response data as object if details.responseType was set
    • responseXML - the response data as XML document
    • responseText - the response data as plain string

GM_xmlhttpRequest returns an object with the following property:

  • abort - function to be called to cancel this request

Here is an example of how the GM_xmlhttpRequest function might be used in a userscript:

GM_xmlhttpRequest({
  method: "GET",
  url: "https://example.com/",
  headers: {
    "Content-Type": "application/json"
  },
  onload: function(response) {
    console.log(response.responseText);
  }
});

Note: the synchronous flag at details is not supported

Important: if you want to use this method then please also check the documentation about @connect.

<><![CDATA[...]]></>

Tampermonkey supports this way of storing meta data. TM tries to automatically detect whether a script needs this compatibility option to be enabled.