Os scripts de conteúdo são executados em um ambiente de "mundo isolado" . Você precisa injetar seu state()
método na própria página.
Quando você deseja usar uma das chrome.*
APIs no script, precisa implementar um manipulador de eventos especial, conforme descrito nesta resposta: Extensão do Chrome - recuperando a mensagem original do Gmail .
Caso contrário, se você não precisar usar chrome.*
APIs, recomendo injetar todo o seu código JS na página adicionando uma <script>
tag:
Índice
- Método 1: Injetar outro arquivo
- Método 2: injetar código incorporado
- Método 2b: usando uma função
- Método 3: usando um evento embutido
- Valores dinâmicos no código injetado
Método 1: Injetar outro arquivo
Este é o método mais fácil / melhor quando você tem muito código. Inclua seu código JS real em um arquivo na sua extensão, digamos script.js
. Em seguida, deixe o seu script de conteúdo da seguinte maneira (explicado aqui: Javascript personalizado do "Google Shortcut" do Google Chome ):
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
Nota: Se você usar esse método, o script.js
arquivo injetado deverá ser adicionado à "web_accessible_resources"
seção ( exemplo ). Caso contrário, o Chrome se recusará a carregar seu script e exibirá o seguinte erro no console:
Negando a carga da extensão chrome: // [EXTENSIONID] /script.js. Os recursos devem ser listados na chave do manifesto web_accessible_resources para serem carregados por páginas fora da extensão.
Método 2: injetar código incorporado
Esse método é útil quando você deseja executar rapidamente um pequeno pedaço de código. (Veja também: Como desativar as teclas de atalho do facebook com a extensão do Chrome? ).
var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Nota: os literais de modelo são suportados apenas no Chrome 41 e superior. Se você deseja que a extensão funcione no Chrome 40-, use:
var actualCode = ['/* Code here. Example: */' + 'alert(0);',
'// Beware! This array have to be joined',
'// using a newline. Otherwise, missing semicolons',
'// or single-line comments (//) will mess up your',
'// code ----->'].join('\n');
Método 2b: usando uma função
Para um grande pedaço de código, não é possível citar a string. Em vez de usar uma matriz, uma função pode ser usada e stringificada:
var actualCode = '(' + function() {
// All code is executed in a local scope.
// For example, the following does NOT overwrite the global `alert` method
var alert = null;
// To overwrite a global variable, prefix `window`:
window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();
Este método funciona, porque o +
operador em cadeias e uma função converte todos os objetos em uma cadeia. Se você pretende usar o código mais de uma vez, é aconselhável criar uma função para evitar a repetição do código. Uma implementação pode se parecer com:
function injectScript(func) {
var actualCode = '(' + func + ')();'
...
}
injectScript(function() {
alert("Injected script");
});
Nota: Como a função é serializada, o escopo original e todas as propriedades associadas são perdidas!
var scriptToInject = function() {
console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output: "undefined"
Método 3: usando um evento embutido
Às vezes, você deseja executar algum código imediatamente, por exemplo, para executar um código antes que o <head>
elemento seja criado. Isso pode ser feito inserindo uma <script>
etiqueta com textContent
(consulte o método 2 / 2b).
Uma alternativa, mas não recomendada, é usar eventos embutidos. Não é recomendado porque, se a página definir uma política de Segurança de Conteúdo que proíba scripts embutidos, os ouvintes de eventos embutidos serão bloqueados. Os scripts embutidos injetados pela extensão, por outro lado, ainda são executados. Se você ainda deseja usar eventos embutidos, é assim:
var actualCode = '// Some code example \n' +
'console.log(document.documentElement.outerHTML);';
document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');
Nota: Este método assume que não há outros ouvintes de eventos globais que manipulam o reset
evento. Se houver, você também pode escolher um dos outros eventos globais. Basta abrir o console do JavaScript (F12), digitar document.documentElement.on
e escolher os eventos disponíveis.
Valores dinâmicos no código injetado
Ocasionalmente, você precisa passar uma variável arbitrária para a função injetada. Por exemplo:
var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
alert(GREETING + NAME);
};
Para injetar esse código, você precisa passar as variáveis como argumentos para a função anônima. Certifique-se de implementá-lo corretamente! O seguinte não funcionará:
var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
// ^^^^^^^^ ^^^ No string literals!
A solução é usar JSON.stringify
antes de passar o argumento. Exemplo:
var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';
Se você tiver muitas variáveis, vale a pena usar JSON.stringify
uma vez, para melhorar a legibilidade, da seguinte maneira:
...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';
player.addEventListener("onStateChange", state);