Greasemonkey: Executar em frames

Criado em 21 set. 2017  ·  48Comentários  ·  Fonte: greasemonkey/greasemonkey

O Greasemonkey 4 a partir de hoje detecta apenas eventos de navegação no nível superior, então ele efetivamente aplica @noframes a cada script.

Comentários muito úteis

Olá,
Você vai consertar o problema? É um defeito muito antigo e afeta todos os scripts com base na estrutura de iframes ...

Todos 48 comentários

webNavigation.onCommitted não 'vê' a criação de quadro inicial / renderização de página, embora se o quadro navegar em algum lugar diferente de sua página inicial, o ouvinte irá detectá-lo. Se as opções incluírem a chave 'allFrames': true o problema está _algo_ resolvido. Qualquer quadro na página html estática terá o script injetado, embora você tenha problemas de correspondência de origem / url. Além disso, se um quadro for criado usando Javascript, o script não será injetado.

A solução mais fácil que eu poderia pensar seria substituir webNavigation.onCommitted por webRequest.onResponseStarted com um filtro de {'urls': ['<all_urls>'], 'types': ['main_frame', 'sub_frame']} .

Fiz alguns testes limitados e nenhuma alteração adicional foi necessária. Consegui executar um script dentro de um frame e um frame criado usando Javascript.

@arantius algum plano de mesclar a correção de @Sxderp ?

Isso está afetando cenários onde os iframes são objetos de origem cruzada, portanto, é impossível fazer qualquer tipo de modificação sem executar o GM nesses iframes em particular.

Obrigado !

Perdi isso, veremos em breve.

Só uma observação durante o meu teste de scripts antigos, não sei, se isso ajuda ...

Dado um script, ele deve funcionar em um iframe,
parece que executa as mudanças na página,
mas então atualiza novamente para a página não modificada.

Só consigo ver a oscilação quando atualizo a página muito rápido.

Só uma observação durante o meu teste de scripts antigos, não sei, se isso ajuda ...

É com o meu patch ou com a versão lançada?

Ugh, acho que foi a versão 4.0 ...
FUI @ 4.1b3, mas para os testes, tenho quase certeza, que reinstalei a versão de lançamento (até agora!)

O mesmo aqui com iframes como o Eselce descreve. De alguma forma, ele é executado, mas é interrompido depois que o iframe ou a página é carregada.

Se eu injetar este script, obtenho apenas 1 e "self! == top":

console.log('1');
if (self !== top) {
   console.log('self !== top');
   setTimeout(function() {
      console.log('Timeout');
   }, 2000);  
} else {
   console.log('self === top');
}

"Timeout" não é mostrado no log, nem todas as funções e ligações são.

Eu uso 4.1b3.

Eu tenho o mesmo problema ao executar o GM 4.0 no Quantum. Eu escrevi um exemplo fictício muito simples com duas páginas: main.html e framed.html , e um script GM que é carregado em todas as páginas e exibe a URL da página em que foi carregado.

Na maioria das vezes, só recebo notificações sobre main.html , mas em cerca de 5% dos casos, especialmente se eu mantiver F5 pressionado, também posso receber uma notificação sobre framed.html .

Existe algum hack para forçar de forma confiável o GM 4.0 a executar dentro de iframes até que um patch seja lançado?

Acabei de descobrir que scripts de usuário são executados de forma confiável em <embed src="..."> mas não em <iframe src="..">
Eu escrevi um pequeno script de teste:
https://openuserjs.org/scripts/cuzi/iframe_embed_Test_Greasemonkey_4

Mais alguns detalhes: Em alguns casos, meus scripts são executados completamente no quadro (mas a visualização é substituída posteriormente por scripts de página e assim).
Às vezes, as partes síncronas do meu script são encerradas, mas as partes assíncronas são repentinamente interrompidas pela atividade da página ...
Espero que ajude!

Alguém tem mais informações sobre isso?

Apenas um breve resumo deste tópico (problema):

  • Esqueça a maioria das postagens, elas não se aplicam
  • Provavelmente, os scripts são executados sempre (mas não até o final)
  • Infelizmente, a página é atualizada mais tarde - o layout é recalculado, a execução é abortada
  • Isso se aplica principalmente (mas não totalmente) em partes assíncronas dos scripts

