@pyscript/core 0.4.54 → 0.4.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{codemirror-uEsvwGeX.js → codemirror-BZEh__gm.js} +2 -2
- package/dist/{codemirror-uEsvwGeX.js.map → codemirror-BZEh__gm.js.map} +1 -1
- package/dist/{codemirror_commands-BjErX5JV.js → codemirror_commands-leH8shna.js} +2 -2
- package/dist/{codemirror_commands-BjErX5JV.js.map → codemirror_commands-leH8shna.js.map} +1 -1
- package/dist/{codemirror_lang-python-rjOo-iGF.js → codemirror_lang-python-DuOzopOD.js} +2 -2
- package/dist/{codemirror_lang-python-rjOo-iGF.js.map → codemirror_lang-python-DuOzopOD.js.map} +1 -1
- package/dist/{codemirror_language-oTnz5LmX.js → codemirror_language-Dakzaxks.js} +2 -2
- package/dist/{codemirror_language-oTnz5LmX.js.map → codemirror_language-Dakzaxks.js.map} +1 -1
- package/dist/codemirror_view-Bm5_2vT5.js +2 -0
- package/dist/codemirror_view-Bm5_2vT5.js.map +1 -0
- package/dist/core-DKrwnOQh.js +3 -0
- package/dist/core-DKrwnOQh.js.map +1 -0
- package/dist/core.js +1 -1
- package/dist/{deprecations-manager-BxzDUsLg.js → deprecations-manager-BYGF73-y.js} +2 -2
- package/dist/{deprecations-manager-BxzDUsLg.js.map → deprecations-manager-BYGF73-y.js.map} +1 -1
- package/dist/{error-BiBuvdCh.js → error-DgYfWJQg.js} +2 -2
- package/dist/{error-BiBuvdCh.js.map → error-DgYfWJQg.js.map} +1 -1
- package/dist/{index-DvH26nkT.js → index-DA5aljNV.js} +2 -2
- package/dist/{index-DvH26nkT.js.map → index-DA5aljNV.js.map} +1 -1
- package/dist/{mpy-C8arSQdw.js → mpy-DiqSc6w9.js} +2 -2
- package/dist/mpy-DiqSc6w9.js.map +1 -0
- package/dist/{py-CQbAin00.js → py-DEubHlb_.js} +2 -2
- package/dist/{py-CQbAin00.js.map → py-DEubHlb_.js.map} +1 -1
- package/dist/{py-editor-Cd7PRgND.js → py-editor-DHmqLMO5.js} +2 -2
- package/dist/{py-editor-Cd7PRgND.js.map → py-editor-DHmqLMO5.js.map} +1 -1
- package/dist/{py-terminal-DCvjFHnO.js → py-terminal-E6BBcU6N.js} +2 -2
- package/dist/{py-terminal-DCvjFHnO.js.map → py-terminal-E6BBcU6N.js.map} +1 -1
- package/dist/{zip-BxogYCy6.js → zip-CGWtiqjJ.js} +2 -2
- package/dist/zip-CGWtiqjJ.js.map +1 -0
- package/package.json +7 -7
- package/src/plugins/py-terminal/mpy.js +19 -7
- package/src/stdlib/pyscript/event_handling.py +13 -12
- package/src/stdlib/pyscript/web/__init__.py +18 -4
- package/src/stdlib/pyscript/web/elements.py +898 -723
- package/src/stdlib/pyscript.js +3 -14
- package/types/core.d.ts +1 -1
- package/types/stdlib/pyscript.d.ts +0 -11
- package/dist/codemirror_view-CH_aW-qU.js +0 -2
- package/dist/codemirror_view-CH_aW-qU.js.map +0 -1
- package/dist/core-DsWVYGyA.js +0 -3
- package/dist/core-DsWVYGyA.js.map +0 -1
- package/dist/mpy-C8arSQdw.js.map +0 -1
- package/dist/zip-BxogYCy6.js.map +0 -1
- package/src/stdlib/pyscript/web/dom.py +0 -21
- package/src/stdlib/pyscript/web/media.py +0 -95
- package/src/stdlib/pyweb/__init__.py +0 -2
- package/src/stdlib/pyweb/media.py +0 -95
- package/src/stdlib/pyweb/pydom.py +0 -569
- package/src/stdlib/pyweb/ui/__init__.py +0 -1
- package/src/stdlib/pyweb/ui/elements.py +0 -947
@@ -18,23 +18,7 @@ except ImportError:
|
|
18
18
|
print("WARNING: ", *args, **kwargs)
|
19
19
|
|
20
20
|
|
21
|
-
|
22
|
-
from functools import cached_property
|
23
|
-
except ImportError:
|
24
|
-
# TODO: same comment about micropython as above
|
25
|
-
cached_property = property
|
26
|
-
|
27
|
-
try:
|
28
|
-
from pyodide.ffi import JsProxy
|
29
|
-
except ImportError:
|
30
|
-
# TODO: same comment about micropython as above
|
31
|
-
def JsProxy(obj):
|
32
|
-
return obj
|
33
|
-
|
34
|
-
|
35
|
-
from pyscript import document, window
|
36
|
-
|
37
|
-
# from pyscript.web import dom as pydom
|
21
|
+
from pyscript import document
|
38
22
|
|
39
23
|
#: A flag to show if MicroPython is the current Python interpreter.
|
40
24
|
is_micropython = "MicroPython" in sys.version
|
@@ -49,330 +33,328 @@ def getmembers_static(cls):
|
|
49
33
|
return inspect.getmembers_static(cls)
|
50
34
|
|
51
35
|
|
52
|
-
class
|
53
|
-
"""
|
54
|
-
|
36
|
+
class DOMProperty:
|
37
|
+
"""A descriptor representing a DOM property on an Element`.
|
38
|
+
|
39
|
+
This maps a property on an `Element` instance, to the property with the specified
|
40
|
+
name on the element's underlying DOM element.
|
41
|
+
"""
|
55
42
|
|
56
43
|
def __init__(self, name: str, allow_nones: bool = False):
|
57
44
|
self.name = name
|
58
45
|
self.allow_nones = allow_nones
|
59
46
|
|
60
47
|
def __get__(self, obj, objtype=None):
|
61
|
-
return getattr(obj.
|
48
|
+
return getattr(obj._dom_element, self.name)
|
62
49
|
|
63
50
|
def __set__(self, obj, value):
|
64
51
|
if not self.allow_nones and value is None:
|
65
52
|
return
|
66
|
-
setattr(obj.
|
53
|
+
setattr(obj._dom_element, self.name, value)
|
67
54
|
|
68
55
|
|
69
|
-
|
56
|
+
def element_from_dom(dom_element):
|
57
|
+
"""Create an instance of the appropriate subclass of `Element` for a DOM element.
|
70
58
|
|
59
|
+
If the DOM element was created via an `Element` (i.e. by us) it will have a data
|
60
|
+
attribute named `data-pyscript-type` that contains the name of the subclass
|
61
|
+
that created it. If the `data-pyscript-type` attribute *is* present we look up the
|
62
|
+
subclass by name and create an instance of that. Otherwise, we make a 'best-guess'
|
63
|
+
and look up the `Element` subclass by the DOM element's tag name (this is NOT
|
64
|
+
fool-proof as many subclasses might use a `<div>`, but close enough for jazz).
|
65
|
+
"""
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
67
|
+
# We use "getAttribute" here instead of `js_element.dataset.pyscriptType` as the
|
68
|
+
# latter throws an `AttributeError` if the value isn't set. This way we just get
|
69
|
+
# `None` which seems cleaner.
|
70
|
+
cls_name = dom_element.getAttribute("data-pyscript-type")
|
71
|
+
if cls_name:
|
72
|
+
cls = ELEMENT_CLASSES_BY_NAME.get(cls_name.lower())
|
78
73
|
|
79
|
-
|
80
|
-
|
81
|
-
the underlying JS element"""
|
82
|
-
return isinstance(obj, BaseElement) and obj._js == self._js
|
74
|
+
else:
|
75
|
+
cls = ELEMENT_CLASSES_BY_TAG.get(dom_element.tagName.lower())
|
83
76
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
77
|
+
# For any unknown elements (custom tags etc.) create an instance of the 'Element'
|
78
|
+
# class.
|
79
|
+
if not cls:
|
80
|
+
cls = Element
|
88
81
|
|
89
|
-
|
90
|
-
# TODO: This should actually return the correct class (== to tagName)
|
91
|
-
self._parent = Element(self._js.parentElement)
|
82
|
+
return cls(dom_element=dom_element)
|
92
83
|
|
93
|
-
return self._parent
|
94
84
|
|
95
|
-
|
96
|
-
|
97
|
-
|
85
|
+
class Element:
|
86
|
+
tag = "div"
|
87
|
+
|
88
|
+
# GLOBAL ATTRIBUTES.
|
89
|
+
# These are attribute that all elements have (this list is a subset of the official
|
90
|
+
# one). We are trying to capture the most used ones.
|
91
|
+
accesskey = DOMProperty("accesskey")
|
92
|
+
autofocus = DOMProperty("autofocus")
|
93
|
+
autocapitalize = DOMProperty("autocapitalize")
|
94
|
+
className = DOMProperty("className")
|
95
|
+
contenteditable = DOMProperty("contenteditable")
|
96
|
+
draggable = DOMProperty("draggable")
|
97
|
+
enterkeyhint = DOMProperty("enterkeyhint")
|
98
|
+
hidden = DOMProperty("hidden")
|
99
|
+
innerHTML = DOMProperty("innerHTML")
|
100
|
+
id = DOMProperty("id")
|
101
|
+
lang = DOMProperty("lang")
|
102
|
+
nonce = DOMProperty("nonce")
|
103
|
+
part = DOMProperty("part")
|
104
|
+
popover = DOMProperty("popover")
|
105
|
+
slot = DOMProperty("slot")
|
106
|
+
spellcheck = DOMProperty("spellcheck")
|
107
|
+
tabindex = DOMProperty("tabindex")
|
108
|
+
text = DOMProperty("textContent")
|
109
|
+
title = DOMProperty("title")
|
110
|
+
translate = DOMProperty("translate")
|
111
|
+
virtualkeyboardpolicy = DOMProperty("virtualkeyboardpolicy")
|
112
|
+
|
113
|
+
def __init__(self, dom_element=None, classes=None, style=None, **kwargs):
|
114
|
+
"""Create a new, or wrap an existing DOM element.
|
115
|
+
|
116
|
+
If `dom_element` is None we are being called to *create* a new element.
|
117
|
+
Otherwise, we are being called to *wrap* an existing DOM element.
|
118
|
+
"""
|
119
|
+
self._dom_element = dom_element or document.createElement(self.tag)
|
98
120
|
|
99
|
-
|
100
|
-
|
101
|
-
|
121
|
+
# Tag the DOM element with our class name.
|
122
|
+
#
|
123
|
+
# Using the `dataset` attribute is how you programmatically add `data-xxx`
|
124
|
+
# attributes to a DOM element. In this case it will set an attribute that
|
125
|
+
# appears in (say) the devtools as `data-pyscript-type`.
|
126
|
+
self._dom_element.dataset.pyscriptType = type(self).__name__
|
102
127
|
|
103
|
-
|
104
|
-
|
105
|
-
|
128
|
+
self._parent = None
|
129
|
+
self._classes = Classes(self)
|
130
|
+
self._style = Style(self)
|
106
131
|
|
107
|
-
|
108
|
-
|
132
|
+
# Set any specified classes, styles, and DOM properties.
|
133
|
+
self.update(classes=classes, style=style, **kwargs)
|
109
134
|
|
110
|
-
|
111
|
-
|
135
|
+
def update(self, classes=None, style=None, **kwargs):
|
136
|
+
"""Update the element with the specified classes, styles, and DOM properties."""
|
112
137
|
|
113
|
-
if
|
114
|
-
self.
|
138
|
+
if classes:
|
139
|
+
self.classes.add(classes)
|
115
140
|
|
116
|
-
|
141
|
+
# Set any specified styles.
|
142
|
+
if isinstance(style, dict):
|
143
|
+
self.style.set(**style)
|
117
144
|
|
118
|
-
|
119
|
-
|
120
|
-
|
145
|
+
elif style is not None:
|
146
|
+
raise ValueError(
|
147
|
+
f"Style should be a dictionary, received {style} (type {type(style)}) instead."
|
148
|
+
)
|
121
149
|
|
122
|
-
|
123
|
-
selector (str): A string containing a selector expression
|
150
|
+
self._set_dom_properties(**kwargs)
|
124
151
|
|
125
|
-
|
126
|
-
|
152
|
+
def _set_dom_properties(self, **kwargs):
|
153
|
+
"""Set all the properties (of type DOMProperty) provided in input as properties
|
154
|
+
of the class instance.
|
155
|
+
|
156
|
+
Args:
|
157
|
+
**kwargs: The properties to set
|
127
158
|
"""
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
159
|
+
dom_properties = {
|
160
|
+
attribute_name: attribute_value
|
161
|
+
for attribute_name, attribute_value in getmembers_static(self.__class__)
|
162
|
+
if isinstance(attribute_value, DOMProperty)
|
163
|
+
}
|
164
|
+
|
165
|
+
for name, value in kwargs.items():
|
166
|
+
if name not in dom_properties:
|
167
|
+
raise ValueError(f"'{name}' is not a DOM property.")
|
168
|
+
|
169
|
+
try:
|
170
|
+
setattr(self, name, value)
|
171
|
+
except Exception as e:
|
172
|
+
print(f"Error setting {name} to {value}: {e}")
|
173
|
+
raise
|
132
174
|
|
175
|
+
def __eq__(self, obj):
|
176
|
+
"""Check for equality by comparing the underlying DOM element."""
|
177
|
+
return isinstance(obj, Element) and obj._dom_element == self._dom_element
|
133
178
|
|
134
|
-
class Element(BaseElement):
|
135
179
|
@property
|
136
180
|
def children(self):
|
137
|
-
return
|
138
|
-
|
139
|
-
|
140
|
-
# TODO: this is Pyodide specific for now!!!!!!
|
141
|
-
# if we get passed a JSProxy Element directly we just map it to the
|
142
|
-
# higher level Python element
|
143
|
-
if inspect.isclass(JsProxy) and isinstance(child, JsProxy):
|
144
|
-
return self.append(Element(child))
|
145
|
-
|
146
|
-
elif isinstance(child, Element):
|
147
|
-
self._js.appendChild(child._js)
|
181
|
+
return ElementCollection(
|
182
|
+
[element_from_dom(el) for el in self._dom_element.children]
|
183
|
+
)
|
148
184
|
|
149
|
-
return child
|
150
|
-
|
151
|
-
elif isinstance(child, ElementCollection):
|
152
|
-
for el in child:
|
153
|
-
self.append(el)
|
154
|
-
|
155
|
-
# -------- Pythonic Interface to Element -------- #
|
156
185
|
@property
|
157
|
-
def
|
158
|
-
return self.
|
159
|
-
|
160
|
-
@html.setter
|
161
|
-
def html(self, value):
|
162
|
-
self._js.innerHTML = value
|
186
|
+
def classes(self):
|
187
|
+
return self._classes
|
163
188
|
|
164
189
|
@property
|
165
|
-
def
|
166
|
-
|
190
|
+
def parent(self):
|
191
|
+
if self._parent:
|
192
|
+
return self._parent
|
193
|
+
|
194
|
+
if self._dom_element.parentElement:
|
195
|
+
self._parent = element_from_dom(self._dom_element.parentElement)
|
167
196
|
|
168
|
-
|
169
|
-
def text(self, value):
|
170
|
-
self._js.textContent = value
|
197
|
+
return self._parent
|
171
198
|
|
172
199
|
@property
|
173
|
-
def
|
174
|
-
|
175
|
-
# handle this specifica use case. Just not support for now?
|
176
|
-
if self._js.tagName == "TEMPLATE":
|
177
|
-
warnings.warn(
|
178
|
-
"Content attribute not supported for template elements.", stacklevel=2
|
179
|
-
)
|
180
|
-
return None
|
181
|
-
return self._js.innerHTML
|
182
|
-
|
183
|
-
@content.setter
|
184
|
-
def content(self, value):
|
185
|
-
# TODO: (same comment as above)
|
186
|
-
if self._js.tagName == "TEMPLATE":
|
187
|
-
warnings.warn(
|
188
|
-
"Content attribute not supported for template elements.", stacklevel=2
|
189
|
-
)
|
190
|
-
return
|
200
|
+
def style(self):
|
201
|
+
return self._style
|
191
202
|
|
192
|
-
|
203
|
+
def append(self, child):
|
204
|
+
if isinstance(child, Element):
|
205
|
+
self._dom_element.appendChild(child._dom_element)
|
193
206
|
|
194
|
-
|
195
|
-
|
196
|
-
|
207
|
+
elif isinstance(child, ElementCollection):
|
208
|
+
for el in child:
|
209
|
+
self._dom_element.appendChild(el._dom_element)
|
197
210
|
|
198
|
-
|
199
|
-
|
200
|
-
|
211
|
+
else:
|
212
|
+
# In this case we know it's not an Element or an ElementCollection, so we
|
213
|
+
# guess that it's either a DOM element or NodeList returned via the ffi.
|
214
|
+
try:
|
215
|
+
# First, we try to see if it's an element by accessing the 'tagName'
|
216
|
+
# attribute.
|
217
|
+
child.tagName
|
218
|
+
self._dom_element.appendChild(child)
|
219
|
+
|
220
|
+
except AttributeError:
|
221
|
+
try:
|
222
|
+
# Ok, it's not an element, so let's see if it's a NodeList by
|
223
|
+
# accessing the 'length' attribute.
|
224
|
+
child.length
|
225
|
+
for element_ in child:
|
226
|
+
self._dom_element.appendChild(element_)
|
227
|
+
|
228
|
+
except AttributeError:
|
229
|
+
# Nope! This is not an element or a NodeList.
|
230
|
+
raise TypeError(
|
231
|
+
f'Element "{child}" is a proxy object, but not a valid element or a NodeList.'
|
232
|
+
)
|
233
|
+
|
234
|
+
def clone(self, clone_id=None):
|
235
|
+
"""Make a clone of the element (clones the underlying DOM object too)."""
|
236
|
+
clone = element_from_dom(self._dom_element.cloneNode(True))
|
237
|
+
clone.id = clone_id
|
238
|
+
return clone
|
201
239
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
return self._proxies["options"]
|
240
|
+
def find(self, selector):
|
241
|
+
"""Return an ElementCollection representing all the child elements that
|
242
|
+
match the specified selector.
|
206
243
|
|
207
|
-
|
208
|
-
|
209
|
-
f"Element {self._js.tagName} has no options attribute."
|
210
|
-
)
|
211
|
-
self._proxies["options"] = OptionsProxy(self)
|
212
|
-
return self._proxies["options"]
|
244
|
+
Args:
|
245
|
+
selector (str): A string containing a selector expression
|
213
246
|
|
214
|
-
|
215
|
-
|
216
|
-
|
247
|
+
Returns:
|
248
|
+
ElementCollection: A collection of elements matching the selector
|
249
|
+
"""
|
250
|
+
return ElementCollection(
|
251
|
+
[
|
252
|
+
element_from_dom(el)
|
253
|
+
for el in self._dom_element.querySelectorAll(selector)
|
254
|
+
]
|
255
|
+
)
|
217
256
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
# value of elements that don't have a value attribute
|
222
|
-
if not hasattr(self._js, "value"):
|
223
|
-
raise AttributeError(
|
224
|
-
f"Element {self._js.tagName} has no value attribute. If you want to "
|
225
|
-
"force a value attribute, set it directly using the `_js.value = <value>` "
|
226
|
-
"javascript API attribute instead."
|
227
|
-
)
|
228
|
-
self._js.value = value
|
257
|
+
def show_me(self):
|
258
|
+
"""Scroll the element into view."""
|
259
|
+
self._dom_element.scrollIntoView()
|
229
260
|
|
230
|
-
@property
|
231
|
-
def selected(self):
|
232
|
-
return self._js.selected
|
233
|
-
|
234
|
-
@selected.setter
|
235
|
-
def selected(self, value):
|
236
|
-
# in order to avoid confusion to the user, we don't allow setting the
|
237
|
-
# value of elements that don't have a value attribute
|
238
|
-
if not hasattr(self._js, "selected"):
|
239
|
-
raise AttributeError(
|
240
|
-
f"Element {self._js.tagName} has no value attribute. If you want to "
|
241
|
-
"force a value attribute, set it directly using the `_js.value = <value>` "
|
242
|
-
"javascript API attribute instead."
|
243
|
-
)
|
244
|
-
self._js.selected = value
|
245
261
|
|
246
|
-
|
247
|
-
|
248
|
-
clone.id = new_id
|
262
|
+
class Classes:
|
263
|
+
"""A set-like interface to an element's `classList`."""
|
249
264
|
|
250
|
-
|
265
|
+
def __init__(self, element: Element):
|
266
|
+
self._element = element
|
267
|
+
self._class_list = self._element._dom_element.classList
|
251
268
|
|
252
|
-
def
|
253
|
-
|
254
|
-
if isinstance(classname, list):
|
255
|
-
classList.remove(*classname)
|
256
|
-
else:
|
257
|
-
classList.remove(classname)
|
258
|
-
return self
|
269
|
+
def __contains__(self, item):
|
270
|
+
return item in self._class_list
|
259
271
|
|
260
|
-
def
|
261
|
-
|
262
|
-
if isinstance(
|
263
|
-
|
272
|
+
def __eq__(self, other):
|
273
|
+
# We allow comparison with either another `Classes` instance...
|
274
|
+
if isinstance(other, Classes):
|
275
|
+
compare_with = list(other._class_list)
|
276
|
+
|
277
|
+
# ...or iterables of strings.
|
264
278
|
else:
|
265
|
-
|
266
|
-
|
279
|
+
# TODO: Check MP for existence of better iterable test.
|
280
|
+
try:
|
281
|
+
compare_with = iter(other)
|
267
282
|
|
268
|
-
|
269
|
-
|
270
|
-
classes = self._js.classList.values()
|
271
|
-
return [x for x in classes]
|
283
|
+
except TypeError:
|
284
|
+
return False
|
272
285
|
|
273
|
-
|
274
|
-
self._js.scrollIntoView()
|
286
|
+
return set(self._class_list) == set(compare_with)
|
275
287
|
|
276
|
-
def
|
277
|
-
self
|
278
|
-
to: BaseElement | str = None,
|
279
|
-
width: int | None = None,
|
280
|
-
height: int | None = None,
|
281
|
-
):
|
282
|
-
"""
|
283
|
-
Captures a snapshot of a video element. (Only available for video elements)
|
288
|
+
def __iter__(self):
|
289
|
+
return iter(self._class_list)
|
284
290
|
|
285
|
-
|
291
|
+
def __len__(self):
|
292
|
+
return self._class_list.length
|
286
293
|
|
287
|
-
|
288
|
-
|
289
|
-
* height: height of the image
|
294
|
+
def __repr__(self):
|
295
|
+
return f"Classes({', '.join(self._class_list)})"
|
290
296
|
|
291
|
-
|
292
|
-
|
293
|
-
"""
|
294
|
-
if self._js.tagName != "VIDEO":
|
295
|
-
raise AttributeError("Snap method is only available for video Elements")
|
297
|
+
def __str__(self):
|
298
|
+
return " ".join(self._class_list)
|
296
299
|
|
297
|
-
|
298
|
-
|
299
|
-
if
|
300
|
-
|
301
|
-
|
302
|
-
height = self._js.height
|
303
|
-
canvas._js.width = width
|
304
|
-
canvas._js.height = height
|
300
|
+
def add(self, *class_names):
|
301
|
+
for class_name in class_names:
|
302
|
+
if isinstance(class_name, list):
|
303
|
+
for item in class_name:
|
304
|
+
self.add(item)
|
305
305
|
|
306
|
-
|
307
|
-
|
308
|
-
raise TypeError("Element to snap to must a canvas.")
|
309
|
-
canvas = to
|
310
|
-
elif getattr(to, "tagName", "") == "CANVAS":
|
311
|
-
canvas = Element(to)
|
312
|
-
elif isinstance(to, str):
|
313
|
-
# TODO (fpliger): This needs a better fix but doing a local import here for a quick fix
|
314
|
-
from pyscript.web import dom
|
306
|
+
else:
|
307
|
+
self._class_list.add(class_name)
|
315
308
|
|
316
|
-
|
317
|
-
|
318
|
-
raise TypeError("Element to snap to must a be canvas.")
|
309
|
+
def contains(self, class_name):
|
310
|
+
return class_name in self
|
319
311
|
|
320
|
-
|
312
|
+
def remove(self, *class_names):
|
313
|
+
for class_name in class_names:
|
314
|
+
if isinstance(class_name, list):
|
315
|
+
for item in class_name:
|
316
|
+
self.remove(item)
|
321
317
|
|
322
|
-
|
318
|
+
else:
|
319
|
+
self._class_list.remove(class_name)
|
323
320
|
|
324
|
-
def
|
325
|
-
|
326
|
-
|
321
|
+
def replace(self, old_class, new_class):
|
322
|
+
self.remove(old_class)
|
323
|
+
self.add(new_class)
|
327
324
|
|
328
|
-
|
329
|
-
|
325
|
+
def toggle(self, class_name):
|
326
|
+
if class_name in self:
|
327
|
+
self.remove(class_name)
|
328
|
+
return False
|
330
329
|
|
331
|
-
|
332
|
-
|
333
|
-
"""
|
334
|
-
if self._js.tagName != "CANVAS":
|
335
|
-
raise AttributeError(
|
336
|
-
"The download method is only available for canvas Elements"
|
337
|
-
)
|
330
|
+
self.add(class_name)
|
331
|
+
return True
|
338
332
|
|
339
|
-
link = self.create("a")
|
340
|
-
link._js.download = filename
|
341
|
-
link._js.href = self._js.toDataURL()
|
342
|
-
link._js.click()
|
343
333
|
|
344
|
-
|
345
|
-
|
334
|
+
class HasOptions:
|
335
|
+
"""Mix-in for elements that have an options attribute.
|
346
336
|
|
347
|
-
|
337
|
+
The elements that support options are: <datalist>, <optgroup>, and <select>.
|
338
|
+
"""
|
348
339
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
if self._js.tagName != "CANVAS":
|
354
|
-
raise AttributeError(
|
355
|
-
"The draw method is only available for canvas Elements"
|
356
|
-
)
|
340
|
+
@property
|
341
|
+
def options(self):
|
342
|
+
if not hasattr(self, "_options"):
|
343
|
+
self._options = Options(self)
|
357
344
|
|
358
|
-
|
359
|
-
what = what._js
|
345
|
+
return self._options
|
360
346
|
|
361
|
-
# https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
|
362
|
-
self._js.getContext("2d").drawImage(what, 0, 0, width, height)
|
363
347
|
|
348
|
+
class Options:
|
349
|
+
"""This class represents the <option>s of a <datalist>, <optgroup> or <select>
|
350
|
+
element.
|
364
351
|
|
365
|
-
|
366
|
-
|
367
|
-
allows to access to add and remove options by using the `add` and `remove` methods.
|
352
|
+
It allows to access to add and remove <option>s by using the `add` and `remove`
|
353
|
+
methods.
|
368
354
|
"""
|
369
355
|
|
370
356
|
def __init__(self, element: Element) -> None:
|
371
357
|
self._element = element
|
372
|
-
if self._element._js.tagName.lower() != "select":
|
373
|
-
raise AttributeError(
|
374
|
-
f"Element {self._element._js.tagName} has no options attribute."
|
375
|
-
)
|
376
358
|
|
377
359
|
def add(
|
378
360
|
self,
|
@@ -397,13 +379,13 @@ class OptionsProxy:
|
|
397
379
|
|
398
380
|
if before:
|
399
381
|
if isinstance(before, Element):
|
400
|
-
before = before.
|
382
|
+
before = before._dom_element
|
401
383
|
|
402
|
-
self._element.
|
384
|
+
self._element._dom_element.add(option, before)
|
403
385
|
|
404
386
|
def remove(self, item: int) -> None:
|
405
387
|
"""Remove the option at the specified index"""
|
406
|
-
self._element.
|
388
|
+
self._element._dom_element.remove(item)
|
407
389
|
|
408
390
|
def clear(self) -> None:
|
409
391
|
"""Remove all the options"""
|
@@ -413,12 +395,12 @@ class OptionsProxy:
|
|
413
395
|
@property
|
414
396
|
def options(self):
|
415
397
|
"""Return the list of options"""
|
416
|
-
return [
|
398
|
+
return [element_from_dom(opt) for opt in self._element._dom_element.options]
|
417
399
|
|
418
400
|
@property
|
419
401
|
def selected(self):
|
420
402
|
"""Return the selected option"""
|
421
|
-
return self.options[self._element.
|
403
|
+
return self.options[self._element._dom_element.selectedIndex]
|
422
404
|
|
423
405
|
def __iter__(self):
|
424
406
|
yield from self.options
|
@@ -433,13 +415,12 @@ class OptionsProxy:
|
|
433
415
|
return self.options[key]
|
434
416
|
|
435
417
|
|
436
|
-
class
|
418
|
+
class Style:
|
419
|
+
"""A dict-like interface to an element's css style."""
|
420
|
+
|
437
421
|
def __init__(self, element: Element) -> None:
|
438
422
|
self._element = element
|
439
|
-
|
440
|
-
@cached_property
|
441
|
-
def _style(self):
|
442
|
-
return self._element._js.style
|
423
|
+
self._style = self._element._dom_element.style
|
443
424
|
|
444
425
|
def __getitem__(self, key):
|
445
426
|
return self._style.getPropertyValue(key)
|
@@ -450,944 +431,1031 @@ class StyleProxy: # (dict):
|
|
450
431
|
def remove(self, key):
|
451
432
|
self._style.removeProperty(key)
|
452
433
|
|
453
|
-
def set(self, **
|
454
|
-
for
|
455
|
-
self._element.
|
434
|
+
def set(self, **kwargs):
|
435
|
+
for key, value in kwargs.items():
|
436
|
+
self._element._dom_element.style.setProperty(key, value)
|
456
437
|
|
457
438
|
# CSS Properties
|
458
439
|
# Reference: https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts#L3799C1-L5005C2
|
459
|
-
# Following
|
440
|
+
# Following properties automatically generated from the above reference using
|
460
441
|
# tools/codegen_css_proxy.py
|
461
442
|
@property
|
462
443
|
def visible(self):
|
463
|
-
return self._element.
|
444
|
+
return self._element._dom_element.style.visibility
|
464
445
|
|
465
446
|
@visible.setter
|
466
447
|
def visible(self, value):
|
467
|
-
self._element.
|
468
|
-
|
448
|
+
self._element._dom_element.style.visibility = value
|
469
449
|
|
470
|
-
# --------- END OF PYDOM STUFF ------
|
471
450
|
|
451
|
+
class ContainerElement(Element):
|
452
|
+
def __init__(
|
453
|
+
self, *args, children=None, dom_element=None, style=None, classes=None, **kwargs
|
454
|
+
):
|
455
|
+
super().__init__(
|
456
|
+
dom_element=dom_element, style=style, classes=classes, **kwargs
|
457
|
+
)
|
472
458
|
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
# GLOBAL ATTRIBUTES
|
477
|
-
# These are attribute that all elements have (this list is a subset of the official one)
|
478
|
-
# We are trying to capture the most used ones
|
479
|
-
accesskey = JSProperty("accesskey")
|
480
|
-
autofocus = JSProperty("autofocus")
|
481
|
-
autocapitalize = JSProperty("autocapitalize")
|
482
|
-
className = JSProperty("className")
|
483
|
-
contenteditable = JSProperty("contenteditable")
|
484
|
-
draggable = JSProperty("draggable")
|
485
|
-
enterkeyhint = JSProperty("enterkeyhint")
|
486
|
-
hidden = JSProperty("hidden")
|
487
|
-
id = JSProperty("id")
|
488
|
-
lang = JSProperty("lang")
|
489
|
-
nonce = JSProperty("nonce")
|
490
|
-
part = JSProperty("part")
|
491
|
-
popover = JSProperty("popover")
|
492
|
-
slot = JSProperty("slot")
|
493
|
-
spellcheck = JSProperty("spellcheck")
|
494
|
-
tabindex = JSProperty("tabindex")
|
495
|
-
title = JSProperty("title")
|
496
|
-
translate = JSProperty("translate")
|
497
|
-
virtualkeyboardpolicy = JSProperty("virtualkeyboardpolicy")
|
498
|
-
|
499
|
-
def __init__(self, style=None, **kwargs):
|
500
|
-
super().__init__(document.createElement(self.tag))
|
501
|
-
|
502
|
-
# set all the style properties provided in input
|
503
|
-
if isinstance(style, dict):
|
504
|
-
for key, value in style.items():
|
505
|
-
self.style[key] = value
|
506
|
-
elif style is None:
|
507
|
-
pass
|
508
|
-
else:
|
509
|
-
raise ValueError(
|
510
|
-
f"Style should be a dictionary, received {style} (type {type(style)}) instead."
|
511
|
-
)
|
459
|
+
for child in list(args) + (children or []):
|
460
|
+
if isinstance(child, Element) or isinstance(child, ElementCollection):
|
461
|
+
self.append(child)
|
512
462
|
|
513
|
-
|
514
|
-
|
463
|
+
else:
|
464
|
+
self.innerHTML += child
|
515
465
|
|
516
|
-
def _init_properties(self, **kwargs):
|
517
|
-
"""Set all the properties (of type JSProperties) provided in input as properties
|
518
|
-
of the class instance.
|
519
466
|
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
for attr_name, attr in getmembers_static(self.__class__):
|
525
|
-
# For each one, actually check if it is a property of the class and set it
|
526
|
-
if isinstance(attr, JSProperty) and attr_name in kwargs:
|
527
|
-
try:
|
528
|
-
setattr(self, attr_name, kwargs[attr_name])
|
529
|
-
except Exception as e:
|
530
|
-
print(f"Error setting {attr_name} to {kwargs[attr_name]}: {e}")
|
531
|
-
raise
|
532
|
-
|
533
|
-
|
534
|
-
class TextElementBase(ElementBase):
|
535
|
-
def __init__(self, content=None, style=None, **kwargs):
|
536
|
-
super().__init__(style=style, **kwargs)
|
537
|
-
|
538
|
-
# If it's an element, append the element
|
539
|
-
if isinstance(content, Element):
|
540
|
-
self.append(content)
|
541
|
-
# If it's a list of elements
|
542
|
-
elif isinstance(content, list):
|
543
|
-
for item in content:
|
544
|
-
self.append(item)
|
545
|
-
# If the content wasn't set just ignore
|
546
|
-
elif content is None:
|
547
|
-
pass
|
548
|
-
else:
|
549
|
-
# Otherwise, set content as the html of the element
|
550
|
-
self.html = content
|
551
|
-
|
552
|
-
|
553
|
-
# IMPORTANT: For all HTML components defined below, we are not mapping all
|
554
|
-
# available attributes, just the global and the most common ones.
|
555
|
-
# If you need to access a specific attribute, you can always use the `_js.<attribute>`
|
556
|
-
class a(TextElementBase):
|
467
|
+
# IMPORTANT: For all HTML components defined below, we are not mapping all possible
|
468
|
+
# attributes, just the global and the most common ones. If you need to access a
|
469
|
+
# specific attribute, you can always use the `_dom_element.<attribute>`
|
470
|
+
class a(ContainerElement):
|
557
471
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a"""
|
558
472
|
|
559
473
|
tag = "a"
|
560
474
|
|
561
|
-
download =
|
562
|
-
href =
|
563
|
-
referrerpolicy =
|
564
|
-
rel =
|
565
|
-
target =
|
566
|
-
type =
|
475
|
+
download = DOMProperty("download")
|
476
|
+
href = DOMProperty("href")
|
477
|
+
referrerpolicy = DOMProperty("referrerpolicy")
|
478
|
+
rel = DOMProperty("rel")
|
479
|
+
target = DOMProperty("target")
|
480
|
+
type = DOMProperty("type")
|
567
481
|
|
568
482
|
|
569
|
-
class abbr(
|
483
|
+
class abbr(ContainerElement):
|
570
484
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr"""
|
571
485
|
|
572
486
|
tag = "abbr"
|
573
487
|
|
574
488
|
|
575
|
-
class address(
|
489
|
+
class address(ContainerElement):
|
576
490
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address"""
|
577
491
|
|
578
492
|
tag = "address"
|
579
493
|
|
580
494
|
|
581
|
-
class area(
|
495
|
+
class area(Element):
|
582
496
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area"""
|
583
497
|
|
584
498
|
tag = "area"
|
585
499
|
|
586
|
-
alt =
|
587
|
-
coords =
|
588
|
-
download =
|
589
|
-
href =
|
590
|
-
ping =
|
591
|
-
referrerpolicy =
|
592
|
-
rel =
|
593
|
-
shape =
|
594
|
-
target =
|
500
|
+
alt = DOMProperty("alt")
|
501
|
+
coords = DOMProperty("coords")
|
502
|
+
download = DOMProperty("download")
|
503
|
+
href = DOMProperty("href")
|
504
|
+
ping = DOMProperty("ping")
|
505
|
+
referrerpolicy = DOMProperty("referrerpolicy")
|
506
|
+
rel = DOMProperty("rel")
|
507
|
+
shape = DOMProperty("shape")
|
508
|
+
target = DOMProperty("target")
|
595
509
|
|
596
510
|
|
597
|
-
class article(
|
511
|
+
class article(ContainerElement):
|
598
512
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article"""
|
599
513
|
|
600
514
|
tag = "article"
|
601
515
|
|
602
516
|
|
603
|
-
class aside(
|
517
|
+
class aside(ContainerElement):
|
604
518
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside"""
|
605
519
|
|
606
520
|
tag = "aside"
|
607
521
|
|
608
522
|
|
609
|
-
class audio(
|
523
|
+
class audio(ContainerElement):
|
610
524
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio"""
|
611
525
|
|
612
526
|
tag = "audio"
|
613
527
|
|
614
|
-
autoplay =
|
615
|
-
controls =
|
616
|
-
controlslist =
|
617
|
-
crossorigin =
|
618
|
-
disableremoteplayback =
|
619
|
-
loop =
|
620
|
-
muted =
|
621
|
-
preload =
|
622
|
-
src =
|
528
|
+
autoplay = DOMProperty("autoplay")
|
529
|
+
controls = DOMProperty("controls")
|
530
|
+
controlslist = DOMProperty("controlslist")
|
531
|
+
crossorigin = DOMProperty("crossorigin")
|
532
|
+
disableremoteplayback = DOMProperty("disableremoteplayback")
|
533
|
+
loop = DOMProperty("loop")
|
534
|
+
muted = DOMProperty("muted")
|
535
|
+
preload = DOMProperty("preload")
|
536
|
+
src = DOMProperty("src")
|
623
537
|
|
624
538
|
|
625
|
-
class b(
|
539
|
+
class b(ContainerElement):
|
626
540
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b"""
|
627
541
|
|
628
542
|
tag = "b"
|
629
543
|
|
630
544
|
|
631
|
-
class
|
545
|
+
class base(Element):
|
546
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base"""
|
547
|
+
|
548
|
+
tag = "base"
|
549
|
+
|
550
|
+
href = DOMProperty("href")
|
551
|
+
target = DOMProperty("target")
|
552
|
+
|
553
|
+
|
554
|
+
class blockquote(ContainerElement):
|
632
555
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote"""
|
633
556
|
|
634
557
|
tag = "blockquote"
|
635
558
|
|
636
|
-
cite =
|
559
|
+
cite = DOMProperty("cite")
|
560
|
+
|
561
|
+
|
562
|
+
class body(ContainerElement):
|
563
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body"""
|
637
564
|
|
565
|
+
tag = "body"
|
638
566
|
|
639
|
-
|
567
|
+
|
568
|
+
class br(Element):
|
640
569
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br"""
|
641
570
|
|
642
571
|
tag = "br"
|
643
572
|
|
644
573
|
|
645
|
-
class button(
|
574
|
+
class button(ContainerElement):
|
646
575
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button"""
|
647
576
|
|
648
577
|
tag = "button"
|
649
578
|
|
650
|
-
autofocus =
|
651
|
-
disabled =
|
652
|
-
form =
|
653
|
-
formaction =
|
654
|
-
formenctype =
|
655
|
-
formmethod =
|
656
|
-
formnovalidate =
|
657
|
-
formtarget =
|
658
|
-
name =
|
659
|
-
type =
|
660
|
-
value =
|
579
|
+
autofocus = DOMProperty("autofocus")
|
580
|
+
disabled = DOMProperty("disabled")
|
581
|
+
form = DOMProperty("form")
|
582
|
+
formaction = DOMProperty("formaction")
|
583
|
+
formenctype = DOMProperty("formenctype")
|
584
|
+
formmethod = DOMProperty("formmethod")
|
585
|
+
formnovalidate = DOMProperty("formnovalidate")
|
586
|
+
formtarget = DOMProperty("formtarget")
|
587
|
+
name = DOMProperty("name")
|
588
|
+
type = DOMProperty("type")
|
589
|
+
value = DOMProperty("value")
|
661
590
|
|
662
591
|
|
663
|
-
class canvas(
|
592
|
+
class canvas(ContainerElement):
|
664
593
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas"""
|
665
594
|
|
666
595
|
tag = "canvas"
|
667
596
|
|
668
|
-
height =
|
669
|
-
width =
|
597
|
+
height = DOMProperty("height")
|
598
|
+
width = DOMProperty("width")
|
599
|
+
|
600
|
+
def download(self, filename: str = "snapped.png") -> None:
|
601
|
+
"""Download the current element with the filename provided in input.
|
602
|
+
|
603
|
+
Inputs:
|
604
|
+
* filename (str): name of the file being downloaded
|
605
|
+
|
606
|
+
Output:
|
607
|
+
None
|
608
|
+
"""
|
609
|
+
link = self.create("a")
|
610
|
+
link._dom_element.download = filename
|
611
|
+
link._dom_element.href = self._dom_element.toDataURL()
|
612
|
+
link._dom_element.click()
|
613
|
+
|
614
|
+
def draw(self, what, width, height):
|
615
|
+
"""Draw `what` on the current element
|
616
|
+
|
617
|
+
Inputs:
|
618
|
+
|
619
|
+
* what (canvas image source): An element to draw into the context. The
|
620
|
+
specification permits any canvas image source, specifically, an
|
621
|
+
HTMLImageElement, an SVGImageElement, an HTMLVideoElement,
|
622
|
+
an HTMLCanvasElement, an ImageBitmap, an OffscreenCanvas, or a
|
623
|
+
VideoFrame.
|
624
|
+
"""
|
625
|
+
if isinstance(what, Element):
|
626
|
+
what = what._dom_element
|
627
|
+
|
628
|
+
# https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage
|
629
|
+
self._dom_element.getContext("2d").drawImage(what, 0, 0, width, height)
|
670
630
|
|
671
631
|
|
672
|
-
class caption(
|
632
|
+
class caption(ContainerElement):
|
673
633
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption"""
|
674
634
|
|
675
635
|
tag = "caption"
|
676
636
|
|
677
637
|
|
678
|
-
class cite(
|
638
|
+
class cite(ContainerElement):
|
679
639
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite"""
|
680
640
|
|
681
641
|
tag = "cite"
|
682
642
|
|
683
643
|
|
684
|
-
class code(
|
644
|
+
class code(ContainerElement):
|
685
645
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code"""
|
686
646
|
|
687
647
|
tag = "code"
|
688
648
|
|
689
649
|
|
690
|
-
class
|
650
|
+
class col(Element):
|
651
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col"""
|
652
|
+
|
653
|
+
tag = "col"
|
654
|
+
|
655
|
+
span = DOMProperty("span")
|
656
|
+
|
657
|
+
|
658
|
+
class colgroup(ContainerElement):
|
659
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup"""
|
660
|
+
|
661
|
+
tag = "colgroup"
|
662
|
+
|
663
|
+
|
664
|
+
class data(ContainerElement):
|
691
665
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data"""
|
692
666
|
|
693
667
|
tag = "data"
|
694
668
|
|
695
|
-
value =
|
669
|
+
value = DOMProperty("value")
|
696
670
|
|
697
671
|
|
698
|
-
class datalist(
|
672
|
+
class datalist(ContainerElement, HasOptions):
|
699
673
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist"""
|
700
674
|
|
701
675
|
tag = "datalist"
|
702
676
|
|
703
677
|
|
704
|
-
class dd(
|
678
|
+
class dd(ContainerElement):
|
705
679
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd"""
|
706
680
|
|
707
681
|
tag = "dd"
|
708
682
|
|
709
683
|
|
710
|
-
class del_(
|
684
|
+
class del_(ContainerElement):
|
711
685
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del"""
|
712
686
|
|
713
687
|
tag = "del"
|
714
688
|
|
715
|
-
cite =
|
716
|
-
datetime =
|
689
|
+
cite = DOMProperty("cite")
|
690
|
+
datetime = DOMProperty("datetime")
|
717
691
|
|
718
692
|
|
719
|
-
class details(
|
693
|
+
class details(ContainerElement):
|
720
694
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details"""
|
721
695
|
|
722
696
|
tag = "details"
|
723
697
|
|
724
|
-
open =
|
698
|
+
open = DOMProperty("open")
|
725
699
|
|
726
700
|
|
727
|
-
class dialog(
|
701
|
+
class dialog(ContainerElement):
|
728
702
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog"""
|
729
703
|
|
730
704
|
tag = "dialog"
|
731
705
|
|
732
|
-
open =
|
706
|
+
open = DOMProperty("open")
|
733
707
|
|
734
708
|
|
735
|
-
class div(
|
709
|
+
class div(ContainerElement):
|
736
710
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div"""
|
737
711
|
|
738
712
|
tag = "div"
|
739
713
|
|
740
714
|
|
741
|
-
class dl(
|
715
|
+
class dl(ContainerElement):
|
742
716
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl"""
|
743
717
|
|
744
718
|
tag = "dl"
|
745
719
|
|
746
|
-
value =
|
720
|
+
value = DOMProperty("value")
|
747
721
|
|
748
722
|
|
749
|
-
class dt(
|
723
|
+
class dt(ContainerElement):
|
750
724
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt"""
|
751
725
|
|
752
726
|
tag = "dt"
|
753
727
|
|
754
728
|
|
755
|
-
class em(
|
729
|
+
class em(ContainerElement):
|
756
730
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em"""
|
757
731
|
|
758
732
|
tag = "em"
|
759
733
|
|
760
734
|
|
761
|
-
class embed(
|
735
|
+
class embed(Element):
|
762
736
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed"""
|
763
737
|
|
764
738
|
tag = "embed"
|
765
739
|
|
766
|
-
height =
|
767
|
-
src =
|
768
|
-
type =
|
769
|
-
width =
|
740
|
+
height = DOMProperty("height")
|
741
|
+
src = DOMProperty("src")
|
742
|
+
type = DOMProperty("type")
|
743
|
+
width = DOMProperty("width")
|
770
744
|
|
771
745
|
|
772
|
-
class fieldset(
|
746
|
+
class fieldset(ContainerElement):
|
773
747
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset"""
|
774
748
|
|
775
749
|
tag = "fieldset"
|
776
750
|
|
777
|
-
disabled =
|
778
|
-
form =
|
779
|
-
name =
|
751
|
+
disabled = DOMProperty("disabled")
|
752
|
+
form = DOMProperty("form")
|
753
|
+
name = DOMProperty("name")
|
780
754
|
|
781
755
|
|
782
|
-
class figcaption(
|
756
|
+
class figcaption(ContainerElement):
|
783
757
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption"""
|
784
758
|
|
785
759
|
tag = "figcaption"
|
786
760
|
|
787
761
|
|
788
|
-
class figure(
|
762
|
+
class figure(ContainerElement):
|
789
763
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure"""
|
790
764
|
|
791
765
|
tag = "figure"
|
792
766
|
|
793
767
|
|
794
|
-
class footer(
|
768
|
+
class footer(ContainerElement):
|
795
769
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer"""
|
796
770
|
|
797
771
|
tag = "footer"
|
798
772
|
|
799
773
|
|
800
|
-
class form(
|
774
|
+
class form(ContainerElement):
|
801
775
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form"""
|
802
776
|
|
803
777
|
tag = "form"
|
804
778
|
|
805
|
-
accept_charset =
|
806
|
-
action =
|
807
|
-
autocapitalize =
|
808
|
-
autocomplete =
|
809
|
-
enctype =
|
810
|
-
name =
|
811
|
-
method =
|
812
|
-
nonvalidate =
|
813
|
-
rel =
|
814
|
-
target =
|
779
|
+
accept_charset = DOMProperty("accept-charset")
|
780
|
+
action = DOMProperty("action")
|
781
|
+
autocapitalize = DOMProperty("autocapitalize")
|
782
|
+
autocomplete = DOMProperty("autocomplete")
|
783
|
+
enctype = DOMProperty("enctype")
|
784
|
+
name = DOMProperty("name")
|
785
|
+
method = DOMProperty("method")
|
786
|
+
nonvalidate = DOMProperty("nonvalidate")
|
787
|
+
rel = DOMProperty("rel")
|
788
|
+
target = DOMProperty("target")
|
815
789
|
|
816
790
|
|
817
|
-
class h1(
|
791
|
+
class h1(ContainerElement):
|
818
792
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1"""
|
819
793
|
|
820
794
|
tag = "h1"
|
821
795
|
|
822
796
|
|
823
|
-
class h2(
|
797
|
+
class h2(ContainerElement):
|
824
798
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2"""
|
825
799
|
|
826
800
|
tag = "h2"
|
827
801
|
|
828
802
|
|
829
|
-
class h3(
|
803
|
+
class h3(ContainerElement):
|
830
804
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3"""
|
831
805
|
|
832
806
|
tag = "h3"
|
833
807
|
|
834
808
|
|
835
|
-
class h4(
|
809
|
+
class h4(ContainerElement):
|
836
810
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4"""
|
837
811
|
|
838
812
|
tag = "h4"
|
839
813
|
|
840
814
|
|
841
|
-
class h5(
|
815
|
+
class h5(ContainerElement):
|
842
816
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5"""
|
843
817
|
|
844
818
|
tag = "h5"
|
845
819
|
|
846
820
|
|
847
|
-
class h6(
|
821
|
+
class h6(ContainerElement):
|
848
822
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6"""
|
849
823
|
|
850
824
|
tag = "h6"
|
851
825
|
|
852
826
|
|
853
|
-
class
|
827
|
+
class head(ContainerElement):
|
828
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head"""
|
829
|
+
|
830
|
+
tag = "head"
|
831
|
+
|
832
|
+
|
833
|
+
class header(ContainerElement):
|
854
834
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header"""
|
855
835
|
|
856
836
|
tag = "header"
|
857
837
|
|
858
838
|
|
859
|
-
class hgroup(
|
839
|
+
class hgroup(ContainerElement):
|
860
840
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup"""
|
861
841
|
|
862
842
|
tag = "hgroup"
|
863
843
|
|
864
844
|
|
865
|
-
class hr(
|
845
|
+
class hr(Element):
|
866
846
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr"""
|
867
847
|
|
868
848
|
tag = "hr"
|
869
849
|
|
850
|
+
align = DOMProperty("align")
|
851
|
+
color = DOMProperty("color")
|
852
|
+
noshade = DOMProperty("noshade")
|
853
|
+
size = DOMProperty("size")
|
854
|
+
width = DOMProperty("width")
|
855
|
+
|
856
|
+
|
857
|
+
class html(ContainerElement):
|
858
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html"""
|
870
859
|
|
871
|
-
|
860
|
+
tag = "html"
|
861
|
+
|
862
|
+
|
863
|
+
class i(ContainerElement):
|
872
864
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i"""
|
873
865
|
|
874
866
|
tag = "i"
|
875
867
|
|
876
868
|
|
877
|
-
class iframe(
|
869
|
+
class iframe(ContainerElement):
|
878
870
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe"""
|
879
871
|
|
880
872
|
tag = "iframe"
|
881
873
|
|
882
|
-
allow =
|
883
|
-
allowfullscreen =
|
884
|
-
height =
|
885
|
-
loading =
|
886
|
-
name =
|
887
|
-
referrerpolicy =
|
888
|
-
sandbox =
|
889
|
-
src =
|
890
|
-
srcdoc =
|
891
|
-
width =
|
874
|
+
allow = DOMProperty("allow")
|
875
|
+
allowfullscreen = DOMProperty("allowfullscreen")
|
876
|
+
height = DOMProperty("height")
|
877
|
+
loading = DOMProperty("loading")
|
878
|
+
name = DOMProperty("name")
|
879
|
+
referrerpolicy = DOMProperty("referrerpolicy")
|
880
|
+
sandbox = DOMProperty("sandbox")
|
881
|
+
src = DOMProperty("src")
|
882
|
+
srcdoc = DOMProperty("srcdoc")
|
883
|
+
width = DOMProperty("width")
|
892
884
|
|
893
885
|
|
894
|
-
class img(
|
886
|
+
class img(Element):
|
895
887
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img"""
|
896
888
|
|
897
889
|
tag = "img"
|
898
890
|
|
899
|
-
alt =
|
900
|
-
crossorigin =
|
901
|
-
decoding =
|
902
|
-
fetchpriority =
|
903
|
-
height =
|
904
|
-
ismap =
|
905
|
-
loading =
|
906
|
-
referrerpolicy =
|
907
|
-
sizes =
|
908
|
-
src =
|
909
|
-
width =
|
891
|
+
alt = DOMProperty("alt")
|
892
|
+
crossorigin = DOMProperty("crossorigin")
|
893
|
+
decoding = DOMProperty("decoding")
|
894
|
+
fetchpriority = DOMProperty("fetchpriority")
|
895
|
+
height = DOMProperty("height")
|
896
|
+
ismap = DOMProperty("ismap")
|
897
|
+
loading = DOMProperty("loading")
|
898
|
+
referrerpolicy = DOMProperty("referrerpolicy")
|
899
|
+
sizes = DOMProperty("sizes")
|
900
|
+
src = DOMProperty("src")
|
901
|
+
width = DOMProperty("width")
|
910
902
|
|
911
903
|
|
912
904
|
# NOTE: Input is a reserved keyword in Python, so we use input_ instead
|
913
|
-
class input_(
|
905
|
+
class input_(Element):
|
914
906
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input"""
|
915
907
|
|
916
908
|
tag = "input"
|
917
909
|
|
918
|
-
accept =
|
919
|
-
alt =
|
920
|
-
autofocus =
|
921
|
-
capture =
|
922
|
-
checked =
|
923
|
-
dirname =
|
924
|
-
disabled =
|
925
|
-
form =
|
926
|
-
formaction =
|
927
|
-
formenctype =
|
928
|
-
formmethod =
|
929
|
-
formnovalidate =
|
930
|
-
formtarget =
|
931
|
-
height =
|
932
|
-
list =
|
933
|
-
max =
|
934
|
-
maxlength =
|
935
|
-
min =
|
936
|
-
minlength =
|
937
|
-
multiple =
|
938
|
-
name =
|
939
|
-
pattern =
|
940
|
-
placeholder =
|
941
|
-
popovertarget =
|
942
|
-
popovertargetaction =
|
943
|
-
readonly =
|
944
|
-
required =
|
945
|
-
size =
|
946
|
-
src =
|
947
|
-
step =
|
948
|
-
type =
|
949
|
-
value =
|
950
|
-
width =
|
951
|
-
|
952
|
-
|
953
|
-
class ins(
|
910
|
+
accept = DOMProperty("accept")
|
911
|
+
alt = DOMProperty("alt")
|
912
|
+
autofocus = DOMProperty("autofocus")
|
913
|
+
capture = DOMProperty("capture")
|
914
|
+
checked = DOMProperty("checked")
|
915
|
+
dirname = DOMProperty("dirname")
|
916
|
+
disabled = DOMProperty("disabled")
|
917
|
+
form = DOMProperty("form")
|
918
|
+
formaction = DOMProperty("formaction")
|
919
|
+
formenctype = DOMProperty("formenctype")
|
920
|
+
formmethod = DOMProperty("formmethod")
|
921
|
+
formnovalidate = DOMProperty("formnovalidate")
|
922
|
+
formtarget = DOMProperty("formtarget")
|
923
|
+
height = DOMProperty("height")
|
924
|
+
list = DOMProperty("list")
|
925
|
+
max = DOMProperty("max")
|
926
|
+
maxlength = DOMProperty("maxlength")
|
927
|
+
min = DOMProperty("min")
|
928
|
+
minlength = DOMProperty("minlength")
|
929
|
+
multiple = DOMProperty("multiple")
|
930
|
+
name = DOMProperty("name")
|
931
|
+
pattern = DOMProperty("pattern")
|
932
|
+
placeholder = DOMProperty("placeholder")
|
933
|
+
popovertarget = DOMProperty("popovertarget")
|
934
|
+
popovertargetaction = DOMProperty("popovertargetaction")
|
935
|
+
readonly = DOMProperty("readonly")
|
936
|
+
required = DOMProperty("required")
|
937
|
+
size = DOMProperty("size")
|
938
|
+
src = DOMProperty("src")
|
939
|
+
step = DOMProperty("step")
|
940
|
+
type = DOMProperty("type")
|
941
|
+
value = DOMProperty("value")
|
942
|
+
width = DOMProperty("width")
|
943
|
+
|
944
|
+
|
945
|
+
class ins(ContainerElement):
|
954
946
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins"""
|
955
947
|
|
956
948
|
tag = "ins"
|
957
949
|
|
958
|
-
cite =
|
959
|
-
datetime =
|
950
|
+
cite = DOMProperty("cite")
|
951
|
+
datetime = DOMProperty("datetime")
|
960
952
|
|
961
953
|
|
962
|
-
class kbd(
|
954
|
+
class kbd(ContainerElement):
|
963
955
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd"""
|
964
956
|
|
965
957
|
tag = "kbd"
|
966
958
|
|
967
959
|
|
968
|
-
class label(
|
960
|
+
class label(ContainerElement):
|
969
961
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label"""
|
970
962
|
|
971
963
|
tag = "label"
|
972
964
|
|
973
|
-
for_ =
|
965
|
+
for_ = DOMProperty("for")
|
974
966
|
|
975
967
|
|
976
|
-
class legend(
|
968
|
+
class legend(ContainerElement):
|
977
969
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend"""
|
978
970
|
|
979
971
|
tag = "legend"
|
980
972
|
|
981
973
|
|
982
|
-
class li(
|
974
|
+
class li(ContainerElement):
|
983
975
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li"""
|
984
976
|
|
985
977
|
tag = "li"
|
986
978
|
|
987
|
-
value =
|
979
|
+
value = DOMProperty("value")
|
988
980
|
|
989
981
|
|
990
|
-
class link(
|
982
|
+
class link(Element):
|
991
983
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link"""
|
992
984
|
|
993
985
|
tag = "link"
|
994
986
|
|
995
|
-
as_ =
|
996
|
-
crossorigin =
|
997
|
-
disabled =
|
998
|
-
fetchpriority =
|
999
|
-
href =
|
1000
|
-
imagesizes =
|
1001
|
-
imagesrcset =
|
1002
|
-
integrity =
|
1003
|
-
media =
|
1004
|
-
rel =
|
1005
|
-
referrerpolicy =
|
1006
|
-
sizes =
|
1007
|
-
title =
|
1008
|
-
type =
|
1009
|
-
|
1010
|
-
|
1011
|
-
class main(
|
987
|
+
as_ = DOMProperty("as")
|
988
|
+
crossorigin = DOMProperty("crossorigin")
|
989
|
+
disabled = DOMProperty("disabled")
|
990
|
+
fetchpriority = DOMProperty("fetchpriority")
|
991
|
+
href = DOMProperty("href")
|
992
|
+
imagesizes = DOMProperty("imagesizes")
|
993
|
+
imagesrcset = DOMProperty("imagesrcset")
|
994
|
+
integrity = DOMProperty("integrity")
|
995
|
+
media = DOMProperty("media")
|
996
|
+
rel = DOMProperty("rel")
|
997
|
+
referrerpolicy = DOMProperty("referrerpolicy")
|
998
|
+
sizes = DOMProperty("sizes")
|
999
|
+
title = DOMProperty("title")
|
1000
|
+
type = DOMProperty("type")
|
1001
|
+
|
1002
|
+
|
1003
|
+
class main(ContainerElement):
|
1012
1004
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main"""
|
1013
1005
|
|
1014
1006
|
tag = "main"
|
1015
1007
|
|
1016
1008
|
|
1017
|
-
class map_(
|
1009
|
+
class map_(ContainerElement):
|
1018
1010
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map"""
|
1019
1011
|
|
1020
1012
|
tag = "map"
|
1021
1013
|
|
1022
|
-
name =
|
1014
|
+
name = DOMProperty("name")
|
1023
1015
|
|
1024
1016
|
|
1025
|
-
class mark(
|
1017
|
+
class mark(ContainerElement):
|
1026
1018
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark"""
|
1027
1019
|
|
1028
1020
|
tag = "mark"
|
1029
1021
|
|
1030
1022
|
|
1031
|
-
class menu(
|
1023
|
+
class menu(ContainerElement):
|
1032
1024
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"""
|
1033
1025
|
|
1034
1026
|
tag = "menu"
|
1035
1027
|
|
1036
1028
|
|
1037
|
-
class
|
1029
|
+
class meta(ContainerElement):
|
1030
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta"""
|
1031
|
+
|
1032
|
+
tag = "meta"
|
1033
|
+
|
1034
|
+
charset = DOMProperty("charset")
|
1035
|
+
content = DOMProperty("content")
|
1036
|
+
http_equiv = DOMProperty("http-equiv")
|
1037
|
+
name = DOMProperty("name")
|
1038
|
+
|
1039
|
+
|
1040
|
+
class meter(ContainerElement):
|
1038
1041
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter"""
|
1039
1042
|
|
1040
1043
|
tag = "meter"
|
1041
1044
|
|
1042
|
-
form =
|
1043
|
-
high =
|
1044
|
-
low =
|
1045
|
-
max =
|
1046
|
-
min =
|
1047
|
-
optimum =
|
1048
|
-
value =
|
1045
|
+
form = DOMProperty("form")
|
1046
|
+
high = DOMProperty("high")
|
1047
|
+
low = DOMProperty("low")
|
1048
|
+
max = DOMProperty("max")
|
1049
|
+
min = DOMProperty("min")
|
1050
|
+
optimum = DOMProperty("optimum")
|
1051
|
+
value = DOMProperty("value")
|
1049
1052
|
|
1050
1053
|
|
1051
|
-
class nav(
|
1054
|
+
class nav(ContainerElement):
|
1052
1055
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav"""
|
1053
1056
|
|
1054
1057
|
tag = "nav"
|
1055
1058
|
|
1056
1059
|
|
1057
|
-
class object_(
|
1060
|
+
class object_(ContainerElement):
|
1058
1061
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object"""
|
1059
1062
|
|
1060
1063
|
tag = "object"
|
1061
1064
|
|
1062
|
-
data =
|
1063
|
-
form =
|
1064
|
-
height =
|
1065
|
-
name =
|
1066
|
-
type =
|
1067
|
-
usemap =
|
1068
|
-
width =
|
1065
|
+
data = DOMProperty("data")
|
1066
|
+
form = DOMProperty("form")
|
1067
|
+
height = DOMProperty("height")
|
1068
|
+
name = DOMProperty("name")
|
1069
|
+
type = DOMProperty("type")
|
1070
|
+
usemap = DOMProperty("usemap")
|
1071
|
+
width = DOMProperty("width")
|
1069
1072
|
|
1070
1073
|
|
1071
|
-
class ol(
|
1074
|
+
class ol(ContainerElement):
|
1072
1075
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol"""
|
1073
1076
|
|
1074
1077
|
tag = "ol"
|
1075
1078
|
|
1076
|
-
reversed =
|
1077
|
-
start =
|
1078
|
-
type =
|
1079
|
+
reversed = DOMProperty("reversed")
|
1080
|
+
start = DOMProperty("start")
|
1081
|
+
type = DOMProperty("type")
|
1079
1082
|
|
1080
1083
|
|
1081
|
-
class optgroup(
|
1084
|
+
class optgroup(ContainerElement, HasOptions):
|
1082
1085
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup"""
|
1083
1086
|
|
1084
1087
|
tag = "optgroup"
|
1085
1088
|
|
1086
|
-
disabled =
|
1087
|
-
label =
|
1089
|
+
disabled = DOMProperty("disabled")
|
1090
|
+
label = DOMProperty("label")
|
1088
1091
|
|
1089
1092
|
|
1090
|
-
class option(
|
1093
|
+
class option(ContainerElement):
|
1091
1094
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option"""
|
1092
1095
|
|
1093
1096
|
tag = "option"
|
1094
1097
|
|
1095
|
-
disabled =
|
1096
|
-
label =
|
1097
|
-
selected =
|
1098
|
-
value =
|
1098
|
+
disabled = DOMProperty("value")
|
1099
|
+
label = DOMProperty("label")
|
1100
|
+
selected = DOMProperty("selected")
|
1101
|
+
value = DOMProperty("value")
|
1099
1102
|
|
1100
1103
|
|
1101
|
-
class output(
|
1104
|
+
class output(ContainerElement):
|
1102
1105
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output"""
|
1103
1106
|
|
1104
1107
|
tag = "output"
|
1105
1108
|
|
1106
|
-
for_ =
|
1107
|
-
form =
|
1108
|
-
name =
|
1109
|
+
for_ = DOMProperty("for")
|
1110
|
+
form = DOMProperty("form")
|
1111
|
+
name = DOMProperty("name")
|
1112
|
+
|
1113
|
+
|
1114
|
+
class p(ContainerElement):
|
1115
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p"""
|
1116
|
+
|
1117
|
+
tag = "p"
|
1109
1118
|
|
1110
1119
|
|
1111
|
-
class
|
1120
|
+
class param(ContainerElement):
|
1112
1121
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p"""
|
1113
1122
|
|
1114
1123
|
tag = "p"
|
1115
1124
|
|
1116
1125
|
|
1117
|
-
class picture(
|
1126
|
+
class picture(ContainerElement):
|
1118
1127
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture"""
|
1119
1128
|
|
1120
1129
|
tag = "picture"
|
1121
1130
|
|
1122
1131
|
|
1123
|
-
class pre(
|
1132
|
+
class pre(ContainerElement):
|
1124
1133
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre"""
|
1125
1134
|
|
1126
1135
|
tag = "pre"
|
1127
1136
|
|
1128
1137
|
|
1129
|
-
class progress(
|
1138
|
+
class progress(ContainerElement):
|
1130
1139
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress"""
|
1131
1140
|
|
1132
1141
|
tag = "progress"
|
1133
1142
|
|
1134
|
-
max =
|
1135
|
-
value =
|
1143
|
+
max = DOMProperty("max")
|
1144
|
+
value = DOMProperty("value")
|
1136
1145
|
|
1137
1146
|
|
1138
|
-
class q(
|
1147
|
+
class q(ContainerElement):
|
1139
1148
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q"""
|
1140
1149
|
|
1141
1150
|
tag = "q"
|
1142
1151
|
|
1143
|
-
cite =
|
1152
|
+
cite = DOMProperty("cite")
|
1144
1153
|
|
1145
1154
|
|
1146
|
-
class s(
|
1155
|
+
class s(ContainerElement):
|
1147
1156
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s"""
|
1148
1157
|
|
1149
1158
|
tag = "s"
|
1150
1159
|
|
1151
1160
|
|
1152
|
-
class script(
|
1161
|
+
class script(ContainerElement):
|
1153
1162
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script"""
|
1154
1163
|
|
1155
1164
|
tag = "script"
|
1156
1165
|
|
1157
1166
|
# Let's add async manually since it's a reserved keyword in Python
|
1158
|
-
async_ =
|
1159
|
-
blocking =
|
1160
|
-
crossorigin =
|
1161
|
-
defer =
|
1162
|
-
fetchpriority =
|
1163
|
-
integrity =
|
1164
|
-
nomodule =
|
1165
|
-
nonce =
|
1166
|
-
referrerpolicy =
|
1167
|
-
src =
|
1168
|
-
type =
|
1169
|
-
|
1170
|
-
|
1171
|
-
class section(
|
1167
|
+
async_ = DOMProperty("async")
|
1168
|
+
blocking = DOMProperty("blocking")
|
1169
|
+
crossorigin = DOMProperty("crossorigin")
|
1170
|
+
defer = DOMProperty("defer")
|
1171
|
+
fetchpriority = DOMProperty("fetchpriority")
|
1172
|
+
integrity = DOMProperty("integrity")
|
1173
|
+
nomodule = DOMProperty("nomodule")
|
1174
|
+
nonce = DOMProperty("nonce")
|
1175
|
+
referrerpolicy = DOMProperty("referrerpolicy")
|
1176
|
+
src = DOMProperty("src")
|
1177
|
+
type = DOMProperty("type")
|
1178
|
+
|
1179
|
+
|
1180
|
+
class section(ContainerElement):
|
1172
1181
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section"""
|
1173
1182
|
|
1174
1183
|
tag = "section"
|
1175
1184
|
|
1176
1185
|
|
1177
|
-
class select(
|
1186
|
+
class select(ContainerElement, HasOptions):
|
1178
1187
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select"""
|
1179
1188
|
|
1180
1189
|
tag = "select"
|
1181
1190
|
|
1191
|
+
value = DOMProperty("value")
|
1192
|
+
|
1182
1193
|
|
1183
|
-
class small(
|
1194
|
+
class small(ContainerElement):
|
1184
1195
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small"""
|
1185
1196
|
|
1186
1197
|
tag = "small"
|
1187
1198
|
|
1188
1199
|
|
1189
|
-
class source(
|
1200
|
+
class source(Element):
|
1190
1201
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source"""
|
1191
1202
|
|
1192
1203
|
tag = "source"
|
1193
1204
|
|
1194
|
-
media =
|
1195
|
-
sizes =
|
1196
|
-
src =
|
1197
|
-
srcset =
|
1198
|
-
type =
|
1205
|
+
media = DOMProperty("media")
|
1206
|
+
sizes = DOMProperty("sizes")
|
1207
|
+
src = DOMProperty("src")
|
1208
|
+
srcset = DOMProperty("srcset")
|
1209
|
+
type = DOMProperty("type")
|
1199
1210
|
|
1200
1211
|
|
1201
|
-
class span(
|
1212
|
+
class span(ContainerElement):
|
1202
1213
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span"""
|
1203
1214
|
|
1204
1215
|
tag = "span"
|
1205
1216
|
|
1206
1217
|
|
1207
|
-
class strong(
|
1218
|
+
class strong(ContainerElement):
|
1208
1219
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong"""
|
1209
1220
|
|
1210
1221
|
tag = "strong"
|
1211
1222
|
|
1212
1223
|
|
1213
|
-
class style(
|
1224
|
+
class style(ContainerElement):
|
1214
1225
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style"""
|
1215
1226
|
|
1216
1227
|
tag = "style"
|
1217
1228
|
|
1218
|
-
blocking =
|
1219
|
-
media =
|
1220
|
-
nonce =
|
1221
|
-
title =
|
1229
|
+
blocking = DOMProperty("blocking")
|
1230
|
+
media = DOMProperty("media")
|
1231
|
+
nonce = DOMProperty("nonce")
|
1232
|
+
title = DOMProperty("title")
|
1222
1233
|
|
1223
1234
|
|
1224
|
-
class sub(
|
1235
|
+
class sub(ContainerElement):
|
1225
1236
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub"""
|
1226
1237
|
|
1227
1238
|
tag = "sub"
|
1228
1239
|
|
1229
1240
|
|
1230
|
-
class summary(
|
1241
|
+
class summary(ContainerElement):
|
1231
1242
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary"""
|
1232
1243
|
|
1233
1244
|
tag = "summary"
|
1234
1245
|
|
1235
1246
|
|
1236
|
-
class sup(
|
1247
|
+
class sup(ContainerElement):
|
1237
1248
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup"""
|
1238
1249
|
|
1239
1250
|
tag = "sup"
|
1240
1251
|
|
1241
1252
|
|
1242
|
-
class table(
|
1253
|
+
class table(ContainerElement):
|
1243
1254
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table"""
|
1244
1255
|
|
1245
1256
|
tag = "table"
|
1246
1257
|
|
1247
1258
|
|
1248
|
-
class tbody(
|
1259
|
+
class tbody(ContainerElement):
|
1249
1260
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody"""
|
1250
1261
|
|
1251
1262
|
tag = "tbody"
|
1252
1263
|
|
1253
1264
|
|
1254
|
-
class td(
|
1265
|
+
class td(ContainerElement):
|
1255
1266
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td"""
|
1256
1267
|
|
1257
1268
|
tag = "td"
|
1258
1269
|
|
1259
|
-
colspan =
|
1260
|
-
headers =
|
1261
|
-
rowspan =
|
1270
|
+
colspan = DOMProperty("colspan")
|
1271
|
+
headers = DOMProperty("headers")
|
1272
|
+
rowspan = DOMProperty("rowspan")
|
1262
1273
|
|
1263
1274
|
|
1264
|
-
class template(
|
1275
|
+
class template(ContainerElement):
|
1265
1276
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template"""
|
1266
1277
|
|
1267
1278
|
tag = "template"
|
1268
1279
|
|
1269
|
-
shadowrootmode =
|
1280
|
+
shadowrootmode = DOMProperty("shadowrootmode")
|
1270
1281
|
|
1271
1282
|
|
1272
|
-
class textarea(
|
1283
|
+
class textarea(ContainerElement):
|
1273
1284
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea"""
|
1274
1285
|
|
1275
1286
|
tag = "textarea"
|
1276
1287
|
|
1277
|
-
autocapitalize =
|
1278
|
-
autocomplete =
|
1279
|
-
autofocus =
|
1280
|
-
cols =
|
1281
|
-
dirname =
|
1282
|
-
disabled =
|
1283
|
-
form =
|
1284
|
-
maxlength =
|
1285
|
-
minlength =
|
1286
|
-
name =
|
1287
|
-
placeholder =
|
1288
|
-
readonly =
|
1289
|
-
required =
|
1290
|
-
rows =
|
1291
|
-
spellcheck =
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1288
|
+
autocapitalize = DOMProperty("autocapitalize")
|
1289
|
+
autocomplete = DOMProperty("autocomplete")
|
1290
|
+
autofocus = DOMProperty("autofocus")
|
1291
|
+
cols = DOMProperty("cols")
|
1292
|
+
dirname = DOMProperty("dirname")
|
1293
|
+
disabled = DOMProperty("disabled")
|
1294
|
+
form = DOMProperty("form")
|
1295
|
+
maxlength = DOMProperty("maxlength")
|
1296
|
+
minlength = DOMProperty("minlength")
|
1297
|
+
name = DOMProperty("name")
|
1298
|
+
placeholder = DOMProperty("placeholder")
|
1299
|
+
readonly = DOMProperty("readonly")
|
1300
|
+
required = DOMProperty("required")
|
1301
|
+
rows = DOMProperty("rows")
|
1302
|
+
spellcheck = DOMProperty("spellcheck")
|
1303
|
+
value = DOMProperty("value")
|
1304
|
+
wrap = DOMProperty("wrap")
|
1305
|
+
|
1306
|
+
|
1307
|
+
class tfoot(ContainerElement):
|
1296
1308
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot"""
|
1297
1309
|
|
1298
1310
|
tag = "tfoot"
|
1299
1311
|
|
1300
1312
|
|
1301
|
-
class th(
|
1313
|
+
class th(ContainerElement):
|
1302
1314
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th"""
|
1303
1315
|
|
1304
1316
|
tag = "th"
|
1305
1317
|
|
1306
1318
|
|
1307
|
-
class thead(
|
1319
|
+
class thead(ContainerElement):
|
1308
1320
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead"""
|
1309
1321
|
|
1310
1322
|
tag = "thead"
|
1311
1323
|
|
1312
1324
|
|
1313
|
-
class time(
|
1325
|
+
class time(ContainerElement):
|
1314
1326
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time"""
|
1315
1327
|
|
1316
1328
|
tag = "time"
|
1317
1329
|
|
1318
|
-
datetime =
|
1330
|
+
datetime = DOMProperty("datetime")
|
1319
1331
|
|
1320
1332
|
|
1321
|
-
class title(
|
1333
|
+
class title(ContainerElement):
|
1322
1334
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title"""
|
1323
1335
|
|
1324
1336
|
tag = "title"
|
1325
1337
|
|
1326
1338
|
|
1327
|
-
class tr(
|
1339
|
+
class tr(ContainerElement):
|
1328
1340
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr"""
|
1329
1341
|
|
1330
1342
|
tag = "tr"
|
1331
1343
|
|
1332
|
-
abbr =
|
1333
|
-
colspan =
|
1334
|
-
headers =
|
1335
|
-
rowspan =
|
1336
|
-
scope =
|
1344
|
+
abbr = DOMProperty("abbr")
|
1345
|
+
colspan = DOMProperty("colspan")
|
1346
|
+
headers = DOMProperty("headers")
|
1347
|
+
rowspan = DOMProperty("rowspan")
|
1348
|
+
scope = DOMProperty("scope")
|
1337
1349
|
|
1338
1350
|
|
1339
|
-
class track(
|
1351
|
+
class track(Element):
|
1340
1352
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track"""
|
1341
1353
|
|
1342
1354
|
tag = "track"
|
1343
1355
|
|
1344
|
-
default =
|
1345
|
-
kind =
|
1346
|
-
label =
|
1347
|
-
src =
|
1348
|
-
srclang =
|
1356
|
+
default = DOMProperty("default")
|
1357
|
+
kind = DOMProperty("kind")
|
1358
|
+
label = DOMProperty("label")
|
1359
|
+
src = DOMProperty("src")
|
1360
|
+
srclang = DOMProperty("srclang")
|
1349
1361
|
|
1350
1362
|
|
1351
|
-
class u(
|
1363
|
+
class u(ContainerElement):
|
1352
1364
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u"""
|
1353
1365
|
|
1354
1366
|
tag = "u"
|
1355
1367
|
|
1356
1368
|
|
1357
|
-
class ul(
|
1369
|
+
class ul(ContainerElement):
|
1358
1370
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul"""
|
1359
1371
|
|
1360
1372
|
tag = "ul"
|
1361
1373
|
|
1362
1374
|
|
1363
|
-
class var(
|
1375
|
+
class var(ContainerElement):
|
1364
1376
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var"""
|
1365
1377
|
|
1366
1378
|
tag = "var"
|
1367
1379
|
|
1368
1380
|
|
1369
|
-
class video(
|
1381
|
+
class video(ContainerElement):
|
1370
1382
|
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video"""
|
1371
1383
|
|
1372
1384
|
tag = "video"
|
1373
1385
|
|
1374
|
-
autoplay =
|
1375
|
-
controls =
|
1376
|
-
crossorigin =
|
1377
|
-
disablepictureinpicture =
|
1378
|
-
disableremoteplayback =
|
1379
|
-
height =
|
1380
|
-
loop =
|
1381
|
-
muted =
|
1382
|
-
playsinline =
|
1383
|
-
poster =
|
1384
|
-
preload =
|
1385
|
-
src =
|
1386
|
-
width =
|
1386
|
+
autoplay = DOMProperty("autoplay")
|
1387
|
+
controls = DOMProperty("controls")
|
1388
|
+
crossorigin = DOMProperty("crossorigin")
|
1389
|
+
disablepictureinpicture = DOMProperty("disablepictureinpicture")
|
1390
|
+
disableremoteplayback = DOMProperty("disableremoteplayback")
|
1391
|
+
height = DOMProperty("height")
|
1392
|
+
loop = DOMProperty("loop")
|
1393
|
+
muted = DOMProperty("muted")
|
1394
|
+
playsinline = DOMProperty("playsinline")
|
1395
|
+
poster = DOMProperty("poster")
|
1396
|
+
preload = DOMProperty("preload")
|
1397
|
+
src = DOMProperty("src")
|
1398
|
+
width = DOMProperty("width")
|
1399
|
+
|
1400
|
+
def snap(
|
1401
|
+
self,
|
1402
|
+
to: Element | str = None,
|
1403
|
+
width: int | None = None,
|
1404
|
+
height: int | None = None,
|
1405
|
+
):
|
1406
|
+
"""
|
1407
|
+
Captures a snapshot of a video.
|
1408
|
+
|
1409
|
+
Inputs:
|
1410
|
+
|
1411
|
+
* to: element where to save the snapshot of the video frame to
|
1412
|
+
* width: width of the image
|
1413
|
+
* height: height of the image
|
1414
|
+
|
1415
|
+
Output:
|
1416
|
+
(Element) canvas element where the video frame snapshot was drawn into
|
1417
|
+
"""
|
1418
|
+
if to is None:
|
1419
|
+
to_canvas = self.create("canvas")
|
1420
|
+
if width is None:
|
1421
|
+
width = self._dom_element.width
|
1422
|
+
if height is None:
|
1423
|
+
height = self._dom_element.height
|
1424
|
+
to_canvas._dom_element.width = width
|
1425
|
+
to_canvas._dom_element.height = height
|
1426
|
+
|
1427
|
+
elif isinstance(to, Element):
|
1428
|
+
if to._dom_element.tagName != "CANVAS":
|
1429
|
+
raise TypeError("Element to snap to must a canvas.")
|
1430
|
+
to_canvas = to
|
1431
|
+
|
1432
|
+
elif getattr(to, "tagName", "") == "CANVAS":
|
1433
|
+
to_canvas = canvas(to)
|
1434
|
+
|
1435
|
+
# If 'to' is a string, then assume it is a query selector.
|
1436
|
+
elif isinstance(to, str):
|
1437
|
+
nodelist = document.querySelectorAll(to)
|
1438
|
+
if nodelist.length == 0:
|
1439
|
+
raise TypeError("No element with selector {to} to snap to.")
|
1440
|
+
|
1441
|
+
if nodelist[0].tagName != "CANVAS":
|
1442
|
+
raise TypeError("Element to snap to must a be canvas.")
|
1443
|
+
|
1444
|
+
to_canvas = canvas(nodelist[0])
|
1445
|
+
|
1446
|
+
to_canvas.draw(self, width, height)
|
1447
|
+
|
1448
|
+
return canvas
|
1449
|
+
|
1450
|
+
|
1451
|
+
class wbr(Element):
|
1452
|
+
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr"""
|
1453
|
+
|
1454
|
+
tag = "wbr"
|
1387
1455
|
|
1388
1456
|
|
1389
1457
|
# Custom Elements
|
1390
|
-
class grid(
|
1458
|
+
class grid(ContainerElement):
|
1391
1459
|
tag = "div"
|
1392
1460
|
|
1393
1461
|
def __init__(self, layout, content=None, gap=None, **kwargs):
|
@@ -1400,6 +1468,64 @@ class grid(TextElementBase):
|
|
1400
1468
|
self.style["gap"] = gap
|
1401
1469
|
|
1402
1470
|
|
1471
|
+
class ClassesCollection:
|
1472
|
+
def __init__(self, collection: "ElementCollection") -> None:
|
1473
|
+
self._collection = collection
|
1474
|
+
|
1475
|
+
def __contains__(self, class_name):
|
1476
|
+
for element in self._collection:
|
1477
|
+
if class_name in element.classes:
|
1478
|
+
return True
|
1479
|
+
|
1480
|
+
return False
|
1481
|
+
|
1482
|
+
def __eq__(self, other):
|
1483
|
+
return (
|
1484
|
+
isinstance(other, ClassesCollection)
|
1485
|
+
and self._collection == other._collection
|
1486
|
+
)
|
1487
|
+
|
1488
|
+
def __iter__(self):
|
1489
|
+
for class_name in self._all_class_names():
|
1490
|
+
yield class_name
|
1491
|
+
|
1492
|
+
def __len__(self):
|
1493
|
+
return len(self._all_class_names())
|
1494
|
+
|
1495
|
+
def __repr__(self):
|
1496
|
+
return f"ClassesCollection({repr(self._collection)})"
|
1497
|
+
|
1498
|
+
def __str__(self):
|
1499
|
+
return " ".join(self._all_class_names())
|
1500
|
+
|
1501
|
+
def add(self, *class_names):
|
1502
|
+
for element in self._collection:
|
1503
|
+
element.classes.add(*class_names)
|
1504
|
+
|
1505
|
+
def contains(self, class_name):
|
1506
|
+
return class_name in self
|
1507
|
+
|
1508
|
+
def remove(self, *class_names):
|
1509
|
+
for element in self._collection:
|
1510
|
+
element.classes.remove(*class_names)
|
1511
|
+
|
1512
|
+
def replace(self, old_class, new_class):
|
1513
|
+
for element in self._collection:
|
1514
|
+
element.classes.replace(old_class, new_class)
|
1515
|
+
|
1516
|
+
def toggle(self, class_name):
|
1517
|
+
for element in self._collection:
|
1518
|
+
element.classes.toggle(class_name)
|
1519
|
+
|
1520
|
+
def _all_class_names(self):
|
1521
|
+
all_class_names = set()
|
1522
|
+
for element in self._collection:
|
1523
|
+
for class_name in element.classes:
|
1524
|
+
all_class_names.add(class_name)
|
1525
|
+
|
1526
|
+
return all_class_names
|
1527
|
+
|
1528
|
+
|
1403
1529
|
class StyleCollection:
|
1404
1530
|
def __init__(self, collection: "ElementCollection") -> None:
|
1405
1531
|
self._collection = collection
|
@@ -1414,6 +1540,9 @@ class StyleCollection:
|
|
1414
1540
|
for element in self._collection._elements:
|
1415
1541
|
element.style[key] = value
|
1416
1542
|
|
1543
|
+
def __repr__(self):
|
1544
|
+
return f"StyleCollection({repr(self._collection)})"
|
1545
|
+
|
1417
1546
|
def remove(self, key):
|
1418
1547
|
for element in self._collection._elements:
|
1419
1548
|
element.style.remove(key)
|
@@ -1422,29 +1551,64 @@ class StyleCollection:
|
|
1422
1551
|
class ElementCollection:
|
1423
1552
|
def __init__(self, elements: [Element]) -> None:
|
1424
1553
|
self._elements = elements
|
1425
|
-
self.
|
1554
|
+
self._classes = ClassesCollection(self)
|
1555
|
+
self._style = StyleCollection(self)
|
1556
|
+
|
1557
|
+
@property
|
1558
|
+
def children(self):
|
1559
|
+
return self._elements
|
1560
|
+
|
1561
|
+
@property
|
1562
|
+
def classes(self):
|
1563
|
+
return self._classes
|
1564
|
+
|
1565
|
+
@property
|
1566
|
+
def style(self):
|
1567
|
+
return self._style
|
1568
|
+
|
1569
|
+
@property
|
1570
|
+
def innerHTML(self):
|
1571
|
+
return self._get_attribute("innerHTML")
|
1572
|
+
|
1573
|
+
@innerHTML.setter
|
1574
|
+
def innerHTML(self, value):
|
1575
|
+
self._set_attribute("innerHTML", value)
|
1576
|
+
|
1577
|
+
@property
|
1578
|
+
def value(self):
|
1579
|
+
return self._get_attribute("value")
|
1580
|
+
|
1581
|
+
@value.setter
|
1582
|
+
def value(self, value):
|
1583
|
+
self._set_attribute("value", value)
|
1584
|
+
|
1585
|
+
def __eq__(self, obj):
|
1586
|
+
"""Check if the element is the same as the other element by comparing
|
1587
|
+
the underlying DOM element"""
|
1588
|
+
return isinstance(obj, ElementCollection) and obj._elements == self._elements
|
1426
1589
|
|
1427
1590
|
def __getitem__(self, key):
|
1428
1591
|
# If it's an integer we use it to access the elements in the collection
|
1429
1592
|
if isinstance(key, int):
|
1430
1593
|
return self._elements[key]
|
1594
|
+
|
1431
1595
|
# If it's a slice we use it to support slice operations over the elements
|
1432
1596
|
# in the collection
|
1433
1597
|
elif isinstance(key, slice):
|
1434
1598
|
return ElementCollection(self._elements[key])
|
1435
1599
|
|
1436
|
-
# If it's anything else (basically a string) we use it as a selector
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1600
|
+
# If it's anything else (basically a string) we use it as a query selector.
|
1601
|
+
elements = self._elements.querySelectorAll(key)
|
1602
|
+
return ElementCollection([element_from_dom(el) for el in elements])
|
1603
|
+
|
1604
|
+
def __iter__(self):
|
1605
|
+
yield from self._elements
|
1440
1606
|
|
1441
1607
|
def __len__(self):
|
1442
1608
|
return len(self._elements)
|
1443
1609
|
|
1444
|
-
def
|
1445
|
-
"
|
1446
|
-
the underlying JS element"""
|
1447
|
-
return isinstance(obj, ElementCollection) and obj._elements == self._elements
|
1610
|
+
def __repr__(self):
|
1611
|
+
return f"{self.__class__.__name__} (length: {len(self._elements)}) {self._elements}"
|
1448
1612
|
|
1449
1613
|
def _get_attribute(self, attr, index=None):
|
1450
1614
|
if index is None:
|
@@ -1457,28 +1621,39 @@ class ElementCollection:
|
|
1457
1621
|
for el in self._elements:
|
1458
1622
|
setattr(el, attr, value)
|
1459
1623
|
|
1460
|
-
@property
|
1461
|
-
def html(self):
|
1462
|
-
return self._get_attribute("html")
|
1463
|
-
|
1464
|
-
@html.setter
|
1465
|
-
def html(self, value):
|
1466
|
-
self._set_attribute("html", value)
|
1467
|
-
|
1468
|
-
@property
|
1469
|
-
def value(self):
|
1470
|
-
return self._get_attribute("value")
|
1471
|
-
|
1472
|
-
@value.setter
|
1473
|
-
def value(self, value):
|
1474
|
-
self._set_attribute("value", value)
|
1475
1624
|
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1625
|
+
# fmt: off
|
1626
|
+
ELEMENT_CLASSES = [
|
1627
|
+
# We put grid first because it is really just a <div> but we want the div class to
|
1628
|
+
# be used if wrapping existing js elements that we have not tagged with a
|
1629
|
+
# `data-pyscript-type` attribute (last one is the winner when it comes to this
|
1630
|
+
# list).
|
1631
|
+
grid,
|
1632
|
+
# The rest in alphabetical order.
|
1633
|
+
a, abbr, address, area, article, aside, audio,
|
1634
|
+
b, base, blockquote, body, br, button,
|
1635
|
+
canvas, caption, cite, code, col, colgroup,
|
1636
|
+
data, datalist, dd, del_, details, dialog, div, dl, dt,
|
1637
|
+
em, embed,
|
1638
|
+
fieldset, figcaption, figure, footer, form,
|
1639
|
+
h1, h2, h3, h4, h5, h6, head, header, hgroup, hr, html,
|
1640
|
+
i, iframe, img, input_, ins,
|
1641
|
+
kbd,
|
1642
|
+
label, legend, li, link,
|
1643
|
+
main, map_, mark, menu, meta, meter,
|
1644
|
+
nav,
|
1645
|
+
object_, ol, optgroup, option, output,
|
1646
|
+
p, param, picture, pre, progress,
|
1647
|
+
q,
|
1648
|
+
s, script, section, select, small, source, span, strong, style, sub, summary, sup,
|
1649
|
+
table, tbody, td, template, textarea, tfoot, th, thead, time, title, tr, track,
|
1650
|
+
u, ul,
|
1651
|
+
var, video,
|
1652
|
+
wbr,
|
1653
|
+
]
|
1654
|
+
# fmt: on
|
1655
|
+
|
1656
|
+
|
1657
|
+
# Lookup tables to get an element class by its name or tag.
|
1658
|
+
ELEMENT_CLASSES_BY_NAME = {cls.__name__: cls for cls in ELEMENT_CLASSES}
|
1659
|
+
ELEMENT_CLASSES_BY_TAG = {cls.tag: cls for cls in ELEMENT_CLASSES}
|