Skip to content

Commit 5b2cb87

Browse files
committed
feat: add import files via pyscript config file.
1 parent ecb5fbb commit 5b2cb87

16 files changed

Lines changed: 493 additions & 0 deletions

File tree

index.html

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<!-- Semantic tags: 'https://www.semrush.com/blog/semantic-html5-guide/', 'https://developer.mozilla.org/en-US/docs/Glossary/Semantics#semantic_elements'. -->
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<!-- Window title. -->
8+
<title>Antigravity</title>
9+
<!-- Window logo. -->
10+
<link rel="icon" type="image/png" href="/rsrcs/media/icon-favicon.png" />
11+
<!--
12+
External CSS stylesheet: 'https://www.w3schools.com/html/html_css.asp', 'https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/link'.
13+
- In this case, PyScript CSS.
14+
-->
15+
<link rel="stylesheet" href="https://pyscript.net/releases/2025.8.1/core.css" />
16+
<!-- External (local) CSS stylesheet, with multiple external CSS links. ORDER MATTERS! 'https://www.programminghead.com/how-to-link-multiple-css-style-sheets-in-html'. -->
17+
<link rel="stylesheet" href="/rsrcs/css_styles/style-loading_splashscreen.css">
18+
<link rel="stylesheet" href="/rsrcs/css_styles/style.css">
19+
<!--
20+
Script call; e.g. this js script tag bootstraps PyScript.
21+
- NOTE: threated as deferred script. Ref. 'https://stackoverflow.com/questions/436411/where-should-i-put-script-tags-in-html-markup/24070373#24070373'.
22+
-->
23+
<script type="module" src="https://pyscript.net/releases/2025.8.1/core.js"></script>
24+
<!--
25+
JS script call: (module) loading splashscreen.
26+
- If 'type' not defined, defaults to 'text/javascript': 'https://www.w3schools.com/tags/att_script_type.asp'.
27+
- For HTML 5, if default, discouraged to be explicit, since it's redundant: 'https://stackoverflow.com/questions/4195427/is-the-type-attribute-necessary-for-script-tags/4195504#4195504'.
28+
- 'type' module: 'https://forum.freecodecamp.org/t/the-type-module-in-html-file-whats-for/488865', 'https://stackoverflow.com/questions/39652618/classic-scripts-vs-module-scripts-in-javascript/53821485#53821485'.
29+
- 'module' scripts: 'https://neerajdana.medium.com/understanding-type-module-in-javascript-a-comprehensive-guide-ebb13926da7a'.
30+
- 'module' vs. 'non-module' scripts: 'https://neerajdana.medium.com/understanding-type-module-in-javascript-a-comprehensive-guide-ebb13926da7a'.
31+
-->
32+
<script type="module" src="/rsrcs/code_functionalities/app-loading_splashscreen.js"></script>
33+
</head>
34+
<body>
35+
<!-- Main dialog (as 'modal', defined in js module 'app-loading_splashscreen.js'), what appears 1st as sson as web page is loaded. -->
36+
<dialog id="dialog_loading">
37+
<h1>Loading...</h1>
38+
</dialog>
39+
<main>
40+
<nav class="main-nav">
41+
<div class="main-nav-header">
42+
<!-- '/' in 'href' redirects to ROOT / HOME vs. '#' thta redirects to TOP of CURRENT PAGE (causing scrolling): 'https://stackoverflow.com/questions/17772692/what-does-it-means-when-there-is-fowards-slash-after-a-href/17772747#17772747', 'https://www.w3schools.com/tags/att_a_href.asp'. -->
43+
<a href="/"><img class="main-nav-header-logo" src="./rsrcs/media/img-logo.png" /></a>
44+
<!-- Blank 'href' REFRESH CURRENT PAGE; i.e. act as hyperlink to CURRENT PAGE: 'https://stackoverflow.com/questions/4855168/what-is-href-and-why-is-it-used/21397285#21397285'. -->
45+
<a class="main-nav-header-title" href="">Antigravity</a>
46+
</div>
47+
</nav>
48+
<section class="main-pyscript">
49+
<h1>Hello world!</h1>
50+
<br>
51+
<hr>
52+
<!-- Display content: 'https://docs.pyscript.net/2024.5.2/user-guide/builtins/#pyscriptdisplay'. -->
53+
<h2>Using 'pyscript.display': default (i.e. 'append=True') vs. 'append=False'.</h2>
54+
<ul>
55+
<li><b>Default</b>: encapsulates the result from 'pyscript.display' between a 'div' tag. Then the 'div' gets ADDED to the inner content of the target DOM element.</li>
56+
<li><b>'append=False'</b>: RE-WRITES WHATEVER previous inner content of the target DOM, with the result from 'pyscript.display'.</li>
57+
</ul>
58+
<br>
59+
<p><b>IMPORTANT</b>: whenever as possible, create an html element (and include an id) to populate with the result of 'pyscript.display' by using the 'target=' parameter / property. Otherwise, <b>un-expected behaviours</b> can happen, as the one described <i>in the comments of this html</i>.</p>
60+
<br>
61+
<p>Use the 'target=' specification inside the pyscript as a <b>parameter</b> of the 'pyscript.display' function: '<code>from pyscript import display display("PyScript running...", target="pyscript_output")</code>'.</p>
62+
<br>
63+
<p><b>CASE 01: default, default.</b></p>
64+
<p><i>Default:</i></p>
65+
<!--
66+
If running ALONE: 'pyscript.display' adds new html element '<script-py>'', right after <script>...</script>: '<script-py id="py-0"><div>...<result_from_pyscript01>...</div></script-py>'.
67+
- IMPORTANT: 'div' is added to ATTACH result, to ANY PREVIOUS inner content of the target DOM element; in this case '<script-py>', since target DOM wasn't specified in the 'pyscript.display' function.
68+
-->
69+
<script type="py" defer>
70+
from pyscript import display
71+
display("This is PyScript running... Default.", target="pyscript_tests_case01a")
72+
</script>
73+
<p id="pyscript_tests_case01a"></p>
74+
<p><i>Default:</i></p>
75+
<!--
76+
When both 'script's run sequentially, it adds new html elements, but both results get placed at the end, RIGHT AFTER the LAST <script>...</script> EXECUTED (in case, target DOMs were NOT specified in the 'pyscript.display' functions):
77+
- For 1st script, html element '<script-py id="py-0"></script-py>', still gets created in-place as regular (i.e. after the corresponding '<script>' element), but EMPTY; i.e. '<script-py id="py-0"></script-py>'.
78+
- Outputs are ALL created and assigned to LAST html element '<script-py>' (in case, target DOMs were NOT specified in the 'pyscript.display' functions): '<script-py id="py-1"><div>...<result_from_pyscript01>...</div><div>...<result_from_pyscript02>...</div></script-py>'; id="py-0" to "py-1", in this case for x2 pyscripts executions.
79+
-->
80+
<script type="py" defer>
81+
from pyscript import display
82+
display("This is PyScript running... Default.", target="pyscript_tests_case01b")
83+
</script>
84+
<p id="pyscript_tests_case01b"></p>
85+
<br>
86+
<p><b>CASE 02: default, 'append=False'.</b></p>
87+
<p><i>Default:</i></p>
88+
<!-- [As first example.] -->
89+
<script type="py" defer>
90+
from pyscript import display
91+
display("This is PyScript running... Default.", target="pyscript_tests_case02a")
92+
</script>
93+
<p id="pyscript_tests_case02a"></p>
94+
</p><i>'append=False':</i></p>
95+
<!--
96+
If running ALONE: 'pyscript.display' adds new html element '<script-py>'', right after <script>...</script> (without <div>): '<script-py id="py-0">...<result_from_display>...</script-py>'.
97+
- IMPORTANT: this time, there are no '<div>', since ANY PREVIOUS inner content of the target DOM element is OVERWRITTEN.
98+
-->
99+
<!--
100+
When both 'script's run sequentially, it adds new html elements, but both results get placed at the end, RIGHT AFTER the LAST <script>...</script> EXECUTED (in case, target DOMs were NOT specified in the 'pyscript.display' functions):
101+
- For 1st script, html element '<script-py id="py-0"></script-py>', still gets created in-place as regular (i.e. after the corresponding '<script>' element), but EMPTY; i.e. '<script-py id="py-0"></script-py>'.
102+
- Created outputs depend on which pyscripts were run with 'append=False'. Any pyscript as such, WILL OVERWRITE ANY PREVIOUS inner content of the target DOM (in case, target DOMs were NOT specified in the 'pyscript.display' functions); in this case, 1st pyscript is overwritten and only results from 2nd pyscript are showed: '<script-py id="py-1">...<result_from_pyscript02>...</script-py>'; id="py-0" to "py-1", in this case for x2 scripts executions.
103+
-->
104+
<script type="py" defer>
105+
from pyscript import display
106+
display("This is PyScript running... 'append=False'.", append=False, target="pyscript_tests_case02b")
107+
</script>
108+
<p id="pyscript_tests_case02b"></p>
109+
<br>
110+
<h2>Example with 'pyscript.display': review 'pyscript.config' parameters.</h2>
111+
<script type="py" defer>
112+
from pyscript import display, config
113+
display(config.get("files"), target="pyscript_output_config_files")
114+
display(config.get("packages"), target="pyscript_output_config_packages")
115+
</script>
116+
<p id="pyscript_output_config_files"><b>Config. files</b>: </p>
117+
<p id="pyscript_output_config_packages"><b>Config packages</b>: </p>
118+
<br>
119+
<h2>Example with 'pyscript.display': display date and time. DOESN'T USE 'target=' specification.</h2>
120+
<p>This is the current date and time, as computed by Python:</p>
121+
<script type="py" defer>
122+
from pyscript import display
123+
from datetime import datetime
124+
now = datetime.now()
125+
display(now.strftime("%m/%d/%Y, %H:%M:%S"))
126+
</script>
127+
<br>
128+
<hr>
129+
</section>
130+
<section class="main-pyscript">
131+
<b>Based on xkcd: antigravity <a href="https://xkcd.com/353/" target="_blank">https://xkcd.com/353/</a>.</b>
132+
<script type="py" src="/rsrcs/code_functionalities/main.py" config="/rsrcs/code_imports/main-pyscript.json" defer></script>
133+
<!--
134+
TODO: investigate how to redirect output to an html element.
135+
- So far, un-successful; e.g. use 'svg' element.
136+
- For now, it renders output in a 'svg' tag, but OUT of 'main', but inside of 'body'. Check with developer tools (F12), in a regular web-browser.
137+
-->
138+
<!-- <svg id="pyscript_output"></svg> -->
139+
</section>
140+
</main>
141+
</body>
142+
</html>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// VARIABLES DECLARATION.
2+
// 'conts' vs. 'let' vs. 'var': 'https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/'.
3+
const HTML_LOADING = document.getElementById('dialog_loading');
4+
5+
// CODE EXECUTION.
6+
7+
// Add an event listener to browser's window: 'https://stackoverflow.com/questions/43558169/addeventlistener-as-a-global-function/43558191#43558191', 'https://www.w3schools.com/jsref/obj_window.asp'.
8+
addEventListener('py:ready', () => HTML_LOADING.close()); // When loading python script is ready, close HTML_LOADING element: 'https://www.w3schools.com/jsreF/met_dialog_close.asp'.
9+
HTML_LOADING.showModal(); // Show 'modal' dialog; i.e. dialog that locks user interactivity: 'https://www.w3schools.com/jsreF/met_dialog_showModal.asp', 'https://dev.to/iam_timsmith/dialogs-vs-modals-is-there-a-difference-210k'.