Não gosto muito desses detalhes internos, mas provavelmente alguém está ...

Como uma correção temporária, estou trocando iframes por incorporações ( script de exemplo ), que funciona para obter um script correspondente ao frame a ser acionado (crédito para @cvzi por descobrir que <embed src="..."> funciona) .

Pode ser interessante notar que Violentmonkey e Tampermonkey funcionam bem dentro de frames incorporados. Visto que a VM é de código aberto, talvez veja como eles fizeram isso?

Infelizmente, Violentmonkey e Tampermonkey ainda usam o antigo esquema de nomenclatura GM_ para as funções especiais, portanto, os scripts ainda não são portáveis.

https://github.com/greasemonkey/gm4-polyfill

Tampermonkey => GM. * Chama, se não for fornecido
Violentmonkey => GM. * Chamadas
Greasemonkey -3,17 / FF -56,0 => chamadas GM. *
Greasemonkey 4.0+ / FF 57.0+ => chamadas GM. * Internas

// <strong i="11">@grant</strong>        GM.getValue
// <strong i="12">@grant</strong>        GM.setValue
// <strong i="13">@require</strong>      https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// <strong i="14">@grant</strong>        GM_getValue
// <strong i="15">@grant</strong>        GM_setValue

A correção de @Sxderp já foi incorporada ao branch principal? Se não, como devo proceder para instalar seu garfo?

A correção de @Sxderp já foi incorporada ao branch principal? Se não, como devo proceder para instalar seu garfo?

  1. Não, não tem.
  2. Infelizmente, esse é um dos meus PRs que não tenho sincronizado com o master e, portanto, não foi reformulado. Portanto, a própria ramificação está faltando algumas das alterações atuais.
  3. Também nunca implementei as mudanças sugeridas nos comentários de RP. Honestamente, essas mudanças _não_ devem ser necessárias, mas como o Mozilla continuamente bagunça as coisas, as mudanças são necessárias.
  4. Se ainda quiser usá-lo (não recomendado), siga as etapas abaixo.

  1. git clone -b use-on-response-started-for-execute --single-branch https://github.com/Sxderp/greasemonkey.git [1]
  2. Execute ./package.sh , isso criará um arquivo XPI.
  3. Vá para about:config no Firefox e defina xpinstall.signatures.required como false
  4. Vá para about:addons no Firefox, clique na engrenagem e selecione instalar do arquivo.
  5. Selecione o XPI que foi criado na etapa 2.

[1] Se sua versão do git não suporta os sinalizadores -b e / ou --single-branch (versão mais antiga do git), você pode fazer git clone https://github.com/Sxderp/greasemonkey.git e git checkout use-on-response-started-for-execute .

Olá,
Você vai consertar o problema? É um defeito muito antigo e afeta todos os scripts com base na estrutura de iframes ...

Como um lembrete, temos 13 de março amanhã (ver Firefox 59.0 ) ...

Quero me referir a @Sxderp :

webNavigation.onCommitted não 'vê' a criação de quadro inicial / renderização de página, embora se o quadro navegar em algum lugar diferente de sua página inicial, o ouvinte irá detectá-lo. Se as opções incluírem a chave 'allFrames': true, o problema está um pouco resolvido. Qualquer quadro na página html estática terá o script injetado, embora você tenha problemas de correspondência de origem / url. Além disso, se um quadro for criado usando Javascript, o script não será injetado.

Na verdade, tenho provas de que (no meu sistema) o ouvinte executeUserscriptOnNavigation é chamado de forma confiável com chrome.webNavigation.onCommitted , de modo que chrome.tabs.executeScriptInFrame é chamado com frameId correto . Por que isso não resolve todos os nossos problemas com quadros? Não devemos precisar de chrome.webRequest.onResponseStarted para reagir a um iframe! (Ou você quis dizer que reage ao evento, mas o quadro não é visível?) É definitivamente chamado ...

