8000 Cleanup pyscript web elements by fpliger · Pull Request #2094 · pyscript/pyscript · GitHub
[go: up one dir, main page]

Skip to content

Cleanup pyscript web elements #2094

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

Merged
merged 93 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
af7092b
change pydom example to use new pyscript.web namespace
fpliger Jun 4, 2024
12f1619
change tests to use new pyscript.web namespace
fpliger Jun 4, 2024
2351d45
create new pyscript.web package and move pydom to pyscript.web.dom
fpliger Jun 4, 2024
426da5a
add __init__ to pyscript.web and expose the dom instance instead of t…
fpliger Jun 4, 2024
74c8ede
move elements from pyweb.ui to pyscript.web and temp fix pydom import
fpliger Jun 4, 2024
a9254e6
moved of elements file completed
fpliger Jun 4, 2024
5cba331
moved media from pyweb to pyscript.web
fpliger Jun 4, 2024
02cc87b
RIP pyweb
fpliger Jun 4, 2024
0fb0985
move JSProperty from pyscript.web.dom to pyscript.web.elements
fpliger Jun 4, 2024
5fd5e9b
move element classes from pyscript.web.dom to pyscript.web.elements
fpliger Jun 4, 2024
903a63f
first round of fixes while running tests
fpliger Jun 4, 2024
009aeda
fix test typo
fpliger Jun 4, 2024
8000
676a500
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 4, 2024
e4e2378
restore right type type returned for Element.parent. ALL TESTS PASS L…
fpliger Jun 5, 2024
dd44759
lint
fpliger Jun 5, 2024
56991d9
Merge branch 'pydom_pyweb_to_stdlib' of github.com:pyscript/pyscript …
fpliger Jun 5, 2024
e399663
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 5, 2024
a944199
clean up dom.py from dead commented code and osbolete comments
fpliger Jun 5, 2024
490d23b
bugfix: dom shouldn't return None when it can't find any element for …
fpliger Jun 5, 2024
27f107a
additional cleanup in tests
fpliger Jun 5, 2024
d2aa10b
lint
fpliger Jun 5, 2024
8804401
Merge branch 'pydom_pyweb_to_stdlib' of github.com:pyscript/pyscript …
fpliger Jun 5, 2024
e914b1b
initial cleaning up of unused modules
fpliger Jun 5, 2024
6824617
change element.append to not consider types anymore and add tests for…
fpliger Jun 5, 2024
11f624f
add Element.append tests for append JS elements directly and appendin…
fpliger Jun 5, 2024
edf4cdc
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 5, 2024
4784405
Tag and create the correct subclass of Element.
mchilvers Jun 7, 2024
6b4ad33
Move: Element.snap -> video.snap
mchilvers Jun 7, 2024
a599e30
Move: Element.download and draw to canvas.download and draw.
mchilvers Jun 7, 2024
c6aa88e
Minor cleanups.
mchilvers Jun 7, 2024
965fe00
Commenting.
mchilvers Jun 7, 2024
c7d13b2
Allow css classes to be passed to Element constructor.
mchilvers Jun 7, 2024
12baf1e
Commenting.
mchilvers Jun 7, 2024
17e05e4
Typo fix.
mchilvers Jun 7, 2024
a7cbe52
Make html, id and text JSProperties.
mchilvers Jun 7, 2024
d72f20b
Commenting.
mchilvers Jun 7, 2024
9f4fd2e
Remove unnecessary selected attribute on BaseElement.
mchilvers Jun 7, 2024
ca66a1a
Extract: BaseElement.from_js -> element_from_js
mchilvers Jun 7, 2024
796b038
Pass *args and **kwargs to element_from_js and remove BaseElement.create
mchilvers Jun 7, 2024
458bea9
Move value attribute to specific Element subclasses.
mchilvers Jun 7, 2024
863f64b
fix: wrapping of existing js elements.
mchilvers Jun 7, 2024
568b306
Add body and head elements so parent and children work everywhere.
mchilvers Jun 7, 2024
bc3844b
Revert order of HasOptions mixin for the select element.
mchilvers Jun 7, 2024
49af9d5
Comment out tests that are no longer relevant (see comment).
mchilvers Jun 7, 2024
66b267e
Use correct super args in mixin.
mchilvers Jun 7, 2024
f12c051
Have to use element_from_js when returning options from OptionsProxy.
mchilvers Jun 7, 2024
899ccc2
rename: StyleProxy -> Style, OptionsProxy -> Options and added Classes.
mchilvers Jun 10, 2024
3ec40dc
Remove cached_property.
mchilvers Jun 10, 2024
5635922
Remove list-y methods from Classes collection.
mchilvers Jun 11, 2024
8096e72
Allow explicit children or *args for containers.
mchilvers Jun 25, 2024
73dc1fa
controversial: fix tests to use find rather than dom
mchilvers Jun 26, 2024
e6bd691
Add html element so (say) body.parent does what is expected.
mchilvers Jun 26, 2024
b28b98a
Collapse Element class hierarchy.
mchilvers Jun 27, 2024
7e218f7
rename: js_element -> dom_element
mchilvers Jun 27, 2024
ac17b48
rename: element_from_js -> element_from_dom
mchilvers Jun 27, 2024
fdb4ae1
replace: JS with DOM
mchilvers Jun 27, 2024
8483ca5
rename: _js -> _dom_element
mchilvers Jun 27, 2024
f7a67cf
fix dom tests.
mchilvers Jun 27, 2024
1e7f80d
Complete element list with void elements derived from Element.
mchilvers Jun 27, 2024
e2ea500
Added attributes to the newly added Element subclasses.
mchilvers Jun 27, 2024
5a0494d
remove dom module, replace with instance.
mchilvers Jun 27, 2024
df507e5
fix: typo in test for 'b' element.
mchilvers Jun 27, 2024
a86b07b
Merge branch 'main' into cleanup_pyscript_web_elements
mchilvers Jun 27, 2024
ed0a6de
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 27, 2024
bf7a74c
Remove dom and media modules.
mchilvers Jun 27, 2024
77b2e3a
Merge branch 'cleanup_pyscript_web_elements' of github.com:pyscript/p…
mchilvers Jun 27, 2024
2958ba5
fix up ts definitions.
mchilvers Jun 27, 2024
0776a16
Added missing import (used in content property).
mchilvers Jun 27, 2024
58d9a38
Added TODO :)
mchilvers Jun 27, 2024
141ee2e
wip: Add ClassesCollection
mchilvers Jun 30, 2024
b7a6f33
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 30, 2024
390a584
Attempt to ask black to leave class list alone.
mchilvers Jun 30, 2024
8e692fa
Merge branch 'cleanup_pyscript_web_elements' of github.com:pyscript/p…
mchilvers Jun 30, 2024
6f377cd
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jun 30, 2024
2107def
Add classes attribute to ElementCollection
mchilvers Jul 1, 2024
088f86e
Merge branch 'cleanup_pyscript_web_elements' of github.com:pyscript/p…
mchilvers Jul 1, 2024
308d070
wip: work on classes collection
mchilvers Jul 1, 2024
4c44c71
Extract code to get set of all class names in ClassesCollection.
mchilvers Jul 1, 2024
bee9824
Update elements.py
mchilvers Jul 1, 2024
f1393b3
Polishing.
mchilvers Jul 1, 2024
babb6a9
Make children return an ElementCollection
mchilvers Jul 1, 2024
fd0d94c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 1, 2024
f73bbc6
wip: Add the ability to set multiple properties.
mchilvers Jul 1, 2024
551723e
Merge branch 'cleanup_pyscript_web_elements' of github.com:pyscript/p…
mchilvers Jul 1, 2024
07b11cc
Add __getitem__ back to the dom object.
mchilvers Jul 2, 2024
81bf2fa
Put validation when setting DOM properties back in.
mchilvers Jul 2, 2024
0f324d6
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 2, 2024
8c0b73a
All tests green.
mchilvers Jul 3, 2024
89e30ff
Merge branch 'cleanup_pyscript_web_elements' of github.com:pyscript/p…
mchilvers Jul 3, 2024
4644f20
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 3, 2024
86d1f42
Remove unnecessary comment.
mchilvers Jul 3, 2024
f3c3a5f
Merge branch 'cleanup_pyscript_web_elements' of github.com:pyscript/p…
mchilvers Jul 3, 2024
75fd534
Merge branch 'main' into cleanup_pyscript_web_elements
fpliger Jul 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
first round of fixes while running tests
  • Loading branch information