rsrcs/code_functionalities/main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import antigravity
2+
3+
antigravity.fly()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"files": {
3+
"/rsrcs/io_inputs/config/antigravity.py": ""
4+
}
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* Use of 'media queries' to define layouts according to specific screen resolutions: 'https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries#targeting_media_features'. */
2+
@media (width > 0px) { /* Base design, as starting point: e.g. for desktop, although recommended to start with mobile, 1st: 'https://stackoverflow.com/questions/6370690/media-queries-how-to-target-desktop-tablet-and-mobile/20350990#20350990'. */
3+
4+
/* CUSTOM CLASSES. */
5+
6+
/* Loading splashscreen: 'modal' dialog; i.e. dialog that locks user interactivity. */
7+
#dialog_loading {
8+
margin: auto; /* If setting 'margin: 0;' in all html elements; i.e. in CSS '* { margin: 0; }', restores default margin so it's centered: 'https://stackoverflow.com/questions/73925255/how-can-the-html-dialog-element-be-positioned-according-to-normal-flow-when-op/77652902#77652902'. */
9+
color: #CCDAD1; /* If setting a 'dark theme' for the body; i.e. in CSS 'body { background-color: var(--colors_background); color: var(--colors_01); }', to match theme. 'dialog' elements do not inherit properties from 'html' and child elements, like 'body'. */
10+
outline: none;
11+
border: none;
12+
width: 100vw;
13+
height: 100vh;
14+
background-color: rgb(0 0 0 / 0.85); /* Make a box semi-transparent: 'https://developer.mozilla.org/en-US/docs/Learn_web_development/Howto/Solve_CSS_problems/Make_box_transparent'.*/
15+
}
16+
17+
}

