More DesktopHTMLViewer woes

Up to now I’ve been doing the following in my PrintWindow: prepare the HTML string, for macOS get permission to load local images, then send the HTML string into the HTMViewer. This works OK for macOS, Linux, and Windows:

if  (f<>Nil)  Then PrintViewer.grantAccesstoFolder (f.Parent)
PrintViewer.LoadPage (htmlStr, f)

Moving to a DesktopHTMLViewer, it seems, according to the page documenting the .LoadPage method, we are no longer able to use the above incantation under Windows because “This method signature is not supported on Windows due to CEF Security.” This implies that one write the HTML string into a file and load that, so I’m trying the following:

ff = FolderItem.TemporaryFile
Var  outStr As TextOutputStream
outStr = TextOutputStream.Create (ff)
outStr.Write (htmlStr)
outStr.Close ()

PrintViewer.LoadPage (ff)

ff is a FolderItem property on the PrintWindow, so it has persistence. I tried this under macOS and Windows, but the following happens:

  1. macOS. I get an error event on the DesktopHTMLViewer, with message “Frame load interrupted” and error code 102.

  2. On Windows I get no error and the expected HTML is loaded into the DesktopHTMLViewer, but it is not rendered.

Neither of these is particularly useful; any suggestions welcome.

I just use the following,

I store my HTML help file in a string constant, but a straight string works as well, I just replace the HTML name for wether like or dark mode. Never had an issue… You don’t need to write anything to the temp file, it’s just a place holder, put your HTML in a string and use the following. Obviously change the names to suit your controls.

Var f As FolderItem = FolderItem.TemporaryFile
hvReference.LoadPage(ALSLanguageReferenceDarK, f)

TC

Then you must be doing it with an HTMLViewer, not a DesktopHTMLViewer.

However your reply reminded me of something, which is that my help file is displayed the same way and it, too, works. Perhaps because of the filename, which is help.html.

Nope I’m using DesktopHtmlViewer as I’ve updated everything to API2…

Screen Shot 2021-12-21 at 7.53.52 am

OK thanks. I’m still working on it.

The older code you’ve used to “grantAcccessToFolder” wasn’t technically correct, it worked… I have never versions of the code (for both existing pages and strings), but I haven’t tested it with DesktopHTMLViewer, only HTMLViewer.

https://ohanaware.com/blog/202150/WKWebKit,-Xojo-HTMLViewer-and-App-Sandbox.html

Perhaps this will help.

Since posting last night, I’ve been through a number of steps, the summary of which is that it seems I can continue with existing code, at least on macOS. On Windows, where pages weren’t displaying at all, it turns out that the CancelLoad event now behaves differently. If one calls .LoadPage with the html in a string, then CancelLoad gets called with the URL containing the html string, but encoded as a data: URI, thus:

data:text/html,base64,<original-html-string-base64-encoded>

Once I detected this and ignored it, pages started loading.

However:

My app requires that it be possible to load local images, referred to in the html string as something like:

<img src="file://c:\Users\myusername\Documents\Images\someimage.gif">

Just as happened for macOS, this appears no longer to be possible and perhaps requires a Windows equivalent of Sam’s Declare that saved my bacon previously. I did verify that taking the html string that can’t load images, and putting it on the desktop of my Windows VM as a file such as test.html, could load the images when loaded into IE or Edge.

I think you can’t do it this way, you must remove the absolute paths and replace them with relative ones to the root where the “rootFile” is.

DeskHTMLView1.LoadPage(htmlCode, rootFile)

Suppose rootFile points to “C:\myTempFolder\garbage.html”
You could create a folder called “C:\myTempFolder\Images” and put your images there.
And in your code, you could reference them as <img src="Images/someimage.gif">

Works OK (for the moment) for macOS, using the @Sam_Rowlands Declare. For Windows, I’m going to try writing the html string to a file where the images already are. That should make the paths exceedingly relative! :smile:

Unless Xojo have made a custom weak security CEF version, I don’t believe you will break the file access security just calling absolute paths as relative.

You mean a Declare asking for access permission is the only solution? Since IE/Edge can do this, presumably that is what they do?

As for what I do remember, explicit file: protocol should not be allowed, like in file://C:/path/image.png", absolute paths should not be allowed, like “/root/place/files/image.png”, trying to escape the landing folder going backwards should not be allowed, like “··/··/system32/FeatureToastDlpImg.png”.

Do some tests, report your findings.

Until now I deploy my packs of images, libs and whatever in subfolders of the resources folder, then I land there and use them via relative paths (forward only).

:wink:

In progress, Cap’n.

I use this in a couple of places

Changing one place to use:

ff = new FolderItem (app.datarootpath + "Images" + app.dirch + "temp.html", FolderItem.pathModes.Native)
if  (ff.Exists=True)  then ff.Remove ()
Var  outStr As TextOutputStream
outStr = TextOutputStream.Create (ff)
outStr.Write (htmlStr)
outStr.Close ()
PrintViewer.LoadPage (ff)

.
and under macOS either approach works. But neither works under Windows (Win7, specifically). I don’t even get the page minus the local images. This is using absolute paths in the html, mind.

That’s enough for tonight.

I’ll try to create a simple example here. But currently I’m not using the DesktopHTMLViewer, but the previous one, but the engine should be the same.

Try this https://drive.google.com/file/d/11ThG5RyVrdbEkZSjl1ZZrUwEKB43Y51z/view?usp=sharing

Download the zip, compile and run.

There’s a build step that prepares the resources. I made your approach of creating a file there, works if the resource folder is writable.

1 Like

Thanks for that, Rick. Now trying to adapt it to my app.

This is just a proof of concept. You need to complete it. The best approach is to copy/move your “writeable resources” to a proper writeable place in windows, like a place under SpecialFolder.ApplicationData

OK - I have my way forward now. My images are already in their own folder, for Windows I just write the html text there too. Thanks - starting from a working example was the crucial step. I was able to adapt to my app.

2 Likes