Existe um bug conhecido com chrome.tabs.executeScriptInFrame e frameId ? Houve problemas há anos, mas agora estão resolvidos. all_frames não está definido, portanto frameId deve ser válido. Definir a opção matchAboutBlank para true parece importar (caso contrário, executeScript retornou um erro <unavailable> ), embora eu não tenha entendido totalmente que about:blank stuff (onde está?) ...

Alguma ideia?

Recursos? Esta é a funcionalidade básica que falta desde o início ... Espero, eu interpretei mal isso.

@Eselce , isso foi há muito tempo e não tenho certeza se me lembro inteiramente do que estava me referindo, mas vou tentar. Além disso, isso só se aplica se meu entendimento sobre a combinação de quadros do GM 3.x estiver correto. Ou seja, cada origem + caminho de quadro é combinada individualmente para determinar quais scripts precisam ser executados. NÃO apenas o documento pai.

Agora, vamos ao assunto. Quando fiz meu teste inicial, tinha uma página estática com o mesmo quadro de origem e um quadro remoto. No carregamento da página inicial, só consegui fazer o retorno de chamada onCommitted disparar uma vez. Ele disparou para o documento principal, mas não disparou para nenhum dos frames estáticos do documento [1]. Portanto, nenhum script seria injetado neles.

No entanto, após o carregamento inicial, se eu fizesse um dos quadros 'navegar' em algum lugar, o retorno de chamada onCommitted seria chamado e os scripts seriam injetados no quadro no novo local.

Foi feita uma tentativa de usar a chave de opção all_frames para solucionar o problema acima. Embora o uso da chave fizesse com que os scripts fossem injetados nos quadros da página, havia a lacuna óbvia de não corresponder adequadamente a origem + caminho do quadro ao qual o script deveria ou não ser executado.

Como um aparte, também mencionei que usar a chave all_frames não injetaria scripts em quadros criados por Javascript.

[1] Se esse problema ainda está presente, eu não sei. Se bem me lembro, este problema não estava presente em FF 52 ESR, mas estava presente em 56 (57?) (Portanto, regressão). Talvez tenha sido consertado.

Eu concordo com você em quase todos os pontos.

E você está correto em que cada quadro é correspondido separadamente, como se fosse uma guia inteira (com seus próprios window e seus próprios document , embutidos em um quadro).

Bem, eu usei quase sempre a mesma estrutura de menu / frame, então talvez eu deva testar uma diferente.

Quando você diz "disparou", você se refere ao chamado puro do ouvinte?

Como eu disse, encontrei alguns exemplos com executeScript produzindo uma condição de erro, mas o listener ainda foi chamado.

all_frames não pode funcionar por causa do location errado ( window diferente, document ). BTW: O menu lida apenas com urls de mainframe de cada guia - se o menu estiver errado, isso não significa que o script não é chamado ...

Quando você diz "disparou", você se refere ao chamado puro do ouvinte?

Nessa mensagem em particular, eu quis dizer 'A função passada para onCommitted.addListener foi chamada.'.

Olá,

Eu li esta postagem com atenção, mas não entendo como usar sua solução alternativa em meu script local ".user.js". Como posso aplicar sua solução? Desculpe, sou novo.

(Desde a atualização do Firefox, um iframe pop-up gerado não é mais reconhecido pelo script adicional, mas se eu abrir o mesmo pop-up em uma nova janela, o script é aplicado.)

Agradeço antecipadamente por sua ajuda

Você descreveu exatamente qual é o problema: É como se @noframes estivesse ativado. O URL do conteúdo do quadro não ativa seu script corretamente. Espero que isso seja corrigido em breve (abrir frames em janelas extras é irritante) ...

Obrigado Eselce.
E sempre desde a atualização do Firefox, sou obrigado no cabeçalho a declarar todos os scipts '.js' (com require) já usados ​​no site de destino. (incluindo jquerry)
E não é a mesma coisa .... Isso cria bugs ou conflitos.
Você também conhece esse problema?

2945 contém outro exemplo para a observação, que os scripts são iniciados em quadros, mas abandonados após alguns milissegundos.

