Extension Docs

Documentation

Gear Browser supports two extension models on iOS: Web Extension and UserScript, to extend browser functionality.

Web Extension

Supports Web Extensions based on the Manifest v3 model and the iOS Web Extension runtime exposed by WebKit.

Because extension resource schemes may differ across platforms, browser.runtime.getURL() is recommended instead of relying on chrome-extension:// or webkit-extension:// directly.

References

UserScript

The built-in, high-performance UserScript engine is compatible with Tampermonkey, Greasemonkey, and Violentmonkey.

All metadata and GM_* / GM.* APIs are documented below.

UserScript quick start

A minimal UserScript template to get started quickly.

// ==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

Supported metadata fields, matching rules, grants, and resource declarations.

  • @name

    The name of the UserScript. Supports localization.

    // @name My Script
    // @name:jp 私のスクリプト
  • @namespace

    The namespace of the UserScript.

  • @version

    The version of the UserScript. Increase this number whenever the script changes so Gear can determine whether an update is available.

  • @author

    The author of the UserScript. It appears in the script detail view.

  • @description

    The description of the UserScript. It appears in the add-on list. Supports localization.

    // @description Improve web page speed
    // @description:jp ウェブページの速度を改善する
  • @homepage

    The homepage URL of the script.

  • @icon, @iconURL, @defaulticon

    The icon of the UserScript. It appears in the add-on list.

    // @icon https://www.example.com/icon.png
    // @icon data:image/gif;base64,R0lGODlhEAAQAMQAAOR...
  • @icon64, @icon64URL

    The high-resolution icon of the UserScript. Gear prefers this value when displaying the icon, if it is set.

    // @icon64 https://www.example.com/icon.png
    // @icon64 data:image/gif;base64,R0lGODlhEAAQAMQAAOR...
  • @updateURL

    The URL used to check for script updates. Gear prefers this value when checking for new versions.

  • @downloadURL

    The URL used to download the script. Gear uses this value for updates if @updateURL is not set. If neither value is set, Gear reuses the original installation URL.

  • @supportURL

    The support URL for contacting the author. It is displayed in the add-on detail view.

  • @contributionURL

    The contribution URL for donations or sponsorship. It is displayed in the add-on detail view.

  • @run-at

    Defines when the script is injected.

    • document-start

      The script will be injected as fast as possible.

    • document-body

      The script will be injected if the body element exists.

    • document-end

      The script is injected when or after the DOMContentLoaded event is dispatched.

    • document-idle

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

    • context-menu

      The script is injected when it is selected from the browser context menu.

  • @run-in

    Defines the type of browser context in which the script will be injected.

    • normal-tabs

      The script will be injected for normal tabs.

    • incognito-tabs

      The script will be injected for private tabs only.

    • both

      The script will be injected for both normal tabs and private tabs.

  • @include

    The URL patterns on which the script will run. Gear prefers this value for matching.

    Matches any URL that uses the http scheme
    // @include http://*/*

    Will match: http://foo.bar/ http://example.org/foo/bar.html

    Matches any URL that uses the HTTP scheme, on any host, as long as the path starts with /foo.
    // @include http://*/foo*

    Will match: http://example.com/foo/bar.html http://abc.com/foo

    Matches any URL that starts with http or https for foo.bar.
    // @include *://foo.bar/

    Will match: http://foo.bar/ https://foo.bar

  • @match

    Works like @include. Gear uses this value if @include is not set.

  • @exclude, @exclude-match

    The URL patterns on which the script should not run. The matching rules are the same as @include.

  • @require

    The file will be loaded and executed before the script starts running.

    // @require https://code.jquery.com/jquery-2.1.4.min.js
    // @require https://foo.bar/your_packing.js
  • @resource

    Access these resources with GM_getResourceText and GM_getResourceURL. Resources are downloaded and cached in advance.

    // @resource image https://www.example.com/image.png
    // @resource data https://www.example.com/data.json
  • @connect

    The allowed domains for GM_xmlHttpRequest.

  • @grant

    The allowlist for GM_* and GM.* APIs. See the grant group list below for details.

    // @grant GM_setValue
    // @grant GM_getValue
    // @grant GM_setClipboard
    // @grant unsafeWindow
  • @webRequest

    The JSON data that follows the rule format of GM_webRequest.

    // @webRequest [{selector: 'https://example.com/*', action: 'cancel'}]
  • @tag

    Tags shown in the detail view.

    // @tag productivity
    // @tag blocker
    // @tag social
    
  • @license

    License information for the script.

  • @noframes

    Indicates that the script should run only in the top-level page, not in iframes.

  • @unwrap

    The script is injected directly into the page without a wrapper. This allows direct access to global page variables and functions. The @grant meta key is ignored, and GM_* APIs are not available.

  • @antifeature

    Indicates that the script discloses monetized or potentially undesirable features.

    // @antifeature type description
    // @antifeature ads This script contains ads.
    // @antifeature:jp ads このスクリプトには広告が含まれています。

