webbrowser — u_pbt_webbrowser #
← Referência dos componentes · Índice do guia
Navegador web integrado na janela: apresentação de uma página, barra de endereço, histórico Anterior / Seguinte, menu de contexto de navegação.
▶ Ver ao vivo — Aplicação de demonstração, mosaico Web browser: a pré-visualização, o código que o produz e esta página, lado a lado.
Em resumo #
| Userobject | u_pbt_webbrowser |
| Classe de items | — (componente sem items) |
| Serve para | Apresentar uma página web, um portal interno, documentação em linha ou conteúdo HTML gerado, sem sair da aplicação |
Início rápido #
// event open da janela
uo_browser.ib_address_bar = true // barra de endereco + botoes de navegacao
uo_browser.is_address = "https://pt.wikipedia.org/wiki/PowerBuilder"
Atribuir is_address é o ato de navegação: cada atribuição abre a página pedida. Um endereço sem protocolo ("exemplo.com") recebe automaticamente https://. Um caminho de disco (C:\pasta\pagina.html, \\servidor\partilha\pagina.html) torna-se um endereço file:///. Palavras que não são um endereço ("fatura 2026") vão para o motor de pesquisa de is_search_url; sem motor, são recusadas e ue_error indica-o. Um nome de servidor de uma só palavra seguido de /, ? ou # (office/, intranet/inicio) é um endereço, tal como um endereço IPv6 entre parênteses retos ([::1]/x); a palavra sozinha (intranet) continua a ser texto livre. Um servidor sem HTTPS escreve-se com http:// explícito.
Propriedades #
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
is_address | string | "" | Endereço apresentado. Atribuir esta propriedade inicia a navegação. Relê-la devolve a página realmente apresentada: se o utilizador seguir uma ligação ou recuar, ela acompanha (ue_load_completed avisa-o). Esquemas aceites: http(s):, file: (também um caminho de disco), about:, data:, mailto:, tel:; javascript: é recusado |
ib_address_bar | boolean | false | Apresenta a barra de endereço integrada: campo URL, botões Anterior / Seguinte / Recarregar |
ib_context_menu | boolean | false | Ativa o menu de contexto no clique direito: Anterior, Seguinte, Recarregar, mais Copiar sobre uma seleção, Abrir link e Copiar endereço do link sobre um link, Copiar imagem sobre uma imagem. Aberto pelo teclado (Shift+F10), aparece sobre o elemento. Num campo de entrada mantém-se o menu Cortar / Copiar / Colar |
is_search_url | string | "" | Motor de pesquisa para palavras que não são um endereço, %s = o texto codificado (ex. https://www.bing.com/search?q=%s). Vazio por omissão: esse texto é recusado e ue_error é acionado — uma aplicação de gestão não envia o que os utilizadores escrevem a um motor que não escolheu. Só é aceite um endereço http(s) que contenha %s: qualquer outro lança ue_error e o motor em vigor mantém-se |
ib_veto_new_window | boolean | false | Pergunta a ue_new_window antes de abrir uma nova janela na vista; devolver false mantém a página atual |
ib_veto_downloads | boolean | false | Pergunta a ue_download_starting antes de cada transferência; devolver false cancela-a |
ib_veto_navigation | boolean | false | Pergunta a ue_navigating antes de o site passar para outra página (link, formulário, script); devolver false mantém a página atual. Uma página autorizada é reaberta no endereço pedido: um formulário enviado por POST perde os seus dados |
ib_private | boolean | false | Navegação privada: cookies, armazenamento e cache dos sites nunca são escritos no disco e desaparecem com a vista. Deve ser definida antes de is_address: alterá-la reabre a vista vazia (sem página nem histórico); voltar a pô-la a true abre uma sessão privada nova |
is_title | string | "" | Título da página apresentada, lido em direto (ue_title_changed avisa quando muda). Só de leitura: escrevê-lo não altera nada |
is_theme_style | string | "" | Estilo visual do componente (constantes THEME_STYLE_*); vazio = o da aplicação, seguido a cada mudança |
is_theme_mode | string | "" | Variante clara ou escura (constantes THEME_MODE_*); vazio = a da aplicação, seguida a cada mudança |
il_theme_accent | long | -1 | Cor de destaque deste componente (-1 = destaque da aplicação, ou o do tema) |
Métodos #
| Método | Função |
|---|---|
of_refresh ( ) | Recarrega a página atual. Devolve 0 uma vez pedido, -4 se nenhuma página estiver apresentada (is_address vazio), -2 se o componente não estiver criado |
of_go_back ( ) | Volta à página anterior. Segue a ordem do seu código: is_address e depois of_go_back() são executados por essa ordem |
of_go_forward ( ) | Avança para a página seguinte |
of_can_go_back ( ) → boolean | true se existir uma página anterior — para ativar ou inativar o botão Anterior. Lido em direto na página; leia-o após um carregamento (ue_load_completed) |
of_can_go_forward ( ) → boolean | true se existir uma página seguinte |
of_stop ( ) | Interrompe o carregamento em curso e abandona as páginas ainda em espera; o carregamento interrompido aciona ue_load_failed |
of_execute_javascript (string as_script) | Executa um script na página apresentada e devolve o seu valor em JSON: um texto volta entre aspas, um número não (42), um script que lança um erro ou não devolve nada dá null. Uma resposta longa volta inteira. Uma só condição, e é estrutural: a página tem de estar carregada, portanto chame-a a partir de ue_load_completed, nunca logo após definir is_address. Devolve uma cadeia vazia se ainda não houver página ou sem resposta em 5 segundos: of_get_last_error() diz porquê |
of_show_html (string as_html) → long | Apresenta uma página construída pela aplicação (uma fatura, uma carta). A página é codificada: uma cor #c00, uma âncora, um % ou um acento aparecem tal como escritos. No máximo 2 MB depois de codificada: acima disso, ue_error e nada muda. Devolve 0 uma vez enviado, -2 se o componente não estiver criado |
of_clear_browsing_data ( ) → long | Apaga o que os sites guardaram: cookies (uma sessão iniciada), armazenamento local, cache, permissões concedidas. A limpeza ocupa o seu lugar depois dos endereços já definidos: a página seguinte abre-se limpa. Todos os webbrowser da aplicação partilham estes dados. Devolve 0 uma vez enviado, -2 se o componente não estiver criado |
of_reset ( ) | Repõe o componente: página esvaziada, histórico de navegação apagado, barra de endereço oculta, menu de contexto desativado, motor de pesquisa esvaziado, perguntas (ib_veto_*) desativadas, navegação privada desligada. Os cookies e sessões dos sites mantêm-se: para isso existe of_clear_browsing_data. Devolve 0 uma vez aplicado, -2 se o componente não estiver criado |
of_save_as_png (string) · of_save_as_jpg (string) | Exporta o site apresentado como imagem. Devolve 0 depois de a imagem ser escrita, -4 se a escrita falhar, -2 se o componente não estiver criado |
Eventos #
| Evento | Acionado quando |
|---|---|
ue_load_completed (string as_url) | Uma página terminou de carregar (a sua, uma ligação, Anterior, of_refresh); as_url é o endereço efetivamente atingido, redirecionamentos incluídos. Não acionado para um endereço vazio (about:blank) nem para um carregamento falhado |
ue_load_failed (string as_url, long al_status) | Uma página não pôde ser carregada: anfitrião desconhecido, sem rede, certificado, ou carregamento cancelado por of_stop ou por um endereço mais recente. al_status indica o motivo: ver Porque é que uma página não carregou |
ue_error (string as_message) | Um texto definido em is_address (ou escrito na barra) não é um endereço e não há is_search_url, um endereço não pôde de todo ser aberto, ou o processo da página parou. Nada mais fica retido: o endereço seguinte carrega normalmente |
ue_new_window (string as_url) → boolean | A página pede uma nova janela após um clique (ligação target=_blank, window.open): abre-se nesta vista. Cancelável se ib_veto_new_window = true: devolver false mantém a página atual. Uma janela aberta só por um script, sem clique, é ignorada. Só se abrem endereços http e https: um site que peça um ficheiro, uma página data: ou um link de correio recebe ue_error. Uma ligação file: numa página web (http, https, data:) é recusada pelo próprio motor, antes do componente: nada se abre e nenhum evento é lançado |
ue_download_starting (string as_url, string as_path) → boolean | Uma transferência está a começar: as_url é o que é transferido, as_path o ficheiro que será escrito. Cancelável se ib_veto_downloads = true: devolver false cancela-a; caso contrário continua como no Edge |
ue_navigating (string as_url) → boolean | O site passa para outra página: um link, um formulário, um script — nunca um endereço definido pela aplicação. Cancelável se ib_veto_navigation = true: devolver false mantém a página atual |
ue_title_changed (string as_title) | O título da página apresentada mudou (is_title volta a lê-lo a qualquer momento) |
ue_permission_requested (string as_url, string as_kind) → boolean | O site pede a câmara, o microfone, a localização… (as_kind = uma constante PERMISSION_*). Recusado a menos que o event devolva true: a única pergunta da biblioteca em que o silêncio vale NÃO |
ue_ready ( ) | O componente terminou o carregamento; tudo o que foi enviado antes foi reproduzido |
ue_runtime_missing ( ) | O runtime WebView2 está ausente: o componente permanece vazio |
ue_bg_color (long al_color) | O componente calculou a cor de fundo do respetivo tema; o userobject já a adotou (backcolor) |
ue_script_error (string as_message, string as_stack) | Ocorreu um erro de JavaScript na barra de endereço do componente (nunca no site apresentado) |
Navegar #
A barra de endereço integrada #
É a solução mais rápida: uma propriedade e o utilizador dispõe de um campo URL e dos botões Anterior / Seguinte / Recarregar, com o tema do resto da aplicação.
// A barra de enderecos, depois a pagina a abrir
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://pt.wikipedia.org/wiki/PowerBuilder"
Os botões ficam inativos automaticamente quando não há para onde ir. No campo de endereço, F5 (ou Ctrl+R) recarrega, Alt+← / Alt+→ recuam e avançam (invertidos na escrita da direita para a esquerda), Esc repõe o endereço atual depois de uma escrita abandonada, e o primeiro clique seleciona todo o endereço.
Botões próprios #
Se preferir comandar a navegação a partir de uma barra de ferramentas própria, deve ocultar-se a barra integrada e utilizar os métodos:
// Botoes Anterior / Seguinte da sua janela
uo_browser.of_go_back()
uo_browser.of_go_forward()
// event ue_load_completed de uo_browser : (string as_url)
// Atualizar o estado dos seus botoes apos cada pagina
uo_toolbar.of_item(/*keys*/ "main/back").ib_enabled = uo_browser.of_can_go_back()
uo_toolbar.of_item(/*keys*/ "main/forward").ib_enabled = uo_browser.of_can_go_forward()
// E refletir o endereco real (incluindo redirecionamentos)
sle_url.text = as_url
O menu de contexto de navegação #
ib_context_menu acrescenta ao clique direito um pequeno menu Anterior / Seguinte / Recarregar, com tema e desenhado pela aplicação. Segue o que está sob o rato: Copiar sobre um texto selecionado, Abrir link e Copiar endereço do link sobre um link, Copiar imagem sobre uma imagem. Aberto pelo teclado (Shift+F10, tecla Menu), aparece sobre o elemento. Partilha exatamente o mesmo histórico que a barra de endereço: ambos permanecem, por isso, sempre coerentes.
// A small menu on a right click : back, forward, refresh
uo_browser.ib_context_menu = true
Parar um carregamento #
// Botao Parar : interrompe uma pagina que demora
uo_browser.of_stop()
Palavras em vez de um endereço #
Por omissão, um texto que não é um endereço é recusado (ue_error), sem reter nada: o endereço seguinte carrega normalmente. Para o transformar numa pesquisa, escolha o motor:
// Words typed in the address bar go to this engine (%s = the text)
uo_browser.is_search_url = "https://www.bing.com/search?q=%s"
uo_browser.is_address = "PowerBuilder WebView2"
Novas janelas e transferências #
Uma ligação «abrir num novo separador» ou uma janela de início de sessão aberta após um clique aparece na vista, e ue_new_window indica-o. Uma transferência continua como no Edge, e ue_download_starting dá-lhe o endereço e o ficheiro. Ambos se tornam uma pergunta quando o pede:
// Ask before each download
uo_browser.ib_veto_downloads = true
// ue_download_starting event of uo_browser : (string as_url, string as_path)
// Only PDF files may be downloaded
return Lower(Right(as_path, 4)) = ".pdf"
Ficar nos seus próprios servidores #
ue_navigating é lançado sempre que o site passa para outra página — um link, um formulário, um script —, nunca para um endereço definido pelo seu código. Com ib_veto_navigation é uma pergunta: devolver false mantém a página atual. Uma página autorizada é reaberta no endereço pedido pelo site; um formulário enviado por POST perde os seus dados.
// Ask before the site leaves for another page
uo_browser.ib_veto_navigation = true
// ue_navigating event of uo_browser : (string as_url)
// Only the company servers may be opened
return Pos(Lower(as_url), "://intranet.example.com/") > 0
Câmara, microfone, localização #
Quando um site pede a câmara, o microfone, a localização, as notificações ou a leitura da área de transferência, é ue_permission_requested que decide, e a resposta por omissão é não: um site não liga uma câmara através de um aviso que o utilizador não compreende. É a única pergunta da biblioteca em que o silêncio vale recusa. Nada é memorizado: a pergunta volta a cada pedido.
// ue_permission_requested event of uo_browser : (string as_url, string as_kind)
// The video-call page of the company may use the camera and the microphone
if Pos(Lower(as_url), "://visio.example.com/") = 0 then return false
return as_kind = uo_browser.PERMISSION_CAMERA or as_kind = uo_browser.PERMISSION_MICROPHONE
Valores de as_kind: PERMISSION_CAMERA, PERMISSION_MICROPHONE, PERMISSION_GEOLOCATION, PERMISSION_NOTIFICATIONS, PERMISSION_CLIPBOARD, PERMISSION_SENSORS, PERMISSION_DOWNLOADS (várias transferências seguidas), PERMISSION_FILES, PERMISSION_AUTOPLAY, PERMISSION_FONTS, PERMISSION_MIDI, PERMISSION_WINDOWS, PERMISSION_UNKNOWN.
Porque é que uma página não carregou #
al_status de ue_load_failed compara-se com as constantes LOADSTATUS_* do componente:
| Constante | Significa |
|---|---|
LOADSTATUS_HOST_NOT_RESOLVED | Anfitrião desconhecido (nome mal escrito, DNS) |
LOADSTATUS_DISCONNECTED · LOADSTATUS_CANNOT_CONNECT · LOADSTATUS_SERVER_UNREACHABLE | Sem rede, servidor inacessível |
LOADSTATUS_TIMEOUT | O servidor não respondeu a tempo |
LOADSTATUS_CERT_INVALID · LOADSTATUS_CERT_EXPIRED · LOADSTATUS_CERT_NAME_INCORRECT · LOADSTATUS_CERT_REVOKED · LOADSTATUS_CLIENT_CERT_ERROR | Certificado recusado |
LOADSTATUS_CANCELED | Carregamento cancelado por of_stop ou por um endereço mais recente |
LOADSTATUS_AUTH_REQUIRED · LOADSTATUS_PROXY_AUTH_REQUIRED | Credenciais pedidas (servidor, proxy) |
LOADSTATUS_CONNECTION_ABORTED · LOADSTATUS_CONNECTION_RESET · LOADSTATUS_INVALID_RESPONSE · LOADSTATUS_REDIRECT_FAILED · LOADSTATUS_UNEXPECTED_ERROR · LOADSTATUS_UNKNOWN | Outras falhas de ligação ou de resposta |
// ue_load_failed event of uo_browser : (string as_url, long al_status)
if al_status = uo_browser.LOADSTATUS_HOST_NOT_RESOLVED then
st_message.text = "Unknown address : " + as_url
end if
Executar um script na página #
of_execute_javascript lê ou altera a página apresentada (o título, um campo, um contador). Não é limitado pela licença, mesmo numa página about:blank ou data:: executar um script na página é o trabalho de um navegador, e o componente é gratuito.
// ue_load_completed event of uo_browser : (string as_url)
// The page title, as JSON : "PowerBuilder - Wikipedia" (quotes included)
sle_title.text = uo_browser.of_execute_javascript(/*script*/ "document.title")
Sites que recusam a apresentação integrada #
Alguns sites — Google, a maioria dos bancos, muitas aplicações SaaS — enviam cabeçalhos de segurança que proíbem a sua apresentação dentro de outra página. O componente não é afetado: nunca apresenta um site numa moldura. A página é aberta como documento principal, exatamente como faz o seu próprio navegador, e esses cabeçalhos deixam de se aplicar.
Não há, portanto, nada a definir nem qualquer caso particular a tratar no seu código.
// Um site que recusa ser integrado numa pagina : nada de especial a fazer
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://www.google.com"
Em contrapartida, a página ocupa toda a superfície do componente sob a barra de endereço: aquilo que desenhasse por cima (faixas, sobreposições com tema) não é visível durante a navegação.
Conteúdo HTML sem rede #
of_show_html apresenta uma página HTML construída pela aplicação: a pré-visualização de uma carta, de um ticket, de uma fatura ou de um relatório, sem qualquer chamada de rede nem ficheiro temporário. A página é codificada por si: uma cor #c00, uma âncora, um % ou um acento aparecem tal como escritos (no máximo 2 MB).
// Local variables
string ls_html
// An order summary built by the application : the colour and the "%" come out as written
ls_html = "<html><body>" &
+ "<h1 style='color:#1f6feb'>Order #4152</h1>" &
+ "<p>Discount : 10%</p>" &
+ "</body></html>"
uo_browser.of_show_html(/*html*/ ls_html)
Definido diretamente em is_address, um endereço data:text/html, não é codificado: um # corta ali a página (tudo o que se segue passa por uma âncora) e um % baralha-a. Prefira of_show_html, ou codifique por si (# → %23, % → %25).
Um ficheiro local abre-se da mesma forma com file:///C:/temp/relatorio.html, ou simplesmente com o seu caminho C:\temp\relatorio.html.
Recomeçar do zero #
of_reset() não se limita a esvaziar a página: apaga também o histórico de navegação. Assim, um utilizador não pode regressar, através do botão Anterior, a uma página consultada pelo utilizador anterior ou noutro dossiê. Não toca no que os sites guardaram: cookies, sessões iniciadas, armazenamento local, permissões. Num posto partilhado, o utilizador seguinte chegaria com a sessão do anterior — é of_clear_browsing_data() que a apaga. Os sites vivem num perfil de navegação próprio, separado dos componentes da aplicação.
// Mudanca de dossie : recomeca-se com um navegador virgem, sem historico
uo_browser.of_reset()
// Depois o dossie, com a sua barra de enderecos
uo_browser.ib_address_bar = true
uo_browser.is_address = ls_folder_url
// The user of the workstation changes : no page, no history, no signed-in session left
uo_browser.of_reset()
uo_browser.of_clear_browsing_data()
Para que nada seja alguma vez escrito no disco, defina ib_private = true antes do primeiro endereço: cookies e armazenamento desaparecem com a vista.
É o reflexo a ter sempre que um mesmo componente serve para apresentar conteúdos de contextos diferentes.
Exemplo completo #
// event open da janela : pagina inicial do portal interno
uo_browser.of_reset() // recomecar limpo (incluindo o historico)
// As ferramentas de navegacao, depois a pagina inicial
uo_browser.ib_address_bar = true // campo URL + Anterior / Seguinte / Recarregar
uo_browser.ib_context_menu = true // mesma navegacao com o clique direito
uo_browser.is_address = "https://intranet.empresa.pt/inicio"
// event ue_load_completed de uo_browser : (string as_url)
uo_status.of_panel(/*key*/ "main").is_text = "Página carregada: " + as_url
Boas práticas #
- Atribuir
is_address, sem chamar qualquer método de navegação: é a propriedade que aciona a abertura da página. - Deve ativar-se
ib_address_barsempre que o utilizador possa navegar livremente; o comando através de botões próprios fica reservado aos percursos condicionados. - Convém confiar em
of_can_go_back()/of_can_go_forward()para o estado dos botões, em vez de contar as páginas manualmente: os redirecionamentos falseariam essa contagem. - Nada a prever para os sites que recusam a apresentação integrada: a página é sempre aberta como documento principal, esses cabeçalhos não se aplicam.
- Deve chamar-se
of_reset()na mudança de contexto: é a única forma de garantir que nenhuma página anterior fica acessível através do botão Anterior. Quando o utilizador do posto muda, acrescenteof_clear_browsing_data(): sem ele, os cookies e sessões dos sites mantêm-se. - O componente necessita do runtime web instalado no posto: o event
ue_runtime_missingdeve ser tratado como em qualquer outro componente (Instalação). - Um site pode tocar som sem um gesto do utilizador: a reprodução automática com som é permitida em todo o ambiente WebView2 da aplicação (o leitor de vídeo e o leitor de sons precisam dela, uma página oculta não tem gestos). Uma página que lança um vídeo com som ao abrir vai tocá-lo; se isso incomodar, abra endereços que conhece.
Herdado da base comum #
Estes membros existem em todos os componentes visuais — não são próprios deste. São detalhados uma só vez, nos capítulos transversais; esta tabela apenas diz onde os ler.
| Membros | Função | Detalhado em |
|---|---|---|
of_reset | Repor o componente a zero | 3.6 Repor um componente a zero: of_reset() |
of_register_shortcut · of_clear_shortcuts | Atalhos de teclado do componente | 3.5 Os atalhos de teclado |
of_is_created · of_is_ready · of_get_last_error | Se nasceu, se está pronto, o que falhou | 3.7 Diagnóstico |
of_save_as_png · of_save_as_jpg | Exportar a renderização como imagem | 3.8 Exportar a representação como imagem |
of_set_redraw | Agrupar as alterações num único repinte | 3.10 Boas práticas |
of_preload_icons | Ícones mostrados sem atraso | Apresentação instantânea: of_icon |
of_set_translation | Traduzir uma legenda do componente | 5.2 Adaptar uma etiqueta: of_set_translation |
of_focus_webview | Dar o foco ao componente | 6.4 Teclado e focus |
of_print · of_print_to_pdf | Imprimir, ou escrever um PDF | 6.9 Imprimir |
of_set_property · of_get_property · of_component_name | Controlar uma propriedade pelo nome | 3.1 O motor de propriedades |
Duas ajudas não são herdadas: of_icon e of_escape_markup vivem em n_pbt_utils. Declare um — n_pbt_utils lnv_utils, nada a criar — e chame-as nele.