@pyscript/core 0.5.0-rc1 → 0.5.0-rc3

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.
@@ -1,14 +1,12 @@
1
- # noinspection PyPep8Naming
2
- import inspect
3
- import sys
4
-
5
1
  try:
6
2
  from typing import Any
3
+
7
4
  except ImportError:
8
5
  Any = "Any"
9
6
 
10
7
  try:
11
8
  import warnings
9
+
12
10
  except ImportError:
13
11
  # TODO: For now it probably means we are in MicroPython. We should figure
14
12
  # out the "right" way to handle this. For now we just ignore the warning
@@ -21,90 +19,13 @@ except ImportError:
21
19
 
22
20
  from pyscript import document
23
21
 
24
- #: A flag to show if MicroPython is the current Python interpreter.
25
- is_micropython = "MicroPython" in sys.version
26
-
27
-
28
- def getmembers_static(cls):
29
- """Cross-interpreter implementation of inspect.getmembers_static."""
30
-
31
- if is_micropython: # pragma: no cover
32
- return [(name, getattr(cls, name)) for name, _ in inspect.getmembers(cls)]
33
-
34
- return inspect.getmembers_static(cls)
35
-
36
-
37
- class DOMProperty:
38
- """A descriptor representing a DOM property on an `Element` instance.
39
-
40
- This maps a property on an `Element` instance, to the property with the specified
41
- name on the element's underlying DOM element.
42
- """
43
-
44
- def __init__(self, name: str, allow_nones: bool = False):
45
- self.name = name
46
- self.allow_nones = allow_nones
47
-
48
- def __get__(self, obj, objtype=None):
49
- return getattr(obj._dom_element, self.name)
50
-
51
- def __set__(self, obj, value):
52
- if not self.allow_nones and value is None:
53
- return
54
- setattr(obj._dom_element, self.name, value)
55
-
56
22
 
57
23
  class Element:
58
- tag = "div"
59
-
60
- # These are attribute that all elements have (this list is a subset of the official
61
- # one - we are just trying to capture the most used ones).
62
- accesskey = DOMProperty("accesskey")
63
- autofocus = DOMProperty("autofocus")
64
- autocapitalize = DOMProperty("autocapitalize")
65
- className = DOMProperty("className")
66
- contenteditable = DOMProperty("contenteditable")
67
- draggable = DOMProperty("draggable")
68
- enterkeyhint = DOMProperty("enterkeyhint")
69
- hidden = DOMProperty("hidden")
70
- innerHTML = DOMProperty("innerHTML")
71
- id = DOMProperty("id")
72
- lang = DOMProperty("lang")
73
- nonce = DOMProperty("nonce")
74
- part = DOMProperty("part")
75
- popover = DOMProperty("popover")
76
- slot = DOMProperty("slot")
77
- spellcheck = DOMProperty("spellcheck")
78
- tabindex = DOMProperty("tabindex")
79
- tagName = DOMProperty("tagName")
80
- textContent = DOMProperty("textContent")
81
- title = DOMProperty("title")
82
- translate = DOMProperty("translate")
83
- virtualkeyboardpolicy = DOMProperty("virtualkeyboardpolicy")
84
-
85
24
  @classmethod
86
25
  def from_dom_element(cls, dom_element):
87
- """Create an instance of the appropriate subclass of `Element` for a DOM
88
- element.
89
-
90
- If the DOM element was created via an `Element` (i.e. by us) it will have a data
91
- attribute named `data-pyscript-type` that contains the name of the subclass
92
- that created it. Hence, if the `data-pyscript-type` attribute *is* present we
93
- look up the subclass by name and create an instance of that. Otherwise, we make
94
- a 'best-guess' and look up the `Element` subclass by the DOM element's tag name
95
- (this is NOT fool-proof as many subclasses might use a `<div>`, but close enough
96
- for jazz).
97
- """
26
+ """Create an instance of a subclass of `Element` for a DOM element."""
98
27
 
99
- # We use "getAttribute" here instead of `js_element.dataset.pyscriptType` as the
100
- # latter throws an `AttributeError` if the value isn't set. This way we just get
101
- # `None` which seems cleaner.
102
- cls_name = dom_element.getAttribute("data-pyscript-type")
103
- if cls_name:
104
- element_cls = ELEMENT_CLASSES_BY_NAME.get(cls_name.lower())
105
-
106
- else:
107
- element_cls = ELEMENT_CLASSES_BY_TAG.get(dom_element.tagName.lower())
28
+ element_cls = ELEMENT_CLASSES_BY_TAG_NAME.get(dom_element.tagName.lower())
108
29
 
109
30
  # For any unknown elements (custom tags etc.) create an instance of this
110
31
  # class ('Element').
@@ -119,14 +40,9 @@ class Element:
119
40
  If `dom_element` is None we are being called to *create* a new element.
