PBToolboxAI v5 ← Site

webbrowser — u_pbt_webbrowser #

← Référence des composants · Sommaire du guide

Navigateur web intégré à votre fenêtre : affichage d'une page, barre d'adresse, historique Précédent / Suivant, menu contextuel de navigation.

▶ Le voir en vrai — Application de démonstration, tuile Web browser : l'aperçu, le code qui le produit et cette page, côte à côte.


En bref #

Userobjectu_pbt_webbrowser
Classe d'items— (composant sans items)
Sert àAfficher une page web, un portail interne, une documentation en ligne ou un contenu HTML généré, sans quitter l'application

Démarrage rapide #

// event open de la fenetre
uo_browser.ib_address_bar = true    // barre d'adresse + boutons de navigation
uo_browser.is_address = "https://fr.wikipedia.org/wiki/PowerBuilder"

Poser is_address est l'acte de navigation : chaque affectation ouvre la page demandée. Une adresse sans protocole ("exemple.com") reçoit automatiquement https://. Un chemin disque (C:\dossier\page.html, \\serveur\partage\page.html) devient une adresse file:///. Des mots qui ne sont pas une adresse ("facture 2026") partent vers le moteur de recherche de is_search_url ; sans moteur, ils sont refusés et ue_error le dit. Un nom de serveur d'un seul mot suivi de /, ? ou # (office/, intranet/home) est une adresse, comme une adresse IPv6 entre crochets ([::1]/x) ; le mot seul (intranet) reste un texte libre. Un serveur sans HTTPS s'écrit avec http:// explicite.


Propriétés #

