diff --git a/.github/styles/Vocab/LeaningTechnologies/accept.txt b/.github/styles/Vocab/LeaningTechnologies/accept.txt index 3fa6b777..99e07aff 100644 --- a/.github/styles/Vocab/LeaningTechnologies/accept.txt +++ b/.github/styles/Vocab/LeaningTechnologies/accept.txt @@ -4,6 +4,8 @@ CheerpJ CheerpX WebVM CheerpJ Applet Runner +cjCall +cjNew Astro Yarn @@ -15,3 +17,30 @@ Web Workers APIs CMake toolchain +gzip +iText +ProGuard +profiler +preload +preloader +preloading +preloaded +params +classpath +devtools +PDFs +transpiler +async +interoperate +minimalistic +codegen +filesystem +namespace +untyped +virtualized +methodName +resolvedMethod +preloadResources + + + diff --git a/astro.config.mjs b/astro.config.mjs index 9496987c..40fbfe32 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -6,12 +6,14 @@ import robotsTxt from "astro-robots-txt"; import pagefind from "astro-pagefind"; import svelte from "@astrojs/svelte"; import prefetch from "@astrojs/prefetch"; +import astroExpressiveCode from "astro-expressive-code"; const prod = process.env.NODE_ENV === "production"; // https://astro.build/config export default defineConfig({ site: "https://labs.leaningtech.com", integrations: [ + astroExpressiveCode(), mdx(), sitemap(), tailwind(), diff --git a/package.json b/package.json index 1fa99e25..9ed1fba0 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@astrojs/tailwind": "^4.0.0", "@tailwindcss/typography": "^0.5.9", "astro": "^2.8.5", + "astro-expressive-code": "^0.22.2", "astro-icon": "^0.8.1", "astro-pagefind": "^1.2.3", "astro-robots-txt": "^0.5.0", @@ -30,13 +31,15 @@ "devDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": "^0.11.0", + "prettier-plugin-svelte": "^3.0.3", "typescript": "^5.1.6" }, "prettier": { "trailingComma": "all", "useTabs": true, "plugins": [ - "prettier-plugin-astro" + "prettier-plugin-astro", + "prettier-plugin-svelte" ], "overrides": [ { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5109658e..0f933beb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,6 +29,9 @@ dependencies: astro: specifier: ^2.8.5 version: 2.8.5 + astro-expressive-code: + specifier: ^0.22.2 + version: 0.22.2(astro@2.8.5) astro-icon: specifier: ^0.8.1 version: 0.8.1 @@ -55,6 +58,9 @@ devDependencies: prettier-plugin-astro: specifier: ^0.11.0 version: 0.11.0 + prettier-plugin-svelte: + specifier: ^3.0.3 + version: 3.0.3(prettier@3.0.0)(svelte@4.1.2) typescript: specifier: ^5.1.6 version: 5.1.6 @@ -72,7 +78,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - dev: false /@astrojs/compiler@1.5.6: resolution: {integrity: sha512-gtcpm20y4EUUQNc7evn+ffSJLTlrZRKfBS6kT7r1aB9u+AAeP2BZIiyuSdgXJUS679pCV4sqbM80u8Iek575lg==} @@ -460,6 +465,11 @@ packages: to-fast-properties: 2.0.0 dev: false + /@ctrl/tinycolor@3.6.1: + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + dev: false + /@emmetio/abbreviation@2.3.3: resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==} dependencies: @@ -872,6 +882,38 @@ packages: dev: false optional: true + /@expressive-code/core@0.22.2: + resolution: {integrity: sha512-fVfnopl4dz75KgZ8q9G6sL+GW7QAzuWnNrm4zTKRabRzwdTZ9MCUmGPJvUpxKovJ1Z4t6YIKGHTson0a7fvV5g==} + dependencies: + '@ctrl/tinycolor': 3.6.1 + hast-util-to-html: 8.0.4 + hastscript: 7.2.0 + postcss: 8.4.25 + postcss-nested: 6.0.1(postcss@8.4.25) + dev: false + + /@expressive-code/plugin-frames@0.22.2: + resolution: {integrity: sha512-Tn4COPTdySVJ6gygCCqYd0KMQXea4l6NN/9Px2uSekPDLUiE9Ff4i3005Pa1rr31m0hLBes4POnFRRmwqIu+ZA==} + dependencies: + '@expressive-code/core': 0.22.2 + hastscript: 7.2.0 + dev: false + + /@expressive-code/plugin-shiki@0.22.2: + resolution: {integrity: sha512-BDNkEb2OwmoL5kJJnNZ6fXk5IytZordEWGjWycEiKyHMXotJ+94S0PIIiTfVIp38H1faL+yd+kz2pF4t7ePcww==} + dependencies: + '@expressive-code/core': 0.22.2 + shiki: 0.14.3 + dev: false + + /@expressive-code/plugin-text-markers@0.22.2: + resolution: {integrity: sha512-9lMON0kVEn0LAIe9mHcXaxdwqnxCF7MR+IExyC4OGhMVEc1p8Vp7rvSxsUPjySQV2QvYNTlQOaKVi/eI5oM1Ag==} + dependencies: + '@expressive-code/core': 0.22.2 + hastscript: 7.2.0 + unist-util-visit-parents: 5.1.3 + dev: false + /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} @@ -879,32 +921,26 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.18 - dev: false /@jridgewell/resolve-uri@3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - dev: false /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: false /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: false /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: false /@jridgewell/trace-mapping@0.3.18: resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: false /@mdx-js/mdx@2.3.0: resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} @@ -1073,7 +1109,6 @@ packages: /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} - dev: false /@types/hast@2.3.5: resolution: {integrity: sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==} @@ -1157,7 +1192,6 @@ packages: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true - dev: false /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -1237,7 +1271,6 @@ packages: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} dependencies: dequal: 2.0.3 - dev: false /array-iterate@2.0.1: resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} @@ -1248,6 +1281,15 @@ packages: hasBin: true dev: false + /astro-expressive-code@0.22.2(astro@2.8.5): + resolution: {integrity: sha512-pmyuTJcEzfYzxPNBsIEjVNTzgWHxDGiv4D/oJusvOm30x7ETADMusqf9uYmJ6rS1jlwAgfaUWm7vTv6SaxWrSw==} + peerDependencies: + astro: ^2.0.0 || ^3.0.0-beta + dependencies: + astro: 2.8.5 + remark-expressive-code: 0.22.2 + dev: false + /astro-icon@0.8.1: resolution: {integrity: sha512-APk+fbFnoyGdIVSPFrdrOW9YBK96/1fYuVe7ULTGW92+z00RKB8GfLJiUvzNVXUAX2rZJCFmruGVF4rrhcTYsg==} dependencies: @@ -1373,7 +1415,6 @@ packages: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} dependencies: dequal: 2.0.3 - dev: false /bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -1582,7 +1623,6 @@ packages: acorn: 8.10.0 estree-walker: 3.0.3 periscopic: 3.1.0 - dev: false /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -1669,7 +1709,6 @@ packages: dependencies: mdn-data: 2.0.30 source-map-js: 1.0.2 - dev: false /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} @@ -1758,7 +1797,6 @@ packages: /dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - dev: false /devalue@4.3.2: resolution: {integrity: sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==} @@ -1962,7 +2000,6 @@ packages: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: '@types/estree': 1.0.1 - dev: false /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} @@ -2014,6 +2051,15 @@ packages: strip-final-newline: 3.0.0 dev: false + /expressive-code@0.22.2: + resolution: {integrity: sha512-2KOsjZKx6pRLVhlIo7ikZxL0CJzuvpP4LeGcFiz7YsqUtT3ak4MgEeD1ph82FNp2isl+vnc8OZu1xoGDi9JxMw==} + dependencies: + '@expressive-code/core': 0.22.2 + '@expressive-code/plugin-frames': 0.22.2 + '@expressive-code/plugin-shiki': 0.22.2 + '@expressive-code/plugin-text-markers': 0.22.2 + dev: false + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -2460,7 +2506,6 @@ packages: resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==} dependencies: '@types/estree': 1.0.1 - dev: false /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} @@ -2568,7 +2613,6 @@ packages: /locate-character@3.0.0: resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} - dev: false /locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} @@ -2639,7 +2683,6 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - dev: false /markdown-extensions@1.1.1: resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} @@ -2850,7 +2893,6 @@ packages: /mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} - dev: false /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -3495,7 +3537,6 @@ packages: '@types/estree': 1.0.1 estree-walker: 3.0.3 is-reference: 3.0.1 - dev: false /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} @@ -3635,6 +3676,16 @@ packages: synckit: 0.8.5 dev: false + /prettier-plugin-svelte@3.0.3(prettier@3.0.0)(svelte@4.1.2): + resolution: {integrity: sha512-dLhieh4obJEK1hnZ6koxF+tMUrZbV5YGvRpf2+OADyanjya5j0z1Llo8iGwiHmFWZVG/hLEw/AJD5chXd9r3XA==} + peerDependencies: + prettier: ^3.0.0 + svelte: ^3.2.0 || ^4.0.0-next.0 + dependencies: + prettier: 3.0.0 + svelte: 4.1.2 + dev: true + /prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} @@ -3728,6 +3779,14 @@ packages: unified: 10.1.2 dev: false + /remark-expressive-code@0.22.2: + resolution: {integrity: sha512-NwVpKDHiHsD+3CwxDrXA6B2fNttVDK0BBnkHLPQoKNOuEokYWA9+3trZQw77txBGimNLsJQCBl/tddsHen2g8w==} + dependencies: + expressive-code: 0.22.2 + hast-util-to-html: 8.0.4 + unist-util-visit: 4.1.2 + dev: false + /remark-frontmatter@4.0.1: resolution: {integrity: sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==} dependencies: @@ -3975,7 +4034,6 @@ packages: /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: false /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} @@ -4168,7 +4226,6 @@ packages: locate-character: 3.0.0 magic-string: 0.30.2 periscopic: 3.1.0 - dev: false /svgo@2.8.0: resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} diff --git a/src/components/EventBanner.svelte b/src/components/EventBanner.svelte index 38145c71..2bd7ddf0 100644 --- a/src/components/EventBanner.svelte +++ b/src/components/EventBanner.svelte @@ -3,23 +3,31 @@ const now = new Date(); const isFuture = now.getTime() - date.getTime() < 0; const dateString = new Intl.DateTimeFormat(undefined, { - weekday: 'long', - year: 'numeric', - month: 'numeric', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', + weekday: "long", + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", hour12: true, }).format(date); {#if isFuture} - -
+ +
- Interested in running Java in the browser with CheerpJ 3.0?
+ Interested in running Java in the browser with CheerpJ 3.0?
Ask our developers anything at our live Q&A on - ! + !
Join the event » diff --git a/src/content/docs/cheerpj2/00-faq.md b/src/content/docs/cheerpj2/00-faq.md index 68eea59a..cf410897 100644 --- a/src/content/docs/cheerpj2/00-faq.md +++ b/src/content/docs/cheerpj2/00-faq.md @@ -52,7 +52,7 @@ Yes, it should. However, this has not been one of our areas of focus so far. ## When compiling my application I see the message `Failure compiling MyFile.class`, but cheerpjfy continues to execute with no errors -This means that it was not possible to use the new codegen. Cheerpj will use, for this class, the legacy codegen. This might happen for multiple classes in the same .jar, +This means that it was not possible to use the new codegen. CheerpJ will use, for this class, the legacy codegen. This might happen for multiple classes in the same .jar, ## My Java application needs to get data over the network, but I only get `SocketException`s @@ -64,26 +64,26 @@ Please note that when using CheerpJ to run applets the custom handlers are enabl ## When I run an application compiled with CheerpJ I see 404 errors in the browser console. What's going on? -Ignore those errors. CheerpJ provides a FileSystem implementation on top of HTTP. In this context it is absolutely ok for some files to be missing. CheerpJ will correctly interpret 404 errors as a file not found condition. +Ignore those errors. CheerpJ provides a filesystem implementation on top of HTTP. In this context it is absolutely ok for some files to be missing. CheerpJ will correctly interpret 404 errors as a file not found condition. ## My application compiled with CheerpJ does not work and I just see the "CheerpJ runtime ready" on the top of the screen. What's going on? Many first time users get stuck at this point. The most common issues are: - Opening the HTML page directly from disk: The URL in the browser should always start with http:// or https://, if it starts with file:// CheerpJ will not work. You need to use a local web server during testing. -- Forgetting to add "/app/" prefix to the JAR files used in Web page. CheerpJ implements a virtual fileystem with multiple mount points, the "/app/" prefix is required. +- Forgetting to add "/app/" prefix to the JAR files used in Web page. CheerpJ implements a virtual filesystem with multiple mount points, the "/app/" prefix is required. - More in general, you can use the "Network tab" of the developer tools in the browser to check if the JAR is being correctly downloaded. If the JAR is never downloaded, or a 404 error is returned, something is wrong with the JAR path. If you don't see anything in the "Network tab", please reload the page while keeping the developer tools open. - When converting obfuscated JARs on MacOS and Windows there might be collisions between classes due to the case-insensitive nature of the filesystem. For example `a.class` and `A.class` will be considered the same. Always try to convert the JAR using a Linux machine before reporting a bug when converting obfuscated JARs. ## My application compiled with CheerpJ does not work and I see a cross origin error to a Google service in the console. What's going on? -The cross origin message you see happens as part of our automatic bug reporting system and it is not the real error. Something else is making your application crash, please report a bug here: https://github.com/leaningtech/cheerpj-meta/issues +The cross origin message you see happens as part of our automatic bug reporting system and it is not the real error. Something else is making your application crash, please report a bug [here](https://github.com/leaningtech/cheerpj-meta/issues). ## Can I play Old School RuneScape using CheerpJ or the CheerpJ Applet Runner extension? Not yet. The main problem is that RuneScape requires low level network connections primitives (sockets) which are not provided by browsers at this time due to security concerns. In the future we might provide a paid add-on to the CheerpJ Applet Runner extension to support this use case via tunneling. -## How can I use CheerpJ to generate WebAssembly code instead of Javascript? +## How can I use CheerpJ to generate WebAssembly code instead of JavaScript? CheerpJ cannot be used to generate WebAssembly code at the moment. diff --git a/src/content/docs/cheerpj2/01-demos.md b/src/content/docs/cheerpj2/01-demos.md index bfa45d5f..e1e6beb6 100644 --- a/src/content/docs/cheerpj2/01-demos.md +++ b/src/content/docs/cheerpj2/01-demos.md @@ -6,39 +6,37 @@ To showcase the capabilities of the CheerpJ compiler we have published several d ## OpenAstexViewer - - This demo highlights how complex Java applets with 3D rendering can efficiently and safely run in any browser using CheerpJ. -This specific applet is a visualization tool for protein structures, the source code is available here: +This specific applet is a visualization tool for protein structures. -## Swing examples: +- Go to the [demo](https://cheerpjdemos.leaningtech.com/OpenAstexViewer.html) +- Find the source code [here](https://github.com/openastexviewer/openastexviewer) - +## Swing examples: A few selected Java Swing examples to demonstrate how complex Swing GUI apps can be automatically converted to HTML5/JavaScript. -Source: +- Go to the [demo](https://cheerpjdemos.leaningtech.com/SwingDemo.html) +- [Source](https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html) ## JavaFiddle - - A playground to compile and run Java programs directly in the browser. Both console and GUI applications are supported. The standard `javac` compiler is used, since `javac` is also written in Java the whole compiler runs in the browser, together with the compiled application. -Source: [https://javafiddle.leaningtech.com/index.html] (Inspect the page using the devtools) -## iText Demo +- Go to the [demo](ttps://javafiddle.leaningtech.com/) (please inspect the page using the devtools). - +## iText Demo Edit PDFs fully client side using the industry standard [iText](https://itextpdf.com/en) library converted to JavaScript. This demo demonstrates how CheerpJ APIs can be used to instance Java objects and call methods directly from JavaScript. -Source: +- Go to the [demo](https://cheerpjdemos.leaningtech.com/iTextDemo.html) +- [Source](https://cheerpjdemos.leaningtech.com/itextCheerpJDemo.js) diff --git a/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md b/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md index 406ade2e..69f08644 100644 --- a/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md +++ b/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md @@ -4,54 +4,56 @@ title: Installation CheerpJ is very easy to use, this tutorial will guide you step by step into compiling an unmodified JAR file to a JAR.JS file. We will also create a basic HTML file integrated with the CheerpJ loader to run the Java application in the browser. -# Download and install CheerpJ +## Download and install CheerpJ Visit [our download page](https://leaningtech.com/download-cheerpj/) and download the CheerpJ archive for your platform. CheerpJ is available for Linux, Mac OS X and Windows. -CheerpJ is distributed as an archive for all the platforms, you can unpack the archive anywhere in the system. During the tutorial we will assume that CheerpJ has been unpacked in the home directory and its root is `~/cheerpj_2.3/`. Please keep in mind to use a different path in the following commands if you have chosen a different position or you are using a different version of CheerpJ. +CheerpJ is distributed as an archive for all the platforms, you can unpack the archive anywhere in the system. During the tutorial we will assume that CheerpJ has been unpacked in the Applications directory `/Applications/cheerpj_2.3/`. Please keep in mind to use a different path in the following commands if you have chosen a different position or you are using a different version of CheerpJ. -# Build or download the JAR file +## Using CheerpJ's AOT compiler + +### Build or download the JAR file CheerpJ compiles unmodified JAR files to JavaScript so that they can run in the browser. Java source code is not needed to use CheerpJ. If you are building your own application you should already have its JAR file. For this example we will download a basic Swing example. Download the [TextDemo.jar](https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TextDemoProject/TextDemo.jar) file into a new directory. Below we will assume that this new directory is `~/cheerpj_tutorial/` -# Build the JAR.JS file +### Build the JAR.JS file CheerpJ provides a convenient python program to convert whole JARs to JavaScript: `cheerpjfy.py`. It supports several options for advanced users, but it's basic syntax is very simple. The following command will generate `TextDemo.jar.js` -``` +```shell cd ~/cheerpj_tutorial/ -~/cheerpj_2.3/cheerpjfy.py TextDemo.jar +/Applications/cheerpj_2.3/cheerpjfy.py TextDemo.jar ``` **NOTE**: `cheerpjfy.py` it's a python3 program, you need to have python3 installed on your system. **NOTE**: On windows you should prefix the command with the `py` launcher to use the correct version of python. -# Create an HTML page +### Create an HTML page Copy the following HTML code into `~/cheerpj_tutorial/cheerpj_tutorial.html` -``` - +```html title="cheerpj_tutorial/cheerpj_tutorial.html" + - - - CheerpJ test - - - - - + + + CheerpJ test + + + + ``` Let's break down what is going on: -- We first include the CheerpJ loader from our cloud runtime. (https://cjrtnc.leaningtech.com/2.3/loader.js). This file is the only script that needs to be loaded to use CheerpJ. CheerpJ will _automatically_ load all other files, including the `TextDemo.jar.js` we generated above. -- We initialize CheerpJ using the `cheerpjInit()` API. See [Runtime API](/cheerpj2/reference/Runtime-API) for more information. +- We first include the CheerpJ [loader](https://cjrtnc.leaningtech.com/2.3/loader.js) from our cloud runtime as ``. This file is the only script that needs to be loaded to use CheerpJ. CheerpJ will _automatically_ load all other files, including the `TextDemo.jar.js` we generated above. + +- We initialize CheerpJ using `cheerpjInit()`. See [Runtime API](/cheerpj2/reference/Runtime-API#cheerpjinit) for more information. - We want to run a graphical application (i.e. a Swing or AWT application), so we need to initialize a _virtual display_ in the page. CheerpJ will render all Java windows into this display. - We can now start the JAR file. CheerpJ will _automatically_ download the `TextDemo.jar.js` file as soon as the first application class is loaded @@ -66,25 +68,25 @@ The `/app/` directory is virtual, it only exists inside of CheerpJ and it's need - `/app/TextDemo.jar` -> `http://127.0.0.1:8080/TextDemo.jar` - `/app/subdirectory/data.txt` -> `http://127.0.0.1:8080/subdirectory/data.txt` -# Run the application in the browser +### Run the application in the browser To test CheerpJ you _must_ use a local Web Server. Opening the `cheerpj_tutorial.html` page directly from the disk (for example, by double-clicking on it) is **_not supported_**. This is a very common mistake for first time users. -**_TIP_**: There are many different Web servers that you can use, and all of them should work. For a quick test we recommand: +**_TIP_**: There are many different Web servers that you can use, and all of them should work. For a quick test we recommend: - Python2: `python2 -m SimpleHTTPServer 8080` - Python3: `python3 -m http.server 8080` -- NPM (http-server): `http-server -p 8080` +- npm (http-server): `http-server -p 8080` To run TextDemo.jar in the browser using CheerpJ, do the following -``` +```console cd ~/cheerpj_tutorial/ python3 -m http.server 8080 ``` Now open your favourite browser and enter the following URL `http://127.0.0.1:8080/cheerpj_tutorial.html`. You will see the CheerpJ spinner during a brief loading phase. Then the Java window will appear and it will look identical to the native version. -# The end! +## The end! Congratulations, you have successfully compiled and run your first Java application using CheerpJ. For more information, please read our in-depth [Getting Started](/cheerpj2/getting-started/Getting-Started) page. diff --git a/src/content/docs/cheerpj2/03-getting-started/01-Getting-Started.md b/src/content/docs/cheerpj2/03-getting-started/01-Getting-Started.md index b7a3dacf..7a26adf7 100644 --- a/src/content/docs/cheerpj2/03-getting-started/01-Getting-Started.md +++ b/src/content/docs/cheerpj2/03-getting-started/01-Getting-Started.md @@ -4,18 +4,20 @@ title: Getting started This page will help you getting started with CheerpJ and converting your first Java application to JavaScript in no time. -To start, make sure to download the latest available version of CheerpJ [here](https://leaningtech.com/download-cheerpj/). Decompress the Cheerpj 2.3 archive anywhere, for example in `~/cheerpj_2.3`. +To start, make sure to download the latest available version of CheerpJ [here](https://leaningtech.com/download-cheerpj/). Decompress the CheerpJ 2.3 archive anywhere, for example in `~/cheerpj_2.3` or `/Applications/cheerpj_2.3/`. **Important:** Converting an applet is documented at the bottom of this page. -# Converting a single JAR to a JAR.JS file +## Converting from .jar to .jar.js + +### Converting a single .jar file `cheerpjfy.py` is an helper script that automatically takes care of unpacking, compiling and optimising a whole JAR archive. Using `cheerpjfy.py` is the recommended way of compiling applications and libraries using CheerpJ. The basic usage is very simple: -``` -~/cheerpj_2.3/cheerpjfy.py my_application_archive.jar +```shell +/Applications/cheerpj_2.3/cheerpjfy.py my_application_archive.jar ``` This command will generate a file called `my_application_archive.jar.js`, which needs to be deployed in the same folder of the original .JAR archive, and hosted on a web server. Instructions on how to serve the converted JavaScript on a web page are provided below. @@ -24,16 +26,16 @@ This command will generate a file called `my_application_archive.jar.js`, which **Note to Windows users:** You will need to have python3 installed on the system. Python provides a launcher called `py` that will automatically detect and use the right version of python for a given script. To use `cheerpjfy.py` on Windows you need to prefix all the commands with `py`, for example: -``` +```shell py c:\cheerpj_2.3\cheerpjfy.py application.jar ``` -# Converting multiple JARs to JAR.JS's files +### Converting multiple .jar files If your JAR has any dependencies in the form of further JAR archives, the `cheerpjfy.py` command line must be modified as follows: -``` -~/cheerpj_2.3/cheerpjfy.py --deps my_dependency_archive.jar my_application_archive.jar +```shell +/Applications/cheerpj_2.3/cheerpjfy.py --deps my_dependency_archive.jar my_application_archive.jar ``` This command will generate `my_application_archive.jar.js` but **not** `my_dependency_archive.jar.js`. Each archive should be compiled separately by invoking `~/cheerpj_2.3/cheerpjfy.py my_dependency_archive.jar`. @@ -47,9 +49,9 @@ do done ``` -# Basic HTML page for testing a Java application +## Basic HTML page for testing a Java application -```html +```html title="index.html" @@ -71,42 +73,51 @@ done This page will initialize the CheerpJ system, create a graphical environment to contain all Java windows and then execute the `main` method of `ChangeThisToYourClassName`. The second parameter of cheerpjRunMain is a `:` separated list of JARs where application classes can be found (the classpath). The `/app/` is a virtual file system mount point that reference the root of the web server this page is loaded from. -You can now serve this web page on a simple http server, such as the http-server utility. +You can now serve this web page on a simple HTTP server, such as the http-server utility. -``` -http-server ~/cheerpj_2.3/ +```shell +http-server [path] [options] ``` -# Converting an applet +## Converting an applet Applets can be run by Chrome users using the [CheerpJ Applet Runner](https://chrome.google.com/webstore/detail/cheerpj-applet-runner-bet/bbmolahhldcbngedljfadjlognfaaein) Chrome extension. You can also compile the applet ahead of time using the method described above. To support all browsers, you can add the following tags to your page: -``` +```html - + ``` -This should be sufficient to get the applet to run on any browser, with the pre-compiled JAR.JS's files deployed in the same directory of the the original JAR files. The `cheerpjInit({enablePreciseAppletArchives:true});` call can be done during page initialization. +This should be sufficient to get the applet to run on any browser, with the pre-compiled JAR.JS's files deployed in the same directory of the original JAR files. The `cheerpjInit({enablePreciseAppletArchives:true});` call can be done during page initialization. To avoid potential conflicts with native Java we recommend replacing the original HTML tag with `cheerpj-` prefixed version. You should use ``, `` or `` depending on the original tag. -# Basic HTML page for testing a Java applet +## Basic HTML page for testing a Java applet -``` - +```html title="index.html" + - - - CheerpJ applet test - - - - - -

