### Blacklist Configuration Example Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/smart-rules-for-blacklist.md Demonstrates how to configure blacklist rules using hostnames, @exclude-match, and @exclude patterns. Comments are ignored. ```plaintext # hostnames www.google.com # @exclude-match rules *://twitter.com/* # @exclude rules @exclude https://example.com/* ``` -------------------------------- ### Install and Import @violentmonkey/shortcut Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx Install the library using NPM and import its functions directly into your code. This method is recommended for projects using bundlers and TypeScript. ```bash $ npm i @violentmonkey/shortcut ``` ```js import { register } from '@violentmonkey/shortcut'; ``` -------------------------------- ### Start Development Server Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md Run the development command to watch for source code changes and automatically recompile them to the dist directory. ```bash $ npm run dev ``` -------------------------------- ### Whitelist Configuration Example Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/smart-rules-for-blacklist.md Shows how to set up a whitelist using @match and @include rules, followed by a catch-all '*' rule to block all other URLs. ```plaintext # match rules @match https://www.google.com/* # include rules @include https://example.com/* # block everything else * ``` -------------------------------- ### GM.xmlHttpRequest Example Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx This example shows how to use GM.xmlHttpRequest, which is compatible with multiple userscript managers. It demonstrates a basic request with an onload handler. ```javascript // compatible with multiple userscript managers GM.xmlHttpRequest({ url, onload: res => {/*....*/} }); ``` -------------------------------- ### Basic @match and @exclude-match Rules Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md These are examples of basic @match and @exclude-match rules. @match defines URLs where the script should run, while @exclude-match defines URLs to be excluded. ```javascript // @match *://*/* // @exclude-match *://*.tk/* ``` -------------------------------- ### Basic @include and @exclude Rules Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md Examples of @include and @exclude rules. @include specifies URLs to run the script on, and @exclude specifies URLs to prevent the script from running. These can be simple strings or regular expressions. ```javascript // @include * // @include https://www.google.com/* // @include /\.com\.hk\/ // @exclude https://www.google.com/exact/url ``` -------------------------------- ### GM.xmlHttpRequest with Abort Control (VM2.18.3+, TM) Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx This example demonstrates how to get a control object from GM.xmlHttpRequest to abort the request, using async/await syntax. Available in Violent Monkey version 2.18.3 and later, and Tampermonkey. ```javascript // VM2.18.3+, TM const control = GM.xmlHttpRequest({ url }); myButton.addEventListener('click', control.abort, { once: true }); const res = await control; ``` -------------------------------- ### GM.xmlHttpRequest with Promise Wrapper Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx This example demonstrates wrapping GM.xmlHttpRequest in a Promise for easier asynchronous handling, compatible with multiple userscript managers. ```javascript // compatible with multiple userscript managers const res = await new Promise((resolve, reject) => { GM.xmlHttpRequest({ url, onload: resolve, onerror: reject }); }); ``` -------------------------------- ### Run Userscript on Entire SPA Site Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md This example shows how to use the @match rule to ensure a userscript runs on an entire Single Page Application (SPA) site, like YouTube. ```javascript // @match *://www.youtube.com/* ``` -------------------------------- ### GM.xmlHttpRequest Async/Await (VM2.18.3+, TM) Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx This example shows the modern async/await usage for GM.xmlHttpRequest, available in Violent Monkey version 2.18.3 and later, and Tampermonkey. ```javascript // VM2.18.3+, TM const res = await GM.xmlHttpRequest({ url }); ``` -------------------------------- ### Get text resource from metadata Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves the content of a text resource defined in the script's metadata block. ```javascript let text = GM_getResourceText(name) ``` -------------------------------- ### Get a value from storage Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves a specific value from the script's storage. If the key does not exist, it returns the provided default value. ```javascript let value = GM_getValue(key, defaultValue) ``` -------------------------------- ### Userscript Metadata Block Structure Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The metadata block must start with `// ==UserScript==` and end with `// ==/UserScript==`. Each line within the block must begin with `//` followed by a single space. ```javascript // ==UserScript== // @key value // ==/UserScript== ``` -------------------------------- ### Get Resource URL Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves a blob: or data: URL for a resource defined in the metadata block. Use isBlobUrl=true for a cacheable blob: URL, or false for a data: URL which is useful for sites with strict CSP. ```javascript let blobUrl = GM_getResourceURL(name); let blobOrDataUrl = GM_getResourceURL(name, isBlobUrl); ``` -------------------------------- ### Get multiple values from storage Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves multiple values from the script's storage. Can accept an array of keys or an object where keys are names and values are defaults. ```javascript let values = GM_getValues(['foo', 'bar']) ``` ```javascript let values = GM_getValues({ foo: 1, bar: [2] }) ``` -------------------------------- ### Create Project Directory Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md Create a new directory for your userscript project and navigate into it. ```bash $ mkdir my-script $ cd my-script ``` -------------------------------- ### Initialize New Userscript Project Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md Use npx to generate a new userscript project with a modern JavaScript toolchain, including Babel for compilation and Rollup for bundling. ```bash $ npx -p github:violentmonkey/generator-userscript -p yo yo @violentmonkey/userscript ``` -------------------------------- ### Build Userscript for Production Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/using-modern-syntax/index.md Execute the build command to compile the source code once for production deployment. This process syncs version and author information from package.json. ```bash $ npm run build ``` -------------------------------- ### Register a Key Sequence Shortcut Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx Bind a sequence of key combinations (e.g., 'c-a c-b' for Ctrl+A followed by Ctrl+B) to a callback function. ```js VM.shortcut.register('c-a c-b', () => { console.log('You just pressed Ctrl-A Ctrl-B sequence'); }); ``` -------------------------------- ### Demonstration of Synchronous vs. Asynchronous Injection Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-scripts-with-blob-urls.md This code demonstrates the difference in execution order between synchronous textContent injection and asynchronous Blob URL injection. The synchronous method logs '1' then '3' then '2', while the asynchronous method logs '1', '3', and finally '2'. ```javascript { const s = document.createElement('script'); s.textContent = 'console.log(1)'; document.body.appendChild(s); document.body.removeChild(s); } { const s = document.createElement('script'); const b = new Blob(['console.log(2)'], { type: 'text/javascript' }); const u = URL.createObjectURL(b); s.src = u; document.body.appendChild(s); document.body.removeChild(s); URL.revokeObjectURL(u); } console.log(3); ``` -------------------------------- ### GM_openInTab Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Opens a URL in a new tab, with options to control its behavior like activation, pinning, and container. ```APIDOC ## GM_openInTab Opens URL in a new tab. ### Usage 1. Using an object for options: ```js let tabControl = GM_openInTab(url, options) ``` - **url** (string) - Required - The URL to open in a new tab. Relative URLs are also allowed. Note that `data:`, `blob:`, `chrome:`, `file:`, and many `about:` URLs are disallowed for security reasons. - **options** (object) - Optional - **active** (boolean) - Optional, defaultValue: `true` - Make the new tab active (open in foreground). - **container** (number) - Optional, since VM2.12.5, Firefox-only - Set tab's container in Firefox: * not specified = reuse script's tab container * `0` = default (main) container * `1`, `2`, etc. = internal container index - **insert** (boolean) - Optional, since VM2.11.0, defaultValue: `true` - Insert the new tab next to the current tab and set its "openerTab" so when it's closed the original tab will be focused automatically. When `false` or not specified, the usual browser behavior is to open the tab at the end of the tab list. - **pinned** (boolean) - Optional, since VM2.12.5, defaultValue: `false` - Pin the tab (show without a title at the beginning of the tab list). 2. Using a boolean for background opening (compatible with Greasemonkey): ```js let tabControl = GM_openInTab(url, openInBackground) ``` - **openInBackground** (boolean) - Required - Open the tab in background. `true` is the same as `{ active: false }`. ### Returns An object with the following properties: - **onclose** (function) - Optional - Can be assigned to a function. If provided, it will be called when the opened tab is closed. - **closed** (boolean) - Whether the opened tab is closed. - **close** (function) - A function to explicitly close the opened tab. ### Example ```js let tabControl = GM_openInTab(url); tab.onclose = () => console.log('tab is closed'); tab.close(); ``` ``` -------------------------------- ### GM_download with options object Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Downloads a URL to a local file using an options object. Supports various configuration options for the download process. ```APIDOC ## GM_download(options) ### Description Downloads a URL to a local file using an options object. Most [GM_xmlhttpRequest](#gm_xmlhttprequest) options are supported. ### Parameters #### Request Body - **options** (object) - Required - An object containing download configuration. - **url** (string) - Required - The URL to download. - **name** (string) - Required - The filename to save to. Folders/subpaths aren't supported yet. - **headers?** (object) - Optional - Custom headers for the request. - **timeout?** (number) - Optional (since VM2.9.5) - Timeout for the download in milliseconds. - **context?** (any) - Optional (since VM2.13.4) - Context for the request. - **user?** (string) - Optional (since VM2.13.4) - Username for authentication. - **password?** (string) - Optional (since VM2.13.4) - Password for authentication. - **anonymous?** (boolean) - Optional (since VM2.13.4, default: false) - Whether to use anonymous download. - **onabort?** (function) - Optional (since VM2.13.4) - Callback for when the download is aborted. - **onerror?** (function) - Optional - Callback for when an error occurs during download. - **onload?** (function) - Optional - Callback for when the download is successful. Called after data is downloaded, before writing the file. - **onloadend?** (function) - Optional (since VM2.13.4) - Callback for when the download finishes (success or error). - **onloadstart?** (function) - Optional (since VM2.13.4) - Callback for when the download starts. - **onprogress?** (function) - Optional - Callback for download progress. - **onreadystatechange?** (function) - Optional (since VM2.13.4) - Callback for changes in the ready state. - **ontimeout?** (function) - Optional - Callback for when the download times out. ### Returns - **object** - A control object with an `abort` function to cancel the download. ### Request Example ```javascript GM_download({ url: 'https://example.com/file.zip', name: 'downloaded_file.zip', onload: () => console.log('Download complete!'), onerror: (err) => console.error('Download failed:', err) }); ``` ### Response Example ```json { "abort": "() => void" } ``` ``` -------------------------------- ### GM_download with Options Object Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Use this method to download a URL to a local file by providing an options object. Most GM_xmlhttpRequest options are supported, including callbacks for download events. ```javascript GM_download(options) ``` -------------------------------- ### Update Menu Command In-Place Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Shows how to update an existing menu command in-place using its ID, or how to recreate commands if in-place updates are not supported. ```javascript const id = 'status'; const inplace = id === GM_registerMenuCommand('Enabled', onClick, { id }); if (inplace) { // supported: change the command in-place using the same `id` GM_registerMenuCommand('Disabled', onClick, { id, title: 'Status' }); } else { // not supported: recreate the commands GM_unregisterMenuCommand('Enabled'); GM_unregisterMenuCommand('Foo'); GM_unregisterMenuCommand('Bar'); GM_registerMenuCommand('Disabled', onClick); GM_registerMenuCommand('Foo', onClick2); GM_registerMenuCommand('Bar', onClick3); } ``` -------------------------------- ### Project Structure Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/README.md Illustrates the directory layout of the Violentmonkey project. ```tree └── content ├── pages └── posts # blog posts about Violentmonkey ``` -------------------------------- ### List all values in storage Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Returns an array containing the keys of all values currently stored for the script. ```javascript let arrayOfKeys = GM_listValues() ``` -------------------------------- ### GM_setClipboard Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Sets data to the system clipboard. ```APIDOC ## GM_setClipboard ### Description Sets data to system clipboard. ### Method Signature ```js GM_setClipboard(data, type) ``` ### Parameters #### Path Parameters - **data** (string) - Required - The data to be copied to system clipboard. - **type** (string) - Optional - The MIME type of data to copy. Defaults to `'text/plain'`. ``` -------------------------------- ### Register a Simple Keyboard Shortcut Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx Use the register function to bind a key combination (e.g., 'c-i' for Ctrl+I) to a callback function. ```js VM.shortcut.register('c-i', () => { console.log('You just pressed Ctrl-I'); }); ``` -------------------------------- ### Add @violentmonkey/shortcut via @require Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx Include the @violentmonkey/shortcut library in your script's meta block using the @require directive. Access exports via VM.shortcut. ```js // ==UserScript== // ... // @require https://cdn.jsdelivr.net/npm/@violentmonkey/shortcut@1 // ==/UserScript== const { register } = VM.shortcut; ``` -------------------------------- ### GM_download with Separate Parameters Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Use this method to download a URL to a local file by providing the URL and filename as separate parameters. Folders and subpaths are not supported for the filename. ```javascript GM_download(url, name) ``` -------------------------------- ### GM_download with separate parameters Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Downloads a URL to a local file using separate URL and name parameters. ```APIDOC ## GM_download(url, name) ### Description Downloads a URL to a local file using separate URL and name parameters. ### Parameters #### Path Parameters - **url** (string) - Required - The URL to download. - **name** (string) - Required - The filename to save to. Folders/subpaths aren't supported yet. ### Returns - **object** - A control object with an `abort` function to cancel the download. ### Request Example ```javascript GM_download('https://example.com/image.png', 'my_image.png'); ``` ### Response Example ```json { "abort": "() => void" } ``` ``` -------------------------------- ### Disable and Enable All Key Bindings Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx Temporarily disable all registered keyboard shortcuts using VM.shortcut.disable() and re-enable them later with VM.shortcut.enable(). ```js // Disable all key bindings temporarily VM.shortcut.disable(); // Re-enable key bindings VM.shortcut.enable(); ``` -------------------------------- ### Open URL in New Tab with Options Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Opens a URL in a new tab using an options object for detailed control over tab behavior like activation, pinning, and container. ```javascript let tabControl = GM_openInTab(url, options) ``` -------------------------------- ### GM_info Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves information about the current script and its environment. ```APIDOC ## GM_info ### Description Retrieves information about the current script and its environment. ### Response #### Success Response (200) - **script** (object) - Information about the script. - **version** (string) - The version of Violentmonkey. - **script.uuid** (string) - The unique identifier of the script. - **script.name** (string) - The name of the script. - **script.namespace** (string) - The namespace of the script. - **script.version** (string) - The version of the script. - **script.author** (string) - The author of the script. - **script.description** (string) - The description of the script. - **script.homepage** (string) - The homepage of the script. - **script.updateURL** (string) - The update URL of the script. - **script.defaulturl** (string) - The default URL of the script. - **script.iconURL** (string) - The icon URL of the script. - **script.icon64URL** (string) - The 64x64 icon URL of the script. - **script.matches** (string[]) - An array of match patterns for the script. - **script.includes** (string[]) - An array of include patterns for the script. - **script.excludes** (string[]) - An array of exclude patterns for the script. - **script.runAt** (string) - The run at setting for the script. - **script.grant** (string[]) - An array of granted APIs for the script. - **script.require** (string[]) - An array of required scripts for the script. - **script.resources** (object) - An object containing script resources. - **script.unwrap** (boolean) - Whether the script is unwrapped. - **script.originalCode** (string) - The original code of the script. ### Response Example ```json { "script": { "uuid": "123e4567-e89b-12d3-a456-426614174000", "name": "My Script", "namespace": "my.namespace", "version": "1.0.0", "author": "John Doe", "description": "A sample script.", "homepage": "http://example.com", "updateURL": "http://example.com/update", "defaulturl": "http://example.com/default", "iconURL": "http://example.com/icon.png", "icon64URL": "http://example.com/icon64.png", "matches": ["http://*/*"], "includes": [], "excludes": [], "runAt": "document-end", "grant": ["GM_info"], "require": [], "resources": {}, "unwrap": false, "originalCode": "// ==UserScript==\n// @name My Script\n// @namespace my.namespace\n// @version 1.0.0\n// @author John Doe\n// @description A sample script.\n// @homepage http://example.com\n// @updateURL http://example.com/update\n// @defaulturl http://example.com/default\n// @iconURL http://example.com/icon.png\n// @icon64URL http://example.com/icon64.png\n// @match http://*/*\n// @grant GM_info\n// ==/UserScript==\n\nconsole.log(GM_info)" }, "version": "2.19.1" } ``` ``` -------------------------------- ### Script Resources Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @resource key defines static resources accessible via GM_getResourceText and GM_getResourceURL. It includes a resource name and its URL. ```javascript // @resource logo https://my.cdn.com/logo.png // @resource text https://my.cdn.com/some-text.txt ``` -------------------------------- ### Localized Script Description Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @description key provides a summary of the script and can be localized using a locale code suffix. ```javascript // @description This script rocks. // @description:zh-CN 这个脚本很棒! ``` -------------------------------- ### Observe DOM Elements with @violentmonkey/dom and jQuery Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/observing-dom/index.mdx Integrate jQuery with `VM.observe` for DOM manipulation. Ensure both `@violentmonkey/dom` and jQuery are included as script dependencies. ```javascript VM.observe(document.body, () => { // Find the target node const $node = $('.profile'); if ($node.length) { $node.prepend('