PropriétéTypeDéfautRôle
is_addressstring""Adresse affichée. Affecter cette propriété déclenche la navigation. La relire donne la page réellement affichée : si l'utilisateur suit un lien ou revient en arrière, elle suit aussi (ue_load_completed vous prévient). Schémas acceptés : http(s):, file: (un chemin disque aussi), about:, data:, mailto:, tel: ; javascript: est refusé. Une page affichée par of_show_html (une page data:) n'a pas d'adresse à elle : elle se relit vide
ib_address_barbooleanfalseAffiche la barre d'adresse intégrée : champ URL, boutons Précédent / Suivant / Recharger — qui devient Arrêter pendant le chargement d'une page
ib_context_menubooleanfalseActive le menu contextuel au clic droit : Précédent, Suivant, Recharger, plus Copier sur une sélection, Ouvrir le lien et Copier l'adresse du lien sur un lien, Copier l'image sur une image. Ouvert au clavier (Maj+F10), il se pose sur l'élément. Dans un champ de saisie, le menu Couper / Copier / Coller reste
is_search_urlstring""Moteur de recherche des mots qui ne sont pas une adresse, %s = le texte encodé (ex. https://www.bing.com/search?q=%s). Vide par défaut : un tel texte est refusé et ue_error est levé — une application métier n'envoie pas la frappe de ses utilisateurs à un moteur qu'elle n'a pas choisi. Seule une adresse http(s) contenant %s est acceptée : toute autre lève ue_error et le moteur en place reste
ib_veto_new_windowbooleanfalseDemande à ue_new_window avant d'ouvrir une nouvelle fenêtre dans la vue ; renvoyer false y laisse la page courante
ib_veto_downloadsbooleanfalseDemande à ue_download_starting avant chaque téléchargement ; renvoyer false l'annule
ib_veto_navigationbooleanfalseDemande à ue_navigating avant que la page parte vers une autre : un lien, un formulaire ou un script du site, ou un geste de l'utilisateur (une adresse tapée dans la barre, Ouvrir le lien, une nouvelle fenêtre) ; renvoyer false y laisse la page courante. Jamais pour une adresse posée par votre code, ni pour une redirection du serveur : pour garder l'application sur ses serveurs, voir is_allowed_hosts. Une page autorisée est rouverte à l'adresse demandée : un formulaire envoyé en POST y perd ses données
ib_privatebooleanfalseNavigation privée : cookies, stockage et cache des sites ne sont jamais écrits sur le disque et disparaissent avec la vue. À poser avant is_address : le changer rouvre la vue vide (ni page, ni historique) ; le reposer à true ouvre une session privée neuve
is_titlestring""Titre de la page affichée, lu en direct (ue_title_changed prévient quand il change). En lecture seule : l'écrire ne change rien. Vide pour une page sans titre à elle
is_allowed_hostsstring""Les hôtes que la page peut montrer, joints par | : "intranet.example.com|*.example.com" (*. = tout sous-domaine, pas le domaine lui-même). Toute page d'une adresse http(s) hors de la liste est refusée, d'où que vienne la demande — votre code, un lien, l'utilisateur dans la barre, une redirection du serveur — et ue_navigation_blocked le dit ; la page affichée reste. Un fichier local, une page d'of_show_html et about:blank ne sont pas concernés. Une entrée qui n'est pas un nom d'hôte lève ue_error et la liste en vigueur reste. Vide par défaut : tout hôte
ii_zoominteger100Zoom du site en pour cent, de 25 à 500 (la barre d'adresse ne zoome jamais) ; une valeur hors bornes y est ramenée. Lu en direct : Ctrl+molette dans le site le change aussi. Gardé d'une page à l'autre et à travers ib_private
ib_certificate_questionsbooleanfalseDemande à ue_certificate_error quand le certificat d'un serveur n'est pas valide (un intranet à certificat interne ou expiré), au lieu de le refuser aussitôt. La réponse ne vaut que pour cette navigation, et une question restée sans réponse est un non. Désactivé par défaut : la page est refusée et ue_load_failed donne un statut LOADSTATUS_CERT_*
ib_web_messagesbooleanfalseOuvre le pont entre le site et l'application : la page envoie une valeur par chrome.webview.postMessage(value) et ue_web_message la reçoit ; of_post_message en envoie une à la page. Seulement pour les origines de is_message_origins : sans origine, le pont reste fermé. Un message de plus de 64 Ko est ignoré. Désactivé par défaut : aucun site n'atteint l'application
is_message_originsstring""Les origines autorisées à parler avec l'application (voir ib_web_messages), jointes par | : "https://portal.example.com|https://erp.example.com" — un schéma, un hôte, un port s'il n'est pas celui par défaut ; le chemin est ignoré. Exactes : un sous-domaine est une autre origine. file:/// désigne les pages du poste. Une entrée sans schéma lève ue_error et la liste en vigueur reste
is_theme_stylestring""Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement
is_theme_modestring""Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement
il_theme_accentlong-1Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème)

Méthodes #

MéthodeRôle
of_refresh ( )Recharge la page courante. Renvoie 0 une fois demandé, -4 si aucune page n'est affichée (is_address vide), -2 si le composant n'est pas créé
of_go_back ( ) → longRevient à la page précédente. Suit l'ordre de votre code : is_address puis of_go_back() jouent dans cet ordre. Renvoie 0 une fois demandé, -2 si le composant n'est pas créé
of_go_forward ( ) → longAvance à la page suivante. Renvoie 0 une fois demandé, -2 si le composant n'est pas créé
of_can_go_back ( ) → booleantrue si une page précédente existe — pour activer ou griser votre bouton Précédent. Lu en direct sur la page ; à lire après un chargement (ue_load_completed)
of_can_go_forward ( ) → booleantrue si une page suivante existe
of_stop ( ) → longInterrompt le chargement en cours et abandonne les pages encore en attente ; le chargement interrompu lève ue_load_failed. Renvoie 0 une fois demandé, -2 si le composant n'est pas créé
of_execute_javascript (string as_script)Exécute un script dans la page affichée et renvoie sa valeur en JSON : un texte revient entre guillemets, un nombre non (42), un script qui lève une erreur ou ne renvoie rien donne null. Une réponse longue revient entière. Une seule condition, et elle est structurelle : la page doit être chargée, donc appelez-la depuis ue_load_completed, jamais juste après avoir posé is_address. Renvoie une chaîne vide s'il n'y a pas encore de page ou sans réponse en 5 secondes : of_get_last_error() dit pourquoi
of_show_html (string as_html) → longAffiche une page construite par l'application (facture, courrier). La page est encodée : une couleur #c00, une ancre, un % ou un accent s'affichent tels qu'écrits. 2 Mo au plus une fois encodée : au-delà, ue_error et rien ne change. Renvoie 0 une fois envoyé, -2 si le composant n'est pas créé
of_clear_browsing_data ( ) → longEfface ce que les sites ont retenu : cookies (une session ouverte), stockage local, cache, permissions accordées. L'effacement prend sa place après les adresses déjà posées : la page suivante s'ouvre vierge. Tous les webbrowser de l'application partagent ces données. Renvoie 0 une fois envoyé, -2 si le composant n'est pas créé
of_is_loading ( ) → booleantrue tant qu'une page se charge : de ue_load_started à ue_load_completed ou ue_load_failed — pour un sablier ou un bouton Arrêter. Lu en direct ; false avant toute page
of_post_message (string as_json) → longEnvoie une valeur à la page affichée, écrite en JSON (un objet, un texte entre guillemets, un nombre) ; la page la reçoit par l'événement message de chrome.webview. Seulement avec ib_web_messages, vers une page d'une origine de is_message_origins : toute autre page lève ue_error et ne reçoit rien. Renvoie 0 une fois envoyé, -5 si le texte est vide ou n'est pas du JSON (of_get_last_error dit pourquoi), -2 si le composant n'est pas créé
of_reset ( )Remet le composant à neuf : page vidée, historique de navigation effacé, barre d'adresse masquée, menu contextuel désactivé, moteur de recherche vidé, demandes (ib_veto_*) désactivées, navigation privée coupée. Les cookies et sessions des sites restent : c'est of_clear_browsing_data. Renvoie 0 une fois appliqué, -2 si le composant n'est pas créé. Il vide aussi is_allowed_hosts, remet ii_zoom à 100, ferme le pont des messages (ib_web_messages, is_message_origins) et éteint ib_certificate_questions
of_save_as_png (string) · of_save_as_jpg (string)Exporte le site affiché en image. Renvoie 0 une fois l'image écrite, -4 si l'écriture échoue, -2 si le composant n'est pas créé

Événements #

ÉvénementDéclenché quand
ue_load_completed (string as_url)Une page a fini de se charger (la vôtre, un lien, Précédent, of_refresh) ; as_url est l'adresse effectivement atteinte, redirections comprises. Pas levé pour une adresse vide (about:blank) ni pour un chargement en échec. Pour une page d'of_show_html, as_url est vide
ue_load_failed (string as_url, long al_status)Une page n'a pas pu être chargée : hôte inconnu, pas de réseau, certificat, ou chargement annulé par of_stop ou par une adresse plus récente. al_status dit pourquoi : voir Pourquoi une page n'a pas chargé
ue_error (string as_message)Un texte posé dans is_address (ou tapé dans la barre) n'est pas une adresse et aucun is_search_url n'est posé, une adresse n'a pas pu être ouverte du tout, ou le processus de la page s'est arrêté. Rien d'autre n'est retenu : l'adresse suivante se charge normalement
ue_new_window (string as_url) → booleanLa page demande une nouvelle fenêtre après un clic (lien target=_blank, window.open) : elle s'ouvre dans cette vue. Annulable si ib_veto_new_window = true : renvoyer false garde la page courante. Une fenêtre ouverte par un script seul, sans clic, est ignorée. Seules les adresses http et https s'ouvrent : un site qui demande un fichier, une page data: ou un lien de courrier obtient ue_error. Un lien file: dans une page web (http, https, data:) est refusé par le moteur lui-même, avant le composant : rien ne s'ouvre et aucun événement n'est levé
ue_download_starting (string as_url, string as_path) → booleanUn téléchargement commence : as_url est ce qui est téléchargé, as_path le fichier qui sera écrit. Annulable si ib_veto_downloads = true : renvoyer false l'annule ; sinon il continue comme dans Edge
ue_navigating (string as_url) → booleanLa page part vers une autre : un lien, un formulaire ou un script du site, ou un geste de l'utilisateur (adresse tapée dans la barre, Ouvrir le lien, nouvelle fenêtre) — jamais pour une adresse posée par votre application, ni pour une redirection du serveur. Annulable si ib_veto_navigation = true : renvoyer false garde la page courante
ue_title_changed (string as_title)Le titre de la page affichée a changé (is_title le relit à tout moment)
ue_permission_requested (string as_url, string as_kind) → booleanLe site demande la caméra, le micro, la position… (as_kind = une constante PERMISSION_*). Refusé sauf si l'événement renvoie true : la seule question de la bibliothèque où le silence vaut NON
ue_load_started (string as_url)Une page commence à se charger — une adresse de votre code, un lien, un geste de l'utilisateur. as_url est vide pour une page d'of_show_html. of_is_loading() rend true jusqu'à ue_load_completed ou ue_load_failed
ue_navigation_blocked (string as_url)is_allowed_hosts a refusé une page : une adresse, un lien ou une redirection vers un hôte hors de la liste. Rien n'a été chargé, la page affichée reste
ue_certificate_error (string as_url, long al_status) → booleanLe certificat d'un serveur n'est pas valide (al_status = une constante LOADSTATUS_CERT_*). Levé seulement si ib_certificate_questions = true. Refusé sauf si l'événement renvoie true : accepter un certificat est une décision de sécurité, jamais le défaut. La réponse ne vaut que pour cette navigation
ue_web_message (string as_origin, string as_json)Le site a envoyé une valeur (chrome.webview.postMessage) : as_json est cette valeur en JSON (à lire avec n_pbt_json), as_origin l'origine de la page qui l'a envoyée. Seulement avec ib_web_messages et depuis une origine de is_message_origins
ue_ready ( )Le composant a fini de charger ; tout ce qui a été envoyé avant a été rejoué
ue_runtime_missing ( )Le runtime WebView2 est absent : le composant reste vide
ue_bg_color (long al_color)Le composant a calculé sa couleur de fond de thème ; l'userobject l'a déjà adoptée (backcolor)
ue_script_error (string as_message, string as_stack)Une erreur JavaScript s'est produite dans la barre d'adresse du composant (jamais dans le site affiché)

La barre d'adresse intégrée #

C'est la solution la plus rapide : une propriété, et l'utilisateur dispose d'un champ URL et des boutons Précédent / Suivant / Recharger, thémés comme le reste de l'application.

// La barre d'adresse, puis la page a ouvrir
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://fr.wikipedia.org/wiki/PowerBuilder"

Les boutons se grisent tout seuls quand il n'y a nulle part où aller. Dans le champ d'adresse, F5 (ou Ctrl+R) recharge, Alt+← / Alt+→ reviennent et avancent (inversés en écriture de droite à gauche), Échap rend l'adresse courante après une frappe abandonnée, et le premier clic sélectionne toute l'adresse. Un texte qui n'est pas une adresse est signalé : le champ se borde de rouge, avec une infobulle, jusqu'à la frappe suivante. Entrée sur un champ vide ne fait rien : la page reste.

Vos propres boutons #

Si vous préférez piloter la navigation depuis votre propre barre d'outils, masquez la barre intégrée et utilisez les méthodes :

// Boutons Precedent / Suivant de votre fenetre
uo_browser.of_go_back()
uo_browser.of_go_forward()
// event ue_load_completed de uo_browser : (string as_url)
// Mettre a jour l'etat de vos boutons apres chaque page
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()

// Et refleter l'adresse reelle (redirections comprises)
sle_url.text = as_url

Le menu contextuel de navigation #

ib_context_menu ajoute au clic droit un petit menu Précédent / Suivant / Recharger, thémé et rendu par l'application. Il suit ce qui est sous la souris : Copier sur un texte sélectionné, Ouvrir le lien et Copier l'adresse du lien sur un lien, Copier l'image sur une image. Ouvert au clavier (Maj+F10, touche Menu), il se pose sur l'élément. Il partage exactement le même historique que la barre d'adresse : les deux restent donc toujours cohérents.

// A small menu on a right click : back, forward, refresh
uo_browser.ib_context_menu = true

Arrêter un chargement #

// Bouton Stop : interrompt une page qui tarde
uo_browser.of_stop()

Des mots plutôt qu'une adresse #

Par défaut, un texte qui n'est pas une adresse est refusé (ue_error), sans rien bloquer : l'adresse suivante se charge normalement. Pour en faire une recherche, choisissez le moteur :

// 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"

Nouvelles fenêtres et téléchargements #

Un lien « ouvrir dans un nouvel onglet » ou une fenêtre de connexion ouverte après un clic s'affiche dans la vue, et ue_new_window vous le dit. Un téléchargement continue comme dans Edge, et ue_download_starting vous donne l'adresse et le fichier. Les deux se changent en question quand vous le demandez :

// 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"

Une fenêtre de connexion qui dialogue avec la page qui l'a ouverte (une connexion OAuth ou Microsoft en fenêtre surgissante) perd ce lien une fois affichée dans la vue, et la connexion n'aboutit pas : ouvrez une telle connexion dans la page elle-même (mode redirection).

Rester sur ses serveurs #

Pour garder une application métier sur ses serveurs, listez-les dans is_allowed_hosts : toute page d'un autre hôte est refusée, d'où que vienne la demande — votre code, un lien, une adresse tapée dans la barre, une redirection du serveur —, et ue_navigation_blocked le dit. La page affichée reste.

// 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, lui, est levé chaque fois que la page part vers une autre — un lien, un formulaire ou un script du site, une adresse tapée par l'utilisateur, Ouvrir le lien, une nouvelle fenêtre —, jamais pour une adresse posée par votre code ni pour une redirection. Avec ib_veto_navigation, c'est une question : renvoyer false y laisse la page courante. Une page autorisée est rouverte à l'adresse demandée ; un formulaire envoyé en POST y perd ses données. Comparez l'hôte de l'adresse, jamais un morceau de l'adresse entière : https://evil.test/?next=://intranet.example.com/ contient le nom de votre serveur.

// 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"

Caméra, micro, position #

Quand un site demande la caméra, le micro, la position, les notifications ou la lecture du presse-papiers, c'est ue_permission_requested qui décide, et la réponse par défaut est non : un site n'allume pas une caméra par une invite que l'utilisateur ne comprend pas. C'est la seule question de la bibliothèque où le silence vaut refus. Rien n'est retenu : la question revient à chaque demande.

// 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

Valeurs de as_kind : PERMISSION_CAMERA, PERMISSION_MICROPHONE, PERMISSION_GEOLOCATION, PERMISSION_NOTIFICATIONS, PERMISSION_CLIPBOARD, PERMISSION_SENSORS, PERMISSION_DOWNLOADS (plusieurs téléchargements d'affilée), PERMISSION_FILES, PERMISSION_AUTOPLAY, PERMISSION_FONTS, PERMISSION_MIDI, PERMISSION_WINDOWS, PERMISSION_UNKNOWN.

Pourquoi une page n'a pas chargé #

al_status de ue_load_failed se compare aux constantes LOADSTATUS_* du composant :

ConstanteSignifie
LOADSTATUS_HOST_NOT_RESOLVEDHôte inconnu (nom mal écrit, DNS)
LOADSTATUS_DISCONNECTED · LOADSTATUS_CANNOT_CONNECT · LOADSTATUS_SERVER_UNREACHABLEPas de réseau, serveur injoignable
LOADSTATUS_TIMEOUTLe serveur n'a pas répondu à temps
LOADSTATUS_CERT_INVALID · LOADSTATUS_CERT_EXPIRED · LOADSTATUS_CERT_NAME_INCORRECT · LOADSTATUS_CERT_REVOKED · LOADSTATUS_CLIENT_CERT_ERRORCertificat refusé
LOADSTATUS_CANCELEDChargement annulé par of_stop ou par une adresse plus récente
LOADSTATUS_AUTH_REQUIRED · LOADSTATUS_PROXY_AUTH_REQUIREDIdentification demandée (serveur, proxy)
LOADSTATUS_CONNECTION_ABORTED · LOADSTATUS_CONNECTION_RESET · LOADSTATUS_INVALID_RESPONSE · LOADSTATUS_REDIRECT_FAILED · LOADSTATUS_UNEXPECTED_ERROR · LOADSTATUS_UNKNOWNAutres échecs de connexion ou de réponse
// 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

Exécuter un script dans la page #

of_execute_javascript lit ou modifie la page affichée (son titre, un champ, un compteur). Il n'est pas bridé par la licence, y compris sur une page about:blank ou data: : exécuter un script dans la page est le métier d'un navigateur, et le composant est gratuit.

// 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")

Indicateur de chargement #

ue_load_started est levé quand une page commence à se charger — une adresse de votre code, un lien, un geste de l'utilisateur —, et of_is_loading() rend true jusqu'à ue_load_completed ou ue_load_failed : de quoi montrer un sablier ou activer votre bouton Arrêter.

// 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 agrandit ou réduit le site (la barre d'adresse garde sa taille), de 25 à 500 %. Il se relit en direct : Ctrl+molette dans le site le change aussi, et votre code le voit.

// A screen read from a distance : the site one and a half times larger
uo_browser.ii_zoom = 150

Le certificat d'un intranet #

Un serveur dont le certificat n'est pas valide (certificat interne, expiré) est refusé, et ue_load_failed donne un statut LOADSTATUS_CERT_*. Avec ib_certificate_questions, ue_certificate_error décide — et sa réponse par défaut est non, comme pour une permission : accepter un certificat est une décision de sécurité. Une réponse ne vaut que pour la navigation en cours ; rien n'est retenu.

// 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/"

Des messages entre la page et l'application #

Un portail interne peut prévenir l'application (« dossier enregistré », « ligne choisie ») : ouvrez le pont avec ib_web_messages, et listez dans is_message_origins les origines qui ont le droit de parler. Sans origine listée, le pont reste fermé : aucun site du Web ne peut atteindre votre application. La page envoie une valeur JSON, ue_web_message la reçoit telle quelle ; of_post_message répond à la page.

// 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

Une origine s'écrit schéma, hôte et port s'il n'est pas celui par défaut (https://portal.example.com:8443) ; un sous-domaine est une autre origine, et file:/// désigne les pages du poste. Un message de plus de 64 Ko est ignoré. of_post_message vers une page d'une autre origine lève ue_error et n'envoie rien.


Sites qui refusent l'affichage intégré #

Certains sites — Google, la plupart des banques, beaucoup d'applications SaaS — envoient des en-têtes de sécurité qui interdisent leur affichage à l'intérieur d'une autre page. Le composant n'est pas concerné : il n'affiche jamais un site dans un cadre. La page est ouverte comme document principal, exactement comme le fait votre navigateur, et ces en-têtes ne s'appliquent alors plus.

Il n'y a donc rien à régler, et aucun cas particulier à prévoir dans votre code.

// Un site qui refuse d'etre integre dans une page : rien de special a faire
uo_browser.ib_address_bar = true
uo_browser.is_address = "https://www.google.com"

En contrepartie, la page occupe toute la surface du composant sous la barre d'adresse : les habillages posés par-dessus (bandeaux, superpositions thémées) ne sont pas visibles pendant la navigation.


Contenu HTML sans réseau #

of_show_html affiche une page HTML construite par votre application : un aperçu de courrier, un ticket, une facture ou un rapport, sans aucun appel réseau ni fichier temporaire. La page est encodée pour vous : une couleur #c00, une ancre, un % ou un accent s'affichent tels qu'écrits (2 Mo au plus).

// 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)

Posée directement dans is_address, une adresse data:text/html, n'est pas encodée : un # y coupe la page (tout ce qui suit passe pour une ancre) et un % la brouille. Préférez of_show_html, ou encodez vous-même (# → %23, % → %25).

Une telle page n'a pas d'adresse à elle : is_address se relit vide, la barre d'adresse aussi, et ue_load_completed reçoit une adresse vide. Sans <title>, son titre est vide. Une image du disque (file:///) n'y est pas affichée : le moteur ne laisse pas une page data: lire les fichiers du poste ; écrivez l'image dans la page (<img src="data:image/png;base64,…">).

Un fichier local s'ouvre de la même façon avec file:///C:/temp/rapport.html, ou simplement son chemin C:\temp\rapport.html.


Repartir de zéro #

of_reset() ne se contente pas de vider la page : il efface aussi l'historique de navigation. Un utilisateur ne peut donc pas revenir, par le bouton Précédent, sur une page consultée par l'utilisateur précédent ou dans un autre dossier. Il ne touche pas à ce que les sites ont retenu : cookies, sessions ouvertes, stockage local, permissions. Sur un poste partagé, l'utilisateur suivant arriverait connecté sous le compte du précédent — c'est of_clear_browsing_data() qui l'efface. Les sites vivent dans un profil de navigation à part, séparé des composants de l'application.

// Local variables
string ls_folder_url

// L'adresse du dossier que l'utilisateur vient d'ouvrir
ls_folder_url = "https://intranet.example.com/files/4152"

// Changement de dossier : on repart d'un navigateur vierge, sans historique
uo_browser.of_reset()

// Puis le dossier, avec sa barre d'adresse
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()

Pour que rien ne soit jamais écrit sur le disque, posez ib_private = true avant la première adresse : cookies et stockage disparaissent avec la vue.

C'est le réflexe à avoir chaque fois qu'un même composant sert à afficher des contenus de contextes différents.


Exemple complet #

// event open de la fenetre : page d'accueil du portail interne
uo_browser.of_reset()                  // repartir propre (historique compris)

// Les outils de navigation, puis la page d'accueil
uo_browser.ib_address_bar  = true      // champ URL + Precedent / Suivant / Recharger
uo_browser.ib_context_menu = true      // meme navigation au clic droit
uo_browser.is_address = "https://intranet.example.com/home"
// event ue_load_completed de uo_browser : (string as_url)
uo_status.of_panel(/*key*/ "main").is_text = "Page chargee : " + as_url

Bonnes pratiques #

Hérité du socle commun #

Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.

MembresRôleDétaillé dans
of_resetRemettre le composant à zéro3.6 Remettre un composant à zéro : of_reset()
of_register_shortcut · of_clear_shortcutsRaccourcis clavier du composant3.5 Les raccourcis clavier
of_is_created · of_is_ready · of_get_last_errorS'il est né, s'il est prêt, ce qui a échoué3.7 Diagnostic
of_save_as_png · of_save_as_jpgExporter le rendu en image3.8 Exporter le rendu en image
of_set_redrawGrouper les modifications en un seul repaint3.10 Bonnes pratiques
of_preload_iconsIcônes affichées sans délaiAffichage instantané : of_icon
of_set_translationTraduire un libellé du composant5.2 Adapter un libellé : of_set_translation
of_focus_webviewDonner le focus au composant6.4 Clavier et focus
of_print · of_print_to_pdfImprimer, ou écrire un PDF6.9 Imprimer
of_set_property · of_get_property · of_component_namePiloter une propriété par son nom3.1 Le moteur de propriétés
is_accessible_name · is_accessible_descriptionLe nom et la description que dit un lecteur d'écran3.4 Propriétés et events optionnels

Deux aides ne sont pas héritées : of_icon et of_escape_markup vivent sur n_pbt_utils. Déclarez-en une — n_pbt_utils lnv_utils, rien à créer — et appelez-les dessus.


← Référence des composants · Sommaire du guide