Gear Browser

Userscript Add-on Documentation

Gear provides a new high-performance mobile Userscript engine compatible with Tampermonkey, Greasemonkey, and Violentmonkey Userscript.

Basic demo

// ==UserScript==
// @name         {{name}}
// @version      0.1
// @description  New Userscript
// @author       You
// @match        *
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    // Your code here...
    
})();

Userscript headers

GM APIs

unsafeWindow

The shadow window object for full access to the page's JavaScript functions and variables.

Storage
Gear provides a high-performance storage engine. You save your script data here. It's standalone with the website and will be cleared up when the script is uninstalled. You can use those functions to save and delete data from the storage.
Set value to the storage.

GM_setValue(name, value) : void
GM.setValue(name, value) : Promise
        
Set values with multiple key-value pairs to the storage.

GM_setValues(values) : void
GM.setValues(values) : Promise

GM_setValues({
    "foo": "bar",
    "key": "value"
});

await GM.setValues({
    "foo": "bar",
    "key": "value"
});
        
Get value from the storage. You can provide a default value if nothing is found in the storage.

GM_getValue(name, defaultValue) : any
GM.getValue(name, defaultValue) : Promise
        
Get values with keys from the storage. You can provide a default value if nothing is found in the storage.

GM_getValues(keys) : any
GM.getValues(keys) : Promise

const values = GM_getValues(['foo', 'bar']);
const asyncValues = await GM.getValues(['foo', 'bar']);

const defaultValues = GM_getValues({
    "foo": 1,
    "bar": 2
});

const asyncDefaultValues = await GM.getValues({
    "foo": 1,
    "bar": 2
});
        
Delete a value from the storage.

GM_deleteValue(name) : void
GM.deleteValue(name) : Promise
        
Delete values from the storage.

GM_deleteValues(keys) : void
GM.deleteValues(keys) : Promise

GM_deleteValues(["foo", "bar"]);
await GM.deleteValues(["foo", "bar"]);
        
List an array of keys from the storage.

GM_listValues() : array
GM.listValues() : Promise
        

// All GM cookie APIs are experimental, and may change in the further.
GM_cookie.list(details, callback) : void
GM.cookies.list(details) : Promise

const details = {
    // url string?, The URL to retrieve cookies. If not specified, it will use the current URL.
    url: "https://gear4.app",

    // domain string?, The domain of the cookies to retrieve.
    domain: "gear4.app",

    // name string?, The name of the cookies to retrieve.
    name: "foo",

    // path string?, The path of the cookies to retrieve.
    path: "/"
};

GM_cookie.list(details, function(cookies, error) {
    console.log(cookies);
});

const cookies = await GM.cookies.list(details)
console.log(cookies);

// ----------------------
GM_cookie.set(details, callback) : void
GM.cookies.set(details) : Promise

const details = {
    // name string, the name of the cookie.
    name: "foo",

    // value string, the value of the cookie.

    // url string?, the URL to retrieve cookies. If not specified, it will use the current URL.
    url: "https://gear4.app",

    // domain string?, the domain of the cookies to retrieve.
    domain: "gear4.app",

    // path string?, the path of the cookies to retrieve.
    path: "/",

    // secure bool?, should cookie be sent over HTTPS.
    secure: true,

    // httpOnly bool?, should cookie used as HTTPOnly.
    httpOnly: false,

    // expirationDate number?, the expiration date for the cookie.
    expirationDate: 60 * 60 * 24 // Expires in one day.
};

GM_cookie.set(details, function () {
    console.log('Set cookie successfully.');
});

GM.cookie
    .set(details)
    .then(() => {
        console.log('Set cookie successfully.');
    });

// ----------------------
GM_cookie.delete(details, callback) : void

const details = {
    // url string?, the URL to retrieve cookies. If not specified, it will use the current URL.
    url: "https://gear4.app",

    // name string, the name of the cookie will be deleted.
    name: "foo"
};

GM_cookie.delete(details, function(error) {
    console.log('Delete cookie successfully');
});
        
Add a value listener to detect value change, and return the listenerId that you can remove by calling GM_removeValueChangeListener(listenerId).
GM_addValueChangeListener(name, function(name, oldValue, newValue, isRemote)) : string
Remove the value listener by listenerId.
GM_removeValueChangeListener(listenerId)
Insert a new CSS style to the head element.