rsrcs/css_styles/style.css

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/* IMPORTS. */
2+
3+
/*
4+
IMPORTS - FONTS.
5+
*/
6+
7+
/*
8+
VARIABLES DECLARATION.
9+
- variable's name MUST BEGIN with 2 dashes (--), and it's CASE SENSITIVE.
10+
- Scopes:
11+
- Global scope: declare within ':root' selector.
12+
- Local scope: declare variable within specific selector, not in ':root'.
13+
- Ref.: 'https://www.w3schools.com/css/css3_variables.asp'.
14+
*/
15+
:root {
16+
--font_size_default: 16px; /* Default web-browsers font-size: 'https://stackoverflow.com/questions/29511983/is-the-default-font-size-of-every-browser-16px-why/29512572#29512572'. */
17+
--colors_background: #0D1117;
18+
--colors_01: #F0AB3C;
19+
--colors_02: #F6F6F6;
20+
--colors_03: #000000;
21+
--fonts_default: system-ui, sans-serif; /* Hierarchical list of fonts; from preferred, to fallback: 'https://www.w3schools.com/cssref/pr_font_font-family.php', 'https://developer.mozilla.org/en-US/docs/Web/CSS/font-family', 'https://www.w3schools.com/css/css_font_websafe.asp'. */
22+
--line_height_default: 1.5;
23+
}
24+
25+
/* Universal changes for all tags / elements / classes */
26+
* {
27+
/* Set proper dimensions for full page size: 'https://www.freecodecamp.org/news/html-page-width-height/'. */
28+
padding: 0;
29+
margin: 0;
30+
box-sizing: border-box; /* Set appropiate box-sizing: 'https://www.w3schools.com/css/css3_box-sizing.asp'. */
31+
}
32+
33+
/* DEFAULT HTML TAGS. */
34+
35+
html {
36+
font-size: var(--font_size_default); /* Recommended, explicit declaration: 'https://stackoverflow.com/questions/29511983/is-the-default-font-size-of-every-browser-16px-why/29512572#29512572'. */
37+
font-family: var(--fonts_default);
38+
line-height: var(--line_height_default);
39+
}
40+
41+
body {
42+
background-color: var(--colors_background);
43+
color: var(--colors_02);
44+
}
45+
46+
ul {
47+
padding: 10px 0px 0px 20px !important; /* IMPORTANT: lists REQUIRE PADDING; therefore, need manual adjustment, if padding set GLOBALLY to 0; i.e. '* { padding: 0; }'. Ref.: 'https://stackoverflow.com/questions/72279264/unordered-list-not-showing-bullets/72281511#72281511', 'https://www.w3schools.com/css/css_important.asp'.*/
48+
}
49+
50+
/* Use of 'media queries' to define layouts according to specific screen resolutions: 'https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries#targeting_media_features'. */
51+
@media (width > 0px) { /* Base design, as starting point: e.g. for desktop, although recommended to start with mobile, 1st: 'https://stackoverflow.com/questions/6370690/media-queries-how-to-target-desktop-tablet-and-mobile/20350990#20350990'. */
52+
53+
/* CUSTOM CLASSES. */
54+
55+
.main-nav {
56+
background-color: var(--colors_03);
57+
/* position: sticky; */
58+
/* width: 100%; */
59+
/* top: 0; */
60+
/* left: 0; */
61+
/* z-index: 9999; */
62+
}
63+
64+
.main-nav-header {
65+
display: flex;
66+
align-items: center;
67+
padding: 0.5rem 1rem;
68+
}
69+
70+
.main-nav-header-logo {
71+
height: 30px;
72+
padding-right: 10px;
73+
/* font-size: 28px; */
74+
/* max-width: inherit; */
75+
}
76+
77+
.main-nav-header-title {
78+
color: var(--colors_01);
79+
text-decoration-line: none;
80+
font-size: 1.5em;
81+
line-height: 2em;
82+
/* text-decoration: none; */
83+
/* text-decoration-style: initial; */
84+
/* text-decoration-color: initial; */
85+
/* font-weight: 400; */
86+
/* white-space: nowrap; */
87+
}
88+
89+
.main-pyscript {
90+
margin: 0.5rem;
91+
}
92+
93+
}