120
41
  Otherwise, we are being called to *wrap* an existing DOM element.
121
42
  """
122
- self._dom_element = dom_element or document.createElement(self.tag)
123
-
124
- # Tag the DOM element with our class name.
125
- #
126
- # Using the `dataset` attribute is how you programmatically add `data-xxx`
127
- # attributes to a DOM element. In this case it will set an attribute that
128
- # appears in the DOM as `data-pyscript-type`.
129
- self._dom_element.dataset.pyscriptType = type(self).__name__
43
+ self._dom_element = dom_element or document.createElement(
44
+ type(self).__name__.replace("_", "")
45
+ )
130
46
 
131
47
  self._parent = None
132
48
  self._classes = Classes(self)
@@ -135,6 +51,35 @@ class Element:
135
51
  # Set any specified classes, styles, and DOM properties.
136
52
  self.update(classes=classes, style=style, **kwargs)
137
53
 
54
+ def __getattr__(self, name):
55
+ # This allows us to get attributes on the underlying DOM element that clash
56
+ # with Python keywords or built-ins (e.g. the output element has an
57
+ # attribute `for` which is a Python keyword, so you can access it on the
58
+ # Element instance via `for_`).
59
+ if name.endswith("_"):
60
+ name = name[:-1]
61
+
62
+ return getattr(self._dom_element, name)
63
+
64
+ def __setattr__(self, name, value):
65
+ # This class overrides `__setattr__` to delegate "public" attributes to the
66
+ # underlying DOM element. BUT, we don't use the usual Python pattern where
67
+ # we set attributes on the element itself via `self.__dict__` as that is not
68
+ # yet supported in our build of MicroPython. Instead, we handle it here by
69
+ # using super for all "private" attributes (those starting with an underscore).
70
+ if name.startswith("_"):
71
+ super().__setattr__(name, value)
72
+
73
+ else:
74
+ # This allows us to set attributes on the underlying DOM element that clash
75
+ # with Python keywords or built-ins (e.g. the output element has an
76
+ # attribute `for` which is a Python keyword, so you can access it on the
77
+ # Element instance via `for_`).
78
+ if name.endswith("_"):
79
+ name = name[:-1]
80
+
81
+ setattr(self._dom_element, name, value)
82
+
138
83
  def update(self, classes=None, style=None, **kwargs):
139
84
  """Update the element with the specified classes, styles, and DOM properties."""
140
85
 
@@ -158,22 +103,8 @@ class Element:
158
103
  Args:
159
104
  **kwargs: The properties to set
160
105
  """
161
- # Harvest all DOM properties from the instance's class.
162
- dom_properties = {
163
- attribute_name: attribute_value
164
- for attribute_name, attribute_value in getmembers_static(self.__class__)
165
- if isinstance(attribute_value, DOMProperty)
166
- }
167
-
168
106
  for name, value in kwargs.items():
169
- if name not in dom_properties:
170
- raise ValueError(f"'{name}' is not a DOM property.")
171
-
172
- try:
173
- setattr(self, name, value)
174
- except Exception as e:
175
- print(f"Error setting {name} to {value}: {e}")
176
- raise
107
+ setattr(self, name, value)
177
108
 
178
109
  def __eq__(self, obj):
179
110
  """Check for equality by comparing the underlying DOM element."""
@@ -472,139 +403,66 @@ class ContainerElement(Element):
472
403
  self.innerHTML += child
473
404
 
474
405
 
475
- # IMPORTANT: For all HTML components defined below, we are not mapping all possible
476
- # attributes, just the global and the most common ones. If you need to access a
477
- # specific attribute, you can always use the `_dom_element.<attribute>`
478
- class a(ContainerElement):
479
- """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a"""
406
+ # Classes for every element type. If the element type (e.g. "input") clashes with
407
+ # either a Python keyword or common symbol, then we suffix the class name with an "_"
408
+ # (e.g. "input_").
480
409
 
481
- tag = "a"
482
410
 
483
- download = DOMProperty("download")
484
- href = DOMProperty("href")
485
- referrerpolicy = DOMProperty("referrerpolicy")
486
- rel = DOMProperty("rel")
487
- target = DOMProperty("target")
488
- type = DOMProperty("type")
411
+ class a(ContainerElement):
412
+ """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a"""
489
413
 
490
414
 
491
415
  class abbr(ContainerElement):
492
416
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr"""
493
417
 
494
- tag = "abbr"
495
-
496
418
 
497
419
  class address(ContainerElement):
498
420
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address"""
499
421
 
500
- tag = "address"
501
-
502
422
 
503
423
  class area(Element):
