Você precisa adicionar um "Grant" a esse script de qualquer maneira ...
O Greasemonkey 1.0 adiciona um imperativo especial do Bloco de Metadados: @grant.
If a script does not specify any @grant values, Greasemonkey 1.0-1.9 will attempt to auto-detect the right settings. From GreaseMonkey 2.0, @grant none is assumed by default, if no other values are specified.[1]
If a script specifies any values (or they were auto detected), then it will be provided with only those API methods that it declares.
The valid values are unsafeWindow, and the names of those GM_ prefixed values that you wish your script to be granted access to.
Otherwise the script will be granted no special API privileges, and thus run without the security constraints Greasemonkey scripts have traditionally had. If you want your script to operate in this mode, you should explicitly declare @grant none.
Exemplos
É comum que scripts (mais da metade quando contados pela última vez) não usem nenhuma API especial. Para tais scripts, pedir explicitamente que não sejam concedidos privilégios especiais significa que o script será executado diretamente na página de conteúdo. Isso significa que não há sandbox de segurança e nenhuma de suas limitações, portanto, acessar variáveis na página simplesmente funciona, chamar funções e ler seus resultados também funciona. Para fazer isso, simplesmente:
// ==UserScript==
// @name Grant None Example (can be omitted since GM 2.0)
// @include http*
// @grant none
// ==/UserScript==
console.log('This script grants no special privileges, so it runs without security limitations.');
Se você usar uma das APIs do Greasemonkey, deverá pedir explicitamente que ela seja concedida ao seu script:
// ==UserScript==
// @name Grant Some Example
// @include http*
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
var counter = GM_getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM_setValue('counter', ++counter);
Nesse caso, o script está pedindo para ter acesso aos dois GM_getValue
e GM_setValue
, um em cada linha @grant
. Especifique o nome de qualquer API do Greasemonkey para receber acesso a ele. (Todos os scripts sempre obtêm GM_info
sem solicitá-lo especificamente.) Temporariamente, isso também funcionaria:
// ==UserScript==
// @name Grant Legacy Example
// @include http*
// ==/UserScript==
var counter = GM_getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM_setValue('counter', ++counter);
Este exemplo funcionará na versão 1.0 do Greasemonkey. Quando não há linhas @grant, o Greasemonkey tenta detectar quais APIs estão sendo usadas e age como se essas linhas @grant tivessem sido especificadas. Essa detecção pode falhar em certos casos, especialmente quando eval()
é usado.
Todos os scripts escritos antes de @grant devem continuar a funcionar por causa disso, mas você deve alterar seus scripts para especificar @grant assim que eles não forem violados no futuro.
Camada de Compatibilidade
Muitas das APIs do Greasemonkey foram duplicadas pelos padrões da web, como o DOM Storage. Se você espera que seu script opere apenas em um único domínio, você pode usar @grant none e sua compatibilidade aumentada sem nenhum inconveniente imediatamente. Basta usar uma biblioteca @require para emular as APIs do Greasemonkey com recursos de navegador agora padrão:
// ==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);
Este script funcionará da mesma forma que o exemplo acima, exceto que o grant none shim está fornecendo emulação de API com recursos padrão do navegador. Quando a camada de compatibilidade do shim funciona bem o suficiente para o seu script, esse é o melhor dos dois mundos.
Âmbito
Na concessão de nenhum caso, o script de usuário ainda possui seu próprio escopo global, distinto do escopo global da página de conteúdo. Isso significa que um var x = 1;
de nível superior não estará visível no escopo do conteúdo e, portanto, não quebrará a página (isto é, se depender de uma variável x com um valor diferente). Para gravar valores no escopo do conteúdo, window.x = 1;
.
Se você usar @require
de uma versão do jQuery, ela será atribuída implicitamente a window.$
e window.jQuery
. Se a página que você executar depender de uma versão diferente do jQuery, isso poderá quebrar a página. Para contornar este problema, em qualquer lugar no nível superior do seu script, faça o seguinte:
this.$ = this.jQuery = jQuery.noConflict(true);
Este código salvará uma referência jQuery (para isso, o escopo global do script quando executado no modo nenhum de concessão), enquanto o remove da janela (o escopo global do conteúdo) e restaura qualquer coisa originalmente armazenada lá.