GM_addStyle(style) : void
GM.addStyle(style) : void
        
Insert a new element to the document or parent node, and returns the element itself.

GM_addElement(parentNode, tagName, attributes) : node
GM_addElement(tagName, attributes) : node

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

GM_addElement(
    document.head,
    'script',
    {
        src: 'https://abc.com/script.js',
        type: 'text/javascript'
    }
);
        
Output log message to the console.

GM_log(message) : void
GM.log(message) : void
        
Get the raw content predefined from @resource.
GM_getResourceText(name) : String
Get the base64 encoded URI predefined from @resource.

GM_getResourceURL(name) : any
GM.getResourceUrl(name) : Promise
        
Register a menu command that can access from the running add-on menu.

GM_registerMenuCommand(name, fn) : String
GM.registerMenuCommand(name, fn) : String
GM_registerMenuCommand(name, fn, accessKey) : String
GM.registerMenuCommand(name, fn, accessKey) : String
GM_registerMenuCommand(name, fn, options) : String
GM.registerMenuCommand(name, fn, options) : String

const menuAction = GM_registerMenuCommand("Show Menu", callback, {
    // id number|string? The menu id will be return. If not specified it will auto generate a new menu id.
    id: "menu",
    // title string? The subtitle will be shown under the name.
    title: "show the menu",
    // autoClose: bool? Should close the menu if this menu command is tapped. Defaule is true.
    autoClose: false,
    // accessKey: string? The access key for the menu item. Not supported yet.
    accessKey: "s"
});

// You can use the return id for GM_unregisterMenuCommand to remove the menu.
GM_unregisterMenuCommand(menuAction)
        
Unregister the menu command by its id.

GM_unregisterMenuCommand(id) : void
GM.unregisterMenuCommand(id) : void
        
Open a new tab with options.

GM_openInTab(url, options) : TabObject
GM_openInTab(url, loadInBackground) : TabObject

TabObject = {
    // The tab is closed or not.
    'closed': Bool,

    // The event handler will be called when the tab is closed.
    'onclose': Function,

    // The method to close the newly opened tab.
    'close': Function
}
        
Create a new xmlHttpRequest.

GM_xmlhttpRequest(options) : RequestObject
GM.xmlHttpRequest(options) : Promise

// Contains abort() to cancel the request. The onabort handler will be called.
RequestObject = {'abort': Function}

const request = GM_xmlhttpRequest({
    // @required string: The destination URL, support URL relative path.
    "url": "https://www.example.com",

    // string (GET|POST|HEAD): The request method.
    "method": "GET",

    // Key-value object: The request header.
    "headers": {
        "referer": "value"
    },

    // string | ArrayBuffer | Blob | DataView | FormData: The data will be sent with the request.
    "data": "foo",

    // Key-value object: The cookie data with the request.
    "cookie": {
        "foo": "bar"
    },

    // boolean: Should send data in binary mode.
    "binary": false,

    // boolean: Should send data without cache.
    "nocache": false,
    
    // boolean: Should revalidate the cached content.
    "revalidate": false,

    // int: The timeout in ms
    "timeout": 2000,
    
    // any: The value which will be added to the response object.
    "context": [],

    // string (text|json|blob|arraybuffer|document): The response data type.
    "responseType": "text",

    // string: The MIME type for the request.
    "overrideMimeType": "text/plain",

    // boolean: Should send the request without cookies if true.
    "anonymous": false,
    
    // string: The user name for request authentication.
    "user": "foo",
    // string: The password for request authentication.
    "password": "pwd",
    
    // The event handlers.
    "onabort": (event) => void,
    "onerror": (event) => void,
    "onload": (event) => void,
    "onloadend": (event) => void,
    "onloadstart": (event) => void,
    "onprogress": (event) => void,
    "onreadystatechange": (event) => void,
    "ontimeout": (event) => void,

    // The event object from handlers will contain 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 response headers.
    // "response" - The response data as an object if details.responseType was set.
    // "responseXML" - The response data as an XML document.
    // "responseText" - The response data a plain string.
});

// Call this method to cancel the request.
request.abort()

// GM.xmlHttpRequest will return a promise object for async call.
const response = await GM.xmlHttpRequest(options)

console.log(response.responseText)
        
