Skip to content

Commit b27aef9

Browse files
committed
Fix #77 - Update and improve builtins documentation
1 parent e84f499 commit b27aef9

File tree

1 file changed

+170
-18
lines changed

1 file changed

+170
-18
lines changed

docs/user-guide/builtins.md

+170-18
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,25 @@ code running on a web worker:
2222

2323
### `pyscript.window`
2424

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
2628
[global window context](https://developer.mozilla.org/en-US/docs/Web/API/Window).
2729

2830
!!! warning
2931

3032
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
3335
`globalThis`).
3436

3537
### `pyscript.document`
3638

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
3840
[document object](https://developer.mozilla.org/en-US/docs/Web/API/Document).
3941
The `document` is a representation of the
4042
[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.
4244

4345
### `pyscript.display`
4446

@@ -50,23 +52,59 @@ The `display` function takes a list of `*values` as its first argument, and has
5052
two optional named arguments:
5153

5254
* `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.
5357
* `append=True` - a flag to indicate if the output is going to be appended to
5458
the `target`.
5559

5660
There are some caveats:
5761

5862
* 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.
6468
* When used in a worker, the `display` function needs an explicit
6569
`target="dom-id"` argument to identify where the content will be
6670
displayed.
6771
* In both the main thread and worker, `append=True` is the default
6872
behaviour.
6973

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+
70108
### `pyscript.when`
71109

72110
A Python decorator to indicate the decorated function should handle the
@@ -102,7 +140,7 @@ def click_handler(event):
102140
display("I've been clicked!")
103141
```
104142

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).
106144

107145
### `pyscript.js_modules`
108146

@@ -208,24 +246,138 @@ the function to an event. Should you not `create_proxy` around the callback
208246
function, it will be immediately garbage collected after being bound to the
209247
event.
210248

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+
&lt;em&gt;em&lt;/em&gt;
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+
211340
## Main-thread only features
212341

213342
### `pyscript.PyWorker`
214343

215344
A class used to instantiate a new worker from within Python.
216345

217-
!!! danger
346+
!!! Note
218347

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.
220357

221358
The following fragment demonstrates who to start the Python code in the file
222359
`worker.py` on a new worker from within Python.
223360

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
226373

374+
display("Hello World", target="output", append=True)
227375

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")
229381
```
230382

231383
## Worker only features
@@ -269,9 +421,9 @@ use of inline event handlers via custom HTML attributes.
269421
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)
270422
of why this is currently considered bad practice.
271423

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
273425
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`).
275427
This is similar to how all
276428
[event handlers on elements](https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects)
277429
start with `on` in standard HTML (e.g. `onclick`). The rule of thumb is to

0 commit comments

Comments
 (0)