GM APIs

Storage, network, resource, menu, tab, clipboard, audio, and notification APIs.

unsafeWindow
A shadow window object that provides full access to the page's JavaScript functions and variables.
Storage
Gear provides a high-performance storage engine for UserScripts. Data stored here is isolated from the website and is removed when the script is uninstalled. Use these APIs to save, read, and delete script data.
Set a value in storage.

GM_setValue(name, value) : void
GM.setValue(name, value) : Promise
        
Set multiple key-value pairs in storage.

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

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

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

GM_getValue(name, defaultValue) : any
GM.getValue(name, defaultValue) : Promise
        
Get multiple values from storage. You can also provide default values for missing keys.

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 storage.

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

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

GM_deleteValues(["foo", "bar"]);
await GM.deleteValues(["foo", "bar"]);
        
Return an array of keys stored for the script.

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

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

const details = {
    // url string?, The URL from which to retrieve cookies. If not specified, the current URL is used.
    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 for the cookie. If not specified, the current URL is used.
    url: "https://gear4.app",

    // domain string?, The domain for the cookie.
    domain: "gear4.app",

    // path string?, The path for the cookie.
    path: "/",

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

    // httpOnly bool?, Whether the cookie should be marked 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.cookies
    .set(details)
    .then(() => {
        console.log('Set cookie successfully.');
    });

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

const details = {
    // url string?, The URL for the cookie. If not specified, the current URL is used.
    url: "https://gear4.app",

    // name string, The name of the cookie to delete.
    name: "foo"
};

GM_cookie.delete(details, function(error) {
    console.log('Delete cookie successfully');
});
        
Add a value change listener and return a listener ID. Remove it with GM_removeValueChangeListener(listenerId).
GM_addValueChangeListener(name, function(name, oldValue, newValue, isRemote)) : string
Remove a value change listener by listener ID.
GM_removeValueChangeListener(listenerId)
Insert a CSS style element into the document head.

GM_addStyle(style) : void
GM.addStyle(style) : void
        
Insert a new element into the document or a parent node, and return 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 a log message to the console.

GM_log(message) : void
GM.log(message) : void
        
Get the raw content defined by @resource.
GM_getResourceText(name) : String
Get the Base64-encoded URI defined by @resource.

GM_getResourceURL(name) : any
GM.getResourceUrl(name) : Promise
        
Register a menu command that can be accessed 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 to return. If omitted, a new ID is generated automatically.
    id: "menu",
    // title string? A subtitle shown under the name.
    title: "show the menu",
    // autoClose: bool? Whether to close the menu when this item is tapped. Default is true.
    autoClose: false,
    // accessKey: string? The access key for the menu item. Not supported yet.
    accessKey: "s"
});

// Use the returned ID with GM_unregisterMenuCommand to remove the menu item.
GM_unregisterMenuCommand(menuAction)
        