Hesito em fornecer os URLs específicos que estou testando, pois eles estão fora do meu controle, mas estou achando um comportamento consistente, mas estranho, para repassar.

Tenho um site com o qual preciso interagir. Inicialmente, ele carrega um conjunto de quadros / quadro com linhas = "100%, 0" (um quadro para preencher a tela) em um domínio diferente. Este quadro contém um conjunto de quadros / 3 quadros dentro do domínio do conjunto de quadros / quadro intermediário.

Alguns dos scripts GM dos quadros filhos 1 + 3 irão "aparecer" e desaparecer após o ciclo inicial - eles nunca mais voltarão após qualquer operação assíncrona. Isso se encaixa em algum comportamento descrito neste tópico. Observe que quais "blip" e o comportamento descrito abaixo variam de acordo com a versão do navegador / GM, mas não é aleatório; os padrões são estranhos, mas 100% repetíveis para qualquer configuração.

  1. O primeiro frameset / frame NUNCA aparecerá. Eu tentei desanexar e reconstruir a tag frame, tanto por meio de window.document quanto unsafeWindow.document, tanto no ciclo inicial quanto após um atraso, mas nada fará com que o script GM desse frame relate qualquer coisa para console.log. (O @include é *, sem @exclude ou outra filtragem de URL.)
  2. Alguns dos comportamentos posteriores serão diferentes entre o Firefox 52.8 / GM 4.1 e o Firefox 60.0 / GM 4.3, mas posso fazer com que os scripts GM dos frames em cada caso sejam "transferidos" para a existência, independentemente de @noframes estar definido ou não. Isso ocorre com @includes *, sem outros filtros de URL. Eles nunca devem aparecer com
  3. No Firefox 52.8 / GM 4.1, o próximo conjunto de quadros / 3 quadros SEMPRE aparecerá. No Firefox 60.0 / GM 4.3, eles não "blip" no carregamento inicial do frame.
  4. No Firefox 60.0 / GM 4.3, clicar em um link em um dos 3 frames que navega por outro dos 3 frames (por meio de um atributo "target" no link âncora, não no script) irá "blip" - não o novo URL, mas o URL antigo para o quadro navegado. (Este é um dos quadros que apareceu no carregamento inicial no item 3).
  5. Aqui está a parte mais estranha. Em ambas as configurações do navegador --- Seguindo as etapas, abrimos a página inicial com 2 camadas de conjuntos de quadros, 4 quadros no total e clicamos em um link em um quadro para navegar em um quadro diferente na mesma página. Para dar nomes a isso, nosso conjunto de quadros de segundo nível inicialmente exibido tinha os quadros "top.htm", "menu.htm" e "start, htm". Clicamos em um link no quadro "menu.htm" para fazer com que o quadro que segurava "start.htm" navegue até "content.htm", com comportamento semelhante, mas ligeiramente diferente por configuração do navegador, observado acima. Agora, clicamos em um link dentro do frame "content.htm", para navegar dentro do mesmo frame, mesmo domínio.

Neste ponto, o script para "content.htm" não apenas "blip" ... ele também permanecerá ativo após a conclusão de um GM.xmlHttpRequest - um evento assíncrono. Neste ponto, "content.htm" não está em nenhum lugar na tela do navegador, mas seu script continuará a operar.

Portanto, parece-me que o motivo pelo qual os scripts GM em páginas dentro de quadros não estão funcionando é porque o script está sendo carregado no descarregamento da página em vez de no carregamento da página. Definir @ run-at para início de documento e colocar o script em um evento DOMContentReady de unsafeWindow.document não teve melhorias. (Configurá-lo em window.document nunca dispara o evento.)

-Ryan

No Firefox 52.8 / GM 4.1, o próximo conjunto de quadros / 3 quadros SEMPRE aparecerá. No Firefox 60.0 / GM 4.3, eles não "blip" no carregamento inicial do frame.

Na transição para o Firefox 57, o Mozilla mudou _algo_. Fosse o que fosse, mudou (ou quebrou) a maneira como os Frames podiam ser acionados. Isso foi brevemente falado em alguma outra edição. Como resultado, os scripts não seriam executados no carregamento de quadro inicial (57+).