504
424
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area"""
505
425
 
506
- tag = "area"
507
-
508
- alt = DOMProperty("alt")
509
- coords = DOMProperty("coords")
510
- download = DOMProperty("download")
511
- href = DOMProperty("href")
512
- ping = DOMProperty("ping")
513
- referrerpolicy = DOMProperty("referrerpolicy")
514
- rel = DOMProperty("rel")
515
- shape = DOMProperty("shape")
516
- target = DOMProperty("target")
517
-
518
426
 
519
427
  class article(ContainerElement):
520
428
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article"""
521
429
 
522
- tag = "article"
523
-
524
430
 
525
431
  class aside(ContainerElement):
526
432
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside"""
527
433
 
528
- tag = "aside"
529
-
530
434
 
531
435
  class audio(ContainerElement):
532
436
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio"""
533
437
 
534
- tag = "audio"
535
-
536
- autoplay = DOMProperty("autoplay")
537
- controls = DOMProperty("controls")
538
- controlslist = DOMProperty("controlslist")
539
- crossorigin = DOMProperty("crossorigin")
540
- disableremoteplayback = DOMProperty("disableremoteplayback")
541
- loop = DOMProperty("loop")
542
- muted = DOMProperty("muted")
543
- preload = DOMProperty("preload")
544
- src = DOMProperty("src")
545
-
546
438
 
547
439
  class b(ContainerElement):
548
440
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b"""
549
441
 
550
- tag = "b"
551
-
552
442
 
553
443
  class base(Element):
554
444
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base"""
555
445
 
556
- tag = "base"
557
-
558
- href = DOMProperty("href")
559
- target = DOMProperty("target")
560
-
561
446
 
562
447
  class blockquote(ContainerElement):
563
448
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote"""
564
449
 
565
- tag = "blockquote"
566
-
567
- cite = DOMProperty("cite")
568
-
569
450
 
570
451
  class body(ContainerElement):
571
452
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body"""
572
453
 
573
- tag = "body"
574
-
575
454
 
576
455
  class br(Element):
577
456
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br"""
578
457
 
579
- tag = "br"
580
-
581
458
 
582
459
  class button(ContainerElement):
583
460
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button"""
584
461
 
585
- tag = "button"
586
-
587
- autofocus = DOMProperty("autofocus")
588
- disabled = DOMProperty("disabled")
589
- form = DOMProperty("form")
590
- formaction = DOMProperty("formaction")
591
- formenctype = DOMProperty("formenctype")
592
- formmethod = DOMProperty("formmethod")
593
- formnovalidate = DOMProperty("formnovalidate")
594
- formtarget = DOMProperty("formtarget")
595
- name = DOMProperty("name")
596
- type = DOMProperty("type")
597
- value = DOMProperty("value")
598
-
599
462
 
600
463
  class canvas(ContainerElement):
601
464
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas"""
602
465
 
603
- tag = "canvas"
604
-
605
- height = DOMProperty("height")
606
- width = DOMProperty("width")
607
-
608
466
  def download(self, filename: str = "snapped.png") -> None:
609
467
  """Download the current element with the filename provided in input.
610
468
 
@@ -648,773 +506,354 @@ class canvas(ContainerElement):
648
506
  class caption(ContainerElement):
649
507
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption"""
650
508
 
651
- tag = "caption"
652
-
653
509
 
654
510
  class cite(ContainerElement):
655
511
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite"""
656
512
 
657
- tag = "cite"
658
-
659
513
 
660
514
  class code(ContainerElement):
661
515
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code"""
662
516
 
663
- tag = "code"
664
-
665
517
 
666
518
  class col(Element):
667
519
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col"""
668
520
 
669
- tag = "col"
670
-
671
- span = DOMProperty("span")
672
-
673
521
 
674
522
  class colgroup(ContainerElement):
675
523
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup"""
676
524
 
677
- tag = "colgroup"
678
-
679
525
 
680
526
  class data(ContainerElement):
681
527
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data"""
682
528
 
683
- tag = "data"
684
-
685
- value = DOMProperty("value")
686
-
687
529
 
688
530
  class datalist(ContainerElement, HasOptions):
689
531
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist"""
690
532
 
691
- tag = "datalist"
692
-
693
533
 
694
534
  class dd(ContainerElement):
695
535
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd"""
696
536
 
697
- tag = "dd"
698
-
699
537
 
700
538
  class del_(ContainerElement):
701
539
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del"""
702
540
 
703
- tag = "del"
704
-
705
- cite = DOMProperty("cite")
706
- datetime = DOMProperty("datetime")
707
-
708
541
 
709
542
  class details(ContainerElement):
710
543
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details"""
711
544
 
712
- tag = "details"
713
-
714
- open = DOMProperty("open")
715
-
716
545
 
717
546
  class dialog(ContainerElement):
