-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path_pyscript_dev.html
131 lines (101 loc) · 4.55 KB
/
_pyscript_dev.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/releases/2024.10.2/core.css">
<script type="module" src="https://pyscript.net/releases/2024.10.2/core.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--
set `script[@type='py']` with :
config='{"packages":["htag"]}' # runned as local file (using pypi htag latest)
config='{"packages":["./dist/htag-0.0.0-py3-none-any.whl"]}' # runned thru a webserver(*) (using local whl from webserver)
(*) This thing is complex to test/develop (need to use a local wheel, thru a webserver), you'll need to do :
- poetry build # to produce dist/htag-0.0.0-py3-none-any.whl
- python3 -m http.server 8001
- chrome http://localhost:8001/_pyscript_dev2_.html
-->
</head>
<body> loading (recent/2024) pyscript ;-)
<!--script type="py" config='{"packages":["htag"]}'-->
<script type="py" config='{"packages":["./dist/htag-0.0.0-py3-none-any.whl"]}'>
from htag import Tag
import asyncio,time
class App(Tag.body):
statics="body {background:#EEE;}"
def init(self):
self.place = Tag.div()
asyncio.ensure_future( self.loop_timer() )
self += "Hello World" + self.place
self+= Tag.button("yo",_onclick=self.doit)
async def doit(self,o):
self+="x"
async def loop_timer(self):
while self.place:
self.place.clear(time.time() )
await self.place.update() # !!! update component (with tag.update() ) !!!
await asyncio.sleep(0.5)
###############################################################################
## here is the htag.runner.pyscript file (easier to modify in place)
## should be the same as "htag.runner.pyscript.py"
###############################################################################
from htag.render import HRenderer
from htag.runners import commons
import json
class PyScript2:
def __init__(self,tagClass:type):
#TODO: __init__ could accept a 'file' parameter based on localstorage to make persistent session !
assert issubclass(tagClass,Tag)
self.tagClass=tagClass
def run(self,window=None): # window: "pyscript js.window"
if window is None:
try:
from js import window # this import should work in pyscript context ;-)
except:
pass
self.window=window
js = """
interact=async function(o) {
action( await window.interactions( JSON.stringify(o) ) );
}
function pyscript_starter() {
if(document.querySelector("*[needToLoadBeforeStart]"))
window.setTimeout( pyscript_starter, 100 )
else
window.start()
}
"""
self.hr = HRenderer(self.tagClass, js, init=commons.url2ak( window.document.location.href ))
self.hr.sendactions=self.updateactions
window.interactions = self.interactions
assert window.document.head, "No <head> in <html>"
assert window.document.body, "No <body> in <html>"
# install statics in headers
window.document.head.innerHTML=""
for s in self.hr._statics:
if isinstance(s,Tag):
tag=window.document.createElement(s.tag)
tag.innerHTML = "".join([str(i) for i in s.childs if i is not None])
for key,value in s.attrs.items():
setattr(tag, key, value)
if key in ["src","href"]:
tag.setAttribute("needToLoadBeforeStart", True)
tag.onload = lambda o: o.target.removeAttribute("needToLoadBeforeStart")
window.document.head.appendChild(tag)
# install the first object in body
window.document.body.outerHTML=str(self.hr)
# and start the process
window.pyscript_starter() # will run window.start, when dom ready
async def interactions(self, o):
data=json.loads(o)
actions = await self.hr.interact( data["id"], data["method"], data["args"], data["kargs"], data.get("event") )
return json.dumps(actions)
async def updateactions(self, actions:dict):
self.window.action( json.dumps(actions) ) # send action as json (not a js(py) object) ;-(
return True
###############################################################################
# the runner part
###############################################################################
#from htag.runners import PyScript
PyScript2( App ).run() # use local one
</script>
</body>
</html>