A eventual mudança para userScript ou contentScript APIs deve resolver tudo isso de qualquer maneira.

É o que as pessoas continuam dizendo, mas Violentmonkey continua a ser executado em frames. A VM não separa corretamente os scripts de usuário do conteúdo da página da web (os CSPs bloqueiam scripts de usuário, as páginas da web podem reescrever objetos globais etc.), ou eu teria descartado o Greasemonkey há muito tempo. Talvez sejam problemas relacionados, mas estou usando mecanismos de script de usuário, então não preciso explorar o cromo do Firefox a fundo o suficiente para descobrir sozinho.

Hmm, este é um problema difícil, alguns dos meus scripts não funcionam mais porque não funcionam com iframes. Então parece que não é realmente possível consertar, e temos que caminho para a Mozilla implementar alguma API? Não há nada que possamos fazer sozinhos, como uma solução alternativa? Eu só preciso fazer algumas coisas em uma página em um iframe, geralmente até do mesmo domínio.

Minha própria solução no momento é executar Greasemonkey nos quadros superiores e Violentmonkey nos quadros filhos. Não posso usar Tampermonkey porque tem uma licença caseira ambígua, mas se isso não for um problema para você, então pode ou não funcionar melhor.

Lembre-se de que a VM coloca o script no próprio contexto da página. É como a janela insegura da GM sem o equivalente seguro. Uma das vezes mais memoráveis ​​que tive foi depurar um script em que o conteúdo da página definiu um método 'toJSON () "em Array.prototype, fazendo com que JSON.stringify () cuspisse um JSON inválido dentro do meu script. Eu tive que prenda e conserte defensivamente como eu os encontrei.

Outra grande preocupação com a VM é que ela respeita a política de segurança de conteúdo da página de conteúdo, portanto, qualquer diretiva que limite as fontes de script fará com que o script da VM nunca seja executado. Você pode ver isso no console do navegador (mas não no console da web). É por isso que não consigo executar o VM inteiramente e simplesmente me livrar do GM. Ainda não encontrei uma empresa criança com um conjunto de CSP, mas quando o encontrar, ficará completamente inutilizável.

@RyanHanekamp Obrigado pela dica! Talvez eu use Violentmonkey para alguns scripts, então.

Violent também tem algo como GM_getValue síncrono? Esse é outro problema problemático que quebra uma tonelada de scripts no novo Greasemonkey. Eu ainda confio mais no Greasemonkey, por vários motivos, então não vou desistir.

Quanto aos iframes, tenho tentado substituí-los por tags de objeto, que aparentemente se pode acessar diretamente usando Javascript, como:

myObject= document.createElement('object');
myObject.setAttribute('id', 'myObject'); 
document.body.appendChild(myObject);
myObject.setAttribute('src', 'https://example.com');

Então, uma vez que o objeto é carregado:
document.querySelector('#myObject').contentDocument.defaultView.document.querySelectorAll('someElementInsideObjectPage')
Pelo menos isso funciona para mim em um script em que o objeto está no mesmo host da página principal. Você também pode enviar mensagens de e para ( ... contentDocument.defaultView.postMessage('hello, object') ) o objeto.

Não sou um especialista em VM, mas acredito que ela implemente pelo menos a maior parte da API GM_ * original. Eu acho que é melhor adaptar seus scripts para assíncronos do que voltar para uma plataforma síncrona no longo prazo. Pelo meu entendimento, Greasemonkey fez isso como um aumento de desempenho dentro da nova estrutura Quantum, que não permite chamadas síncronas entre scripts de fundo e de conteúdo.

Quanto à solução do objeto, não resolverá meu problema específico, mas fico feliz que outros a tenham achado útil. Além de empacotar CSS / propriedades / etc e fazer com que funcionem com frames e iframes, tenho que filtrar objetos em um processo de captura como potencialmente inseguros. Existem maneiras de contornar todos esses problemas, mas VM era o ínterim mais fácil até que a GM finalmente faça o que diz na lata.