718
547
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog"""
719
548
 
720
- tag = "dialog"
721
-
722
- open = DOMProperty("open")
723
-
724
549
 
725
550
  class div(ContainerElement):
726
551
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div"""
727
552
 
728
- tag = "div"
729
-
730
553
 
731
554
  class dl(ContainerElement):
732
555
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl"""
733
556
 
734
- tag = "dl"
735
-
736
- value = DOMProperty("value")
737
-
738
557
 
739
558
  class dt(ContainerElement):
740
559
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt"""
741
560
 
742
- tag = "dt"
743
-
744
561
 
745
562
  class em(ContainerElement):
746
563
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em"""
747
564
 
748
- tag = "em"
749
-
750
565
 
751
566
  class embed(Element):
752
567
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed"""
753
568
 
754
- tag = "embed"
755
-
756
- height = DOMProperty("height")
757
- src = DOMProperty("src")
758
- type = DOMProperty("type")
759
- width = DOMProperty("width")
760
-
761
569
 
762
570
  class fieldset(ContainerElement):
763
571
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset"""
764
572
 
765
- tag = "fieldset"
766
-
767
- disabled = DOMProperty("disabled")
768
- form = DOMProperty("form")
769
- name = DOMProperty("name")
770
-
771
573
 
772
574
  class figcaption(ContainerElement):
773
575
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption"""
774
576
 
775
- tag = "figcaption"
776
-
777
577
 
778
578
  class figure(ContainerElement):
779
579
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure"""
780
580
 
781
- tag = "figure"
782
-
783
581
 
784
582
  class footer(ContainerElement):
785
583
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer"""
786
584
 
787
- tag = "footer"
788
-
789
585
 
790
586
  class form(ContainerElement):
791
587
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form"""
792
588
 
793
- tag = "form"
794
-
795
- accept_charset = DOMProperty("accept-charset")
796
- action = DOMProperty("action")
797
- autocapitalize = DOMProperty("autocapitalize")
798
- autocomplete = DOMProperty("autocomplete")
799
- enctype = DOMProperty("enctype")
800
- name = DOMProperty("name")
801
- method = DOMProperty("method")
802
- nonvalidate = DOMProperty("nonvalidate")
803
- rel = DOMProperty("rel")
804
- target = DOMProperty("target")
805
-
806
589
 
807
590
  class h1(ContainerElement):
808
591
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1"""
809
592
 
810
- tag = "h1"
811
-
812
593
 
813
594
  class h2(ContainerElement):
814
595
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2"""
815
596
 
816
- tag = "h2"
817
-
818
597
 
819
598
  class h3(ContainerElement):
820
599
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3"""
821
600
 
822
- tag = "h3"
823
-
824
601
 
825
602
  class h4(ContainerElement):
826
603
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4"""
827
604
 
828
- tag = "h4"
829
-
830
605
 
831
606
  class h5(ContainerElement):
832
607
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5"""
833
608
 
834
- tag = "h5"
835
-
836
609
 
837
610
  class h6(ContainerElement):
838
611
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6"""
839
612
 
840
- tag = "h6"
841
-
842
613
 
843
614
  class head(ContainerElement):
844
615
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head"""
845
616
 
846
- tag = "head"
847
-
848
617
 
849
618
  class header(ContainerElement):
850
619
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header"""
851
620
 
852
- tag = "header"
853
-
854
621
 
855
622
  class hgroup(ContainerElement):
856
623
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup"""
857
624
 
858
- tag = "hgroup"
859
-
860
625
 
861
626
  class hr(Element):
862
627
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr"""
863
628
 
864
- tag = "hr"
865
-
866
- align = DOMProperty("align")
867
- color = DOMProperty("color")
868
- noshade = DOMProperty("noshade")
869
- size = DOMProperty("size")
870
- width = DOMProperty("width")
871
-
872
629
 
873
630
  class html(ContainerElement):
874
631
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/html"""
875
632
 
876
- tag = "html"
877
-
878
633
 
879
634
  class i(ContainerElement):
880
635
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i"""
881
636
 
882
- tag = "i"
883
-
884
637
 
885
638
  class iframe(ContainerElement):
886
639
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe"""
887
640
 
888
- tag = "iframe"
889
-
890
- allow = DOMProperty("allow")
891
- allowfullscreen = DOMProperty("allowfullscreen")
892
- height = DOMProperty("height")
893
- loading = DOMProperty("loading")
894
- name = DOMProperty("name")
895
- referrerpolicy = DOMProperty("referrerpolicy")
896
- sandbox = DOMProperty("sandbox")
897
- src = DOMProperty("src")
898
- srcdoc = DOMProperty("srcdoc")
899
- width = DOMProperty("width")
900
-
901
641
 
902
642
  class img(Element):
