@@ -22,23 +22,25 @@ code running on a web worker:
22
22
23
23
### ` pyscript.window `
24
24
25
- This object is a proxy for the web page's
25
+ On the main thread, this object is a direct reference to the ` import js ` module which, in turn, is a proxy of the [ globalThis] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis ) .
26
+
27
+ On a worker thread, this object is a proxy for the web page's
26
28
[ global window context] ( https://developer.mozilla.org/en-US/docs/Web/API/Window ) .
27
29
28
30
!!! warning
29
31
30
32
Please note that in workers, this is still the main window, not the
31
- worker's own global context. A worker's global context is reachable instead
32
- via `import js` (the `js` object being a proxy for the worker's
33
+ worker's own global context. A worker's global context is always reachable
34
+ instead via `import js` (the `js` object being a proxy for the worker's
33
35
`globalThis`).
34
36
35
37
### ` pyscript.document `
36
38
37
- This object is a proxy for the the web page's
39
+ On both main and worker threads, this object is a proxy for the the web page's
38
40
[ document object] ( https://developer.mozilla.org/en-US/docs/Web/API/Document ) .
39
41
The ` document ` is a representation of the
40
42
[ DOM] ( https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Using_the_Document_Object_Model )
41
- and can be used to manipulate the content of the web page.
43
+ and can be used to read or manipulate the content of the web page.
42
44
43
45
### ` pyscript.display `
44
46
@@ -50,23 +52,59 @@ The `display` function takes a list of `*values` as its first argument, and has
50
52
two optional named arguments:
51
53
52
54
* ` target=None ` - the DOM element into which the content should be placed.
55
+ If not specified, the ` target ` will use the ` current_script() ` returned id
56
+ and populate the related dedicated node to show the content.
53
57
* ` append=True ` - a flag to indicate if the output is going to be appended to
54
58
the ` target ` .
55
59
56
60
There are some caveats:
57
61
58
62
* When used in the main thread, the ` display ` function automatically uses
59
- the current ` <script> ` tag as the ` target ` into which the content will
60
- be displayed.
61
- * If the ` <script> ` tag has the ` target ` attribute, the element on the page
62
- with that ID (or which matches that selector) will be used to display
63
- the content instead.
63
+ the current ` <py- script> ` or ` <mpy-script> ` tag as the ` target ` into which
64
+ the content will be displayed.
65
+ * If the ` <script> ` tag has the ` target ` attribute, and is not a worker,
66
+ the element on the page with that ID (or which matches that selector)
67
+ will be used to display the content instead.
64
68
* When used in a worker, the ` display ` function needs an explicit
65
69
` target="dom-id" ` argument to identify where the content will be
66
70
displayed.
67
71
* In both the main thread and worker, ` append=True ` is the default
68
72
behaviour.
69
73
74
+
75
+ ``` html title="Some display example"
76
+ <!-- will produce
77
+ <py-script>PyScript</py-script>
78
+ -->
79
+ <py-script worker >
80
+ from pyscript import display
81
+ display("PyScript", append=False)
82
+ </py-script >
83
+
84
+ <!-- will produce
85
+ <script type="py">...</script>
86
+ <script-py>PyScript</script-py>
87
+ -->
88
+ <script type =" py" >
89
+ from pyscript import display
90
+ display (" PyScript" , append= False)
91
+ </script >
92
+
93
+ <!-- will populate <h1>PyScript</h1> -->
94
+ <script type =" py" target =" my-h1" >
95
+ from pyscript import display
96
+ display (" PyScript" , append= False)
97
+ </script >
98
+ <h1 id =" my-h1" ></h1 >
99
+
100
+ <!-- will populate <h2>PyScript</h2> -->
101
+ <script type =" py" worker >
102
+ from pyscript import display
103
+ display (" PyScript" , target= " my-h2" , append= False)
104
+ </script >
105
+ <h2 id =" my-h2" ></h2 >
106
+ ```
107
+
70
108
### ` pyscript.when `
71
109
72
110
A Python decorator to indicate the decorated function should handle the
@@ -102,7 +140,7 @@ def click_handler(event):
102
140
display(" I've been clicked!" )
103
141
```
104
142
105
- This functionality is related to the [ HTML py-* ] ( #html-attributes ) attributes .
143
+ This functionality is related to the ` py-* ` or ` mpy-* ` [ HTML attributes ] ( #html-attributes ) .
106
144
107
145
### ` pyscript.js_modules `
108
146
@@ -208,24 +246,138 @@ the function to an event. Should you not `create_proxy` around the callback
208
246
function, it will be immediately garbage collected after being bound to the
209
247
event.
210
248
249
+ !!! warning
250
+
251
+ In *Pyodide* it's expected that the created proxy is explicitly destroyed
252
+ when it's not needed / used anymore but that `proxy.destroy()` method has
253
+ not been implemented in *MicroPython* (yet).
254
+ To try simplifying this dance and automatically destroy proxies, based on
255
+ JS Garbage Collector heuristics, we have introduced an **experimental flag**
256
+ called `experimental_create_proxy = "auto"` which currently tries to be
257
+ smart enough to orchestrate the whole proxy creation and destruction dance
258
+ out of the box.
259
+ If you'd like to try that flag keep in mind you should never need or care about
260
+ using explictly *create_proxy* but like it is with everything experimental,
261
+ there might be edge cases we have not (yet) tackled.
262
+
263
+ ### ` pyscript.current_target `
264
+
265
+ A utility function to retrieve the unique identifier of the element used
266
+ to display content. If the element is not a ` <script> ` and it has already
267
+ an ` id ` , that ` id ` will be returned.
268
+
269
+ ``` html title="The current_target utility"
270
+ <!-- current_target(): explicit-id -->
271
+ <mpy-script id =" explicit-id" >
272
+ from pyscript import display, current_target
273
+ display(f"current_target(): {current_target()}")
274
+ </mpy-script >
275
+
276
+ <!-- current_target(): mpy-0 -->
277
+ <mpy-script >
278
+ from pyscript import display, current_target
279
+ display(f"current_target(): {current_target()}")
280
+ </mpy-script >
281
+
282
+ <!-- current_target(): mpy-1 -->
283
+ <!-- creates right after the <script>:
284
+ <script-py id="mpy-1">
285
+ <div>current_target(): mpy-1</div>
286
+ </script-py>
287
+ -->
288
+ <script type =" mpy" >
289
+ from pyscript import display, current_target
290
+ display (f" current_target(): {current_target()}" )
291
+ </script >
292
+ ```
293
+
294
+ !!! Note
295
+
296
+ Please note that `current_target()` points at a visible element on the page,
297
+ **not** at the current `<script>` that is executing the code.
298
+ If you need to explicitly reach the `<script>` element, you can always assign
299
+ an `id` to it so that at any time, within any listener or functionality,
300
+ you can `document.getElementById(script_id)` to reach out that element:
301
+ `<script type="mpy" id="unique-id">...</script>`
302
+
303
+ ### ` pyscript.HTML `
304
+
305
+ A class utility able to wrap a generic content and display it on the page.
306
+ The content can be any of these mime types:
307
+
308
+ * ` text/plain ` to show the content as text
309
+ * ` text/html ` to show the content as * HTML*
310
+ * ` image/png ` to show the content as ` <img> `
311
+ * ` image/jpeg ` to show the content as ` <img> `
312
+ * ` image/svg+xml ` to show the content as ` <svg> `
313
+ * ` application/json ` to show the content as * JSON*
314
+ * ` application/javascript ` to put the content in ` <script> ` (discouraged)
315
+
316
+ ``` html title="The HTML class"
317
+ <!-- display escaped text:
318
+ <em>em</em>
319
+ -->
320
+ <script type =" mpy" >
321
+ from pyscript import display, HTML
322
+ display (" <em>em</em>" )
323
+ </script >
324
+
325
+ <!-- display exactly this HTML:
326
+ <em>em</em>
327
+ -->
328
+ <script type =" mpy" >
329
+ from pyscript import display, HTML
330
+ display (HTML (" <em>em</em>" ))
331
+ </script >
332
+ ```
333
+
334
+ ### ` pyscript.RUNNING_IN_WORKER `
335
+
336
+ This constant indicates when the current code is running within a * worker* or within the * main* thread.
337
+
338
+ It is ` True ` when the current code is executing in a * worker* , ` False ` when the code is running on * main* .
339
+
211
340
## Main-thread only features
212
341
213
342
### ` pyscript.PyWorker `
214
343
215
344
A class used to instantiate a new worker from within Python.
216
345
217
- !!! danger
346
+ !!! Note
218
347
219
- Currently this only works with Pyodide.
348
+ We currently changed names within the JS module's exports to
349
+ bootstrap and disambiguate `PyWorker` from `MPWorker` and
350
+ automatically use the right interpreter behind the scene.
351
+ The Python class currently is always named `PyWorker` and
352
+ it requires at least a valid `type` option, [among others](https://pyscript.github.io/polyscript/#xworker-options),
353
+ which must be either `micropython` or `pyodide`.
354
+ We will keep this feature alive but in the future this might default
355
+ to `pyodide` unless a new `MPWorker` class is also exported which will
356
+ default to `micropython` instead. The explicit `type` would still exist.
220
357
221
358
The following fragment demonstrates who to start the Python code in the file
222
359
` worker.py ` on a new worker from within Python.
223
360
224
- ``` python title="Starting a new worker from Python"
225
- from pyscript import PyWorker
361
+ ``` html title="Starting a new worker from Python"
362
+ <script type =" mpy" >
363
+ from pyscript import PyWorker
364
+
365
+ # type can be either ` micropython` or ` pyodide`
366
+ PyWorker (" worker.py" , type= " micropython" )
367
+ </script >
368
+ <div id =" output" ></div >
369
+ ```
370
+
371
+ ``` python title="the worker.py content"
372
+ from pyscript import RUNNING_IN_WORKER , display, sync
226
373
374
+ display(" Hello World" , target = " output" , append = True )
227
375
228
- a_worker = PyWorker(" ./worker.py" )
376
+ # will log into devtools console
377
+ print (RUNNING_IN_WORKER ) # True
378
+ print (" sleeping" )
379
+ sync.sleep(1 )
380
+ print (" awake" )
229
381
```
230
382
231
383
## Worker only features
@@ -269,9 +421,9 @@ use of inline event handlers via custom HTML attributes.
269
421
Mozilla [have a good explanation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#inline_event_handlers_%E2%80%94_dont_use_these)
270
422
of why this is currently considered bad practice.
271
423
272
- These attributes are expressed as ` py-* ` attributes of an HTML element that
424
+ These attributes are expressed as ` py-* ` or ` mpy-* ` attributes of an HTML element that
273
425
reference the name of a Python function to run when the event is fired. You
274
- should replace the ` * ` with the _ actual name of an event_ (e.g. ` py-click ` ).
426
+ should replace the ` * ` with the _ actual name of an event_ (e.g. ` py-click ` or ` mpy-click ` ).
275
427
This is similar to how all
276
428
[ event handlers on elements] ( https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects )
277
429
start with ` on ` in standard HTML (e.g. ` onclick ` ). The rule of thumb is to
0 commit comments