@pyscript/core 0.7.10 → 0.7.12
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-7vXPINKi.js → codemirror-WbVPJuAs.js} +2 -2
- package/dist/codemirror-WbVPJuAs.js.map +1 -0
- package/dist/{codemirror_commands-CN4gxvZk.js → codemirror_commands-BRu2f-2p.js} +2 -2
- package/dist/codemirror_commands-BRu2f-2p.js.map +1 -0
- package/dist/codemirror_lang-python-q-wuh0nL.js +2 -0
- package/dist/codemirror_lang-python-q-wuh0nL.js.map +1 -0
- package/dist/codemirror_language-DqPeLcFN.js +2 -0
- package/dist/codemirror_language-DqPeLcFN.js.map +1 -0
- package/dist/{codemirror_state-BIAL8JKm.js → codemirror_state-DWQh5Ruf.js} +2 -2
- package/dist/codemirror_state-DWQh5Ruf.js.map +1 -0
- package/dist/codemirror_view-CMXZSWgf.js +2 -0
- package/dist/codemirror_view-CMXZSWgf.js.map +1 -0
- package/dist/core-DmpFMpAn.js +4 -0
- package/dist/core-DmpFMpAn.js.map +1 -0
- package/dist/core.js +1 -1
- package/dist/{deprecations-manager-qW023Rjf.js → deprecations-manager-HQLYNCYn.js} +2 -2
- package/dist/{deprecations-manager-qW023Rjf.js.map → deprecations-manager-HQLYNCYn.js.map} +1 -1
- package/dist/{donkey-7fH6-q0I.js → donkey-B3F8VdSV.js} +2 -2
- package/dist/{donkey-7fH6-q0I.js.map → donkey-B3F8VdSV.js.map} +1 -1
- package/dist/{error-CO7OuWCh.js → error-DS_5_C5_.js} +2 -2
- package/dist/{error-CO7OuWCh.js.map → error-DS_5_C5_.js.map} +1 -1
- package/dist/index-DaYI1YXo.js +2 -0
- package/dist/index-DaYI1YXo.js.map +1 -0
- package/dist/{mpy-BZxQ23WL.js → mpy-Bo2uW6nt.js} +2 -2
- package/dist/{mpy-BZxQ23WL.js.map → mpy-Bo2uW6nt.js.map} +1 -1
- package/dist/{py-DI_TP8Id.js → py-BEf8j7L5.js} +2 -2
- package/dist/{py-DI_TP8Id.js.map → py-BEf8j7L5.js.map} +1 -1
- package/dist/{py-editor-BJBbMtNv.js → py-editor-C0XF2rwE.js} +2 -2
- package/dist/{py-editor-BJBbMtNv.js.map → py-editor-C0XF2rwE.js.map} +1 -1
- package/dist/{py-game-C7N5JK0D.js → py-game-eWNz96mt.js} +2 -2
- package/dist/{py-game-C7N5JK0D.js.map → py-game-eWNz96mt.js.map} +1 -1
- package/dist/{py-terminal-Cy8siD6F.js → py-terminal-VtavPj1S.js} +2 -2
- package/dist/{py-terminal-Cy8siD6F.js.map → py-terminal-VtavPj1S.js.map} +1 -1
- package/dist/xterm_addon-fit-DxKdSnof.js +14 -0
- package/dist/xterm_addon-fit-DxKdSnof.js.map +1 -0
- package/dist/xterm_addon-web-links-B6rWzrcs.js +14 -0
- package/dist/xterm_addon-web-links-B6rWzrcs.js.map +1 -0
- package/dist/zip-CgZGjqjF.js +2 -0
- package/dist/zip-CgZGjqjF.js.map +1 -0
- package/package.json +16 -15
- package/src/3rd-party/xterm_addon-fit.js +14 -2
- package/src/3rd-party/xterm_addon-web-links.js +14 -2
- package/src/core.js +13 -2
- package/src/stdlib/pyscript/__init__.py +100 -31
- package/src/stdlib/pyscript/context.py +198 -0
- package/src/stdlib/pyscript/display.py +211 -127
- package/src/stdlib/pyscript/events.py +191 -88
- package/src/stdlib/pyscript/fetch.py +156 -25
- package/src/stdlib/pyscript/ffi.py +132 -16
- package/src/stdlib/pyscript/flatted.py +78 -1
- package/src/stdlib/pyscript/fs.py +207 -50
- package/src/stdlib/pyscript/media.py +210 -50
- package/src/stdlib/pyscript/storage.py +214 -27
- package/src/stdlib/pyscript/util.py +28 -7
- package/src/stdlib/pyscript/web.py +1079 -881
- package/src/stdlib/pyscript/websocket.py +252 -45
- package/src/stdlib/pyscript/workers.py +176 -27
- package/src/stdlib/pyscript.js +13 -13
- package/src/sync.js +1 -1
- package/types/stdlib/pyscript.d.ts +1 -1
- package/dist/codemirror-7vXPINKi.js.map +0 -1
- package/dist/codemirror_commands-CN4gxvZk.js.map +0 -1
- package/dist/codemirror_lang-python-CkOVBHci.js +0 -2
- package/dist/codemirror_lang-python-CkOVBHci.js.map +0 -1
- package/dist/codemirror_language-DOkvasqm.js +0 -2
- package/dist/codemirror_language-DOkvasqm.js.map +0 -1
- package/dist/codemirror_state-BIAL8JKm.js.map +0 -1
- package/dist/codemirror_view-Bt4sLgyA.js +0 -2
- package/dist/codemirror_view-Bt4sLgyA.js.map +0 -1
- package/dist/core-5ORB_Mcj.js +0 -4
- package/dist/core-5ORB_Mcj.js.map +0 -1
- package/dist/index-jZ1aOVVJ.js +0 -2
- package/dist/index-jZ1aOVVJ.js.map +0 -1
- package/dist/xterm_addon-fit--gyF3PcZ.js +0 -2
- package/dist/xterm_addon-fit--gyF3PcZ.js.map +0 -1
- package/dist/xterm_addon-web-links-D95xh2la.js +0 -2
- package/dist/xterm_addon-web-links-D95xh2la.js.map +0 -1
- package/dist/zip-CakRHzZu.js +0 -2
- package/dist/zip-CakRHzZu.js.map +0 -1
- package/src/stdlib/pyscript/magic_js.py +0 -84
|
@@ -1,64 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Display Pythonic content in the browser.
|
|
3
|
+
|
|
4
|
+
This module provides the `display()` function for rendering Python objects
|
|
5
|
+
in the web page. The function introspects objects to determine the appropriate
|
|
6
|
+
[MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types)
|
|
7
|
+
and rendering method.
|
|
8
|
+
|
|
9
|
+
Supported MIME types:
|
|
10
|
+
|
|
11
|
+
- `text/plain`: Plain text (HTML-escaped)
|
|
12
|
+
- `text/html`: HTML content
|
|
13
|
+
- `image/png`: PNG images as data URLs
|
|
14
|
+
- `image/jpeg`: JPEG images as data URLs
|
|
15
|
+
- `image/svg+xml`: SVG graphics
|
|
16
|
+
- `application/json`: JSON data
|
|
17
|
+
- `application/javascript`: JavaScript code (discouraged)
|
|
18
|
+
|
|
19
|
+
The `display()` function uses standard Python representation methods
|
|
20
|
+
(`_repr_html_`, `_repr_png_`, etc.) to determine how to render objects.
|
|
21
|
+
Objects can provide a `_repr_mimebundle_` method to specify preferred formats
|
|
22
|
+
like this:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
def _repr_mimebundle_(self):
|
|
26
|
+
return {
|
|
27
|
+
"text/html": "<b>Bold HTML</b>",
|
|
28
|
+
"image/png": "<base64-encoded-png-data>",
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Heavily inspired by
|
|
33
|
+
[IPython's rich display system](https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html).
|
|
34
|
+
"""
|
|
35
|
+
|
|
1
36
|
import base64
|
|
2
37
|
import html
|
|
3
38
|
import io
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
from pyscript.magic_js import current_target, document, window
|
|
39
|
+
from collections import OrderedDict
|
|
40
|
+
from pyscript.context import current_target, document, window
|
|
7
41
|
from pyscript.ffi import is_none
|
|
8
42
|
|
|
9
|
-
_MIME_METHODS = {
|
|
10
|
-
"savefig": "image/png",
|
|
11
|
-
"_repr_javascript_": "application/javascript",
|
|
12
|
-
"_repr_json_": "application/json",
|
|
13
|
-
"_repr_latex": "text/latex",
|
|
14
|
-
"_repr_png_": "image/png",
|
|
15
|
-
"_repr_jpeg_": "image/jpeg",
|
|
16
|
-
"_repr_pdf_": "application/pdf",
|
|
17
|
-
"_repr_svg_": "image/svg+xml",
|
|
18
|
-
"_repr_markdown_": "text/markdown",
|
|
19
|
-
"_repr_html_": "text/html",
|
|
20
|
-
"__repr__": "text/plain",
|
|
21
|
-
}
|
|
22
|
-
|
|
23
43
|
|
|
24
44
|
def _render_image(mime, value, meta):
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
45
|
+
"""
|
|
46
|
+
Render image (`mime`) data (`value`) as an HTML img element with data URL.
|
|
47
|
+
Any `meta` attributes are added to the img tag.
|
|
48
|
+
|
|
49
|
+
Accepts both raw bytes and base64-encoded strings for flexibility. This
|
|
50
|
+
only handles PNG and JPEG images. SVG images are handled separately as
|
|
51
|
+
their raw XML content (which the browser can render directly).
|
|
52
|
+
"""
|
|
28
53
|
if isinstance(value, bytes):
|
|
29
54
|
value = base64.b64encode(value).decode("utf-8")
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
base64_pattern = re.compile(
|
|
33
|
-
r"^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
|
|
34
|
-
)
|
|
35
|
-
# If value doesn't match the base64 pattern we should encode it to base64
|
|
36
|
-
if len(value) > 0 and not base64_pattern.match(value):
|
|
37
|
-
value = base64.b64encode(value.encode("utf-8")).decode("utf-8")
|
|
38
|
-
|
|
39
|
-
data = f"data:{mime};charset=utf-8;base64,{value}"
|
|
40
|
-
attrs = " ".join(['{k}="{v}"' for k, v in meta.items()])
|
|
41
|
-
return f'<img src="{data}" {attrs}></img>'
|
|
55
|
+
attrs = "".join([f' {k}="{v}"' for k, v in meta.items()])
|
|
56
|
+
return f'<img src="data:{mime};base64,{value}"{attrs}>'
|
|
42
57
|
|
|
43
58
|
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
# Maps MIME types to rendering functions.
|
|
60
|
+
_MIME_TO_RENDERERS = {
|
|
61
|
+
"text/plain": lambda v, m: html.escape(v),
|
|
62
|
+
"text/html": lambda v, m: v,
|
|
63
|
+
"image/png": lambda v, m: _render_image("image/png", v, m),
|
|
64
|
+
"image/jpeg": lambda v, m: _render_image("image/jpeg", v, m),
|
|
65
|
+
"image/svg+xml": lambda v, m: v,
|
|
66
|
+
"application/json": lambda v, m: v,
|
|
67
|
+
"application/javascript": lambda v, m: f"<script>{v}<\\/script>",
|
|
68
|
+
}
|
|
46
69
|
|
|
47
70
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
71
|
+
# Maps Python representation methods to MIME types. This is an ordered dict
|
|
72
|
+
# because the order defines preference when multiple methods are available,
|
|
73
|
+
# and MicroPython's limited dicts don't preserve insertion order.
|
|
74
|
+
_METHOD_TO_MIME = OrderedDict(
|
|
75
|
+
[
|
|
76
|
+
("savefig", "image/png"),
|
|
77
|
+
("_repr_png_", "image/png"),
|
|
78
|
+
("_repr_jpeg_", "image/jpeg"),
|
|
79
|
+
("_repr_svg_", "image/svg+xml"),
|
|
80
|
+
("_repr_html_", "text/html"),
|
|
81
|
+
("_repr_json_", "application/json"),
|
|
82
|
+
("_repr_javascript_", "application/javascript"),
|
|
83
|
+
("__repr__", "text/plain"),
|
|
84
|
+
]
|
|
85
|
+
)
|
|
57
86
|
|
|
58
87
|
|
|
59
88
|
class HTML:
|
|
60
89
|
"""
|
|
61
|
-
Wrap a string
|
|
90
|
+
Wrap a string to render as unescaped HTML in `display()`. This is
|
|
91
|
+
necessary because plain strings are automatically HTML-escaped for safety:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
from pyscript import HTML, display
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
display(HTML("<h1>Hello World</h1>"))
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Inspired by
|
|
101
|
+
[`IPython.display.HTML`](https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.HTML).
|
|
62
102
|
"""
|
|
63
103
|
|
|
64
104
|
def __init__(self, html):
|
|
@@ -68,112 +108,156 @@ class HTML:
|
|
|
68
108
|
return self._html
|
|
69
109
|
|
|
70
110
|
|
|
71
|
-
def
|
|
111
|
+
def _get_representation(obj, method):
|
|
72
112
|
"""
|
|
73
|
-
|
|
113
|
+
Call the given representation `method` on an object (`obj`).
|
|
114
|
+
|
|
115
|
+
Handles special cases like matplotlib's `savefig`. Returns `None`
|
|
116
|
+
if the `method` doesn't exist.
|
|
74
117
|
"""
|
|
75
|
-
if
|
|
118
|
+
if method == "__repr__":
|
|
76
119
|
return repr(obj)
|
|
77
|
-
if hasattr(obj,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def _format_mime(obj):
|
|
120
|
+
if not hasattr(obj, method):
|
|
121
|
+
return None
|
|
122
|
+
if method == "savefig":
|
|
123
|
+
buf = io.BytesIO()
|
|
124
|
+
obj.savefig(buf, format="png")
|
|
125
|
+
buf.seek(0)
|
|
126
|
+
return base64.b64encode(buf.read()).decode("utf-8")
|
|
127
|
+
return getattr(obj, method)()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _get_content_and_mime(obj):
|
|
90
131
|
"""
|
|
91
|
-
|
|
132
|
+
Returns the formatted raw content to be inserted into the DOM representing
|
|
133
|
+
the given object, along with the object's detected MIME type.
|
|
134
|
+
|
|
135
|
+
Returns a tuple of (html_string, mime_type).
|
|
136
|
+
|
|
137
|
+
Prefers _repr_mimebundle_ if available, otherwise tries individual
|
|
138
|
+
representation methods, falling back to __repr__ (with a warning in
|
|
139
|
+
the console).
|
|
140
|
+
|
|
141
|
+
Implements a subset of IPython's rich display system (mimebundle support,
|
|
142
|
+
etc...).
|
|
92
143
|
"""
|
|
93
144
|
if isinstance(obj, str):
|
|
94
145
|
return html.escape(obj), "text/plain"
|
|
95
|
-
|
|
96
|
-
mimebundle =
|
|
97
|
-
if
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
output, not_available = None, []
|
|
103
|
-
for method, mime_type in _MIME_METHODS.items():
|
|
104
|
-
if mime_type in format_dict:
|
|
105
|
-
output = format_dict[mime_type]
|
|
146
|
+
# Prefer an object's mimebundle.
|
|
147
|
+
mimebundle = _get_representation(obj, "_repr_mimebundle_")
|
|
148
|
+
if mimebundle:
|
|
149
|
+
if isinstance(mimebundle, tuple):
|
|
150
|
+
# Grab global metadata.
|
|
151
|
+
format_dict, global_meta = mimebundle
|
|
106
152
|
else:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
153
|
+
format_dict, global_meta = mimebundle, {}
|
|
154
|
+
# Try to render using mimebundle formats.
|
|
155
|
+
for mime_type, output in format_dict.items():
|
|
156
|
+
if mime_type in _MIME_TO_RENDERERS:
|
|
157
|
+
meta = global_meta.get(mime_type, {})
|
|
158
|
+
# If output is a tuple, merge format-specific metadata.
|
|
159
|
+
if isinstance(output, tuple):
|
|
160
|
+
output, format_meta = output
|
|
161
|
+
meta.update(format_meta)
|
|
162
|
+
return _MIME_TO_RENDERERS[mime_type](output, meta), mime_type
|
|
163
|
+
# No mimebundle or no available renderers therein, so try individual
|
|
164
|
+
# methods.
|
|
165
|
+
for method, mime_type in _METHOD_TO_MIME.items():
|
|
166
|
+
if mime_type not in _MIME_TO_RENDERERS:
|
|
110
167
|
continue
|
|
111
|
-
|
|
112
|
-
|
|
168
|
+
output = _get_representation(obj, method)
|
|
169
|
+
if output is None:
|
|
113
170
|
continue
|
|
114
|
-
break
|
|
115
|
-
if is_none(output):
|
|
116
|
-
if not_available:
|
|
117
|
-
window.console.warn(
|
|
118
|
-
f"Rendered object requested unavailable MIME renderers: {not_available}"
|
|
119
|
-
)
|
|
120
|
-
output = repr(output)
|
|
121
|
-
mime_type = "text/plain"
|
|
122
|
-
elif isinstance(output, tuple):
|
|
123
|
-
output, meta = output
|
|
124
|
-
else:
|
|
125
171
|
meta = {}
|
|
126
|
-
|
|
172
|
+
if isinstance(output, tuple):
|
|
173
|
+
output, meta = output
|
|
174
|
+
return _MIME_TO_RENDERERS[mime_type](output, meta), mime_type
|
|
175
|
+
# Ultimate fallback to repr with warning.
|
|
176
|
+
window.console.warn(
|
|
177
|
+
f"Object {type(obj).__name__} has no supported representation method. "
|
|
178
|
+
"Using __repr__ as fallback."
|
|
179
|
+
)
|
|
180
|
+
output = repr(obj)
|
|
181
|
+
return html.escape(output), "text/plain"
|
|
127
182
|
|
|
128
183
|
|
|
129
|
-
def
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
184
|
+
def _write_to_dom(element, value, append):
|
|
185
|
+
"""
|
|
186
|
+
Given an `element` and a `value`, write formatted content to the referenced
|
|
187
|
+
DOM element. If `append` is True, content is added to the existing content;
|
|
188
|
+
otherwise, the existing content is replaced.
|
|
133
189
|
|
|
190
|
+
Creates a wrapper `div` when appending multiple items to preserve
|
|
191
|
+
structure.
|
|
192
|
+
"""
|
|
193
|
+
html_content, mime_type = _get_content_and_mime(value)
|
|
194
|
+
if not html_content.strip():
|
|
195
|
+
return
|
|
134
196
|
if append:
|
|
135
|
-
|
|
136
|
-
element.append(
|
|
197
|
+
container = document.createElement("div")
|
|
198
|
+
element.append(container)
|
|
137
199
|
else:
|
|
138
|
-
|
|
139
|
-
if is_none(out_element):
|
|
140
|
-
out_element = element
|
|
141
|
-
|
|
200
|
+
container = element
|
|
142
201
|
if mime_type in ("application/javascript", "text/html"):
|
|
143
|
-
|
|
144
|
-
out_element.append(script_element)
|
|
202
|
+
container.append(document.createRange().createContextualFragment(html_content))
|
|
145
203
|
else:
|
|
146
|
-
|
|
204
|
+
container.innerHTML = html_content
|
|
147
205
|
|
|
148
206
|
|
|
149
207
|
def display(*values, target=None, append=True):
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
elif not isinstance(target, str):
|
|
153
|
-
msg = f"target must be str or None, not {target.__class__.__name__}"
|
|
154
|
-
raise TypeError(msg)
|
|
155
|
-
elif target == "":
|
|
156
|
-
msg = "Cannot have an empty target"
|
|
157
|
-
raise ValueError(msg)
|
|
158
|
-
elif target.startswith("#"):
|
|
159
|
-
# note: here target is str and not None!
|
|
160
|
-
# align with @when behavior
|
|
161
|
-
target = target[1:]
|
|
208
|
+
"""
|
|
209
|
+
Display Python objects in the web page.
|
|
162
210
|
|
|
163
|
-
|
|
211
|
+
* `*values`: Python objects to display. Each object is introspected to
|
|
212
|
+
determine the appropriate rendering method.
|
|
213
|
+
* `target`: DOM element ID where content should be displayed. If `None`
|
|
214
|
+
(default), uses the current script tag's designated output area. This
|
|
215
|
+
can start with '#' (which will be stripped for compatibility).
|
|
216
|
+
* `append`: If `True` (default), add content to existing output. If
|
|
217
|
+
`False`, replace existing content before displaying.
|
|
164
218
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
219
|
+
When used in a worker, `display()` requires an explicit `target` parameter
|
|
220
|
+
to identify where content will be displayed. If used on the main thread,
|
|
221
|
+
it automatically uses the current `<script>` tag as the target. If the
|
|
222
|
+
script tag has a `target` attribute, that element will be used instead.
|
|
223
|
+
|
|
224
|
+
A ValueError is raised if a valid target cannot be found for the current
|
|
225
|
+
context.
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
from pyscript import display, HTML
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# Display raw HTML.
|
|
232
|
+
display(HTML("<h1>Hello, World!</h1>"))
|
|
233
|
+
|
|
234
|
+
# Display in current script's output area.
|
|
235
|
+
display("Hello, World!")
|
|
236
|
+
|
|
237
|
+
# Display in a specific element.
|
|
238
|
+
display("Hello", target="my-div")
|
|
169
239
|
|
|
170
|
-
#
|
|
171
|
-
|
|
172
|
-
|
|
240
|
+
# Replace existing content (note the `#`).
|
|
241
|
+
display("New content", target="#my-div", append=False)
|
|
242
|
+
|
|
243
|
+
# Display multiple values in the default target.
|
|
244
|
+
display("First", "Second", "Third")
|
|
245
|
+
```
|
|
246
|
+
"""
|
|
247
|
+
if isinstance(target, str):
|
|
248
|
+
# There's a valid target.
|
|
249
|
+
target = target[1:] if target.startswith("#") else target
|
|
250
|
+
elif is_none(target):
|
|
251
|
+
target = current_target()
|
|
252
|
+
element = document.getElementById(target)
|
|
253
|
+
if is_none(element):
|
|
254
|
+
raise ValueError(f"Cannot find element with id='{target}' in the page.")
|
|
255
|
+
# If possible, use a script tag's target attribute.
|
|
173
256
|
if element.tagName == "SCRIPT" and hasattr(element, "target"):
|
|
174
257
|
element = element.target
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
258
|
+
# Clear before displaying all values when not appending.
|
|
259
|
+
if not append:
|
|
260
|
+
element.replaceChildren()
|
|
261
|
+
# Add each value.
|
|
262
|
+
for value in values:
|
|
263
|
+
_write_to_dom(element, value, append)
|