903
643
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img"""
904
644
 
905
- tag = "img"
906
-
907
- alt = DOMProperty("alt")
908
- crossorigin = DOMProperty("crossorigin")
909
- decoding = DOMProperty("decoding")
910
- fetchpriority = DOMProperty("fetchpriority")
911
- height = DOMProperty("height")
912
- ismap = DOMProperty("ismap")
913
- loading = DOMProperty("loading")
914
- referrerpolicy = DOMProperty("referrerpolicy")
915
- sizes = DOMProperty("sizes")
916
- src = DOMProperty("src")
917
- width = DOMProperty("width")
918
645
 
919
-
920
- # NOTE: Input is a reserved keyword in Python, so we use input_ instead
921
646
  class input_(Element):
922
647
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input"""
923
648
 
924
- tag = "input"
925
-
926
- accept = DOMProperty("accept")
927
- alt = DOMProperty("alt")
928
- autofocus = DOMProperty("autofocus")
929
- capture = DOMProperty("capture")
930
- checked = DOMProperty("checked")
931
- dirname = DOMProperty("dirname")
932
- disabled = DOMProperty("disabled")
933
- form = DOMProperty("form")
934
- formaction = DOMProperty("formaction")
935
- formenctype = DOMProperty("formenctype")
936
- formmethod = DOMProperty("formmethod")
937
- formnovalidate = DOMProperty("formnovalidate")
938
- formtarget = DOMProperty("formtarget")
939
- height = DOMProperty("height")
940
- list = DOMProperty("list")
941
- max = DOMProperty("max")
942
- maxlength = DOMProperty("maxlength")
943
- min = DOMProperty("min")
944
- minlength = DOMProperty("minlength")
945
- multiple = DOMProperty("multiple")
946
- name = DOMProperty("name")
947
- pattern = DOMProperty("pattern")
948
- placeholder = DOMProperty("placeholder")
949
- popovertarget = DOMProperty("popovertarget")
950
- popovertargetaction = DOMProperty("popovertargetaction")
951
- readonly = DOMProperty("readonly")
952
- required = DOMProperty("required")
953
- size = DOMProperty("size")
954
- src = DOMProperty("src")
955
- step = DOMProperty("step")
956
- type = DOMProperty("type")
957
- value = DOMProperty("value")
958
- width = DOMProperty("width")
959
-
960
649
 
961
650
  class ins(ContainerElement):
962
651
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins"""
963
652
 
964
- tag = "ins"
965
-
966
- cite = DOMProperty("cite")
967
- datetime = DOMProperty("datetime")
968
-
969
653
 
970
654
  class kbd(ContainerElement):
971
655
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd"""
972
656
 
973
- tag = "kbd"
974
-
975
657
 
976
658
  class label(ContainerElement):
977
659
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label"""
978
660
 
979
- tag = "label"
980
-
981
- for_ = DOMProperty("for")
982
-
983
661
 
984
662
  class legend(ContainerElement):
985
663
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend"""
986
664
 
987
- tag = "legend"
988
-
989
665
 
990
666
  class li(ContainerElement):
991
667
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li"""
992
668
 
993
- tag = "li"
994
-
995
- value = DOMProperty("value")
996
-
997
669
 
998
670
  class link(Element):
999
671
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link"""
1000
672
 
1001
- tag = "link"
1002
-
1003
- as_ = DOMProperty("as")
1004
- crossorigin = DOMProperty("crossorigin")
1005
- disabled = DOMProperty("disabled")
1006
- fetchpriority = DOMProperty("fetchpriority")
1007
- href = DOMProperty("href")
1008
- imagesizes = DOMProperty("imagesizes")
1009
- imagesrcset = DOMProperty("imagesrcset")
1010
- integrity = DOMProperty("integrity")
1011
- media = DOMProperty("media")
1012
- rel = DOMProperty("rel")
1013
- referrerpolicy = DOMProperty("referrerpolicy")
1014
- sizes = DOMProperty("sizes")
1015
- title = DOMProperty("title")
1016
- type = DOMProperty("type")
1017
-
1018
673
 
1019
674
  class main(ContainerElement):
1020
675
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main"""
1021
676
 
1022
- tag = "main"
1023
-
1024
677
 
1025
678
  class map_(ContainerElement):
1026
679
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map"""
1027
680
 
1028
- tag = "map"
1029
-
1030
- name = DOMProperty("name")
1031
-
1032
681
 
1033
682
  class mark(ContainerElement):
1034
683
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark"""
1035
684
 
1036
- tag = "mark"
1037
-
1038
685
 
1039
686
  class menu(ContainerElement):
1040
687
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu"""
1041
688
 
1042
- tag = "menu"
1043
-
1044
689
 
1045
690
  class meta(ContainerElement):
