onClick na extensão do Chrome não funciona

Esta parece ser a coisa mais fácil de fazer, mas simplesmente não está funcionando. Em um navegador normal, os arquivos .html e .js funcionam perfeitamente, mas na extensão do Chrome, a function onClick não está executando o que deve fazer.

arquivo .js:

 function hellYeah(text) { document.getElementById("text-holder").innerHTML = text; } 

arquivo .html:

     Getting Started Extension's Popup     
ha

hyhy

Então, basicamente, uma vez que o usuário clica em “hyhy”, “ha” deve mudar para “xxx”. E novamente – funciona perfeitamente no navegador, mas não funciona na extensão. Você sabe por quê? Apenas no caso eu estou anexando o manifest.json abaixo também.

Desde já, obrigado!

manifest.json:

 { "name": "My First Extension", "version": "1.0", "manifest_version": 2, "description": "The first extension that I made.", "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "permissions": [ "http://api.flickr.com/" ] } 

As extensões do Google Chrome não permitem que você tenha JavaScript inline ( documentação ). Você vai ter que fazer algo parecido com isso.

Atribua um ID ao link ( torna-se ) e use addEventListener para vincular o evento. Coloque o seguinte no seu arquivo popup.js :

 document.addEventListener('DOMContentLoaded', function() { var link = document.getElementById('link'); // onClick's logic below: link.addEventListener('click', function() { hellYeah('xxx'); }); }); 

Razão

Isso não funciona, porque o Google Chrome proíbe qualquer tipo de código inline nas extensões por meio da Política de segurança de conteúdo.

O JavaScript embutido não será executado. Essa restrição proíbe os blocos inline e os manipuladores de events in - line (por exemplo, ).

Como detectar

Se esse for realmente o problema, o Chrome produzirá o seguinte erro no console:

Recusou-se a executar o script in-line porque viola a seguinte diretiva da Diretiva de Segurança de Conteúdo: "script-src 'self' chrome-extension-resource:". A palavra-chave 'inseguro', um hash ('sha256 -...') ou um nonce ('nonce -...') é necessário para ativar a execução em linha.

Para acessar o console JavaScript de um pop-up (que é útil para debugging em geral), clique com o botão direito do mouse no botão da sua extensão e selecione "Inspecionar pop-up" no menu de contexto.

Mais informações sobre a debugging de um pop-up estão disponíveis aqui .

Como consertar

É preciso remover todo o JavaScript inline. Existe um guia na documentação do Chrome .

Suponha que o original se pareça com:

 Click this  

É preciso remover o atributo onclick e fornecer ao elemento um ID exclusivo:

 Click this  

Em seguida, anexe o listener de um script (que deve estar em um arquivo .js , suponha que popup.js ):

 // Pure JS: document.addEventListener('DOMContentLoaded', function() { document.getElementById("click-this").addEventListener("click", handler); }); // The handler also must go in a .js file function handler() { /* ... */ } 

Observe o envolvimento em um evento DOMContentLoaded . Isso garante que o elemento exista no momento da execução. Agora adicione a tag de script, por exemplo, no do documento:

  

Alternativa se você estiver usando jQuery:

 // jQuery $(document).ready(function() { $("#click-this").click(handler); }); 

Relaxando a política

P: O erro menciona maneiras de permitir o código embutido. Eu não quero / não posso mudar meu código, como eu habilito scripts embutidos?

R: Apesar do que o erro diz, você não pode habilitar o script embutido :

Não há mecanismo para relaxar a restrição contra a execução do JavaScript in-line. Em particular, definir uma política de script que inclua 'unsafe-inline' não terá efeito.

Atualização: desde o Chrome 46, é possível colocar na lista de permissions blocos de códigos embutidos específicos:

A partir do Chrome 46, os scripts sequenciais podem estar na lista de permissions, especificando o hash codificado em base64 do código-fonte na política. Esse hash deve ser prefixado pelo algoritmo de hash usado (sha256, sha384 ou sha512). Consulte Uso de hash para elementos para um exemplo.

No entanto, não vejo um motivo para usá-lo e ele não ativará atributos inline como onclick="code" .

Eu tive o mesmo problema, e não queria rewrite o código, então escrevi uma function para modificar o código e criar os events declarados em linha:

 function compile(qSel){ var matches = []; var match = null; var c = 0; var html = $(qSel).html(); var pattern = /(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/mg; while (match = pattern.exec(html)) { var arr = []; for (i in match) { if (!isNaN(i)) { arr.push(match[i]); } } matches.push(arr); } var items_with_events = []; var compiledHtml = html; for ( var i in matches ){ var item_with_event = { custom_id : "my_app_identifier_"+i, code : matches[i][5], on : matches[i][3], }; items_with_events.push(item_with_event); compiledHtml = compiledHtml.replace(/(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/m, "<$2 custom_id='"+item_with_event.custom_id+"' $7 $8"); } $(qSel).html(compiledHtml); for ( var i in items_with_events ){ $("[custom_id='"+items_with_events[i].custom_id+"']").bind(items_with_events[i].on, function(){ eval(items_with_events[i].code); }); } } $(document).ready(function(){ compile('#content'); }) 

Isso deve remover todos os events inline do nó selecionado e recriá-los com jquery.