1
0
Эх сурвалжийг харах

Merge pull request #1030 from zauberzeug/ignore-events

ignore events on disabled or hidden elements by default
Falko Schindler 1 жил өмнө
parent
commit
99363003b5

+ 8 - 0
nicegui/elements/mixins/disableable_element.py

@@ -12,6 +12,14 @@ class DisableableElement(Element):
     def __init__(self, **kwargs: Any) -> None:
         super().__init__(**kwargs)
         self.enabled = True
+        self.ignores_events_when_disabled = True
+
+    @property
+    def is_ignoring_events(self) -> bool:
+        """Return whether the element is currently ignoring events."""
+        if super().is_ignoring_events:
+            return True
+        return not self.enabled and self.ignores_events_when_disabled
 
     def enable(self) -> None:
         """Enable the element."""

+ 6 - 0
nicegui/elements/mixins/visibility.py

@@ -14,6 +14,12 @@ class Visibility:
     def __init__(self, **kwargs: Any) -> None:
         super().__init__(**kwargs)
         self.visible = True
+        self.ignores_events_when_hidden = True
+
+    @property
+    def is_ignoring_events(self) -> bool:
+        """Return whether the element is currently ignoring events."""
+        return not self.visible and self.ignores_events_when_hidden
 
     def bind_visibility_to(self,
                            target_object: Any,

+ 2 - 0
nicegui/events.py

@@ -277,6 +277,8 @@ def handle_event(handler: Optional[Callable[..., Any]],
         no_arguments = not any(p.default is Parameter.empty for p in signature(handler).parameters.values())
         sender = arguments.sender if isinstance(arguments, EventArguments) else sender
         assert sender is not None and sender.parent_slot is not None
+        if sender.is_ignoring_events:
+            return
         with sender.parent_slot:
             result = handler() if no_arguments else handler(arguments)
         if isinstance(result, Awaitable):

+ 16 - 0
tests/test_events.py

@@ -1,6 +1,8 @@
 import asyncio
 
+import pytest
 from selenium.webdriver.common.by import By
+from typing_extensions import Literal
 
 from nicegui import ui
 from nicegui.events import ClickEventArguments
@@ -158,3 +160,17 @@ def test_throttling_variants(screen: Screen):
     assert events == []
     screen.wait(1.1)
     assert events == [3]
+
+
+@pytest.mark.parametrize('attribute', ['disabled', 'hidden'])
+def test_server_side_validation(screen: Screen, attribute: Literal['disabled', 'hidden']):
+    b = ui.button('Button', on_click=lambda: ui.label('Success'))
+    b.disable() if attribute == 'disabled' else b.set_visibility(False)
+    ui.button('Hack', on_click=lambda: ui.run_javascript(f'''
+        getElement({b.id}).$emit("click", {{"id": {b.id}, "listener_id": "{list(b._event_listeners.keys())[0]}"}});
+    ''', respond=False))
+
+    screen.open('/')
+    screen.click('Hack')
+    screen.wait(0.5)
+    screen.should_not_contain('Success')