not able to load Java applet

-
- + + + CheerpJ applet test + + + + + +

not able to load Java applet

+
+ ``` diff --git a/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx b/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx index ad74cee6..1936e9fa 100644 --- a/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx +++ b/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx @@ -31,7 +31,7 @@ CheerpJ Applet Runner is available for Chrome and Edge. ## Usage -1. [Install CheerpJ Applet Runner](#installation) +1. [Install CheerpJ Applet Runner](https://chrome.google.com/webstore/detail/cheerpj-applet-runner-bet/bbmolahhldcbngedljfadjlognfaaein) 2. Visit a page with a Java applet, [such as this one](http://www.neilwallis.com/projects/java/water/index.php) 3. Click on the CheerpJ Applet Runner icon in the toolbar 4. Click the **Enable CheerpJ** button diff --git a/src/content/docs/cheerpj2/04-guides/DOM-and-JavaScript-interoperability.md b/src/content/docs/cheerpj2/04-guides/DOM-and-JavaScript-interoperability.md index 287dc968..c3a01906 100644 --- a/src/content/docs/cheerpj2/04-guides/DOM-and-JavaScript-interoperability.md +++ b/src/content/docs/cheerpj2/04-guides/DOM-and-JavaScript-interoperability.md @@ -10,7 +10,7 @@ The `com.leaningtech.client.Global` is a representation of the global namespace ## Basic example -```java +```java title="DomExample.java" import com.leaningtech.client.Document; import com.leaningtech.client.Element; import com.leaningtech.client.Global; @@ -60,7 +60,7 @@ The various methods behave the same, with the only difference being the expected Assuming the example above is contained in `DomExample.java`, you need to first build the program using the standard `javac` compiler, create a JAR and then create the JAR.JS from it using CheerpJ. In both steps the `cheerpj-dom.jar` must be explicitly added to the command line as a dependency. -``` +```shell # The CHEERPJ_INSTALL_PATH is assumed to be set to the location where the CheerpJ archive has been installed javac -cp $CHEERPJ_INSTALL_PATH/cheerpj-dom.jar DomExample.java jar cvf domexample.jar DomExample.class diff --git a/src/content/docs/cheerpj2/04-guides/File-System-support.md b/src/content/docs/cheerpj2/04-guides/File-System-support.md index 63b26922..3d770639 100644 --- a/src/content/docs/cheerpj2/04-guides/File-System-support.md +++ b/src/content/docs/cheerpj2/04-guides/File-System-support.md @@ -8,7 +8,7 @@ Read only and read/write filesystems are exposed in Java and can be used to read **Note**: CheerpJ provides access to a virtualized filesystem, which does not correspond to the local computer. Accessing local files from the browser it's forbidden for security reasons. -# File Systems in CheerpJ +## File Systems in CheerpJ CheerpJ implements three main filesystem concepts: @@ -23,7 +23,7 @@ CheerpJ filesystems are implemented as UNIX-style virtual filesystems with multi 3. `/lt/` → Another HTTP-based read-only filesystem, pointing to the CheerpJ runtime 4. `/str/` → A read-only filesystem to easily share JavaScript Strings or binary data (an `Uint8Array`) with Java code -# `/app/` mount point +## `/app/` mount point The /app/ mount point corresponds to a virtual read-only, HTTP-based filesystem. `/app/` is used to access JAR files and data from your local server. @@ -34,25 +34,25 @@ The `/app/` directory refers to the root of your web server. So, assuming that y - `/app/example.jar` → `http://127.0.0.1:8080/example.jar` - `/app/subdirectory/example.txt` → `http://127.0.0.1:8080/subdirectory/example.txt` -# `/files/` mount point +## `/files/` mount point The `/files/` mount point corresponds to a virtual read-write, IndexedDB-based filesystem. `/files/` is used to store persistent data on the browser client. The `/files/` directory is a virtual concept used by CheerpJ to store and refer to files. -# `/str/` mount point +## `/str/` mount point The `/str/` mount point is a simple read-only filesystem that can be populated from JavaScript to share data with Java code. From JavaScript you can add files into the filesystem using the `cheerpjAddStringFile` API. Example: -``` +```js cheerpjAddStringFile("/str/fileName.txt", "Some text in a JS String"); ``` You can access this data from Java, for example: -``` +```java import java.io.FileReader; ... diff --git a/src/content/docs/cheerpj2/04-guides/Implementing-Java-native-methods-in-JavaScript.md b/src/content/docs/cheerpj2/04-guides/Implementing-Java-native-methods-in-JavaScript.md index 6a1cb096..5bbcd68a 100644 --- a/src/content/docs/cheerpj2/04-guides/Implementing-Java-native-methods-in-JavaScript.md +++ b/src/content/docs/cheerpj2/04-guides/Implementing-Java-native-methods-in-JavaScript.md @@ -4,11 +4,11 @@ title: Implementing native methods With CheerpJ, it is possible to implement Java 'native' methods (that would normally be implemented in C/C++ or other AOT-compiled language) in JavaScript, similarly to what would be done in regular Java using the Java Native Interface (JNI). -# Java Native Methods +## Java Native Methods Take as an example the following Java class -```java +```java title="SomeClass.java" public class SomeClass { public static void someStaticMethod() { ... @@ -24,7 +24,7 @@ Java will search for the implementation of `someNativeMethod` using the JNI. When compiling this class with CheerpJ, a JavaScript implementation of this method will need to be provided. Implementing native Java methods in JavaScript can be useful to use browser functionalities that are not currently exposed at the Java level. -# Java Native Methods in CheerpJ +## Java Native Methods in CheerpJ Implementing native methods is simply a matter of adding a JavaScript function in the global scope with a correctly mangled signature. @@ -32,7 +32,7 @@ Since this is a rather involved process, the `cheerpjfy.py` script provides func Assume the previous class has been compiled and packaged in `some.jar`, to generate a directory tree for JS native code you can do: -``` +```shell mkdir native/ cheerpjfy.py --stub-natives=native/ some.jar ``` @@ -41,7 +41,7 @@ This will generate a tree of directories under the `native` folder, which will r Once all have been implemented, native methods can be packaged with the compiled code using the following command: -``` +```shell cheerpjfy.py --natives=native/ some.jar ``` diff --git a/src/content/docs/cheerpj2/04-guides/Startup-time-optimization.md b/src/content/docs/cheerpj2/04-guides/Startup-time-optimization.md index e22d5fcc..290c7c3d 100644 --- a/src/content/docs/cheerpj2/04-guides/Startup-time-optimization.md +++ b/src/content/docs/cheerpj2/04-guides/Startup-time-optimization.md @@ -4,7 +4,7 @@ title: Startup time optimization This page is a collection of different steps to reduce the startup time of a Java application converted with CheerpJ. -# Overview +## Overview Traditionally, users had to have Java preinstalled on their computer in order to run Java applications and applets. CheerpJ converts Java to HTML5/JavaScript, allowing to run applications and applets on browser without users having to install any additional dependency on their computer. Similarly to their JVM counterparts, applications converted to JavaScript with CheerpJ require runtime components to be loaded during execution. In CheerpJ, runtime components are JavaScript modules that are loaded on demand, only if required. @@ -12,39 +12,41 @@ The CheerpJ runtime is highly optimised to minimise the total download size of a This page provides a list of recommendations to reduce the one-time download size, and the resulting application first startup time. -# Gzip compression of JavaScript on server +## Gzip compression of JavaScript on server In our experience it is not uncommon to see that most of the loading time is spent downloading the main `jar.js` file for the application (i.e. not from the runtime). **It is critical that the Web server on which your application is deployed has gzip compression enabled for the application's JavaScript files**. If you are self-hosting the CheerpJ runtime (most likely you will not), please make sure to enable compression on these components as well. The CheerpJ cloud runtime has compression enabled by default. -# Use ProGuard to remove unused code +## Use ProGuard to remove unused code ProGuard is an industry standard open-source tool to optimize and obfuscate Java bytecode. ProGuard, by itself, can automatically trace the classes used from the application entry point and automatically remove unused classes, methods and field. This can enable a very significant reduction of download size and startup time, especially with applications using multiple third party libraries. Since Java allows reflection at runtime, ProGuard may end up removing code which is actually used, causing unexpected errors. To help in this scenario CheerpJ supports a special option: -`cheerpjInit({enableProguardTrace:true})` +```js +cheerpjInit({ enableProguardTrace: true }); +``` -When initialized with this option CheerpJ will keep track of the classes used at runtime, including classes which are accessed via reflection. Follow these steps to safely optimize an application using proguard. +When initialized with this option CheerpJ will keep track of the classes used at runtime, including classes which are accessed via reflection. Follow these steps to safely optimize an application using ProGuard. 1. Build a single `uber-JAR` by merging the application and dependencies 2. Convert the new JAR to JS using `cheerpjfy.py` 3. Run the application using CheerpJ with the `enableProguardTrace:true` option 4. Fully test the application, making sure that all possible scenarios are executed and all needed classes are loaded -5. From the browser console call `cjGetProguardConfiguration()`, a proguard configuration file (`cheerpj.pro`) will be automatically generated and downloaded +5. From the browser console call `cjGetProguardConfiguration()`, a ProGuard configuration file (`cheerpj.pro`) will be automatically generated and downloaded 6. Run `proguard` on the `uber-JAR` using the generated configuration file to generate a smaller JAR with only the needed classes. `proguard -dontwarn -injars uber.jar -outjars uber-stripped.jar -libraryjars ~/cheerpj_1.2/rt.jar @cheerpj.pro` 7. Convert this new JAR using `cheerpjfy.py` -# Reduce the size of the JAR file +## Reduce the size of the JAR file `cheerpjfy.py` supports a command line option (`--pack-jar`) to generate a minimised JAR for deployment. This smaller JAR is stripped of all original Java bytecode and can no longer be used to run the application on the JVM. The JAR is however necessary for CheerpJ to support Java reflection. -More details are available [here](/cheerpj2/reference/Command-Line-Options#--pack-jarpackjar) +More details are available [here](/cheerpj2/reference/Command-Line-Options#pack-jarpackjar) -# Preload resources +## Preload resources CheerpJ cannot predict which runtime resources will be required by an arbitrary application. CheerpJ runtime resources are therefore loaded on demand, one after the other, depending on the requirements of the application at run time. @@ -56,17 +58,23 @@ By combining the use of this profiler together with the preloader, one can highl 1. Run the application normally using CheerpJ. After the application is loaded, open the JavaScript console of the browser (e.g. Ctrl+Shift+I on many browsers), and type: -`cjGetRuntimeResources()` +```js +cjGetRuntimeResources(); +``` The result will look like this: -`["/lts/file1","/lt/file2"]` +```js +["/lts/file1", "/lt/file2"]; +``` The JavaScript console may enclose the string between quotes (`"`), which you should ignore. See [here](/cheerpj2/reference/Runtime-API#cjgetruntimeresources) for more information. 2. Modify the CheerpJ integration to enable preloading. You will only need to change the `cheerpjInit` call, to pass the `preloadResources` option. For example: -`cheerpjInit({preloadResources:["/lts/file1","/lt/file2"]});` +```js +cheerpjInit({ preloadResources: ["/lts/file1", "/lt/file2"] }); +``` See [here](/cheerpj2/reference/Runtime-API#preloadresources) for more information. diff --git a/src/content/docs/cheerpj2/05-reference/02-Command-Line-Options.md b/src/content/docs/cheerpj2/05-reference/02-Command-Line-Options.md index 23fa91f7..5964ef3e 100644 --- a/src/content/docs/cheerpj2/05-reference/02-Command-Line-Options.md +++ b/src/content/docs/cheerpj2/05-reference/02-Command-Line-Options.md @@ -4,7 +4,7 @@ title: Command line options The basic usage of the `cheerpjfy.py` build script is: -``` +```shell ./cheerpjfy.py application.jar ``` diff --git a/src/content/docs/cheerpj2/05-reference/Runtime-API.md b/src/content/docs/cheerpj2/05-reference/Runtime-API.md index 6c8570ad..31f5e0e4 100644 --- a/src/content/docs/cheerpj2/05-reference/Runtime-API.md +++ b/src/content/docs/cheerpj2/05-reference/Runtime-API.md @@ -4,11 +4,11 @@ title: Runtime API CheerpJ exposes a simple API to interact with a Java application converted to JavaScript. This API can be use to initialise CheerpJ, invoke Java methods, convert data and to enable/disable certain debugging features. -# Integrating an application converted with CheerpJ in a HTML page +## Integrating an application converted with CheerpJ in a HTML page A basic HTML file to load a CheerpJ application will look as follows: -```html +```html title="index.html" @@ -28,7 +28,7 @@ A basic HTML file to load a CheerpJ application will look as follows: ``` -# Loading the CheerpJ runtime +## Loading the CheerpJ runtime To load the most recent runtime, use the following link: @@ -44,20 +44,24 @@ More in general, you can use this line: where version is the specific runtime version you want to link to. -# cheerpjInit +## cheerpjInit `cheerpjInit` must be called once in the page to setup and initialise the CheerpJ runtime environment. `cheerpjInit` accepts an optional object argument which can be used to set options. -This method is to be invoked as follows: `cheerpjInit({option:"value"});` +This method is to be invoked as follows: + +```js +cheerpjInit({ option: "value" }); +``` All the supported options are described below. -## `clipboardMode` +### `clipboardMode` By default CheerpJ supports an internal clipboard which is local to the Java application and is not integrated with the system clipboard. To change this behaviour you can initialize CheerpJ in the following way: -``` -cheerpjInit({clipboardMode:"system"}); +```js +cheerpjInit({ clipboardMode: "system" }); ``` In `system` mode CheerpJ will share the clipboard with the system. Browsers enforce serious limitations on how the system clipboard can be accessed. In practice it is generally accessible when the `Ctrl+C` and `Ctrl+V` shortcuts are used (`Cmd+C` and `Cmd+V` on MacOSX). Due to these limitations the UX when using `clipboardMode:"system"` is: @@ -68,49 +72,49 @@ In `system` mode CheerpJ will share the clipboard with the system. Browsers enfo Commercial users adopting this integration have so far reported that this change in UX is not a significant burden for users. Moreover, in the future we plan to add an additional clipboard mode to take advantage of a new permission-based browser API which is currently being standardized. This future mode will provide native like user experience in all cases. -## `disableErrorReporting` +### `disableErrorReporting` CheerpJ automatically reports errors at runtime. Setting this option to `true` disables this system. Example: -``` -cheerpjInit({disableErrorReporting:true}); +```js +cheerpjInit({ disableErrorReporting: true }); ``` -## `disableLoadTimeReporting` +### `disableLoadTimeReporting` CheerpJ automatically get data about loading time. Setting this option to `true` disables this system. Example: -``` -cheerpjInit({disableLoadTimeReporting:true}); +```js +cheerpjInit({ disableLoadTimeReporting: true }); ``` -## `enableInputMethods` +### `enableInputMethods` When this option is set to `true` CheerpJ will be able to receive text input from the input method framework of the platform. This is useful to support text input for languages such as Chinese, Japanese and Korean. -## `enableProguardTrace` +### `enableProguardTrace` -When this option is set to `true` CheerpJ will automatically keep track of the classes actually used at runtime. Moreover, it will also keep track of classes which are accessed by reflection. After the application has been fully tested you can use the `cjGetProguardConfiguration()` function from the browser console to download a proguard configuration file (`cheerpj.pro`) that you can directly use with proguard to remove unneeded classes, methods and fields from the application, greatly reducing the download size and startup time. +When this option is set to `true` CheerpJ will automatically keep track of the classes actually used at runtime. Moreover, it will also keep track of classes which are accessed by reflection. After the application has been fully tested you can use the `cjGetProguardConfiguration()` function from the browser console to download a ProGuard configuration file (`cheerpj.pro`) that you can directly use with ProGuard to remove unneeded classes, methods and fields from the application, greatly reducing the download size and startup time. -## `javaProperties` +### `javaProperties` An array of Java properties in the form `"key=value"`. They will be defined on the System object (System properties). This option should be used if command line arguments in the form `-Dkey=value` are required when using native Java. Example usage: -``` -cheerpjInit({javaProperties:["prop1=value1","prop2=value2"]}); +```js +cheerpjInit({ javaProperties: ["prop1=value1", "prop2=value2"] }); ``` -## `listener` +### `listener` An object containing callbacks that CheerpJ will use to report various information to the user. Currently only the `jsLoadReason` and `preloadProgress` callbacks are supported. -### `jsLoadReason(scriptName, directReason, userReason)` +#### `jsLoadReason(scriptName, directReason, userReason)` **Please note that enabling this listener may have significant performance impact and should not be used in production** @@ -122,40 +126,39 @@ For each new .jar.js to be loaded, CheerpJ will call this function. This can be Example usage: -``` +```js var cheerpjListener = {jsLoadReason:function(scriptName, directReason, userReason){ ... }}; cheerpjInit({listener:cheerpjListener}); ``` -### `preloadProgress(loadedFiles, totalFiles)` +#### `preloadProgress(loadedFiles, totalFiles)` -This listener may be used in combination with [[preloading support | Startup-time-optimization#Preload-resources]] to monitor the loading of an application. The information provided is useful, for example, to display a loading/progress bar. +This listener may be used in combination with [[preloading support | Startup-time-optimization#preload-resources]] to monitor the loading of an application. The information provided is useful, for example, to display a loading/progress bar. - `loadedFiles`: How many files have been preloaded so far - `totalFiles`: How many files needs to be preloaded in total. This number may increment during the loading phase. CheerpJ has a prediction mechanism and may preload additional resources depending on application behaviour Example usage: -``` -function showPreloadProgress(loadedFiles, totalFiles) -{ - console.log("Percentage loaded "+(loadedFiles*100/totalFiles)); +```js +function showPreloadProgress(loadedFiles, totalFiles) { + console.log("Percentage loaded " + (loadedFiles * 100) / totalFiles); } -var cheerpjListener = {preloadProgress:showPreloadProgress}; -cheerpjInit({listener:cheerpjListener}); +var cheerpjListener = { preloadProgress: showPreloadProgress }; +cheerpjInit({ listener: cheerpjListener }); ``` -## `logCanvasUpdates` +### `logCanvasUpdates` When set to `true`, it enables logs on the console about the display areas which are being updated. Useful to debug overdrawing. Example: -``` -cheerpjInit({logCanvasUpdates:true}); +```js +cheerpjInit({ logCanvasUpdates: true }); ``` -## `overrideShortcuts` +### `overrideShortcuts` Some applications needs to internally handle keyboard shortcuts which are also used by the browser, for example Ctrl+F. Most users expect the standard browser behavior for these shortcuts and CheerpJ does not, by default, override them in any way. @@ -168,29 +171,29 @@ Whenever possible we recommend _not_ to use browser reserved shortcuts, to maint Example: -``` -cheerpjInit({overrideShortcuts:function(e) -{ - // Let Java handle Ctrl+F - if(e.ctrlKey && e.keyCode == 70) - return true; - return false; -}}); +```js +cheerpjInit({ + overrideShortcuts: function (e) { + // Let Java handle Ctrl+F + if (e.ctrlKey && e.keyCode == 70) return true; + return false; + }, +}); ``` -## `preloadResources`
+### `preloadResources` By using `preloadResources`, you can provide CheerpJ with a list of runtime files which you know in advance will be required for the specific application. The list should be given as a JavaScript array of strings. Example: -``` -cheerpjInit({preloadResources:["/lts/file1","/lt/file2"]}); +```js +cheerpjInit({ preloadResources: ["/lts/file1", "/lt/file2"] }); ``` See also [cjGetRuntimeResources](#cjGetRuntimeResources). -## `status` +### `status` This option determines the level of verbosity of CheerpJ in reporting status updates. @@ -198,54 +201,66 @@ This option determines the level of verbosity of CheerpJ in reporting status upd - `"splash"`: Enabled status reporting only during initialization. There will be no feedback after the first window is shown on screen. - `"none"`: Disable all status reporting. -## `appletParamFilter` +### `appletParamFilter` Some applications may need to have some parameter modified before getting those inside the applet. Example: -``` -cheerpjInit({appletParamFilter:function(name, value) -{ - if(name==="httpServer") - return value.replace("http", "https"); - return value; -}}); +```js +cheerpjInit({ + appletParamFilter: function (name, value) { + if (name === "httpServer") return value.replace("http", "https"); + return value; + }, +}); ``` -# cheerpjCreateDisplay +## cheerpjCreateDisplay This method will create the HTML element that will contain all Java windows. It is only required to run graphical applications. -`cheerpjCreateDisplay(width, height, /*optional*/parent)` +```js +cheerpjCreateDisplay(width, height, /*optional*/ parent); +``` The `width` and `height` parameter represent the display area size in CSS pixels. It is also possible to specify a parent element if required, if a parent element is not specified the display area will be appended to the page `body` element. If a parent is specified it is also possible to pass `-1` to both `width` and `height`, in that case the size will correspond to the parent size and it will also change dynamically if the parent is modified by either CSS changes or browser window resize. -# Running applications and JARs +## Running applications and JARs **Warning**: CheerpJ does not support opening the HTML pages directly from disk. If the URL in your browser starts with `file://`, CheerpJ will not run. You _must_ use a local Web server. The most common way of starting an application is to use the `cheerpjRunMain` API, which lets you execute the static main method of a Java class in the classpath. -``` -cheerpjRunMain("fully.qualified.class.name", "/app/my_application_archive.jar:/app/my_dependency_archive.jar", arg1, arg2); +```js +cheerpjRunMain( + "fully.qualified.class.name", + "/app/my_application_archive.jar:/app/my_dependency_archive.jar", + arg1, + arg2, +); ``` Alternatively, if your JAR is designed to be executed with `java -jar my_application_archive.jar`, you can use this simpler API. -``` +```js cheerpjRunJar("/app/my_application_archive.jar", arg1, arg2); ``` Optionally, if your JAR also need additional dependencies, you can use. -``` -cheerpjRunJarWithClasspath("/app/my_application_archive.jar", "/app/my_dependency_archive.jar", arg1, arg2); +```js +cheerpjRunJarWithClasspath( + "/app/my_application_archive.jar", + "/app/my_dependency_archive.jar", + arg1, + arg2, +); ``` In all cases the arguments should be JavaScript Strings. -# cjCall / cjNew +## cjCall / cjNew These functions make it possible to conveniently call Java code from JS. Java code is always run asynchronously, so the returned values are `Promise`s. See below for details. @@ -329,9 +344,9 @@ resolvedMethod(arg1, arg2, arg3); Please note that this convenient form can unfortunately only be used on the main thread, not on Workers. For more information see [WebWorker API](/cheerpj2/reference/WebWorker-API) -# Data conversion +## Data conversion -## cjStringJavaToJs(str) / cjStringJsToJava(str) +### cjStringJavaToJs(str) / cjStringJsToJava(str) ```js var jsString = cjStringJavaToJs(javaString); @@ -345,7 +360,7 @@ String javaString = cjStringJStoJava(jsString); This converts a JavaScript string into a Java string. This operations also implies a copy. String parameters passed to `cheerpjRunMain`, `cjCall` and `cjNew` are automatically converted so it is not necessary to use this methods in that case. -## cjTypedArrayToJava +### cjTypedArrayToJava Converts a TypedArray to a Java compatible primitive array. This operation implies a copy. Data is converted as follows: @@ -360,8 +375,8 @@ Converts a TypedArray to a Java compatible primitive array. This operation impli | Float32Array | float[] | | Float64Array | double[] | -# Preloading APIs +## Preloading APIs -## cjGetRuntimeResources +### cjGetRuntimeResources Returns a JavaScript string representing the data that should be passed to [preloadResources](#preloadResources). It is a list of files that have been loaded from the runtime up to the time this function is called. diff --git a/src/content/docs/cheerpj2/05-reference/WebWorker-API.md b/src/content/docs/cheerpj2/05-reference/WebWorker-API.md index 63641306..be60903d 100644 --- a/src/content/docs/cheerpj2/05-reference/WebWorker-API.md +++ b/src/content/docs/cheerpj2/05-reference/WebWorker-API.md @@ -10,9 +10,11 @@ All code in a Worker runs in parallel and asynchronously with the main thread. A The main entry point for CheerpJ workers is the `CheerpJWorker` JS interface. It is a normal JS object and it is possible to instantiate it multiple times. -``` +```js var w = new CheerpJWorker(); -w.cheerpjInit().then(function(e) { console.log("CheerpJWorker is ready"); }); +w.cheerpjInit().then(function (e) { + console.log("CheerpJWorker is ready"); +}); ``` This starts the WebWorker and initializes CheerpJ in that context. All workers need to be initialized in this way. As a general rule the `CheerpJWorker` exposes the same API as CheerpJ in the main thread. @@ -38,15 +40,15 @@ Java Strings, being Java objects, cannot be passed or returned. But JavaScript s Runs a Java main method in the WebWorker context -``` +```js w.cheerpjRunMain("ClassName", classPath, arg1, arg2).then(...) ``` ## CheerpJWorker.cjCall -Executes a static Java method in the WebWorker contet +Executes a static Java method in the WebWorker content -``` +```js w.cjCall("ClassName", "methodName", arg1, arg2).then(...) ``` @@ -54,15 +56,20 @@ w.cjCall("ClassName", "methodName", arg1, arg2).then(...) Uses Java reflection to resolve the method and returns an opaque handle to it. This handle can then be used multiple times without using Java reflection again. -``` -w.cjResolveCall("ClassName", "methodName", /*Or array of parameter types if methodName is not unique*/null).then(function(resolvedMethod) { w.cjCall(resolvedMethod, arg1, arg2); ... }); +```js +w.cjResolveCall("ClassName", "methodName", null).then( // or array of parameter types if methodName is not unique + function(resolvedMethod) { + w.cjCall(resolvedMethod, arg1, arg2); + ... + } +); ``` -# Java API for Workers +## Java API for Workers CheerpJ exposes a custom API to access this feature directly from Java code. The API is equivalent in terms of capabilities. This API is blocking, so to actually take advantage of concurrency between the main thread and Web Workers it is necessary to use this API from a Java thread. -```java +```java title="Worker.java" package com.leaningtech.cheerpj; public class Worker @@ -91,7 +98,7 @@ The Java version of the API is also extended to support `long`s in parameters an Example usage: -```java +```java title="WW.java" import com.leaningtech.cheerpj.Worker; public class WW @@ -106,6 +113,6 @@ public class WW To build the class you need to add `cheerpj-public.jar` to the classpath -``` +```shell javac -cp cheerpj_install_dir/cheerpj-public.jar WW.java ``` diff --git a/src/content/docs/cheerpj2/index.md b/src/content/docs/cheerpj2/index.md index 1e05a9f7..f97fd3ef 100644 --- a/src/content/docs/cheerpj2/index.md +++ b/src/content/docs/cheerpj2/index.md @@ -5,19 +5,23 @@ subtitle: Convert Java to WebAssembly and JavaScript CheerpJ is a Java bytecode to WebAssembly and JavaScript compiler, compatible with 100% of Java, which allows to compile any Java SE application, library or Java applet into a WebAssembly/JavaScript application. -**Main project link**: +Please visit the project [website](https://leaningtech.com/cheerpj/). **Download latest version**: [![Latest version](https://img.shields.io/badge/cheerpj-2.3-green.svg)](https://leaningtech.com/download-cheerpj/) [![Latest version changelog](https://img.shields.io/badge/2.3-changelog-green.svg)](/cheerpj2/changelog) -**Link to latest runtime**: `https://cjrtnc.leaningtech.com/2.3/loader.js` +**Link to latest runtime** -If you are unsure how to start, try our [Tutorial](/cheerpj2/getting-started/Tutorial). +``` +https://cjrtnc.leaningtech.com/2.3/loader.js +``` + +If you are unsure how to start, try our [tutorial](/cheerpj2/getting-started/Tutorial). ## What is CheerpJ? ![](/cheerpj2/assets/cheerpj_visual_2.png) -CheerpJ is constituted of three components: +**CheerpJ is constituted of three components:** 1. The CheerpJ AOT compiler, an LLVM-based Java-bytecode to JavaScript compiler. This can be used to convert Java archives (e.g. .jar) or single .class files to JavaScript. The CheerpJ AOT compiler is available for Linux, macOS and Windows. 2. The CheerpJ runtime library, a full Java SE runtime in WebAssembly and JavaScript, that can be distributed in part or in full with applications converted with CheerpJ. @@ -34,7 +38,7 @@ CheerpJ is constituted of three components: ## Getting Started -You can download CheerpJ for Linux, Windows and macOS on our website () +You can download CheerpJ for Linux, Windows and macOS on our [website](https://leaningtech.com/cheerpj/) To get started with CheerpJ, please refer to the following pages: @@ -44,7 +48,7 @@ To get started with CheerpJ, please refer to the following pages: ## Demos -Several demos of CheerpJ can be found at . +Several demos of CheerpJ can be found [here](https://leaningtech.com/demo/?cheerpjfilter). ## Bugs and Questions diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 85efd25b..f1de8c55 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -21,6 +21,13 @@ const exportColorsAsCssVariables = plugin(({ addBase, theme }) => { }); /** @type {import('tailwindcss').Config} */ +const disabledCss = { + "code::before": false, + "code::after": false, + "blockquote p:first-of-type::before": false, + "blockquote p:last-of-type::after": false, +}; + module.exports = { content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"], theme: { @@ -45,6 +52,11 @@ module.exports = { "--tw-prose-invert-links": theme("colors.primary[400]"), }, }, + DEFAULT: { css: disabledCss }, + sm: { css: disabledCss }, + lg: { css: disabledCss }, + xl: { css: disabledCss }, + "2xl": { css: disabledCss }, }), }, },