Unregister a 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-style request.

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. Relative paths are supported.
    "url": "https://www.example.com",

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

    // Key-value object: Request headers.
    "headers": {
        "referer": "value"
    },

    // string | ArrayBuffer | Blob | DataView | FormData: Data to send with the request.
    "data": "foo",

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

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

    // boolean: Whether to send the request without using cache.
    "nocache": false,
    
    // boolean: Whether to revalidate cached content.
    "revalidate": false,

    // int: Timeout in milliseconds.
    "timeout": 2000,
    
    // any: A value 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: Whether to send the request without cookies.
    "anonymous": false,
    
    // string: The username 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 as a plain string.
});

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

// GM.xmlHttpRequest returns a Promise for async usage.
const response = await GM.xmlHttpRequest(options)

console.log(response.responseText)
        
Control audio state

GM_audio.setMute(details, callback?) : void
GM.audio.setMute(details, callback?) : Promise

GM_audio.getState(callback) : void
GM.audio.getState() : Promise

GM_audio.addStateChangeListener(listener, callback?) : void
GM.audio.addStateChangeListener(listener, callback?) : Promise

GM_audio.removeStateChangeListener(listener, callback?) : void
GM.audio.removeStateChangeListener(listener, callback?) : Promise

// Set the mute state for current tab.
GM_audio.setMute({
    // @required boolean: true to mute the tab, false to unmute it.
    "isMuted": true
}, (error) => {
    if (error) {
        console.error('mute failed:', error)
        return
    }

    console.log('tab muted')
})

// Read the current audio state.
GM_audio.getState((state) => {
    if (!state) {
        console.error('failed to read state')
        return
    }

    // boolean: Whether the tab is muted.
    console.log('muted?', state.isMuted)

    // string (user|capture|extension): The mute reason if the tab is muted.
    console.log('mute reason:', state.muteReason)

    // boolean: Whether the tab is currently playing audio.
    console.log('audible?', state.isAudible)
})

// Listen for mute / audible changes.
function onAudioStateChange(event) {
    // string | false: Mute reason, or false if not muted.
    if ('muted' in event) {
        console.log('muted:', event.muted)
    }

    // boolean: Whether the tab is currently playing audio.
    if ('audible' in event) {
        console.log('audible:', event.audible)
    }
}

GM_audio.addStateChangeListener(onAudioStateChange)

// Remove a previously registered listener.
GM_audio.removeStateChangeListener(onAudioStateChange, () => {
    console.log('listener removed')
})

// Promise style examples.
await GM.audio.setMute({ isMuted: false })

const state = await GM.audio.getState()
console.log(`muted=${state.isMuted} reason=${state.muteReason} audible=${state.isAudible}`)

await GM.audio.addStateChangeListener((event) => {
    if (event.muted) {
        console.log('muted by', event.muted)
    }
})

await GM.audio.removeStateChangeListener(onAudioStateChange)
        
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. Relative paths are supported.
    "url": "https://www.example.com/file.mp3",

    // @required string: The file name to save as.
    "name": "my.mp3",

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

    // boolean: Whether to show the Save As prompt.
    "saveAs": false,

    // int: Timeout in milliseconds.
    "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 as a plain string.
});

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

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

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

// This function is currently unsupported.
GM_saveTab
        
Send a notification.

// GM_notification currently logs only the text and title to the console.
GM_notification(text, title, image, onclick)
        
Read 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
]
        

Grant groups

Grant behavior and iOS compatibility notes for writing stable scripts.

To avoid missing related APIs in your grants, declaring any API from the following groups also grants the other APIs in the same group. API names that start with GM. and GM_ are equivalent.
  • GM_getValue, GM_addValueChangeListener, GM_removeValueChangeListener, GM_listValues
  • GM_setValue, GM_deleteValue
  • GM_addStyle, GM_addElement
  • GM_getResourceText, GM_getResourceURL, GM_getResourceUrl
  • GM_getTab, GM_saveTab, GM_getTabs
  • GM_registerMenuCommand, GM_unregisterMenuCommand

iOS compatibility

On iOS, all browsers use WebKit through the WKWebView framework to render web content. As a result, Safari and other iOS browsers share the same JavaScript engine. UserScripts can usually run on Gear with only minor changes, but there are still some compatibility differences to watch for.