Create webRequest rules to manipulate web requests, including XMLHttpRequest, WebSocket, script, and iframe. It's better to use @webRequest meta to register.
This is an experimental feature and may change at any time.

GM_webRequest([
    // selector: string - The URL match rule. It's the shortening as `{include: [selector]}`.
    // selector: object - The URL match rules. It will work like @includes, @matches, @excludes meta. Both of them support string or array values.

    // action: string - The action for matched request. The value `Cancel` is the shortening as `{cancel: true}`.
    // action: object = {cancel: true} - Cancel the request.
    // action: object = {redirect: "URL"} - Redirect the request to a new URL.
    // action: object = {redirect: {from: "Pattern", to: "Replacement"}} - Redirect the request to a new URL that matches the pattern.
    {
        selector: 'https://example.com/*',
        action: 'cancel'
    },

    {
        selector: {
            include: '*',
            exclude: 'http://example.com/*'
        },
        action: {
            redirect: 'http://example.app'
        }
    },

    {
        selector: {
            match: 'https://example/*'
        },
        action: {
            redirect: {
                from: '([^:]+)://example.com/(.*)',
                to: '$1://example.app/redirect/$2'
            }
        }
    }
], function(info, message, details) {

    // The callback if the rule is matched.
    
    // info: string - The type of action with value "cancel" or "redirect".
    // message: string - The status message with value "ok" or "error".
    // details: object - Information about the request and rule.
        // > rule: object - The matched rule.
        // > url: string - The URL of the request.
        // > redirect_url: string - The redirected URL.
    // description: string - The error description.
});
        
Create a new download task.

GM_download(options), GM_download(url, name) : RequestObject

// Contains abort() to cancel the download request. The onabort handler will be called.
RequestObject = {'abort': Function}

const request = GM_download({
    // @required string: The destination URL, support URL relative path.
    "url": "https://www.example.com/file.mp3",

    // @required string: The file name will be saved.
    "name": "my.mp3",

    // Key-value object: The download request header.
    "headers": {
        "referer": "value"
    },

    // boolean: Should show the save as prompt. 
    "saveAs": false,

    // int: The timeout in ms
    "timeout": 2000,

    // The event handlers.
    "onerror": (event) => void,
    "onprogress": (event) => void,
    "ontimeout": (event) => void,
    "onload": (event) => void,

    // The event object from handlers will contain 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 response headers.
    // "response" - The response data as an object if details.responseType was set.
    // "responseXML" - The response data as an XML document.
    // "responseText" - The response data a plain string.
});

// Call this method to cancel the download request.
request.abort()
Set value to the clipboard.

GM_setClipboard(data, info = 'text|html') : void
GM.setClipboard(data, info = 'text|html') : void
        
Get the tab object.

// This function is unsupported.
GM_getTab
        
Save the tab object.

// This function is unsupported.
GM_saveTab
        
Send notification.

// GM_notification will only display text and title message on console.
GM_notification(text, title, image, onclick)
        
Output script information.

// You don't need to declare this API on @grant to read this value.
console.log(GM_info)

[
    "script": [
        "uuid": string,
        "name": string,
        "author": string,
        "description": string,
        "namespace": string,
        "homepage": string,
        "version": string,
        "icon": string,
        "icon64": string,
        "excludes": array,
        "includes": array,
        "matches": array,
        "requires": array,
        "resources": object,
        "run-at": string,
        "updateURL": string,
        "downloadURL": string,
        "supportURL": string,
    ],
    "downloadMode": string = native,
    "scriptMetaStr": string,
    "scriptSource": string,
    "scriptUpdateURL": string,
    "scriptHandler": string = Tampermonkey,
    "isIncognito": bool,
    "version": string
]
        

API granting group

In order to prevent the lack of some related APIs when declaring, when you are declaring any APIs in the following groups, all related APIs will also be granted. API names started with GM. or GM_ are the same.

Compatibility Issues for iOS

On iOS, all web browser render engines are using the WKWebView framework based on WebKit for displaying web content. That means all web browsers on iOS including Safari, will have the same JavaScript engine for running JavaScript code. Although WKWebView and desktop browsers like Chrome, and Microsoft Edge are WebKit-based and Userscript can run on Gear just like a desktop without having significant modification, there are still some different compatibility issues that need to check out.