Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebView on Android displays empty page when html contains style element #2242

Open
t-arn opened this issue Nov 24, 2023 · 10 comments
Open

WebView on Android displays empty page when html contains style element #2242

t-arn opened this issue Nov 24, 2023 · 10 comments
Labels
android The issue relates to Android mobile support. bug A crash or error in behavior. good first issue Is this your first time contributing? This could be a good place to start!

Comments

@t-arn
Copy link
Contributor

t-arn commented Nov 24, 2023

Describe the bug

When displaying a html file that contains a style element (on Android) the page is not rendered and remains white.
The html file is rendered correctly with Android's HTML Viewer
The html file is rendered correctly in WebView on Windows
The html file was rendered correctly in WebView on Android with Toga 0.3.1dev93

When the style element is removed, the page is shown in WebView (but without the styles of course).
When using a separate CSS file, the html file is shwon in WebView but without the styles.

Steps to reproduce

I use this code to display the html file:

        # create box for content
        main_box = toga.Box(style=Pack(direction=COLUMN, flex=1))
        # read help file
        f = open(self._html_file, "r", encoding="utf-8")
        text = f.read()
        f.close()
        webView = toga.WebView(style=Pack(flex=1))
        webView.set_content("data:text/html", text)
        main_box.add(webView)

Expected behavior

The html file should be rendered correctly also with Toga 0.4.x

Screenshots

No response

Environment

  • Operating System: Android 13
  • Python version: 3.11.2
  • Software versions:
    • Briefcase: 0.3.16
    • Toga: 0.4.1.dev65+g0eaf2c06e

help-en.html.zip

Logs


Additional context

No response

@t-arn t-arn added the bug A crash or error in behavior. label Nov 24, 2023
@freakboy3742
Copy link
Member

I can verify that I can reproduce this problem; but I have no idea what is causing it.

The existence of any <head> content seems to alter the rendering. Setting a page title or setting a <meta> should both be completely neutral from the perspective of page content; and yet they seem to prevent the page content from being displayed.

I thought it might be a bug caused by loading content before the web view is ready; but putting in a 2s delay before the page load doesn't fix the problem; neither does using the same content in the webview demo, where the static content is loaded on a button press.

It's not all style tags, either. If you remove all the references to color and border-bottom CSS descriptors, the page renders. It's a mess of font sizes.... but it renders. background-colour does work, so it's not just references to color.

I'm at a bit of a loss to explain any of this. Have you got any ideas @mhsmith?

@mhsmith
Copy link
Member

mhsmith commented Nov 28, 2023

As part of the Toga 0.4 work, the Android WebView stopped using base64 encoding in its data URLs. But according to the Android documentation:

Applications targeting Build.VERSION_CODES.Q or later must either use base64 or encode any # characters in the content as %23, otherwise they will be treated as the end of the content and the remaining text used as a document fragment identifier.

Apparently the encoding argument, despite taking a string, actually only has two possible states:base64 for base64, or literally anything else for URL % encoding. The correct way of dealing with character encoding is explained further down:

If you need to set a different charset, you should form a 'data' scheme URL which explicitly specifies a charset parameter in the mediatype portion of the URL and call loadUrl(java.lang.String) instead.

For now, you can work around this by %-encoding the data yourself using something like urllib.parse.quote, but you'll have to revert that when this bug is fixed in a future version of Toga.

@mhsmith mhsmith added the android The issue relates to Android mobile support. label Nov 28, 2023
@t-arn
Copy link
Contributor Author

t-arn commented Nov 28, 2023

@mhsmith I use the data URL data:text/html which does not need to be encoded. Besides that, according to the Toga docs, this parameter is ignored on Android anyway.

I use WebView.set_content, not loadUrl.

@mhsmith
Copy link
Member

mhsmith commented Nov 28, 2023

The documentation I quoted was from the native loadData method, which is what Toga's set_content method currently uses on Android.

The workaround is to wrap the content argument in urllib.parse.quote, e.g.:

        webView.set_content("data:text/html", urllib.parse.quote(text))

I've tried this with your example and it works fine. Though obviously you should only do it on Android, unless a similar bug happens to exist on other platforms.

@t-arn
Copy link
Contributor Author

t-arn commented Nov 28, 2023

@mhsmith I will try this, many thanks!

@t-arn
Copy link
Contributor Author

t-arn commented Nov 29, 2023

@mhsmith Yes, the workaround is working! Thanks again

@bitstuffing
Copy link

bitstuffing commented Dec 30, 2023

I'm able to confirm that the same issue is happening with my current project on Android, but not on Linux:

pychat

In Linux it's working fine, but... when I launch it on Android it displays an empty page, but also, chromium said that javascript functions are not implemented.

I/chromium: [INFO:CONSOLE(1)] "Uncaught ReferenceError: updateChatMessageNode is not defined", source: ...

I have put a print to verify that application is reading the code and should load it.

@freakboy3742
Copy link
Member

FWIW: The fix here would be relatively straightforward - the Android backend needs to do the urllib.parse.quote(text) dance on the set_content() call. Add a testbed test for this (or, modify the existing set_content call to include some of the problematic content), and we're done.

@freakboy3742 freakboy3742 added the good first issue Is this your first time contributing? This could be a good place to start! label Dec 31, 2023
@bitstuffing
Copy link

bitstuffing commented Dec 31, 2023

I cannot confirm it right now but I think your fix could work because I saw in chromium an exception with url-encoded html that I didn't put it, and it could be the reason of lost javascript, but until next days I don't touch a PC xD. When I try it I will put the results.

By the way, happy new year!

@bitstuffing
Copy link

I can confirm that the problem with urllib.parse.quote(html) is fixed for Android

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android The issue relates to Android mobile support. bug A crash or error in behavior. good first issue Is this your first time contributing? This could be a good place to start!
Projects
None yet
Development

No branches or pull requests

4 participants