rsrcs/io_inputs/config/.gitkeep

Whitespace-only changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import random
2+
from pyscript.web import page
3+
from js import DOMParser
4+
from pyodide.http import open_url
5+
from pyodide.ffi.wrappers import set_interval
6+
7+
8+
class Antigravity:
9+
10+
url = "/rsrcs/media/img-antigravity-white.svg" # Path with respect to 'HOME'.
11+
12+
def __init__(self, target=None, interval=10, append=True, fly=False):
13+
if isinstance(target, str):
14+
# get element with target as id
15+
self.target = page[f"#{target}"][0]
16+
else:
17+
self.target = page["body"][0]
18+
19+
doc = DOMParser.new().parseFromString(
20+
open_url(self.url).read(), "image/svg+xml"
21+
)
22+
self.node = doc.documentElement
23+
24+
if append:
25+
self.target.append(self.node)
26+
else:
27+
self.target._js.replaceChildren(self.node)
28+
29+
self.xoffset, self.yoffset = 0, 0
30+
self.interval = interval
31+
32+
if fly:
33+
self.fly()
34+
35+
def fly(self):
36+
set_interval(self.move, self.interval)
37+
38+
def move(self):
39+
char = self.node.getElementsByTagName("g")[1]
40+
char.setAttribute("transform", f"translate({self.xoffset}, {-self.yoffset})")
41+
self.xoffset += random.normalvariate(0, 1) / 20
42+
if self.yoffset < 50:
43+
self.yoffset += 0.1
44+
else:
45+
self.yoffset += random.normalvariate(0, 1) / 20
46+
47+
_auto = Antigravity(append=True)
48+
fly = _auto.fly

0 commit comments

Comments
 (0)