1046
691
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta"""
1047
692
 
1048
- tag = "meta"
1049
-
1050
- charset = DOMProperty("charset")
1051
- content = DOMProperty("content")
1052
- http_equiv = DOMProperty("http-equiv")
1053
- name = DOMProperty("name")
1054
-
1055
693
 
1056
694
  class meter(ContainerElement):
1057
695
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter"""
1058
696
 
1059
- tag = "meter"
1060
-
1061
- form = DOMProperty("form")
1062
- high = DOMProperty("high")
1063
- low = DOMProperty("low")
1064
- max = DOMProperty("max")
1065
- min = DOMProperty("min")
1066
- optimum = DOMProperty("optimum")
1067
- value = DOMProperty("value")
1068
-
1069
697
 
1070
698
  class nav(ContainerElement):
1071
699
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav"""
1072
700
 
1073
- tag = "nav"
1074
-
1075
701
 
1076
702
  class object_(ContainerElement):
1077
703
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object"""
1078
704
 
1079
- tag = "object"
1080
-
1081
- data = DOMProperty("data")
1082
- form = DOMProperty("form")
1083
- height = DOMProperty("height")
1084
- name = DOMProperty("name")
1085
- type = DOMProperty("type")
1086
- usemap = DOMProperty("usemap")
1087
- width = DOMProperty("width")
1088
-
1089
705
 
1090
706
  class ol(ContainerElement):
1091
707
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol"""
1092
708
 
1093
- tag = "ol"
1094
-
1095
- reversed = DOMProperty("reversed")
1096
- start = DOMProperty("start")
1097
- type = DOMProperty("type")
1098
-
1099
709
 
1100
710
  class optgroup(ContainerElement, HasOptions):
1101
711
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup"""
1102
712
 
1103
- tag = "optgroup"
1104
-
1105
- disabled = DOMProperty("disabled")
1106
- label = DOMProperty("label")
1107
-
1108
713
 
1109
714
  class option(ContainerElement):
1110
715
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option"""
1111
716
 
1112
- tag = "option"
1113
-
1114
- disabled = DOMProperty("value")
1115
- label = DOMProperty("label")
1116
- selected = DOMProperty("selected")
1117
- value = DOMProperty("value")
1118
-
1119
717
 
1120
718
  class output(ContainerElement):
1121
719
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output"""
1122
720
 
1123
- tag = "output"
1124
-
1125
- for_ = DOMProperty("for")
1126
- form = DOMProperty("form")
1127
- name = DOMProperty("name")
1128
-
1129
721
 
1130
722
  class p(ContainerElement):
1131
723
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p"""
1132
724
 
1133
- tag = "p"
1134
-
1135
725
 
1136
726
  class param(ContainerElement):
1137
- """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p"""
1138
-
1139
- tag = "p"
727
+ """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param"""
1140
728
 
1141
729
 
1142
730
  class picture(ContainerElement):
1143
731
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture"""
1144
732
 
1145
- tag = "picture"
1146
-
1147
733
 
1148
734
  class pre(ContainerElement):
1149
735
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre"""
1150
736
 
1151
- tag = "pre"
1152
-
1153
737
 
1154
738
  class progress(ContainerElement):
1155
739
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress"""
1156
740
 
1157
- tag = "progress"
1158
-
1159
- max = DOMProperty("max")
1160
- value = DOMProperty("value")
1161
-
1162
741
 
1163
742
  class q(ContainerElement):
1164
743
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q"""
1165
744
 
1166
- tag = "q"
1167
-
1168
- cite = DOMProperty("cite")
1169
-
1170
745
 
1171
746
  class s(ContainerElement):
1172
747
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s"""
1173
748
 
1174
- tag = "s"
1175
-
1176
749
 
1177
750
  class script(ContainerElement):
1178
751
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script"""
1179
752
 
1180
- tag = "script"
1181
-
1182
- # Let's add async manually since it's a reserved keyword in Python
1183
- async_ = DOMProperty("async")
1184
- blocking = DOMProperty("blocking")
1185
- crossorigin = DOMProperty("crossorigin")
1186
- defer = DOMProperty("defer")
1187
- fetchpriority = DOMProperty("fetchpriority")
1188
- integrity = DOMProperty("integrity")
1189
- nomodule = DOMProperty("nomodule")
1190
- nonce = DOMProperty("nonce")
1191
- referrerpolicy = DOMProperty("referrerpolicy")
1192
- src = DOMProperty("src")
1193
- type = DOMProperty("type")
1194
-
1195
753
 
1196
754
  class section(ContainerElement):
1197
755
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section"""
1198
756
 
1199
- tag = "section"
1200
-
1201
757
 
1202
758
  class select(ContainerElement, HasOptions):
1203
759
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select"""
1204
760
 
1205
- tag = "select"
1206
-
1207
- value = DOMProperty("value")
1208
-
1209
761
 
1210
762
  class small(ContainerElement):
1211
763
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small"""
1212
764
 
