Compare commits

..

640 Commits

Author SHA1 Message Date
Peter W
39725c1384 Use latest instead 2023-11-21 11:11:57 -06:00
Peter W
48c5158b46 Fix 404 in main README.md 2023-11-21 11:09:48 -06:00
Antonio Cuni
4b89c84692 use UTC time (#1859) 2023-11-15 16:00:09 +01:00
Antonio Cuni
df68449b82 Improve README and and mention the community calls (#1858)
Improve the readme in two ways:

- remove the mention to <py-repl>, and shows a quick summary of the various ways of running Python code

- add a link to the google calendar which contains the community calls
2023-11-15 12:10:52 +01:00
Andrea Giammarchi
48e3383f66 Fix #1841 - Provide a better error when input is used (#1857) 2023-11-14 15:25:17 +01:00
Fabio Pliger
e750fa7393 Add Deprecation message when loading from latest (#1848)
* add tests to verify if we show an error banner when users load from latest

* add deprecation manager to take care of showing a notification in case script src is being loaded from latest

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* make sure deprecation warning also register onWorker

* restore tests for banner in worker

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add a wait selector when testing banner since worker seems to take too long to render in CI

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix test_deprecate_loading_scripts_from_latest: I think that the
previous failure was because we actually TRIED to execute the js from
latest/core.js and it conflicted with our local copy.

But to trigger the warning is enough to have a script pointing to
pyscript.net/latest, there is no need to execute it: modify it with
type="ignore-me" and an URL which doesn't exist.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2023-11-10 08:18:30 -08:00
Fabio Pliger
5a15199a3a Fix Click test example (#1849)
* fix type in div id

* add types
2023-11-08 11:09:15 -08:00
Fabio Pliger
1801472fc4 Remove when from pydom (#1850)
* bye bye when

* fix create to drop parent and actually pass the other arguments through

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* update types

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-08 09:28:58 -08:00
Nicholas Tollervey
ab15ac37ff Add playwright to dependency installation steps. (#1852) 2023-11-08 13:31:12 +00:00
Nicholas Tollervey
0955a6be49 Re-add CHANGELOG.md into root of the repository. (#1851)
* Re-add CHANGELOG.md from the tip of "classic" into root of the repository. Tidy
the formatting in CHANGELOG.md. Update the PR template to reflect the new
location of the CHANGELOG.md.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Replace with specific version.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-08 13:28:12 +00:00
Jeff Glass
d58237ea15 Update link to not use /latest (#1847)
* Update link in README.me to use specific version, not /latest
2023-11-07 16:37:10 -06:00
Andrea Giammarchi
2d50ca86a6 Fix #1840 - Do not bootstrap interactive shell (#1846) 2023-11-07 19:22:08 +01:00
Andrea Giammarchi
f1a46be738 Fix #1838 - Provides all TS from all projects (#1843) 2023-11-07 17:17:40 +01:00
Andrea Giammarchi
3e2a67d434 PyTerminal: use Pyodide instead of Python (#1833) 2023-11-03 17:59:11 +01:00
Andrea Giammarchi
aef028be6e Fix #1834 - Throw an error if more than a terminal exists (#1837) 2023-11-03 15:19:30 +01:00
Andrea Giammarchi
c8ec29a3d8 Improve offline dist content (#1836) 2023-11-03 10:00:52 +01:00
Fabio Pliger
e81830a2ea Value property to PyDom.Element and ElementCollection (#1828)
* add base test for input value field

* add value property to Element

* add test for non supported element

* prevent users to set value attribute on elements that do not support it

* add test for setting value on collections

* add value property to collection and add more tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-01 08:33:38 -07:00
Nicholas Tollervey
54df7171a2 Update publish-snapshot.yml (#1827)
Ensure playwright is installed when building.
2023-11-01 10:23:33 +00:00
Andrea Giammarchi
b31af823d1 Use <py-terminal> as default target (#1826) 2023-10-31 16:58:20 +01:00
Andrea Giammarchi
72f266532b PyScript Terminal - the latest kind (#1816) 2023-10-31 15:16:15 +01:00
Andrea Giammarchi
d9bf5cae12 Fix #1814 - Basic mpy integration (#1815) 2023-10-27 15:30:21 +02:00
Andrea Giammarchi
cd95a42e5e Fix #1812 - Avoid duplicated pyscript module (#1813) 2023-10-26 19:44:31 +02:00
Andrea Giammarchi
e67eb06d8b Breaking: new Polyscript Hooks mechanism (#1811)
* Breaking: new Polyscript Hooks mechanism

* Added proper smoke test
2023-10-26 17:13:36 +02:00
Andrea Giammarchi
28d37cdead Fix #1775 - Use latest polyscript dev script (#1810) 2023-10-24 15:23:05 +02:00
Nicholas Tollervey
13604e0a47 Simplify Makefile. Remove Conda. Use requirements.txt. Remove pointless type annotations. Update CI tests.yml. (#1793) 2023-10-24 09:53:10 +01:00
Andrea Giammarchi
aeb6f1a755 Create a dist.zip artifact (#1809) 2023-10-24 10:29:29 +02:00
Madhur Tandon
92e6f711b7 fix docs for append as True (#1808) 2023-10-23 19:32:32 +05:30
Andrea Giammarchi
a24113f42b Fix #1799 - Avoid multiple bootstraps when embedded (#1800) 2023-10-23 15:54:51 +02:00
Madhur Tandon
7a6f8ab3ad Update README.md (#1806) 2023-10-23 19:06:29 +05:30
Andrea Giammarchi
6dd242f3ce Allow PyScript to fully run locally (#1805) 2023-10-20 15:02:05 +02:00
shubhalgupta
88fa82c61a Fix contributing link is README file #1782 (#1797) 2023-10-10 13:24:15 -05:00
Andrea Giammarchi
2299ba5f61 Updated npm version (#1796) 2023-10-10 15:23:18 +02:00
Andrea Giammarchi
117df6ca38 Updated to latest polyscript + coincident (#1795) 2023-10-10 12:38:01 +02:00
Antonio Cuni
4256a81653 run pre-commit on all files (#1789)
pre-commit.ci has been disabled for a while.
This PR ensures that all the files has been validated/formatted by pre-commit, to avoid spurious diffs in subsequent PRs.

During the process, ruff broke the code because it removed an "unused" import which was actually used.
A linter which breaks my code is a linter which I cannot trust, so I just removed it. I re-enabled isort instead.
2023-10-05 15:10:31 +02:00
Andrea Giammarchi
d5b6935c0b Wait for plugins before defining the custom type (#1788) 2023-10-05 13:54:55 +02:00
Madhur Tandon
b4503ef729 remove pyscriptjs and synclink (#1787)
* remove pyscriptjs and synclink

* remove chdir fixture
2023-10-04 21:46:34 +05:30
Valerio Maggio
a00a6750b4 FIX to display function handling null element reference, and wrong target parameter values (#1784)
* blacked

* More robust code for display, with tests

Display now includes more robust controls when checking
the input target parameters, with appropriate exception raised
(i.e. ValueError or TypeError) whether target is either
an empty string, or a not-string, not-None type, respectively.

The TypeError aligns with other similar behaviour with other Pyton
functions (e.g. str.split with integer separator).

Also, now display raises a ValueError whether the target element
is not found or not existing.

All changes are supported by tests.

* traceback lines in check_py_error & removed clones

check_py_error function now automatically includes
check of the traceback in console errors.

This way tests in basic and display have been refactored,
and lots of duplicated code removed.

* removed useless console check lines.

If check_py_errors function is running, those
console log lines are useless to check.
2023-10-03 18:23:44 +01:00
Andrea Giammarchi
a08f891b20 Fix #1777 - Export also PyWorker and current_target (#1779) 2023-10-02 16:02:34 +02:00
Andrea Giammarchi
bc1cac9c41 Fix #1780 - Clean up elements before writing (#1781) 2023-10-02 15:39:34 +02:00
Andrea Giammarchi
50f7ab0f34 Improved py:all-done event (#1778) 2023-10-02 13:38:28 +02:00
Andrea Giammarchi
fdc35ce3ed Add a selector to the HTML tag + export config (#1773) 2023-09-29 15:24:20 +02:00
Andrea Giammarchi
5c4e400d32 Fix #1766 - Ensure correct hooks types (#1772) 2023-09-29 14:01:35 +02:00
Andrea Giammarchi
7a23e355b9 Add experimental files config parser (#1770) 2023-09-28 21:15:04 +02:00
Andrea Giammarchi
dffac642a1 Fix #1765 - Pass the optional config interpreter value (#1768) 2023-09-28 17:49:11 +02:00
Andrea Giammarchi
97699eaded Fix #1764 - Unescape innerHTML artifacts (#1767) 2023-09-28 16:05:51 +02:00
Antonio Cuni
c6aaacdbf1 Re-enable CI tests (#1760)
This re-enables CI tests on every PR 🎉.
This uses make test-integration, which runs tests sequentially.

In theory, we also have test-integration-parallel but it seems to be very flaky: many tests randomly timeout. I didn't spend too much time investigating this, it's probably worth its own investigation in a separate PR, but for now it's important to re-enable CI tests, even if they are a bit slower.
2023-09-27 17:02:49 +02:00
Antonio Cuni
abfc68765f Enable worker tests (#1757)
This PR re-enables tests on `worker`s. Highlights:
 
* by default, each test is run twice: the main thread version uses `<script type="py">`, the worker version automatically turn the tags into `<script type="py" worker>`

* you can tweak the settings per-class by using the `@with_execution_thread` decorator. In particular, `@with_execution_thread(None)` is for those tests which don't care about it (e.g., `test_py_config.py`)

* inside each class, there might be some test which should be run only in the main thread (because it doesn't make sense to test it in a worker). For those, I introduced the `@only_main` decorator

* we might introduce `@only_worker` in the future, if needed

* `@skip_worker` is for those tests which currently pass on main but not on workers. These are meant to be temporary, and eventually they should all be fixed
 
During the process, I tweaked/improved/fixed/deleted some of the existing tests. Some of them were at risk of being flaky and I made them more robust, others depended on some very precise implementation detail, and I made them more generic (for example, `test_image_renders_correctly` relied on pillow to render an image with a very specific string of bytes, and it broke due to the recent upgrade to pyodide 0.24.1)
 
I also renamed all the skip messages to start with `NEXT`, so that they are easier to grep.
2023-09-27 10:05:40 +02:00
Andrea Giammarchi
3ac2ac0982 Added py:all-done event (#1756) 2023-09-26 15:56:50 +02:00
Antonio Cuni
b9a1227e47 Unskip some tests, delete others (#1742)
Clean up a bit the testsuite and integration tests.
Highlights:

- Some of the @skipped tests just worked -- I unskipped them
- some worked after some small tweak to adapt to the new pyscript next
- some are still skipped, but I tweaked the skip message to be more precise and descriptive
- Moreover, I killed/removed the ones which no longer make sense in the context of pyscript next; in particular, I removed all the ones which tested Element (which is now gone) and the one which tested py-config features which are no longer needed (e.g., multiple interpreters).

The testsuite passes locally.
2023-09-25 18:14:20 +02:00
Jeff Glass
801c63947a Skip test_interpreter_config (#1752)
* skip test_interpreter_config

*Clarify the skip() comments on a couple other config tests
2023-09-25 07:30:22 -05:00
Jeff Glass
ffee4add4a Fix target attribute lookup on <script type="py"> (#1751)
* queryTarget takes element as first param

* Add test for 'target' attribute on script tags test_tag_target_attribute
2023-09-25 07:27:47 -05:00
Andrea Giammarchi
f0be7ef418 Fixed eslint ignoring global leaks (#1754) 2023-09-25 12:09:47 +02:00
Andrea Giammarchi
e4eedd80bc [RC] Work on the reverted changes (#1753) 2023-09-25 11:41:34 +02:00
Jeff Glass
c9e7fe16e4 Adding JS Types (#1749)
Added types for some exceptions, config objects, and sleep()
2023-09-22 12:19:22 -05:00
Ted Patrick
5079dd19cb Revert "[RC] Ensure dedicated configs per interpreter (#1743)" (#1747)
This reverts commit b4c686f411.
2023-09-21 14:11:22 -05:00
Andrea Giammarchi
b4c686f411 [RC] Ensure dedicated configs per interpreter (#1743) 2023-09-21 19:20:02 +02:00
Ted Patrick
287d0fa1af Prepare and Publish Release (#1741)
* Prepare and Publish Release

* Add prepare release and publish release

* Update AWS Credentials config to v4
2023-09-20 15:37:37 -05:00
Ted Patrick
b78455c4c1 Add permissions section (#1740) 2023-09-20 15:12:15 -05:00
Ted Patrick
312b6b0706 Fix publish unstable (#1739) 2023-09-20 14:53:19 -05:00
Ted Patrick
924e530096 Update pathing in publish-unstable (#1738) 2023-09-20 14:42:49 -05:00
Ted Patrick
ef8918f3a7 Update Build Unstable (#1737) 2023-09-20 14:35:57 -05:00
Ted Patrick
91ae242e49 Build unstable (#1736)
* Add build unstable

* update publish snapshot

* naming action and steps
2023-09-20 14:30:21 -05:00
Ted Patrick
fd307e52ae Update publish snapshot (#1735)
* Update publish snapshot

* naming is hard
2023-09-20 13:40:24 -05:00
Ted Patrick
a68967c773 Add publish snapshot GHA (#1734) 2023-09-20 13:37:02 -05:00
Ted Patrick
52da45bb9c Disable all workflows - mv to / from .github (#1733) 2023-09-20 13:01:08 -05:00
Andrea Giammarchi
ad0dde3f17 [next] Add mpy as custom type with PyScript magic attached (#1728) 2023-09-20 18:06:52 +02:00
Andrea Giammarchi
8f3c36deea [next] Fix #1730 - Make worker an empty attribute only (#1732) 2023-09-20 16:44:00 +02:00
Ted Patrick
23e1ab81b3 Docs to the docs repo (#1731) 2023-09-20 08:02:19 -05:00
Antonio Cuni
77b40aa348 Use <script type="py"> instead of <py-script> in most tests (#1723)
This is mostly a global search&replace, to replace <py-script> with <script type="py">.

The vast majority of tests just works, some needed some tweak.
2023-09-19 18:35:15 +02:00
Andrea Giammarchi
f6decfd93d [next] Errors on ambiguous/conflicting code intents (#1724) 2023-09-19 18:10:46 +02:00
Andrea Giammarchi
e8d5138cfa [next] Fix #1699 - Updated polyscript + added smoke test (#1726) 2023-09-19 18:08:21 +02:00
Jeff Glass
a088fbd6fb Add pexpect to environment.yml(#1725) 2023-09-19 09:38:58 -05:00
Andrea Giammarchi
19214901f9 [next] Fix regressions around config (#1720) 2023-09-18 14:53:50 +02:00
Andrea Giammarchi
c330a623b2 [next] Remove artifacts from GitHub (#1721) 2023-09-18 14:07:03 +02:00
Fabio Pliger
f77241e977 next integration tests (#1712)
* move integration tests pyscriptjs/tests/integration ->pyscript.core/tests/integration

* add information in regards to how to run integration tests to README

* fix fake server build paths

* fix paths to build and run tests. The change of path before integration tests is a glitch maybe due to pytest cache?

* remove test files created by mistake

* update readme with latest changes

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-15 14:09:07 -07:00
Antonio Cuni
ed6de66c08 emit a clear error message if you try to use pyscript.sync from the (#1715)
main thread or pyscript.PyWorker from a worker
2023-09-15 15:45:40 +02:00
Antonio Cuni
5191c45113 Refactor the pyscript python package. (#1713) 2023-09-15 13:57:06 +02:00
Andrea Giammarchi
840bc803b7 [next] Improve config parsing on bootstrap (#1704) 2023-09-15 12:50:52 +02:00
Fabio Pliger
00fdc73015 [NEXT] Pydom (#1681)
* add pyweb

* build

* add test file

* fix pydom example code

* remove old reference to js

* temporarily comment out query functions on BaseElement while rearranging code to reuse the same underlying logic accross PyDom and other elements

* add temp TODO comment to content as it breaks with template elements

* update pydom example to define code on external file

* fix name type while renaming document -> dom

* add real pydom test files

* add classes to dom scope

* __len__ to ElementCollection

* fix some of the old tests

* rename test from test_query_by_class to test_getitem_by_class

* change test for read and write multiple elements

* add find method to BaseElement

* fix remaining tests

* add Collection Tests

* add equality to Collection

* add test for collection style manipulation

* fix getter for style property and rename style related attribute from pop to remove

* add single element creation test

* remove append on BaseElement and add body and head to dom

* add test_create_element_child to verify child creation

* add children getter property to Element

* remove old code

* remove more old code, change style attribute from visibility to visible and now default getters on collection to return a list with the value of an attribute for every element in the collection

* remove more old code and add possibility to customize test flags via url

* add support to pass Js and pydom.Element elements to when decorator

* remove methods related to input type of elements until we have a better design for it

* rename _element to _js

* add test_when decorator with a ElementCollection input

* when decorator now supporte pydom.ElementCollection as input

* update pyscript.js

* remove useless variable from when decorator

* remove base.py from pyweb

* add nodes for append collection test and add better feedback on successes vs failure

* add tests and fix code for support of append Element and ElementCollection

* manage access to content attribute when tagname is template

* fix comment

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-14 13:31:23 -07:00
Ted Patrick
9660976d1d Fix to HTML template logic (#1711) 2023-09-14 13:40:57 -05:00
Ted Patrick
7f666dc6a0 Fix HTML template (#1709) 2023-09-14 13:35:57 -05:00
Ted Patrick
e2a2292a6f Add release html template (#1705) 2023-09-14 12:45:22 -05:00
Andrea Giammarchi
4d89cbde01 [next] Terminal smoke-test follow up (#1702) 2023-09-14 18:11:10 +02:00
Andrea Giammarchi
d8e1cb8b0f [next] Testing XTerm (#1696) 2023-09-14 11:26:09 +02:00
Andrea Giammarchi
3aef5a99dc [next] Bootstrap plugins directly (#1698) 2023-09-14 11:11:44 +02:00
Andrea Giammarchi
7994207c78 [next] Dispatch ready event for the custom py type (#1694) 2023-09-13 12:02:04 +02:00
Andrea Giammarchi
f376097a15 [next] Update CDN links to avoid breaking (#1693) 2023-09-13 11:59:52 +02:00
Fabio Pliger
2a2ff4066d Restore the when decorator and HTML (#1691)
* restore HTML code in display module

* restore when decorator code in event_handling module

* add when and HTML at pyscript import level

* add test for display with HTML

* add quick manual test for when

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-12 06:27:56 -07:00
Andrea Giammarchi
32c3fb72cc [next] try workaround explicit for jsdelivr (#1692) 2023-09-12 12:06:48 +02:00
Andrea Giammarchi
e44e18114d [next] Use all jsdelivr suggested fields for CDN (#1690) 2023-09-11 16:20:06 +02:00
Andrea Giammarchi
7d2df4895e [next] improve integration tests (#1684) 2023-09-08 17:59:50 +02:00
Andrea Giammarchi
59db56feec [next] Add PyScript Developers Team copy (#1685) 2023-09-08 17:43:54 +02:00
Andrea Giammarchi
fd60b4789a [next] Follow up on stderr (#1683) 2023-09-08 09:55:27 +02:00
Andrea Giammarchi
0696e4682d [next] Cumulative pre-release patches (#1682) 2023-09-07 15:17:09 +02:00
Andrea Giammarchi
d56eeb59ed [next] @pyscript/core 0.1.8 (#1679) 2023-09-06 17:34:11 +02:00
Andrea Giammarchi
1d015c7534 [next] Include most basic error plugin (#1677) 2023-09-06 16:49:43 +02:00
Andrea Giammarchi
264675d0c3 [next] Fix #1675 - use async runner in py-script too (#1676) 2023-09-06 11:28:58 +02:00
Jeff Glass
37d4cb7c48 Adjust Comments in target.html test (#1674)
* Adjust comments

* Remove unnecessary styling
2023-09-06 10:20:16 +02:00
Andrea Giammarchi
cabb1c72b6 [next] Provide less magic around the display (#1673) 2023-09-05 18:51:10 +02:00
Andrea Giammarchi
489a2bb20e [next] Avoid conflicts on @pyscript/core npm artifacts (#1672) 2023-09-05 10:57:40 +02:00
Andrea Giammarchi
d5f42e57ce [next] update PyScript Next to v0.1.7 (#1669) 2023-09-04 13:18:06 +02:00
Andrea Giammarchi
94b0bf4131 [next] Updated latest Polyscript bringing in worker attribute (#1667) 2023-09-04 10:04:12 +02:00
Fabio Pliger
12428c0617 Bring tests to next (#1657)
* bring Makefile to root folder

* add back the print to console when pyscript is ready

* fix build path on tests, link to core.js and overall timeout since it now loads faster

* fix and mark some tests accordingly

* change default timeout to 20s

* review tests and skip what is a known regression

* more tests review until pycondif and skip what is a known regression

* fix pyodide version used on tests

* remove display from config test since it's not testing anything more than console already tests and display as its own tests

* disable config tests that rely on the banner

* skip REPL tests since it's not included in pyscript NEXT

* skip PyTerminal tests since it's not included in pyscript NEXT

* skip more tests relying on Element

* Fix wrong script type from py-script to py

* review more tests related to attributes and add test for worker

* skip spashscreen tests

* wrap up reviews on remaining tests

* update core

* update display tests to use import

* fix more tests and skip some that have known issues

* skip other 2 tests that fail because the test framework injects values that cause the config to fail

* fix getPySrc test due to changed interface

* another round of fixes and commenting on specific tests

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-01 10:01:09 -07:00
Andrea Giammarchi
ef44df5dda [next] Bring in stdlib as artifact (#1666) 2023-09-01 09:24:49 -07:00
Andrea Giammarchi
da3b43abdd [next] xworker.sync pollution example (#1659) 2023-08-31 15:37:17 +02:00
Andrea Giammarchi
4cc9647dc6 [next] allow document.createElement(py-script) (#1662) 2023-08-31 14:23:01 +02:00
Andrea Giammarchi
74cd7c840a [next] Sanitize <py-script> content + deprecate html content (#1663) 2023-08-31 10:43:28 +02:00
Andrea Giammarchi
0f2deeb71a [next] Place a target in the body (#1658) 2023-08-30 14:43:48 +02:00
Andrea Giammarchi
93539c9b5a Fix #1651 - Avoid leaks from the registered module (#1655) 2023-08-29 22:32:05 +02:00
Andrea Giammarchi
e48e6276e1 [next] PyScript Next basic documentation (#1634) 2023-08-17 08:12:55 -07:00
Andrea Giammarchi
75a57a49f5 [next] Porting most basic examples (#1631) 2023-08-10 22:42:01 +02:00
Andrea Giammarchi
8a1db288fc [next] Updated polyscript to use PyScript custom stderr when running code (#1629) 2023-08-09 19:30:18 +02:00
Andrea Giammarchi
84dcde188b [next] Bring in the good old PyScript display (#1628) 2023-08-09 16:28:06 +02:00
Andrea Giammarchi
27c91e9703 [next] Updated LICENSE & dependencies (#1626) 2023-08-08 17:16:43 +02:00
Andrea Giammarchi
b5a0cd4057 [sw] Added a first version of the PyScript Service Worker (#1621)
* Added a first version of the PyScript Service Worker

* Fix typo as suggested

Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>

---------

Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>
2023-08-08 10:57:26 +02:00
Andrea Giammarchi
77d8fe3562 [next] Improved worker attribute DX (#1625) 2023-08-07 18:36:33 +02:00
Andrea Giammarchi
a484aff457 Moved back pyscript.core where it belongs (#1622) 2023-08-07 15:15:05 +02:00
Andrea Giammarchi
c96f5912df Prepared for the first publish (#1620) 2023-08-03 11:22:16 +02:00
Andrea Giammarchi
8a01a56e51 Add pyscript module in both Main and Workers (#1619) 2023-08-03 10:44:17 +02:00
Andrea Giammarchi
2774e49ab9 [next] Brought back home PyScript Next (#1616) 2023-08-01 22:28:57 +02:00
Andrea Giammarchi
26e7a54f1f @pyscript/core deprecation (#1607) 2023-07-21 11:07:42 +02:00
Jack Zhao
f0e69cbc36 fix interpreter absoluteURL (#1603) 2023-07-19 13:21:44 +02:00
Andrea Giammarchi
413428f535 [next] Better Errors - Worker (#1602) 2023-07-19 13:20:03 +02:00
Andrea Giammarchi
0c54036466 [next] Add basic integrations tests (#1576)
* [next] WIP: Add basic integrations tests

* fix typos in  README.md

* Update README.md to specify when files are _ files ignored

---------

Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>
2023-07-19 10:18:17 +02:00
Andrea Giammarchi
2555833831 [next] FS create folder before writing in it (#1582) 2023-07-17 13:46:17 +02:00
Andrea Giammarchi
7e0aceced1 [next] Updated to latest coincident + MicroPython (#1595) 2023-07-13 17:00:04 +02:00
Andrea Giammarchi
77234f6df3 [next] Updated coincident to fix a MicroPython bug (#1591) 2023-07-12 17:55:39 +02:00
Andrea Giammarchi
45af96aad4 [next] Updated to latest MicroPython (#1590) 2023-07-12 10:45:46 +02:00
Andrea Giammarchi
184d29055e [next] Await events when invoked (#1589) 2023-07-11 13:27:59 +02:00
Andrea Giammarchi
9e73181816 [next] Use the very same source for all Python interpreters (#1588) 2023-07-10 17:54:13 +02:00
Andrea Giammarchi
0b0e03456c [next] Improve the whole events story (#1584) 2023-07-10 15:36:48 +02:00
Andrea Giammarchi
c6b5ce7f55 [next] Drop web like events (#1578)
* Use registerJSModule when available (#1573)

* Updated version to publish latest
2023-07-06 17:56:06 +02:00
Andrea Giammarchi
a14e701be4 Use registerJSModule when available (#1573) 2023-06-29 22:50:35 +02:00
Andrea Giammarchi
7813c3f03f Added npm run dev (#1572) 2023-06-29 12:45:07 +02:00
Andrea Giammarchi
3a3cb7b11d Align npm versioning (#1568) 2023-06-27 22:34:10 +02:00
Andrea Giammarchi
d7b0731385 Added a section dedicated to XWorker required headers (#1567) 2023-06-27 20:56:16 +02:00
Andrea Giammarchi
df8973736f Update latest package.json version + lock (#1565) 2023-06-27 17:11:53 +02:00
Andrea Giammarchi
9121071ba3 PyScript Core Documentation (#1560) 2023-06-27 16:53:19 +02:00
Andrea Giammarchi
bf6470c046 Cleanup and improve the index.html for tests (#1558) 2023-06-22 21:37:11 +02:00
Andrea Giammarchi
3b7099cd3d Fixed issues around XWorker context (#1556) 2023-06-22 19:04:57 +02:00
Andrea Giammarchi
f6dfc5361e Implement PyScript custom <script type> (#1548)
* updated MicroPython to latest in order to have `globals` API available
  * reduced code around helpers for both MicroPython and Pyodide as now these are more aligned
  * updated all dependencies and brought in latest [coincident/window](https://github.com/WebReflection/coincident#coincidentwindow) goodness to any `xworker`, preserving the `sync` previous behavior
  * using [@ungap/structured-clone/json](https://github.com/ungap/structured-clone#tojson) as *coincident* default `parse` and `stringify` utility to allow recursive and more complex data to travel back from the *Worker* (forward data is still fully [structured clone algorithm compatible](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm))
  * renamed all *plugin/s* references to *custom/s* as plugin as a word was too misleading
  * changed *custom types* helpers logic to allow any single node to have its own version of the interpreter wrapper, and all the extra fields it carries with it, including a way to augment every interpreter execution, among as every worker code execution
  * created a `custom` folder where I've landed the very first `pyscript.js` custom type
  * created an exhaustive test page to demonstrate the current abilities of *PyScript Next* among its ability to expose utilities that can be used to create *PyScript* plugins
2023-06-22 17:29:07 +02:00
Andrea Giammarchi
0a7e1ce0d7 Fix #1531 - Remove overall need for globalThis pollution (#1543) 2023-06-19 18:05:45 +02:00
Andrea Giammarchi
d6b1c393f6 MicroPython as CDN (#1521) 2023-06-19 12:06:15 +02:00
Andrea Giammarchi
bccd5e3750 Fix #1538 - use same customElements Registry utilities (#1542) 2023-06-16 15:34:05 +02:00
Andrea Giammarchi
6df5905b2b [next] Ditch handy shortcuts for good (#1537) 2023-06-15 17:08:28 +02:00
Andrea Giammarchi
6284c02032 [next] Rename all runtime(s) references to interpreter(s) (#1536) 2023-06-15 15:34:07 +02:00
Andrea Giammarchi
db27d52352 [next] Update MicroPython and other dependencies (#1535) 2023-06-15 14:04:47 +02:00
Fábio Rosado
8ba28989fb Add ci for next (#1530)
* Add ci for next

* Install deps from the right folder and build the project

* Rename CI job for test next

* Remove all things pyscriptjs

* Remove ESLint job
2023-06-14 16:01:01 +01:00
Andrea Giammarchi
da544929ac [next] Enabled hooks around plugins (#1522) 2023-06-12 22:18:55 +02:00
Andrea Giammarchi
bb364b0524 Shared array buffer missing error (#1518)
Improve error reporting around SharedArrayBuffer
2023-06-09 20:51:51 +02:00
Andrea Giammarchi
818614b798 Improved Promise polyfill for MicroPython only (#1517) 2023-06-09 12:53:31 +02:00
Andrea Giammarchi
50b1a1d7c5 Fix #1512 - Improve worker tests + update Pyodide (#1513)
* Fix #1512 - Improve worker tests + update Pyodide

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-06-08 17:39:01 +02:00
Andrea Giammarchi
7d3b792a79 Fix #1514 - Provide a better feedback on HTML typos (#1515) 2023-06-08 13:49:49 +02:00
Andrea Giammarchi
af72e232c3 Worker sync utility (#1511)
* patched an issue with wasmoon randomly asking to resolve proxy references
  * simplified pyodide and micropython dance by grouping their common utilities together
  * created an integration test around a worker to main thread input between MicroPython and Lua
  * commented some weird bugs / funny behaviors around both MicroPython and Pyodide
  * other minor clean ups
2023-06-08 11:10:47 +02:00
Andrea Giammarchi
0cdbfbeb30 Updated MicroPython (#1510)
Updated MicroPython
2023-06-06 11:42:23 +02:00
Andrea Giammarchi
339e40063a WIP: Bringing PyScript.next PoC to the main project (#1507)
* kill unwrapped_remote (#1490)

* kill unwrapped_remote

* linting

* don't use callKwargs for python plugins

* fix tests and improve types

* Bringing PyScript.next PoC to the main project

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Madhur Tandon <20173739+madhur-tandon@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-06-05 21:52:28 +02:00
Neon22
4467898473 Update py-click.md (#1499)
Add links to other events so its clear py-click is not a limitation or umbrella term for the only kind of interaction.
2023-06-05 20:42:42 +05:30
Madhur Tandon
17d16b987f kill unwrapped_remote (#1490)
* kill unwrapped_remote

* linting

* don't use callKwargs for python plugins

* fix tests and improve types
2023-06-01 22:52:23 +05:30
Ted Patrick
8e86daac71 Year 2023 (#1496) 2023-05-31 17:13:13 -05:00
Ted Patrick
856720da49 Simple 404 in _static (#1495)
* Simple 404 in _static

* Docs 404 error

* s3_error.html
2023-05-31 16:42:30 -05:00
Ted Patrick
8f2c150d1e Docs correction (#1494) 2023-05-31 16:19:36 -05:00
Ted Patrick
7d8b4c980a Error html to root of docs (#1493)
* Error html to root of docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-05-31 16:10:32 -05:00
Jeff Glass
932756c7a0 Add Option to make Py-Terminal and Xterm.js (#1317)
* Add 'xterm' attribute in py-config using new validation

* Use screen reader mode

* Add `xtermReady` promise to allow users to away xterm.js init

* Guard against initializing a tag twice

* Add tests and doc
2023-05-29 10:00:20 -05:00
Andrea Giammarchi
538aac9a28 Fix #1482 - Add utils.py to the list of modules (#1485) 2023-05-25 10:39:07 +02:00
Andrea Giammarchi
856bf8f5fb Fix #1474 - await both JS and Python plugins all at once (#1481) 2023-05-24 18:59:23 +02:00
Jeff Glass
e1758ae2e2 Upgrade to Pyodide 0.23 (#1347)
* Upgrade to Pyodide 0.23.2

* Update changelog

* Use @param decorator to fix kmeans examlpe

* Separate zz_example tests to run sequentially

* Remove pytest.raises from pyscript_src_not_found test, use check_js_errors instead

* Add 'check_js_errors' to wait_for_pyscript
2023-05-24 07:59:19 -05:00
Andrea Giammarchi
61b3154461 [chore] Improve current Error extends (#1467) 2023-05-22 13:22:53 +02:00
Jeff Glass
fb9b30d144 Fix zz_examples tests (pin dependencies) (#1477) 2023-05-18 19:27:47 -05:00
StefanoHiway
b0df96b13f html tag not closed (#1473) 2023-05-17 16:16:35 +05:30
Andrea Giammarchi
a469062a32 Simplified classList within Python code (#1459) 2023-05-15 12:45:11 +02:00
Andrea Giammarchi
89d5d5c7db Fix svg errors on the page caused by <py-script> (#1464) 2023-05-15 12:44:19 +02:00
Madhur Tandon
b8c2d6b05d fix panel kmeans test (#1465) 2023-05-15 15:24:08 +05:30
Madhur Tandon
b247864414 remove PyWidget and py-register-widget + refactor PyList as a Python Plugin (#1452)
* remove PyWidget and py-register-widget

* refactor py-list as Plugin

* add newline

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix eslint

* handle case if src not supplied

* move inside if

* - Remove src attribute for py-list
- Re-implement as a Python plugin
- Remove pylist.py from examples directory
- Remove PyListPlugin as one of the default ones

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* move PyItem and PyList classes to the plugin

* clean up PyListTemplate and PyItemTemplate from pyscript module

* fix linting

* use PyList instead of PyListTemplate instead

* fix example for todo-pylist

* re-enable and improve test

* move py-list plugin to examples

* fix py-list plugin link

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-05-10 20:17:07 +05:30
Andrea Giammarchi
d3bcd87cfa Allow nodes in shadow roots to be addressed via Element (#1454) 2023-05-09 17:42:09 +02:00
Antonio Cuni
82e5b64bad Make sure that tests fail in case there is an unhandled Python error (#1456)
Before this PR, the following test passed:

    def test_pyscript_hello(self):
        self.pyscript_run(
            """
            <script type="py">
                raise Exception("hello")
            </script>
            """)

What happens is that we intercept the Python exception and display a nice banner on the DOM, but the test itself passes. This is error prone: if we have Python exceptions on the page, the test should fail by default, and we should have a way to silence it in case those exceptions are expected.

This PR treats Python errors as we treat JS errors: unhandled exceptions cause the test to fail, but you can silence them by calling self.check_py_errors(), exactly as you can call self.check_js_errors().
2023-05-09 15:39:19 +02:00
Andrea Giammarchi
73e0271c23 Fix typo in py-events attributes handling (#1458) 2023-05-09 14:29:00 +02:00
Andrea Giammarchi
a2dabee0e9 Fix element.select tests (#1457) 2023-05-09 13:12:29 +02:00
Andrea Giammarchi
6a27c6d9f2 Cleanup some unnecessary utility (#1453) 2023-05-06 08:20:08 +02:00
woxtu
213ced0c7f Fix an error message when loading local modules failed (#1394)
* Fix an error message when loading local modules failed

* Fix an error message when loading local modules failed
2023-05-05 18:17:35 +05:30
Andrea Giammarchi
5086c23d47 Fix #1445 - Move the EditorView into ShadowDOM (#1449) 2023-05-05 10:41:05 +02:00
Ted Patrick
ee345a5206 Add Andrea Giammarchi as PyScript Maintainer (#1450) 2023-05-04 19:27:50 -05:00
Andrea Giammarchi
f74cddc3b1 Fix #1446 - Move pyscript defer after other dependencies (#1448) 2023-05-04 12:42:35 +02:00
Andrea Giammarchi
5b986b8b26 Fix #1425 - Move scripts within the tutor to make it explicit more files are needed (#1444) 2023-05-03 13:12:06 +02:00
Andrea Giammarchi
14887b9814 Fix #1341 - Use <script type="py"> instead to avoid entities (#1443) 2023-05-03 13:11:27 +02:00
Andrea Giammarchi
ecc40315b3 Fix #1427 - Avoid multiple initialization of the same node (#1433) 2023-05-03 10:00:35 +02:00
Andrea Giammarchi
e7aed7fcf0 Fix #1059 - Observe py-* attributes changes (#1435) 2023-05-03 09:50:21 +02:00
Madhur Tandon
cd1aa948f9 [Worker support] test for no cors headers (#1374)
* test for no cors headers

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix tests

* suggested changes

* disable directly

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add error message

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* improve test

* improve error message

* remove py-config tag from cors test

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-05-02 18:43:11 +05:30
Andrea Giammarchi
82613d016a Fix #1429 - Use basic-devtools module (#1430)
This MR brings in `$`, `$$`, and `$x` browsers devtools' utilities to our code so we can use these whenever we find it convenient.
2023-05-02 15:12:28 +02:00
Jeff Glass
3a66be585f Add @when decorator (#1428)
* Add new _event_handling.py file with @when decorator

* @when decorate is in pyscript package namespace/_all__

* Write tests in new test_event_handling.py

* Add docs for @when decorator

------------

Co-authored-by: Mariana Meireles <marian.meireles@gmail.com>
2023-05-01 09:51:49 -05:00
Andrea Giammarchi
0a4e36ae09 Fix <script src> + test all py-script attributes (#1434) 2023-04-28 18:08:53 +02:00
Andrea Giammarchi
92643539cf Fix #735 - Test <script type="py"> against all special cases (#1431) 2023-04-27 17:46:42 +02:00
Andrea Giammarchi
a1281d1331 Fix #1326 - Allow <script type="py"> tag to work as <py-script> (#1396)
The goal of this MR is to unobtrusively allow the usage of `<script type="py">`, `<script type="pyscript">` or `<script type="py-script">` tags instead of `<py-script>` for all those case where the layout in custom elements get parsed and breaks users' expectations (including our SVG based tests).
2023-04-27 15:21:31 +02:00
Cameron Cairns
074ca0ef8f Adds missing dependency description (anaconda) to docs (#1409) 2023-04-27 12:06:31 +01:00
Fábio Rosado
464a9633dc Fix what is pyscript example h1 color (#1417) 2023-04-26 15:31:01 +01:00
Andrea Giammarchi
fc2d91c5bb Fix #801 - Simplified events listeners attachment: (#1403)
* always same listener, for easy removal and reduce RAM
  * avoid duplicated entries for smaller library outcome
  * use XPath to crawl all attributes names instead of CSS
2023-04-26 15:55:22 +02:00
MrValdez
d68169bffb Development documentation (#1410)
* Updated the instructions for setting up the documentation environment to be clearer

* Expanded on setting up the development and documentation environments.

Moved the documentation section to its own section as it's behavior and purpose is different from the development environment.

* Added alternative to git upstream

Indented list instead of using &nbsp;

* Add 'Using a Local Dev Server' to Getting Started Docs (#1400)

* Added alternative to git upstream

Indented list instead of using &nbsp;

Updated the test environment section

cleaned up "reviewing your work" section to make it easier to read.

* added "setting up environment" changes to changelog

* reverted additions to changelog

---------

Co-authored-by: Jeff Glass <glass.jeffrey@gmail.com>
2023-04-26 12:28:43 +01:00
Andrea Giammarchi
7efdb04e1e Increase commonly failing tests timeout (#1412) 2023-04-26 10:01:20 +02:00
Jeff Glass
0155e122fd Add nodejs=16 to docs conda env (#1413) 2023-04-25 11:36:27 -05:00
Jeff Glass
eb03f16a77 Improve PR template - Doc Changes Don't Need Changelogs(#1411) 2023-04-25 10:03:12 -05:00
Jeff Glass
5ac39641ab Add 'Using a Local Dev Server' to Getting Started Docs (#1400) 2023-04-25 08:17:57 -05:00
Ikko Eltociear Ashimine
8d1e48e400 Fix typo in py-config.md (#1399)
unspecifed -> unspecified
2023-04-21 10:01:59 -06:00
Andrea Giammarchi
0021ccb49f Remove redundant .shadow property as that is defined at the Custom Element level. (#1395) 2023-04-21 10:05:50 +02:00
woxtu
8590c7e5b8 Remove an unused dependency (#1390) 2023-04-16 14:23:52 +05:30
Antonio Cuni
8c5475f78f Move pyodide to a web worker (#1333)
This PR adds support for optionally running pyodide in a web worker:

- add a new option config.execution_thread, which can be `main` or `worker`. The default is `main`

- improve the test machinery so that we run all tests twice, once for `main` and once for `worker`

- add a new esbuild target which builds the code for the worker

The support for workers is not complete and many features are still missing: there are 71 tests which are marked as `@skip_worker`, but we can fix them in subsequent PRs.

The vast majority of tests fail because js.document is unavailable: for it to run transparently, we need the "auto-syncify" feature of synclink.


Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com>
Co-authored-by: Madhur Tandon <20173739+madhur-tandon@users.noreply.github.com>
2023-04-14 10:55:31 +02:00
Jeff Glass
dfa116eb70 Improve validate() function for plugin options (#1323)
* Add `validateConfigParameter` and `validateConfigParameterFromArray` functions to validate user-provided parameters from py-config

* Add units tests for `validateConfigParameter` and `validateConfigParameterFromArray`

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-13 14:35:01 -05:00
Mike Chen
3a9fd3c074 Fix path errors on Windows systems (#1368)
* Add docs to repl with attr src

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix path errors on Windows systems

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix path errors on Windows systems

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-13 20:51:49 +05:30
Stefane Fermigier
5a92ef3c11 doc: remove duplicated link (#1386)
"How to write content to the page" appeared twice in the index.
2023-04-13 11:00:28 +05:30
woxtu
d3902f5c93 Update to the latest TypeScript (#1377) 2023-04-12 23:49:54 +05:30
Hood Chatham
c886f887ae Split pyscript into multiple files (#1338)
In the future this should help us leak fewer names into the pyscript
namespace.

Rather than assigning to the pyscript module from JavaScript, we
mount a separate private JS module with the extra names needed by
PyScript. I moved a bit more interpeter intialization into
remote_interpreter.

I added a deprecation warning for `pyscript.js`: the proper way to
access `js` is `import js`.

---------

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2023-04-12 14:49:47 +02:00
Hood Chatham
fc5089ac59 same thread syncify (#1372)
Switch to using the new version of synclink with support for same thread syncify (and also correct types). 
Uses syncify to replace one use of `_unwrapped_remote`.
2023-04-11 21:31:05 -07:00
Madhur Tandon
e3602f464b remove pys-on* and py-on* attributes (#1361)
* remove pys-on* and py-on* attributes

* update changelog

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix eslint

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-11 18:59:42 +05:30
Madhur Tandon
f3db6a339c remove PY_COMPLETE and the associated message of Python initialization complete (#1373)
* remove PY_COMPLETE

* fix test_multiple_async
2023-04-11 18:59:09 +05:30
cnelir98
c05195c045 DOCS Update display.md (#1375) 2023-04-10 18:44:08 +02:00
Antonio Cuni
af981fc719 Improve self.wait_for_console() (#1363)
- Previously, if the message appeared on the console immediately before the call to self.wait_for_console(), the call would hang forever until the timeout. Now, it returns immediately.

- `wait_for_pyscript` now logs the time actually taken for waiting

- `wait_for_pyscript` takes a `timeout` argument so that we can tweak it on a test-by-test basis
2023-04-05 16:00:17 +02:00
Mike Chen
088a264910 Add docs to repl with attr src (#1353)
* Add docs to repl with attr src

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-03 14:19:23 +02:00
Mike Chen
d7e80ad51b load code from the attr src of py-repl (#1292)
* load code from the attr src of py-repl

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-03 11:06:30 +02:00
Antonio Cuni
b53ddd401f re-enable source maps (#1340) 2023-03-31 16:42:19 +02:00
Hood Chatham
e9122bca9d Fix test_async and test_stdio_handling (#1319)
Resolves pyscript#1313 and pyscript#1314. On top of pyscript#1318.

The point of these tests is to define the execution order of Tasks
that are scheduled in <py-script> tags: first all the py-script tags
are executed and their related lifecycle events. Once all of this
is done, we schedule any enqueued tasks.

To delay the execution of these tasks, we use a custom event loop for
pyExec with this defer behavior. Until schedule_deferred_tasks is called,
we defer tasks started by user code. schedule_deferred_tasks starts all 
deferred user tasks and switches to immediately scheduling any further
user tasks.
2023-03-30 14:38:51 -07:00
Hood Chatham
b61e8435d1 Fix main.test.ts (#1320) 2023-03-30 10:52:39 -07:00
Hood Chatham
146afb6532 Remove all but 2 eslint-disable pragmas (#1335)
Turns off:
 - no-explicit-any (we need to handle any return values from runPython)
 - no-unsafe-assignment (noisy and pointless)

And resolves all but two remaining ones. The last two lints regard access to private Pyodide variables and so:
 - they are not easy to work around without an upstream Pyodide patch
 - they should trigger linter and require explicit override
2023-03-30 10:51:36 -07:00
Hood Chatham
854e9d1378 Refactor pyexec (#1318)
This is some refactoring I did on the way towards resolving pyscript#1313.
I added a new _run_pyscript Python function which executes the code
inside a context manager that sets the display target. We can then
return a JS object wrapper directly from Python.

I moved the "installation" of the pyscript module to loadInterpreter,
and pyimport pyscript_py there and give it a type. This avoids a bunch
of creating and deleting of proxies for pyscript_py and allows us to
give it a type once and for all.

I also did some minor logic cleanup in a few places.
2023-03-30 04:34:24 +02:00
Jeff Glass
689878ce32 Remove AWS upload (#1331)
Deleted final 2 steps of docs-review to un-break CI
2023-03-29 13:22:21 -05:00
Jeff Glass
d7ab177cc5 Deprecate py-mount Attribute (#1330)
* Deprecate py-mount attribute, with comments as to when it was deprecated

* Add changelog entry for deprecation

* Fix 'unused' examples that used py-mount (handtrack and mario)
2023-03-29 10:49:31 -05:00
aneesh98
f4c6093c47 Docs: make tests should be make test (#1332) 2023-03-29 07:33:32 -07:00
Hood Chatham
9fedfe3699 Use Promise.all to fetch files part of py-config (#1322)
This is a first step towards loading more stuff simultaneously rather
than sequentially.

The functional part of this is pretty small: call `calculateFetchPaths` and
then `Promise.all(fetchPaths.map(loadFileFromURL));`. I also transposed the
return type of `calculateFetchPaths` since it's more convenient to consume
this way.

I redid the logic in `calculateFetchPaths` a bit. I renamed `src/plugins/fetch.ts`
to `calculateFetchPaths.ts` since the file performs no fetching. I also
renamed `loadFromFile` to `loadFileFromURL`.
2023-03-29 07:32:09 -07:00
Hood Chatham
26f07246e1 Allow pyscript package to contain multiple files (#1309)
Followup to pyscript#1232. Closes pyscript#1226.

Use node to make a manifest of the src/python dir and then use an esbuild
plugin to resolve an import called `pyscript_python_package.esbuild_injected.json`
to an object indicating the directories and files in the package folder.
This object is then used to govern runtime installation of the package.
2023-03-29 07:31:14 -07:00
Antonio Cuni
3ae4b3c4de use a dynamic import for loading pyodide. This greatly simplifies the logic around interpreter loading and handling of UserError (#1306) 2023-03-27 18:46:50 +02:00
Madhur Tandon
c8f9f16791 synclink integration (#1258)
synclink integration + fixes for `py-repl` related tests and `display` tests
2023-03-27 20:56:31 +05:30
Antonio Cuni
88f0738500 re-enable blank issues
They were disabled by PR #1157 but without any discussion or consensus, so I guess it was a mistake. Personally I found them very useful and AFAIK we never had a problem of people abusing them, so I don't see why they should be disabled  (#1311)
2023-03-27 17:25:28 +02:00
Jeff Glass
03c79d5f2f Make repl hooks optional (#1310)
`beforeByReplExec()` and `afterPyReplExec()` only called if they exist on a plugin
2023-03-27 09:20:58 -05:00
zipperer
e7c3b7bcfe Update getting-started.md (#1307)
1. replace 'other then' with 'other than'
2. replace 'cherrie' with 'cherry'
2023-03-25 20:16:40 -05:00
Andrea Giammarchi
c8becca044 Slightly imporved pyrepl (#1296)
* removed unnecessary getAttribute
  * removed unnecessary shadow and ShadowDOM in general, as it was never used
  * dropped redundant constructor
  * removed unnecessary usage of the label element
  * fixed redundant always-same buttons IDs
2023-03-24 11:42:45 +01:00
Mariana Meireles
543a27271f Add docs for py-event* (#1300)
* Fix markdown
Add event-handlers.md

* Address changes from Jeff + Antonion and add it to index

* how tos don't exist anymore theyre now guides

* Restore p on contributing

* Adding changelog

* Aadd space

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Carmelo <carmelofiorello@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-23 17:57:49 +01:00
Fábio Rosado
a62aba83a0 Update changelog date (#1289) 2023-03-23 11:20:20 +00:00
pre-commit-ci[bot]
53c6cf5f45 [pre-commit.ci] pre-commit autoupdate (#1281)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/charliermarsh/ruff-pre-commit: v0.0.254 → v0.0.257](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.254...v0.0.257)
- [github.com/codespell-project/codespell: v2.2.2 → v2.2.4](https://github.com/codespell-project/codespell/compare/v2.2.2...v2.2.4)
- [github.com/pre-commit/mirrors-eslint: v8.35.0 → v8.36.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.35.0...v8.36.0)

* Fixes lint

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2023-03-23 11:58:25 +01:00
Hood Chatham
89842e20da Set pre-commit autoupdate to monthly (#1271)
* Set pre-commit autoupdate to quarterly

Weekly autoupdate creates a lot of noise

* Update .pre-commit-config.yaml

Co-authored-by: Christian Clauss <cclauss@me.com>

---------

Co-authored-by: Christian Clauss <cclauss@me.com>
2023-03-23 10:27:01 +01:00
Jeff Glass
ef793aecf3 Add REPL plugin hooks; Add output, output-mode, stderr attributes (#1106)
* Add before, after REPL hooks

* Re-introduce 'output-mode' attribute for py-repl

* Add plugin execution tests

* Documentation

* Changelog

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2023-03-22 20:19:22 -05:00
Andrea Giammarchi
51d51409d3 Using esbuild instead of rollup (#1298) 2023-03-22 16:57:37 +01:00
Fábio Rosado
371b5eac45 Add tests for snippets in docs (#1264) 2023-03-22 15:34:23 +00:00
Mariana Meireles
5319bd13d5 Fix tests running on osx + remove auto-gen where doesnt make sense (#1297)
* Fix tests running on osx + remove auto-gen where doesnt make sense

* Linting

* Adds a changelog

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-21 14:39:51 +01:00
Andrea Giammarchi
e10d055453 Docked auto py-terminal (#1284) 2023-03-20 10:22:16 +00:00
Mariana Meireles
716254e655 Revert "Ruff: Add pylint (#1277)" (#1283)
This reverts commit 4c00b1683f.
2023-03-14 17:46:13 +01:00
Christian Clauss
4c00b1683f Ruff: Add pylint (#1277) 2023-03-13 18:03:15 +01:00
Hood Chatham
37c9db09c6 Fix many ESlint errors (#1265)
* Unvendor toml package

* Fix many ESlint errors

For mysterious reasons, these errors appear on my branch #1262 even
though they are not related to changes there. The eslint config seems
a bit unstable.

Anyways this fixes them.

* Put back Record

* Fix typescript compilation

* Fix lints

* Try @iarna/toml instead

* Fix import

* Use @ltd/j-toml

* Update test

* Use toml-j0.4

* Some changes

* Fix toml import

* Try adding eslint gha job

* Add forgotten checkout action

* Force CI to run

* Blah

* Fix

* Revert changes to github workflow

* Fix lints

* wget toml-j0.4 type definitions

* Add toml-j types workaround to eslint workflow

* Apply formatter

* Use @hoodmane/toml-j0.4

* Import from @hoodmane/toml-j0.4
2023-03-13 15:51:28 +01:00
Fábio Rosado
653e2c9be4 Revert changes to the sync workflow (#1276) 2023-03-13 13:39:17 +00:00
Kanishk Pachauri
a2a9613da1 Added Pull request template (#1279)
* Added Pull request template

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: you@example.com <you@example.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-13 13:03:47 +00:00
Antonio Cuni
e8d92d0d34 we cannot use ../build paths in the main examples/ directory (#1275) 2023-03-11 10:35:26 +00:00
Fábio Rosado
755b98a8c0 Update sync-examples CI to be run manually as well (#1274) 2023-03-11 10:34:59 +00:00
Hood Chatham
13e9252260 Run eslint in github actions, skip it in precommit.ci (#1268)
precommit.ci seems to have different results than when I run eslint
locally. At least at first glance, github seems to behave the same
as local. So this turns off eslint in pre-commit.ci and turns it on
in gha.
2023-03-09 14:48:24 +05:30
Hood Chatham
6a9c27325a Fix typo in workflow file (#1266) 2023-03-09 14:45:36 +05:30
Hood Chatham
a1cb78eb85 Fix paths in py-unit/conftest.py (#1269)
The path logic here assumes that the tests are being run from inside
the pyscriptjs directory. It is better to compute releative to `Path(__file__)`
so that it does not depend on the working directory
2023-03-09 14:44:33 +05:30
Hood Chatham
716b57ebd3 Pass --fix to ruff in pre-commit to enable autofixes (#1270) 2023-03-09 14:43:42 +05:30
pre-commit-ci[bot]
8e231313b8 [pre-commit.ci] pre-commit autoupdate (#1260)
updates:
- [github.com/charliermarsh/ruff-pre-commit: v0.0.247 → v0.0.254](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.247...v0.0.254)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <20173739+madhur-tandon@users.noreply.github.com>
2023-03-09 14:42:59 +05:30
Hood Chatham
84e4e361c5 Unvendor toml package (#1263)
* Unvendor toml package

* Try @iarna/toml instead

* Fix import

* Use @ltd/j-toml

* Update test

* Use toml-j0.4

* Fix toml import
2023-03-09 14:36:43 +05:30
Mariana Meireles
41a8d804e3 Attrs doc (#1125)
* adds attr ref

* lint

* address comments

* Addressing to Fabio's rewrite
2023-03-07 11:49:46 +01:00
Hood Chatham
03e798a079 Add prettier to pre-commit (#1255)
* Add prettier to pre-commit

* Apply prettier
2023-03-07 15:02:16 +05:30
Hood Chatham
34a0205757 Add missing </body> tags (#1256) 2023-03-06 22:11:46 +05:30
dependabot[bot]
ba145f04ea Bump json5 from 2.2.1 to 2.2.3 in /pyscriptjs (#1216) 2023-03-06 16:24:17 +00:00
Hood Chatham
22fd023635 More automatically generated formatter changes (#1254)
Apparently some of these were accidentally lost when generating #1210...
2023-03-06 15:06:30 +00:00
Hood Chatham
08f34f748b Apply prettier to css, html, js, md, ts, and yml (#1249)
* Apply prettier to css, js, html, md, ts, and yml

As a followup I will add prettier to the .pre-commit config.
This patch is 100% generated by prettier.
I used a forked version of prettier that understands the
py-script tag.
See https://github.com/hoodmane/pyscript-prettier-precommit
for more info.

* Apply old pre-commit

* Revert some problems

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Revert some changes

* More changes

* Fix pre-commit

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-06 14:20:21 +00:00
Christian Clauss
7ffe6a598e pre-commit: Add ruff to replace bandit, flake8, isort, and pyupgrade (#1210)
* pre-commit: Add ruff to replace bandit, flake8, isort, and pyupgrade

* Upgrade ruff

* Update .pre-commit-config.yaml

* Update .pre-commit-config.yaml

* Update .pre-commit-config.yaml
2023-03-06 14:20:08 +00:00
Kd-Here
71d24a445e Add description of src attribute to py-script (#1136)
* Added description of src attribute to py-script

* Description for py-script src attribute

* resolved mistake of raised by pre-commit

* Update docs/reference/elements/py-script.md

---------

Co-authored-by: Fábio Rosado <hello@fabiorosado.dev>
2023-03-06 12:39:55 +00:00
Fábio Rosado
6bcbbfb085 Add tutorial for using requests (#1164) 2023-03-06 12:36:52 +00:00
Hood Chatham
04fe1348d8 Fix test reporter again (#1247)
* Fix test reporter again

* Escape brackets
2023-03-06 17:15:01 +05:30
Madhur Tandon
3033c779b0 use mkdirTree in emscripten FS (#1245)
* try mkdirTree

* suggested changes

* fix pre-commit
2023-03-04 18:48:01 +05:30
Hood Chatham
4483f0db0f Move prism.js and prism.css to prism.min.* (#1248) 2023-03-03 17:32:06 +00:00
Madhur Tandon
727267ae22 split interpreter class (#1218)
* split interpreter class

* add new files

* add newlines

* disable eslint for run

* remove usage of interpreter from unit test

* delete fakeinterpreter class

* fix unit tests

* add comments

* remove interpreter.ts and pyodide.ts files

* suggested changes
2023-03-03 22:23:52 +05:30
Hood Chatham
b5d15c2f7e Actually generate test reports (#1246) 2023-03-03 14:10:48 +01:00
Hood Chatham
589c614e57 Fix syntax errors in html files, apply dos2unix, prettier everything (#1244)
* Fix syntax errors in html files

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-03 12:59:49 +01:00
Hood Chatham
4588e90226 Add test reporter (#1242)
* Add test reporter

* Fix indendation

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-02 12:38:51 +00:00
Hood Chatham
8665a14dec Begin making pyscript.py into a Python package (#1232)
* Begin making pyscript.py into a Python package

* Fix path
2023-03-02 12:30:43 +00:00
Jeff Glass
43d598d951 Fix Failing test_multiple_async (#1237) 2023-02-28 07:21:10 -06:00
Fábio Rosado
68018cf078 Add intersphinx and some docs (#1217)
* Add intersphinx and some docs

* Remove spaces

* Address Jeff comments
2023-02-28 11:37:21 +00:00
Jeff Glass
ef4ab0d7a8 Add typing for tagExecutionLock (#1235) 2023-02-28 12:27:49 +05:30
Hood Chatham
e66a2702df Fix error message (#1225) 2023-02-28 12:22:40 +05:30
Hood Chatham
c57d4a7054 Remove @staticmethod decorator from top level definitions (#1224) 2023-02-28 12:22:13 +05:30
Hood Chatham
a36f08f0f1 Try new import path and fall back to old one (#1223) 2023-02-28 12:21:55 +05:30
pre-commit-ci[bot]
760a8c75a5 [pre-commit.ci] pre-commit autoupdate (#1234)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.34.0 → v8.35.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.34.0...v8.35.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-28 12:12:28 +05:30
Jeff Glass
740fd921e1 Make plugin methods optional (#1134)
* Make plugin methods optional using optional chaining on all methods.
2023-02-27 20:14:07 -06:00
Jeff Glass
065c697070 Fix by comparing to str(results)) (#1233) 2023-02-27 19:45:24 -06:00
Madhur Tandon
e2c2459290 wrap runPython in async (#1212) 2023-02-21 20:35:19 +00:00
pre-commit-ci[bot]
11c79a5344 [pre-commit.ci] pre-commit autoupdate (#1211)
updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.6.0 → v2.7.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.6.0...v2.7.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-21 09:16:17 +00:00
pre-commit-ci[bot]
429fe4c356 [pre-commit.ci] pre-commit autoupdate (#1202)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.33.0 → v8.34.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.33.0...v8.34.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-14 11:14:02 +00:00
Russell Keith-Magee
a18b4edfc0 Updated freedom demo to make use of Toga 0.3.0 and briefcase web backend. (#1203) 2023-02-14 11:13:39 +00:00
Mariana Meireles
b14a2bba5f Marimeireles fix/#1081 (#1155)
* Improves repl id output

* Fix tests for new REPL output ids

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add new REPL tests

* Pre commit linting

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove mistake

* Fixing tests that i didn't notice were broken?

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-14 07:51:43 +01:00
Ted Patrick
1f825edc28 Issues Configuration (#1157)
* Issues Configuration

* format

* Remove issue staler
2023-02-09 17:05:54 -06:00
Mariana Meireles
6ed834807a Adding info on how to set up test env + rewording a few things (#1156)
* Adding info on how to set up test env + rewording a few things

* changelog entry

* lint
2023-02-08 11:25:12 -08:00
Madhur Tandon
9a908e5fd0 Upgrade Pyodide to v0.22.1 (#1144)
* upgrade to pyodide 0.22.1

* pin bokeh in panel examples

* fix typo

* fix tests by using custom bokeh wheel

* fix bokeh interactive test

* adhere to new loadPackage API
2023-02-08 22:01:51 +05:30
Mariana Meireles
4c30359b71 Missing one line to make test (#1154)
`make test` command was incomplete.
2023-02-07 11:18:45 +05:30
pre-commit-ci[bot]
34dfe2d80b [pre-commit.ci] pre-commit autoupdate (#1153)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/psf/black: 22.12.0 → 23.1.0](https://github.com/psf/black/compare/22.12.0...23.1.0)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-07 11:17:57 +05:30
Fábio Rosado
25bcff10b7 Fix import warning for js.document (#1151) 2023-02-06 16:11:47 +00:00
Fábio Rosado
81268d0545 Add config option to splashscreen so users can disable it plus docs (#1138)
* Allow disabling splashscreen

* Move disabled to if statement

* Add docs for py-splashscreen and test for logging

* Add entry to changelog

* Address Jeff's comments

* Rename disabled option to enabled and set to true by default

* Fix logic and tests

* Uncomment test

* Fix test
2023-02-04 15:56:48 +00:00
Madhur Tandon
8f0a7706d7 fix py-markdown plugin test (#1145) 2023-02-04 20:57:17 +05:30
Mariana Meireles
46150f9b80 complete install guide (#1140) 2023-01-31 08:18:58 -08:00
INC
247745b7e7 Fixing docs Issue #1033 (#1037)
* Move the info in /pyscriptjs/README.md to /docs/development/developing.md

* developing.md: Markdown linting

* Fixing docs issue #1033

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* setting-up-environment.md: Markdown Linting

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-31 12:28:25 +00:00
pre-commit-ci[bot]
94cc09b610 [pre-commit.ci] pre-commit autoupdate (#1139)
updates:
- [github.com/pycqa/isort: 5.11.4 → 5.12.0](https://github.com/pycqa/isort/compare/5.11.4...5.12.0)
- [github.com/pre-commit/mirrors-eslint: v8.32.0 → v8.33.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.32.0...v8.33.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-31 10:49:14 +05:30
Jeff Glass
a210b2d5f5 Improve typing on PyScriptTag (#1135) 2023-01-26 09:38:07 -06:00
Jeff Glass
12bf6db331 Change Plugin Hooks to Use options object/kwargs (#1132) 2023-01-26 07:20:04 -06:00
Madhur Tandon
697ac9de9a fix exception thrown but not shown in DOM in event handler (#1131)
* fix exception not thrown in event handler

* fix implicit display test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-25 20:08:05 +05:30
Fábio Rosado
4124bb5edc Restructure the tutorials index page (#1090) 2023-01-25 12:28:23 +00:00
Fabio Pliger
d55340a817 Better test support for Python Plugins (#1108)
* add plugins testing utils module

* add plugins manager fixture and init plugins tests helper in conftest

* add _custom_elements attribute to pyscript.Plugin to allow plugins to track the CE they register

* add test for py_tutor

* remove unrelated code from prims js script

* ensure a Plugin always has the app attribute and improve tests

* add tests for py_tutor create_code_section

* implement PluginsManager reset and add teardown on plugins_manager fixture to clean it up after a test

* add test to check if plugin has been registered

* add docstrings to new tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add docstrings to plugins tester

* add changes from main

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* lint

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add todo to add remaining PluginsManager lifecycle events

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-24 13:32:16 -08:00
Mohammad Anash
0de8cd9ab7 Update README to point to development docs (#1129) 2023-01-24 19:57:00 +00:00
Madhur Tandon
4e8281c749 fix display multiple append with target (#1126)
* fix display multiple append with target

* flake8 ignore long lines

* fix img render test
2023-01-24 22:01:19 +05:30
pre-commit-ci[bot]
357fbc644d [pre-commit.ci] pre-commit autoupdate (#1127)
updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.5.0 → v2.6.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.5.0...v2.6.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-24 11:20:07 +05:30
Fábio Rosado
7947a8a2dc Add an id if the user forgot when using py-attribute (#1122) 2023-01-21 20:48:27 +00:00
Fábio Rosado
35de3aa154 Add f string formatting ignore (#1121) 2023-01-20 21:14:43 +05:30
pre-commit-ci[bot]
1ea687beb8 [pre-commit.ci] pre-commit autoupdate (#1111)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.31.0 → v8.32.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.31.0...v8.32.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-20 21:14:32 +05:30
Fábio Rosado
bb5c59307a Rename runtimes with interpreter (#1082) 2023-01-16 18:52:31 +00:00
Mariana Meireles
5a3c414c8f we don't really use numpy here (#1101) 2023-01-11 19:43:26 -08:00
Fábio Rosado
cc4b460183 Allow fetching plugins from URL (#1065) 2023-01-11 17:03:53 +00:00
Jeff Glass
470c3489dd Restore output attribute of py-script tags, add py-script exec lifecycle hooks (#1063)
* Add beforePyScriptExec, afterPyScriptExec lifecycle hooks

* Add stdiodirector plugin for `output`, `stderr` attributes of py-script tag

* Add docs on `output` and `stderr` attributes of py-script tag

* Tests

* Removed output deprecation warning for `output` attribute

* Add createSingularWarning(), with createDeprecationWarning as alias
2023-01-10 13:00:29 -06:00
Jeff Glass
e1b4415193 Fix Flaky test_execute_on_shift_enter (#1097)
* Wait for text to render in DOM before 'assert', to fix timing issue.
2023-01-05 07:29:20 -06:00
Jeff Glass
77d98a565e In a Py-Repl, Shift Enter Shouldn't Insert Newline (#1094)
* Prevent shift-enter adding newlines in Py-Repl

* Add test
2023-01-04 12:26:46 -06:00
Fábio Rosado
412da2de08 Add version file (#1087) 2023-01-03 17:31:13 +00:00
Fábio Rosado
dbdcd0b3d0 Remove deprecated elements and adds deprecation banner to pys-on (#1084)
* Show deprecation banner

* Add test for deprecation warning

* Remove deprecated elements

* Add entry in changelog

* Update test_style

* Remove random color rule

* Add PR link to changelog
2023-01-03 13:14:20 +00:00
pre-commit-ci[bot]
5c67384fbf [pre-commit.ci] pre-commit autoupdate (#1086)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.30.0 → v8.31.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.30.0...v8.31.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-03 10:55:37 +00:00
Fábio Rosado
35b0f9d377 pys-onClick shouldn't prevent splashscreen from closing (#1069) 2022-12-30 12:34:27 +00:00
Fábio Rosado
95783bc284 Add changelog to docs (#1066) 2022-12-29 23:07:39 +00:00
Ioannis Chrysostomakis
4b840f7cbd Minor refactoring in logger and pyconfig (#1072) 2022-12-28 10:51:21 +00:00
pre-commit-ci[bot]
f73d6cd9f2 [pre-commit.ci] pre-commit autoupdate (#1078)
updates:
- [github.com/pycqa/isort: v5.11.3 → 5.11.4](https://github.com/pycqa/isort/compare/v5.11.3...5.11.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-27 19:05:40 +00:00
Roman Kehr
15bb8f03ea Pandas example file for /examples folder (#1067)
* Add files via upload

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-26 10:38:16 +00:00
Jeff Glass
059dbc88c9 Don't add plugin to manager twice (#1064)
* Prevent Python plugins from being added to PluginManager twice
2022-12-21 12:10:01 -06:00
Fabio Pliger
c0f36aa047 examples inspector plugin (#1040)
* replace unnecessary elements from hello_world example and replace with py-tutor tag

* add py_tutor plugin

* port altair example

* add code for more granular tutor mode

* add support for including modules source in pytutor

* remove js dependencies in hello_world

* put antigravity on a diet ;)

* use py-tutor on antigravity example

* use py-tutor on d3 example

* use py-tutor on bokeh example

* use py-tutor on bokeh_interactive example

* fix issue when module_paths is undefined

* remove prism js dependency leftovers

* ooops, really remove prism js dependency leftovers

* port follium example to pytutor

* port pymarkdown and matplotlib example to pytutor

* port message_passing and numpy_convas_fractals examples to pytutor

* port the panel complex  examples to pytutor

* port the panel complex  examples to pytutor

* port last examples to py-tutor

* remove prism

* remore most debugging logs and replace log with info

* add new d3.py file

* add comments to connect method

* clean pyscript class from logs

* revert class pySrc attribute

* add check_tutor_generated_code to test code inspector plugin in examples

* add doctsting to PyTutor connect

* add check for tutor code inspection on all examples

* Update pyscriptjs/src/plugins/python/py_tutor.py

fix template indentation

Co-authored-by: Fábio Rosado <fabioglrosado@gmail.com>

* Update examples/todo-pylist.html

fix typo (stray = )

Co-authored-by: Fábio Rosado <fabioglrosado@gmail.com>

* fix pymarkdown example

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
Co-authored-by: Fábio Rosado <fabioglrosado@gmail.com>
2022-12-20 07:48:07 -08:00
pre-commit-ci[bot]
d4120d2af3 [pre-commit.ci] pre-commit autoupdate (#1056)
updates:
- [github.com/pycqa/isort: 5.11.1 → v5.11.3](https://github.com/pycqa/isort/compare/5.11.1...v5.11.3)
- [github.com/pre-commit/mirrors-eslint: v8.29.0 → v8.30.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.29.0...v8.30.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-20 12:09:44 +00:00
Nayan Khedkar
dd1c008447 missing closing > in img tag (#1058) 2022-12-20 10:26:22 +00:00
Jeff Glass
3721d2cd72 Add name:pyscript to minified output (#1054) 2022-12-16 19:11:58 -06:00
Roman Kehr
e0dda0e547 Fixed "Direct usage of document is deprecated." warning (#1052) 2022-12-16 20:28:12 +00:00
Jeff Glass
3c7568c72c Adjust version_info test regex - no dot (#1045)
Tweaked the `test_version_info` test to remove matching against an extraneous '.'
2022-12-13 16:10:06 -06:00
Ted Patrick
6be1758548 Back to development 2022-12-13 11:39:11 -06:00
Ted Patrick
25809660ef 2022.12.1 (#1044)
* 2022.12.1

* release level

* fix tests for release
2022-12-13 08:06:38 -06:00
pre-commit-ci[bot]
6b9eff45bb [pre-commit.ci] pre-commit autoupdate (#1042)
updates:
- [github.com/psf/black: 22.10.0 → 22.12.0](https://github.com/psf/black/compare/22.10.0...22.12.0)
- [github.com/pycqa/isort: 5.10.1 → 5.11.1](https://github.com/pycqa/isort/compare/5.10.1...5.11.1)
- [github.com/asottile/pyupgrade: v3.3.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v3.3.0...v3.3.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-13 10:12:34 +05:30
Madhur Tandon
08e83feaf5 getPySrc should return source code (#1041)
* getPySrc should return source code

* fix lint

* add test

* fix dynamic tag test

* address feedback
2022-12-13 02:41:21 +05:30
Madhur Tandon
4f05b5afc6 remove fetching of pyscript.py from tutorial (#1036)
* remove fetching of pyscript.py from tutorial

* fix indentation
2022-12-10 01:04:04 +05:30
Fabio Pliger
9a5bf9918e Fix py-markdown plugin (#1008)
* fix wrong console method and unescape the tag content before running markdown on it

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add markdown plugin example test

* add PyMarkdown minimal test

* remove commented code

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove import of console from pyscript

* remove unused imports

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2022-12-08 10:09:31 -08:00
Jeff Glass
1c7cf0ba7d Bump bokeh, panel versions (#1032)
Bump panel version 13.1 -> 14.1 ; bump bokeh version 2.4.2 -> 2.4.3
2022-12-08 11:40:48 -06:00
Ted Patrick
ce2d1a4513 Release 2022.12.1.RC1 (#1030)
* Release 2022.12.1

* RC1
2022-12-08 07:49:22 -06:00
Madhur Tandon
7d50d7eea0 add docs for using display with matplotlib (#1029) 2022-12-08 07:38:45 -06:00
Fábio Rosado
e9411dc796 Fix the toga example (#1028) 2022-12-08 10:52:09 +00:00
Fábio Rosado
5cf2de16d1 Remove freedom units from examples (#1026) 2022-12-07 12:53:03 +00:00
Ted Patrick
e53bcf15a9 Fix for D3 and 3JS demos (#1025)
* fix for d3 example

* fix webgl +upgrade 3js
2022-12-06 13:36:03 -06:00
Madhur Tandon
bec70b60b8 add reference to Jeff's blog (#1024)
* add reference to Jeff's blog

* fix url
2022-12-06 23:08:12 +05:30
Fábio Rosado
8b7fb89c68 Update docs examples so they don't use deprecated features, styling tweaks (#982)
* Deprecate pyscript output attribute

* Update code blocks so they work

* Small tweaks to styling and use html to warning

* Fix broken test from bad conflict resolution

* lowercase pyodide
2022-12-06 14:36:17 +00:00
Madhur Tandon
b2bbdda73d updated docs for fetch (#1019) 2022-12-06 19:36:23 +05:30
Madhur Tandon
ee2f46cfb9 split py-config into sections (#1022)
* split into sections

* new section about custom keys

* link to fetch section

* add example for using runtime
2022-12-06 19:26:19 +05:30
Fábio Rosado
4337e6833a Rewrite the get started tutorial using the ice cream demo (#985)
* Rewrite the get started tutorial using the ice cream demo

* Update docs/tutorials/getting-started.md

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* Address Antonio's comments

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-12-06 13:47:08 +00:00
Jeff Glass
a73c73b814 Fix antigravity (#1017)
* Fix antigravity

* Add test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-06 19:09:58 +05:30
Antonio Cuni
e8318a98f0 Introduce DeprecatedGlobal and show proper warnings (#1014)
* kill the PyScript class and the weird pyscript instance; from the user point of view its functionalities are still available as pyscript.*, but pyscript is not the module, not the instance of PyScript

* simplify the code in _set_version_info, while I'm at it

* start to implement DeprecatedGlobal

* DeprecatedGlobal.__getattr__

* don't show the same warning twice

* DeprecatedGlobal.__call__

* make it possible to specify a different warning message for every global

* WIP: carefully use DeprecatedGlobal to show reasonable warning messages depending on which name you are accessing to. More names to follow

* deprecate more names

* deprecate private names

* depreacte direct usage of console and document

* deprecate the PyScript class

* use a better error message

* fix test_pyscript.py

* introduce a __repr__ for DeprecatedGlobal

* add an helper to ensure that we don't show any error or warning on the page

* WIP: ensure that examples don't use depreacted features. Many tests are failing

* don't deprecate Element

* don't use the global micropip to install packages, else we trigger a warning

* use a better error message for micropip

* fix test_todo_pylist to avoid using deprecated globals

* fix test_webgl_raycaster

* fix tests

* make HTML globally available

* add MIME_RENDERERS and MIME_METHODS

* fix the typing of Micropip, thanks to @FabioRosado
2022-12-06 19:01:57 +05:30
Ted Patrick
94f2ac6204 Fake server 404 support (#994)
* Fake server 404 support

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* 404 test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-05 21:26:11 -06:00
pre-commit-ci[bot]
cc6cb4ded0 [pre-commit.ci] pre-commit autoupdate (#1021)
updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.4.0 → v2.5.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.4.0...v2.5.0)
- [github.com/asottile/pyupgrade: v3.2.2 → v3.3.0](https://github.com/asottile/pyupgrade/compare/v3.2.2...v3.3.0)
- [github.com/pre-commit/mirrors-eslint: v8.28.0 → v8.29.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.28.0...v8.29.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-05 21:07:16 -06:00
Fábio Rosado
c61d4191c3 Convert image bytes to base64 in pyscript's render_image (#1020)
* Convert bytes to b64 if needed

* Move test and check for pattern
2022-12-05 21:37:03 +00:00
Madhur Tandon
e284da7c09 Fix clashing test names (#1018)
* rename tests

* rename tests for element
2022-12-06 00:43:02 +05:30
Fábio Rosado
9992096654 Add Element to the API reference (#998) 2022-12-05 15:14:34 +00:00
Mariana Meireles
c696d92f40 Rm MIME types that we don't offer support to (#1013) 2022-12-05 16:09:34 +01:00
Fábio Rosado
af60299324 Improve UX when we can't install a package (#1000) 2022-12-05 14:35:15 +00:00
Fábio Rosado
5aa9135a34 Remove comments from github actions (#1011) 2022-12-02 14:11:59 +00:00
Mariana Meireles
72e23ac86f Rm id use (#912)
* rm unecessary code on output rendering on pyscript.py

* Remove all ids from repl

* Fix problems on rendering outside repl

* fixing tests

* Fixes repl and tes_py_repl

* Fix zz tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test 864now works consistently

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-02 00:59:21 +01:00
Madhur Tandon
33d49ad87d add docstrings for loadFromFile (#997)
* add docstrings for loadFromFile

* address feedback

* add example usage

* fix typo
2022-11-30 20:54:10 +05:30
pre-commit-ci[bot]
aa2335ca2e [pre-commit.ci] pre-commit autoupdate (#990)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.4.0)
- [github.com/PyCQA/flake8: 5.0.4 → 6.0.0](https://github.com/PyCQA/flake8/compare/5.0.4...6.0.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-30 09:05:26 -06:00
Fábio Rosado
b31428006c Use response.ok instead of just status 200 (#999) 2022-11-30 13:17:48 +00:00
Madhur Tandon
dc1d583791 remove unneeded imports (#991) 2022-11-30 15:16:16 +05:30
Jeff Glass
4299a74e40 Invalidate Importlib's Module Cache on Writes to FS (#996)
* Add runtime.invalidate_module_path_cache() to clear importlib's cache of modules

* Clear cache after [[fetch]], after plugin files download, after plugins setup, and prior to py-script tag execution.
2022-11-29 15:36:23 -06:00
Fabio Pliger
3e408b7baa Python Plugins (#961)
* add test and example files

* update config to include python plugins in build

* add markdown plugin

* remove full pyscript execution from pyodide

* move loading of pyscript.py from pyodide loagInterpreter to main setupVirtualEnv and add function to create python CE plugins

* add plugin class to pyscript.py

* add missing import

* fix plugin path

* add fetchPythonPlugins to PyScriptApp

* remove old comments

* fix test

* add support for python plugins beyond custom elements and add app to python namespace in main

* inject reference to PyScript app onto python plugins

* add example hook onto markdown plugin

* change plugin events logs

* remove unused PyPlugin

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix type import

* add docstring to fetchPythonPlugins

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* rename addPythonPlugin method

* address PR comment

* call python plugins on hooks after the interpreted is ready

* add test for event hooks and split the test in 2 separate plugins to isolte type of plugins tests

* change python plugins initialization and registration, to inject the app from app itself instead of on the plugins themselves

* handle case when plugin cannot load due to missing plugin attribute

* add test for fail scenario when a plugin module does not have a plugin attribute

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add deprecation warning for pyscript objects loaded in global namespace

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove all from global scope

* remove create_custom_element from global scope

* rename create_custom_element to define_custom_element

* rename attributes in define_custom_element and add docstrings

* better handle connect event output

* add warning to py_markdown plugin

* remove debugging logs

* improve tests

* remove debugging log

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove unused import

* add executable shebang

* add pyodide mock module

* fmt and lint

* Update to pyodide.ffi.create_proxy per pyodide v21 api change

* Mock pyodide as package instead of mdoule

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add __init__ to pyodide package

* Update pyscriptjs/src/plugin.ts

fix logger name

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* fix pyodide import but handling the diff in their API change

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* oops, conflict resolution blooper

* Fix failing integration tests

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Jeff Glass <glass.jeffrey@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: FabioRosado <fabiorosado@outlook.com>
2022-11-28 12:39:31 -06:00
Fábio Rosado
446c131ccb Deprecate pyscript output attribute (#981)
* Deprecate pyscript output attribute

* Update pyscriptjs/src/components/pyscript.ts

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-11-25 18:04:27 +00:00
Fábio Rosado
b062efcf17 Add error codes to our custom errors (#959) 2022-11-25 17:04:10 +00:00
Mariana Meireles
30e31a86ef Fix test and add new ones to close 878 (#971)
* Fix test and add new ones to close 887

* lint
2022-11-25 17:40:36 +01:00
Fábio Rosado
182272e8c7 Add tests for changes to examples/ (#980) 2022-11-24 11:17:52 +00:00
Fábio Rosado
06df21e8e3 Add three new tutorials and small tweaks to docs (#972) 2022-11-24 10:53:22 +00:00
Fábio Rosado
cafebd68f2 Fix failing tests (#978) 2022-11-24 09:46:06 +00:00
woxtu
061d4b3f72 Use a more precise type (#976) 2022-11-23 19:16:26 +00:00
Jason Washburn
6586e79d5e remove deprecated ref in getting started doc (#974) 2022-11-23 16:52:26 +00:00
Fábio Rosado
cda6c6bc7e Update docs GitHub actions to deploy to unstable or latest (#977) 2022-11-23 16:51:11 +00:00
Fábio Rosado
a628026838 Restyle examples and add button to show code on all examples (#968) 2022-11-22 15:46:54 +00:00
pre-commit-ci[bot]
6700856b9f [pre-commit.ci] pre-commit autoupdate (#970)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.27.0 → v8.28.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.27.0...v8.28.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-22 12:21:36 +05:30
Lukas Schönmann
411aa0bbed Remove hardcoded cursor for <input> (#967) 2022-11-21 21:10:24 +00:00
woxtu
0d79d31b96 Specify the unknown type (#965) 2022-11-21 23:43:57 +05:30
Jeff Glass
cb05a9b067 Export Version from JS Module (#963)
* Export PyScript version from js module

* Add docs and test
2022-11-20 09:58:09 -06:00
woxtu
536f359fb9 Fix a typo (#964) 2022-11-20 13:51:09 +00:00
Jeff Glass
56e888ed33 Fix stray capitalization in file name (#960) 2022-11-19 03:39:54 +05:30
Jeff Glass
687b93d148 Import PyScript Version into Python Runtime (#958)
* Import current version as PyScript.__version__ and PyScript.version_info

* Add integration, python unit tests
 
* Mock pyscript.py with __mocks__/pyscript.js to make jest tests happy
2022-11-18 11:49:45 -06:00
Fábio Rosado
0e1c396d7c Add div id to target in the display so examples get displayed in the right tag (#955)
* Add target to display

* Remove output from examples
2022-11-17 14:51:16 +00:00
Jeff Glass
7e24289703 Unwind async/await chains (#957)
*Cleanup several spots where runtime.run() no longer needs to be awaited, now that #928 is merged.
2022-11-16 13:42:40 -06:00
Jeff Glass
0b23310a06 Remove 'Implicit Async', Don't Await runtime.run() (#928)
* Revert to runPython instead of await runPythonAsync

* "Implicit Coroutines" are no longer permitted in py-script tags

* Tests added for the above

* xfail test_importmap (See #938)
2022-11-16 13:11:40 -06:00
Antonio Cuni
41ebaaf366 More plugins: splashscreen and importmap (#938)
This PR move codes from main.ts into two new plugins:

- splashscreen (formerly known as py-loader)
- importmap

The old setting config.autoclose_loader is still supported but deprecated; the new setting is config.splashscreen.autoclose.

Moreover, it does a small refactoring around UserError: now UserErrors are correctly caught even if they are raised from within afterRuntimeLoad.
2022-11-16 18:08:17 +01:00
Ted Patrick
b79ceea7a8 version number in build (#953) 2022-11-15 15:50:25 -06:00
Fábio Rosado
b990bcb67a Add basic docs for py-terminal (#933)
* Add basic docs for py-terminal

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add Antonio's suggestions

* Remove terminal = true

* fix typo

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-11-15 15:35:50 +00:00
pre-commit-ci[bot]
3f0f2d9910 [pre-commit.ci] pre-commit autoupdate (#951)
updates:
- [github.com/asottile/pyupgrade: v3.2.0 → v3.2.2](https://github.com/asottile/pyupgrade/compare/v3.2.0...v3.2.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-15 18:25:18 +05:30
Fábio Rosado
4333f5f979 Zip the build folder and add it to release (#949) 2022-11-14 20:32:11 +00:00
Madhur Tandon
07e75293b8 use a const for run button svg (#948)
* use a const for run button svg

* remove id

* remove consts.ts file
2022-11-15 01:47:36 +05:30
Fábio Rosado
a9ca7106cb Fix deprecated message (#950) 2022-11-15 01:36:21 +05:30
Fábio Rosado
da2728e6df Add flag to send HTML or plain Text to banner (#947) 2022-11-14 18:36:54 +00:00
Fábio Rosado
adfa9a9b05 Deprecate py-button, py-inputbox, py-box and py-title (#931) 2022-11-14 16:29:28 +00:00
Madhur Tandon
be9b9f66d3 remove one more unneeded import (#946) 2022-11-14 19:09:03 +05:30
Madhur Tandon
9521bc7175 remove unneeded import (#945) 2022-11-14 17:07:33 +05:30
Fábio Rosado
b445f8a834 Handle non-200 code when fetch py-script src (#940) 2022-11-12 10:07:51 +00:00
Fábio Rosado
3c3dffd5ed Raise error if we get a non 200 status from fetch (#935)
* Raise error if we get a non 200 status from fetch

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add custom exception

* Add check for TypeError as well

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-10 15:00:41 +00:00
Antonio Cuni
4c8443fd00 Make HTTP cache persisten across sessions (#936)
* use pytest-cache to cache HTTP requests, so that it survives across multiple runs

* add an option to clear the HTTP cache

* add some docs about pytest
2022-11-10 15:01:27 +01:00
Fábio Rosado
06a5a54103 Fix banner width (#930) 2022-11-09 16:42:10 +00:00
Antonio Cuni
0d3c3eef4e Introduce a Plugin system, implement <py-terminal> as a plugin (#917)
This PR does two things:

1. introduce the first minimal version of a Plugin system. Plugins are subclasses of the Plugin class, and pyscript will call the relevant methods/hooks at the right time. Currently, I have added only the minimal sets of hooks which were needed for this PR.

2. Implement <py-terminal> as a plugin.
2022-11-09 16:17:21 +01:00
Madhur Tandon
f0a6fb913f add test for not escaping characters in pyconfig (#929) 2022-11-09 12:18:02 +05:30
Madhur Tandon
5f0c508fed use user error for paths calculation (#927) 2022-11-09 03:13:18 +05:30
pre-commit-ci[bot]
16d9657982 [pre-commit.ci] pre-commit autoupdate (#922)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.26.0 → v8.27.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.26.0...v8.27.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-09 03:01:19 +05:30
Madhur Tandon
40d098310e decode innerhtml for pyconfig (#926) 2022-11-09 03:00:37 +05:30
Fábio Rosado
1345449d57 Create error or warning level banners and allow users to close it (#909) 2022-11-08 17:19:01 +00:00
Madhur Tandon
515858f313 implement proposal for fetching paths and retaining structure of dirs and packages (#914)
* implement proposal

* update docs and replace py-env

* more docs

* suggested proposal

* update docs

* add to_file parameter

* remove comment from Makefile

* suggested improvements

* move tests from basic to py_config

* retain leading slash from the first path
2022-11-08 17:26:45 +05:30
Fábio Rosado
2f452e9dc7 Add development section to our docs (#920) 2022-11-07 15:36:05 +00:00
Antonio Cuni
66119157a7 display() should escape by default (#915)
- display(some_str) escapes the string by default. This is almost always what you want

- display(some_obj) calls repr(obj) and escapes the result. Again, it's a very sensible default

- if you want to inject some raw HTML in the output, you can use the new HTML class: display(HTML("<p>hello</p>")).
2022-11-03 09:20:10 +01:00
pre-commit-ci[bot]
5b671dd1d0 [pre-commit.ci] pre-commit autoupdate (#913)
updates:
- [github.com/asottile/pyupgrade: v3.1.0 → v3.2.0](https://github.com/asottile/pyupgrade/compare/v3.1.0...v3.2.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-01 14:05:10 +05:30
woxtu
1017362eec Use globalThis (#908) 2022-10-31 15:25:36 +01:00
Antonio Cuni
f67b8e0285 Fix py-repl auto-generate=true (#910)
What is not tested is broken man_facepalming
Test&fix <py-repl auto-generate=true> which was broken by PR #884
2022-10-31 12:55:20 +01:00
woxtu
4c635fe84c Add syntax highlighting (#903) 2022-10-31 14:55:11 +05:30
Mariana Meireles
68e463493e Address to Jeff's review on output docs + Ted's remodeling of docs (#866) 2022-10-29 16:24:18 +01:00
Ted Patrick
f1979d60b7 Add Fabio Rosado (#899) 2022-10-28 10:41:34 -05:00
Ted Patrick
9150ebafec Fix py-repl docs (#896) 2022-10-28 07:21:48 -05:00
woxtu
9543019336 Format the TypeScript files (#877) 2022-10-28 14:18:27 +05:30
Fábio Rosado
1c53d91c6b Add more type definitions (#882)
* More typing to base.ts

* Add more types

* More types
2022-10-27 17:48:28 -05:00
Jeff Glass
4850f39b5a Upgrade to Pyodide 0.21.3 (#887)
* Upgrade to Pyodide 21.3

* During the PyodideRuntime test, set the indexURL parameter of loadPyodide to allow Jest to find pyodide-adjacent files.
2022-10-27 15:16:17 -05:00
Madhur Tandon
ab085c2d92 Retain path structure for loading paths (#845)
* update retain dir structure logic to use emscripten FS APIs

* remove unused import

* replace error message
2022-10-27 20:08:58 +05:30
Madhur Tandon
bf4d835948 remove duplicate pytest_configure (#894) 2022-10-27 16:57:12 +05:30
Antonio Cuni
214e39537b Simplify pyrepl.ts and kill base.ts (#884)
Major highlights:

1. Merge&simplify base.ts and pyrepl.ts; kill base.ts
2. improve and extente the py-repl integration tests
3. Reorder the code in pyrepl.ts. This part of the PR doesn't change much of the concrete logic: it's just a sequence of renaming variables, moving code around, group code into functions, killing code which is no longer needed. But the end result is much better and nicer to read, IMHO.

Minor highlights:

1. py-repl now uses the new logic in pyexec.ts to run the code

2. after PR Add display impl, rm outputManage, print and console.log default to browser console #749 py-repl no longer displayed the result of the last evaluated expression (e.g. if you typed 42 and run it, it displayed nothing). This PR re-introduces this behavior, which is what you would expect by a REPL.

3. improve the pytest --dev option: now it implies --no-fake-server so that sourcemaps works automatically

4. improve the names of the CSS classes to be more consistent

5. kill pyrepl.test.ts: the old tests didn't check anything useful,  this style of unit test doesn't really add much value if you have good integration tests (which now we have) and trying to revive them was not worth the hassle
2022-10-27 10:10:57 +02:00
Antonio Cuni
2d33afc195 try to display a reasonable message if you run a bare 'pytest' command (#890) 2022-10-26 18:05:12 +02:00
Ted Patrick
87ea24ebd4 header for pyrepl table (#889) 2022-10-25 19:34:27 -05:00
Ted Patrick
5380f8b9b3 Reference Docs (#888)
* Reference Docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* py-repl

* pyrepl

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-25 17:42:30 -05:00
Fábio Rosado
00121ff8ba Remove svelte (#886) 2022-10-25 14:49:53 -05:00
pre-commit-ci[bot]
80e5d20e37 [pre-commit.ci] pre-commit autoupdate (#885)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.25.0 → v8.26.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.25.0...v8.26.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-24 17:48:54 -05:00
Antonio Cuni
58f7c2137d Introduce/improve check_js_errors and improve test_no_implicit_target (#874)
Until now, we didn't have a nice way to check that we expect a specific JS error in the web page.
This PR improves check_js_errors() so that now you can pass a list of error messages that you expect.
It is tricky because we need to handle (and test!) all various combinations of cases:

- errors expected and found / expected but not found
- unexpected errors found / not found

Moreover, JS exceptions now are logged in the special category console.js_error, which means that the printed text is also available using e.g. self.console.js_error.text or self.console.all.text. However, this should never be required and it's preferred to use self.check_js_errors to check for exceptions. This fixes #795 .

Finally, use the new logic to improve test_no_implicit_target.
2022-10-24 16:24:52 +02:00
Antonio Cuni
f9194cc833 Refactor how py-script are executed, kill scriptQueue store, introduce pyExec (#881)
Yet another refactoring to untangle the old mess.
Highlights:

base.ts, pyscript.ts and pyrepl.ts were a tangled mess of code, in which each of them interacted with the others in non-obvious ways. Now PyScript is no longer a subclass of BaseEvalElement and it is much simpler. I removed code for handling the attributes std-out and std-err because they are no longer needed with the new display() logic.

The logic for executing python code is now in pyexec.ts: so we are decoupling the process of "finding" the python code (handled by the py-script web component) and the logic to actually execute it. This has many advantages, including the fact that it will be more easily usable by other components (e.g. pyrepl). Also, note that it's called pyexec and not pyeval: in the vast majority of cases in Python you have statements to execute, and almost never expressions to evaluate.

I killed the last remaining global store, scriptQueue tada. As a bonus effect, now we automatically do the correct thing when a <py-script> tag is dynamically added to the DOM (I added a test for it). I did not remove svelte from packages.json, because I don't fully understand the implications: there are various options which mention svelte in rollup.js and tsconfig.json, so it's probably better to kill it in its own PR.

pyexec.ts is also responsible of handling the default target for display() and correct handling/visualization of exceptions. I fixed/improved/added display/output tests in the process.
I also found a problem though, see issue #878, so I improved the test and marked it as xfail.

I removed BaseEvalElement as the superclass of most components. Now the only class which inherits from it is PyRepl. In a follow-up PR, I plan to merge them into a single class and do more cleanup.

During the refactoring, I killed guidGenerator: now instead of generating random py-* IDs which are very hard to read for humans, we generated py-internal-X IDs, where X is 0, 1, 2, 3, etc. This makes writing tests and debugging much easier.

I improved a lot our test machinery: it turns out that PR #829 broke the ability to use/view sourcemaps inside the playwright browser (at least on my machine).
For some reason chromium is unable to find sourcemaps if you use playwrights internal routing. So I reintroduced the http_server fixture which was removed by that PR, and added a pytest option --no-fake-server to use it instead, useful for debugging. By default we are still using the fakeserver though (which is faster and parallelizable).

Similarly, I added --dev which implies --headed and also automatically open chrome dev tools.
2022-10-23 23:31:50 +02:00
Jeff Glass
d9b8b48972 Export Runtime from PyScript Module (#868)
* export 'pyscript' JS module with runtime attribute, to allow accessing (Pyodide) runtime and globals from JS.
* add docs to explain the js module
* add integration tests for the js module

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-23 13:46:19 -05:00
woxtu
aa85f5f596 Migrate the Jest config (#873)
* Migrate the Jest config

* Run Prettier
2022-10-21 19:35:14 +05:30
woxtu
5341a0be4a Add type annotations (#869)
* Add a type declaration

* Add a missing type annotation
2022-10-21 09:03:54 -05:00
Madhur Tandon
0cfe20ca65 use emscripten virtual FS directly to load paths (#870)
* use emscripten virtual FS directly to load paths

* use more low level APIs

* use await instead of then

* remove try...catch from loadFromFile since it's being handled externally

* add test for an invalid path

* test checks for error shown to the user too

* add comment about a missing case
2022-10-21 18:43:03 +05:30
Ted Patrick
c352b502c4 ts strict - getAttribute (#863)
* ts strict getAttribute

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* mark xfail

* fix to string

* Remove

* use getAttribute for theme

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-21 07:47:44 -05:00
Antonio Cuni
58b4df6b3d skip test_repl as it's flaky (#875) 2022-10-21 14:31:54 +02:00
Jeff Glass
29ba9436c8 Fix 'no unncessary type assertion' (#871) 2022-10-20 16:18:27 +02:00
pre-commit-ci[bot]
2a044e88ad [pre-commit.ci] pre-commit autoupdate (#862)
updates:
- [github.com/codespell-project/codespell: v2.2.1 → v2.2.2](https://github.com/codespell-project/codespell/compare/v2.2.1...v2.2.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-17 19:09:20 -05:00
Ted Patrick
63092f9d72 Add note on [[runtimes]] TOML table in docs (#861)
* Note on pyconfig. Fixes #859

* spell

* grammar

* mor grammar

* goes to go
2022-10-17 17:45:24 -05:00
woxtu
0209324d57 Pin dependencies for pre-commit (#860)
* Remove an unused dependency

* Pin dependencies
2022-10-17 15:12:53 -05:00
Mariana Meireles
1587273868 Add display impl, rm outputManage, print and console.log default to browser console (#749)
* Add display impl, remove outputManage, print and console.log defaults to terminal

* Fixing tests

* Lint

* Erase unecessary code, add cuter CSS formating for errors, fix problems around REPL output

* Add fix to repl2 and lint

* lint

* Allow for list of display, fix elif to else

* Add better global option

* test work

* xfails

* (antocuni, mariana): let's try to start again with TDD methodology: write the minimum test and code for a simple display()

* (antocuni, mariana): this test works out of the box

* WIP: this test is broken, mariana is going to fix it

* add a failing test

* Add ability to deal with targets

* Add append arg and append tests

* Add multiple values to display

* Small adjustments to tests. I noticed I wasn;t running all at some point

* add display test

* Add console tests

* Add async tests

* Fix repl tests

* Fixing merging issues

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Address antocuni's review

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixing more tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* linting

* Improve repl tests

* Change my test so codespell is hapy with it

* Test: change test_runtime_config to use json instead of toml to see if stops failing on CI

* kill this file: it is a merge artifact since it was renamed into test_py_config.py on the main branch

* Change test execution order and add async tests to async test file

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-17 16:28:40 +02:00
Antonio Cuni
beb3aa1574 kill stores.runtimeLoaded and many other stores (#850)
As the title stays, the main goal of the branch is to kill the infamous runtimeLoaded global store and all the complications, problems and bugs caused by the fact that in many places we needed to ensure/wait that the global runtime was properly set before being able to execute code.

The core idea is that runtime is never a global object and that it's passed around explicitly, which means that when a function receives it, it is guaranteed to be initialized&ready.

This caused a bit of complications in pybutton.ts, pyinputbox.ts and pyrepl.ts, because they indirectly want to call runtime.run from connectedCallback, which is the only place where we cannot explicitly pass the runtime because it's automatically called by the browser.
But also, it is also a sign of a bad design, because it were entirely possible that connectedCallback was called before the runtime was ready, which probably caused many bugs, see e.g. #673 and #747.

The solution to is use dependency injection and create the class later on: so instead of having a global PyButton class which relies on a global runtime (whose state is uncertain) we have a make_PyButton function which takes a runtime and make a PyButton class which is tied to that specific runtime (whose state is certainly ready, because we call make_PyButton only when we know that the runtime is ready).
Similar for PyInputBox and PyRepl.

Other highlights: thanks to this, I could kill the also infamous runAfterRuntimeInitialized and a couple of smelly lines which used setTimeout to "wait" for the runtime.

While I was at it, I also called a lot of other stores which were completely unused and where probably leftovers from a past universe.
2022-10-17 10:31:57 +02:00
woxtu
fe708c9fb4 Remove an unused import (#858) 2022-10-17 00:38:52 +05:30
John Franey
e45d8bf973 Fix typo in passing-objects.md (#856)
Fixes typo in HTML example: `do-mmath` -> `do-math`
2022-10-15 14:56:29 -04:00
Jeff Glass
b184c92f01 Use only single rollup-plugin-copy() to avoid race condition (#843)
* Use only single copy() plugin to avoid race condition

* clean production def, better copy_target structure

* Restore '!process.env.ROLLUP_WATCH to production definition

Co-authored-by: Ted Patrick <tpatrick@anaconda.com>
2022-10-12 12:05:14 -05:00
Ted Patrick
6c8afb05a7 Don't hide undefined elements in the CSS (#837)
* Hide py-config element

* display:none for all web components

* docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add style tests for raw html and pyscript enabled html

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test naming

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-11 12:27:22 -05:00
pre-commit-ci[bot]
d3dd4573cf [pre-commit.ci] pre-commit autoupdate (#844)
updates:
- [github.com/psf/black: 22.8.0 → 22.10.0](https://github.com/psf/black/compare/22.8.0...22.10.0)
- [github.com/asottile/pyupgrade: v2.38.2 → v3.1.0](https://github.com/asottile/pyupgrade/compare/v2.38.2...v3.1.0)
- [github.com/pre-commit/mirrors-eslint: v8.23.1 → v8.25.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.1...v8.25.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-11 08:21:23 -05:00
Ted Patrick
d5cf68391a Upgrade and pin dependencies (#840)
* Upgrade and Pin Dependencies

* Removal all unused deps

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* lock

* remove svelte-fa reference from the svg style.

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-11 07:20:31 -05:00
Ted Patrick
4e54e93450 Correct the url in the example (#841) 2022-10-09 10:24:00 +05:30
Ted Patrick
e4f6387f18 Remove fa reference in py-repl 2022-10-08 20:13:25 -05:00
Ted Patrick
54cb35b60a Add directly listing for releases (fix error) (#839)
* move copy index.html out of !production to run every time

* format

* dir syntax

* file order in dir listing

* Example title
2022-10-09 05:04:28 +05:30
Ted Patrick
18ede2b729 Add directly listing for releases (#838)
* Add directly listing for releases

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-08 16:05:03 -05:00
Ted Patrick
f138b5a4f4 Add cache, fetch, retry logic to tests (#829)
* Add cache, fetch, retry logic to tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* run in parallel

* add pytest-xdist

* undo parallelism. Need to remove http server to enable.

* woops a extra space

* Pass flake8

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* spell fulfill

* use decorator for fetch if not in cache

* Fix --headed and limit to PlaywrightRequestError

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* docs on cache

* CICD caching of conda on unstable builds

* fix config issues

* empty commit to trigger gh-actions

* restore build-unstable

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove http server, add parallel

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* temp: Bypass zip runtime test and point to v0.21.3 on CDN

* suport for files in zip under /pyodide

* remove test-one

* self.http_server and remove content_type

* domcontentloaded w no timeout on base url + longer timeout on wait_for_pyscript

* Fixed #678

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* set default timeout to 60000

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* seamless --headed support

* add test-integration-parallel and default for GHActions

* simplify the code. Use http://fakeserver instead of localhost:8080 so that it's clearer that the browser is NOT hitting a real server, and use urllib to parse the url. Moreover, the special case for pyodide is no longer needed, it's automatically handled by the normal 'fakeserver' logic

* The page-routing logic is becoming too much complicated to stay as an inner function. Move it to its own class, and add some logic to workaround a limitation of playwright which just hangs if a Python exception is raised inside it

* no need to use a hash, we can use the url as the key

* re-implement the retry logic. The old @retry decorator was nice but a bit too over-engineered and most importantly failed silently in case of exceptions. This new approach is less powerful but since we want to retry only two times, simple is better than complex -- and in case of exception, the exception is actually raised

* improve logging

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <madhurtandon23@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-10-07 10:31:26 -05:00
Antonio Cuni
11a517bba4 Make the life-cycle more linear and kill some svelte stores (#830)
This is a follow-up of PR #806 and it's a big step forward towards solving issue #763.

The basic idea is that at this stage I want to streamline the execution logic
and make it as linear and easy to read/understand as possible. The diff is
relatively big, but for the most part is just "shuffling code around".


Svelte stores:
the idea is to eventually kill of them, so that we can remove the dependency
on svelte but also to avoid relying on so much global state, which makes
things more complicated and error-prone (e.g., we have several issues related
to using runtime when it's not ready yet).

I killed addInitializer, addPostInitializer and the corresponding svelte
stores tada. They are no longer needed since the relevant code is called
directly from main.ts.

I started to kill the usage of the runtimeLoaded svelte store: instead of
relying on a global variable, I want to arrive at the point in which the
runtime is passed as a parameter in all places where it's needed: pyscript.ts
is now free of global state, but I couldn't kill it yet because it's used
heavily by base.ts and pyrepl.ts. I will do it in another PR.

Other misc changes:
I added sanity checks (and corresponding tests!) which complain if you specify
0 or multiple runtimes. Currently we support having one and only one, so there
is no point to pretend otherwise

I modified the messages displayed by the loader, to be more informative from
the user point of view.
2022-10-07 17:13:12 +02:00
Jeff Glass
66b57bf812 Remove fortawesome/free-solid-svg-icons (#831) 2022-10-06 22:54:10 +05:30
Ted Patrick
a9357bd97e SVG Docs logo (#832)
* SVG Docs logo. Fixes https://github.com/pyscript/pyscript/issues/818

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-06 20:48:08 +05:30
Madhur Tandon
d7c6d42c3d remove warning (#828) 2022-10-05 01:24:51 +05:30
Madhur Tandon
4dd1dc28b1 move py-config between body tags (#827) 2022-10-05 01:13:34 +05:30
Antonio Cuni
1e05ff7c95 detect the case in which multiple <py-config> are listed
Ideally I would like it to be a fatal error, but it's too hard to do it with the current state of the code, will refactor it later (#826)
2022-10-04 19:59:59 +02:00
Mariana Meireles
e8e2e65584 Update CONTRIBUTING.md (#822)
To add that we need to have a test for every feature :)
closes https://github.com/pyscript/pyscript/issues/615
2022-10-04 17:16:48 +02:00
Ted Patrick
3727e60152 Maintainers Update (#823) 2022-10-04 09:23:47 -05:00
Ted Patrick
0254012db6 Add epic to exempt labels (#821) 2022-10-04 08:55:55 -05:00
Jeff Glass
8b97e4757f Update to Codemirror 6 (py-repl) (#814)
* Upgrade to codemirror v6

* Increase indentation to 4 spaces by default
2022-10-04 08:49:42 -05:00
Madhur Tandon
c70e121078 eliminate py-env altogether (#775)
* examples use toml now

* use 0.21.2 for now

* change config in docs

* fix pre-commit
2022-10-04 19:00:39 +05:30
Ted Patrick
a4f97e6e46 Add Github Stale to PyScript repo (#791)
* Add stale to pyscript repo

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add tags: backlog, needs-triage, needs-work

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-04 08:08:26 -05:00
Antonio Cuni
800145a83c Add a link to docs in the README (#817) 2022-10-04 18:14:12 +05:30
Antonio Cuni
c75f885cb4 Refactor py-config and the general initialization logic of the page (#806)
This PR is the first step to improve and rationalize the life-cycle of a pyscript app along the lines of what I described in #763 .
It is not a complete solution, more PRs will follow.
Highlights:

- py-config is no longer a web component: the old code relied on PyConfig.connectedCallback to do some logic, but then if no <py-config> tag was present, we had to introduce a dummy one with the sole goal of activating the callback. Now the logic is much more linear.

- the new pyconfig.ts only contains the code which is needed to parse the config; I also moved some relevant code from utils.ts because it didn't really belong to it

- the old PyConfig class did much more than dealing with the config: in particular, it contained the code to initialize the env and the runtime. Now this logic has been moved directly into main.ts, inside the new PyScriptApp class. I plan to refactor the initialization code in further PRs

- the current code relies too much on global state and global variables, they are everywhere. This PR is a first step to solve the problem by introducing a PyScriptApp class, which will hold all the mutable state of the page. Currently only config is stored there, but eventually I will migrate more state to it, until we will have only one global singleton, globalApp

- thanks to what I described above, I could kill the appConfig svelte store: one less store to kill :).
2022-10-04 14:26:12 +02:00
Ted Patrick
4011a51013 add tsc as a build step with noEmit (#816) 2022-10-04 04:51:56 -05:00
Ted Patrick
f4165dabcf TOML Error Cases (#815)
* TOML Error Cases

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove traceback

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* any is a ts feature

* full eslint

* format and disable eslint for toml.js

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <madhurtandon23@gmail.com>
2022-10-04 13:13:24 +05:30
djchou
de6c26eb05 Add discord channel (#811)
from Ted Patrick --
tedpatrick — 09/19/2022
Hello and Good Morning (CST in Austin TX)
Key: We want the dialog about Pyscript OSS to be transparent and centered in the community. Rather than add another communication platform, using this Discord meets the community where they are.
2022-10-01 20:44:58 +05:30
Ted Patrick
5f319452d5 simplify OutputCtxManager logging (#809)
* simplify OutputCtxManager logging

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-30 09:41:53 -05:00
Madhur Tandon
60d505d2d1 update docs for the minimal config (#807) 2022-09-30 19:35:16 +05:30
Ted Patrick
f64cc4dcae Minimum viable py-config default schema (#803)
* Minimium viable py-config default schema

* Add packages and paths to default

* Add in default for plugins

* Remove tests for values no longer in the default config
2022-09-29 18:54:56 -05:00
Madhur Tandon
60e6f4293a new docs for py-config without removing py-env (#802)
* new docs for py-config without removing py-env

* fix table

* fix table

* fix message for local modules

* fix src
2022-09-29 20:50:33 +05:30
Jeff Glass
00ab9a8d02 Update MAINTAINERS.md (#797) 2022-09-28 18:34:41 -05:00
Ted Patrick
7d5f6c9ead Loading and void script.evaluate() (#796)
* Loading and Script evaluate with Promise.all

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Move to 'void script.evaluate();'

* chmod files to 644

* Add a test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-28 17:38:21 -05:00
pre-commit-ci[bot]
a295edf19d [pre-commit.ci] pre-commit autoupdate (#794)
updates:
- [github.com/asottile/pyupgrade: v2.38.0 → v2.38.2](https://github.com/asottile/pyupgrade/compare/v2.38.0...v2.38.2)
- [github.com/pre-commit/mirrors-eslint: v8.23.1 → v8.24.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.1...v8.24.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-28 18:52:34 +02:00
Fábio Rosado
b674515d06 Add more unit and integration tests (#773)
* Add unit tests for pyloader and pytitle

* Add more unit tests for pyrepl, pybox and pyinputbox

* Add more tests for pyscript and pyconfig

* White space

* Fix d3 tests and improve more examples test

* Update matplotlib test

* Add numpy to dependencies

* Address Madhur comments

* Update test name
2022-09-27 03:47:32 +05:30
Ted Patrick
d033ab04da Credit Pyodide within readme.md (#792)
* Credit pyodide within readme

* Use pyscript.net definition
2022-09-26 07:03:01 -05:00
Ted Patrick
304d76d088 Enable snapshot publishing by removing --dryrun (#790) 2022-09-26 05:41:13 -05:00
Ted Patrick
978afdad97 Snapshot releases (#789)
* A workflow that enables snapshot releases by manual github action

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* typo in comment

* match naming and add name to workflow

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-25 12:24:41 -05:00
Ted Patrick
d4e41e679d examples: py-env to py-config (#784)
* examples: py-env to py-config

* 1 example as JSON with type

* Fix todo event attribute
2022-09-23 11:04:31 -05:00
Madhur Tandon
146264ff12 add toml support for configs with fast-toml (#783)
* add toml support for configs with fast-toml

* fix package-lock.json and pin pyodide to 0.21.2

* use browser version of fast-toml

* disable eslint and add credits

* fix jest issues

* use type attribute for py-config
2022-09-23 20:11:22 +05:30
Emir
dcb107ae65 add pure-python (async) HTTP request how to (#778)
* add HTTP request how to

First draft.
Proof read http-requests.md


Formatting


Reword intro


modify fetch API docs links


Conclusion

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add http-request howto into toctree, index

* implement review

By @madhur-tandon
Implement review

and fix formatting mistake in request function docstring.

* add # HTTP requests section, add fetch_kwargs to helper function

Add a section in the explanation discussing HTTP Requests

* add API reference

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* specify docs for `pyodide.http` members

* address review

By @marimeireles

* Change code [Python] to Python

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-09-23 14:14:00 +02:00
Ted Patrick
c236269d13 Update MAINTAINERS.md (#782) 2022-09-22 02:23:39 +05:30
Subramanian Mahadevan
8f658e6d85 fixed Makefile to always clean and recopy the examples build folder (located under examples) (#772) 2022-09-21 16:25:13 +02:00
Fábio Rosado
d203b60f44 Update contributing docs and remove lint from makefile (#779) 2022-09-21 16:22:12 +02:00
pre-commit-ci[bot]
a1a16aba74 [pre-commit.ci] pre-commit autoupdate (#780)
updates:
- [github.com/asottile/pyupgrade: v2.37.3 → v2.38.0](https://github.com/asottile/pyupgrade/compare/v2.37.3...v2.38.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-21 13:56:20 +02:00
Valerio Maggio
6ded003447 Fixed typo in logger message (#774) 2022-09-19 09:31:59 +02:00
Madhur Tandon
4841e29fc6 refactor py-config to use json (#754)
* refactor py-config to use toml

* switch from toml to json and add unit tests

* fix test for py-config

* fix integration test

* use flat structure for JSON

* allow merging configs

* replace arrays instead of concatenating them

* remove extra keys from inline config of integration test

* simplify array replacement logic

* allow config from src to be partial as well

* add comments to unit tests

* add unit test for setting config from both inline and src

* handle parse errors + validate config supplied

* separate functions for src and inline

* suggested improvements

* show error message in red on parser error

* fix eslint

* use resolveJsonModule as true

* use default config defined as a variable without import

* remove disable eslint comment

* remove import for covfefe.json as well

* metadata injection

* add support for schema + extra keys

* use schema_version
2022-09-16 02:07:00 +05:30
Jeff Glass
0b014eea56 Execute pys-on* events when triggered, not at load (#686)
* Execute pys-on* events when triggered, not at load

Mimicing the behavior of Javascripts 'onLoad' event, we should
not be executing the use code at page-load time, only when
the event is triggered.

* Update examples to new syntax

* Fix merge issue

* Await running event handler code

* Restore pys-on* events with original behavior, deprecation warning

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* xfail toga example

* Add missing { (typo)

* Adjust callback chandling to make linter happy

* Change alpha to latest (#760)

* Don't create custom elements in main and fix various small issues on tests (#747)

* Create custom elements when the runtime finishes loading

* Remove xfails and fix repl integration test

* Fix commented ignore

* Address Antonio's comments

* Fix bad rebase

* Make ure to wait for repl to be in attached state before asserting content

* Move createCustomeElement up so it runs before we close the loader, xfail flaky d3 test

* Fix xfail

* [pre-commit.ci] pre-commit autoupdate (#762)

updates:
- [github.com/pre-commit/mirrors-eslint: v8.23.0 → v8.23.1](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.0...v8.23.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* change documentation to point to latest instead of frozen alpha (#764)

* Toga example is xpass

* Correct 'xpass' to 'xfail' mark

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Peter W <34256109+pww217@users.noreply.github.com>
Co-authored-by: Fábio Rosado <fabiorosado@outlook.com>
2022-09-14 20:33:42 -05:00
Peter W
1c0be16f30 change documentation to point to latest instead of frozen alpha (#764) 2022-09-13 12:02:05 -04:00
pre-commit-ci[bot]
27ba8bea2f [pre-commit.ci] pre-commit autoupdate (#762)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.23.0 → v8.23.1](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.0...v8.23.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-13 10:34:24 -05:00
Fábio Rosado
c566977749 Don't create custom elements in main and fix various small issues on tests (#747)
* Create custom elements when the runtime finishes loading

* Remove xfails and fix repl integration test

* Fix commented ignore

* Address Antonio's comments

* Fix bad rebase

* Make ure to wait for repl to be in attached state before asserting content

* Move createCustomeElement up so it runs before we close the loader, xfail flaky d3 test

* Fix xfail
2022-09-13 16:59:33 +02:00
Peter W
5c1b785b4b Change alpha to latest (#760) 2022-09-12 12:07:44 -04:00
Jeff Glass
8657dfb5da Docs: How To Pass Objects between JavaScript and PyScript (#753)
* Begin writeup

* Draft full howto

* Correct code errors in writeup, swap sections

* Add introduction, clarification

* Add link to howto:js in index

* Copyedit, update examples to Pyodide 21

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add toc tree context

* Use print instead of js console in python examples

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-09-12 04:29:25 -04:00
Neil Stoker
dfa837754e Remove line numbers from example (#745)
As per #565 the current best fix is to simply remove the line numbers from the output
2022-09-12 04:28:19 -04:00
Ted Patrick
0a7df78770 Add space before/after secrets value (#757)
Co-authored-by: Ted Patrick <tpatrick@anaconda.com>
2022-09-08 07:54:33 -05:00
Mariana Meireles
066ecbe022 Add docs on how to contribute to docs (#720)
* Add docs on how to contribute to docs

* Reword some phrases
2022-09-08 07:38:31 -04:00
Ted Patrick
6c80db810f pyon-dragover to py-dragover (#755)
typo in events
2022-09-07 16:31:59 -05:00
Mariana Meireles
6023c413ab Update CONTRIBUTING.md (#728)
* Update CONTRIBUTING.md

Adding docs on how to make a pr

* Rewording so ideas are clearer
2022-09-07 03:05:20 +05:30
Peter W
7910d040b6 fix ci file sync (#752) 2022-09-06 19:30:01 +02:00
pre-commit-ci[bot]
5bd99f5224 [pre-commit.ci] pre-commit autoupdate (#750)
updates:
- [github.com/psf/black: 22.6.0 → 22.8.0](https://github.com/psf/black/compare/22.6.0...22.8.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-06 10:12:52 -05:00
Antonio Cuni
f3157b377f Improve JS logging (#743)
This PR tries to improve and rationalize what we log. Key points:
- introduce `logger.ts`: each file/component is encouraged to use the logger instead of writing directly to `console.*`
    * the logger automatically prepend a prefix like `[py-config]`, `[py-env]` which make it easier to understand where a certain message is printed from
    * it provide a central place where to add more features in the future. E.g., I can imagine having a config setting to completely silence the logs (not implemented yet)
- use the new loggers everywhere
- write to `.info()` instead of `.log()`. The idea is to keep `console.log` free, so that for the users it's easier to tell apart their own messages and the pyscript ones
- generally improve what we log. This is an endless exercise, but I tried to print more things which are useful to understand what's going on and in which order the various things are executed, and remove prints which were clearly debugging leftovers
2022-09-06 15:18:41 +02:00
Madhur Tandon
e31e03afde add tests for runtime config inside py-config and remove usage of indexURL (#734)
* add integration test for py-config

* fix bug

* fix test

* remove indexURL altogether

* make jest happy

* fix create_proxy import

* check that py-config loads an older version

* add unit test

* suggested changes

* don't use /tmp because of bandit
2022-09-01 01:02:43 +05:30
Peter W
eddde7c94c [WIP] Actions workflow cleanup/readability (#695)
* discrete steps and artifact passing

* fix small mistakes, prep test

* upload path

* fix path again

* change again

* checkout for test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* formatting

* artifact paths

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* diagnostics

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* simplify

* small cosemtic changes

* move upload to end

* needs:

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-31 10:01:41 -05:00
pre-commit-ci[bot]
7be72ee4c1 [pre-commit.ci] pre-commit autoupdate (#737)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.22.0 → v8.23.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.22.0...v8.23.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-30 19:49:15 +05:30
woxtu
6731467514 Update TypeScript to 4.8 (#739) 2022-08-30 19:47:14 +05:30
Madhur Tandon
8dd699d235 Remove workaround for sed and upgrade pyodide to 0.21.2 (#738)
* remove sed workaround + upgrade version

* upgrade package.json and package-lock.json
2022-08-30 18:19:00 +05:30
woxtu
6cb81b5c3d Remove the Svelte plugins for ESLint/Prettier (#733)
* Remove the Svelte plugins for Prettier

* Remove the Svelte plugins for ESLint
2022-08-29 01:13:16 +05:30
woxtu
17187ba3ec Remove the Svelte plugins for Rollup (#730) 2022-08-27 02:40:37 +05:30
Madhur Tandon
531ee928b0 fix linting and types related issues (#731) 2022-08-27 02:18:01 +05:30
Madhur Tandon
db806a5df9 make runtime an object of Runtime class when it is just an object (#729)
* make runtime an object of Runtime class when it is just an object

* fix constructor

* remove explicit string type

* define default values out of pyodide runtime and use default config instead of initializing a DEFAULT_RUNTIME instance

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-08-26 15:19:03 -05:00
Fábio Rosado
9de154595a Add more unit tests for PyButton and BaseEvalElement (#711)
* Add more unit tests

* Rebase main and fix failing tests

* xfail flaky test

* Fix import
2022-08-26 08:25:51 -04:00
Fábio Rosado
9e4cb79679 Fix: Examples not importing pyscript from build folder when running locally (#705)
* Copy build to examples if not running prod

* Add rollup-copy as a dev dep

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-25 18:05:17 -04:00
Bikarna Pokharel
b7834073b8 Remove unwanted code and/or text (#589)
* Remove unwanted class attribute

Multiple attributes with the same name are illegal in html. Nonetheless, the class task-check is not doing anything here.

* Remove to=task_list

The argument to=task_list is not playing any role, since the function works well without it.

Please see comment in pyscript.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Clean comment

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-25 17:30:54 -04:00
woxtu
b0e56577b5 Fix misused promises (#723)
* Remove an unnecessary await

* Add an async IIFE wrapper
2022-08-26 02:17:29 +05:30
tkeech1
ccb0e6b269 585: Add a line to the makefile to run the examples on a python serve… (#689)
* 585: Add a line to the makefile to run the examples on a python server with one line command

* Build exs and run server with previous makefile cmds

Co-authored-by: Todd Keech <tkeech1@hotmail.com>

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-25 16:43:25 -04:00
Madhur Tandon
edfd4baa1f import create_proxy and to_js from pyodide.ffi (#725) 2022-08-25 22:11:18 +02:00
woxtu
0f50f4a9fd Remove overwriting properties (#724) 2022-08-25 23:27:13 +05:30
Madhur Tandon
47494e62a7 Fix and enable integration tests in CI (#721)
* run jest only inside node + fix indexURL for integration tests

* add integration tests to CI

* use pytest from env
2022-08-25 22:01:05 +05:30
Fábio Rosado
7aa25712d9 Update tsconfig to use es2017 (#704) 2022-08-24 21:01:51 -05:00
Madhur Tandon
1db155570d PyodideRuntime should be one of the runtimes (#698)
* PyodideRuntime should be one of the runtimes

* subsume interpreter into runtime API

* fix eslint

* add comments

* move initializers, postInitializers, scriptsQueue, etc. to initialize() of Runtime Super Class

* modify comment for initialize

* small renaming

* change id to default

* fix pyscript.py import

* try adding tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add inlineDynamicImports option

* Make jest happy about ESM modules

* Attempt to make jest happy about pyodide

* point to version in accordance with node module being used

* fix base.ts

* fix tests

* fix indexURL path determination

* edit pyodide.asm.js as a part of setup process

* load runtime beforeAll tests

* add test for loading a package

* use only runPythonAsync underneath for pyodide

* import PyodideInterface type directly from pyodide

* add some comments

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>
2022-08-25 02:33:36 +05:30
Dylan
1054e8e644 Add clarification where to place script and stylesheet - README.md (#713)
* Update README.md

UPDATE: Specified to add files to head tag of HTML file

* UPDATE README.md

UPDATE README: Specify to add CSS and JS file to head tag of HTML

* Update README.md

Clean up wording.
2022-08-24 11:10:20 +05:30
Fábio Rosado
aa429f34d8 Add more integration tests for py-components and examples (#709)
* Add more integration tests for py-components and examples

for more information, see https://pre-commit.ci

* remove xfail mark since we merged fix for issue 707

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-08-23 18:22:44 -05:00
Fábio Rosado
e351889811 Set importmaps to an empty array (#708)
Use const instead
2022-08-23 18:03:52 -05:00
Fabio Pliger
24a70a8273 fix error management bug and improve examples automation (#717)
* add build to the make examples cmd so that it automates more to the user

* temporarily improve error managament when executing eval until we properly refactor the whole io and error workflow

* add minimal test for format_mime
2022-08-23 17:12:30 -05:00
Fabio Pliger
3f26657116 update pyodide version (#719) 2022-08-23 17:11:42 -05:00
pre-commit-ci[bot]
d41669af8b [pre-commit.ci] pre-commit autoupdate (#710)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/codespell-project/codespell: v2.1.0 → v2.2.1](https://github.com/codespell-project/codespell/compare/v2.1.0...v2.2.1)

* push

* push

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: pww217 <pwilson@anaconda.com>
2022-08-23 17:07:04 -05:00
Peter W
56466c2a00 fix typo 2022-08-23 17:06:19 -05:00
Fabio Pliger
fa7a97ca30 Bootstrap python tests (#697)
* move current integration tests to the integration folder

* move pyscript.py into its own python folder

* change the path for python unit testing files

* change pyscript.py path

* Update Makefile

* remove echo

* replace conda run with pytest directly

* oops, add python test files I embarrassingly forgot to add

Co-authored-by: Peter W <34256109+pww217@users.noreply.github.com>
2022-08-18 16:59:07 -05:00
Fabio Pliger
8aba271a42 Add TS tests tooling (#661)
* install test dependencies

* change config for tests

* fix linter failing tests

* add basic test file

* add custom element registration to test

* update dependencies

* add jest config file

* fix test calls on makefile and minor fix on test

* update local npm version

* clean testm file
2022-08-16 16:39:42 -05:00
Philipp Rudiger
8275aa2810 Ensure that angle brackets in pyscript tag are escaped before parsing (#684)
* Ensure that angle brackets in pyscript tag are escaped before parsing

* Improve tests

* Update pyscriptjs/tests/test_01_basic.py

Co-authored-by: James A. Bednar <jbednar@users.noreply.github.com>

Co-authored-by: James A. Bednar <jbednar@users.noreply.github.com>
2022-08-16 21:41:09 +05:30
imbev
410ddf314c Correct typo in CONTRIBUTING.md (#692) 2022-08-16 10:12:09 -05:00
pre-commit-ci[bot]
fa217bee20 [pre-commit.ci] pre-commit autoupdate (#691)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.21.0 → v8.22.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.21.0...v8.22.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-16 09:56:13 -05:00
Antonio Cuni
817d0edc69 Use the new testing machinery for test_examples (#676)
* WIP: start to use the PyScriptTests machinery to test the examples

* factor test_hello_world out of test_examples

* B011 forbids 'assert False' in tests because python -O remove asserts. Thank you, I knew that.

* improve test_simple_clock and remove it from test_examples

* test_altair

* test_bokeh

* rename

* kill the parametrized test_example and write individual tests for each of them

* test_kmeans it's slow, increase the timeout

* improve these xfail

* kill wait_for_load, no longer needed

* write the name of the issue

* add issue number

* add a trick which I discovered to run test interactively

* move the docstring inside the class
2022-08-11 19:18:42 -05:00
Antonio Cuni
513dfe0b42 Introduce PyScriptTest, an helper class to write integration tests (#663)
This PR is about integration tests: they use playwright to load HTML pages in the browser and check that PyScript works as intended, as opposed to unit tests like the ones being introduced by #665 and #661.

The main goal of this PR is to introduce some machinery to make such tests easier to write, read and maintain, with some attention to capture enough information to produce useful error messages in case they fail in the CI.

In order to use the machinery, you need to subclass tests.support.PyScriptTest, which provides several useful API calls in the form self.xxx().

See the full description here:
https://github.com/pyscript/pyscript/pull/663

Co-authored-by: Mariana Meireles <marian.meireles@gmail.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-10 12:29:59 +02:00
pre-commit-ci[bot]
bd7a20309b [pre-commit.ci] pre-commit autoupdate (#669)
updates:
- [github.com/PyCQA/flake8: 5.0.2 → 5.0.4](https://github.com/PyCQA/flake8/compare/5.0.2...5.0.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-09 09:13:52 -05:00
woxtu
a726be3c7c Remove unnecessary await (#662) 2022-08-08 23:16:02 +05:30
Mariana Meireles
10f2054e9a Create command to run tests locally (#668) 2022-08-08 10:07:37 +02:00
Fabio Pliger
2fa47f310d remove output manager code injection in repl source (#664) 2022-08-05 18:50:20 +02:00
Antonio Cuni
5b927a70c2 PyItemTemplate.strike() uses the CSS class line-through, which was part of Tailwind. Reintroduce it in our custom CSS. This fixes the todo-pylist example (#638) 2022-08-03 12:29:39 +02:00
Peter W
2a59ff8e68 point examples to /latest instead of /alpha (#624)
* point examples to /unstable instead of /alpha

* Change makefile from alpha to unstable

* unstable -> latest

* Update Makefile

* Update repl.html

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-02 13:59:50 -04:00
woxtu
e4d1befcdb Specify the array type (#653) 2022-08-02 21:10:08 +05:30
ic-768
844e04ff96 Minor refactoring (#557)
* checkpoint: added some text

* checkpoint: added setting up the environment, tips for writing good issues

* continuing to fill it out

* added more detailed description of the process of creating a change and some other cleanup.

* added a getting started section and cleaned up the grammar. This ready for the PR now

* forgot to add the new section to the TOC

* Changes

* Minor fixes

* Minor fixes

* Minor fixes

* Minor fixes

* Minor fixes

* Minor fixes

* Fix

Co-authored-by: Kevin Goldsmith <kgoldsmith@anaconda.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
2022-08-02 20:58:21 +05:30
pre-commit-ci[bot]
cc05a98b0e [pre-commit.ci] pre-commit autoupdate (#650)
updates:
- [github.com/PyCQA/flake8: 4.0.1 → 5.0.2](https://github.com/PyCQA/flake8/compare/4.0.1...5.0.2)
- [github.com/asottile/pyupgrade: v2.37.2 → v2.37.3](https://github.com/asottile/pyupgrade/compare/v2.37.2...v2.37.3)
- [github.com/pre-commit/mirrors-eslint: v8.20.0 → v8.21.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.20.0...v8.21.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-02 10:27:46 -05:00
Madhur Tandon
006d161a32 cleanup leftovers such as mode and pyodideReadyPromise (#649)
* remove usage of mode

* clean up pyodideReadyPromise
2022-08-02 20:44:41 +05:30
Madhur Tandon
a4839db79a fix tests by changing serving dir (#652)
* fix tests by changing serving dir

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-02 20:35:09 +05:30
Madhur Tandon
87e3b5b1dc remove App.svelte as CSS is already present in pyscript_base.css (#648)
* remove App.svelte as CSS is already present in pyscript_base.css

* remove usage of app
2022-08-02 17:01:23 +02:00
Madhur Tandon
faa900d502 change args for Linux for sed (#651) 2022-08-02 12:27:56 +02:00
woxtu
a5275db3ec Specify the type of store value (#643) 2022-08-01 21:45:20 +05:30
Madhur Tandon
77e017a574 Add myself as maintainer as per discussion (#636) 2022-08-01 21:40:21 +05:30
Madhur Tandon
8ed8ddbf76 use pip (latest) to install playwright (#647) 2022-08-01 20:45:49 +05:30
Philipp Rudiger
eb31978488 Add tests verifying correct example behavior (#625) 2022-07-29 14:42:49 -04:00
woxtu
677d708588 Make the stores simple (#564) 2022-07-28 22:09:21 -04:00
Nicholas Tollervey
ade0dca8f9 Update to latest Pyodide (#631) 2022-07-28 20:52:54 -04:00
Fabio Pliger
8e1cd0b268 minor changes to make linting happier (#598)
* minor changes to make linting happy

* remove cast since linter wasn't happy

* address PR comments
2022-07-28 15:30:03 -05:00
woxtu
9102768366 Improve with string interpolations (#604)
* Use string interpolations

* Fix the key in py-env
2022-07-28 11:07:10 -04:00
pre-commit-ci[bot]
0c722b9164 [pre-commit.ci] pre-commit autoupdate (#630)
updates:
- [github.com/asottile/pyupgrade: v2.37.1 → v2.37.2](https://github.com/asottile/pyupgrade/compare/v2.37.1...v2.37.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-28 11:05:34 -04:00
takahiro ono
b6f514451a fix links in contribution & troubleshooting doc (#632) 2022-07-28 11:04:55 -04:00
Mariana Meireles
c49fdfc56c Re-introduce xPyWidget update on CustomWidget's class (#576)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-07-21 15:13:11 -05:00
Peter W
676e04b28e sync examples on stable releases (#623) 2022-07-21 16:00:02 -04:00
Antonio Cuni
6aa864a351 enable blank issues (#626) 2022-07-20 15:30:28 -04:00
pre-commit-ci[bot]
72acb4826c [pre-commit.ci] pre-commit autoupdate (#620)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.19.0 → v8.20.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.19.0...v8.20.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-19 17:02:10 -05:00
pre-commit-ci[bot]
734be5f355 [pre-commit.ci] pre-commit autoupdate (#594)
updates:
- [github.com/asottile/pyupgrade: v2.34.0 → v2.37.1](https://github.com/asottile/pyupgrade/compare/v2.34.0...v2.37.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-18 11:43:38 -04:00
Leonardo Pliger
cede06ae19 Clearer contribution docs & add troubleshooting page (#597)
* Expanded upon the make setup docs

* Fixed formatting & speling, added troubleshooting

* same

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-18 11:42:32 -04:00
Christian Clauss
19491d8010 f-string accelerates examples.utils.format_date() (#591) 2022-07-12 11:26:47 -05:00
pww217
c580aac991 add workflow dispatch to unstable 2022-07-07 14:47:23 -05:00
pww217
032d1aaad7 change path to /build 2022-07-07 14:45:33 -05:00
Mariana Meireles
afa216dc5e Mv build folder from examples/build to build/ (#571)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-07-07 11:29:09 -03:00
Nicholas Tollervey
69339fe3de Add myself to the list of maintainers as per recent discussion. (#573) 2022-07-06 10:36:23 +02:00
pre-commit-ci[bot]
571bb2b294 [pre-commit.ci] pre-commit autoupdate (#570)
updates:
- [github.com/psf/black: 22.3.0 → 22.6.0](https://github.com/psf/black/compare/22.3.0...22.6.0)
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.3.0 → v2.4.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.3.0...v2.4.0)
- [github.com/pre-commit/mirrors-eslint: v8.18.0 → v8.19.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.18.0...v8.19.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-04 21:03:35 -03:00
Fabio Pliger
91a09a09f7 Rename examples cmd and add checks (#563)
* add checks for node and npm versions

* rename example cmd to examples
2022-07-04 15:21:17 -03:00
munyoudoum
9b3433f6ae fix: typos in play_mario, handtrack examples (#566) 2022-07-04 15:19:18 -03:00
Leonardo Pliger
ee9b0960f7 Add support to py- events that map all js events available (#561)
* added the  py- events throughout pyscript.ts

* Integrated the py- event throughout the examples

* Fixed spelling error
2022-06-29 19:49:21 -03:00
woxtu
506ac2574f Add type annotations (#562) 2022-06-28 14:17:23 -05:00
ic-768
dc84d7c1b5 Minor improvements (#556)
* checkpoint: added some text

* checkpoint: added setting up the environment, tips for writing good issues

* continuing to fill it out

* added more detailed description of the process of creating a change and some other cleanup.

* added a getting started section and cleaned up the grammar. This ready for the PR now

* forgot to add the new section to the TOC

* Minor fixes

Co-authored-by: Kevin Goldsmith <kgoldsmith@anaconda.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
2022-06-28 14:16:05 -05:00
Fabio Pliger
fcaa57307f See you later tailwind (#452)
* start removing tailwind and rebuilding some css

* add css to pybox and add class to repl

* set output component visibility

* replace tailwind class with single component class

* add styles to css

* replace classes on  button

* replace classes on input

* replace classes in title

* replace classes on list

* replace classes

* add new style file

* add list element style

* remove tailwind classes from todo example

* revert link on examples files

* remove tailwind config files

* remove commented old code

* add missing ;
2022-06-24 18:30:07 -05:00
Mariana Meireles
d25e754beb Move dashboard workflow to worflow dir (#554)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-24 17:01:52 -05:00
Peter W
7f6f411ea8 Try new method to keep CI from running on forks (#538) 2022-06-24 16:55:15 -05:00
Fabio Pliger
96a73e31f3 add diataxis info to docs readme (#548)
* add loca build info to htmlserve

* add info about diataxis to the docs/readme

* add diataxis img
2022-06-24 17:06:47 -03:00
woxtu
c7942d7d8f Use the type definition of pyodide (#535)
* Import the type definition

* Add type annotations
2022-06-24 14:25:14 -05:00
Leonardo Pliger
479348eec9 Added section and cleared up documentation in getting started (#547)
* add section and cleared up documentation

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* I fixed the typo in getting-started

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-24 16:14:48 -03:00
Peter W
ebfed27630 release, latest, unstable branches (#550)
* build unstable workflow

* releases are synced to /latest and /releases/YYYY.MM.MICRO/

* slashes
2022-06-24 10:32:00 -05:00
Mariana Meireles
8923485169 Update feature-request.yml (#541)
Fix typo
2022-06-23 17:44:55 -05:00
Brandon High
d62de26683 Fix inconsistencies and reduce verbosity in examples/index.html (#545) 2022-06-23 17:40:36 -05:00
pww217
1dd9c5b009 small renaming 2022-06-23 11:22:33 -05:00
Peter W
01b64e18ab add release.yml, release automation ready for prod (#539)
* add release.yml, release automation ready for prod

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update .github/workflows/build-release.yml

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* dont overwrite /alpha/ and change unstable to latest

* alpha -> releases

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-06-23 11:08:25 -05:00
Mariana Meireles
fa61339a49 Add GHA to push issues directly to dashboard (#534)
* Add GHA to push issues directly to dashboard

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-22 13:40:31 -03:00
Philipp Rudiger
deb2eee3ad Revert output manager after REPR evaluation (#522)
* Revert output manager after repr evaluation

* Fix indentation
2022-06-21 16:42:53 -05:00
Philipp Rudiger
829cc9f6f9 Simplify tests with pytest-playwright (#523)
* Simplify tests with pytest-playwright

* Add pytest-playwright to pip

* Fix simple_clock example

* Attempt to make example tests more robust

* Make pre-commit happy

* Revert accidental change to simple_clock pyscript resources

* Another attempt at reducing flakeyness

* Do not wait until page load event is fired

* Remove pointless py-config

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-21 14:28:05 -03:00
pww217
1c7ef6622b test release automation 2022-06-21 10:26:39 -05:00
pww217
f54ae52b2a test publishing 2022-06-21 10:10:10 -05:00
pww217
171ae3cabe skip test for now 2022-06-21 09:57:30 -05:00
Peter W
f3888df88c Release automation (#521)
* workflow updates

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* build release

* remove if

* test on main

* update docs release workflow

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-21 09:42:56 -05:00
pre-commit-ci[bot]
9274f9ec08 [pre-commit.ci] pre-commit autoupdate (#516)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.2.0 → v4.3.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.2.0...v4.3.0)
- [github.com/asottile/pyupgrade: v2.32.1 → v2.34.0](https://github.com/asottile/pyupgrade/compare/v2.32.1...v2.34.0)
- [github.com/pre-commit/mirrors-eslint: v8.17.0 → v8.18.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.17.0...v8.18.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-21 09:11:00 -05:00
woxtu
6822105c70 Add type annotations (#488) 2022-06-20 13:22:03 -03:00
Gabriel Silvério
d5d855e4c3 Improved user interface of the examples page (#504)
* Added card components for basic examples

* Added card components for mime rendering

* fix anchor tag inside anchor tag

* Added card components for js interaction

* Added card components for visualizations e dashboards

* Refactor card components responsive

* Fix href Fractals with NumPy and canvas

* Refactor quote format

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added css files

* Refactor card components for basic examples

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Rename global file to main

* Add css variables

* Refactor card components

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Refactor move css files into css folder

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-15 16:20:20 -05:00
idanenglander
1e09ac4fd3 Adding FAQ topic and link from main index (#513)
* Adding FAQ topic and link from main index

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Adding periods

* fix typo

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-15 15:37:03 -05:00
LandonTheCoder
bc513400c5 Fix URL source reference. (#517)
The old version erroneously referenced "./build/" instead of "https://pyscript.net/alpha/".
2022-06-14 14:21:08 -05:00
Ryan Russell
715ceb9ed4 Improve WebGL Raycaster example (#478)
Signed-off-by: Ryan Russell <ryanrussell@users.noreply.github.com>
2022-06-10 11:02:02 -05:00
pre-commit-ci[bot]
0115b152a8 [pre-commit.ci] pre-commit autoupdate (#497)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.16.0 → v8.17.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.16.0...v8.17.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-10 10:48:14 -05:00
andre-dietrich
e1622a56fa fix: < & > are parsed with HTML escape symbols (#481)
Adds utils.htmlDecode arround innerHTML to read the code for <py-repl> and
<py-script>, which preserves all newlines, tabs, and < & > characters.

Fix bug #480
2022-06-09 16:01:31 -05:00
WrigglySplash
03fee56a54 Added example code block to py-repl tag section (#455) 2022-06-02 16:10:21 -03:00
J.I. Cruz
d00171a629 Fix typo/reformat GETTING-STARTED.md (#460)
* Fix conflict

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-02 16:09:29 -03:00
Nuhman Pk
fa28b218ec Added link to Readme file (#487)
https://github.com/pyscript/pyscript/blob/main/README.md
2022-06-02 14:29:05 -03:00
Mariana Meireles
eb882170d5 Fix all favicon issues (#483)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-01 15:41:52 -05:00
Mariana Meireles
48a565a51d Fix all favicon issues (#483)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-01 15:41:31 -05:00
Fabio Pliger
f60dd6a788 Fix extensions regression bug (#489)
* add output div visibility rule and make sure CustomWidget is being registered

* add new runAfterRuntimeInitialized method that classes can use to run code only after runtime actually initialized

* replace setTimout with proper event to wait for runtime to be completed

* replace setTimout on pyinpytbox with proper event to wait for runtime to be completed
2022-06-01 15:39:05 -05:00
Jannis Leidel
d6a88d4c9e Only run docs review workflow on non-forks. (#490)
* Only run docs review workflow on non-forks.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-01 21:23:42 +02:00
woxtu
4b4ff08131 Change the metadata format (#457)
* Chnage the metadata format

* Add syntax highlighting

* have simple_clock example run from local build to test change

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-06-01 15:49:41 -03:00
Michael Mayer
698478ef95 added a link to the Contributing Guidelines (#477)
The Contributing Guidelines are referenced in the PyScript Documentation readme. Added a quick link to get there
2022-05-30 14:18:30 -03:00
Ifihanagbara Olusheye
4ab9ab51f6 Fixed typo in getting-started.md (#466)
* Fixed little typo

* Fixed extra typo
2022-05-27 17:02:52 -05:00
Jaynarayan vaishnav
bf3995d45c update README.md and CONTRIBUTING.md (#254)
* update README.md

Corrected the grammatical mistakes to make the documents easier to read and understand.

* update README.md

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update README.md

made required changes

* update CONTRIBUTING.md

made necessary changes.

* fixed a typo in CONTRIBUTING.md

* removed unnecessary file

* removed unnecessary file

* removed unnecessary words

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-27 01:09:56 -05:00
Mariana Meireles
4fe603bf96 Fix import link (#339)
Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-27 01:05:53 -05:00
Fabio Pliger
0639827d00 fix examples indent (#454) 2022-05-27 00:36:37 -05:00
marianoweber
eaacd45672 [FIX] output management cleanups (#464)
* return on \n before empty div is appended

* use appendOutput with out.write

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: Mariano Weber <info@uiremotely.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-27 00:21:47 -05:00
Dan Meador
5d733ab915 Add issue forms (#264)
* Added bug report and feature request issue forms

* Update bug-report.yml

Added browsers dropdown to bugs

* Added misc issue type

* Add keypress event to todo example (#241)

* add enter keypress event in todo example

* fix linting

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Changed variable names to snake_case for PEP8 formatting (#211)

* Changed variable names to snakecase for PEP8 formatting.

* Changed variable names to snakecase for PEP8 formatting.

* fix indentation

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>

* Add issue templates (#252)

* add issue templates

* incorporate @fpliger suggestions

* Removed mardown files. Added link for questions

* Updated browser dev console info

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Minor typo

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix issue with labels that should be strings, ignore pretty-format of ISSUE_TEMPLATE yaml files

* Removed old md. Updated label

* add the needs-triage label to all new issues

Co-authored-by: Allan Lago <35788148+alago1@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Jason Barnwell <master.j1994@gmail.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
2022-05-26 23:59:42 +02:00
Peter W
1bf6cc0e72 Fix examples Ci, Makefile, some doc references (#469)
* fix examples ci, makefile, and update docs

* getting started reference
2022-05-26 16:56:54 -05:00
Mariana Meireles
a9470ed9c1 Move tests, create makefile action to run tests on examples (#433)
* Move tests, create makefile action to run tests on examples

* Correct import file for html files

* Build environment for tests

* Fix the CI

* rearrange CI

* fix find cmd and make sure we don't delete the folder implicitly

* more rearranging

* fix folder permissions and custom sed for subfolders

* add toga wheels files

* re-add missing file

* mirror latest changes in alpha ci

* fix find cmd

* try different fix for find

* remove redundant build

Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: pww217 <pwilson@anaconda.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-26 16:31:38 -05:00
Philipp Rudiger
2c5ef95027 Update panel examples to panel 0.13.1 (#458)
* Update panel examples to panel 0.13.1

* More indent
2022-05-24 18:01:45 -05:00
marianoweber
f712b1369a [PROPOSAL] REPL output replacement (#439)
* fix OutputManager _append setter

* fix OutputManager change parameters

* fix OutputCtxManager __init__ and change methods

* replacing OutputManager pyscript.write with write function

* add optional output-append attribute to py-repl

* add appendOutput(default: true) to base component

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update pyscriptjs/src/components/pyrepl.ts

Co-authored-by: woxtu <woxtup@gmail.com>

* change from output-append flag to output-mode attribute

* removed type annotation

* repositioned setOutputMode call for auto-generated REPLs to work

* fixed indentation error for indented input

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* added preEvaluate method

* moved output-mode logic to preEvaluate

* remove static write method from PyScript, add write method to Element

* removed err parameter from OutputCtxManager

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add PyScript.write back with a deprecation warning

* fix wrong input name

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: woxtu <woxtup@gmail.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-24 17:58:48 -05:00
Iftikhar #100Devs
2f03b18619 updated-README-files-Contributing-Section (#438) 2022-05-23 18:18:30 -05:00
ic-768
8cd5ba6361 Minor refactoring (#437) 2022-05-23 18:15:37 -05:00
pre-commit-ci[bot]
c951961a92 [pre-commit.ci] pre-commit autoupdate (#450)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.15.0 → v8.16.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.15.0...v8.16.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-23 15:11:44 -05:00
woxtu
3b68e1b27d Bundle the Python files into the output file (#441)
* Bundle the Python files into the output file

* Remove unused functions
2022-05-22 16:30:19 -05:00
weensy
48e6b1a84e Fix typo in getting-started.md (#443)
- place holders => placeholders
- can by used by => can be used by
2022-05-22 11:09:34 -05:00
Peter W
ee46b46234 Add testing to CI flow (#418)
* new testing ci flow

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* install conda

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test conda

* pre-commit fix

* remove if

* makefile fix

* fix pytest install

* argument for test

* restructure

* fix sync

* full path filter

* use setup-condav2

* syntax

* test path

* add binary argument

* remove which

* Update Makefile

* remove arguments

* trigger CI

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-20 13:45:49 -05:00
Furkan Doğan
db49fd498a fixed the logging of initializers (#431) 2022-05-19 19:44:55 -03:00
woxtu
e95b90363e Add event listeners properly (#424) 2022-05-19 17:56:53 -03:00
woxtu
82c0d741e4 Add type annotations (#396)
* Add type annotations

* Replace `StateCommand` with `Command`

* Revert "Replace `StateCommand` with `Command`"

This reverts commit 2dfc2d34e4.

* Fix the return value
2022-05-19 16:59:39 -03:00
Peter W
87b150d539 Update build-alpha.yml 2022-05-19 12:16:41 -05:00
ic-768
508a7d8605 Add labels for pyrepl component (#322)
* Add labels for pyrepl component

* Add id to editor box instead of main div

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-19 09:23:08 -05:00
Fabio Pliger
9119939c3d add components description in getting started (#417)
* add missing tags in getting started

* add py-config tag to getting started

* Edits to Fabio's tags/definitions

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update getting-started.md

Co-authored-by: Idan <ienglander@anaconda.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: idanenglander <60263976+idanenglander@users.noreply.github.com>
2022-05-18 16:47:56 -05:00
cleonard
59fc667651 Basic tests (#355)
* Added microsoft channel and playwright as dependency

* Added test-setup to run

* Basic tests for each example in examples/index.html

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_webgl_raycaster_index.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_folium.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_folium.py

* Update test_folium.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_bokeh.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Whitelisting assertion statements in test files

* Updated bare execept statements with ImportError

* Flake8 compliance

* Updated  message

* Removed 'make test-setup'

* Removed @echo from make test

* Uncommented Toga test

* Removed __test_all__.py file

* Removing unnecessary files

* Removed individual test files

* conftest.py with all data for running tests

* Consolidated test file

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixed pre-commit flake8 issues

* flake8 issue

* add playwright installation to setup

* Testing parameterization and webserver to serve examples locally

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Flake8 compliance

* More flake8

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Michael Verhulst <michael@terminallabs.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-18 13:08:15 -05:00
idanenglander
0d946f853f Embedding video, adding PS tag definitions (#403)
* Embedding video, adding PS tag definitions

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* html -> HTML; add sphinxcontrib.youtube to env.yml

* change place of sphinxcontrib.youtube in env.yml

* one more sphinxcontrib-youtube change

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-18 09:03:46 -05:00
Jeff Glass
b767a78b05 Provide Visible Error if <py-env> paths is used in a local HTML file (#311)
* Add onscreen error when using py-env paths in local HTTP files without file server

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove redundant code, fix error handling, add 404 error

* Lint and Format

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* manage errors loading files

* use handleFetchError for handling fetch errors in env

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-17 23:48:02 -05:00
woxtu
39774a83c5 Use a recommended method (#363) 2022-05-17 22:24:33 -05:00
marianoweber
c04015899b fixed REPL bugs (#372)
* fixed REPL play button alignment

* fixed REPL auto-generate

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* changed nextExecId selector

* added removeClasses to utils.ts

* fixed visual bug after error output

* changed play button alignment

Co-authored-by: Mariano Weber <info@uiremotely.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-17 16:20:00 -05:00
Jannis Leidel
6898daf0ce Documentation infrastructure. (#262)
* Initial setup.

This does a few things:

- Adds some placeholders following the Diátaxis framework (https://diataxis.fr)
- Sets up Sphinx with MyST parser for Markdown in addition to rST.
- Uses the well-known PyData Sphinx theme.
- Moves some already existing Markdown files into the docs directory.
- Sets up the initial doc review GitHub action to auto-deploy to GitHub pages.

* Activate conda env.

* Remove custom action.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Make the dir.

* Push directly

* Add readthedocs config.

* Disable GitHub pages deployment for now.

* Add release and latest workflows as well.

* Make clear that this is work in progress.

* Made docs merge ready, added What is PyScript section with example.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Replace `on:tags:` with `on:create:`

The existing trigger is apparently not in the GHA spec

* Pretty format YAML

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add s3 sync and permissions

* Leave status message in PR.

* Redirect from docs.pyscript.net/ to docs.pyscript.net/latest/

* Delete latest directory before deployment.

* Update review and release workflows, too.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Allow access to S3 for review and release doc workflow.

* Fix name of workflow.

* Bump up Python version.

* Because YAML.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Revert move to 3.10.

* Fix sitemap.

* Remove status settgin from release and latest build.

* Comment out cleanup.

* Add write permissions for statuses.

* More permissions?

* Fix artifact name.

* Use appropriate concurrency.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* .zip not needed

* Align name of workflows with CI workflows.

* Add checks permission.

* Set a notice instead.

* Move to sphinx-design.

* Add sphinx-autobuild.

* Use frontmatter more.

* Add section for mdformat but disable it for now.

See https://github.com/executablebooks/mdformat-myst/pull/9 for more details.

* Fix fencing.

* Actually using html renderer.

* Revert moving governance files.

* Use full URLs for governance docs.

* Added warning.

* Fix copyright and author.

* Another minor fix.

* Use GitHub Action summary instead of notice.

* Fix variable name.

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
Co-authored-by: ximena9201 <ximenandrea.ro@gmail.com>
2022-05-17 12:08:06 -05:00
hoge1e3
eb3a31a698 fixed the bug std-err attribute cannot set stderr properly (#371) 2022-05-16 21:30:57 -05:00
Fabio Pliger
0476627f34 fix autogenerated element (#397)
* use static string in checkId to simplify behaviour and ensure ids always start with alpha char

* re-enable terser on minify

* fix example local path
2022-05-16 16:08:28 -05:00
Yannick Funk
eba42ad9b4 Add checkId() for PyButton and PyInputBox, add id check for tags with pys- Event handlers (#400)
* Add id generation to PyButton and PyInputBox components

* Refactor init handlers and add check for id
2022-05-16 16:05:11 -05:00
Javadz
ca909b4f6b Create readme.md (#374) 2022-05-16 11:13:39 -05:00
369 changed files with 23274 additions and 15268 deletions

63
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: Bug Report
description: Create a report to help us improve
labels: ["type: bug", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for helping PyScript! 🐍
Going through bugs and issues takes up a lot of time, so please be so kind and take a few minutes to fill out all the areas to the best of your ability.
There will always be more issues than there is time to do them, and so we will need to selectively close issues that don't provide enough information, so we can focus our time on helping people like you who fill out the issue form completely. Thank you for your collaboration!
There are also already a lot of open issues, so please take 2 minutes and search through existing ones to see if what you are experiencing already exists
Thanks for helping PyScript be amazing. We are nothing without people like you helping build a better community 💐!
- type: checkboxes
id: checks
attributes:
label: Checklist
description: Please confirm and check all the following options.
options:
- label: I added a descriptive title
required: true
- label: I searched for other issues and couldn't find a solution or duplication
required: true
- label: I already searched in Google and didn't find any good information or help
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: And what should have happened instead? This really helps everyone review quicker and greatly increases the chance that someone can get around to solve your issue
placeholder: Tell us what you see!
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: What browsers are you seeing the problem on? (if applicable)
multiple: true
options:
- Firefox
- Chrome
- Safari
- Microsoft Edge
- Other
validations:
required: false
- type: textarea
id: list
attributes:
label: Console info
description: |
If there are errors in your browser console then its helpful to be able to troubleshoot.
- Chrome , Firefox, and Edge: Right-click on the page and select *Inspect*. Alternatively you can press F12 on your keyboard.
- Safari: Find instructions [here](https://support.apple.com/guide/safari/use-the-developer-tools-in-the-develop-menu-sfri20948/mac).
render: shell
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any additional context information or screenshots you think are useful.

View File

@@ -1,23 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: needs-triage
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior: either a code snippet or a link to an HTML page which shows the bug.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Feature Proposals
url: https://github.com/pyscript/pyscript/discussions/new?category=proposals
about: Create a feature request to make PyScript even better
- name: Questions
url: https://github.com/pyscript/pyscript/discussions/new?category=q-a
about: For questions or discussions about pyscript

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
labels: needs-triage
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. As a user, I'd like to [...]
**Describe the solution you'd like**
A clear and concise description of what you expect to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

15
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,15 @@
## Description
<!--Please describe the changes in your pull request in few words here. -->
## Changes
<!-- List the changes done to fix a bug or introduce a new feature.Please note both user-facing changes and changes to internal API's here -->
## Checklist
<!-- Note: Only user-facing changes require a changelog entry. Internal-only API changes do not require a changelog entry. Changes in documentation do not require a changelog entry. -->
- [ ] All tests pass locally
- [ ] I have updated `CHANGELOG.md`
- [ ] I have created documentation for this(if applicable)

5
.github/release.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
changelog:
categories:
- title: New Features
- title: Breaking Changes
- title: Known Issues

View File

@@ -1,56 +0,0 @@
name: '[CI] Build Alpha'
on:
push:
branches:
- main
tags:
- '**' # Currently any tag, need to slim down
paths:
- pyscriptjs/**
- .github/workflows/build-alpha.yml # Test that workflow works when changed
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: pyscriptjs
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install dependencies
run: |
npm install
- name: Build pyscript
run: |
npm run build
# Deploy to S3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{secrets.AWS_REGION}}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
run: aws s3 sync --quiet ./examples/build/ s3://pyscript.net/alpha/

View File

@@ -1,63 +0,0 @@
name: '[CI] Build Latest'
on:
push: # Only run on merges into main that modify files under pyscriptjs/
branches:
- main
paths:
- pyscriptjs/**
- .github/workflows/build-latest.yml # Test that workflow works when changed
pull_request: # Run on any PR that modifies files in pyscriptjs/
branches:
- main
paths:
- pyscriptjs/**
- .github/workflows/build-latest.yml # Test that workflow works when changed
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: pyscriptjs
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install dependencies
run: |
npm install
- name: Build pyscript
run: |
npm run build
# Deploy to S3
- name: Configure AWS credentials
if: github.ref == 'refs/heads/main' # Only deploy on merge into main
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{secrets.AWS_REGION}}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
if: github.ref == 'refs/heads/main'
run: aws s3 sync --quiet ./examples/build/ s3://pyscript.net/unstable

56
.github/workflows/prepare-release.yml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: "Prepare Release"
on:
push:
tags:
- "[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9]+" # YYYY.MM.MICRO
defaults:
run:
working-directory: ./pyscript.core
jobs:
prepare-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: NPM Install
run: npm install && npx playwright install
- name: Build
run: npm run build
- name: Generate index.html
working-directory: .
run: sed 's#_PATH_#./#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Zip dist folder
run: zip -r -q ./build.zip ./dist
- name: Prepare Release
uses: softprops/action-gh-release@v1
with:
draft: true
prerelease: true
generate_release_notes: true
files: ./build.zip

59
.github/workflows/publish-release.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: "Publish Release"
on:
release:
types: [published]
defaults:
run:
working-directory: ./pyscript.core
jobs:
publish-release:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: npm install
run: npm install && npx playwright install
- name: build
run: npm run build
- name: Generate index.html in snapshot
working-directory: .
run: sed 's#_PATH_#https://pyscript.net/releases/${{ github.ref_name }}/#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
run:
| # Update /latest and create an explicitly versioned directory under releases/YYYY.MM.MICRO/
aws s3 sync --quiet ./dist/ s3://pyscript.net/latest/
aws s3 sync --quiet ./dist/ s3://pyscript.net/releases/${{ github.ref_name }}/

61
.github/workflows/publish-snapshot.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: "Publish Snapshot"
on:
workflow_dispatch:
inputs:
snapshot_version:
description: "The calver version of this snapshot: 2022.09.1 or 2022.09.1.RC1"
type: string
required: true
defaults:
run:
working-directory: ./pyscript.core
jobs:
publish-snapshot:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Install Dependencies
run: npm install && npx playwright install
- name: Build Pyscript.core
run: npm run build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Generate index.html in snapshot
working-directory: .
run: sed 's#_PATH_#https://pyscript.net/snapshots/${{ inputs.snapshot_version }}/#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Copy to Snapshot
run: >
aws s3 sync ./dist/ s3://pyscript.net/snapshots/${{ inputs.snapshot_version }}/

61
.github/workflows/publish-unstable.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: "Publish Unstable"
on:
push: # Only run on merges into main that modify files under pyscript.core/ and examples/
branches:
- main
paths:
- pyscript.core/**
- examples/**
workflow_dispatch:
jobs:
publish-unstable:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
defaults:
run:
working-directory: ./pyscript.core
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: NPM Install
run: npm install && npx playwright install
- name: Build
run: npm run build
- name: Generate index.html in snapshot
working-directory: .
run: sed 's#_PATH_#https://pyscript.net/unstable/#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
run: aws s3 sync --quiet ./dist/ s3://pyscript.net/unstable/

View File

@@ -1,33 +0,0 @@
name: '[CI] Sync Examples'
on:
push: # Only run on merges into main that modify files under pyscriptjs/examples/
branches:
- main
paths:
- pyscriptjs/examples/**
- .github/workflows/sync-examples.yml # Test that workflow works when changed
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: pyscriptjs/examples
steps:
# Deploy to S3
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{secrets.AWS_REGION}}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
# Sync outdated or new files, delete ones no longer in source
run: aws s3 sync --quiet --delete . s3://pyscript.net/examples/ # Sync directory, delete what is not in source

92
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,92 @@
name: "[CI] Test"
on:
push: # Only run on merges into main that modify certain files
branches:
- main
paths:
- pyscript.core/**
- .github/workflows/test.yml
pull_request: # Only run on merges into main that modify certain files
branches:
- main
paths:
- pyscript.core/**
- .github/workflows/test.yml
workflow_dispatch:
jobs:
BuildAndTest:
runs-on: ubuntu-latest-8core
env:
MINICONDA_PYTHON_VERSION: py38
MINICONDA_VERSION: 4.11.0
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 3
# display a git log: when you run CI on PRs, github automatically
# merges the PR into main and run the CI on that commit. The idea
# here is to show enough of git log to understand what is the
# actual commit (in the PR) that we are using. See also
# 'fetch-depth: 3' above.
- name: git log
run: git log --graph -3
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 20.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: setup Miniconda
uses: conda-incubator/setup-miniconda@v2
- name: Create and activate virtual environment
run: |
python3 -m venv test_venv
source test_venv/bin/activate
echo PATH=$PATH >> $GITHUB_ENV
echo VIRTUAL_ENV=$VIRTUAL_ENV >> $GITHUB_ENV
- name: Setup dependencies in virtual environment
run: |
make setup
- name: Build
run: make build
- name: Integration Tests
#run: make test-integration-parallel
run: |
make test-integration
- uses: actions/upload-artifact@v3
with:
name: pyscript
path: |
pyscript.core/dist/
if-no-files-found: error
retention-days: 7
- uses: actions/upload-artifact@v3
if: success() || failure()
with:
name: test_results
path: test_results/
if-no-files-found: error

16
.github/workflows/test_report.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Test Report
on:
workflow_run:
workflows: ['\[CI\] Test']
types:
- completed
jobs:
report:
runs-on: ubuntu-latest-8core
steps:
- uses: dorny/test-reporter@v1.6.0
with:
artifact: test_results
name: Test reports
path: "*.xml"
reporter: java-junit

15
.gitignore vendored
View File

@@ -71,6 +71,7 @@ instance/
# Sphinx documentation
docs/_build/
docs/_env/
# PyBuilder
target/
@@ -134,3 +135,17 @@ dmypy.json
.pyre/
node_modules/
coverage/
# junit xml for test results
test_results
# @pyscript/core npm artifacts
pyscript.core/core.*
pyscript.core/dist
pyscript.core/dist.zip
pyscript.core/src/plugins.js
pyscript.core/src/stdlib/pyscript.js
pyscript.core/src/3rd-party/*
!pyscript.core/src/3rd-party/READMEmd

View File

@@ -1,77 +1,53 @@
# This is the configuration for pre-commit, a local framework for managing pre-commit hooks
# Check out the docs at: https://pre-commit.com/
ci:
#skip: [eslint]
autoupdate_schedule: monthly
default_stages: [commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-json
exclude: tsconfig.json
exclude: tsconfig\.json
- id: check-toml
exclude: bad\.toml
- id: check-xml
- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
exclude: \.min\.js$
exclude: pyscript\.core/dist|\.min\.js$
- id: trailing-whitespace
- repo: https://github.com/PyCQA/bandit
rev: 1.7.4
hooks:
- id: bandit
args:
- --skip=B201
- repo: https://github.com/psf/black
rev: 22.3.0
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
exclude: pyscript\.core/src/stdlib/pyscript/__init__\.py
- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
hooks:
- id: codespell # See 'setup.cfg' for args
- id: codespell # See 'pyproject.toml' for args
exclude: \.js\.map$
additional_dependencies:
- tomli
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
- repo: https://github.com/hoodmane/pyscript-prettier-precommit
rev: "v3.0.0-alpha.6"
hooks:
- id: flake8 # See 'setup.cfg' for args
additional_dependencies: [flake8-bugbear, flake8-comprehensions]
- id: prettier
exclude: pyscript\.core/test|pyscript\.core/dist|pyscript\.core/types|pyscript.core/src/stdlib/pyscript.js|pyscript\.sw/|pyscript.core/src/3rd-party
args: [--tab-width, "4"]
- repo: https://github.com/pycqa/isort
rev: 5.10.1
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
name: isort (python)
args: [--profile, black]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.3.0
hooks:
- id: pretty-format-yaml
args: [--autofix, --indent, '4']
- repo: https://github.com/asottile/pyupgrade
rev: v2.32.1
hooks:
- id: pyupgrade
args:
- --py310-plus
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.15.0
hooks:
- id: eslint
files: pyscriptjs/src/.*\.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
types: [file]
additional_dependencies:
- eslint
- eslint-plugin-svelte3
- typescript
- '@typescript-eslint/eslint-plugin'
- '@typescript-eslint/parser'

5
.prettierignore Normal file
View File

@@ -0,0 +1,5 @@
ISSUE_TEMPLATE
*.min.*
package-lock.json
docs
examples/panel.html

28
.readthedocs.yml Normal file
View File

@@ -0,0 +1,28 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: miniconda3-4.7
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
conda:
environment: docs/environment.yml
# If using Sphinx, optionally build your docs in additional formats such as PDF
# formats:
# - pdf
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt

87
CHANGELOG.md Normal file
View File

@@ -0,0 +1,87 @@
# Release Notes
## 2023.05.01
### Features
- Added the `xterm` attribute to `py-config`. When set to `True` or `xterm`, an (output-only) [xterm.js](http://xtermjs.org/) terminal will be used in place of the default py-terminal.
- The default version of Pyodide is now `0.23.2`. See the [Pyodide Changelog](https://pyodide.org/en/stable/project/changelog.html#version-0-23-2) for a detailed list of changes.
- Added the `@when` decorator for attaching Python functions as event handlers
- The `py-mount` attribute on HTML elements has been deprecated, and will be removed in a future release.
#### Runtime py- attributes
- Added logic to react to `py-*` attributes changes, removal, `py-*` attributes added to already live nodes but also `py-*` attributes added or defined via injected nodes (either appended or via `innerHTML` operations). ([#1435](https://github.com/pyscript/pyscript/pull/1435))
#### &lt;script type="py"&gt;
- Added the ability to optionally use `<script type="py">`, `<script type="pyscript">` or `<script type="py-script">` instead of a `<py-script>` custom element, in order to tackle cases where the content of the `<py-script>` tag, inevitably parsed by browsers, could accidentally contain _HTML_ able to break the surrounding page layout. ([#1396](https://github.com/pyscript/pyscript/pull/1396))
#### &lt;py-terminal&gt;
- Added a `docked` field and attribute for the `<py-terminal>` custom element, enabled by default when the terminal is in `auto` mode, and able to dock the terminal at the bottom of the page with auto scroll on new code execution.
#### &lt;py-script&gt;
- Restored the `output` attribute of `py-script` tags to route `sys.stdout` to a DOM element with the given ID. ([#1063](https://github.com/pyscript/pyscript/pull/1063))
- Added a `stderr` attribute of `py-script` tags to route `sys.stderr` to a DOM element with the given ID. ([#1063](https://github.com/pyscript/pyscript/pull/1063))
#### &lt;py-repl&gt;
- The `output` attribute of `py-repl` tags now specifies the id of the DOM element that `sys.stdout`, `sys.stderr`, and the results of a REPL execution are written to. It no longer affects the location of calls to `display()`
- Added a `stderr` attribute of `py-repl` tags to route `sys.stderr` to a DOM element with the given ID. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
- Resored the `output-mode` attribute of `py-repl` tags. If `output-mode` == 'append', the DOM element where output is printed is _not_ cleared before writing new results.
- Load code from the attribute src of py-repl and preload it into the corresponding py-repl tag by use the attribute `str` in your `py-repl` tag([#1292](https://github.com/pyscript/pyscript/pull/1292))
- &lt;py-repl&gt; elements now have a `getPySrc()` method, which returns the code inside the REPL as a string.([#1516](https://github.com/pyscript/pyscript/pull/1292))
#### Plugins
- Plugins may now implement the `beforePyReplExec()` and `afterPyReplExec()` hooks, which are called immediately before and after code in a `py-repl` tag is executed. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
#### Web worker support
- introduced the new experimental `execution_thread` config option: if you set `execution_thread = "worker"`, the python interpreter runs inside a web worker
- worker support is still **very** experimental: not everything works, use it at your own risk
### Bug fixes
- Fixes [#1280](https://github.com/pyscript/pyscript/issues/1280), which describes the errors on the PyRepl tests related to having auto-gen tags that shouldn't be there.
### Enhancements
- Py-REPL tests now run on both osx and non osx OSs
- migrated from _rollup_ to _esbuild_ to create artifacts
- updated `@codemirror` dependency to its latest
### Docs
- Add docs for event handlers
## 2023.03.1
### Features
### Bug fixes
- Fixed an issue where `pyscript` would not be available when using the minified version of PyScript. ([#1054](https://github.com/pyscript/pyscript/pull/1054))
- Fixed missing closing tag when rendering an image with `display`. ([#1058](https://github.com/pyscript/pyscript/pull/1058))
- Fixed a bug where Python plugins methods were being executed twice. ([#1064](https://github.com/pyscript/pyscript/pull/1064))
### Enhancements
- When adding a `py-` attribute to an element but didn't added an `id` attribute, PyScript will now generate a random ID for the element instead of throwing an error which caused the splash screen to not shutdown. ([#1122](https://github.com/pyscript/pyscript/pull/1122))
- You can now disable the splashscreen by setting `enabled = false` in your `py-config` under the `[splashscreen]` configuration section. ([#1138](https://github.com/pyscript/pyscript/pull/1138))
### Documentation
- Fixed 'Direct usage of document is deprecated' warning in the getting started guide. ([#1052](https://github.com/pyscript/pyscript/pull/1052))
- Added reference documentation for the `py-splashscreen` plugin ([#1138](https://github.com/pyscript/pyscript/pull/1138))
- Adds doc for installing tests ([#1156](https://github.com/pyscript/pyscript/pull/1156))
- Adds docs for custom Pyscript attributes (`py-*`) that allow you to add event listeners to an element ([#1125](https://github.com/pyscript/pyscript/pull/1125))
### Deprecations and Removals
- The py-config `runtimes` to specify an interpreter has been deprecated. The `interpreters` config should be used instead. ([#1082](https://github.com/pyscript/pyscript/pull/1082))
- The attributes `pys-onClick` and `pys-onKeyDown` have been deprecated, but the warning was only shown in the console. An alert banner will now be shown on the page if the attributes are used. They will be removed in the next release. ([#1084](https://github.com/pyscript/pyscript/pull/1084))
- The pyscript elements `py-button`, `py-inputbox`, `py-box` and `py-title` have now completed their deprecation cycle and have been removed. ([#1084](https://github.com/pyscript/pyscript/pull/1084))
- The attributes `pys-onClick` and `pys-onKeyDown` have been removed. Use `py-click` and `py-keydown` instead ([#1361](https://github.com/pyscript/pyscript/pull/1361))

View File

@@ -1,4 +1,4 @@
# Code of Conduct
The Code of Conduct is available in the pyscript Governance repo.
The Code of Conduct is available in the PyScript Governance repo.
See https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md

View File

@@ -4,81 +4,64 @@ Thank you for wanting to contribute to the PyScript project!
## Table of contents
* [Code of Conduct](#code-of-conduct)
* [Contributing](#contributing)
* [Reporting bugs](#reporting-bugs)
* [Reporting security issues](#reporting-security-issues)
* [Asking questions](#asking-questions)
* [Setting up your environment](#setting-up-your-environment)
* [Places to start](#places-to-start)
* [Submitting a change](#submitting-a-change)
* [License terms for contributions](#license-terms-for-contributions)
* [Becoming a maintainer](#becoming-a-maintainer)
* [Trademarks](#trademarks)
- [Contributing to PyScript](#contributing-to-pyscript)
- [Table of contents](#table-of-contents)
- [Code of Conduct](#code-of-conduct)
- [Contributing](#contributing)
- [Reporting bugs](#reporting-bugs)
- [Creating useful issues](#creating-useful-issues)
- [Reporting security issues](#reporting-security-issues)
- [Asking questions](#asking-questions)
- [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
- [Developing](#developing)
- [Rebasing changes](#rebasing-changes)
- [Building the docs](#building-the-docs)
- [Places to start](#places-to-start)
- [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
- [Submitting a change](#submitting-a-change)
- [License terms for contributions](#license-terms-for-contributions)
- [Becoming a maintainer](#becoming-a-maintainer)
- [Trademarks](#trademarks)
## Code of Conduct
# Code of Conduct
The [PyScript Code of Conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md) governs the project and everyone participating in it. By participating, you are expected to uphold this code. Please report unacceptable behavior to the maintainers or administrators as described in that document.
## Contributing
# Contributing
### Reporting bugs
## Reporting bugs
Bugs are tracked on the [project issues page](https://github.com/pyscript/pyscript/issues). Please check if your issue has already been filed by someone else by searching the existing issues before filing a new one. Once your issue is filed, it will be triaged by another contributor or maintainer. If there are questions raised about your issue, please respond promptly.
#### Creating useful issues
## Creating useful issues
* Use a clear and descriptive title.
* Describe the specific steps that reproduce the problem with as many details as possible so that someone can verify the issue.
* Describe the behavior you observed, and the behavior you had expected.
* Include screenshots if they help make the issue clear.
- Use a clear and descriptive title.
- Describe the specific steps that reproduce the problem with as many details as possible so that someone can verify the issue.
- Describe the behavior you observed, and the behavior you had expected.
- Include screenshots if they help make the issue clear.
### Reporting security issues
## Reporting security issues
If you aren't confident that it is appropriate to submit a security issue using the above process, you can e-mail it to security@pyscript.net
### Asking questions
## Asking questions
If you have questions about the project, using PyScript, or anything else, please ask in the [PyScript forum](https://community.anaconda.cloud/c/tech-topics/pyscript).
### Setting up your environment
## Places to start
* clone the repo
```
git clone https://github.com/pyscript/pyscript
```
* cd into the main project folder
```
cd pyscript/pyscriptjs
```
* install the dependencies with npm install - make sure to use nodejs version >= 16
```
npm install
```
* run npm run dev to build and run the dev server. This will also watch for changes and rebuild when a file is saved.
```
npm run dev
```
If you would like to contribute to PyScript, but you aren't sure where to begin, here are some suggestions:
### Places to start
- **Read over the existing documentation.** Are there things missing, or could they be clearer? Make some changes/additions to those documents.
- **Review the open issues.** Are they clear? Can you reproduce them? You can add comments, clarifications, or additions to those issues. If you think you have an idea of how to address the issue, submit a fix!
- **Look over the open pull requests.** Do you have comments or suggestions for the proposed changes? Add them.
- **Check out the examples.** Is there a use case that would be good to have sample code for? Create an example for it.
If you would like to contribute to PyScript, but you aren't sure where to begin, here are some suggestions.
## Setting up your local environment and developing
* **Read over the existing documentation.** Are there things missing, or could they be clearer? Make some changes/additions to those documents.
* **Review the open issues.** Are they clear? Can you reproduce them? You can add comments, clarifications, or additions to those issues. If you think you have an idea of how to address the issue, submit a fix!
* **Look over the open pull requests.** Do you have comments or suggestions for the proposed changes? Add them.
* **Check out the examples.** Is there a use case that would be good to have sample code for? Create an example for it.
If you would like to contribute to PyScript, you will need to set up a local development environment. The [following instructions](https://docs.pyscript.net/latest/development/setting-up-environment.html) will help you get started.
### Submitting a change
All contributions must be licensed Apache 2.0, and all files must have a copy of the boilerplate license comment (can be copied from an existing file).
To create a change for PyScript, you can follow the process described [here](https://docs.github.com/en/get-started/quickstart/contributing-to-projects).
* Fork a personal copy of the PyScript project.
* Make the changes you would like (don't forget to test them!)
* Please squash all commits for a change into a single commit (this can be done using "git rebase -i"). Do your best to have a well-formed commit message for the change.
* Open a pull request back to the PyScript project and address any comments/questions from the maintainers and other contributors.
You can also read about PyScript's [development process](https://docs.pyscript.net/latest/development/developing.html) to learn how to contribute code to PyScript, how to run tests and what's the PR etiquette of the community!
## License terms for contributions
@@ -86,12 +69,13 @@ This Project welcomes contributions, suggestions, and feedback. All contribution
## Becoming a maintainer
Contributors are invited to be maintainers to the project by demonstrating good decision making in their contributions, a commitment to the goals of the project, and consistent adherence to the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md). New maintainers are invited by a 3/4 vote of the existing maintainers.
Contributors are invited to be maintainers of the project by demonstrating good decision making in their contributions, a commitment to the goals of the project, and consistent adherence to the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md). New maintainers are invited by a 3/4 vote of the existing maintainers.
## Trademarks
The Project abides by the Organization's [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md).
---
Part of MVG-0.1-beta.
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).

View File

@@ -1,210 +0,0 @@
# Getting started with PyScript
This page will guide you through getting started with PyScript.
## Development setup
PyScript does not require any development environment other
than a web browser. We recommend using [Chrome](https://www.google.com/chrome/).
If you're using [VSCode](https://code.visualstudio.com/), the
[Live Server extension](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)
can be used to reload the page as you edit the HTML file.
## Installation
There is no installation required. In this document we'll use
the PyScript assets served on https://pyscript.net.
If you want to download the source and build it yourself, follow
the instructions in the README.md file.
## Your first PyScript HTML file
Here's a "Hello, world!" example using PyScript.
Using your favorite editor create a new file called `hello.html` in
the same directory as your PyScript, JavaScript, and CSS files with the
following content, and open the file in your web browser. You can typically
open an HTML by double clicking it in your file explorer.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body> <py-script> print('Hello, World!') </py-script> </body>
</html>
```
Notice the use of the `<py-script>` tag in the HTML body. This
is where you'll write your Python code. In the following sections we'll
introduce the 8 tags provided by PyScript.
## The py-script tag
The `<py-script>` tag lets you execute multi-line Python scripts and
print back onto the page. For
example, we can compute π.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<py-script>
print("Let's compute π:")
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
s = f"π is approximately {pi:.3f}"
print(s)
</py-script>
</body>
</html>
```
### Writing into labeled elements
In the example above we had a single `<py-script>` tag and it printed
one or more lines onto the page in order. Within the `<py-script>` you
have access to the `pyscript` module, which provides a `.write()` method
to send strings into labeled elements on the page.
For example we'll add some style elements and provide place holders for
the `<py-script>` tag write to.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<b><p>Today is <u><label id='today'></label></u></p></b>
<br>
<div id="pi" class="alert alert-primary"></div>
<py-script>
import datetime as dt
pyscript.write('today', dt.date.today().strftime('%A %B %d, %Y'))
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
pyscript.write('pi', f'π is approximately {pi:.3f}')
</py-script>
</body>
</html>
```
## Packages and modules
In addition to the [Python Standard Library](https://docs.python.org/3/library/) and
the `pyscript` module, many 3rd-party OSS packages will work out-of-the-box with PyScript.
In order to use them you will need to declare the dependencies using the `<py-env>` in the
HTML head. You can also link to `.whl` files directly on disk like in our [toga example](https://github.com/pyscript/pyscript/blob/main/pyscriptjs/examples/toga/freedom.html)
```
<py-env>
- './static/wheels/travertino-0.1.3-py3-none-any.whl'
</py-env>
```
If your `.whl` is not a pure Python wheel, then open a PR or issue with [pyodide](https://github.com/pyodide/pyodide) to get it added [here](https://github.com/pyodide/pyodide/tree/main/packages).
If there's enough popular demand the pyodide team will likely work on supporting your package, regardless things will likely move faster if you make the PR and consult with the team to get unblocked.
For example, NumPy and Matplotlib are available. Notice here we're using `<py-script output="plot">`
as a shortcut, which takes the expression on the last line of the script and runs `pyscript.write('plot', fig)`.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- numpy
- matplotlib
</py-env>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-script output="plot">
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
fig
</py-script>
</body>
</html>
```
### Local modules
In addition to packages you can declare local Python modules that will
be imported in the `<py-script>` tag. For example, we can place the random
number generation steps in a function in the file `data.py`.
```python
# data.py
import numpy as np
def make_x_and_y(n):
x = np.random.randn(n)
y = np.random.randn(n)
return x, y
```
In the HTML tag `<py-env>` paths to local modules are provided in the
`paths:` key.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- numpy
- matplotlib
- paths:
- /data.py
</py-env>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-script output="plot">
import matplotlib.pyplot as plt
from data import make_x_and_y
x, y = make_x_and_y(n=1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
fig
</py-script>
</body>
</html>
```

View File

@@ -1,6 +1,6 @@
# Governance Policy
This document provides the governance policy for the Project. Maintainers agree to this policy and to abide by all Project polices, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/ANTITRUST.md) by adding their name to the [maintainers.md file](./MAINTAINERS.md).
This document provides the governance policy for the Project. Maintainers agree to this policy and to abide by all Project policies, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/ANTITRUST.md) by adding their name to the [maintainers.md file](https://github.com/pyscript/pyscript/blob/main/MAINTAINERS.md).
## 1. Roles.
@@ -41,5 +41,6 @@ Any names, trademarks, logos, or goodwill developed by and associated with the P
Amendments to this governance policy may be made by affirmative vote of 2/3 of all Maintainers, with approval by the Organization's Steering Committee.
---
Part of MVG-0.1-beta.
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).

View File

@@ -1,17 +1,24 @@
# Maintainers
This document lists the Maintainers of the Project. Maintainers may be added once approved by the existing maintainers as described in the [Governance document](./GOVERNANCE.md). By adding your name to this list you are agreeing to abide by the Project governance documents and to abide by all of the Organization's polices, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md). If you are participating because of your affiliation with another organization (designated below), you represent that you have the authority to bind that organization to these policies.
This document lists the Maintainers of the Project. Maintainers may be added once approved by the existing maintainers as described in the [Governance document](https://github.com/pyscript/pyscript/blob/main/GOVERNANCE.md). By adding your name to this list you are agreeing to abide by the Project governance documents and to abide by all of the Organization's polices, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md). If you are participating because of your affiliation with another organization (designated below), you represent that you have the authority to bind that organization to these policies.
| **NAME** | **Organization** |
| --- | --- |
| -------------------- | ---------------- |
| Fabio Pliger | Anaconda, Inc |
| Antonio Cuni | Anaconda, Inc |
| Philipp Rudiger | Anaconda, Inc |
| Peter Wang | Anaconda, Inc |
| Kevin Goldsmith | Anaconda, Inc |
| Mariana Meireles | Anaconda, Inc |
| --- | --- |
| Mariana Meireles | |
| Nicholas H.Tollervey | Anaconda, Inc |
| Madhur Tandon | Anaconda, Inc |
| Ted Patrick | Anaconda, Inc |
| Jeff Glass | |
| Paul Everitt | |
| Fabio Rosado | Anaconda, Inc |
| Andrea Giammarchi | Anaconda, Inc |
---
Part of MVG-0.1-beta.
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).

92
Makefile Normal file
View File

@@ -0,0 +1,92 @@
MIN_NODE_VER := 20
MIN_NPM_VER := 6
MIN_PY3_VER := 8
NODE_VER := $(shell node -v | cut -d. -f1 | sed 's/^v\(.*\)/\1/')
NPM_VER := $(shell npm -v | cut -d. -f1)
PY3_VER := $(shell python3 -c "import sys;t='{v[1]}'.format(v=list(sys.version_info[:2]));print(t)")
PY_OK := $(shell python3 -c "print(int($(PY3_VER) >= $(MIN_PY3_VER)))")
all:
@echo "\nThere is no default Makefile target right now. Try:\n"
@echo "make setup - check your environment and install the dependencies."
@echo "make clean - clean up auto-generated assets."
@echo "make build - build PyScript."
@echo "make precommit-check - run the precommit checks (run eslint)."
@echo "make test-integration - run all integration tests sequentially."
@echo "make fmt - format the code."
@echo "make fmt-check - check the code formatting.\n"
.PHONY: check-node
check-node:
@if [ $(NODE_VER) -lt $(MIN_NODE_VER) ]; then \
echo "\033[0;31mBuild requires Node $(MIN_NODE_VER).x or higher: $(NODE_VER) detected.\033[0m"; \
false; \
fi
.PHONY: check-npm
check-npm:
@if [ $(NPM_VER) -lt $(MIN_NPM_VER) ]; then \
echo "\033[0;31mBuild requires Node $(MIN_NPM_VER).x or higher: $(NPM_VER) detected.\033[0m"; \
false; \
fi
.PHONY: check-python
check-python:
@if [ $(PY_OK) -eq 0 ]; then \
echo "\033[0;31mRequires Python 3.$(MIN_PY3_VER).x or higher: 3.$(PY3_VER) detected.\033[0m"; \
false; \
fi
# Check the environment, install the dependencies.
setup: check-node check-npm check-python
cd pyscript.core && npm install && cd ..
ifeq ($(VIRTUAL_ENV),)
echo "\n\n\033[0;31mCannot install Python dependencies. Your virtualenv is not activated.\033[0m"
false
else
python -m pip install -r requirements.txt
playwright install
endif
# Clean up generated assets.
clean:
find . -name \*.py[cod] -delete
rm -rf $(env) *.egg-info
rm -rf .pytest_cache .coverage coverage.xml
# Build PyScript.
build:
cd pyscript.core && npx playwright install && npm run build
# Run the precommit checks (run eslint).
precommit-check:
pre-commit run --all-files
# Run all integration tests sequentially.
test-integration:
mkdir -p test_results
pytest -vv $(ARGS) pyscript.core/tests/integration/ --log-cli-level=warning --junitxml=test_results/integration.xml
# Run all integration tests in parallel.
test-integration-parallel:
mkdir -p test_results
pytest --numprocesses auto -vv $(ARGS) pyscript.core/tests/integration/ --log-cli-level=warning --junitxml=test_results/integration.xml
# Format the code.
fmt: fmt-py
@echo "Format completed"
# Check the code formatting.
fmt-check: fmt-py-check
@echo "Format check completed"
# Format Python code.
fmt-py:
black -l 88 --skip-string-normalization .
isort --profile black .
# Check the format of Python code.
fmt-py-check:
black -l 88 --check .
.PHONY: $(MAKECMDGOALS)

View File

@@ -3,43 +3,81 @@
## What is PyScript
### Summary
PyScript is a Pythonic alternative to Scratch, JSFiddle, and other "easy to use" programming frameworks, with the goal of making the web a friendly, hackable place where anyone can author interesting and interactive applications.
To get started see [GETTING-STARTED](GETTING-STARTED.md).
PyScript is a framework that allows users to create rich Python applications in the browser using HTML's interface and the power of [Pyodide](https://pyodide.org/en/stable/), [MicroPython](https://micropython.org/) and [WASM](https://webassembly.org/), and modern web technologies.
For examples see [the pyscript folder](pyscriptjs).
To get started see the [getting started tutorial](https://pyscript.github.io/docs/latest/beginning-pyscript/).
For examples see [here](examples).
### Longer Version
PyScript is a meta project that aims to combine multiple open technologies into a framework that allows users to create sophisticated browser applications with Python. It integrates seamlessly with the way the DOM works in the browser and allows users to add Python logic in a way that feels natural both to web and Python developers.
## Try PyScript
To try PyScript, import the appropriate pyscript files to your html page with:
To try PyScript, import the appropriate pyscript files into the `<head>` tag of your html page:
```html
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<head>
<link
rel="stylesheet"
href="https://pyscript.net/releases/2023.11.1/core.css"
/>
<script
type="module"
src="https://pyscript.net/releases/2023.11.1/core.js"
></script>
</head>
<body>
<script type="py" terminal>
from pyscript import display
display("Hello World!") # this goes to the DOM
print("Hello terminal") # this goes to the terminal
</script>
</body>
```
You can then use PyScript components in your html page. PyScript currently implements the following elements:
* `<py-script>`: can be used to define python code that is executable within the web page. The element itself is not rendered to the page and is only used to add logic
* `<py-repl>`: creates a REPL component that is rendered to the page as a code editor and allows users to write executable code
You can then use PyScript components in your html page. PyScript currently offers various ways of running Python code:
Check out the [pyscriptjs/examples](pyscriptjs/examples) folder for more examples on how to use it, all you need to do is open them in Chrome.
- `<script type="py">`: can be used to define python code that is executable within the web page.
- `<script type="py" src="hello.py">`: same as above, but the python source is fetched from the given URL.
- `<script type="py" terminal>`: same as above, but also creates a terminal where to display stdout and stderr (e.g., the output of `print()`); `input()` does not work.
- `<script type="py" terminal worker>`: run Python inside a web worker: the terminal if fully functional and `input()` works.
- `<py-script>`: same as `<script type="py">`, but it is not recommended because if the code contains HTML tags, they could be parsed wrongly.
- `<script type="mpy">`: same as above but use MicroPython instead of Python.
Check out the [official docs](https://docs.pyscript.net) for more detailed documentation.
## How to Contribute
To contribute see the [CONTRIBUTING](CONTRIBUTING.md) document.
Read the [contributing guide](CONTRIBUTING.md) to learn about our development process, reporting bugs and improvements, creating issues and asking questions.
Check out the [developing process](https://docs.pyscript.net/latest/contributing) documentation for more information on how to setup your development environment.
## Community calls and events
Every Tuesday at 15:30 UTC there is the _PyScript Community Call_ on zoom, where we can talk about PyScript development in the open. Most of the maintainers regularly participate in the call, and everybody is welcome to join.
Every other Thursday at 16:00 UTC there is the _PyScript FUN_ call: this is a call in which everybody is encouraged to show what they did with PyScript.
For more details on how to join the calls and up to date schedule, consult the official calendar:
- [Google calendar](https://calendar.google.com/calendar/u/0/embed?src=d3afdd81f9c132a8c8f3290f5cc5966adebdf61017fca784eef0f6be9fd519e0@group.calendar.google.com&ctz=UTC) in UTC time;
- [iCal format](https://calendar.google.com/calendar/ical/d3afdd81f9c132a8c8f3290f5cc5966adebdf61017fca784eef0f6be9fd519e0%40group.calendar.google.com/public/basic.ics).
## Resources
* [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript)
* [Home Page](https://pyscript.net/)
* [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
- [Official docs](https://docs.pyscript.net)
- [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript)
- [Home Page](https://pyscript.net/)
- [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
- [Discord Channel](https://discord.gg/BYB2kvyFwm)
## Notes
* This is an extremely experimental project, so expect things to break!
* PyScript has been only tested on Chrome at the moment.
- This is an extremely experimental project, so expect things to break!
- PyScript has been only tested on Chrome at the moment.
## Governance

19
TROUBLESHOOTING.md Normal file
View File

@@ -0,0 +1,19 @@
# Troubleshooting
This page is meant for troubleshooting common problems with PyScript.
## Table of contents:
- [Make Setup](#make-setup)
## Make setup
A lot of problems related to `make setup` are related to node and npm being outdated. Once npm and node are updated, `make setup` should work. You can follow the steps on the [npm documentation](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) to update npm (the update command for Linux should work for Mac as well). Once npm has been updated you can continue to the instructions to update node below.
To update Node run the following commands in order (Most likely you'll be prompted for your user password, this is normal):
```
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
```

90
examples/altair.html Normal file
View File

@@ -0,0 +1,90 @@
<html>
<head>
<title>Altair</title>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="./favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<link rel="stylesheet" href="./assets/css/examples.css" />
<style>
py-script {
display: none;
}
</style>
<script
type="module"
src="https://esm.sh/@pyscript/core@latest/core.js"
></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c">Altair</a>
</div>
</nav>
<section class="pyscript">
<div id="altair"></div>
<py-tutor>
<py-config>
packages = [
"altair",
"pandas",
"vega_datasets"
]
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
</py-config>
<py-script>
from pyscript import display
import altair as alt
from vega_datasets import data
source = data.movies.url
pts = alt.selection(type="single", encodings=['x'])
rect = alt.Chart(data.movies.url).mark_rect().encode(
alt.X('IMDB_Rating:Q', bin=True),
alt.Y('Rotten_Tomatoes_Rating:Q', bin=True),
alt.Color('count()',
scale=alt.Scale(scheme='greenblue'),
legend=alt.Legend(title='Total Records')
)
)
circ = rect.mark_point().encode(
alt.ColorValue('grey'),
alt.Size('count()',
legend=alt.Legend(title='Records in Selection')
)
).transform_filter(
pts
)
bar = alt.Chart(source).mark_bar().encode(
x='Major_Genre:N',
y='count()',
color=alt.condition(pts, alt.ColorValue("steelblue"), alt.ColorValue("grey"))
).properties(
width=550,
height=200
).add_selection(pts)
display(alt.vconcat(
rect + circ,
bar
).resolve_legend(
color="independent",
size="independent"
), target="altair")
</py-script>
</py-tutor>
</section>
</body>
</html>

39
examples/antigravity.html Normal file
View File

@@ -0,0 +1,39 @@
<html>
<head>
<title>Antigravity</title>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="./favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<link rel="stylesheet" href="./assets/css/examples.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c">Antigravity</a>
</div>
</nav>
<py-tutor modules="antigravity.py">
<section class="pyscript">
<py-config>
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
[[fetch]]
files = ["./antigravity.py"]
</py-config>
<b>Based on xkcd: antigravity https://xkcd.com/353/.</b>
<py-script>
import antigravity
antigravity.fly()
</py-script>
</section>
</py-tutor>
</body>
</html>

View File

@@ -1,19 +1,18 @@
import random
import sys
from js import DOMParser, document, setInterval
from pyodide import create_proxy
from pyodide.ffi import create_proxy
from pyodide.http import open_url
class Antigravity:
url = "./antigravity.svg"
def __init__(self, target=None, interval=10, append=True, fly=False):
target = target or sys.stdout._out
self.target = (
document.getElementById(target) if isinstance(target, str) else target
document.getElementById(target)
if isinstance(target, str)
else document.body
)
doc = DOMParser.new().parseFromString(
open_url(self.url).read(), "image/svg+xml"

View File

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 212 KiB

View File

@@ -0,0 +1,91 @@
body {
margin: 0;
}
.pyscript {
margin: 0.5rem;
}
.code {
display: flex;
position: absolute;
right: 0px;
z-index: 9998;
top: 7rem;
}
@media (max-width: 1300px) {
.code:has(> .code-section-visible) {
width: 90%;
/* Absolute position is messing up the layout on small screens */
right: 70px;
}
}
.code-section-hidden {
width: 0px;
display: none;
}
.code-section-visible {
display: flex;
flex-direction: column;
width: 100%;
background-color: rgb(45 46 53 / 90%);
padding: 1rem;
border-radius: 10px 0px 0px 10px;
color: #c6c6c8;
}
.code-section-visible p {
margin: 0;
font-style: italic;
font-size: small;
}
.language-html,
.language-python {
float: left;
}
#view-code-button {
writing-mode: tb-rl;
text-orientation: sideways-right;
background-color: #1d1d22;
color: white;
padding: 0.5rem;
border-radius: 5px;
cursor: pointer;
height: 81px;
}
nav {
position: sticky;
width: 100%;
top: 0;
left: 0;
z-index: 9999;
}
.logo {
padding-right: 10px;
font-size: 28px;
height: 30px;
max-width: inherit;
}
.title {
text-decoration: none;
text-decoration-line: none;
text-decoration-style: initial;
text-decoration-color: initial;
font-weight: 400;
font-size: 1.5em;
line-height: 2em;
white-space: nowrap;
}
.app-header {
display: flex;
align-items: center;
padding: 0.5rem 1rem;
}

View File

@@ -0,0 +1,74 @@
.example {
margin-bottom: 5rem;
}
.example h2 {
/* color: #000000; */
font-family: "Inconsolata", monospace;
font-size: 2.25rem;
margin-bottom: 1rem;
}
.card {
height: 15rem;
background-color: var(--color-secondary);
padding: 1rem;
border-radius: 10px;
}
.card:hover,
.card:hover a,
.card:hover a:visited,
.card:hover h2 {
background-color: var(--color-primary);
color: #1d1d22;
}
.card a h2 {
color: var(--color-primary);
margin: 0;
font-family: "Inconsolata", monospace;
font-size: 2.25rem;
}
.card a p {
color: var(--text-color);
}
a .card {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-content {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-content a,
.card-content a:visited {
color: var(--color-primary);
}
.container-card {
max-width: 1500px;
margin: 0 auto;
display: grid;
gap: 1rem;
}
@media (min-width: 600px) {
.container-card {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 900px) {
.container-card {
grid-template-columns: repeat(4, 1fr);
}
}

View File

@@ -0,0 +1,25 @@
@import url("https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap");
@import "./variables.css";
@import "./reset.css";
body {
background: #2d2e35
url("https://assets.anaconda.com/production/Content/1650828148240.png?w=3240&auto=compress%2Cformat&fit=crop&dm=1650828161&s=c558dc55e0ed1f8419a892e842a5728f")
repeat-x center bottom / 250px;
background-attachment: fixed;
overflow-x: hidden;
color: var(--text-color);
}
.container {
max-width: 1510px;
margin: auto;
padding: 0 2rem;
}
.title-main {
font-size: 4.25rem;
font-family: "Inconsolata", monospace;
text-align: center;
margin: 2rem 0;
}

View File

@@ -0,0 +1,22 @@
*,
*:after,
*:before {
margin: 0;
padding: 0;
box-sizing: border-box;
text-decoration: none;
}
body {
font-size: 100%;
list-style-type: none;
}
p {
font-family: "Inconsolata", monospace;
font-weight: 400;
}
a {
text-decoration: none;
}

View File

@@ -0,0 +1,6 @@
:root {
--color-primary: #fda703;
--color-secondary: #1d1d22;
--text-color: white;
--card-shadow: 0px 5px 11px 0px rgb(0 0 0 / 15%);
}

3
examples/assets/prism/prism.min.css vendored Normal file
View File

@@ -0,0 +1,3 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+clike+javascript+python */
code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}

7
examples/assets/prism/prism.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(0.1)
</py-script>
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(0.1)
</py-script>
</body>
</html>

View File

@@ -0,0 +1,45 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME
LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCallLoop1():
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(2)
asyncCallLoop1()
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME
LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCallLoop2():
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(2)
asyncCallLoop2()
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME
LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCallLoop1():
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(2)
asyncCallLoop1()
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME
LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(2)
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,45 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await NON-BLOCKING Pyscript Twice</title>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER
THAN LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCall1():
await asyncio.sleep(2)
for i in range(3):
js.console.log('A', i)
asyncCall1()
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER
THAN LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCall2():
await asyncio.sleep(2)
for i in range(3):
js.console.log('B', i)
asyncCall2()
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,39 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME
LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(2)
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME
LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(2)
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,22 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
import asyncio
from itertools import count
for i in count():
print(f"Count: {i}")
await asyncio.sleep(1)
</py-script>
</body>
</html>

94
examples/bokeh.html Normal file
View File

@@ -0,0 +1,94 @@
<html>
<head>
<title>Bokeh Example</title>
<meta charset="iso-8859-1" />
<link rel="icon" type="image/x-icon" href="./favicon.png" />
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-3.0.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-3.0.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.0.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.0.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.0.3.min.js"
></script>
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<link rel="stylesheet" href="./assets/css/examples.css" />
<style>
py-script {
display: none;
}
</style>
<script
type="module"
src="https://esm.sh/@pyscript/core@latest/core.js"
></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c"
>Bokeh Example</a
>
</div>
</nav>
<py-tutor>
<section class="pyscript">
<div id="myplot"></div>
<py-config>
packages = [
"pandas",
"bokeh",
"xyzservices"
]
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
</py-config>
<py-script id="main">
import json
import pyodide
from js import Bokeh, console, JSON
from bokeh.embed import json_item
from bokeh.plotting import figure
from bokeh.resources import CDN
# create a new plot with default tools, using figure
p = figure(width=400, height=400)
# add a circle renderer with x and y coordinates, size, color, and alpha
p.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=15, line_color="navy", fill_color="orange", fill_alpha=0.5)
p_json = json.dumps(json_item(p, "myplot"))
Bokeh.embed.embed_item(JSON.parse(p_json))
</py-script>
</section>
</py-tutor>
</body>
</html>

View File

@@ -0,0 +1,136 @@
<html>
<head>
<title>Bokeh Example</title>
<meta charset="iso-8859-1" />
<link rel="icon" type="image/x-icon" href="./favicon.png" />
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.3.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.3.min.js"
></script>
<script
type="text/javascript"
src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.3.min.js"
></script>
<link rel="stylesheet" href="./assets/css/examples.css" />
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c"
>Bokeh Example</a
>
</div>
</nav>
<py-tutor>
<section class="pyscript">
<h1>Bokeh Example</h1>
<div id="myplot"></div>
<py-config>
packages = [
"https://cdn.holoviz.org/panel/0.14.3/dist/wheels/bokeh-2.4.3-py3-none-any.whl",
"numpy",
]
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
</py-config>
<py-script id="main">
import asyncio
import json
import pyodide
from js import Bokeh, console, JSON
from bokeh import __version__
from bokeh.document import Document
from bokeh.embed.util import OutputDocumentFor, standalone_docs_json_and_render_items
from bokeh.models import Slider, Div
from bokeh.layouts import Row
from bokeh.protocol.messages.patch_doc import process_document_events
# create a new plot with default tools, using figure
p = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude")
div = Div(text=f'Amplitude is: {p.value}')
def callback(attr, old, new):
div.text = f'Amplitude is: {new}'
p.on_change('value', callback)
row = Row(children=[p, div])
def doc_json(model, target):
with OutputDocumentFor([model]) as doc:
doc.title = ""
docs_json, _ = standalone_docs_json_and_render_items(
[model], suppress_callback_warning=True
)
doc_json = list(docs_json.values())[0]
root_id = doc_json['roots']['root_ids'][0]
return doc, json.dumps(dict(
target_id = target,
root_id = root_id,
doc = doc_json,
version = __version__,
))
def _link_docs(pydoc, jsdoc):
def jssync(event):
if getattr(event, 'setter_id', None) is not None:
return
events = [event]
json_patch = jsdoc.create_json_patch_string(pyodide.ffi.to_js(events))
pydoc.apply_json_patch(json.loads(json_patch))
jsdoc.on_change(pyodide.ffi.create_proxy(jssync), pyodide.ffi.to_js(False))
def pysync(event):
json_patch, buffers = process_document_events([event], use_buffers=True)
buffer_map = {}
for (ref, buffer) in buffers:
buffer_map[ref['id']] = buffer
jsdoc.apply_json_patch(JSON.parse(json_patch), pyodide.ffi.to_js(buffer_map), setter_id='js')
pydoc.on_change(pysync)
async def show(plot, target):
pydoc, model_json = doc_json(plot, target)
views = await Bokeh.embed.embed_item(JSON.parse(model_json))
jsdoc = views[0].model.document
_link_docs(pydoc, jsdoc)
asyncio.ensure_future(show(row, 'myplot'))
</py-script>
</section>
</py-tutor>
</body>
</html>

138
examples/d3.html Normal file
View File

@@ -0,0 +1,138 @@
<html>
<head>
<title>d3: JavaScript & PyScript visualizations side-by-side</title>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="./favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="./assets/css/examples.css" />
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.loading {
display: inline-block;
width: 50px;
height: 50px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: black;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c"
>Simple d3 visualization</a
>
</div>
</nav>
<section class="pyscript">
<py-tutor modules="d3.py">
<py-config>
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
[[fetch]]
files = ["./d3.py"]
</py-config>
</py-tutor>
<b>
Based on
<i
><a
href="https://observablehq.com/@d3/learn-d3-shapes?collection=@d3/learn-d3>"
>Learn D3: Shapes</a
></i
>
tutorial.
</b>
<div style="display: flex; flex-direction: row">
<div>
<div style="text-align: center">JavaScript version</div>
<div id="js" style="width: 400px; height: 400px">
<div class="loading"></div>
</div>
</div>
<div>
<div style="text-align: center">PyScript version</div>
<div id="py" style="width: 400px; height: 400px">
<div class="loading"></div>
</div>
</div>
</div>
<py-script src="d3.py"></py-script>
</section>
<script type="module">
const fruits = [
{ name: "🍊", count: 21 },
{ name: "🍇", count: 13 },
{ name: "🍏", count: 8 },
{ name: "🍌", count: 5 },
{ name: "🍐", count: 3 },
{ name: "🍋", count: 2 },
{ name: "🍎", count: 1 },
{ name: "🍉", count: 1 },
];
const fn = (d) => d.count;
const data = d3.pie().value(fn)(fruits);
const arc = d3
.arc()
.innerRadius(210)
.outerRadius(310)
.padRadius(300)
.padAngle(2 / 300)
.cornerRadius(8);
const js = d3.select("#js");
js.select(".loading").remove();
const svg = js
.append("svg")
.attr("viewBox", "-320 -320 640 640")
.attr("width", "400")
.attr("height", "400");
for (const d of data) {
svg.append("path").style("fill", "steelblue").attr("d", arc(d));
const text = svg
.append("text")
.style("fill", "white")
.attr(
"transform",
`translate(${arc.centroid(d).join(",")})`,
)
.attr("text-anchor", "middle");
text.append("tspan")
.style("font-size", "24")
.attr("x", "0")
.text(d.data.name);
text.append("tspan")
.style("font-size", "18")
.attr("x", "0")
.attr("dy", "1.3em")
.text(d.value);
}
</script>
</body>
</html>

64
examples/d3.py Normal file
View File

@@ -0,0 +1,64 @@
import js
from pyodide.ffi import create_proxy, to_js
d3 = js.d3
fruits = [
{"name": "🍊", "count": 21},
{"name": "🍇", "count": 13},
{"name": "🍏", "count": 8},
{"name": "🍌", "count": 5},
{"name": "🍐", "count": 3},
{"name": "🍋", "count": 2},
{"name": "🍎", "count": 1},
{"name": "🍉", "count": 1},
]
fn = create_proxy(lambda d, *_: d["count"])
data = d3.pie().value(fn)(to_js(fruits))
arc = (
d3.arc()
.innerRadius(210)
.outerRadius(310)
.padRadius(300)
.padAngle(2 / 300)
.cornerRadius(8)
)
py = d3.select("#py")
py.select(".loading").remove()
svg = (
py.append("svg")
.attr("viewBox", "-320 -320 640 640")
.attr("width", "400")
.attr("height", "400")
)
for d in data:
d_py = d.to_py()
(svg.append("path").style("fill", "steelblue").attr("d", arc(d)))
text = (
svg.append("text")
.style("fill", "white")
.attr("transform", f"translate({arc.centroid(d).join(',')})")
.attr("text-anchor", "middle")
)
(
text.append("tspan")
.style("font-size", "24")
.attr("x", "0")
.text(d_py["data"]["name"])
)
(
text.append("tspan")
.style("font-size", "18")
.attr("x", "0")
.attr("dy", "1.3em")
.text(d_py["value"])
)

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

81
examples/folium.html Normal file
View File

@@ -0,0 +1,81 @@
<html>
<head>
<title>Folium</title>
<meta charset="utf-8" />
<link rel="icon" type="image/x-icon" href="./favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<link rel="stylesheet" href="./assets/css/examples.css" />
<style>
py-script {
display: none;
}
</style>
<script
type="module"
src="https://esm.sh/@pyscript/core@latest/core.js"
></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c">Folium</a>
</div>
</nav>
<section class="pyscript">
<div id="folium"></div>
<py-tutor>
<py-config>
packages = [
"folium",
"pandas"
]
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
</py-config>
<py-script>
from pyscript import display
import folium
import json
import pandas as pd
from pyodide.http import open_url
url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
)
state_geo = f"{url}/us-states.json"
state_unemployment = f"{url}/US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(open_url(state_unemployment))
geo_json = json.loads(open_url(state_geo).read())
m = folium.Map(location=[48, -102], zoom_start=3)
folium.Choropleth(
geo_data=geo_json,
name="choropleth",
data=state_data,
columns=["State", "Unemployment"],
key_on="feature.id",
fill_color="YlGn",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="Unemployment Rate (%)",
).add_to(m)
folium.LayerControl().add_to(m)
display(m, target="folium")
</py-script>
</py-tutor>
</section>
</body>
</html>

View File

@@ -0,0 +1,137 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Say Hello</title>
<link rel="icon" type="image/png" href="../favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
from js import handTrack, requestAnimationFrame, console
from pyodide import create_once_callable
import asyncio
update_note = Element("update-note")
canvas = Element("canvas")
video = Element("myvideo")
context = canvas.element.getContext("2d")
isVideo = False
model = None
modelParams = {
"flipHorizontal": True, # flip e.g for video
"maxNumBoxes": 20, # maximum number of boxes to detect
"iouThreshold": 0.5, # ioU threshold for non-max suppression
"scoreThreshold": 0.6, # confidence threshold for predictions.
}
def toggle_video():
global isVideo
if (not isVideo):
update_note.write("Starting video")
pyscript.run_until_complete(start_video())
else:
update_note.write("Stopping video")
handTrack.stopVideo(video.element)
isVideo = False
update_note.write("Video stopped")
async def start_video():
global isVideo
update_note.write("Inside sstart video")
status = await handTrack.startVideo(video.element)
console.log("video started", status)
if status:
update_note.write("Video started. Now tracking")
isVideo = True
console.log( "Calling RUN DETECTION")
y = await run_detection()
else:
update_note.write( "Please enable video")
def sync_run_detection(evt):
pyscript.run_until_complete(run_detection())
async def run_detection():
console.log("in RUN DETECTION: ");
global model
global isVideo
console.log("...1")
predictions = await model.detect(video.element)
console.log("done...1")
console.log("Predictions: ", predictions);
model.renderPredictions(predictions, canvas.element, context, video.element);
console.log("is Video?", isVideo)
if (isVideo):
console.log("requestingAnimation!")
await requestAnimationFrame(create_once_callable(sync_run_detection));
console.log("...2")
def run_detection_image(img):
console.log("in RUN DETECTION IMAGE", predictions);
global model
def detect(predition):
console.log("Predictions: ", predictions);
model.renderPredictions(predictions, canvas, context, img);
console.log("...3")
model.detect(img).then(detect)
console.log("...4")
def handle_model(lmodel):
global model
model = lmodel
update_note.write("Loaded Model!")
async def start():
console.log("creating x")
console.log("calling x")
model = await handTrack.load(modelParams)#.then(handle_model)
console.log("loaded model!")
console.log(model)
handle_model(model)
print(dir(x))
print(x)
pyscript.run_until_complete(start())
#});
</py-script>
<div class="mb10">
<button
id="trackbutton"
class="bx--btn bx--btn--secondary"
type="button"
py-click="toggle_video()"
>
Toggle Video
</button>
<button
id="nextimagebutton"
class="mt10 bx--btn bx--btn--secondary"
type="button"
disabled
>
Next Image
</button>
<div id="update-note" class="updatenote mt10">loading model ..</div>
</div>
<div>
<video autoplay="autoplay" id="myvideo" py-mount="video"></video>
<canvas id="canvas" class="border canvasbox"></canvas>
</div>
<script src="lib/handtrack.min.js"></script>
</body>
</html>

55
examples/hello_world.html Normal file
View File

@@ -0,0 +1,55 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>PyScript Hello World</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<link rel="stylesheet" href="./assets/css/examples.css" />
<style>
py-script {
display: none;
}
</style>
<script
type="module"
src="https://esm.sh/@pyscript/core@latest/core.js"
></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo" />
</a>
<a class="title" href="" style="color: #f0ab3c">Hello World</a>
</div>
</nav>
<py-tutor>
<py-config>
plugins = [
"https://pyscript.net/latest/plugins/python/py_tutor.py"
]
</py-config>
<section class="pyscript">
Hello world! <br />
This is the current date and time, as computed by Python:
<py-script>
from pyscript import display
from datetime import datetime
now = datetime.now()
display(now.strftime("%m/%d/%Y, %H:%M:%S"))
</py-script>
</section>
</py-tutor>
</body>
</html>

315
examples/index.html Normal file
View File

@@ -0,0 +1,315 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>PyScript demo</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="./assets/css/main.css" />
<link rel="stylesheet" href="./assets/css/index.css" />
</head>
<body class="container">
<h1 class="title-main">PyScript demos</h1>
<section class="example">
<h2>Basic examples</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./hello_world.html" target="_blank">
<h2>Hello world</h2>
</a>
<p>
A static demo of the
<code>&lt;py-script&gt;</code> tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./simple_clock.html" target="_blank">
<h2>Simple clock</h2>
</a>
<p>
A dynamic demo of the
<code>&lt;py-script&gt;</code> tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./repl.html" target="_blank">
<h2>REPL</h2>
</a>
<p>A Python REPL (Read Eval Print Loop)</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./repl2.html" target="_blank">
<h2>REPL2</h2>
</a>
<p>
A Python REPL (Read Eval Print Loop) with slightly
better formatting
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./todo.html" target="_blank">
<h2>TODO App</h2>
</a>
<p>Simple TODO App</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./todo-pylist.html" target="_blank">
<h2>PyScript Native TODO App</h2>
</a>
<p>
Simple TODO App using <code>&lt;py-list&gt;</code>
</p>
</div>
</div>
</div>
</section>
<section class="example">
<h2>MIME Rendering</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./matplotlib.html" target="_blank">
<h2>Matplotlib</h2>
</a>
<p>
Demonstrates rendering a
<a href="https://matplotlib.org/" target="_blank"
>Matplotlib</a
>
figure as output of the py-script tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./altair.html" target="_blank">
<h2>Altair</h2>
</a>
<p>
Demonstrates rendering a
<a
href="https://altair-viz.github.io/"
target="_blank"
>Altair</a
>
plot as output of the py-script tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./folium.html" target="_blank">
<h2>Folium</h2>
</a>
<p>
Demonstrates rendering a
<a
href="https://python-visualization.github.io/folium/"
target="_blank"
>Folium</a
>
map as output of the py-script tag
</p>
</div>
</div>
</div>
</section>
<section class="example">
<h2>JS Interaction</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./d3.html" target="_blank">
<h2>Simple d3 visualization</h2>
</a>
<p>
Minimal
<a href="https://d3js.org/" target="_blank">D3</a>
demo demonstrating how to create a visualization
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./webgl/raycaster/index.html" target="_blank">
<h2>Webgl Icosahedron Example</h2>
</a>
<p>
Demo showing how a Simple
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API"
target="_blank"
>WebGL</a
>
scene would work in the
<code>&lt;py-script&gt;</code> tag
</p>
</div>
</div>
</div>
</section>
<section class="example">
<h2>Visualizations & Dashboards</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./bokeh.html" target="_blank">
<h2>Simple Static Bokeh Plot</h2>
</a>
<p>
Minimal Bokeh demo demonstrating how to create a
simple
<a href="https://bokeh.org/" target="_blank"
>Bokeh</a
>
plot from code
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./bokeh_interactive.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
Bokeh Interactive
</h2>
</a>
<p>
Interactive demo using a
<a href="https://bokeh.org/" target="_blank"
>Bokeh</a
>
slider widget to dynamically change a value in the
page WARNING: This examples takes a little longer to
load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel_kmeans.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
KMeans Demo in Panel
</h2>
</a>
<p>
Interactive KMeans Chart using
<a href="https://panel.holoviz.org/" target="_blank"
>Panel</a
>
WARNING: This examples takes a little longer to
load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel_stream.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
Streaming Demo in Panel
</h2>
</a>
<p>
Interactive Streaming Table and Bokeh plot using
<a href="https://panel.holoviz.org/" target="_blank"
>Panel</a
>
WARNING: This examples takes a little longer to
load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel.html" target="_blank">
<h2 class="text-3xl font-bold text-blue-600">
Simple Panel Demo
</h2>
</a>
<p>
Simple demo showing
<a href="https://panel.holoviz.org/" target="_blank"
>Panel</a
>
widgets interacting with parts of the page WARNING:
This examples takes a little longer to load. So be
patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel_deckgl.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
NYC Taxi Data Panel DeckGL Demo
</h2>
</a>
<p>
Interactive application exploring the NYC Taxi
dataset using
<a href="https://panel.holoviz.org/" target="_blank"
>Panel</a
>
and
<a href="https://deck.gl/" target="_blank"
>DeckGL</a
>
WARNING: This examples takes a little longer to
load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./numpy_canvas_fractals.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
Fractals with NumPy and canvas
</h2>
</a>
<p>
Visualization of Mandelbrot and Julia sets with
<a href="https://numpy.org/" target="_blank"
>Numpy</a
>
and
<a
href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"
target="_blank"
>
HTML5 canvas
</a>
</p>
</div>
</div>
</div>
</section>
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@@ -0,0 +1,35 @@
html,
body,
ul,
li {
margin: 0;
border: 0;
padding: 0;
}
canvas {
display: block;
width: 762;
margin: 0 auto;
background-color: blue;
}
p {
text-align: center;
}
body {
overflow: hidden;
height: 100%;
}
html {
overflow: hidden;
height: 100%;
}
.info {
position: absolute;
top: 0;
left: 0;
}

View File

@@ -0,0 +1,43 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Bcoin = (Mario.Bcoin = function (pos) {
Mario.Entity.call(this, {
pos: pos,
sprite: level.bcoinSprite(),
hitbox: [0, 0, 16, 16],
});
});
Mario.Util.inherits(Bcoin, Mario.Entity);
//I'm not sure whether it makes sense to use an array for vel and acc here
//in order to keep with convention, or to just use a single value, since
//it's literally impossible for these to move left or right.
Bcoin.prototype.spawn = function () {
sounds.coin.currentTime = 0.05;
sounds.coin.play();
this.idx = level.items.length;
level.items.push(this);
this.active = true;
this.vel = -12;
this.targetpos = this.pos[1] - 32;
};
Bcoin.prototype.update = function (dt) {
if (!this.active) return;
if (this.vel > 0 && this.pos[1] >= this.targetpos) {
player.coins += 1;
//spawn a score thingy.
delete level.items[this.idx];
}
this.acc = 0.75;
this.vel += this.acc;
this.pos[1] += this.vel;
this.sprite.update(dt);
};
Bcoin.prototype.checkCollisions = function () {};
})();

View File

@@ -0,0 +1,84 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
//TODO: clean up the logic for sprite switching.
//TODO: There's a weird bug with the collision logic. Look into it.
var Block = (Mario.Block = function (options) {
this.item = options.item;
this.usedSprite = options.usedSprite;
this.bounceSprite = options.bounceSprite;
this.breakable = options.breakable;
Mario.Entity.call(this, {
pos: options.pos,
sprite: options.sprite,
hitbox: [0, 0, 16, 16],
});
this.standing = true;
});
Mario.Util.inherits(Block, Mario.Floor);
Block.prototype.break = function () {
sounds.breakBlock.play();
new Mario.Rubble().spawn(this.pos);
var x = this.pos[0] / 16,
y = this.pos[1] / 16;
delete level.blocks[y][x];
};
Block.prototype.bonk = function (power) {
sounds.bump.play();
if (power > 0 && this.breakable) {
this.break();
} else if (this.standing) {
this.standing = false;
if (this.item) {
this.item.spawn();
this.item = null;
}
this.opos = [];
this.opos[0] = this.pos[0];
this.opos[1] = this.pos[1];
if (this.bounceSprite) {
this.osprite = this.sprite;
this.sprite = this.bounceSprite;
} else {
this.sprite = this.usedSprite;
}
this.vel[1] = -2;
}
};
Block.prototype.update = function (dt, gameTime) {
if (!this.standing) {
if (this.pos[1] < this.opos[1] - 8) {
this.vel[1] = 2;
}
if (this.pos[1] > this.opos[1]) {
this.vel[1] = 0;
this.pos = this.opos;
if (this.osprite) {
this.sprite = this.osprite;
}
this.standing = true;
}
} else {
if (this.sprite === this.usedSprite) {
var x = this.pos[0] / 16,
y = this.pos[1] / 16;
level.statics[y][x] = new Mario.Floor(
this.pos,
this.usedSprite,
);
delete level.blocks[y][x];
}
}
this.pos[1] += this.vel[1];
this.sprite.update(dt, gameTime);
};
})();

62
examples/mario/js/coin.js Normal file
View File

@@ -0,0 +1,62 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Coin = (Mario.Coin = function (pos, sprite) {
Mario.Entity.call(this, {
pos: pos,
sprite: sprite,
hitbox: [0, 0, 16, 16],
});
this.idx = level.items.length;
});
Mario.Util.inherits(Coin, Mario.Entity);
Coin.prototype.isPlayerCollided = function () {
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [
player.pos[0] + player.hitbox[0],
player.pos[1] + player.hitbox[1],
];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + player.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + player.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
this.collect();
}
}
};
Coin.prototype.render = function (ctx, vX, vY) {
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
//money is not affected by gravity, you see.
Coin.prototype.update = function (dt) {
this.sprite.update(dt);
};
Coin.prototype.checkCollisions = function () {
this.isPlayerCollided();
};
Coin.prototype.collect = function () {
sounds.coin.currentTime = 0.05;
sounds.coin.play();
player.coins += 1;
delete level.items[this.idx];
};
})();

View File

@@ -0,0 +1,34 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Entity = (Mario.Entity = function (options) {
this.vel = [0, 0];
this.acc = [0, 0];
this.standing = true;
this.pos = options.pos;
this.sprite = options.sprite;
this.hitbox = options.hitbox;
this.left = false;
});
Entity.prototype.render = function (ctx, vX, vY) {
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Entity.prototype.collideWall = function (wall) {
//the wall will always be a 16x16 block with hitbox = [0,0,16,16].
if (this.pos[0] > wall.pos[0]) {
//from the right
this.pos[0] = wall.pos[0] + wall.hitbox[2] - this.hitbox[0];
this.vel[0] = Math.max(0, this.vel[0]);
this.acc[0] = Math.max(0, this.acc[0]);
} else {
this.pos[0] =
wall.pos[0] + wall.hitbox[0] - this.hitbox[2] - this.hitbox[0];
this.vel[0] = Math.min(0, this.vel[0]);
this.acc[0] = Math.min(0, this.acc[0]);
}
};
Entity.prototype.bump = function () {};
})();

View File

@@ -0,0 +1,145 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Fireball = (Mario.Fireball = function (pos) {
this.hit = 0;
this.standing = false;
Mario.Entity.call(this, {
pos: pos,
sprite: new Mario.Sprite(
"sprites/items.png",
[96, 144],
[8, 8],
5,
[0, 1, 2, 3],
),
hitbox: [0, 0, 8, 8],
});
});
Mario.Util.inherits(Fireball, Mario.Entity);
Fireball.prototype.spawn = function (left) {
sounds.fireball.currentTime = 0;
sounds.fireball.play();
if (fireballs[0]) {
this.idx = 1;
fireballs[1] = this;
} else {
this.idx = 0;
fireballs[0] = this;
}
this.vel[0] = left ? -5 : 5;
this.standing = false;
this.vel[1] = 0;
};
Fireball.prototype.render = function (ctx, vX, vY) {
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Fireball.prototype.update = function (dt) {
if (this.hit == 1) {
this.sprite.pos = [96, 160];
this.sprite.size = [16, 16];
this.sprite.frames = [0, 1, 2];
this.sprite.speed = 8;
this.hit += 1;
return;
} else if (this.hit == 5) {
delete fireballs[this.idx];
player.fireballs -= 1;
return;
} else if (this.hit) {
this.hit += 1;
return;
}
//In retrospect, the way collision is being handled is RIDICULOUS
//but I don't have to use some horrible kludge for this.
if (this.standing) {
this.standing = false;
this.vel[1] = -4;
}
this.acc[1] = 0.5;
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
if (this.pos[0] < vX || this.pos[0] > vX + 256) {
this.hit = 1;
}
this.sprite.update(dt);
};
Fireball.prototype.collideWall = function () {
if (!this.hit) this.hit = 1;
};
Fireball.prototype.checkCollisions = function () {
if (this.hit) return;
var h = this.pos[1] % 16 < 8 ? 1 : 2;
var w = this.pos[0] % 16 < 8 ? 1 : 2;
var baseX = Math.floor(this.pos[0] / 16);
var baseY = Math.floor(this.pos[1] / 16);
if (baseY + h > 15) {
delete fireballs[this.idx];
player.fireballs -= 1;
return;
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
if (level.statics[baseY + i][baseX + j]) {
level.statics[baseY + i][baseX + j].isCollideWith(this);
}
if (level.blocks[baseY + i][baseX + j]) {
level.blocks[baseY + i][baseX + j].isCollideWith(this);
}
}
}
var that = this;
level.enemies.forEach(function (enemy) {
if (enemy.flipping || enemy.pos[0] - vX > 336) {
//stop checking once we get to far away dudes.
return;
} else {
that.isCollideWith(enemy);
}
});
};
Fireball.prototype.isCollideWith = function (ent) {
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
this.hit = 1;
ent.bump();
}
}
};
Fireball.prototype.bump = function () {};
})();

View File

@@ -0,0 +1,90 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Fireflower = (Mario.Fireflower = function (pos) {
this.spawning = false;
this.waiting = 0;
Mario.Entity.call(this, {
pos: pos,
sprite: level.fireFlowerSprite,
hitbox: [0, 0, 16, 16],
});
});
Mario.Util.inherits(Fireflower, Mario.Entity);
Fireflower.prototype.render = function (ctx, vX, vY) {
if (this.spawning > 1) return;
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Fireflower.prototype.spawn = function () {
sounds.itemAppear.play();
this.idx = level.items.length;
level.items.push(this);
this.spawning = 12;
this.targetpos = [];
this.targetpos[0] = this.pos[0];
this.targetpos[1] = this.pos[1] - 16;
};
Fireflower.prototype.update = function (dt) {
if (this.spawning > 1) {
this.spawning -= 1;
if (this.spawning == 1) this.vel[1] = -0.5;
return;
}
if (this.spawning) {
if (this.pos[1] <= this.targetpos[1]) {
this.pos[1] = this.targetpos[1];
this.vel[1] = 0;
this.spawning = 0;
}
}
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
this.sprite.update(dt);
};
Fireflower.prototype.checkCollisions = function () {
if (this.spawning) {
return;
}
this.isPlayerCollided();
};
Fireflower.prototype.isPlayerCollided = function () {
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [
player.pos[0] + player.hitbox[0],
player.pos[1] + player.hitbox[1],
];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + player.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + player.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
player.powerUp(this.idx);
}
}
};
//This should never be called, but just in case.
Fireflower.prototype.bump = function () {};
})();

51
examples/mario/js/flag.js Normal file
View File

@@ -0,0 +1,51 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
Flag = Mario.Flag = function (pos) {
//afaik flags always have the same height and Y-position
this.pos = [pos, 49];
this.hitbox = [0, 0, 0, 0];
this.vel = [0, 0];
this.acc = [0, 0];
};
Flag.prototype.collideWall = function () {};
Flag.prototype.update = function (dt) {
if (!this.done && this.pos[1] >= 170) {
this.vel = [0, 0];
this.pos[1] = 170;
player.exit();
this.done = true;
}
this.pos[1] += this.vel[1];
};
Flag.prototype.checkCollisions = function () {
this.isPlayerCollided();
};
Flag.prototype.isPlayerCollided = function () {
if (this.hit) return;
if (player.pos[0] + 8 >= this.pos[0]) {
music.overworld.pause();
sounds.flagpole.play();
setTimeout(function () {
music.clear.play();
}, 2000);
this.hit = true;
player.flag();
this.vel = [0, 2];
}
};
Flag.prototype.render = function () {
level.flagpoleSprites[2].render(
ctx,
this.pos[0] - 8,
this.pos[1],
vX,
vY,
);
};
})();

View File

@@ -0,0 +1,83 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Floor = (Mario.Floor = function (pos, sprite) {
Mario.Entity.call(this, {
pos: pos,
sprite: sprite,
hitbox: [0, 0, 16, 16],
});
});
Mario.Util.inherits(Floor, Mario.Entity);
Floor.prototype.isCollideWith = function (ent) {
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
Math.floor(this.pos[0] + this.hitbox[0]),
Math.floor(this.pos[1] + this.hitbox[1]),
];
var hpos2 = [
Math.floor(ent.pos[0] + ent.hitbox[0]),
Math.floor(ent.pos[1] + ent.hitbox[1]),
];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
if (!this.standing) {
ent.bump();
} else {
//if the entity is over the block, it's basically floor
var center = hpos2[0] + ent.hitbox[2] / 2;
if (
Math.abs(hpos2[1] + ent.hitbox[3] - hpos1[1]) <=
ent.vel[1]
) {
if (
level.statics[this.pos[1] / 16 - 1][
this.pos[0] / 16
]
) {
return;
}
ent.vel[1] = 0;
ent.pos[1] = hpos1[1] - ent.hitbox[3] - ent.hitbox[1];
ent.standing = true;
if (ent instanceof Mario.Player) {
ent.jumping = 0;
}
} else if (
Math.abs(hpos2[1] - hpos1[1] - this.hitbox[3]) >
ent.vel[1] &&
center + 2 >= hpos1[0] &&
center - 2 <= hpos1[0] + this.hitbox[2]
) {
//ent is under the block.
ent.vel[1] = 0;
ent.pos[1] = hpos1[1] + this.hitbox[3];
if (ent instanceof Mario.Player) {
this.bonk(ent.power);
ent.jumping = 0;
}
} else {
//entity is hitting it from the side, we're a wall
ent.collideWall(this);
}
}
}
}
};
Floor.prototype.bonk = function () {};
})();

253
examples/mario/js/game.js Normal file
View File

@@ -0,0 +1,253 @@
var requestAnimFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
})();
//create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var updateables = [];
var fireballs = [];
var player = new Mario.Player([0, 0]);
//we might have to get the size and calculate the scaling
//but this method should let us make it however big.
//Cool!
//TODO: Automatically scale the game to work and look good on widescreen.
//TODO: fiddling with scaled sprites looks BETTER, but not perfect. Hmm.
canvas.width = 762;
canvas.height = 720;
ctx.scale(3, 3);
document.body.appendChild(canvas);
//viewport
var vX = 0,
vY = 0,
vWidth = 256,
vHeight = 240;
//load our images
resources.load([
"sprites/player.png",
"sprites/enemy.png",
"sprites/tiles.png",
"sprites/playerl.png",
"sprites/items.png",
"sprites/enemyr.png",
]);
resources.onReady(init);
var level;
var sounds;
var music;
//initialize
var lastTime;
function init() {
music = {
overworld: new Audio("sounds/aboveground_bgm.ogg"),
underground: new Audio("sounds/underground_bgm.ogg"),
clear: new Audio("sounds/stage_clear.wav"),
death: new Audio("sounds/mariodie.wav"),
};
sounds = {
smallJump: new Audio("sounds/jump-small.wav"),
bigJump: new Audio("sounds/jump-super.wav"),
breakBlock: new Audio("sounds/breakblock.wav"),
bump: new Audio("sounds/bump.wav"),
coin: new Audio("sounds/coin.wav"),
fireball: new Audio("sounds/fireball.wav"),
flagpole: new Audio("sounds/flagpole.wav"),
kick: new Audio("sounds/kick.wav"),
pipe: new Audio("sounds/pipe.wav"),
itemAppear: new Audio("sounds/itemAppear.wav"),
powerup: new Audio("sounds/powerup.wav"),
stomp: new Audio("sounds/stomp.wav"),
};
Mario.oneone();
lastTime = Date.now();
main();
}
var gameTime = 0;
//set up the game loop
function main() {
var now = Date.now();
var dt = (now - lastTime) / 1000.0;
update(dt);
render();
lastTime = now;
requestAnimFrame(main);
}
function update(dt) {
gameTime += dt;
handleInput(dt);
updateEntities(dt, gameTime);
checkCollisions();
}
function handleInput(dt) {
if (player.piping || player.dying || player.noInput) return; //don't accept input
if (input.isDown("RUN")) {
player.run();
} else {
player.noRun();
}
if (input.isDown("JUMP")) {
player.jump();
} else {
//we need this to handle the timing for how long you hold it
player.noJump();
}
if (input.isDown("DOWN")) {
player.crouch();
} else {
player.noCrouch();
}
if (input.isDown("LEFT")) {
// 'd' or left arrow
player.moveLeft();
} else if (input.isDown("RIGHT")) {
// 'k' or right arrow
player.moveRight();
} else {
player.noWalk();
}
}
//update all the moving stuff
function updateEntities(dt, gameTime) {
player.update(dt, vX);
updateables.forEach(function (ent) {
ent.update(dt, gameTime);
});
//This should stop the jump when he switches sides on the flag.
if (player.exiting) {
if (player.pos[0] > vX + 96) vX = player.pos[0] - 96;
} else if (level.scrolling && player.pos[0] > vX + 80) {
vX = player.pos[0] - 80;
}
if (player.powering.length !== 0 || player.dying) {
return;
}
level.items.forEach(function (ent) {
ent.update(dt);
});
level.enemies.forEach(function (ent) {
ent.update(dt, vX);
});
fireballs.forEach(function (fireball) {
fireball.update(dt);
});
level.pipes.forEach(function (pipe) {
pipe.update(dt);
});
}
//scan for collisions
function checkCollisions() {
if (player.powering.length !== 0 || player.dying) {
return;
}
player.checkCollisions();
//Apparently for each will just skip indices where things were deleted.
level.items.forEach(function (item) {
item.checkCollisions();
});
level.enemies.forEach(function (ent) {
ent.checkCollisions();
});
fireballs.forEach(function (fireball) {
fireball.checkCollisions();
});
level.pipes.forEach(function (pipe) {
pipe.checkCollisions();
});
}
//draw the game!
function render() {
updateables = [];
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = level.background;
ctx.fillRect(0, 0, canvas.width, canvas.height);
//scenery gets drawn first to get layering right.
for (var i = 0; i < 15; i++) {
for (
var j = Math.floor(vX / 16) - 1;
j < Math.floor(vX / 16) + 20;
j++
) {
if (level.scenery[i][j]) {
renderEntity(level.scenery[i][j]);
}
}
}
//then items
level.items.forEach(function (item) {
renderEntity(item);
});
level.enemies.forEach(function (enemy) {
renderEntity(enemy);
});
fireballs.forEach(function (fireball) {
renderEntity(fireball);
});
//then we draw every static object.
for (var i = 0; i < 15; i++) {
for (
var j = Math.floor(vX / 16) - 1;
j < Math.floor(vX / 16) + 20;
j++
) {
if (level.statics[i][j]) {
renderEntity(level.statics[i][j]);
}
if (level.blocks[i][j]) {
renderEntity(level.blocks[i][j]);
updateables.push(level.blocks[i][j]);
}
}
}
//then the player
if (player.invincibility % 2 === 0) {
renderEntity(player);
}
//Mario goes INTO pipes, so naturally they go after.
level.pipes.forEach(function (pipe) {
renderEntity(pipe);
});
}
function renderEntity(entity) {
entity.render(ctx, vX, vY);
}

147
examples/mario/js/goomba.js Normal file
View File

@@ -0,0 +1,147 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
//TODO: On console the hitbox is smaller. Measure it and edit this.
var Goomba = (Mario.Goomba = function (pos, sprite) {
this.dying = false;
Mario.Entity.call(this, {
pos: pos,
sprite: sprite,
hitbox: [0, 0, 16, 16],
});
this.vel[0] = -0.5;
this.idx = level.enemies.length;
});
Goomba.prototype.render = function (ctx, vX, vY) {
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Goomba.prototype.update = function (dt, vX) {
if (this.pos[0] - vX > 336) {
//if we're too far away, do nothing.
return;
} else if (this.pos[0] - vX < -32) {
delete level.enemies[this.idx];
}
if (this.dying) {
this.dying -= 1;
if (!this.dying) {
delete level.enemies[this.idx];
}
}
this.acc[1] = 0.2;
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
this.sprite.update(dt);
};
Goomba.prototype.collideWall = function () {
this.vel[0] = -this.vel[0];
};
Goomba.prototype.checkCollisions = function () {
if (this.flipping) {
return;
}
var h = this.pos[1] % 16 === 0 ? 1 : 2;
var w = this.pos[0] % 16 === 0 ? 1 : 2;
var baseX = Math.floor(this.pos[0] / 16);
var baseY = Math.floor(this.pos[1] / 16);
if (baseY + h > 15) {
delete level.enemies[this.idx];
return;
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
if (level.statics[baseY + i][baseX + j]) {
level.statics[baseY + i][baseX + j].isCollideWith(this);
}
if (level.blocks[baseY + i][baseX + j]) {
level.blocks[baseY + i][baseX + j].isCollideWith(this);
}
}
}
var that = this;
level.enemies.forEach(function (enemy) {
if (enemy === that) {
//don't check collisions with ourselves.
return;
} else if (enemy.pos[0] - vX > 336) {
//stop checking once we get to far away dudes.
return;
} else {
that.isCollideWith(enemy);
}
});
this.isCollideWith(player);
};
Goomba.prototype.isCollideWith = function (ent) {
if (ent instanceof Mario.Player && (this.dying || ent.invincibility)) {
return;
}
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
if (ent instanceof Mario.Player) {
//if we hit the player
if (ent.vel[1] > 0) {
//then the goomba dies
this.stomp();
} else if (ent.starTime) {
this.bump();
} else {
//or the player gets hit
ent.damage();
}
} else {
this.collideWall();
}
}
}
};
Goomba.prototype.stomp = function () {
sounds.stomp.play();
player.bounce = true;
this.sprite.pos[0] = 32;
this.sprite.speed = 0;
this.vel[0] = 0;
this.dying = 10;
};
Goomba.prototype.bump = function () {
sounds.kick.play();
this.sprite.img = "sprites/enemyr.png";
this.flipping = true;
this.pos[1] -= 1;
this.vel[0] = 0;
this.vel[1] = -2.5;
};
})();

View File

@@ -0,0 +1,61 @@
(function () {
var pressedKeys = {};
function setKey(event, status) {
var code = event.keyCode;
var key;
switch (code) {
case 32:
key = "SPACE";
break;
case 37:
key = "LEFT";
break;
case 38:
key = "UP";
break;
case 39:
key = "RIGHT";
break;
case 40:
key = "DOWN";
break;
case 88:
key = "JUMP";
break;
case 90:
key = "RUN";
break;
default:
key = String.fromCharCode(code);
}
pressedKeys[key] = status;
}
document.addEventListener("keydown", function (e) {
setKey(e, true);
});
document.addEventListener("keyup", function (e) {
setKey(e, false);
});
window.addEventListener("blur", function () {
pressedKeys = {};
});
window.input = {
isDown: function (key) {
return pressedKeys[key.toUpperCase()];
},
reset: function () {
pressedKeys["RUN"] = false;
pressedKeys["LEFT"] = false;
pressedKeys["RIGHT"] = false;
pressedKeys["DOWN"] = false;
pressedKeys["JUMP"] = false;
},
};
})();

228
examples/mario/js/koopa.js Normal file
View File

@@ -0,0 +1,228 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Koopa = (Mario.Koopa = function (pos, sprite, para) {
this.dying = false;
this.shell = false;
this.para = para; //para. As in, is it a paratroopa?
//So, funny story. The actual hitboxes don't reach all the way to the ground.
//What that means is, as long as I use them to keep things on the floor
//making the hitboxes accurate will make enemies sink into the ground.
Mario.Entity.call(this, {
pos: pos,
sprite: sprite,
hitbox: [2, 8, 12, 24],
});
this.vel[0] = -0.5;
this.idx = level.enemies.length;
});
Koopa.prototype.render = function (ctx, vX, vY) {
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Koopa.prototype.update = function (dt, vX) {
if (this.turn) {
this.vel[0] = -this.vel[0];
if (this.shell) sounds.bump.play();
this.turn = false;
}
if (this.vel[0] != 0) {
this.left = this.vel[0] < 0;
}
if (this.left) {
this.sprite.img = "sprites/enemy.png";
} else {
this.sprite.img = "sprites/enemyr.png";
}
if (this.pos[0] - vX > 336) {
//if we're too far away, do nothing.
return;
} else if (this.pos[0] - vX < -32) {
delete level.enemies[this.idx];
}
if (this.dying) {
this.dying -= 1;
if (!this.dying) {
delete level.enemies[this.idx];
}
}
if (this.shell) {
if (this.vel[0] == 0) {
this.shell -= 1;
if (this.shell < 120) {
this.sprite.speed = 5;
}
if (this.shell == 0) {
this.sprite = level.koopaSprite();
this.hitbox = [2, 8, 12, 24];
if (this.left) {
this.sprite.img = "sprites/enemyr.png";
this.vel[0] = 0.5;
this.left = false;
} else {
this.vel[0] = -0.5;
this.left = true;
}
this.pos[1] -= 16;
}
} else {
this.shell = 360;
this.sprite.speed = 0;
this.sprite.setFrame(0);
}
}
this.acc[1] = 0.2;
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
this.sprite.update(dt);
};
Koopa.prototype.collideWall = function () {
//This stops us from flipping twice on the same frame if we collide
//with multiple wall tiles simultaneously.
this.turn = true;
};
Koopa.prototype.checkCollisions = function () {
var h = this.shell ? 1 : 2;
if (this.pos[1] % 16 !== 0) {
h += 1;
}
var w = this.pos[0] % 16 === 0 ? 1 : 2;
var baseX = Math.floor(this.pos[0] / 16);
var baseY = Math.floor(this.pos[1] / 16);
if (baseY + h > 15) {
delete level.enemies[this.idx];
return;
}
if (this.flipping) {
return;
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
if (level.statics[baseY + i][baseX + j]) {
level.statics[baseY + i][baseX + j].isCollideWith(this);
}
if (level.blocks[baseY + i][baseX + j]) {
level.blocks[baseY + i][baseX + j].isCollideWith(this);
}
}
}
var that = this;
level.enemies.forEach(function (enemy) {
if (enemy === that) {
//don't check collisions with ourselves.
return;
} else if (enemy.pos[0] - vX > 336) {
//stop checking once we get to far away dudes.
return;
} else {
that.isCollideWith(enemy);
}
});
this.isCollideWith(player);
};
Koopa.prototype.isCollideWith = function (ent) {
if (ent instanceof Mario.Player && (this.dying || ent.invincibility)) {
return;
}
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [ent.pos[0] + ent.hitbox[0], ent.pos[1] + ent.hitbox[1]];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
if (ent instanceof Mario.Player) {
if (ent.vel[1] > 0) {
player.bounce = true;
}
if (this.shell) {
sounds.kick.play();
if (this.vel[0] === 0) {
if (ent.left) {
//I'm pretty sure this isn't the real logic.
this.vel[0] = -4;
} else {
this.vel[0] = 4;
}
} else {
if (ent.bounce) {
this.vel[0] = 0;
} else ent.damage();
}
} else if (ent.vel[1] > 0) {
//then we get BOPPED.
this.stomp();
} else {
//or the player gets hit
ent.damage();
}
} else {
if (this.shell && ent instanceof Mario.Goomba) {
ent.bump();
} else this.collideWall();
}
}
}
};
Koopa.prototype.stomp = function () {
//Turn this thing into a shell if it isn't already. Kick it if it is.
player.bounce = true;
if (this.para) {
this.para = false;
this.sprite.pos[0] -= 32;
} else {
sounds.stomp.play();
this.shell = 360;
this.sprite.pos[0] += 64;
this.sprite.pos[1] += 16;
this.sprite.size = [16, 16];
this.hitbox = [2, 0, 12, 16];
this.sprite.speed = 0;
this.frames = [0, 1];
this.vel = [0, 0];
this.pos[1] += 16;
}
};
Koopa.prototype.bump = function () {
sounds.kick.play();
if (this.flipping) return;
this.flipping = true;
this.sprite.pos = [160, 0];
this.sprite.size = [16, 16];
this.hitbox = [2, 0, 12, 16];
this.sprite.speed = 0;
this.vel[0] = 0;
this.vel[1] = -2.5;
};
})();

View File

@@ -0,0 +1,341 @@
var oneone = (Mario.oneone = function () {
//The things that need to be passed in are basically just dependent on what
//tileset we're in, so it makes more sense to just make one variable for that, so
//TODO: put as much of this in the Level object definition as possible.
level = new Mario.Level({
playerPos: [56, 192],
loader: Mario.oneone,
background: "#7974FF",
scrolling: true,
invincibility: [144, 192, 240],
exit: 204,
floorSprite: new Mario.Sprite("sprites/tiles.png", [0, 0], [16, 16], 0),
cloudSprite: new Mario.Sprite(
"sprites/tiles.png",
[0, 320],
[48, 32],
0,
),
wallSprite: new Mario.Sprite("sprites/tiles.png", [0, 16], [16, 16], 0),
brickSprite: new Mario.Sprite(
"sprites/tiles.png",
[16, 0],
[16, 16],
0,
),
brickBounceSprite: new Mario.Sprite(
"sprites/tiles.png",
[32, 0],
[16, 16],
0,
),
rubbleSprite: function () {
return new Mario.Sprite(
"sprites/items.png",
[64, 0],
[8, 8],
3,
[0, 1],
);
},
ublockSprite: new Mario.Sprite(
"sprites/tiles.png",
[48, 0],
[16, 16],
0,
),
superShroomSprite: new Mario.Sprite(
"sprites/items.png",
[0, 0],
[16, 16],
0,
),
fireFlowerSprite: new Mario.Sprite(
"sprites/items.png",
[0, 32],
[16, 16],
20,
[0, 1, 2, 3],
),
starSprite: new Mario.Sprite(
"sprites/items.png",
[0, 48],
[16, 16],
20,
[0, 1, 2, 3],
),
pipeLEndSprite: new Mario.Sprite(
"sprites/tiles.png",
[0, 128],
[16, 16],
0,
),
pipeREndSprite: new Mario.Sprite(
"sprites/tiles.png",
[16, 128],
[16, 16],
0,
),
pipeLMidSprite: new Mario.Sprite(
"sprites/tiles.png",
[0, 144],
[16, 16],
0,
),
pipeRMidSprite: new Mario.Sprite(
"sprites/tiles.png",
[16, 144],
[16, 16],
0,
),
pipeUpMid: new Mario.Sprite("sprites/tiles.png", [0, 144], [32, 16], 0),
pipeSideMid: new Mario.Sprite(
"sprites/tiles.png",
[48, 128],
[16, 32],
0,
),
pipeLeft: new Mario.Sprite("sprites/tiles.png", [32, 128], [16, 32], 0),
pipeTop: new Mario.Sprite("sprites/tiles.png", [0, 128], [32, 16], 0),
qblockSprite: new Mario.Sprite(
"sprites/tiles.png",
[384, 0],
[16, 16],
8,
[0, 0, 0, 0, 1, 2, 1],
),
bcoinSprite: function () {
return new Mario.Sprite(
"sprites/items.png",
[0, 112],
[16, 16],
20,
[0, 1, 2, 3],
);
},
cloudSprites: [
new Mario.Sprite("sprites/tiles.png", [0, 320], [16, 32], 0),
new Mario.Sprite("sprites/tiles.png", [16, 320], [16, 32], 0),
new Mario.Sprite("sprites/tiles.png", [32, 320], [16, 32], 0),
],
hillSprites: [
new Mario.Sprite("sprites/tiles.png", [128, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [144, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [160, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [128, 144], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [144, 144], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [160, 144], [16, 16], 0),
],
bushSprite: new Mario.Sprite(
"sprites/tiles.png",
[176, 144],
[48, 16],
0,
),
bushSprites: [
new Mario.Sprite("sprites/tiles.png", [176, 144], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [192, 144], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [208, 144], [16, 16], 0),
],
goombaSprite: function () {
return new Mario.Sprite(
"sprites/enemy.png",
[0, 16],
[16, 16],
3,
[0, 1],
);
},
koopaSprite: function () {
return new Mario.Sprite(
"sprites/enemy.png",
[96, 0],
[16, 32],
2,
[0, 1],
);
},
flagPoleSprites: [
new Mario.Sprite("sprites/tiles.png", [256, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [256, 144], [16, 16], 0),
new Mario.Sprite("sprites/items.png", [128, 32], [16, 16], 0),
],
});
ground = [
[0, 69],
[71, 86],
[89, 153],
[155, 212],
];
player.pos[0] = level.playerPos[0];
player.pos[1] = level.playerPos[1];
vX = 0;
//build THE GROUND
ground.forEach(function (loc) {
level.putFloor(loc[0], loc[1]);
});
//build scenery
clouds = [
[7, 3],
[19, 2],
[56, 3],
[67, 2],
[87, 2],
[103, 2],
[152, 3],
[163, 2],
[200, 3],
];
clouds.forEach(function (cloud) {
level.putCloud(cloud[0], cloud[1]);
});
twoClouds = [
[36, 2],
[132, 2],
[180, 2],
];
twoClouds.forEach(function (cloud) {
level.putTwoCloud(cloud[0], cloud[1]);
});
threeClouds = [
[27, 3],
[75, 3],
[123, 3],
[171, 3],
];
threeClouds.forEach(function (cloud) {
level.putThreeCloud(cloud[0], cloud[1]);
});
bHills = [0, 48, 96, 144, 192];
bHills.forEach(function (hill) {
level.putBigHill(hill, 12);
});
sHills = [16, 64, 111, 160];
sHills.forEach(function (hill) {
level.putSmallHill(hill, 12);
});
bushes = [23, 71, 118, 167];
bushes.forEach(function (bush) {
level.putBush(bush, 12);
});
twoBushes = [41, 89, 137];
twoBushes.forEach(function (bush) {
level.putTwoBush(bush, 12);
});
threeBushes = [11, 59, 106];
threeBushes.forEach(function (bush) {
level.putThreeBush(bush, 12);
});
//interactable terrain
level.putQBlock(16, 9, new Mario.Bcoin([256, 144]));
level.putBrick(20, 9, null);
level.putQBlock(21, 9, new Mario.Mushroom([336, 144]));
level.putBrick(22, 9, null);
level.putQBlock(22, 5, new Mario.Bcoin([352, 80]));
level.putQBlock(23, 9, new Mario.Bcoin([368, 144]));
level.putBrick(24, 9, null);
level.putPipe(28, 13, 2);
level.putPipe(38, 13, 3);
level.putPipe(46, 13, 4);
level.putRealPipe(57, 9, 4, "DOWN", Mario.oneonetunnel);
level.putBrick(77, 9, null);
level.putQBlock(78, 9, new Mario.Mushroom([1248, 144]));
level.putBrick(79, 9, null);
level.putBrick(80, 5, null);
level.putBrick(81, 5, null);
level.putBrick(82, 5, null);
level.putBrick(83, 5, null);
level.putBrick(84, 5, null);
level.putBrick(85, 5, null);
level.putBrick(86, 5, null);
level.putBrick(87, 5, null);
level.putBrick(91, 5, null);
level.putBrick(92, 5, null);
level.putBrick(93, 5, null);
level.putQBlock(94, 5, new Mario.Bcoin([1504, 80]));
level.putBrick(94, 9, null);
level.putBrick(100, 9, new Mario.Star([1600, 144]));
level.putBrick(101, 9, null);
level.putQBlock(105, 9, new Mario.Bcoin([1680, 144]));
level.putQBlock(108, 9, new Mario.Bcoin([1728, 144]));
level.putQBlock(108, 5, new Mario.Mushroom([1728, 80]));
level.putQBlock(111, 9, new Mario.Bcoin([1776, 144]));
level.putBrick(117, 9, null);
level.putBrick(120, 5, null);
level.putBrick(121, 5, null);
level.putBrick(122, 5, null);
level.putBrick(123, 5, null);
level.putBrick(128, 5, null);
level.putQBlock(129, 5, new Mario.Bcoin([2074, 80]));
level.putBrick(129, 9, null);
level.putQBlock(130, 5, new Mario.Bcoin([2080, 80]));
level.putBrick(130, 9, null);
level.putBrick(131, 5, null);
level.putWall(134, 13, 1);
level.putWall(135, 13, 2);
level.putWall(136, 13, 3);
level.putWall(137, 13, 4);
level.putWall(140, 13, 4);
level.putWall(141, 13, 3);
level.putWall(142, 13, 2);
level.putWall(143, 13, 1);
level.putWall(148, 13, 1);
level.putWall(149, 13, 2);
level.putWall(150, 13, 3);
level.putWall(151, 13, 4);
level.putWall(152, 13, 4);
level.putWall(155, 13, 4);
level.putWall(156, 13, 3);
level.putWall(157, 13, 2);
level.putWall(158, 13, 1);
level.putPipe(163, 13, 2);
level.putBrick(168, 9, null);
level.putBrick(169, 9, null);
level.putQBlock(170, 9, new Mario.Bcoin([2720, 144]));
level.putBrick(171, 9, null);
level.putPipe(179, 13, 2);
level.putWall(181, 13, 1);
level.putWall(182, 13, 2);
level.putWall(183, 13, 3);
level.putWall(184, 13, 4);
level.putWall(185, 13, 5);
level.putWall(186, 13, 6);
level.putWall(187, 13, 7);
level.putWall(188, 13, 8);
level.putWall(189, 13, 8);
level.putFlagpole(198);
//and enemies
level.putGoomba(22, 12);
level.putGoomba(40, 12);
level.putGoomba(50, 12);
level.putGoomba(51, 12);
level.putGoomba(82, 4);
level.putGoomba(84, 4);
level.putGoomba(100, 12);
level.putGoomba(102, 12);
level.putGoomba(114, 12);
level.putGoomba(115, 12);
level.putGoomba(122, 12);
level.putGoomba(123, 12);
level.putGoomba(125, 12);
level.putGoomba(126, 12);
level.putGoomba(170, 12);
level.putGoomba(172, 12);
level.putKoopa(35, 11);
music.underground.pause();
// music.overworld.currentTime = 0;
music.overworld.play();
});

View File

@@ -0,0 +1,138 @@
var oneonetunnel = (Mario.oneonetunnel = function () {
level = new Mario.Level({
playerPos: [40, 16],
loader: Mario.oneonetunnel,
background: "#000000",
scrolling: false,
coinSprite: function () {
return new Mario.Sprite(
"sprites/items.png",
[0, 96],
[16, 16],
6,
[0, 0, 0, 0, 1, 2, 1],
);
},
floorSprite: new Mario.Sprite(
"sprites/tiles.png",
[0, 32],
[16, 16],
0,
),
wallSprite: new Mario.Sprite(
"sprites/tiles.png",
[32, 32],
[16, 16],
0,
),
brickSprite: new Mario.Sprite(
"sprites/tiles.png",
[16, 0],
[16, 16],
0,
),
brickBounceSprite: new Mario.Sprite(
"sprites/tiles.png",
[32, 0],
[16, 16],
0,
),
ublockSprite: new Mario.Sprite(
"sprites/tiles.png",
[48, 0],
[16, 16],
0,
),
pipeLMidSprite: new Mario.Sprite(
"sprites/tiles.png",
[0, 144],
[16, 16],
0,
),
pipeRMidSprite: new Mario.Sprite(
"sprites/tiles.png",
[16, 144],
[16, 16],
0,
),
pipeLEndSprite: new Mario.Sprite(
"sprites/tiles.png",
[0, 128],
[16, 16],
0,
),
pipeREndSprite: new Mario.Sprite(
"sprites/tiles.png",
[16, 128],
[16, 16],
0,
),
pipeUpMid: new Mario.Sprite("sprites/tiles.png", [0, 144], [32, 16], 0),
pipeSideMid: new Mario.Sprite(
"sprites/tiles.png",
[48, 128],
[16, 32],
0,
),
pipeLeft: new Mario.Sprite("sprites/tiles.png", [32, 128], [16, 32], 0),
pipeTop: new Mario.Sprite("sprites/tiles.png", [0, 128], [32, 16], 0),
LPipeSprites: [
new Mario.Sprite("sprites/tiles.png", [32, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [32, 144], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [48, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [48, 144], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [64, 128], [16, 16], 0),
new Mario.Sprite("sprites/tiles.png", [64, 144], [16, 16], 0),
],
});
player.pos[0] = level.playerPos[0];
player.pos[1] = level.playerPos[1];
vX = 0;
level.putFloor(0, 16);
level.putWall(0, 13, 11);
walls = [4, 5, 6, 7, 8, 9, 10];
walls.forEach(function (loc) {
level.putWall(loc, 13, 3);
level.putWall(loc, 3, 1);
});
coins = [
[5, 5],
[6, 5],
[7, 5],
[8, 5],
[9, 5],
[4, 7],
[5, 7],
[6, 7],
[7, 7],
[8, 7],
[9, 7],
[10, 7],
[4, 9],
[5, 9],
[6, 9],
[7, 9],
[8, 9],
[9, 9],
[10, 9],
];
coins.forEach(function (pos) {
level.putCoin(pos[0], pos[1]);
});
//level.putLeftPipe(13,11);
level.putRealPipe(13, 11, 3, "RIGHT", function () {
Mario.oneone.call();
player.pos = [2616, 177];
player.pipe("UP", function () {});
});
level.putPipe(15, 13, 13);
music.overworld.pause();
music.underground.currentTime = 0;
music.underground.play();
});

View File

@@ -0,0 +1,348 @@
(function () {
var Level = (Mario.Level = function (options) {
this.playerPos = options.playerPos;
this.scrolling = options.scrolling;
this.loader = options.loader;
this.background = options.background;
this.exit = options.exit;
this.floorSprite = options.floorSprite;
this.cloudSprite = options.cloudSprite;
this.wallSprite = options.wallSprite;
this.brickSprite = options.brickSprite;
this.rubbleSprite = options.rubbleSprite;
this.brickBounceSprite = options.brickBounceSprite;
this.ublockSprite = options.ublockSprite;
this.superShroomSprite = options.superShroomSprite;
this.fireFlowerSprite = options.fireFlowerSprite;
this.starSprite = options.starSprite;
this.coinSprite = options.coinSprite;
this.bcoinSprite = options.bcoinSprite;
this.goombaSprite = options.goombaSprite;
this.koopaSprite = options.koopaSprite;
//prop pipe sprites, to be phased out
this.pipeLEndSprite = options.pipeLEndSprite;
this.pipeREndSprite = options.pipeREndSprite;
this.pipeLMidSprite = options.pipeLMidSprite;
this.pipeRMidSprite = options.pipeRMidSprite;
//real pipe sprites, use these.
this.pipeUpMid = options.pipeUpMid;
this.pipeSideMid = options.pipeSideMid;
this.pipeLeft = options.pipeLeft;
this.pipeTop = options.pipeTop;
this.flagpoleSprites = options.flagPoleSprites;
this.LPipeSprites = options.LPipeSprites;
this.cloudSprites = options.cloudSprites;
this.hillSprites = options.hillSprites;
this.bushSprite = options.bushSprite;
this.bushSprites = options.bushSprites;
this.qblockSprite = options.qblockSprite;
this.invincibility = options.invincibility;
this.statics = [];
this.scenery = [];
this.blocks = [];
this.enemies = [];
this.items = [];
this.pipes = [];
for (var i = 0; i < 15; i++) {
this.statics[i] = [];
this.scenery[i] = [];
this.blocks[i] = [];
}
});
Level.prototype.putFloor = function (start, end) {
for (var i = start; i < end; i++) {
this.statics[13][i] = new Mario.Floor(
[16 * i, 208],
this.floorSprite,
);
this.statics[14][i] = new Mario.Floor(
[16 * i, 224],
this.floorSprite,
);
}
};
Level.prototype.putGoomba = function (x, y) {
this.enemies.push(
new Mario.Goomba([16 * x, 16 * y], this.goombaSprite()),
);
};
Level.prototype.putKoopa = function (x, y) {
this.enemies.push(
new Mario.Koopa([16 * x, 16 * y], this.koopaSprite(), false),
);
};
Level.prototype.putWall = function (x, y, height) {
//y is the bottom of the wall in this case.
for (var i = y - height; i < y; i++) {
this.statics[i][x] = new Mario.Floor(
[16 * x, 16 * i],
this.wallSprite,
);
}
};
Level.prototype.putPipe = function (x, y, height) {
for (var i = y - height; i < y; i++) {
if (i === y - height) {
this.statics[i][x] = new Mario.Floor(
[16 * x, 16 * i],
this.pipeLEndSprite,
);
this.statics[i][x + 1] = new Mario.Floor(
[16 * x + 16, 16 * i],
this.pipeREndSprite,
);
} else {
this.statics[i][x] = new Mario.Floor(
[16 * x, 16 * i],
this.pipeLMidSprite,
);
this.statics[i][x + 1] = new Mario.Floor(
[16 * x + 16, 16 * i],
this.pipeRMidSprite,
);
}
}
};
//sometimes, pipes don't go straight up and down.
Level.prototype.putLeftPipe = function (x, y) {
this.statics[y][x] = new Mario.Floor(
[16 * x, 16 * y],
this.LPipeSprites[0],
);
this.statics[y + 1][x] = new Mario.Floor(
[16 * x, 16 * (y + 1)],
this.LPipeSprites[1],
);
this.statics[y][x + 1] = new Mario.Floor(
[16 * (x + 1), 16 * y],
this.LPipeSprites[2],
);
this.statics[y + 1][x + 1] = new Mario.Floor(
[16 * (x + 1), 16 * (y + 1)],
this.LPipeSprites[3],
);
this.statics[y][x + 2] = new Mario.Floor(
[16 * (x + 2), 16 * y],
this.LPipeSprites[4],
);
this.statics[y + 1][x + 2] = new Mario.Floor(
[16 * (x + 2), 16 * (y + 1)],
this.LPipeSprites[5],
);
};
Level.prototype.putCoin = function (x, y) {
this.items.push(new Mario.Coin([x * 16, y * 16], this.coinSprite()));
};
Level.prototype.putCloud = function (x, y) {
this.scenery[y][x] = new Mario.Prop([x * 16, y * 16], this.cloudSprite);
};
Level.prototype.putQBlock = function (x, y, item) {
this.blocks[y][x] = new Mario.Block({
pos: [x * 16, y * 16],
item: item,
sprite: this.qblockSprite,
usedSprite: this.ublockSprite,
});
};
Level.prototype.putBrick = function (x, y, item) {
this.blocks[y][x] = new Mario.Block({
pos: [x * 16, y * 16],
item: item,
sprite: this.brickSprite,
bounceSprite: this.brickBounceSprite,
usedSprite: this.ublockSprite,
breakable: !item,
});
};
Level.prototype.putBigHill = function (x, y) {
var px = x * 16,
py = y * 16;
this.scenery[y][x] = new Mario.Prop([px, py], this.hillSprites[0]);
this.scenery[y][x + 1] = new Mario.Prop(
[px + 16, py],
this.hillSprites[3],
);
this.scenery[y - 1][x + 1] = new Mario.Prop(
[px + 16, py - 16],
this.hillSprites[0],
);
this.scenery[y][x + 2] = new Mario.Prop(
[px + 32, py],
this.hillSprites[4],
);
this.scenery[y - 1][x + 2] = new Mario.Prop(
[px + 32, py - 16],
this.hillSprites[3],
);
this.scenery[y - 2][x + 2] = new Mario.Prop(
[px + 32, py - 32],
this.hillSprites[1],
);
this.scenery[y][x + 3] = new Mario.Prop(
[px + 48, py],
this.hillSprites[5],
);
this.scenery[y - 1][x + 3] = new Mario.Prop(
[px + 48, py - 16],
this.hillSprites[2],
);
this.scenery[y][x + 4] = new Mario.Prop(
[px + 64, py],
this.hillSprites[2],
);
};
Level.prototype.putBush = function (x, y) {
this.scenery[y][x] = new Mario.Prop([x * 16, y * 16], this.bushSprite);
};
Level.prototype.putThreeBush = function (x, y) {
px = x * 16;
py = y * 16;
this.scenery[y][x] = new Mario.Prop([px, py], this.bushSprites[0]);
this.scenery[y][x + 1] = new Mario.Prop(
[px + 16, py],
this.bushSprites[1],
);
this.scenery[y][x + 2] = new Mario.Prop(
[px + 32, py],
this.bushSprites[1],
);
this.scenery[y][x + 3] = new Mario.Prop(
[px + 48, py],
this.bushSprites[1],
);
this.scenery[y][x + 4] = new Mario.Prop(
[px + 64, py],
this.bushSprites[2],
);
};
Level.prototype.putTwoBush = function (x, y) {
px = x * 16;
py = y * 16;
this.scenery[y][x] = new Mario.Prop([px, py], this.bushSprites[0]);
this.scenery[y][x + 1] = new Mario.Prop(
[px + 16, py],
this.bushSprites[1],
);
this.scenery[y][x + 2] = new Mario.Prop(
[px + 32, py],
this.bushSprites[1],
);
this.scenery[y][x + 3] = new Mario.Prop(
[px + 48, py],
this.bushSprites[2],
);
};
Level.prototype.putSmallHill = function (x, y) {
var px = x * 16,
py = y * 16;
this.scenery[y][x] = new Mario.Prop([px, py], this.hillSprites[0]);
this.scenery[y][x + 1] = new Mario.Prop(
[px + 16, py],
this.hillSprites[3],
);
this.scenery[y - 1][x + 1] = new Mario.Prop(
[px + 16, py - 16],
this.hillSprites[1],
);
this.scenery[y][x + 2] = new Mario.Prop(
[px + 32, py],
this.hillSprites[2],
);
};
Level.prototype.putTwoCloud = function (x, y) {
px = x * 16;
py = y * 16;
this.scenery[y][x] = new Mario.Prop([px, py], this.cloudSprites[0]);
this.scenery[y][x + 1] = new Mario.Prop(
[px + 16, py],
this.cloudSprites[1],
);
this.scenery[y][x + 2] = new Mario.Prop(
[px + 32, py],
this.cloudSprites[1],
);
this.scenery[y][x + 3] = new Mario.Prop(
[px + 48, py],
this.cloudSprites[2],
);
};
Level.prototype.putThreeCloud = function (x, y) {
px = x * 16;
py = y * 16;
this.scenery[y][x] = new Mario.Prop([px, py], this.cloudSprites[0]);
this.scenery[y][x + 1] = new Mario.Prop(
[px + 16, py],
this.cloudSprites[1],
);
this.scenery[y][x + 2] = new Mario.Prop(
[px + 32, py],
this.cloudSprites[1],
);
this.scenery[y][x + 3] = new Mario.Prop(
[px + 48, py],
this.cloudSprites[1],
);
this.scenery[y][x + 4] = new Mario.Prop(
[px + 64, py],
this.cloudSprites[2],
);
};
Level.prototype.putRealPipe = function (
x,
y,
length,
direction,
destination,
) {
px = x * 16;
py = y * 16;
this.pipes.push(
new Mario.Pipe({
pos: [px, py],
length: length,
direction: direction,
destination: destination,
}),
);
};
Level.prototype.putFlagpole = function (x) {
this.statics[12][x] = new Mario.Floor([16 * x, 192], this.wallSprite);
for (i = 3; i < 12; i++) {
this.scenery[i][x] = new Mario.Prop(
[16 * x, 16 * i],
this.flagpoleSprites[1],
);
}
this.scenery[2][x] = new Mario.Prop(
[16 * x, 32],
this.flagpoleSprites[0],
);
this.items.push(new Mario.Flag(16 * x));
};
})();

View File

@@ -0,0 +1,132 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Mushroom = (Mario.Mushroom = function (pos) {
this.spawning = false;
this.waiting = 0;
Mario.Entity.call(this, {
pos: pos,
sprite: level.superShroomSprite,
hitbox: [0, 0, 16, 16],
});
});
Mario.Util.inherits(Mushroom, Mario.Entity);
Mushroom.prototype.render = function (ctx, vX, vY) {
if (this.spawning > 1) return;
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Mushroom.prototype.spawn = function () {
if (player.power > 0) {
//replace this with a fire flower
var ff = new Mario.Fireflower(this.pos);
ff.spawn();
return;
}
sounds.itemAppear.play();
this.idx = level.items.length;
level.items.push(this);
this.spawning = 12;
this.targetpos = [];
this.targetpos[0] = this.pos[0];
this.targetpos[1] = this.pos[1] - 16;
};
Mushroom.prototype.update = function (dt) {
if (this.spawning > 1) {
this.spawning -= 1;
if (this.spawning == 1) this.vel[1] = -0.5;
return;
}
if (this.spawning) {
if (this.pos[1] <= this.targetpos[1]) {
this.pos[1] = this.targetpos[1];
this.vel[1] = 0;
this.waiting = 5;
this.spawning = 0;
this.vel[0] = 1;
}
} else {
this.acc[1] = 0.2;
}
if (this.waiting) {
this.waiting -= 1;
} else {
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
this.sprite.update(dt);
}
};
Mushroom.prototype.collideWall = function () {
this.vel[0] = -this.vel[0];
};
Mushroom.prototype.checkCollisions = function () {
if (this.spawning) {
return;
}
var h = this.pos[1] % 16 == 0 ? 1 : 2;
var w = this.pos[0] % 16 == 0 ? 1 : 2;
var baseX = Math.floor(this.pos[0] / 16);
var baseY = Math.floor(this.pos[1] / 16);
if (baseY + h > 15) {
delete level.items[this.idx];
return;
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
if (level.statics[baseY + i][baseX + j]) {
level.statics[baseY + i][baseX + j].isCollideWith(this);
}
if (level.blocks[baseY + i][baseX + j]) {
level.blocks[baseY + i][baseX + j].isCollideWith(this);
}
}
}
this.isPlayerCollided();
};
//we have access to player everywhere, so let's just do this.
Mushroom.prototype.isPlayerCollided = function () {
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [
player.pos[0] + player.hitbox[0],
player.pos[1] + player.hitbox[1],
];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + player.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + player.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
player.powerUp(this.idx);
}
}
};
Mushroom.prototype.bump = function () {
this.vel[1] = -2;
};
})();

228
examples/mario/js/pipe.js Normal file
View File

@@ -0,0 +1,228 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
//there are too many possible configurations of pipe to capture in a reasonable
//set of simple variables. Joints, etc. are just too much.
//To that end, the pipe class handles simple pipes, and we'll put together
//anything more complex with individual props. OK? OK.
Pipe = Mario.Pipe = function (options) {
this.pos = options.pos;
//NOTE: direction is the direction you move INTO the pipe.
this.direction = options.direction;
this.destination = options.destination;
this.length = options.length;
if (this.direction === "UP" || this.direction === "DOWN") {
this.hitbox = [0, 0, 32, this.length * 16];
this.midsection = level.pipeUpMid;
this.endsection = level.pipeTop;
} else {
this.hitbox = [0, 0, 16 * this.length, 32];
this.midsection = level.pipeSideMid;
this.endsection = level.pipeLeft;
}
};
Pipe.prototype.checkPipe = function () {
if (this.destination === undefined || !input.isDown(this.direction))
return;
var h = player.power === 0 ? 16 : 32;
var x = Math.floor(player.pos[0]);
var y = Math.floor(player.pos[1]);
switch (this.direction) {
case "RIGHT":
if (
x === this.pos[0] - 16 &&
y >= this.pos[1] &&
y + h <= this.pos[1] + 32
) {
player.pipe(this.direction, this.destination);
}
break;
case "LEFT":
if (
x === this.pos[0] + 16 * this.length &&
y >= this.pos[1] &&
y + h <= this.pos[1] + 32
) {
player.pipe(this.direction, this.destination);
}
break;
case "UP":
if (
y === this.pos[1] + 16 * this.length &&
x >= this.pos[0] &&
x + 16 <= this.pos[0] + 32
) {
player.pipe(this.direction, this.destination);
}
break;
case "DOWN":
if (
y + h === this.pos[1] &&
x >= this.pos[0] &&
x + 16 <= this.pos[0] + 32
) {
player.pipe(this.direction, this.destination);
}
break;
}
};
//Note to self: next time, decide on a convention for which thing checks for collisions
//and stick to it. This is a pain.
Pipe.prototype.checkCollisions = function () {
var that = this;
level.enemies.forEach(function (ent) {
that.isCollideWith(ent);
});
level.items.forEach(function (ent) {
that.isCollideWith(ent);
});
fireballs.forEach(function (ent) {
that.isCollideWith(ent);
});
if (!player.piping) this.isCollideWith(player);
};
Pipe.prototype.isCollideWith = function (ent) {
//long story short: because we scan every item, and and one 'rubble' item is four things with separate positions
//we'll crash without this line as soon as we destroy a block. OOPS.
if (ent.pos === undefined) return;
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
Math.floor(this.pos[0] + this.hitbox[0]),
Math.floor(this.pos[1] + this.hitbox[1]),
];
var hpos2 = [
Math.floor(ent.pos[0] + ent.hitbox[0]),
Math.floor(ent.pos[1] + ent.hitbox[1]),
];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + ent.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + ent.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
//if the entity is over the block, it's basically floor
var center = hpos2[0] + ent.hitbox[2] / 2;
if (
Math.abs(hpos2[1] + ent.hitbox[3] - hpos1[1]) <= ent.vel[1]
) {
ent.vel[1] = 0;
ent.pos[1] = hpos1[1] - ent.hitbox[3] - ent.hitbox[1];
ent.standing = true;
if (ent instanceof Mario.Player) {
ent.jumping = 0;
}
} else if (
Math.abs(hpos2[1] - hpos1[1] - this.hitbox[3]) >
ent.vel[1] &&
center + 2 >= hpos1[0] &&
center - 2 <= hpos1[0] + this.hitbox[2]
) {
//ent is under the block.
ent.vel[1] = 0;
ent.pos[1] = hpos1[1] + this.hitbox[3];
if (ent instanceof Mario.Player) {
ent.jumping = 0;
}
} else {
//entity is hitting it from the side, we're a wall
ent.collideWall(this);
}
}
}
};
//we COULD try to write some shenanigans so that the check gets put into the
//collision code, but there won't ever be more than a handful of pipes in a level
//so the performance hit of scanning all of them is miniscule.
Pipe.prototype.update = function (dt) {
if (this.destination) this.checkPipe();
};
//http://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array
//I honestly have no idea if javascript does this, but I feel like it makes sense
//stylistically to prefer branching outside of loops when possible as convention
//TODO: edit the spritesheet so UP and LEFT pipes aren't backwards.
Pipe.prototype.render = function (ctx, vX, vY) {
switch (this.direction) {
case "DOWN":
this.endsection.render(ctx, this.pos[0], this.pos[1], vX, vY);
for (var i = 1; i < this.length; i++) {
this.midsection.render(
ctx,
this.pos[0],
this.pos[1] + i * 16,
vX,
vY,
);
}
break;
case "UP":
this.endsection.render(
ctx,
this.pos[0],
this.pos[1] + 16 * (this.length - 1),
vX,
vY,
);
for (var i = 0; i < this.length - 1; i++) {
this.midsection.render(
ctx,
this.pos[0],
this.pos[1] + i * 16,
vX,
vY,
);
}
break;
case "RIGHT":
this.endsection.render(ctx, this.pos[0], this.pos[1], vX, vY);
for (var i = 1; i < this.length; i++) {
this.midsection.render(
ctx,
this.pos[0] + 16 * i,
this.pos[1],
vX,
vY,
);
}
break;
case "LEFT":
this.endsection.render(
ctx,
this.pos[0] + 16 * (this.length - 1),
this.pos[1],
vX,
vY,
);
for (var i = 0; i < this.legth - 1; i++) {
this.midsection.render(
ctx,
this.pos[0],
this.pos[1] + i * 16,
vX,
vY,
);
}
break;
}
};
})();

505
examples/mario/js/player.js Normal file
View File

@@ -0,0 +1,505 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Player = (Mario.Player = function (pos) {
//I know, I know, there are a lot of variables tracking Mario's state.
//Maybe these can be consolidated some way? We'll see once they're all in.
this.power = 0;
this.coins = 0;
this.powering = [];
this.bounce = false;
this.jumping = 0;
this.canJump = true;
this.invincibility = 0;
this.crouching = false;
this.fireballs = 0;
this.runheld = false;
this.noInput = false;
this.targetPos = [];
Mario.Entity.call(this, {
pos: pos,
sprite: new Mario.Sprite(
"sprites/player.png",
[80, 32],
[16, 16],
0,
),
hitbox: [0, 0, 16, 16],
});
});
Mario.Util.inherits(Player, Mario.Entity);
Player.prototype.run = function () {
this.maxSpeed = 2.5;
if (this.power == 2 && !this.runheld) {
this.shoot();
}
this.runheld = true;
};
Player.prototype.shoot = function () {
if (this.fireballs >= 2) return; //Projectile limit!
this.fireballs += 1;
var fb = new Mario.Fireball([this.pos[0] + 8, this.pos[1]]); //I hate you, Javascript.
fb.spawn(this.left);
this.shooting = 2;
};
Player.prototype.noRun = function () {
this.maxSpeed = 1.5;
this.moveAcc = 0.07;
this.runheld = false;
};
Player.prototype.moveRight = function () {
//we're on the ground
if (this.vel[1] === 0 && this.standing) {
if (this.crouching) {
this.noWalk();
return;
}
this.acc[0] = this.moveAcc;
this.left = false;
} else {
this.acc[0] = this.moveAcc;
}
};
Player.prototype.moveLeft = function () {
if (this.vel[1] === 0 && this.standing) {
if (this.crouching) {
this.noWalk();
return;
}
this.acc[0] = -this.moveAcc;
this.left = true;
} else {
this.acc[0] = -this.moveAcc;
}
};
Player.prototype.noWalk = function () {
this.maxSpeed = 0;
if (this.vel[0] === 0) return;
if (Math.abs(this.vel[0]) <= 0.1) {
this.vel[0] = 0;
this.acc[0] = 0;
}
};
Player.prototype.crouch = function () {
if (this.power === 0) {
this.crouching = false;
return;
}
if (this.standing) this.crouching = true;
};
Player.prototype.noCrouch = function () {
this.crouching = false;
};
Player.prototype.jump = function () {
if (this.vel[1] > 0) {
return;
}
if (this.jumping) {
this.jumping -= 1;
} else if (this.standing && this.canJump) {
this.jumping = 20;
this.canJump = false;
this.standing = false;
this.vel[1] = -6;
if (this.power === 0) {
sounds.smallJump.currentTime = 0;
sounds.smallJump.play();
} else {
sounds.bigJump.currentTime = 0;
sounds.bigJump.play();
}
}
};
Player.prototype.noJump = function () {
this.canJump = true;
if (this.jumping) {
if (this.jumping <= 16) {
this.vel[1] = 0;
this.jumping = 0;
} else this.jumping -= 1;
}
};
Player.prototype.setAnimation = function () {
if (this.dying) return;
if (this.starTime) {
var index;
if (this.starTime > 60) index = Math.floor(this.starTime / 2) % 3;
else index = Math.floor(this.starTime / 8) % 3;
this.sprite.pos[1] = level.invincibility[index];
if (this.power == 0) {
this.sprite.pos[1] += 32;
}
this.starTime -= 1;
if (this.starTime == 0) {
switch (this.power) {
case 0:
this.sprite.pos[1] = 32;
break;
case 1:
this.sprite.pos[1] = 0;
break;
case 2:
this.sprite.pos[1] = 96;
break;
}
}
}
//okay cool, now set the sprite
if (this.crouching) {
this.sprite.pos[0] = 176;
this.sprite.speed = 0;
return;
}
if (this.jumping) {
this.sprite.pos[0] = 160;
this.sprite.speed = 0;
} else if (this.standing) {
if (Math.abs(this.vel[0]) > 0) {
if (this.vel[0] * this.acc[0] >= 0) {
this.sprite.pos[0] = 96;
this.sprite.frames = [0, 1, 2];
if (this.vel[0] < 0.2) {
this.sprite.speed = 5;
} else {
this.sprite.speed = Math.abs(this.vel[0]) * 8;
}
} else if (
(this.vel[0] > 0 && this.left) ||
(this.vel[0] < 0 && !this.left)
) {
this.sprite.pos[0] = 144;
this.sprite.speed = 0;
}
} else {
this.sprite.pos[0] = 80;
this.sprite.speed = 0;
}
if (this.shooting) {
this.sprite.pos[0] += 160;
this.shooting -= 1;
}
}
if (this.flagging) {
this.sprite.pos[0] = 192;
this.sprite.frames = [0, 1];
this.sprite.speed = 10;
if (this.vel[1] === 0) this.sprite.frames = [0];
}
//which way are we facing?
if (this.left) {
this.sprite.img = "sprites/playerl.png";
} else {
this.sprite.img = "sprites/player.png";
}
};
Player.prototype.update = function (dt, vX) {
if (this.powering.length !== 0) {
var next = this.powering.shift();
if (next == 5) return;
this.sprite.pos = this.powerSprites[next];
this.sprite.size = this.powerSizes[next];
this.pos[1] += this.shift[next];
if (this.powering.length === 0) {
delete level.items[this.touchedItem];
}
return;
}
if (this.invincibility) {
this.invincibility -= Math.round(dt * 60);
}
if (this.waiting) {
this.waiting -= dt;
if (this.waiting <= 0) {
this.waiting = 0;
} else return;
}
if (this.bounce) {
this.bounce = false;
this.standing = false;
this.vel[1] = -3;
}
if (this.pos[0] <= vX) {
this.pos[0] = vX;
this.vel[0] = Math.max(this.vel[0], 0);
}
if (Math.abs(this.vel[0]) > this.maxSpeed) {
this.vel[0] -= (0.05 * this.vel[0]) / Math.abs(this.vel[0]);
this.acc[0] = 0;
}
if (this.dying) {
if (this.pos[1] < this.targetPos[1]) {
this.vel[1] = 1;
}
this.dying -= 1 * dt;
if (this.dying <= 0) {
player = new Mario.Player(level.playerPos);
level.loader.call();
input.reset();
}
} else {
this.acc[1] = 0.25;
if (this.pos[1] > 240) {
this.die();
}
}
if (this.piping) {
this.acc = [0, 0];
var pos = [Math.round(this.pos[0]), Math.round(this.pos[1])];
if (pos[0] === this.targetPos[0] && pos[1] === this.targetPos[1]) {
this.piping = false;
this.pipeLoc.call();
}
}
if (this.flagging) {
this.acc = [0, 0];
}
if (this.exiting) {
this.left = false;
this.flagging = false;
this.vel[0] = 1.5;
if (this.pos[0] >= this.targetPos[0]) {
this.sprite.size = [0, 0];
this.vel = [0, 0];
window.setTimeout(function () {
player.sprite.size =
player.power === 0 ? [16, 16] : [16, 32];
player.exiting = false;
player.noInput = false;
level.loader();
if (player.power !== 0) player.pos[1] -= 16;
music.overworld.currentTime = 0;
}, 5000);
}
}
//approximate acceleration
this.vel[0] += this.acc[0];
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
this.setAnimation();
this.sprite.update(dt);
};
Player.prototype.checkCollisions = function () {
if (this.piping || this.dying) return;
//x-axis first!
var h = this.power > 0 ? 2 : 1;
var w = 1;
if (this.pos[1] % 16 !== 0) {
h += 1;
}
if (this.pos[0] % 16 !== 0) {
w += 1;
}
var baseX = Math.floor(this.pos[0] / 16);
var baseY = Math.floor(this.pos[1] / 16);
for (var i = 0; i < h; i++) {
if (baseY + i < 0 || baseY + i >= 15) continue;
for (var j = 0; j < w; j++) {
if (baseY < 0) {
i++;
}
if (level.statics[baseY + i][baseX + j]) {
level.statics[baseY + i][baseX + j].isCollideWith(this);
}
if (level.blocks[baseY + i][baseX + j]) {
level.blocks[baseY + i][baseX + j].isCollideWith(this);
}
}
}
};
Player.prototype.powerUp = function (idx) {
sounds.powerup.play();
this.powering = [
0, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 3, 5, 1, 5, 2, 5, 3, 5, 1, 5, 4,
];
this.touchedItem = idx;
if (this.power === 0) {
this.sprite.pos[0] = 80;
var newy = this.sprite.pos[1] - 32;
this.powerSprites = [
[80, newy + 32],
[80, newy + 32],
[320, newy],
[80, newy],
[128, newy],
];
this.powerSizes = [
[16, 16],
[16, 16],
[16, 32],
[16, 32],
[16, 32],
];
this.shift = [0, 16, -16, 0, -16];
this.power = 1;
this.hitbox = [0, 0, 16, 32];
} else if (this.power == 1) {
var curx = this.sprite.pos[0];
this.powerSprites = [
[curx, 96],
[curx, level.invincibility[0]],
[curx, level.invincibility[1]],
[curx, level.invincibility[2]],
[curx, 96],
];
this.powerSizes[([16, 32], [16, 32], [16, 32], [16, 32], [16, 32])];
this.shift = [0, 0, 0, 0, 0];
this.power = 2;
} else {
this.powering = [];
delete level.items[idx];
//no animation, but we play the sound and you get 5000 points.
}
};
Player.prototype.damage = function () {
if (this.power === 0) {
//if you're already small, you dead!
this.die();
} else {
//otherwise, you get turned into small mario
sounds.pipe.play();
this.powering = [
0, 5, 1, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2, 5, 1, 5, 2,
5, 3,
];
this.shift = [0, 16, -16, 16];
this.sprite.pos = [160, 0];
this.powerSprites = [
[160, 0],
[240, 32],
[240, 0],
[160, 32],
];
this.powerSizes = [
[16, 32],
[16, 16],
[16, 32],
[16, 16],
];
this.invincibility = 120;
this.power = 0;
this.hitbox = [0, 0, 16, 16];
}
};
Player.prototype.die = function () {
//TODO: rewrite the way sounds work to emulate the channels of an NES.
music.overworld.pause();
music.underground.pause();
music.overworld.currentTime = 0;
music.death.play();
this.noWalk();
this.noRun();
this.noJump();
this.acc[0] = 0;
this.sprite.pos = [176, 32];
this.sprite.speed = 0;
this.power = 0;
this.waiting = 0.5;
this.dying = 2;
if (this.pos[1] < 240) {
//falling into a pit doesn't do the animation.
this.targetPos = [this.pos[0], this.pos[1] - 128];
this.vel = [0, -5];
} else {
this.vel = [0, 0];
this.targetPos = [this.pos[0], this.pos[1] - 16];
}
};
Player.prototype.star = function (idx) {
delete level.items[idx];
this.starTime = 660;
};
Player.prototype.pipe = function (direction, destination) {
sounds.pipe.play();
this.piping = true;
this.pipeLoc = destination;
switch (direction) {
case "LEFT":
this.vel = [-1, 0];
this.targetPos = [
Math.round(this.pos[0] - 16),
Math.round(this.pos[1]),
];
break;
case "RIGHT":
this.vel = [1, 0];
this.targetPos = [
Math.round(this.pos[0] + 16),
Math.round(this.pos[1]),
];
break;
case "DOWN":
this.vel = [0, 1];
this.targetPos = [
Math.round(this.pos[0]),
Math.round(this.pos[1] + this.hitbox[3]),
];
break;
case "UP":
this.vel = [0, -1];
this.targetPos = [
Math.round(this.pos[0]),
Math.round(this.pos[1] - this.hitbox[3]),
];
break;
}
};
Player.prototype.flag = function () {
this.noInput = true;
this.flagging = true;
this.vel = [0, 2];
this.acc = [0, 0];
};
Player.prototype.exit = function () {
this.pos[0] += 16;
this.targetPos[0] = level.exit * 16;
this.left = true;
this.setAnimation();
this.waiting = 1;
this.exiting = true;
};
})();

14
examples/mario/js/prop.js Normal file
View File

@@ -0,0 +1,14 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
//props do even less than entities, so they don't need to inherit really
var Prop = (Mario.Prop = function (pos, sprite) {
this.pos = pos;
this.sprite = sprite;
});
//but we will be using the same Render, more or less.
Prop.prototype.render = function (ctx, vX, vY) {
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
})();

View File

@@ -1,32 +1,32 @@
//simple resource loader
(function() {
(function () {
var resourceCache = {};
var loading = [];
var readyCallbacks = [];
// Load an image url or an array of image urls
function load(urlOrArr) {
if(urlOrArr instanceof Array) {
urlOrArr.forEach(function(url) {
if (urlOrArr instanceof Array) {
urlOrArr.forEach(function (url) {
_load(url);
});
}
else {
} else {
_load(urlOrArr);
}
}
function _load(url) {
if(resourceCache[url]) {
if (resourceCache[url]) {
return resourceCache[url];
}
else {
} else {
var img = new Image();
img.onload = function() {
img.onload = function () {
resourceCache[url] = img;
if(isReady()) {
readyCallbacks.forEach(function(func) { func(); });
if (isReady()) {
readyCallbacks.forEach(function (func) {
func();
});
}
};
resourceCache[url] = false;
@@ -40,9 +40,8 @@
function isReady() {
var ready = true;
for(var k in resourceCache) {
if(resourceCache.hasOwnProperty(k) &&
!resourceCache[k]) {
for (var k in resourceCache) {
if (resourceCache.hasOwnProperty(k) && !resourceCache[k]) {
ready = false;
}
}
@@ -57,6 +56,6 @@
load: load,
get: get,
onReady: onReady,
isReady: isReady
isReady: isReady,
};
})();

View File

@@ -0,0 +1,64 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
//TODO: make each rubble an entity, use that render and write in Entity.update
var Rubble = (Mario.Rubble = function () {
this.sprites = [];
this.poss = [];
this.vels = [];
});
Rubble.prototype.spawn = function (pos) {
this.idx = level.items.length;
level.items.push(this);
this.sprites[0] = level.rubbleSprite();
this.sprites[1] = level.rubbleSprite();
this.sprites[2] = level.rubbleSprite();
this.sprites[3] = level.rubbleSprite();
this.poss[0] = pos;
this.poss[1] = [pos[0] + 8, pos[1]];
this.poss[2] = [pos[0], pos[1] + 8];
this.poss[3] = [pos[0] + 8, pos[1] + 8];
this.vels[0] = [-1.25, -5];
this.vels[1] = [1.25, -5];
this.vels[2] = [-1.25, -3];
this.vels[3] = [1.25, -3];
};
Rubble.prototype.update = function (dt) {
for (var i = 0; i < 4; i++) {
if (this.sprites[i] === undefined) continue;
this.vels[i][1] += 0.3;
this.poss[i][0] += this.vels[i][0];
this.poss[i][1] += this.vels[i][1];
this.sprites[i].update(dt);
if (this.poss[i][1] > 256) {
delete this.sprites[i];
}
}
if (
this.sprites.every(function (el) {
return !el;
})
) {
delete level.items[this.idx];
}
};
//You might argue that things that can't collide are more like scenery
//but these move and need to be deleted, and i'd rather deal with the 1d array.
Rubble.prototype.checkCollisions = function () {};
Rubble.prototype.render = function () {
for (var i = 0; i < 4; i++) {
if (this.sprites[i] === undefined) continue;
this.sprites[i].render(
ctx,
this.poss[i][0],
this.poss[i][1],
vX,
vY,
);
}
};
})();

View File

@@ -0,0 +1,63 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Sprite = (Mario.Sprite = function (
img,
pos,
size,
speed,
frames,
once,
) {
this.pos = pos;
this.size = size;
this.speed = speed;
this._index = 0;
this.img = img;
this.once = once;
this.frames = frames;
});
Sprite.prototype.update = function (dt, gameTime) {
if (gameTime && gameTime == this.lastUpdated) return;
this._index += this.speed * dt;
if (gameTime) this.lastUpdated = gameTime;
};
Sprite.prototype.setFrame = function (frame) {
this._index = frame;
};
Sprite.prototype.render = function (ctx, posx, posy, vX, vY) {
var frame;
if (this.speed > 0) {
var max = this.frames.length;
var idx = Math.floor(this._index);
frame = this.frames[idx % max];
if (this.once && idx >= max) {
this.done = true;
return;
}
} else {
frame = 0;
}
var x = this.pos[0];
var y = this.pos[1];
x += frame * this.size[0];
ctx.drawImage(
resources.get(this.img),
x + 1 / 3,
y + 1 / 3,
this.size[0] - 2 / 3,
this.size[1] - 2 / 3,
Math.round(posx - vX),
Math.round(posy - vY),
this.size[0],
this.size[1],
);
};
})();

130
examples/mario/js/star.js Normal file
View File

@@ -0,0 +1,130 @@
(function () {
if (typeof Mario === "undefined") window.Mario = {};
var Star = (Mario.Star = function (pos) {
this.spawning = false;
this.waiting = 0;
Mario.Entity.call(this, {
pos: pos,
sprite: level.starSprite,
hitbox: [0, 0, 16, 16],
});
});
Mario.Util.inherits(Star, Mario.Entity);
Star.prototype.render = function (ctx, vX, vY) {
if (this.spawning > 1) return;
this.sprite.render(ctx, this.pos[0], this.pos[1], vX, vY);
};
Star.prototype.spawn = function () {
this.idx = level.items.length;
level.items.push(this);
this.spawning = 12;
this.targetpos = [];
this.targetpos[0] = this.pos[0];
this.targetpos[1] = this.pos[1] - 16;
};
Star.prototype.update = function (dt) {
if (this.spawning > 1) {
this.spawning -= 1;
if (this.spawning == 1) this.vel[1] = -0.5;
return;
}
if (this.spawning) {
if (this.pos[1] <= this.targetpos[1]) {
this.pos[1] = this.targetpos[1];
this.vel[1] = 0;
this.waiting = 5;
this.spawning = 0;
this.vel[0] = 1;
}
} else {
this.acc[1] = 0.2;
}
if (this.standing) {
this.standing = false;
this.vel[1] = -3;
}
if (this.waiting) {
this.waiting -= 1;
} else {
this.vel[1] += this.acc[1];
this.pos[0] += this.vel[0];
this.pos[1] += this.vel[1];
this.sprite.update(dt);
}
};
Star.prototype.collideWall = function () {
this.vel[0] = -this.vel[0];
};
Star.prototype.checkCollisions = function () {
if (this.spawning) {
return;
}
var h = this.pos[1] % 16 == 0 ? 1 : 2;
var w = this.pos[0] % 16 == 0 ? 1 : 2;
var baseX = Math.floor(this.pos[0] / 16);
var baseY = Math.floor(this.pos[1] / 16);
if (baseY + h > 15) {
delete level.items[this.idx];
return;
}
for (var i = 0; i < h; i++) {
for (var j = 0; j < w; j++) {
if (level.statics[baseY + i][baseX + j]) {
level.statics[baseY + i][baseX + j].isCollideWith(this);
}
if (level.blocks[baseY + i][baseX + j]) {
level.blocks[baseY + i][baseX + j].isCollideWith(this);
}
}
}
this.isPlayerCollided();
};
//we have access to player everywhere, so let's just do this.
Star.prototype.isPlayerCollided = function () {
//the first two elements of the hitbox array are an offset, so let's do this now.
var hpos1 = [
this.pos[0] + this.hitbox[0],
this.pos[1] + this.hitbox[1],
];
var hpos2 = [
player.pos[0] + player.hitbox[0],
player.pos[1] + player.hitbox[1],
];
//if the hitboxes actually overlap
if (
!(
hpos1[0] > hpos2[0] + player.hitbox[2] ||
hpos1[0] + this.hitbox[2] < hpos2[0]
)
) {
if (
!(
hpos1[1] > hpos2[1] + player.hitbox[3] ||
hpos1[1] + this.hitbox[3] < hpos2[1]
)
) {
player.star(this.idx);
}
}
};
Star.prototype.bump = function () {
this.vel[1] = -2;
};
})();

14
examples/mario/js/util.js Normal file
View File

@@ -0,0 +1,14 @@
(function () {
if (typeof Mario === "undefined") {
window.Mario = {};
}
var Util = (Mario.Util = {});
Util.inherits = function (subclass, superclass) {
function Surrogate() {}
Surrogate.prototype = superclass.prototype;
subclass.prototype = new Surrogate();
};
})();

View File

@@ -0,0 +1,160 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Mario</title>
<link rel="icon" type="image/png" href="../favicon.png" />
<link
rel="stylesheet"
href="https://pyscript.net/latest/pyscript.css"
/>
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<script type="text/javascript" src="js/util.js"></script>
<script type="text/javascript" src="js/input.js"></script>
<script type="text/javascript" src="js/resources.js"></script>
<script type="text/javascript" src="js/sprite.js"></script>
<script type="text/javascript" src="js/entity.js"></script>
<script type="text/javascript" src="js/pipe.js"></script>
<script type="text/javascript" src="js/mushroom.js"></script>
<script type="text/javascript" src="js/fireflower.js"></script>
<script type="text/javascript" src="js/star.js"></script>
<script type="text/javascript" src="js/fireball.js"></script>
<script type="text/javascript" src="js/coin.js"></script>
<script type="text/javascript" src="js/bcoin.js"></script>
<script type="text/javascript" src="js/goomba.js"></script>
<script type="text/javascript" src="js/koopa.js"></script>
<script type="text/javascript" src="js/floor.js"></script>
<script type="text/javascript" src="js/block.js"></script>
<script type="text/javascript" src="js/rubble.js"></script>
<script type="text/javascript" src="js/prop.js"></script>
<script type="text/javascript" src="js/player.js"></script>
<script type="text/javascript" src="js/flag.js"></script>
<script type="text/javascript" src="js/levels/level.js"></script>
<script type="text/javascript" src="js/levels/11.js"></script>
<script type="text/javascript" src="js/levels/11tunnel.js"></script>
<script type="text/javascript" src="js/game.js"></script>
<py-script>
from js import handTrack, setTimeout, requestAnimationFrame, player
from pyodide import create_once_callable
import asyncio
update_note = Element("update-note")
canvas = Element("canvas")
video = Element("myvideo")
context = canvas.element.getContext("2d")
isVideo = False
model = None
last_position = 0
direction = "stop"
modelParams = {
"flipHorizontal": True, # flip e.g for video
"maxNumBoxes": 20, # maximum number of boxes to detect
"iouThreshold": 0.5, # ioU threshold for non-max suppression
"scoreThreshold": 0.6, # confidence threshold for predictions.
}
def toggle_video():
global isVideo
player.jump()
if (not isVideo):
update_note.write("Starting video")
pyscript.run_until_complete(start_video())
else:
update_note.write("Stopping video")
handTrack.stopVideo(video.element)
isVideo = False
update_note.write("Video stopped")
async def start_video():
global isVideo
update_note.write("Inside start video")
status = await handTrack.startVideo(video.element)
console.log("video started", status)
if status:
update_note.write("Video started. Now tracking")
isVideo = True
console.log( "Calling RUN DETECTION")
y = await run_detection()
else:
update_note.write( "Please enable video")
def sync_run_detection(evt):
pyscript.run_until_complete(run_detection())
async def run_detection():
global model
global isVideo
global last_position
global direction
predictions = await model.detect(video.element)
model.renderPredictions(predictions, canvas.element, context, video.element);
if predictions:
curr_position = predictions[0].bbox[0] + (predictions[0].bbox[2] / 2)
delta = last_position - curr_position
last_position = curr_position
#console.log(delta, curr_position, last_position)
if abs(delta) < 2:
direction = "stop"
elif delta > 0:
direction = "left"
else:
direction = "right"
for prediction in predictions:
if prediction.label == 'open':
player.jump()
elif prediction.label == 'close':
player.crouch()
if (isVideo):
await requestAnimationFrame(create_once_callable(sync_run_detection));
def handle_model(lmodel):
global model
model = lmodel
update_note.write("Loaded Model!")
async def start():
model = await handTrack.load(modelParams)#.then(handle_model)
handle_model(model)
pyscript.run_until_complete(start())
</py-script>
<div class="mb10">
<p>
Use < > to move, ↓ to crouch and x to jump. If video is enabled,
say hi to jump as well!
</p>
<button
id="trackbutton"
class="bx--btn bx--btn--secondary"
type="button"
py-click="toggle_video()"
>
Start Video
</button>
<div id="update-note" py-mount class="updatenote mt10">
loading model ..
</div>
</div>
<div>
<video autoplay="autoplay" id="myvideo" py-mount="video"></video>
<canvas id="canvas" py-mount class="border canvasbox"></canvas>
</div>
<script src="../handtrack/lib/handtrack.min.js"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More