@grant

From GreaseSpot Wiki
Revision as of 12:08, 3 November 2017 by Arantius (talk | contribs) (Update for 4.0)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The @grant Metadata Block imperative controls which special APIs (if any) your script uses. If no value is specified, none will be used by default. If any value or values are specified, only those API methods will be provided.

Examples

It's common for scripts not to use any special APIs at all. In that case, use @grant none.

// ==UserScript==
// @name     Grant None Example
// @include  http*
// @grant    none
// ==/UserScript==

console.log('This script uses no special privileges.');

If you specify no @grant at all, none will be assumed.

// ==UserScript==
// @name     No Grant Example
// @include  http*
// ==/UserScript==

console.log('This script uses no special privileges, but doesn't declare that.');

If you specify none and something else, none takes precedence. This can be confusing. Check for a none to remove if you're adding APIs you intend to use.

// ==UserScript==
// @name     Mixed Grant Example
// @include  http*
// @grant    none
// @grant    GM.openInTab
// ==/UserScript==

// Will fail, because `@grant none` was specified.
GM.openInTab('http://www.example.org/');

If you do use one or more of Greasemonkey's APIs, you must ask for it to be granted to your script:

// ==UserScript==
// @name     Grant Some Example
// @include  http*
// @grant    GM.getValue
// @grant    GM.setValue
// ==/UserScript==

(async ()=>{
let counter = await GM.getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM.setValue('counter', ++counter);
})();

In this case, the script is asking to be granted access to both GM.getValue and GM.setValue, one on each @grant line. Specify the name of any Greasemonkey API to be granted access to it. (All scripts always get GM.info even without specifically requesting it.)

Compatibility Layer

Over time many of the Greasemonkey APIs have been duplicated by web standards like DOM Storage. If you only ever expect your script to operate on a single domain, you can use @grant none and these web APIs.

Or, use a @require library to emulate Greasemonkey APIs with those web APIs:

// ==UserScript==
// @name        Grant None Example, With Shim
// @include     http://www.example.com/*
// @grant       none
// @require     https://gist.githubusercontent.com/arantius/3123124/raw/grant-none-shim.js
// ==/UserScript==

var counter = GM_getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM_setValue('counter', ++counter);

This script will work the same as the example above, except that the grant none shim is providing API emulation with standard browser features. When the shim compatibility layer works well enough for your script, this is the best of both worlds.