Além disso, se você tiver um frame / iframe da mesma origem, também poderá acessar o conteúdo deles diretamente. A parte mais difícil é a origem cruzada, e é por isso que preciso de scripts de usuário dentro do quadro. Ele configura um canal window.postMessage () para responder à janela pai.

@RyanHanekamp É bom saber que Violent Monkey ainda tem o antigo e simples GM_ *. Eu realmente gostaria que o Greasemonkey tivesse mantido o antigo GM_getValue síncrono para compatibilidade com versões anteriores, além da nova versão. Posso tentar implementar a nova função assíncrona em um novo script, mas não sou um programador e não tenho certeza se conseguiria fazer isso funcionar. E certamente sou incapaz de refatorar o uso do antigo GM_getValue em um script antigo de 2.000 linhas que encontrei online ... tantos scripts estão corrompidos agora.

Eu entendo por que Violent foi a melhor opção para você. Vamos torcer para que Anthony, Sxderp ou outra pessoa descubra como implementar isso eventualmente. Eu realmente gostaria de poder contribuir, mas sou um leigo total.

Ah, você pode acessar diretamente o conteúdo de um iframe de mesma origem (sem postMessage etc.)? Lembro-me de passar muito tempo tentando encontrar um caminho, mas não parecia possível. É por isso que mudei para postMessage também.

Frames e iframes têm uma propriedade contentWindow que é equivalente à propriedade window. Ambos têm uma propriedade de documento para acessar o DOM.

A parte mais difícil de trabalhar com iframes (na mesma origem) é detectar quando seu conteúdo é carregado, porque você não pode fazer agachamento até que isso aconteça. onload não funciona como parece. O Firefox fornece um evento DOMFrameContentLoaded que dispara para CADA quadro carregado, incluindo quadros de neto / bisneto etc., que você pode combinar com o elemento quadro / iframe original com a propriedade event.target. Se você controlar o conteúdo do frame / iframe, também poderá fazer com que ele responda ao pai com postMessage ou chamando um método global no objeto window.parent.

Falando nisso ... essa é uma solução alternativa para esse problema. Se houver ou puder haver uma maneira de codificar um script GM para injetar manualmente um script de usuário em uma referência de janela de domínio cruzado, seria necessário muito mais codificação para o criador de script de usuário, mas poderia dar conta do recado. O padrão seria ouvir DOMFrameContentLoaded, verificar se o event.target é de primeira geração e, se for o caso, injetar manualmente o script. (Presumindo que o script do frame de primeira geração pode ouvir DOMContentLoaded para frames de segunda geração e, assim, obter uma cadeia completa.) Não haveria como obter o comportamento @ run-at dom-start e também pode haver problemas de tempo, mas provavelmente poderíamos contorná-los para a maioria dos casos de uso.

Eu pessoalmente desisti de que esse problema fosse resolvido e, em vez disso, passei a codificar diretamente uma extensão. Que funciona bem em todos os quadros!

A diferença entre Greasemonkey e Violentmonkey neste ponto parece ser que Violentmonkey está sendo acionado a partir de scripts de conteúdo com all_frames definido como verdadeiro, enquanto Greasemonkey não tem scripts de conteúdo de tempo de instalação e depende inteiramente da capacidade duvidosa do script de fundo para farejar quando um o quadro da guia navegou. (E Violentmonkey falha nas páginas CSP porque injeta temporariamente uma tag SCRIPT em vez de usar o tabs.executeScript () muito mais seguro.)

Coloque em um script de conteúdo estático com all_frames, run_at start, corresponde a tudo para notificar o processo em segundo plano para start / document.DOMContentLoaded / document.Idle para acionar scripts de usuário para cada run_at, e você está pronto para começar. Uma quantidade de trabalho não trivial, mas administrável, para resolver o problema. Eu mesmo consertaria, mas não tenho interesse em vasculhar suas dependências de desenvolvimento e só poderia produzir o código de saída.

@RyanHanekamp

e, em vez disso, passaram a codificar diretamente uma extensão. Que funciona bem em todos os quadros!

Você gostaria de compartilhar esse seu código de extensão?

