diff --git a/pyscript.core/src/stdlib/pyscript/web/elements.py b/pyscript.core/src/stdlib/pyscript/web/elements.py
index e6528531..d27f6448 100644
--- a/pyscript.core/src/stdlib/pyscript/web/elements.py
+++ b/pyscript.core/src/stdlib/pyscript/web/elements.py
@@ -1,14 +1,12 @@
-# noinspection PyPep8Naming
-import inspect
-import sys
-
try:
from typing import Any
+
except ImportError:
Any = "Any"
try:
import warnings
+
except ImportError:
# TODO: For now it probably means we are in MicroPython. We should figure
# out the "right" way to handle this. For now we just ignore the warning
@@ -21,90 +19,13 @@ except ImportError:
from pyscript import document
-#: A flag to show if MicroPython is the current Python interpreter.
-is_micropython = "MicroPython" in sys.version
-
-
-def getmembers_static(cls):
- """Cross-interpreter implementation of inspect.getmembers_static."""
-
- if is_micropython: # pragma: no cover
- return [(name, getattr(cls, name)) for name, _ in inspect.getmembers(cls)]
-
- return inspect.getmembers_static(cls)
-
-
-class DOMProperty:
- """A descriptor representing a DOM property on an `Element` instance.
-
- This maps a property on an `Element` instance, to the property with the specified
- name on the element's underlying DOM element.
- """
-
- def __init__(self, name: str, allow_nones: bool = False):
- self.name = name
- self.allow_nones = allow_nones
-
- def __get__(self, obj, objtype=None):
- return getattr(obj._dom_element, self.name)
-
- def __set__(self, obj, value):
- if not self.allow_nones and value is None:
- return
- setattr(obj._dom_element, self.name, value)
-
class Element:
- tag = "div"
-
- # These are attribute that all elements have (this list is a subset of the official
- # one - we are just trying to capture the most used ones).
- accesskey = DOMProperty("accesskey")
- autofocus = DOMProperty("autofocus")
- autocapitalize = DOMProperty("autocapitalize")
- className = DOMProperty("className")
- contenteditable = DOMProperty("contenteditable")
- draggable = DOMProperty("draggable")
- enterkeyhint = DOMProperty("enterkeyhint")
- hidden = DOMProperty("hidden")
- innerHTML = DOMProperty("innerHTML")
- id = DOMProperty("id")
- lang = DOMProperty("lang")
- nonce = DOMProperty("nonce")
- part = DOMProperty("part")
- popover = DOMProperty("popover")
- slot = DOMProperty("slot")
- spellcheck = DOMProperty("spellcheck")
- tabindex = DOMProperty("tabindex")
- tagName = DOMProperty("tagName")
- textContent = DOMProperty("textContent")
- title = DOMProperty("title")
- translate = DOMProperty("translate")
- virtualkeyboardpolicy = DOMProperty("virtualkeyboardpolicy")
-
@classmethod
def from_dom_element(cls, dom_element):
- """Create an instance of the appropriate subclass of `Element` for a DOM
- element.
+ """Create an instance of a subclass of `Element` for a DOM element."""
- If the DOM element was created via an `Element` (i.e. by us) it will have a data
- attribute named `data-pyscript-type` that contains the name of the subclass
- that created it. Hence, if the `data-pyscript-type` attribute *is* present we
- look up the subclass by name and create an instance of that. Otherwise, we make
- a 'best-guess' and look up the `Element` subclass by the DOM element's tag name
- (this is NOT fool-proof as many subclasses might use a `
`, but close enough
- for jazz).
- """
-
- # We use "getAttribute" here instead of `js_element.dataset.pyscriptType` as the
- # latter throws an `AttributeError` if the value isn't set. This way we just get
- # `None` which seems cleaner.
- cls_name = dom_element.getAttribute("data-pyscript-type")
- if cls_name:
- element_cls = ELEMENT_CLASSES_BY_NAME.get(cls_name.lower())
-
- else:
- element_cls = ELEMENT_CLASSES_BY_TAG.get(dom_element.tagName.lower())
+ element_cls = ELEMENT_CLASSES_BY_TAG_NAME.get(dom_element.tagName.lower())
# For any unknown elements (custom tags etc.) create an instance of this
# class ('Element').
@@ -119,14 +40,9 @@ class Element:
If `dom_element` is None we are being called to *create* a new element.
Otherwise, we are being called to *wrap* an existing DOM element.
"""
- self._dom_element = dom_element or document.createElement(self.tag)
-
- # Tag the DOM element with our class name.
- #
- # Using the `dataset` attribute is how you programmatically add `data-xxx`
- # attributes to a DOM element. In this case it will set an attribute that
- # appears in the DOM as `data-pyscript-type`.
- self._dom_element.dataset.pyscriptType = type(self).__name__
+ self._dom_element = dom_element or document.createElement(
+ type(self).__name__.replace("_", "")
+ )
self._parent = None
self._classes = Classes(self)
@@ -135,6 +51,35 @@ class Element:
# Set any specified classes, styles, and DOM properties.
self.update(classes=classes, style=style, **kwargs)
+ def __getattr__(self, name):
+ # This allows us to get attributes on the underlying DOM element that clash
+ # with Python keywords or built-ins (e.g. the output element has an
+ # attribute `for` which is a Python keyword, so you can access it on the
+ # Element instance via `for_`).
+ if name.endswith("_"):
+ name = name[:-1]
+
+ return getattr(self._dom_element, name)
+
+ def __setattr__(self, name, value):
+ # This class overrides `__setattr__` to delegate "public" attributes to the
+ # underlying DOM element. BUT, we don't use the usual Python pattern where
+ # we set attributes on the element itself via `self.__dict__` as that is not
+ # yet supported in our build of MicroPython. Instead, we handle it here by
+ # using super for all "private" attributes (those starting with an underscore).
+ if name.startswith("_"):
+ super().__setattr__(name, value)
+
+ else:
+ # This allows us to set attributes on the underlying DOM element that clash
+ # with Python keywords or built-ins (e.g. the output element has an
+ # attribute `for` which is a Python keyword, so you can access it on the
+ # Element instance via `for_`).
+ if name.endswith("_"):
+ name = name[:-1]
+
+ setattr(self._dom_element, name, value)
+
def update(self, classes=None, style=None, **kwargs):
"""Update the element with the specified classes, styles, and DOM properties."""
@@ -158,22 +103,8 @@ class Element:
Args:
**kwargs: The properties to set
"""
- # Harvest all DOM properties from the instance's class.
- dom_properties = {
- attribute_name: attribute_value
- for attribute_name, attribute_value in getmembers_static(self.__class__)
- if isinstance(attribute_value, DOMProperty)
- }
-
for name, value in kwargs.items():
- if name not in dom_properties:
- raise ValueError(f"'{name}' is not a DOM property.")
-
- try:
- setattr(self, name, value)
- except Exception as e:
- print(f"Error setting {name} to {value}: {e}")
- raise
+ setattr(self, name, value)
def __eq__(self, obj):
"""Check for equality by comparing the underlying DOM element."""
@@ -472,139 +403,66 @@ class ContainerElement(Element):
self.innerHTML += child
-# IMPORTANT: For all HTML components defined below, we are not mapping all possible
-# attributes, just the global and the most common ones. If you need to access a
-# specific attribute, you can always use the `_dom_element.
`
+# Classes for every element type. If the element type (e.g. "input") clashes with
+# either a Python keyword or common symbol, then we suffix the class name with an "_"
+# (e.g. "input_").
+
+
class a(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a"""
- tag = "a"
-
- download = DOMProperty("download")
- href = DOMProperty("href")
- referrerpolicy = DOMProperty("referrerpolicy")
- rel = DOMProperty("rel")
- target = DOMProperty("target")
- type = DOMProperty("type")
-
class abbr(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr"""
- tag = "abbr"
-
class address(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address"""
- tag = "address"
-
class area(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area"""
- tag = "area"
-
- alt = DOMProperty("alt")
- coords = DOMProperty("coords")
- download = DOMProperty("download")
- href = DOMProperty("href")
- ping = DOMProperty("ping")
- referrerpolicy = DOMProperty("referrerpolicy")
- rel = DOMProperty("rel")
- shape = DOMProperty("shape")
- target = DOMProperty("target")
-
class article(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article"""
- tag = "article"
-
class aside(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside"""
- tag = "aside"
-
class audio(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio"""
- tag = "audio"
-
- autoplay = DOMProperty("autoplay")
- controls = DOMProperty("controls")
- controlslist = DOMProperty("controlslist")
- crossorigin = DOMProperty("crossorigin")
- disableremoteplayback = DOMProperty("disableremoteplayback")
- loop = DOMProperty("loop")
- muted = DOMProperty("muted")
- preload = DOMProperty("preload")
- src = DOMProperty("src")
-
class b(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b"""
- tag = "b"
-
class base(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base"""
- tag = "base"
-
- href = DOMProperty("href")
- target = DOMProperty("target")
-
class blockquote(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote"""
- tag = "blockquote"
-
- cite = DOMProperty("cite")
-
class body(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body"""
- tag = "body"
-
class br(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br"""
- tag = "br"
-
class button(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button"""
- tag = "button"
-
- autofocus = DOMProperty("autofocus")
- disabled = DOMProperty("disabled")
- form = DOMProperty("form")
- formaction = DOMProperty("formaction")
- formenctype = DOMProperty("formenctype")
- formmethod = DOMProperty("formmethod")
- formnovalidate = DOMProperty("formnovalidate")
- formtarget = DOMProperty("formtarget")
- name = DOMProperty("name")
- type = DOMProperty("type")
- value = DOMProperty("value")
-
class canvas(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas"""
- tag = "canvas"
-
- height = DOMProperty("height")
- width = DOMProperty("width")
-
def download(self, filename: str = "snapped.png") -> None:
"""Download the current element with the filename provided in input.
@@ -648,773 +506,354 @@ class canvas(ContainerElement):
class caption(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption"""
- tag = "caption"
-
class cite(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite"""
- tag = "cite"
-
class code(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code"""
- tag = "code"
-
class col(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col"""
- tag = "col"
-
- span = DOMProperty("span")
-
class colgroup(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup"""
- tag = "colgroup"
-
class data(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data"""
- tag = "data"
-
- value = DOMProperty("value")
-
class datalist(ContainerElement, HasOptions):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist"""
- tag = "datalist"
-
class dd(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd"""
- tag = "dd"
-
class del_(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del"""
- tag = "del"
-
- cite = DOMProperty("cite")
- datetime = DOMProperty("datetime")
-
class details(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details"""
- tag = "details"
-
- open = DOMProperty("open")
-
class dialog(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog"""
- tag = "dialog"
-
- open = DOMProperty("open")
-
class div(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div"""
- tag = "div"
-
class dl(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl"""
- tag = "dl"
-
- value = DOMProperty("value")
-
class dt(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt"""
- tag = "dt"
-
class em(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em"""
- tag = "em"
-
class embed(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed"""
- tag = "embed"
-
- height = DOMProperty("height")
- src = DOMProperty("src")
- type = DOMProperty("type")
- width = DOMProperty("width")
-
class fieldset(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset"""
- tag = "fieldset"
-
- disabled = DOMProperty("disabled")
- form = DOMProperty("form")
- name = DOMProperty("name")
-
class figcaption(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption"""
- tag = "figcaption"
-
class figure(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure"""
- tag = "figure"
-
class footer(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer"""
- tag = "footer"
-
class form(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form"""
- tag = "form"
-
- accept_charset = DOMProperty("accept-charset")
- action = DOMProperty("action")
- autocapitalize = DOMProperty("autocapitalize")
- autocomplete = DOMProperty("autocomplete")
- enctype = DOMProperty("enctype")
- name = DOMProperty("name")
- method = DOMProperty("method")
- nonvalidate = DOMProperty("nonvalidate")
- rel = DOMProperty("rel")
- target = DOMProperty("target")
-
class h1(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1"""
- tag = "h1"
-
class h2(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2"""
- tag = "h2"
-
class h3(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3"""
- tag = "h3"
-
class h4(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4"""
- tag = "h4"
-
class h5(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5"""
- tag = "h5"
-
class h6(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6"""
- tag = "h6"
-
class head(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head"""
- tag = "head"
-
class header(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header"""
- tag = "header"
-
class hgroup(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup"""
- tag = "hgroup"
-
class hr(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr"""
- tag = "hr"
-
- align = DOMProperty("align")
- color = DOMProperty("color")
- noshade = DOMProperty("noshade")
- size = DOMProperty("size")
- width = DOMProperty("width")
-
class html(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html"""
- tag = "html"
-
class i(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i"""
- tag = "i"
-
class iframe(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe"""
- tag = "iframe"
-
- allow = DOMProperty("allow")
- allowfullscreen = DOMProperty("allowfullscreen")
- height = DOMProperty("height")
- loading = DOMProperty("loading")
- name = DOMProperty("name")
- referrerpolicy = DOMProperty("referrerpolicy")
- sandbox = DOMProperty("sandbox")
- src = DOMProperty("src")
- srcdoc = DOMProperty("srcdoc")
- width = DOMProperty("width")
-
class img(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img"""
- tag = "img"
- alt = DOMProperty("alt")
- crossorigin = DOMProperty("crossorigin")
- decoding = DOMProperty("decoding")
- fetchpriority = DOMProperty("fetchpriority")
- height = DOMProperty("height")
- ismap = DOMProperty("ismap")
- loading = DOMProperty("loading")
- referrerpolicy = DOMProperty("referrerpolicy")
- sizes = DOMProperty("sizes")
- src = DOMProperty("src")
- width = DOMProperty("width")
-
-
-# NOTE: Input is a reserved keyword in Python, so we use input_ instead
class input_(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input"""
- tag = "input"
-
- accept = DOMProperty("accept")
- alt = DOMProperty("alt")
- autofocus = DOMProperty("autofocus")
- capture = DOMProperty("capture")
- checked = DOMProperty("checked")
- dirname = DOMProperty("dirname")
- disabled = DOMProperty("disabled")
- form = DOMProperty("form")
- formaction = DOMProperty("formaction")
- formenctype = DOMProperty("formenctype")
- formmethod = DOMProperty("formmethod")
- formnovalidate = DOMProperty("formnovalidate")
- formtarget = DOMProperty("formtarget")
- height = DOMProperty("height")
- list = DOMProperty("list")
- max = DOMProperty("max")
- maxlength = DOMProperty("maxlength")
- min = DOMProperty("min")
- minlength = DOMProperty("minlength")
- multiple = DOMProperty("multiple")
- name = DOMProperty("name")
- pattern = DOMProperty("pattern")
- placeholder = DOMProperty("placeholder")
- popovertarget = DOMProperty("popovertarget")
- popovertargetaction = DOMProperty("popovertargetaction")
- readonly = DOMProperty("readonly")
- required = DOMProperty("required")
- size = DOMProperty("size")
- src = DOMProperty("src")
- step = DOMProperty("step")
- type = DOMProperty("type")
- value = DOMProperty("value")
- width = DOMProperty("width")
-
class ins(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins"""
- tag = "ins"
-
- cite = DOMProperty("cite")
- datetime = DOMProperty("datetime")
-
class kbd(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd"""
- tag = "kbd"
-
class label(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label"""
- tag = "label"
-
- for_ = DOMProperty("for")
-
class legend(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend"""
- tag = "legend"
-
class li(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li"""
- tag = "li"
-
- value = DOMProperty("value")
-
class link(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link"""
- tag = "link"
-
- as_ = DOMProperty("as")
- crossorigin = DOMProperty("crossorigin")
- disabled = DOMProperty("disabled")
- fetchpriority = DOMProperty("fetchpriority")
- href = DOMProperty("href")
- imagesizes = DOMProperty("imagesizes")
- imagesrcset = DOMProperty("imagesrcset")
- integrity = DOMProperty("integrity")
- media = DOMProperty("media")
- rel = DOMProperty("rel")
- referrerpolicy = DOMProperty("referrerpolicy")
- sizes = DOMProperty("sizes")
- title = DOMProperty("title")
- type = DOMProperty("type")
-
class main(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main"""
- tag = "main"
-
class map_(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map"""
- tag = "map"
-
- name = DOMProperty("name")
-
class mark(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark"""
- tag = "mark"
-
class menu(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"""
- tag = "menu"
-
class meta(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta"""
- tag = "meta"
-
- charset = DOMProperty("charset")
- content = DOMProperty("content")
- http_equiv = DOMProperty("http-equiv")
- name = DOMProperty("name")
-
class meter(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter"""
- tag = "meter"
-
- form = DOMProperty("form")
- high = DOMProperty("high")
- low = DOMProperty("low")
- max = DOMProperty("max")
- min = DOMProperty("min")
- optimum = DOMProperty("optimum")
- value = DOMProperty("value")
-
class nav(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav"""
- tag = "nav"
-
class object_(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object"""
- tag = "object"
-
- data = DOMProperty("data")
- form = DOMProperty("form")
- height = DOMProperty("height")
- name = DOMProperty("name")
- type = DOMProperty("type")
- usemap = DOMProperty("usemap")
- width = DOMProperty("width")
-
class ol(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol"""
- tag = "ol"
-
- reversed = DOMProperty("reversed")
- start = DOMProperty("start")
- type = DOMProperty("type")
-
class optgroup(ContainerElement, HasOptions):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup"""
- tag = "optgroup"
-
- disabled = DOMProperty("disabled")
- label = DOMProperty("label")
-
class option(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option"""
- tag = "option"
-
- disabled = DOMProperty("value")
- label = DOMProperty("label")
- selected = DOMProperty("selected")
- value = DOMProperty("value")
-
class output(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output"""
- tag = "output"
-
- for_ = DOMProperty("for")
- form = DOMProperty("form")
- name = DOMProperty("name")
-
class p(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p"""
- tag = "p"
-
class param(ContainerElement):
- """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p"""
-
- tag = "p"
+ """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param"""
class picture(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture"""
- tag = "picture"
-
class pre(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre"""
- tag = "pre"
-
class progress(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress"""
- tag = "progress"
-
- max = DOMProperty("max")
- value = DOMProperty("value")
-
class q(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q"""
- tag = "q"
-
- cite = DOMProperty("cite")
-
class s(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s"""
- tag = "s"
-
class script(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script"""
- tag = "script"
-
- # Let's add async manually since it's a reserved keyword in Python
- async_ = DOMProperty("async")
- blocking = DOMProperty("blocking")
- crossorigin = DOMProperty("crossorigin")
- defer = DOMProperty("defer")
- fetchpriority = DOMProperty("fetchpriority")
- integrity = DOMProperty("integrity")
- nomodule = DOMProperty("nomodule")
- nonce = DOMProperty("nonce")
- referrerpolicy = DOMProperty("referrerpolicy")
- src = DOMProperty("src")
- type = DOMProperty("type")
-
class section(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section"""
- tag = "section"
-
class select(ContainerElement, HasOptions):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select"""
- tag = "select"
-
- value = DOMProperty("value")
-
class small(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small"""
- tag = "small"
-
class source(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source"""
- tag = "source"
-
- media = DOMProperty("media")
- sizes = DOMProperty("sizes")
- src = DOMProperty("src")
- srcset = DOMProperty("srcset")
- type = DOMProperty("type")
-
class span(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span"""
- tag = "span"
-
class strong(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong"""
- tag = "strong"
-
class style(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style"""
- tag = "style"
-
- blocking = DOMProperty("blocking")
- media = DOMProperty("media")
- nonce = DOMProperty("nonce")
- title = DOMProperty("title")
-
class sub(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub"""
- tag = "sub"
-
class summary(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary"""
- tag = "summary"
-
class sup(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup"""
- tag = "sup"
-
class table(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table"""
- tag = "table"
-
class tbody(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody"""
- tag = "tbody"
-
class td(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td"""
- tag = "td"
-
- colspan = DOMProperty("colspan")
- headers = DOMProperty("headers")
- rowspan = DOMProperty("rowspan")
-
class template(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template"""
- tag = "template"
-
- shadowrootmode = DOMProperty("shadowrootmode")
-
class textarea(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea"""
- tag = "textarea"
-
- autocapitalize = DOMProperty("autocapitalize")
- autocomplete = DOMProperty("autocomplete")
- autofocus = DOMProperty("autofocus")
- cols = DOMProperty("cols")
- dirname = DOMProperty("dirname")
- disabled = DOMProperty("disabled")
- form = DOMProperty("form")
- maxlength = DOMProperty("maxlength")
- minlength = DOMProperty("minlength")
- name = DOMProperty("name")
- placeholder = DOMProperty("placeholder")
- readonly = DOMProperty("readonly")
- required = DOMProperty("required")
- rows = DOMProperty("rows")
- spellcheck = DOMProperty("spellcheck")
- value = DOMProperty("value")
- wrap = DOMProperty("wrap")
-
class tfoot(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot"""
- tag = "tfoot"
-
class th(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th"""
- tag = "th"
-
class thead(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead"""
- tag = "thead"
-
class time(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time"""
- tag = "time"
-
- datetime = DOMProperty("datetime")
-
class title(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title"""
- tag = "title"
-
class tr(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr"""
- tag = "tr"
-
- abbr = DOMProperty("abbr")
- colspan = DOMProperty("colspan")
- headers = DOMProperty("headers")
- rowspan = DOMProperty("rowspan")
- scope = DOMProperty("scope")
-
class track(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track"""
- tag = "track"
-
- default = DOMProperty("default")
- kind = DOMProperty("kind")
- label = DOMProperty("label")
- src = DOMProperty("src")
- srclang = DOMProperty("srclang")
-
class u(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u"""
- tag = "u"
-
class ul(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul"""
- tag = "ul"
-
class var(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var"""
- tag = "var"
-
class video(ContainerElement):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video"""
- tag = "video"
-
- autoplay = DOMProperty("autoplay")
- controls = DOMProperty("controls")
- crossorigin = DOMProperty("crossorigin")
- disablepictureinpicture = DOMProperty("disablepictureinpicture")
- disableremoteplayback = DOMProperty("disableremoteplayback")
- height = DOMProperty("height")
- loop = DOMProperty("loop")
- muted = DOMProperty("muted")
- playsinline = DOMProperty("playsinline")
- poster = DOMProperty("poster")
- preload = DOMProperty("preload")
- src = DOMProperty("src")
- width = DOMProperty("width")
- videoHeight = DOMProperty("videoHeight")
- videoWidth = DOMProperty("videoWidth")
-
def snap(
self,
to: Element | str = None,
@@ -1465,22 +904,6 @@ class video(ContainerElement):
class wbr(Element):
"""Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr"""
- tag = "wbr"
-
-
-# Custom Elements
-class grid(ContainerElement):
- tag = "div"
-
- def __init__(self, layout, content=None, gap=None, **kwargs):
- super().__init__(content, **kwargs)
- self.style["display"] = "grid"
- self.style["grid-template-columns"] = layout
-
- # TODO: This should be a property
- if gap is not None:
- self.style["gap"] = gap
-
class ClassesCollection:
def __init__(self, collection: "ElementCollection") -> None:
@@ -1602,9 +1025,10 @@ class ElementCollection:
def __setattr__(self, key, value):
# This class overrides `__setattr__` to delegate "public" attributes to the
- # elements in the collection, but we don't use the usual Python pattern where we
- # set attributes on the collection itself via `self.__dict__` as it is not yet
- # supported in our build of MicroPython. Instead, we handle it here.
+ # elements in the collection. BUT, we don't use the usual Python pattern where
+ # we set attributes on the collection itself via `self.__dict__` as that is not
+ # yet supported in our build of MicroPython. Instead, we handle it here by
+ # using super for all "private" attributes (those starting with an underscore).
if key.startswith("_"):
super().__setattr__(key, value)
@@ -1644,12 +1068,6 @@ class ElementCollection:
# fmt: off
ELEMENT_CLASSES = [
- # We put grid first because it is really just a but we want the div class to
- # be used if wrapping existing js elements that we have not tagged with a
- # `data-pyscript-type` attribute (last one is the winner when it comes to this
- # list).
- grid,
- # The rest in alphabetical order.
a, abbr, address, area, article, aside, audio,
b, base, blockquote, body, br, button,
canvas, caption, cite, code, col, colgroup,
@@ -1674,6 +1092,7 @@ ELEMENT_CLASSES = [
# fmt: on
-# Lookup tables to get an element class by its name or tag.
-ELEMENT_CLASSES_BY_NAME = {cls.__name__: cls for cls in ELEMENT_CLASSES}
-ELEMENT_CLASSES_BY_TAG = {cls.tag: cls for cls in ELEMENT_CLASSES}
+# Lookup table to get an element class by its tag name.
+ELEMENT_CLASSES_BY_TAG_NAME = {
+ cls.__name__.replace("_", ""): cls for cls in ELEMENT_CLASSES
+}