mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 10:17:23 -05:00
Py editor (#1860)
* added a *py-editor* plugin based on *codemirror* * use a `<script type="py-editor">` wrapper to bootstrap code * tested that all is good via smoke-test in test/py-editor.html
This commit is contained in:
committed by
GitHub
parent
8b6b055681
commit
40e99abbdf
219
pyscript.core/package-lock.json
generated
219
pyscript.core/package-lock.json
generated
@@ -11,21 +11,17 @@
|
||||
"dependencies": {
|
||||
"@ungap/with-resolvers": "^0.1.0",
|
||||
"basic-devtools": "^0.1.6",
|
||||
"polyscript": "^0.6.2",
|
||||
"sticky-module": "^0.1.1",
|
||||
"to-json-callback": "^0.1.1",
|
||||
"type-checked-collections": "^0.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.40.1",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@webreflection/toml-j0.4": "^1.1.3",
|
||||
"@xterm/addon-fit": "^0.9.0-beta.1",
|
||||
"chokidar": "^3.5.3",
|
||||
"eslint": "^8.54.0",
|
||||
"rollup": "^4.6.1",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-string": "^3.0.0",
|
||||
"static-handler": "^0.4.3",
|
||||
@@ -43,6 +39,100 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.11.0.tgz",
|
||||
"integrity": "sha512-LCPH3W+hl5vcO7OzEQgX6NpKuKVyiKFLGAy7FXROF6nUpsWUdQEgUb3fe/g7B0E1KZCRFfgzdKASt6Wly2UOBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/commands": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.0.tgz",
|
||||
"integrity": "sha512-tFfcxRIlOWiQDFhjBSWJ10MxcvbCIsRr6V64SgrcaY0MwNk32cUOcCuNlWo8VjV4qRQCgNgUAnIeo0svkk4R5Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.2.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-python": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.3.tgz",
|
||||
"integrity": "sha512-S9w2Jl74hFlD5nqtUMIaXAq9t5WlM0acCkyuQWUUSvZclk1sV+UfnpFiZzuZSG+hfEaOmxKR5UxY/Uxswn7EhQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.3.2",
|
||||
"@codemirror/language": "^6.8.0",
|
||||
"@lezer/python": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/language": {
|
||||
"version": "6.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.9.2.tgz",
|
||||
"integrity": "sha512-QGTQXSpAKDIzaSE96zNK1UfIUhPgkT1CLjh1N5qVzZuxgsEOhz5RqaN8QCIdyOQklGLx3MgHd9YrE3X3+Pl1ow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.1.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lint": {
|
||||
"version": "6.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.2.tgz",
|
||||
"integrity": "sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/search": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.4.tgz",
|
||||
"integrity": "sha512-YoTrvjv9e8EbPs58opjZKyJ3ewFrVSUzQ/4WXlULQLSDDr1nGPJ67mMXFNNVYwdFhybzhrzrtqgHmtpJwIF+8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.3.1.tgz",
|
||||
"integrity": "sha512-88e4HhMtKJyw6fKprGaN/yZfiaoGYOi2nM45YCUC6R/kex9sxFWBDGatS1vk4lMgnWmdIIB9tk8Gj1LmL8YfvA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.22.0.tgz",
|
||||
"integrity": "sha512-6zLj4YIoIpfTGKrDMTbeZRpa8ih4EymMCKmddEDcJWrCdp/N1D46B38YEz4creTb4T177AVS9EyXkLeC/HL2jA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.1.4",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
@@ -190,6 +280,40 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/common": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.1.1.tgz",
|
||||
"integrity": "sha512-aAPB9YbvZHqAW+bIwiuuTDGB4DG0sYNRObGLxud8cW7osw1ZQxfDuTZ8KQiqfZ0QJGcR34CvpTMDXEyo/+Htgg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@lezer/highlight": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
|
||||
"integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/lr": {
|
||||
"version": "1.3.14",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.14.tgz",
|
||||
"integrity": "sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/python": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.9.tgz",
|
||||
"integrity": "sha512-8Ua3p8NdICXR6qWvRCnCx5CI1B0DklZGNtRLwOrIS/OHecHIugRHZyr0NsaaQO2H2Nn34EPlRtltXIirLsry5Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
@@ -375,9 +499,6 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.6.1.tgz",
|
||||
"integrity": "sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -388,9 +509,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.6.1.tgz",
|
||||
"integrity": "sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -401,9 +519,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.6.1.tgz",
|
||||
"integrity": "sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -414,9 +529,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.6.1.tgz",
|
||||
"integrity": "sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -427,9 +539,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.6.1.tgz",
|
||||
"integrity": "sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@@ -440,9 +549,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.6.1.tgz",
|
||||
"integrity": "sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -453,9 +559,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.6.1.tgz",
|
||||
"integrity": "sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -466,9 +569,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.6.1.tgz",
|
||||
"integrity": "sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -479,9 +579,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.6.1.tgz",
|
||||
"integrity": "sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -492,9 +589,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.6.1.tgz",
|
||||
"integrity": "sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -505,9 +599,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.6.1.tgz",
|
||||
"integrity": "sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -518,9 +609,6 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.6.1.tgz",
|
||||
"integrity": "sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -858,6 +946,21 @@
|
||||
"plain-tag": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/codemirror": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/commands": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/search": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/coincident": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/coincident/-/coincident-1.1.0.tgz",
|
||||
@@ -926,6 +1029,12 @@
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
@@ -2242,9 +2351,6 @@
|
||||
}
|
||||
},
|
||||
"node_modules/polyscript": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.6.2.tgz",
|
||||
"integrity": "sha512-JL3aIodfdXVQy65iPqjPxbSHzSGJdyf5Z9CuESZVJobcOcOvymjFgsZeoktz0e6PHqM4YSggtKQ9bN9HzlgMBg==",
|
||||
"dependencies": {
|
||||
"@ungap/structured-clone": "^1.2.0",
|
||||
"@ungap/with-resolvers": "^0.1.0",
|
||||
@@ -2941,9 +3047,6 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.6.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.6.1.tgz",
|
||||
"integrity": "sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
@@ -2953,18 +3056,6 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.6.1",
|
||||
"@rollup/rollup-android-arm64": "4.6.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.6.1",
|
||||
"@rollup/rollup-darwin-x64": "4.6.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.6.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.6.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.6.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.6.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.6.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.6.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.6.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.6.1",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@@ -3210,6 +3301,12 @@
|
||||
"integrity": "sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/style-mod": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.0.tgz",
|
||||
"integrity": "sha512-Ca5ib8HrFn+f+0n4N4ScTIA9iTOQ7MaGS1ylHcoVqW9J7w2w8PzN6g9gKmTYgGEBH8e120+RCmhpje6jC5uGWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/stylehacks": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
|
||||
@@ -3405,6 +3502,12 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
"build:plugins": "node rollup/plugins.cjs",
|
||||
"build:stdlib": "node rollup/stdlib.cjs",
|
||||
"build:3rd-party": "node rollup/3rd-party.cjs",
|
||||
"clean:3rd-party": "rm src/3rd-party/*.js && rm src/3rd-party/*.css",
|
||||
"test:mpy": "static-handler --coi . 2>/dev/null & SH_PID=$!; EXIT_CODE=0; playwright test --fully-parallel test/ || EXIT_CODE=$?; kill $SH_PID 2>/dev/null; exit $EXIT_CODE",
|
||||
"dev": "node dev.cjs",
|
||||
"release": "npm run build && npm run zip",
|
||||
"size": "echo -e \"\\033[1mdist/*.js file size\\033[0m\"; for js in $(ls dist/*.js); do echo -e \"\\033[2m$js:\\033[0m $(cat $js | brotli | wc -c) bytes\"; done",
|
||||
"ts": "tsc -p .",
|
||||
"size": "echo -e \"\\033[1mdist/*.js file size\\033[0m\"; for js in $(ls dist/*.js); do cat $js | brotli > ._; echo -e \"\\033[2m$js:\\033[0m $(du -h --apparent-size ._ | sed -e 's/[[:space:]]*._//')\"; rm ._; done",
|
||||
"ts": "rm -rf types && tsc -p .",
|
||||
"zip": "zip -r dist.zip ./dist"
|
||||
},
|
||||
"keywords": [
|
||||
@@ -47,15 +48,21 @@
|
||||
"type-checked-collections": "^0.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.40.1",
|
||||
"@codemirror/commands": "^6.3.0",
|
||||
"@codemirror/lang-python": "^6.1.3",
|
||||
"@codemirror/language": "^6.9.2",
|
||||
"@codemirror/state": "^6.3.1",
|
||||
"@codemirror/view": "^6.22.0",
|
||||
"@playwright/test": "^1.39.0",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@webreflection/toml-j0.4": "^1.1.3",
|
||||
"@xterm/addon-fit": "^0.9.0-beta.1",
|
||||
"chokidar": "^3.5.3",
|
||||
"eslint": "^8.54.0",
|
||||
"rollup": "^4.6.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"eslint": "^8.53.0",
|
||||
"rollup": "^4.4.1",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-string": "^3.0.0",
|
||||
"static-handler": "^0.4.3",
|
||||
|
||||
@@ -10,6 +10,9 @@ const { devDependencies } = require(join(__dirname, "..", "package.json"));
|
||||
|
||||
const v = (name) => devDependencies[name].replace(/[^\d.]/g, "");
|
||||
|
||||
const dropSourceMap = (str) =>
|
||||
str.replace(/^\/.+? sourceMappingURL=\/.+$/m, "");
|
||||
|
||||
// Fetch a module via jsdelivr CDN `/+esm` orchestration
|
||||
// then sanitize the resulting outcome to avoid importing
|
||||
// anything via `/npm/...` through Rollup
|
||||
@@ -31,25 +34,41 @@ const resolve = (name) => {
|
||||
);
|
||||
};
|
||||
|
||||
// create a file rollup can then process and understand
|
||||
const reBundle = (name) => Promise.resolve(`export * from "${name}";\n`);
|
||||
|
||||
// key/value pairs as:
|
||||
// "3rd-party/file-name.js"
|
||||
// string as content or
|
||||
// Promise<string> as resolved content
|
||||
const modules = {
|
||||
// toml
|
||||
"toml.js": join(node_modules, "@webreflection", "toml-j0.4", "toml.js"),
|
||||
|
||||
// xterm
|
||||
"xterm.js": resolve("xterm"),
|
||||
"xterm.css": fetch(`${CDN}/xterm@${v("xterm")}/css/xterm.min.css`).then(
|
||||
(b) => b.text(),
|
||||
),
|
||||
"xterm-readline.js": resolve("xterm-readline"),
|
||||
"xterm_addon-fit.js": fetch(`${CDN}/@xterm/addon-fit/+esm`).then((b) =>
|
||||
b.text(),
|
||||
),
|
||||
"xterm.css": fetch(`${CDN}/xterm@${v("xterm")}/css/xterm.min.css`).then(
|
||||
(b) => b.text(),
|
||||
),
|
||||
|
||||
// codemirror
|
||||
"codemirror.js": reBundle("codemirror"),
|
||||
"codemirror_state.js": reBundle("@codemirror/state"),
|
||||
"codemirror_lang-python.js": reBundle("@codemirror/lang-python"),
|
||||
"codemirror_language.js": reBundle("@codemirror/language"),
|
||||
"codemirror_view.js": reBundle("@codemirror/view"),
|
||||
"codemirror_commands.js": reBundle("@codemirror/commands"),
|
||||
};
|
||||
|
||||
for (const [target, source] of Object.entries(modules)) {
|
||||
if (typeof source === "string") copyFileSync(source, join(targets, target));
|
||||
else {
|
||||
source.then((text) => writeFileSync(join(targets, target), text));
|
||||
source.then((text) =>
|
||||
writeFileSync(join(targets, target), dropSourceMap(text)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
228
pyscript.core/src/plugins/py-editor.js
Normal file
228
pyscript.core/src/plugins/py-editor.js
Normal file
@@ -0,0 +1,228 @@
|
||||
// PyScript py-editor plugin
|
||||
import { Hook, XWorker, dedent } from "polyscript/exports";
|
||||
import { TYPES } from "../core.js";
|
||||
|
||||
const RUN_BUTTON = `<svg style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>`;
|
||||
|
||||
let id = 0;
|
||||
const getID = (type) => `${type}-editor-${id++}`;
|
||||
|
||||
const envs = new Map();
|
||||
|
||||
const hooks = {
|
||||
worker: {
|
||||
// works on both Pyodide and MicroPython
|
||||
onReady: ({ runAsync, io }, { sync }) => {
|
||||
io.stdout = (line) => sync.write(line);
|
||||
io.stderr = (line) => sync.writeErr(line);
|
||||
sync.revoke();
|
||||
sync.runAsync = runAsync;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
async function execute({ currentTarget }) {
|
||||
const { env, pySrc, outDiv } = this;
|
||||
|
||||
currentTarget.disabled = true;
|
||||
outDiv.innerHTML = "";
|
||||
|
||||
if (!envs.has(env)) {
|
||||
const srcLink = URL.createObjectURL(new Blob([""]));
|
||||
const xworker = XWorker.call(new Hook(null, hooks), srcLink, {
|
||||
type: this.interpreter,
|
||||
});
|
||||
|
||||
const { sync } = xworker;
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
envs.set(env, promise);
|
||||
sync.revoke = () => {
|
||||
URL.revokeObjectURL(srcLink);
|
||||
resolve(xworker);
|
||||
};
|
||||
}
|
||||
|
||||
// wait for the env then set the target div
|
||||
// before executing the current code
|
||||
envs.get(env).then((xworker) => {
|
||||
xworker.onerror = ({ error }) => {
|
||||
outDiv.innerHTML += `<span style='color:red'>${
|
||||
error.message || error
|
||||
}</span>`;
|
||||
console.log(error);
|
||||
};
|
||||
|
||||
const enable = () => {
|
||||
currentTarget.disabled = false;
|
||||
};
|
||||
const { sync } = xworker;
|
||||
sync.write = (str) => {
|
||||
outDiv.innerText += str;
|
||||
};
|
||||
sync.writeErr = (str) => {
|
||||
outDiv.innerHTML += `<span style='color:red'>${str}</span>`;
|
||||
};
|
||||
sync.runAsync(pySrc).then(enable, enable);
|
||||
});
|
||||
}
|
||||
|
||||
const makeRunButton = (listener, type) => {
|
||||
const runButton = document.createElement("button");
|
||||
runButton.className = `absolute ${type}-editor-run-button`;
|
||||
runButton.innerHTML = RUN_BUTTON;
|
||||
runButton.setAttribute("aria-label", "Python Script Run Button");
|
||||
runButton.addEventListener("click", listener);
|
||||
return runButton;
|
||||
};
|
||||
|
||||
const makeEditorDiv = (listener, type) => {
|
||||
const editorDiv = document.createElement("div");
|
||||
editorDiv.className = `${type}-editor-input`;
|
||||
editorDiv.setAttribute("aria-label", "Python Script Area");
|
||||
|
||||
const runButton = makeRunButton(listener, type);
|
||||
const editorShadowContainer = document.createElement("div");
|
||||
|
||||
// avoid outer elements intercepting key events (reveal as example)
|
||||
editorShadowContainer.addEventListener("keydown", (event) => {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
editorDiv.append(editorShadowContainer, runButton);
|
||||
|
||||
return editorDiv;
|
||||
};
|
||||
|
||||
const makeOutDiv = (type) => {
|
||||
const outDiv = document.createElement("div");
|
||||
outDiv.className = `${type}-editor-output`;
|
||||
outDiv.id = `${getID(type)}-output`;
|
||||
return outDiv;
|
||||
};
|
||||
|
||||
const makeBoxDiv = (listener, type) => {
|
||||
const boxDiv = document.createElement("div");
|
||||
boxDiv.className = `${type}-editor-box`;
|
||||
|
||||
const editorDiv = makeEditorDiv(listener, type);
|
||||
const outDiv = makeOutDiv(type);
|
||||
boxDiv.append(editorDiv, outDiv);
|
||||
|
||||
return [boxDiv, outDiv];
|
||||
};
|
||||
|
||||
const init = async (script, type, interpreter) => {
|
||||
const [
|
||||
{ basicSetup, EditorView },
|
||||
{ Compartment },
|
||||
{ python },
|
||||
{ indentUnit },
|
||||
{ keymap },
|
||||
{ defaultKeymap },
|
||||
] = await Promise.all([
|
||||
// TODO: find a way to actually produce these bundles locally
|
||||
import(/* webpackIgnore: true */ "../3rd-party/codemirror.js"),
|
||||
import(/* webpackIgnore: true */ "../3rd-party/codemirror_state.js"),
|
||||
import(
|
||||
/* webpackIgnore: true */ "../3rd-party/codemirror_lang-python.js"
|
||||
),
|
||||
import(/* webpackIgnore: true */ "../3rd-party/codemirror_language.js"),
|
||||
import(/* webpackIgnore: true */ "../3rd-party/codemirror_view.js"),
|
||||
import(/* webpackIgnore: true */ "../3rd-party/codemirror_commands.js"),
|
||||
]);
|
||||
|
||||
const selector = script.getAttribute("target");
|
||||
|
||||
let target;
|
||||
if (selector) {
|
||||
target =
|
||||
document.getElementById(selector) ||
|
||||
document.querySelector(selector);
|
||||
if (!target) throw new Error(`Unknown target ${selector}`);
|
||||
} else {
|
||||
target = document.createElement(`${type}-editor`);
|
||||
target.style.display = "block";
|
||||
script.after(target);
|
||||
}
|
||||
|
||||
if (!target.id) target.id = getID(type);
|
||||
if (!target.hasAttribute("exec-id")) target.setAttribute("exec-id", 0);
|
||||
if (!target.hasAttribute("root")) target.setAttribute("root", target.id);
|
||||
|
||||
const env = `${interpreter}-${script.getAttribute("env") || getID(type)}`;
|
||||
const context = {
|
||||
interpreter,
|
||||
env,
|
||||
get pySrc() {
|
||||
return editor.state.doc.toString();
|
||||
},
|
||||
get outDiv() {
|
||||
return outDiv;
|
||||
},
|
||||
};
|
||||
|
||||
// @see https://github.com/JeffersGlass/mkdocs-pyscript/blob/main/mkdocs_pyscript/js/makeblocks.js
|
||||
const listener = execute.bind(context);
|
||||
const [boxDiv, outDiv] = makeBoxDiv(listener, type);
|
||||
|
||||
const inputChild = boxDiv.querySelector(`.${type}-editor-input > div`);
|
||||
const parent = inputChild.attachShadow({ mode: "open" });
|
||||
// avoid inheriting styles from the outer component
|
||||
parent.innerHTML = `<style> :host { all: initial; }</style>`;
|
||||
|
||||
target.appendChild(boxDiv);
|
||||
|
||||
const doc = dedent(script.textContent).trim();
|
||||
|
||||
// preserve user indentation, if any
|
||||
const indentation = /^(\s+)/m.test(doc) ? RegExp.$1 : " ";
|
||||
|
||||
const editor = new EditorView({
|
||||
extensions: [
|
||||
indentUnit.of(indentation),
|
||||
new Compartment().of(python()),
|
||||
keymap.of([
|
||||
...defaultKeymap,
|
||||
{ key: "Ctrl-Enter", run: listener, preventDefault: true },
|
||||
{ key: "Cmd-Enter", run: listener, preventDefault: true },
|
||||
{ key: "Shift-Enter", run: listener, preventDefault: true },
|
||||
]),
|
||||
basicSetup,
|
||||
],
|
||||
parent,
|
||||
doc,
|
||||
});
|
||||
|
||||
editor.focus();
|
||||
};
|
||||
|
||||
// avoid too greedy MutationObserver operations at distance
|
||||
let timeout = 0;
|
||||
|
||||
// reset interval value then check for new scripts
|
||||
const resetTimeout = () => {
|
||||
timeout = 0;
|
||||
pyEditor();
|
||||
};
|
||||
|
||||
// triggered both ASAP on the living DOM and via MutationObserver later
|
||||
const pyEditor = async () => {
|
||||
if (timeout) return;
|
||||
timeout = setTimeout(resetTimeout, 250);
|
||||
for (const [type, interpreter] of TYPES) {
|
||||
const selector = `script[type="${type}-editor"]`;
|
||||
for (const script of document.querySelectorAll(selector)) {
|
||||
// avoid any further bootstrap
|
||||
script.type += "-active";
|
||||
await init(script, type, interpreter);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
new MutationObserver(pyEditor).observe(document, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
// try to check the current document ASAP
|
||||
export default pyEditor();
|
||||
53
pyscript.core/test/py-editor.html
Normal file
53
pyscript.core/test/py-editor.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>PyTerminal</title>
|
||||
<link rel="stylesheet" href="../dist/core.css">
|
||||
<script type="module" src="../dist/core.js"></script>
|
||||
<style>
|
||||
.py-editor-box, .mpy-editor-box {
|
||||
padding: .5rem;
|
||||
position: relative;
|
||||
}
|
||||
.py-editor-run-button, .mpy-editor-run-button {
|
||||
position: absolute;
|
||||
right: .5rem;
|
||||
top: .5rem;
|
||||
opacity: 0;
|
||||
transition: opacity .25s;
|
||||
}
|
||||
.py-editor-box:hover .py-editor-run-button,
|
||||
.mpy-editor-box:hover .mpy-editor-run-button,
|
||||
.py-editor-run-button:focus,
|
||||
.py-editor-run-button:disabled,
|
||||
.mpy-editor-run-button:focus,
|
||||
.mpy-editor-run-button:disabled {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="py-editor">
|
||||
import sys
|
||||
print(sys.version)
|
||||
</script>
|
||||
<script type="mpy-editor">
|
||||
import sys
|
||||
print(sys.version)
|
||||
a = 42
|
||||
</script>
|
||||
<script type="mpy-editor" env="shared">
|
||||
if not 'a' in globals():
|
||||
a = 1
|
||||
else:
|
||||
a += 1
|
||||
print(a)
|
||||
</script>
|
||||
<script type="mpy-editor" env="shared">
|
||||
# doubled a
|
||||
print(a * 2)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1
pyscript.core/types/3rd-party/codemirror.d.ts
vendored
Normal file
1
pyscript.core/types/3rd-party/codemirror.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "codemirror";
|
||||
1
pyscript.core/types/3rd-party/codemirror_commands.d.ts
vendored
Normal file
1
pyscript.core/types/3rd-party/codemirror_commands.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "@codemirror/commands";
|
||||
1
pyscript.core/types/3rd-party/codemirror_lang-python.d.ts
vendored
Normal file
1
pyscript.core/types/3rd-party/codemirror_lang-python.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "@codemirror/lang-python";
|
||||
1
pyscript.core/types/3rd-party/codemirror_language.d.ts
vendored
Normal file
1
pyscript.core/types/3rd-party/codemirror_language.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "@codemirror/language";
|
||||
1
pyscript.core/types/3rd-party/codemirror_state.d.ts
vendored
Normal file
1
pyscript.core/types/3rd-party/codemirror_state.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "@codemirror/state";
|
||||
1
pyscript.core/types/3rd-party/codemirror_view.d.ts
vendored
Normal file
1
pyscript.core/types/3rd-party/codemirror_view.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "@codemirror/view";
|
||||
1
pyscript.core/types/plugins.d.ts
vendored
1
pyscript.core/types/plugins.d.ts
vendored
@@ -1,6 +1,7 @@
|
||||
declare const _default: {
|
||||
"deprecations-manager": () => Promise<typeof import("./plugins/deprecations-manager.js")>;
|
||||
error: () => Promise<typeof import("./plugins/error.js")>;
|
||||
"py-editor": () => Promise<typeof import("./plugins/py-editor.js")>;
|
||||
"py-terminal": () => Promise<typeof import("./plugins/py-terminal.js")>;
|
||||
};
|
||||
export default _default;
|
||||
|
||||
2
pyscript.core/types/plugins/py-editor.d.ts
vendored
Normal file
2
pyscript.core/types/plugins/py-editor.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
declare const _default: Promise<void>;
|
||||
export default _default;
|
||||
12
pyscript.core/types/toml.d.ts
vendored
12
pyscript.core/types/toml.d.ts
vendored
@@ -1,12 +0,0 @@
|
||||
/*! (c) Jak Wings - MIT */ declare class e extends SyntaxError {
|
||||
constructor(r: any, { offset: t, line: e, column: n }: {
|
||||
offset: any;
|
||||
line: any;
|
||||
column: any;
|
||||
});
|
||||
offset: any;
|
||||
line: any;
|
||||
column: any;
|
||||
}
|
||||
declare function n(n: any): any;
|
||||
export { e as SyntaxError, n as parse };
|
||||
1
pyscript.core/types/utils.d.ts
vendored
1
pyscript.core/types/utils.d.ts
vendored
@@ -1 +0,0 @@
|
||||
export function htmlDecode(html: any): string;
|
||||
Reference in New Issue
Block a user