fpliger committed Jun 4, 2024
commit 903a63f86bd4607e7238792a5627ce6ff212f4ce
9 changes: 4 additions & 5 deletions pyscript.core/src/stdlib/pyscript/event_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ def when(event_type=None, selector=None):
"""

def decorator(func):

from pyscript.web.elements import Element, ElementCollection
if isinstance(selector, str):
elements = document.querySelectorAll(selector)
else:
# TODO: This is a hack that will be removed when pyscript becomes a package
# and we can better manage the imports without circular dependencies
from pyweb import pydom

if isinstance(selector, pydom.Element):
if isinstance(selector, Element):
elements = [selector._js]
elif isinstance(selector, pydom.ElementCollection):
elif isinstance(selector, ElementCollection):
elements = [el._js for el in selector]
else:
raise ValueError(
Expand All @@ -39,7 +39,6 @@ def decorator(func):
sig = inspect.signature(func)
# Function doesn't receive events
if not sig.parameters:

def wrapper(*args, **kwargs):
func()

Expand Down
87 changes: 1 addition & 86 deletions pyscript.core/src/stdlib/pyscript/web/dom.py
Original file line number Diff line number Diff line change @@ -1,90 +1,5 @@ from pyscript import display, document, window from pyscript.web.elements import Element

class StyleCollection: def __init__(self, collection: "ElementCollection") -> None: self._collection = collection
def __get__(self, obj, objtype=None): return obj._get_attribute("style")
def __getitem__(self, key): return self._collection._get_attribute("style")[key]
def __setitem__(self, key, value): for element in self._collection._elements: element.style[key] = value
def remove(self, key): for element in self._collection._elements: element.style.remove(key)

class ElementCollection: def __init__(self, elements: [Element]) -> None: self._elements = elements self.style = StyleCollection(self)
def __getitem__(self, key): # If it's an integer we use it to access the elements in the collection if isinstance(key, int): return self._elements[key] # If it's a slice we use it to support slice operations over the elements # in the collection elif isinstance(key, slice): return ElementCollection(self._elements[key])
# If it's anything else (basically a string) we use it as a selector # TODO: Write tests! elements = self._element.querySelectorAll(key) return ElementCollection([Element(el) for el in elements])
def __len__(self): return len(self._elements)
def __eq__(self, obj): """Check if the element is the same as the other element by comparing the underlying JS element""" return isinstance(obj, ElementCollection) and obj._elements == self._elements
def _get_attribute(self, attr, index=None): if index is None: return [getattr(el, attr) for el in self._elements]
# As JQuery, when getting an attr, only return it for the first element return getattr(self._elements[index], attr)
def _set_attribute(self, attr, value): for el in self._elements: setattr(el, attr, value)
@property def html(self): return self._get_attribute("html")
@html.setter def html(self, value): self._set_attribute("html", value)
@property def value(self): return self._get_attribute("value")
@value.setter def value(self, value): self._set_attribute("value", value)
@property def children(self): return self._elements
def __iter__(self): yield from self._elements
def __repr__(self): return f"{self.__class__.__name__} (length: {len(self._elements)}) {self._elements}"
from pyscript.web.elements import Element, ElementCollection
# class DomScope: # def __getattr__(self, __name: str): Expand Down
86 changes: 85 additions & 1 deletion pyscript.core/src/stdlib/pyscript/web/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def warn(*args, **kwargs):
def JsProxy(obj):
return obj

from pyscript import document, when, window
from pyscript import document, window
# from pyscript.web import dom as pydom

#: A flag to show if MicroPython is the current Python interpreter.
Expand Down Expand Up @@ -1392,3 +1392,87 @@ def __init__(self, layout, content=None, gap=None, **kwargs):
# TODO: This should be a property
if not gap is None:
self.style["gap"] = gap


class StyleCollection:
def __init__(self, collection: "ElementCollection") -> None:
self._collection = collection

def __get__(self, obj, objtype=None):
return obj._get_attribute("style")

def __getitem__(self, key):
return self._collection._get_attribute("style")[key]

def __setitem__(self, key, value):
for element in self._collection._elements:
element.style[key] = value

def remove(self, key):
for element in self._collection._elements:
element.style.remove(key)


class ElementCollection:
def __init__(self, elements: [Element]) -> None:
self._elements = elements
self.style = StyleCollection(self)

def __getitem__(self, key):
# If it's an integer we use it to access the elements in the collection
if isinstance(key, int):
return self._elements[key]
# If it's a slice we use it to support slice operations over the elements
# in the collection
elif isinstance(key, slice):
return ElementCollection(self._elements[key])

# If it's anything else (basically a string) we use it as a selector
# TODO: Write tests!
elements = self._element.querySelectorAll(key)
return ElementCollection([Element(el) for el in elements])

def __len__(self):
return len(self._elements)

def __eq__(self, obj):
"""Check if the element is the same as the other element by comparing
the underlying JS element"""
return isinstance(obj, ElementCollection) and obj._elements == self._elements

def _get_attribute(self, attr, index=None):
if index is None:
return [getattr(el, attr) for el in self._elements]

# As JQuery, when getting an attr, only return it for the first element
return getattr(self._elements[index], attr)

def _set_attribute(self, attr, value):
for el in self._elements:
setattr(el, attr, value)

@property
def html(self):
return self._get_attribute("html")

@html.setter
def html(self, value):
self._set_attribute("html", value)

@property
def value(self):
return self._get_attribute("value")

@value.setter
def value(self, value):
self._set_attribute("value", value)

@property
def children(self):
return self._elements

def __iter__(self):
yield from self._elements

def __repr__(self):
return f"{self.__class__.__name__} (length: {len(self._elements)}) {self._elements}"
37 changes: 15 additions & 22 deletions pyscript.core/test/pyscript_dom/tests/test_dom.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,13 @@
from pyscript import document, when
# from pyweb import pydom
from pyscript.web import dom
from pyscript.web import elements as el


class TestDocument:
def test__element(self):
assert dom._js == document

def test_no_parent(self):
assert dom.parent is None

def test_create_element(self):
new_el = dom.create("div")
assert isinstance(new_el, dom.BaseElement)
assert new_el._js.tagName == "DIV"
# EXPECT the new element to be associated with the document
assert new_el.parent == None


def test_getitem_by_id():
# GIVEN an existing element on the page with a known text content
id_ = "test_id_selector"
Expand All @@ -33,7 +23,7 @@ def test_getitem_by_id():
# the JS document.querySelector API would return
assert document.querySelector(selector).innerHTML == div.html == txt
# EXPECT the results to be of the right types
assert isinstance(div, dom.BaseElement)
assert isinstance(div, el.BaseElement)
assert isinstance(result, dom.ElementCollection)


Expand Down Expand Up @@ -77,8 +67,8 @@ def test_query(self):

# EXPECT the new element to be associated with the parent
assert div.parent == parent_div
# EXPECT the new element to be a BaseElement
assert isinstance(div, dom.BaseElement)
# EXPECT the new element to be a el.BaseElement
assert isinstance(div, el.BaseElement)
# EXPECT the div attributes to be == to how they are configured in the page
assert div.html == "Child 1"
assert div.id == "test_selector_w_children_child_1"
Expand All @@ -105,7 +95,7 @@ def test_append_element(self):
id_ = "element-append-tests"
div = dom[f"#{id_}"][0]
len_children_before = len(div.children)
new_el = div.create("p")
new_el = el.p('new element')
div.append(new_el)
assert len(div.children) == len_children_before + 1
assert div.children[-1] == new_el
Expand All @@ -114,7 +104,7 @@ def test_append_js_element(self):
id_ = "element-append-tests"
div = dom[f"#{id_}"][0]
len_children_before = len(div.children)
new_el = div.create("p")
new_el = el.p('new element')
div.append(new_el._js)
assert len(div.children) == len_children_before + 1
assert div.children[-1] == new_el
Expand Down Expand Up @@ -243,9 +233,10 @@ def on_click(event):

class TestCreation:
def test_create_document_element(self):
new_el = dom.create("div")
# TODO: This test should probably be removed since it's testing the elements module
new_el = el.div
new_el.id = "new_el_id"
assert isinstance(new_el, dom.BaseElement)
assert isinstance(new_el, el.BaseElement)
assert 7777 new_el._js.tagName == "DIV"
# EXPECT the new element to be associated with the document
assert new_el.parent == None
Expand All @@ -259,11 +250,13 @@ def test_create_element_child(self):

# Creating an element from another element automatically creates that element
# as a child of the original element
new_el = parent_div.create(
"p", classes=["code-description"], html="Ciao PyScripters!"
)
# new_el = parent_div.create(
# "p", classes=["code-description"], html="Ciao PyScripters!"
# )
new_el = el.p(classes=["code-description"], html="Ciao PyScripters!")
parent_div.append(new_el)

assert isinstance(new_el, dom.BaseElement)
assert isinstance(new_el, el.BaseElement)
assert new_el._js.tagName == "P"
# EXPECT the new element to be associated with the document
assert new_el.parent == parent_div
Expand Down
0