1213
- tag = "small"
1214
-
1215
765
 
1216
766
  class source(Element):
1217
767
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source"""
1218
768
 
1219
- tag = "source"
1220
-
1221
- media = DOMProperty("media")
1222
- sizes = DOMProperty("sizes")
1223
- src = DOMProperty("src")
1224
- srcset = DOMProperty("srcset")
1225
- type = DOMProperty("type")
1226
-
1227
769
 
1228
770
  class span(ContainerElement):
1229
771
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span"""
1230
772
 
1231
- tag = "span"
1232
-
1233
773
 
1234
774
  class strong(ContainerElement):
1235
775
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong"""
1236
776
 
1237
- tag = "strong"
1238
-
1239
777
 
1240
778
  class style(ContainerElement):
1241
779
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style"""
1242
780
 
1243
- tag = "style"
1244
-
1245
- blocking = DOMProperty("blocking")
1246
- media = DOMProperty("media")
1247
- nonce = DOMProperty("nonce")
1248
- title = DOMProperty("title")
1249
-
1250
781
 
1251
782
  class sub(ContainerElement):
1252
783
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub"""
1253
784
 
1254
- tag = "sub"
1255
-
1256
785
 
1257
786
  class summary(ContainerElement):
1258
787
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary"""
1259
788
 
1260
- tag = "summary"
1261
-
1262
789
 
1263
790
  class sup(ContainerElement):
1264
791
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup"""
1265
792
 
1266
- tag = "sup"
1267
-
1268
793
 
1269
794
  class table(ContainerElement):
1270
795
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table"""
1271
796
 
1272
- tag = "table"
1273
-
1274
797
 
1275
798
  class tbody(ContainerElement):
1276
799
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody"""
1277
800
 
1278
- tag = "tbody"
1279
-
1280
801
 
1281
802
  class td(ContainerElement):
1282
803
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td"""
1283
804
 
1284
- tag = "td"
1285
-
1286
- colspan = DOMProperty("colspan")
1287
- headers = DOMProperty("headers")
1288
- rowspan = DOMProperty("rowspan")
1289
-
1290
805
 
1291
806
  class template(ContainerElement):
1292
807
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template"""
1293
808
 
1294
- tag = "template"
1295
-
1296
- shadowrootmode = DOMProperty("shadowrootmode")
1297
-
1298
809
 
1299
810
  class textarea(ContainerElement):
1300
811
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea"""
1301
812
 
1302
- tag = "textarea"
1303
-
1304
- autocapitalize = DOMProperty("autocapitalize")
1305
- autocomplete = DOMProperty("autocomplete")
1306
- autofocus = DOMProperty("autofocus")
1307
- cols = DOMProperty("cols")
1308
- dirname = DOMProperty("dirname")
1309
- disabled = DOMProperty("disabled")
1310
- form = DOMProperty("form")
1311
- maxlength = DOMProperty("maxlength")
1312
- minlength = DOMProperty("minlength")
1313
- name = DOMProperty("name")
1314
- placeholder = DOMProperty("placeholder")
1315
- readonly = DOMProperty("readonly")
1316
- required = DOMProperty("required")
1317
- rows = DOMProperty("rows")
1318
- spellcheck = DOMProperty("spellcheck")
1319
- value = DOMProperty("value")
1320
- wrap = DOMProperty("wrap")
1321
-
1322
813
 
1323
814
  class tfoot(ContainerElement):
1324
815
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot"""
1325
816
 
1326
- tag = "tfoot"
1327
-
1328
817
 
1329
818
  class th(ContainerElement):
1330
819
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th"""
1331
820
 
1332
- tag = "th"
1333
-
1334
821
 
1335
822
  class thead(ContainerElement):
1336
823
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead"""
1337
824
 
1338
- tag = "thead"
1339
-
1340
825
 
1341
826
  class time(ContainerElement):
1342
827
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time"""
1343
828
 
1344
- tag = "time"
1345
-
1346
- datetime = DOMProperty("datetime")
1347
-
1348
829
 
1349
830
  class title(ContainerElement):
1350
831
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title"""
1351
832
 
1352
- tag = "title"
1353
-
1354
833
 
1355
834
  class tr(ContainerElement):
1356
835
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr"""
1357
836
 
1358
- tag = "tr"
1359
-
1360
- abbr = DOMProperty("abbr")
1361
- colspan = DOMProperty("colspan")
1362
- headers = DOMProperty("headers")
1363
- rowspan = DOMProperty("rowspan")
1364
- scope = DOMProperty("scope")
1365
-
1366
837
 
1367
838
  class track(Element):