Minha extensão não é de uso geral. O ponto é que usando um content_script estático no manifesto com all_urls, all_frames executará o script sempre que qualquer frame for carregado ou navegado, e pode até mesmo avaliar / código do construtor de função bem, independentemente da Política de Segurança de Conteúdo da página.

Não testei com quadros / janelas construídos programaticamente, mas imagino que eles seriam executados na criação inicial, independentemente da configuração run_at, porque esses quadros são inicialmente criados em branco e depois preenchidos - o mecanismo provavelmente veria apenas a criação inicial. Eu também não testei data: urls, que pode exigir correspondência explícita - não tenho certeza se all_urls os cobre ou apenas http / https.

Pode não ser uma referência estática a content_script, mas parece incerto na documentação se os scripts de conteúdo invocados dinamicamente carregam automaticamente quando a página é navegada. Minha impressão é que eles são injetados apenas em guias / frames correspondentes no momento, de acordo com o padrão de correspondência fornecido, e a navegação não aciona uma reinjeção. Mas não vejo nenhuma desvantagem em usar um content_script estático para esse propósito.

Obviamente, o Greasemonkey não pode incluir scripts de usuário como recursos estáticos no manifesto, e os scripts de conteúdo não parecem ter acesso direto a tabs.executeScript (embora eu dificilmente seja um especialista nisso, pois estou apenas alguns dias depois), mas o que um script de conteúdo estático PODE fazer é enviar uma mensagem ao processo em segundo plano para informá-lo de que o frameId foi navegado e para qual URL. Isso seria mais confiável do que como eu percebo as tentativas mencionadas neste tópico de conectar o evento certo em webRequest ou webNavigation. O sinal do content_script estático se torna o evento que estamos procurando para acionar o carregador / injetor de userscript do Greasemonkey.

Possivelmente, haveria um atraso para os scripts de usuário que DEVEM executar estritamente em document_start. A chamada para o script de segundo plano é assíncrona e o documento terá progredido no momento em que o script de usuário for invocado. É bem possível que seja por isso que Violentmonkey usa uma tag de script temporária em vez de tabs.executeScript, já que a injeção da tag de script pode ser feita diretamente do content_script, de forma síncrona. Eu acharia problemático ser forçado a contornar a incerteza do estado do documento para run_at document_start, mas é preferível que o script não execute nada.

Greasemonkey ... PODE [usar um script de conteúdo estático para] enviar uma mensagem ao processo em segundo plano para que ele saiba que o frameId foi navegado e para qual URL ...

Isso é o que costumávamos fazer para detectar .user.js navegações. Parece uma solução óbvia e boa: detecte o conteúdo executando um script de conteúdo!

Mas acontece que até mesmo os scripts de conteúdo de extensão podem ser corrompidos por CSP (# 2631 e http://bugzil.la/1267027 e http://bugzil.la/1411641).

Posso executar meu próprio plug-in, incluindo um construtor Function () diretamente de content_script, no Firefox 60.0.1 e 52.8.1ESR com o seguinte conjunto CSP:

dados frame-src :; object-src 'nenhum'; script-src 'nenhum'; style-src 'dados não seguros em linha' :; conectar-src 'nenhum'; media-src 'nenhum';

2631 foi fechado, aparentemente porque o Firefox corrigiu seu bug subjacente. O primeiro bugzilla é uma referência à injeção de tags de script (o método Violentmonkey), não o próprio content_script. O segundo é em referência ao atributo sandbox para CSP, o que não é surpreendente porque força o domínio a nunca concluir com êxito uma correspondência de domínio, mesmo para si mesmo. Mais ou menos como NaN! == NaN.

Quando isso foi apresentado pela primeira vez, há vários meses, fizemos as coisas de maneira diferente. Hoje usamos webNavigation.onCommitted para detectar a navegação e, no teste que estou executando agora, por algum motivo não estou vendo ele disparar em um quadro (ni)).

Olá, isso está resolvido agora?

Não consegui que um script que criei para Tampermonkey fosse iniciado em um iframe com Greasemonkey.

