PT-BR/Tutorial CEF
Esta página possui uma breve introdução ao CEF.
O que é CEF?
CEF é um acrônimo para Chromium Embedded Framework. Consiste em um framework para embutir navegadores baseados no Chromium em outras aplicações, neste caso, o MTA. CEF é construido a partir do projeto Chromium mantido pela Google, este por sua vez consiste em um motor web rápido, estável e seguro. É possível encontrar mais informações sobre o CEF em sua página do GoogleCode: https://bitbucket.org/chromiumembedded/cef
Conceitos Básicos
Criar uma nova instância do navegador é bem simples. Segue o exemplo para abrir a página do Youtube:
-- Criar um novo navegador remoto (seu tamanho é 800x600px), com transparência habilitada local browser = createBrowser(800, 600, true, true) -- Aguardar pelo navegador (isso é necessário porque o CEF roda em uma thread separada, portanto é necessário adotar o sistema de eventos assíncronos) addEventHandler("onClientBrowserCreated", browser, function() -- Agora é possível carregar a URL (o "source" desse evento é o navegador que foi criado) loadBrowserURL(source, "https://youtube.com/") end )
Este exemplo não requer solicitação de domínio já que o Youtube está na lista de domínios autorizados do MTA.
Sistema de Requisição de Domínios
De modo a prevenir abuso quanto as possibilidades que o CEF oferece, decidiu-se introduzir um sistema de controle. Isso significa que domínios desconhecidos não serão carregados automaticamente caso não cumprir com pelo menos uma das exigências a seguir:
- estar incluso na lista mantida pelo time de desenvolvimento do MTA
- ser autorizado pelo usuário após a chamada via script da função
requestBrowserDomains/Browser.requestDomains
- estar incluso na lista de domínios permitidos do usuário, esta disponível em: Configurações do MTA → Aba: Navegador → Whitelist
Alguns domínios são conhecidos por conter conteúdo malicioso, portanto há uma chance desse estar na lista proibida - esta gerenciada automaticamente pelo MTA. Neste caso, nenhuma das alternativas citadas acima funcionará, portanto, todas as solicitações a ele serão negadas. Não há nada que o usuário ou o desenvolvedor possa fazer. Caso haja algum engano, é sugerido contatar nosso time de suporte.
Modo remoto versus local
Existem dois modos que o CEF pode rodar:
1. Modo local:
- é possível executar código em Javascript sem restrição (vide: executeBrowserJavascript)
- é possível carregar sítios hospedados somente na pasta
resource
- não é permitido carregar conteúdo remoto (e.g. www.mtasa.com)
2. Modo remoto:
- não é permitido executar código em Javascript
- é permitido carregar somente conteúdo remoto
- lembre-se que o usuário pode desabilitar o carregamento de websites remotos ou a execução de Javascript nas configurações
Vale ressaltar que não é possível mudar o modo do navegador após sua criação devido a limitações técnicas.
Gerenciamento de Recursos
Como carregar arquivos HTML locais
Carregar um arquivo HTML local funciona de forma similar a carregar imagens.
Adicione o caminho para o arquivo HTML no meta.xml
usando a seguinte tag:
<file src="html/minhaInterface.html"/>
Como carregar arquivos locais dentro do HTML
Suponha que seja necessário carregar uma imagem ou reproduzir um vídeo que foi incluso no seu pacote do MTA. Isso é possível através de um URI específico no formato: "http://mta/"
Exemplo
Este exemplo mostra como reproduzir um vídeo. Note que é necessário habilitar programação orientada a objeto.
Lua
-- Cria um navegador (modo local também é obrigatório para acessar arquivos locais) local janelaNavegador = Browser(640, 480, true, true) addEventHandler("onClientBrowserCreated", janelaNavegador, function() -- Carregar interface em HTML janelaNavegador:loadURL("http://mta/local/html/meuVideo.html") end )
meta.xml
<file src="html/meuVideo.html"/> <file src="midia/meuVideo.webm"/>
HTML
<!DOCTYPE HTML> <html> <head></head> <body> <video width="640" height="480" controls> <!-- todo arquivo local deve ter o prefixo http://mta/local --> <source src="http://mta/local/midia/meuVideo.webm" type="video/webm"/> </video> </body> </html>
Comunicação bidirecional entre Lua e JS
A comunicação entre Lua e Javascript (JS) está somente disponível no modo local devido à razões de segurança.
Lua para JS
É possível chamar código em Javascript a partir do Lua usando a função executeBrowserJavascript.
Os links a seguir contém mais detalhes de como isso é implementado:
- https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/src/WebWindow.lua#L180-189
- https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/src/mtaevents.js#L9-L15
JS para Lua
É possível adicionar um evento-cliente no Javascript usando a função triggerEvent a qual é parte da classe estática mta. Segue a sintaxe:
mta.triggerEvent(string evento, var parametro1, var parametro2, var parametro3, ...)
A fonte (variável "source") desse evento é sempre o elemento navegador que acionou este evento.
Estão disponíveis exemplos nos seguintes links:
- https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/examples/html/ui2.html#L66
- https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/examples/Main.lua#L35-L40
Depuração
O modo desenvolvedor pode ser habilitado da seguinte forma (digite no console após pressionar F8):
start runcode crun setDevelopmentMode(true, true) debugscript 3
Agora é possível visualizar os erros no navegador e os domínios/URLs bloqueados na janela de depuração no canto inferior da tela.
Pontos de atenção
Importante lembrar que nem todas os recursos de um navegador recente estão disponíveis nos computadores de seus usuários. Um exemplo disso é o WebGL.
Adobe Flash também é um recurso problemático. É um complemento habilitado por padrão, porém deve ser evitado porque é possível desabilita-lo nas configurações. Além disso, o Flash, por ser uma tecnologia defasada, não oferece muitas oportunidades para o desenvolvimento de funcionalidades que atendam às expectativas do usuário. Mais especificamente, o flash roda em um processo separado que está limitado a uma interface antiga (aquele dos anos 2010), o qual o desenvolvedor possui pouco controle sob ela. A alternativa recomendada é o HTML5, porque além de ser amplamente adotada, possui uma ótima API para reprodução de áudio/vídeo (http://www.w3schools.com/tags/ref_av_dom.asp). Até mesmo há suporte a áudio 3D.
Uso Avançado
Como a implementação do CEF não contempla o z-ordering por padrão, é necessária uma implementação própria. A especificação sobre esse mecanismo pode ser encontrada em: https://github.com/Jusonex/mtasa_cef_tools Há também algumas funções auxiliares para integrar essas classes facilmente com sua própria interface usando OOP. Será também criado um tutorial de como usar o CEF com o CEGUI.
Desempenho
Criar várias instâncias de navegador não afeta o MTA diretamente porque o CEF roda em um processo distinto. Porém, devido a limitações técnicas, o MTA necessita de uma cópia dos dados de texturas na thread principal do GTA.
Caso não seja necessário manter o navegador visível, é recomendado encerra-lo para economizar recursos. Porém, caso ainda seja importante deixar o navegador rodando (e.g. manter o estado da página), é possível otimizar o desempenho desabilitando a renderização da página via setBrowserRenderingPaused. Isso faz com que o CEF pare de atualizar novos quadros e o MTA também irá pausar a cópia de textura.
Solução de Problemas
google.com não funciona
Por padrão, ao acessar o endereço google.com
, o usuário é redirecionado para um site filial específico dependendo do país em que está. No Brasil, por exemplo, o internauta é transferido para o google.com.br
. É possível contornar esse problema ao acessar o seguinte endereço: https://www.google.com/ncr.
Funções de Scripting
- canBrowserNavigateBack
- canBrowserNavigateForward
- createBrowser
- executeBrowserJavascript
- focusBrowser
- getBrowserProperty
- getBrowserSettings
- getBrowserSource
- getBrowserTitle
- getBrowserURL
- injectBrowserMouseDown
- injectBrowserMouseMove
- injectBrowserMouseUp
- injectBrowserMouseWheel
- isBrowserDomainBlocked
- isBrowserFocused
- isBrowserLoading
- isBrowserRenderingPaused
- loadBrowserURL
- navigateBrowserBack
- navigateBrowserForward
- reloadBrowserPage
- requestBrowserDomains
- resizeBrowser
- setBrowserAjaxHandler
- setBrowserProperty
- setBrowserRenderingPaused
- setBrowserVolume
- toggleBrowserDevTools