1368
839
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track"""
1369
840
 
1370
- tag = "track"
1371
-
1372
- default = DOMProperty("default")
1373
- kind = DOMProperty("kind")
1374
- label = DOMProperty("label")
1375
- src = DOMProperty("src")
1376
- srclang = DOMProperty("srclang")
1377
-
1378
841
 
1379
842
  class u(ContainerElement):
1380
843
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u"""
1381
844
 
1382
- tag = "u"
1383
-
1384
845
 
1385
846
  class ul(ContainerElement):
1386
847
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul"""
1387
848
 
1388
- tag = "ul"
1389
-
1390
849
 
1391
850
  class var(ContainerElement):
1392
851
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var"""
1393
852
 
1394
- tag = "var"
1395
-
1396
853
 
1397
854
  class video(ContainerElement):
1398
855
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video"""
1399
856
 
1400
- tag = "video"
1401
-
1402
- autoplay = DOMProperty("autoplay")
1403
- controls = DOMProperty("controls")
1404
- crossorigin = DOMProperty("crossorigin")
1405
- disablepictureinpicture = DOMProperty("disablepictureinpicture")
1406
- disableremoteplayback = DOMProperty("disableremoteplayback")
1407
- height = DOMProperty("height")
1408
- loop = DOMProperty("loop")
1409
- muted = DOMProperty("muted")
1410
- playsinline = DOMProperty("playsinline")
1411
- poster = DOMProperty("poster")
1412
- preload = DOMProperty("preload")
1413
- src = DOMProperty("src")
1414
- width = DOMProperty("width")
1415
- videoHeight = DOMProperty("videoHeight")
1416
- videoWidth = DOMProperty("videoWidth")
1417
-
1418
857
  def snap(
1419
858
  self,
1420
859
  to: Element | str = None,
@@ -1465,22 +904,6 @@ class video(ContainerElement):
1465
904
  class wbr(Element):
1466
905
  """Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr"""
1467
906
 
1468
- tag = "wbr"
1469
-
1470
-
1471
- # Custom Elements
1472
- class grid(ContainerElement):
1473
- tag = "div"
1474
-
1475
- def __init__(self, layout, content=None, gap=None, **kwargs):
1476
- super().__init__(content, **kwargs)
1477
- self.style["display"] = "grid"
1478
- self.style["grid-template-columns"] = layout
1479
-
1480
- # TODO: This should be a property
1481
- if gap is not None:
1482
- self.style["gap"] = gap
1483
-
1484
907
 
1485
908
  class ClassesCollection:
1486
909
  def __init__(self, collection: "ElementCollection") -> None:
@@ -1602,9 +1025,10 @@ class ElementCollection:
1602
1025
 
1603
1026
  def __setattr__(self, key, value):
1604
1027
  # This class overrides `__setattr__` to delegate "public" attributes to the
1605
- # elements in the collection, but we don't use the usual Python pattern where we
1606
- # set attributes on the collection itself via `self.__dict__` as it is not yet
1607
- # supported in our build of MicroPython. Instead, we handle it here.
1028
+ # elements in the collection. BUT, we don't use the usual Python pattern where
1029
+ # we set attributes on the collection itself via `self.__dict__` as that is not
1030
+ # yet supported in our build of MicroPython. Instead, we handle it here by
1031
+ # using super for all "private" attributes (those starting with an underscore).
1608
1032
  if key.startswith("_"):
1609
1033
  super().__setattr__(key, value)
1610
1034
 
@@ -1644,12 +1068,6 @@ class ElementCollection:
1644
1068
 
1645
1069
  # fmt: off
1646
1070
  ELEMENT_CLASSES = [
1647
- # We put grid first because it is really just a <div> but we want the div class to
1648
- # be used if wrapping existing js elements that we have not tagged with a
1649
- # `data-pyscript-type` attribute (last one is the winner when it comes to this
1650
- # list).
1651
- grid,
1652
- # The rest in alphabetical order.
1653
1071
  a, abbr, address, area, article, aside, audio,
1654
1072
  b, base, blockquote, body, br, button,
1655
1073
  canvas, caption, cite, code, col, colgroup,
@@ -1674,6 +1092,7 @@ ELEMENT_CLASSES = [
1674
1092
  # fmt: on
1675
1093
 
1676
1094
 
1677
- # Lookup tables to get an element class by its name or tag.
1678
- ELEMENT_CLASSES_BY_NAME = {cls.__name__: cls for cls in ELEMENT_CLASSES}
1679
- ELEMENT_CLASSES_BY_TAG = {cls.tag: cls for cls in ELEMENT_CLASSES}
1095
+ # Lookup table to get an element class by its tag name.
1096
+ ELEMENT_CLASSES_BY_TAG_NAME = {
1097
+ cls.__name__.replace("_", ""): cls for cls in ELEMENT_CLASSES
1098
+ }