O código para execução não foi alterado do nosso lado. Portanto, a menos que a Mozilla tenha mudado alguma coisa, isso ainda está quebrado. No entanto, # 2663 deve resolver isso.

Pode ser interessante notar que Violentmonkey e Tampermonkey funcionam bem dentro de frames incorporados.

Tampermonkey tem problemas com iframes no Chrome, pelo menos para mim.

Pode ser interessante notar que Violentmonkey e Tampermonkey funcionam bem dentro de frames incorporados.

Tampermonkey tem problemas com iframes no Chrome, pelo menos para mim.

Mas funciona para mim no Firefox Violentmonkey. Então eu me pergunto como isso pode funcionar lá?

Acabei de notar que um script usando a sincronização antiga GM_GetValue ainda funciona bem no Violentmonkey também. Como isso é possível? Achei que o Firefox havia forçado GM.GetValue assíncrono? Estou tão confuso agora: presumivelmente, o Violentmonkey teve que sacrificar algo mais para ainda suportar a sincronização e outras coisas?

@ Cerberus-tm A mudança no Firefox significa que os dados só podem ser solicitados do armazenamento de extensão ou do contexto de fundo de forma assíncrona (os próprios scripts de usuário são enviados para o script de conteúdo de forma assíncrona). No entanto, os dados podem ser fornecidos aos scripts de usuário de forma síncrona, se cada script de conteúdo GM4 for previamente buscado e armazenado em cache no script de conteúdo os dados armazenados para cada script de usuário sendo carregado nessa página.

Esse cache permitiria que o script de conteúdo respondesse de forma síncrona às solicitações de dados do usercript. A implementação de um cache apresenta problemas com a manutenção da consistência entre os vários scripts de conteúdo, mas isso pode ser resolvido fazendo com que os scripts de conteúdo escutem todas as alterações no armazenamento de extensão do GM4. Além disso, se um script de usuário estiver armazenando uma grande quantidade de dados, armazená-lo em cache em cada script de conteúdo em que o script de usuário é executado também aumenta significativamente a memória necessária para cada script de conteúdo.

TM e VM escolheram fazer algo semelhante ao acima para não quebrar a compatibilidade com as APIs Greasemonkey originais quando esses gerenciadores de script de usuário foram implementados para o Chrome, que tem as mesmas restrições escritas. comunicação assíncrona com armazenamento de extensão, etc. Dado que eles já estão fazendo isso para o Chrome, não houve razão para que mudassem quando implementados para Firefox.

Assim, o FF57 cut-over para WebExtensions fez forçar uma reescrita da GM, mas não forçar a adoção das APIs assíncronas para GM.getValue , GM.setValue , etc. WebExtensions fez o uso de APIs assíncronas mais fáceis de implementar do que as síncronas seriam, mas isso não o tornava obrigatório.

Pessoalmente, acho que a escolha e outras escolhas para quebrar a compatibilidade foram / são infelizes. A falta de compatibilidade com versões anteriores de scripts que funcionam bem no GM3 e / ou compatibilidade com o TM resulta em muitas pessoas optando por não usar o GM4. Minha experiência é que bem mais de 30 dos scripts de usuário que uso, todos os quais funcionaram bem no GM3, não funcionam com o GM4 (ou pelo menos não funcionaram antes de serem reescritos para serem compatíveis com o GM4). Ainda há 28 scripts de usuário que uso diariamente que funcionam bem no GM3, mas não funcionam com o GM4.

Publiquei uma solução alternativa para esse problema no Stack Overflow como uma resposta a como Aplicar um Greasemonkey / ‌Tampermonkey / ‌userscript a um iframe . Basicamente, estou esperando o quadro carregar e, em seguida, estou operando na matriz window.frames . Eu uso um marcador personalizado no corpo de cada quadro para indicar que já vi o quadro.

Talvez o Greasemonkey pudesse implementar uma solução de maneira semelhante?

Seria incrível se também tivéssemos um GM.waitFor(css_selector, action_function) como waitForKeyElements () , mas isso é um aparte.

Esta página foi útil?
0 / 5 - 0 avaliações