Profile

'); // disconnect observer return true; } }); ``` -------------------------------- ### Handle Tab Close and Explicit Close Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Demonstrates how to set a callback for when the opened tab is closed and how to explicitly close the tab using the returned tabControl object. ```javascript let tabControl = GM_openInTab(url); tabControl.onclose = () => console.log('tab is closed'); tabControl.close(); ``` -------------------------------- ### Set multiple values in storage Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Writes multiple key-value pairs to the script's storage efficiently. Values must be JSON serializable. ```javascript GM_setValues({ foo: 1, bar: [1, 2, 3] }) ``` -------------------------------- ### Script Versioning Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @version key specifies the script's version, composed of parts separated by dots. A @version is required for automatic updates. ```javascript // @version 1.0 // @version 1.2a.3 ``` -------------------------------- ### Show Desktop Notification (Parameters) - Violentmonkey API Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Displays a desktop notification using separate parameters, compatible with Greasemonkey. This is a simpler way to show notifications when extensive configuration is not needed. ```javascript GM_notification(text, title, image, onclick) ``` -------------------------------- ### Observe DOM Elements with @violentmonkey/dom Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/observing-dom/index.mdx Use `VM.observe` to watch for DOM changes and perform actions when a target element appears. Return `true` from the callback to automatically disconnect the observer after the first match. ```javascript const disconnect = VM.observe(document.body, () => { // Find the target node const node = document.querySelector('.profile'); if (node) { const h1 = document.createElement('h1'); h1.textContent = 'Profile'; node.prepend(h1); // disconnect observer return true; } }); // You can also disconnect the observer explicitly when it's not used any more disconnect(); ``` -------------------------------- ### Register Menu Command with Shortcut Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/keyboard-shortcuts/index.mdx Associate a keyboard shortcut with a GM_registerMenuCommand. The shortcut representation is included in the menu command name for clarity. ```js const shortcut = 'c-g c-g'; const name = 'Good Game'; const handler = () => alert('Good Game!'); // Register menu command const menuName = `${name} (${VM.shortcut.reprShortcut(shortcut)})`; GM_registerMenuCommand(menuName, handler); // Register shortcut VM.shortcut.register(shortcut, handler); ``` -------------------------------- ### Inject Script using Blob URL (Now) Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-scripts-with-blob-urls.md This is the current method used since Violentmonkey v2.8.15, employing Blob URLs to inject scripts. It resolves CSP issues on Firefox 58+ and is generally more robust. ```javascript const b = new Blob([script], { type: 'text/javascript' }); const u = URL.createObjectURL(b); const s = document.createElement('script'); s.src = u; document.body.appendChild(s); document.body.removeChild(s); URL.revokeObjectURL(u); ``` -------------------------------- ### Userscript Metadata Block Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/guide/creating-a-userscript/index.md The metadata block declares essential information about the script, such as its name, namespace, the URLs it should run on (@match), granted permissions (@grant), version, author, and a brief description. Ensure the @match directive correctly specifies the target URLs. ```javascript // ==UserScript== // @name New script // @namespace Violentmonkey Scripts // @match *://*/* // @grant none // @version 1.0 // @author - // @description 3/8/2020, 8:42:28 PM // ==/UserScript== ``` -------------------------------- ### GM_registerMenuCommand Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Registers a command in the Violent Monkey popup menu, which can be invoked by the user. ```APIDOC ## GM_registerMenuCommand Registers a command in Violentmonkey popup menu. ### Usage ```js GM_registerMenuCommand('Text', onClick) const id2 = GM_registerMenuCommand('Text2', onClick, { title: 'Two' }) const id3 = GM_registerMenuCommand('Text3', onClick, { autoClose: false }) ``` ### Parameters - **caption** (string) - Required - This text will be shown in the popup menu. - **onClick** (function) - Required - When the command is clicked in the menu, this function will run. - **event** (MouseEvent | KeyboardEvent) - Optional, since VM2.13.1 - The event that activated the command, allowing checks for `event.button`, `event.shiftKey`, `event.key`, etc. - **options** (object) - Optional, since VM2.15.9 - **id** (string) - Optional, since VM2.15.9 - Default: `caption` text (since VM2.16.2). Default in 2.15.9-2.16.1: a randomly generated string. - **icon** (string) - Optional, since VM2.31.1 - URL of the icon. - **title** (string) - Optional - A hint shown in the status bar when hovering the command. - **autoClose** (boolean) - Optional, defaultValue: `true` - Whether to auto-close the popup after the user invoked the command. ### Returns The command's `caption` (since VM2.12.5) or `id` (since VM2.15.9). ### Example ```js const id = 'status'; const inplace = id === GM_registerMenuCommand('Enabled', onClick, { id }); if (inplace) { // supported: change the command in-place using the same `id` GM_registerMenuCommand('Disabled', onClick, { id, title: 'Status' }); } else { // not supported: recreate the commands GM_unregisterMenuCommand('Enabled'); GM_unregisterMenuCommand('Foo'); GM_unregisterMenuCommand('Bar'); GM_registerMenuCommand('Disabled', onClick); GM_registerMenuCommand('Foo', onClick2); GM_registerMenuCommand('Bar', onClick3); } ``` ``` -------------------------------- ### Set System Clipboard - Violentmonkey API Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Copies specified data to the system clipboard. You can also specify the MIME type of the data being copied. ```javascript GM_setClipboard(data, type) ``` -------------------------------- ### Required Scripts Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @require key specifies the URL of another script that must be executed before the current one. Local files are not permitted. ```javascript // @require https://my.cdn.com/jquery.js ``` -------------------------------- ### Set a value in storage Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Sets a key-value pair in the script's storage. The value must be JSON serializable. ```javascript GM_setValue(key, value) ``` -------------------------------- ### Add Style Element Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Appends and returns a style element with the specified CSS code. Older versions might return a Promise-like object for compatibility. ```javascript let styleElement = GM_addStyle(css); ``` -------------------------------- ### Detect URL Changes with Navigation API or MutationObserver Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md This snippet demonstrates how to detect URL changes using either the Navigation API or a MutationObserver. It sets up an event listener for 'navigatesuccess' if available, otherwise it falls back to observing DOM mutations to track URL changes. The `onUrlChange` function is called when a URL change is detected. ```javascript if (self.navigation) { navigation.addEventListener('navigatesuccess', onUrlChange); } else { let u = location.href; new MutationObserver(() => u !== (u = location.href) && onUrlChange()) .observe(document, {subtree: true, childList: true}); } function onUrlChange() { if (!location.pathname.startsWith('/watch')) { // deactivate(); return; } console.log('processing', location.href); // activate(); } ``` -------------------------------- ### Show Desktop Notification (Object) - Violentmonkey API Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Displays a desktop notification using the browser's notification API. This method accepts an options object for detailed configuration. It returns a control object with a `remove` function. ```javascript let control = GM_notification(options) ``` -------------------------------- ### Add a storage change listener Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Adds a listener that triggers a callback function when a specified storage value changes. Returns a listener ID for removal. ```javascript let listenerId = GM_addValueChangeListener(name, callback) ``` -------------------------------- ### Grant No Special APIs - @grant none Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx When no special APIs are needed, use '@grant none' to disable sandboxing and allow direct modification of global variables. This was the default behavior before Violentmonkey v2.32.0. ```javascript // @grant none ``` -------------------------------- ### Open URL in New Tab (Background) Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Opens a URL in a new tab, compatible with Greasemonkey's boolean option to control background opening. `true` opens in background. ```javascript let tabControl = GM_openInTab(url, openInBackground) ``` -------------------------------- ### GM_addElement Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Appends and returns an element with the specified attributes. This is primarily used to circumvent strict Content Security Policies that forbid adding inline code or style. ```APIDOC ## GM_addElement *Since VM2.13.1* Appends and returns an element with the specified attributes with the primary purpose of circumventing a strict `Content-Security-Policy` that forbids adding inline code or style. ```js let element1 = GM_addElement(tagName, attributes); let element2 = GM_addElement(parentNode, tagName, attributes); ``` ### Parameters * **parentNode?** (Node | Element | ShadowRoot) - Optional - The parent node to which the new node will be appended. It can be inside ShadowDOM: `someElement.shadowRoot`. When omitted, it'll be determined automatically: `document.head` for `script`, `link`, `style`, `meta` tags; `document.body` for other tags or when there's no ``; `document.documentElement` otherwise. * **tagName** (string) - Required - A tag name like `'script'`. * **attributes?** (object) - Optional - The keys are HTML attributes, not DOM properties, except `textContent` which sets DOM property `textContent`. The values are strings. ### Examples ```js // using a private function in `onload` let el = GM_addElement('script', { src: 'https://....' }); el.onload = () => console.log('loaded', el); ``` ```js // same as GM_addStyle('a { color:red }') let el = GM_addElement('style', { textContent: 'a { color:red }' }); ``` ```js // appending to an arbitrary node let el = GM_addElement(parentElement.shadowRoot, 'iframe', { src: url }); ``` ### Notes The element is returned immediately (synchronously). Invalid arguments will raise an exception, which can be caught using `try {} catch (e) {}`, just like standard DOM API `document.createElement`. ``` -------------------------------- ### GM_getValues Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves multiple values for the current script from storage. ```APIDOC ## GM_getValues ### Description Retrieves multiple values for the current script from storage. ### Method 1. **Using an array of keys.** ```js let values = GM_getValues(['foo', 'bar']) ``` 2. **Using an object.** Each key is a name to read from storage, the value is the default to be used in the result if the key was not in storage. ```js let values = GM_getValues({ foo: 1, bar: [2] }) ``` ### Parameters #### Path Parameters - **keys** (string[]) - Required - An array of keys to retrieve values for. - **defaults** (Object) - Optional - An object where keys are the names to read from storage and values are the defaults to be used in the result if the key was not in storage. ### Response #### Success Response (200) - **values** (Object) - An object containing the retrieved key-value pairs. ### Response Example ```json { "foo": 123, "bar": [1, 2, 3] } ``` ``` -------------------------------- ### GM_setValues Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Writes multiple values to the current script's storage. ```APIDOC ## GM_setValues ### Description Writes multiple values to the current script's storage. ### Method ```js GM_setValues({ foo: 1, bar: [1, 2, 3] }) ``` ### Parameters #### Path Parameters - **data** (Object) - Required - Each `key:value` pair in the object will be stored individually. Must be JSON serializable. ### Request Example ```js GM_setValues({ username: 'Bob', preferences: { theme: 'dark' } }) ``` ``` -------------------------------- ### Grant Window Focus API - @grant window.focus Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx Enable the script to focus the current tab using window.focus(), even without prior user interaction. This feature was added in Violentmonkey v2.12.10. ```javascript // @grant window.focus ``` -------------------------------- ### Watch for URL Changes in SPA Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/matching.md This snippet demonstrates how to manually trigger a check for URL changes within an SPA after the initial script has loaded. This is useful for scripts that need to react to client-side navigation. ```javascript onUrlChange(); ``` -------------------------------- ### GM_listValues Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Returns an array of keys of all available values within this script. ```APIDOC ## GM_listValues ### Description Returns an array of keys of all available values within this script. ### Method ```js let arrayOfKeys = GM_listValues() ``` ### Response #### Success Response (200) - **arrayOfKeys** (string[]) - An array of strings, where each string is a key stored for the current script. ### Response Example ```json ["username", "preferences", "lastLogin"] ``` ``` -------------------------------- ### GM_unregisterMenuCommand Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Unregisters a command that was previously registered to the Violent Monkey popup menu. ```APIDOC ## GM_unregisterMenuCommand ### Description Unregisters a command which has been registered to Violentmonkey popup menu. ### Method Signature ```js GM_unregisterMenuCommand(captionOrId) ``` ### Parameters #### Path Parameters - **captionOrId** (string) - Required - The caption or id of the command to unregister. See [GM_registerMenuCommand](#gm_registermenucommand) for more info. ``` -------------------------------- ### Script Icon Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @icon key specifies the URL for an icon to represent the script. ```javascript // @icon https://my.cdn.com/icon.png ``` -------------------------------- ### Inject Script using textContent (Before v2.8.15) Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-scripts-with-blob-urls.md This method was used in older versions of Violentmonkey to inject scripts by setting the textContent of a script element. It works on Chrome but fails on Firefox 57- with CSP limitations. ```javascript const s = document.createElement('script'); s.textContent = script; document.body.appendChild(s); document.body.removeChild(s); ``` -------------------------------- ### GM_getResourceURL Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves a blob: or data: URL of a resource from the metadata block. This function can return either a blob URL (default) or a data URL based on the `isBlobUrl` parameter. ```APIDOC ## GM_getResourceURL Retrieves a `blob:` or `data:` URL of a resource from the metadata block. ```js let blobUrl = GM_getResourceURL(name); let blobOrDataUrl = GM_getResourceURL(name, isBlobUrl); ``` ### Parameters * **name** (string) - Required - Name of a resource defined in the [metadata block](../metadata-block/#resource). * **isBlobUrl** (boolean) - Optional (since VM2.13.1, defaultValue: true) - If true, returns a `blob:` URL. If false, returns a `data:` URL. ### Notes When setting this URL as `src` or `href` of a DOM element, it may fail on some sites with a particularly strict CSP that forbids `blob:` or `data:` URLs. The workaround in Chrome is to use `GM_addElement`, whereas in Firefox you'll have to disable CSP either globally via `about:config` or by using an additional extension that modifies HTTP headers selectively. ``` -------------------------------- ### GM_setValue Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Sets a key/value pair for the current script to storage. ```APIDOC ## GM_setValue ### Description Sets a key/value pair for the current script to storage. ### Method ```js GM_setValue(key, value) ``` ### Parameters #### Path Parameters - **key** (string) - Required - The unique name for `value` within this script. - **value** (any) - Required - The value to be stored, which must be JSON serializable. ### Request Example ```js GM_setValue('username', 'Alice') ``` ``` -------------------------------- ### Make a Cross-Origin Request with GM_xmlhttpRequest Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Use GM_xmlhttpRequest to make requests similar to XMLHttpRequest, but without same-origin policy restrictions. The `details` object configures the request, and event handlers can be provided to manage the response. ```javascript let control = GM_xmlhttpRequest(details) ``` -------------------------------- ### Localized Script Names Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @name key can be localized for different languages by appending a colon and the locale code, such as `@name:zh-CN` for Simplified Chinese. ```javascript // @name Violentmonkey Script // @name:zh-CN 暴力猴脚本 ``` -------------------------------- ### GM_notification Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Shows a desktop notification using the browser.notifications API. Can be called with an options object or separate parameters. ```APIDOC ## GM_notification ### Description Shows a desktop notification using the [browser.notifications API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications). ### Method Signature (Object) ```js let control = GM_notification(options) ``` ### Parameters (Object) #### Request Body - **options** (object) - Required - **text** (string) - Required - Main text of the notification. - **title?** (string) - Optional - Title of the notification. - **image?** (string) - Optional - URL of an image to show in the notification. - **silent?** (boolean) - Optional - No sounds/vibrations when showing the notification. Only for Chromium-based browsers as of Aug 2023. Defaults to `false`. - **tag?** (string) - Optional - Unique name of the notification, e.g. 'abc', same as the web Notification API. Names are scoped to each userscript. The purpose of a tagged notification is to replace an older notification with the same tag. - **zombieTimeout?** (number) - Optional - Number of milliseconds to keep the notification after the userscript "dies". Defaults to `0`. - **zombieUrl?** (string) - Optional - URL to open when a zombie notification is clicked. - **onclick?** (function) - Optional - Callback when the notification is clicked by user. - **ondone?** (function) - Optional - Callback when the notification is closed. ### Method Signature (Separate Parameters) ```js GM_notification(text, title, image, onclick) ``` ### Parameters (Separate Parameters) #### Path Parameters - **text** (string) - Required - Main text of the notification. - **title?** (string) - Optional - Title of the notification. - **image?** (string) - Optional - URL of an image to show in the notification. - **onclick?** (function) - Optional - Callback when the notification is clicked by user. ### Response #### Success Response (200) As of VM2.12.8 returns a control object with the following properties: - **remove** (function) - A function to remove the notification. ``` -------------------------------- ### GM_getValue Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves a value for the current script from storage. ```APIDOC ## GM_getValue ### Description Retrieves a value for the current script from storage. ### Method ```js let value = GM_getValue(key, defaultValue) ``` ### Parameters #### Path Parameters - **key** (string) - Required - The name for `value` to load. - **defaultValue** (any) - Optional - The default value to return if no value exists in the storage. ### Response #### Success Response (200) - **value** (any) - The retrieved value from storage, or the default value if not found. ### Request Example ```js let username = GM_getValue('username', 'Guest') ``` ### Response Example ```json "Guest" ``` ``` -------------------------------- ### Script Namespace Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx The @namespace key, combined with @name, uniquely identifies a userscript. It can be any string, often a homepage URL. ```javascript // @namespace https://violentmonkey.github.io ``` -------------------------------- ### Grant New GM API - @grant GM.getValue Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx Grant access to the newer GM.* API methods, such as GM.getValue. This syntax is available since Violentmonkey v2.12.10. ```javascript // @grant GM.getValue // @grant GM.setValue ``` -------------------------------- ### Register Menu Command Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Registers a command in the Violent Monkey popup menu. The command is identified by its caption and an optional onClick handler. ```javascript GM_registerMenuCommand('Text', onClick) ``` ```javascript const id2 = GM_registerMenuCommand('Text2', onClick, { title: 'Two' }) ``` ```javascript const id3 = GM_registerMenuCommand('Text3', onClick, { autoClose: false }) ``` -------------------------------- ### Firefox Content Script Workaround with wrappedJSObject and exportFunction Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/posts/inject-into-context.md Use this Firefox-specific workaround to access and expose webpage JavaScript objects from a content script. Ensure `exportFunction` is available and `unsafeWindow` is used if available, otherwise fallback to `window`. ```javascript if (typeof exportFunction === 'function') { const wnd = typeof unsafeWindow === 'object' ? unsafeWindow : window; wnd.wrappedJSObject.foo = 1; wnd.wrappedJSObject.bar = exportFunction(function myFancyApi(x) { return cloneInto({ test: () => x }, wnd, { cloneFunctions: true }); }); } ``` -------------------------------- ### GM_getResourceText Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Retrieves a text resource from the metadata block. ```APIDOC ## GM_getResourceText ### Description Retrieves a text resource from the metadata block. ### Method ```js let text = GM_getResourceText(name) ``` ### Parameters #### Path Parameters - **name** (string) - Required - Name of a resource defined in the [metadata block](../metadata-block/#resource). ### Response #### Success Response (200) - **text** (string) - The content of the requested text resource. ### Request Example ```js let config = GM_getResourceText('config.json') ``` ### Response Example ```json "{\"setting1\": \"value1\", \"setting2\": 123}" ``` ``` -------------------------------- ### Enable Top-Level Await with @top-level-await Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx Enable top-level await in your userscript to use await expressions outside of async functions. This is useful for waiting on external events or network data before the rest of your script executes. Avoid using it for essential dependencies; prefer @require or @resource for those. ```javascript // @top-level-await const data = await fetch('/api/data'); console.log(data); ``` -------------------------------- ### Inject Script Directly with @unwrap Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/metadata-block.mdx Use the @unwrap directive to inject a script directly into the page's global scope without Violentmonkey's standard wrapper. This bypasses GM API access and is useful for interacting with global page variables or migrating from other extensions. ```javascript // @unwrap // @inject-into content console.log('Script injected directly into global scope'); ``` -------------------------------- ### GM_addValueChangeListener Source: https://github.com/violentmonkey/violentmonkey.github.io/blob/source/content/pages/api/gm.mdx Adds a change listener to the storage and returns the listener ID. ```APIDOC ## GM_addValueChangeListener ### Description Adds a change listener to the storage and returns the listener ID. ### Method ```js let listenerId = GM_addValueChangeListener(name, callback) ``` ### Parameters #### Path Parameters - **name** (string) - Required - The name of the observed variable. - **callback** (function) - Required - A function to be called when the value changes. It receives `name`, `oldValue`, `newValue`, and `remote` as arguments. - **name** (string) - The name of the observed variable. - **oldValue** (any) - The old value of the observed variable (`undefined` if it was created). - **newValue** (any) - The new value of the observed variable (`undefined` if it was deleted). - **remote** (boolean) - `true` if modified by another tab, `false` otherwise. ### Request Example ```js GM_addValueChangeListener('counter', (name, oldValue, newValue, remote) => { console.log(`Value of ${name} changed from ${oldValue} to ${newValue}. Remote: ${remote}`); }); ``` ```