-
-
Notifications
You must be signed in to change notification settings - Fork 773
WebView URL filtering #3442
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
base: main
Are you sure you want to change the base?
WebView URL filtering #3442
Changes from all commits
a476f73
23e2747
4c6777d
4849755
7f335d6
a209b71
c6119ba
98ec9fd
39af762
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The WebView widget now supports an on_navigation_starting handler to prevent user-defined URLs from being loaded |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,10 @@ build_gradle_dependencies = [ | |
"com.google.android.material:material:1.12.0", | ||
] | ||
|
||
build_gradle_extra_content=""" | ||
chaquopy.defaultConfig.staticProxy("toga_android.widgets.webview") | ||
""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hrm... Requiring users to manually inject an "extra content" block to make a feature work is a problematic requirement. I understand why it's needed - but we possibly need to solve the bigger problem of allowing toga to declare a list of "classes that need a static proxy". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. But this probably means that this PR cannot be merged any time soon, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It depends how essential the change is. If a WebView will continue to work on Android, but this feature won't work without the extra content declaration, we can probably merge it. We will need to add a set of platform notes in the docs, and we'll need to prioritise finding a better fix - but I don't think it needs to be a complete blocker. However, if Webview (or the whole Android backend) won't work at all if this addition isn't in place, then we'll need to solve that problem first. |
||
|
||
# Web deployment | ||
[tool.briefcase.app.webview.web] | ||
requires = [ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,13 @@ | ||
import asyncio | ||
|
||
import toga | ||
from toga.constants import COLUMN, ROW | ||
from toga.style import Pack | ||
|
||
|
||
class ExampleWebView(toga.App): | ||
allowed_base_url = "https://beeware.org/" | ||
|
||
async def on_do_async_js(self, widget, **kwargs): | ||
self.label.text = repr(await self.webview.evaluate_javascript("2 + 2")) | ||
|
||
|
@@ -22,6 +26,24 @@ def on_bad_js_result(self, result, *, exception=None): | |
def on_webview_load(self, widget, **kwargs): | ||
self.label.text = "www loaded!" | ||
|
||
def on_navigation_starting_sync(self, widget, url): | ||
print(f"on_navigation_starting_sync: {url}") | ||
allow = True | ||
if not url.startswith(self.allowed_base_url): | ||
allow = False | ||
message = f"Navigation not allowed to: {url}" | ||
dialog = toga.InfoDialog("on_navigation_starting()", message) | ||
asyncio.create_task(self.dialog(dialog)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be easier to make on_navigation_starting an async callback, and then There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The example app now has both, a synchronous and an async handler |
||
return allow | ||
|
||
async def on_navigation_starting_async(self, widget, url): | ||
print(f"on_navigation_starting_async: {url}") | ||
if not url.startswith(self.allowed_base_url): | ||
message = f"Do you want to allow navigation to: {url}" | ||
dialog = toga.QuestionDialog("on_navigation_starting_async()", message) | ||
return await self.main_window.dialog(dialog) | ||
return True | ||
|
||
def on_set_url(self, widget, **kwargs): | ||
self.label.text = "Loading page..." | ||
self.webview.url = "https://beeware.org/" | ||
|
@@ -91,6 +113,8 @@ def startup(self): | |
url="https://beeware.org/", | ||
on_webview_load=self.on_webview_load, | ||
style=Pack(flex=1), | ||
on_navigation_starting=self.on_navigation_starting_async, | ||
# on_navigation_starting=self.on_navigation_starting_sync, | ||
) | ||
|
||
box = toga.Box( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked, but this could be a problem if on_navigation_starting is an async callback, because the returned value will be a future.