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. Uma página apresentada por of_show_html (uma página data:) não tem endereço próprio: relê-se vazia |
ib_address_bar | boolean | false | Apresenta a barra de endereço integrada: campo URL, botões Anterior / Seguinte / Recarregar — que passa a Parar enquanto uma página carrega |
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 a página passar para outra: um link, um formulário ou um script do site, ou um gesto do utilizador (um endereço escrito na barra, Abrir link, uma nova janela); devolver false mantém a página atual. Nunca para um endereço definido pelo seu código, nem para um redirecionamento do servidor: para manter a aplicação nos seus próprios servidores, veja is_allowed_hosts. 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. Vazio para uma página sem título próprio |
is_allowed_hosts | string | "" | Os anfitriões que a página pode mostrar, unidos por |: "intranet.example.com|*.example.com" (*. = qualquer subdomínio, não o próprio domínio). Qualquer página de um endereço http(s) fora da lista é recusada, seja quem for que a peça — o seu código, uma ligação, o utilizador na barra, um redirecionamento do servidor — e ue_navigation_blocked indica-o; a página apresentada mantém-se. Um ficheiro local, uma página de of_show_html e about:blank não são abrangidos. Uma entrada que não seja um nome de anfitrião lança ue_error e a lista em vigor mantém-se. Vazio por predefinição: qualquer anfitrião |
ii_zoom | integer | 100 | Zoom do site em percentagem, de 25 a 500 (a barra de endereço nunca faz zoom); um valor fora do intervalo é trazido para ele. Lido em direto: Ctrl+roda do rato no site também o altera. Mantido de uma página para a outra e através de ib_private |
ib_certificate_questions | boolean | false | Pergunta a ue_certificate_error quando o certificado de um servidor não é válido (uma intranet com certificado interno ou expirado), em vez de o recusar de imediato. A resposta só vale para essa navegação, e uma pergunta sem resposta é um não. Desativado por predefinição: a página é recusada e ue_load_failed dá um estado LOADSTATUS_CERT_* |
ib_web_messages | boolean | false | Abre a ponte entre o site e a aplicação: a página envia um valor com chrome.webview.postMessage(value) e ue_web_message recebe-o; of_post_message envia um à página. Só para as origens de is_message_origins: sem origem, a ponte fica fechada. Uma mensagem de mais de 64 KB é descartada. Desativado por predefinição: nenhum site chega à aplicação |
is_message_origins | string | "" | As origens autorizadas a falar com a aplicação (veja ib_web_messages), unidas por |: "https://portal.example.com|https://erp.example.com" — um esquema, um anfitrião, uma porta se não for a predefinida; o caminho é ignorado. Exatas: um subdomínio é outra origem. file:/// designa as páginas do posto. Uma entrada sem esquema lança ue_error e a lista em vigor mantém-se |
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 ( ) → long | Volta à página anterior. Segue a ordem do seu código: is_address e depois of_go_back() são executados por essa ordem. Devolve 0 uma vez pedido, -2 se o componente não estiver criado |
of_go_forward ( ) → long | Avança para a página seguinte. Devolve 0 uma vez pedido, -2 se o componente não estiver criado |
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 ( ) → long | Interrompe o carregamento em curso e abandona as páginas ainda em espera; o carregamento interrompido aciona ue_load_failed. Devolve 0 uma vez pedido, -2 se o componente não estiver criado |
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_is_loading ( ) → boolean | true enquanto uma página carrega: de ue_load_started a ue_load_completed ou ue_load_failed — para uma ampulheta ou um botão Parar. Lido em direto; false antes de qualquer página |
of_post_message (string as_json) → long | Envia um valor à página apresentada, escrito em JSON (um objeto, um texto entre aspas, um número); a página recebe-o através do evento message de chrome.webview. Só com ib_web_messages, para uma página de uma origem de is_message_origins: qualquer outra página lança ue_error e não recebe nada. Devolve 0 uma vez enviado, -5 se o texto estiver vazio ou não for JSON (of_get_last_error diz porquê), -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. Também esvazia is_allowed_hosts, repõe ii_zoom a 100, fecha a ponte de mensagens (ib_web_messages, is_message_origins) e desativa ib_certificate_questions |
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. Para uma página de of_show_html, as_url está vazio |
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 | A página passa para outra: um link, um formulário ou um script do site, ou um gesto do utilizador (endereço escrito na barra, Abrir link, nova janela) — nunca para um endereço definido pela aplicação, nem para um redirecionamento do servidor. 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_load_started (string as_url) | Uma página começa a carregar — um endereço do seu código, uma ligação, um gesto do utilizador. as_url está vazio para uma página de of_show_html. of_is_loading() devolve true até ue_load_completed ou ue_load_failed |
ue_navigation_blocked (string as_url) | is_allowed_hosts recusou uma página: um endereço, uma ligação ou um redirecionamento para um anfitrião fora da lista. Nada foi carregado, a página apresentada mantém-se |
ue_certificate_error (string as_url, long al_status) → boolean | O certificado de um servidor não é válido (al_status = uma constante LOADSTATUS_CERT_*). Só é lançado se ib_certificate_questions = true. Recusado a menos que o evento devolva true: aceitar um certificado é uma decisão de segurança, nunca a predefinição. A resposta só vale para esta navegação |
ue_web_message (string as_origin, string as_json) | O site enviou um valor (chrome.webview.postMessage): as_json é esse valor em JSON (a ler com n_pbt_json), as_origin a origem da página que o enviou. Só com ib_web_messages e a partir de uma origem de is_message_origins |
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. Um texto que não é um endereço é assinalado: o campo fica com uma borda vermelha, com uma dica, até à tecla seguinte. Enter num campo vazio não faz nada: a página mantém-se.
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"
Uma janela de início de sessão que dialoga com a página que a abriu (um início de sessão OAuth ou Microsoft numa janela pop-up) perde essa ligação quando apresentada na vista, e o início de sessão não termina: abra esse início de sessão na própria página (modo de redirecionamento).
Ficar nos seus próprios servidores #
Para manter uma aplicação de gestão nos seus próprios servidores, indique-os em is_allowed_hosts: qualquer página de outro anfitrião é recusada, seja quem for que a peça — o seu código, uma ligação, um endereço escrito na barra, um redirecionamento do servidor —, e ue_navigation_blocked indica-o. A página apresentada mantém-se.
// Only the company servers : any other host is refused, redirections included
uo_browser.is_allowed_hosts = "intranet.example.com|*.example.com"
// ue_navigation_blocked event of uo_browser : (string as_url)
st_message.text = "This site is not allowed : " + as_url
ue_navigating é lançado sempre que a página passa para outra — um link, um formulário ou um script do site, um endereço escrito pelo utilizador, Abrir link, uma nova janela —, nunca para um endereço definido pelo seu código nem para um redirecionamento. Com ib_veto_navigation é uma pergunta: 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. Compare o anfitrião do endereço, nunca um pedaço do endereço inteiro: https://evil.test/?next=://intranet.example.com/ contém o nome do seu servidor.
// Ask before the site leaves for another page
uo_browser.ib_veto_navigation = true
// ue_navigating event of uo_browser : (string as_url)
// Local variables
string ls_host
long ll_cut
// The host of the address : after "://", up to the first "/", "?", "#" or ":"
ls_host = Lower(Mid(as_url, Pos(as_url, "://") + 3))
for ll_cut = 1 to Len(ls_host)
if Pos("/?#:", Mid(ls_host, ll_cut, 1)) > 0 then exit
next
ls_host = Left(ls_host, ll_cut - 1)
// Only the company server may be opened : the host must be EXACTLY it
return ls_host = "intranet.example.com"
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")
Indicador de carregamento #
ue_load_started é lançado quando uma página começa a carregar — um endereço do seu código, uma ligação, um gesto do utilizador —, e of_is_loading() devolve true até ue_load_completed ou ue_load_failed: o suficiente para mostrar uma ampulheta ou ativar o seu botão Parar.
// ue_load_started event of uo_browser : (string as_url)
// The Stop button works while the page loads
cb_stop.enabled = true
// ue_load_completed event of uo_browser : (string as_url)
// Loaded : nothing left to stop
cb_stop.enabled = uo_browser.of_is_loading()
Zoom #
ii_zoom amplia ou reduz o site (a barra de endereço mantém o seu tamanho), de 25 a 500 %. Relê-se em direto: Ctrl+roda do rato no site também o altera, e o seu código vê-o.
// A screen read from a distance : the site one and a half times larger
uo_browser.ii_zoom = 150
O certificado de uma intranet #
Um servidor cujo certificado não é válido (certificado interno ou expirado) é recusado, e ue_load_failed dá um estado LOADSTATUS_CERT_*. Com ib_certificate_questions, decide ue_certificate_error — e a sua resposta predefinida é não, como para uma permissão: aceitar um certificado é uma decisão de segurança. Uma resposta só vale para a navegação em curso; nada é memorizado.
// Ask about certificates instead of refusing them at once
uo_browser.ib_certificate_questions = true
// ue_certificate_error event of uo_browser : (string as_url, long al_status)
// Only the test server of the company, whose certificate is internal
return Left(Lower(as_url), 34) = "https://test-intranet.example.com/"
Mensagens entre a página e a aplicação #
Um portal interno pode avisar a aplicação («dossiê guardado», «linha escolhida»): abra a ponte com ib_web_messages, e indique em is_message_origins as origens autorizadas a falar. Sem origem na lista, a ponte fica fechada: nenhum site da Web consegue chegar à sua aplicação. A página envia um valor JSON, ue_web_message recebe-o tal como está; of_post_message responde à página.
// The company portal may talk with the application
uo_browser.ib_web_messages = true
uo_browser.is_message_origins = "https://portal.example.com"
uo_browser.is_address = "https://portal.example.com/orders"
// In a page of the portal : send a value to the application, and listen to its answers
chrome.webview.postMessage({ order: 4152, action: "open" });
chrome.webview.addEventListener("message", function (e) { console.log(e.data); });
// ue_web_message event of uo_browser : (string as_origin, string as_json)
// Local variables
n_pbt_json lnv_json
// Read the value the page sent, then answer it
lnv_json.of_load(/*json*/ as_json)
if lnv_json.of_get_string(/*path*/ "action") = "open" then
st_message.text = "Order " + String(lnv_json.of_get_number(/*path*/ "order"))
uo_browser.of_post_message(/*json*/ '{"opened":true}')
end if
Uma origem escreve-se com esquema, anfitrião e porta se não for a predefinida (https://portal.example.com:8443); um subdomínio é outra origem, e file:/// designa as páginas do posto. Uma mensagem de mais de 64 KB é descartada. of_post_message para uma página de outra origem lança ue_error e não envia nada.
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).
Uma página assim não tem endereço próprio: is_address relê-se vazio, tal como a barra de endereço, e ue_load_completed recebe um endereço vazio. Sem <title>, o seu título está vazio. Uma imagem do disco (file:///) não é mostrada nela: o motor não deixa uma página data: ler os ficheiros do posto; escreva a imagem na página (<img src="data:image/png;base64,…">).
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.
// Local variables
string ls_folder_url
// O endereco do dossie que o utilizador acabou de abrir
ls_folder_url = "https://intranet.example.com/files/4152"
// 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.
- Para manter a aplicação nos seus próprios servidores, indique-os em
is_allowed_hosts: também trava os redirecionamentos, queue_navigatingnão vê.
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 |
is_accessible_name · is_accessible_description | O nome e a descrição que um leitor de ecrã diz | 3.4 Propriedades e eventos opcionais |
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.