diff --git a/.github/styles/Vocab/LeaningTechnologies/accept.txt b/.github/styles/Vocab/LeaningTechnologies/accept.txt
index 99e07aff..d3785b3f 100644
--- a/.github/styles/Vocab/LeaningTechnologies/accept.txt
+++ b/.github/styles/Vocab/LeaningTechnologies/accept.txt
@@ -41,6 +41,17 @@ virtualized
methodName
resolvedMethod
preloadResources
+arg
+className
+resolvedFunc
+funcName
+JSString
+jsCall
+runMain
+classPath
+resolveCall
+nops
+
diff --git a/src/components/TableOfContents.astro b/src/components/TableOfContents.astro
index 29b42476..7ca3f296 100644
--- a/src/components/TableOfContents.astro
+++ b/src/components/TableOfContents.astro
@@ -29,7 +29,7 @@ function buildToc(headings: BasicHeading[]) {
toc.push(heading);
} else if (
parentHeadings.get(heading.depth - 1) != undefined &&
- heading.depth < 4
+ heading.depth < 5
) {
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
}
diff --git a/src/content/docs/cheerp/00-installation/01-ppa.md b/src/content/docs/cheerp/00-installation/01-ppa.md
index 2821bfa3..11efd638 100644
--- a/src/content/docs/cheerp/00-installation/01-ppa.md
+++ b/src/content/docs/cheerp/00-installation/01-ppa.md
@@ -36,7 +36,7 @@ sudo apt-get update
## Install packages
-To install all cheerp components, run
+To install all Cheerp components, run
```sh
apt-get install cheerp-core
diff --git a/src/content/docs/cheerpj2/01-demos.md b/src/content/docs/cheerpj2/01-demos.md
index e1e6beb6..2a992f99 100644
--- a/src/content/docs/cheerpj2/01-demos.md
+++ b/src/content/docs/cheerpj2/01-demos.md
@@ -30,7 +30,7 @@ A few selected Java Swing examples to demonstrate how complex Swing GUI apps can
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.
-- Go to the [demo](ttps://javafiddle.leaningtech.com/) (please inspect the page using the devtools).
+- Go to the [demo](https://javafiddle.leaningtech.com/) (please inspect the page using the devtools).
## iText Demo
diff --git a/src/content/docs/cheerpj2/03-getting-started/00-Java-app.md b/src/content/docs/cheerpj2/03-getting-started/00-Java-app.md
new file mode 100644
index 00000000..d12ed54b
--- /dev/null
+++ b/src/content/docs/cheerpj2/03-getting-started/00-Java-app.md
@@ -0,0 +1,83 @@
+---
+title: Run a Java application
+---
+
+CheerpJ can run a Java application in the browser with little to no modifications. This page will help you getting started with CheerpJ and running your first Java application 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(s).
+
+**To get started you will need:**
+
+- Your Java application file(s). You can also use this [TextDemo.jar](https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/TextDemoProject/TextDemo.jar) sample.
+- An HTML file where your Java app will be wrapped
+- A simple HTTP server to test your webpage locally
+
+## 1. Create a project directory
+
+Let's start by creating a project folder where all your files will be. Please copy your java and future HTML files here.
+
+```shell
+
+mkdir directory_name
+
+```
+
+## 2. Create a basic HTML file
+
+Let's create a basic HTML file like the following example. Please notice the CheerpJ runtime environment has been integrated and initialized. In this example we are assuming your HTML file and your `.jar` files are under the project directory you just created.
+
+```html title="index.html" {6, 10-12}
+
+
+
+
+ CheerpJ test
+
+
+
+
+
+
+```
+
+Alternatively, if your application is not designed to be executed with the command `java -jar` you can replace `cheerpjRunJar()` for `cheerpjRunMain()` and pass your qualified class name as an argument. For example:
+
+```js
+cheerpjRunMain(
+ "com.application.MyClassName",
+ "/app/my_application_archive.jar:/app/my_dependency_archive.jar",
+);
+```
+
+## 3. Host your page
+
+You can now serve this web page on a simple HTTP server, such as the http-server utility.
+
+```shell
+npm install http-server
+http-server -p 8080
+```
+
+> To test CheerpJ you must use a web server. Opening the `.html` page directly from the disk (for example, by double-clicking on it) is not supported.
+
+## What's going on?
+
+- CheerpJ loader is included from our cloud runtime as
+ ``.
+- CheerpJ runtime environment is initialized by `cheerpjInit()`.
+- `cheerpjCreateDisplay()` creates a graphical environment to contain all Java windows
+- `cheerpjRunMain()` executes the `main` method of `ChangeThisToYourClassName`. The second parameter is a `:` separated list of `.jar` files 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.
+
+## The result
+
+You will see the CheerpJ display on your browser with some loading messages before showing your application running. Depending on your application and the optimizations applied, this could take just a few seconds.
+
+## Further reading
+
+- [AOT optimization](/cheerpj2/guides/AOT-optimization)
+- [Runtime API](/cheerpj2/reference/Runtime-API)
diff --git a/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md b/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md
deleted file mode 100644
index 69f08644..00000000
--- a/src/content/docs/cheerpj2/03-getting-started/00-Tutorial.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-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
-
-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 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.
-
-## 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
-
-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/
-/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
-
-Copy the following HTML code into `~/cheerpj_tutorial/cheerpj_tutorial.html`
-
-```html title="cheerpj_tutorial/cheerpj_tutorial.html"
-
-
-
-
- CheerpJ test
-
-
-
-
-
-```
-
-Let's break down what is going on:
-
-- 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
-
-**_NOTE_**: The `/app/` prefix use in cheerpjRunJar is something that many first time users find confusing. CheerpJ implements a UNIX style virtual filesystem internally, with several _mount points_. For example
-
-- `/lt/` -> CheerpJ cloud runtime
-- `/files/` -> An IndexedDB based, persistent, file storage
-- `/app/` -> An HTTP based filesystem, used to access JARs and data from your local server.
-
-The `/app/` directory is virtual, it only exists inside of CheerpJ and it's needed to distinguish files from the local server from runtime files and files stored in the browser database. The `/app/` directory actually refers to the _root_ of your web server. So, assuming that your web server is available at `http://127.0.0.1:8080/`, here are some example file mappings:
-
-- `/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
-
-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 recommend:
-
-- Python2: `python2 -m SimpleHTTPServer 8080`
-- Python3: `python3 -m http.server 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!
-
-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
deleted file mode 100644
index 7a26adf7..00000000
--- a/src/content/docs/cheerpj2/03-getting-started/01-Getting-Started.md
+++ /dev/null
@@ -1,123 +0,0 @@
----
-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` or `/Applications/cheerpj_2.3/`.
-
-**Important:** Converting an applet is documented at the bottom of this page.
-
-## 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:
-
-```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.
-
-**Important:** The files _must_ be accessed through a Web server. Trying to open the HTML page directly from the disk is not supported. The URL must look like `http://127.0.0.1:8080/cheerpj_test.html`, if it looks like `file://c/users/Test/cheerpj_test.html` CheerpJ won't be able to start.
-
-**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 .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:
-
-```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`.
-
-It is in general safe to put the target JAR in the `--deps` list, although it is not required. If you have an application composed of many JARs you can do something like this:
-
-```
-for f in one.jar two.jar three.jar
-do
- ~/cheerpj_2.3/cheerpjfy.py --deps one.jar:two.jar:three.jar $f
-done
-```
-
-## Basic HTML page for testing a Java application
-
-```html title="index.html"
-
-
-
-
- CheerpJ test
-
-
-
-
-
-```
-
-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.
-
-```shell
-http-server [path] [options]
-```
-
-## 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 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
-
-```html title="index.html"
-
-
-
-
- CheerpJ applet test
-
-
-
-
-
- not able to load Java applet
-
-
-
-```
diff --git a/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx b/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx
new file mode 100644
index 00000000..d5d9fc8d
--- /dev/null
+++ b/src/content/docs/cheerpj2/03-getting-started/01-Java-applet.mdx
@@ -0,0 +1,100 @@
+---
+title: Run a Java applet
+---
+
+import LinkButton from "../../../../components/LinkButton.astro";
+
+CheerpJ can run Java applets in the browser seamlessly. This page will help you getting started with CheerpJ for Java applets.
+
+**There are two different ways to run a Java Applet in the browser:**
+
+- [Running your own Java applet](/cheerpj2/getting-started/Java-applet#running-your-own-applet) using the CheerpJ runtime environment and the `` tag in your own webpage.
+- [Running a public applet](/cheerpj2/getting-started/Java-applet#running-a-public-applet) using the [CheerpJ Applet Runner](https://chrome.google.com/webstore/detail/cheerpj-applet-runner/bbmolahhldcbngedljfadjlognfaaein) Chrome extension for applets integrated with the applet tag `` on public websites.
+
+## Running your own applet
+
+**You will need:**
+
+- Your applet file(s)
+- An HTML file to wrap your applet
+- A basic HTTP server to test locally
+
+### 1. Create a basic HTML file
+
+```html title="index.html" {6-9, 12-20}
+
+
+
+
+ CheerpJ applet test
+
+
+
+
+
+ not able to load Java applet
+
+
+
+```
+
+### 2. Host your page locally
+
+You can now serve this web page on a simple HTTP server, such as the http-server utility.
+
+```shell
+npm install http-server
+http-server -p 8080
+```
+
+### What's going on?
+
+- The `cheerpjInit({enablePreciseAppletArchives:true});` initializes CheerpJ runtime environment indicating we are loading an applet.
+- The `` tag specifies the code base in a similar manner as the now deprecated `` tag.
+
+> 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.
+
+## Running a public applet
+
+### 1. Install the CheerpJ applet runner
+
+CheerpJ Applet Runner is available for Chrome and Edge.
+
+
+
+
+
+
+
+
+### 2. Go to a website with an applet
+
+Visit a page with a Java applet, [such as this one](http://www.neilwallis.com/projects/java/water/index.php) and click on the CheerpJ Applet Runner icon in the toolbar and enable CheerpJ.
+
+![](/cheerpj2/assets/cheerpj_applet_demo.gif)
+
+## The result
+
+You will see the CheerpJ display on your browser with some loading messages before showing your applet running. Depending on your application and the optimizations applied, this could take just a few seconds.
+
+## Further reading
+
+- [AOT optimization](/cheerpj2/guides/AOT-optimization)
+- [Runtime API](/cheerpj2/reference/Runtime-API)
diff --git a/src/content/docs/cheerpj2/03-getting-started/02-Java-library.md b/src/content/docs/cheerpj2/03-getting-started/02-Java-library.md
new file mode 100644
index 00000000..47c9d204
--- /dev/null
+++ b/src/content/docs/cheerpj2/03-getting-started/02-Java-library.md
@@ -0,0 +1,31 @@
+---
+title: Run a Java library
+subtitle: Use Java classes in JavaScript
+---
+
+## 1. Include CheerpJ on your page
+
+```html
+
+```
+
+## 2. Initialize CheerpJ and load your Java library
+
+```js
+cheerpjInit();
+cheerpjRunJar("/app/library.jar");
+```
+
+This will load `library.jar` from the root of your web server.
+
+## 3. Call Java from JavaScript
+
+```js
+let obj = await cjNew("com.library.MyClass");
+await cjCall(obj, "myMethod");
+```
+
+## Further reading
+
+- [API reference](/cheerpj2/reference/Runtime-API#calling-java-from-js)
+- [AOT optimization](/cheerpj2/guides/AOT-optimization)
diff --git a/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx b/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx
deleted file mode 100644
index 1936e9fa..00000000
--- a/src/content/docs/cheerpj2/03-getting-started/applet-runner.mdx
+++ /dev/null
@@ -1,66 +0,0 @@
----
-title: CheerpJ Applet Runner
-subtitle: Run Java applets without installing Java
----
-
-import LinkButton from "../../../../components/LinkButton.astro";
-
-The CheerpJ Applet Runner is a browser extension that enables Java applets without requiring a local Java installation or to install deprecated plugins.
-
-Since Java Applets have lost support on the majority of browsers, a tremendous amount of content, particularly in science and education, is virtually inaccessible. We aim at solving this problem by providing a solution to extend the life of Java applets on modern browsers.
-
-## Installation
-
-CheerpJ Applet Runner is available for Chrome and Edge.
-
-
-
-
-
-
-
-## Usage
-
-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
-
-That's it!
-
-![](/cheerpj2/assets/cheerpj_applet_demo.gif)
-
-## How it works
-
-CheerpJ Applet Runner works by converting the Java Applet on the fly through [CheerpJ](/cheerpj2), a minimal Java-bytecode-to-JavaScript compiler, and linking it to the CheerpJ runtime environment.
-
-The compiler runs directly on your browser and doesn't transmit your applet or the URL you are visiting to any external server.
-
-The CheerpJ Applet Runner is not a plugin, and therefore does not pose any security threat, unlike the Java plugin.
-
-## Bugs and questions
-
-We welcome any feedback and bug report, either through the Extension/Add-On itself (click on icon + "Report bug") or on [GitHub Issues](https://github.com/leaningtech/cheerpj-appletrunner/issues).
-
-We aim at supporting as many Java applets as possible, and eventually Java WebStart applications.
-
-## Privacy
-
-CheerpJ Applet Runner is **completely private.** It communicates with no external servers. 100% of code execution is happening locally on the JavaScript engine of your browser. We don't collect information on the web pages
-you are visiting, and the extension doesn't keep any logs.
-
-## Pricing
-
-CheerpJ Applet Runner is **free to use** on any publicly available Java applet.
-
-If you want to use the CheerpJ Applet Runner within a private network, or for other commercial purposes, please [get in touch](https://leaningtech.com/contact-us/?subject=CheerpJ%20Applet%20Runner%20Licensing#mailus).
diff --git a/src/content/docs/cheerpj2/04-guides/AOT-optimization.md b/src/content/docs/cheerpj2/04-guides/AOT-optimization.md
new file mode 100644
index 00000000..7d42444d
--- /dev/null
+++ b/src/content/docs/cheerpj2/04-guides/AOT-optimization.md
@@ -0,0 +1,59 @@
+---
+title: AOT Optimization
+---
+
+CheerpJ compiles unmodified `.jar` files to JavaScript as an optimization step. CheerpJ AOT compiler is very easy to use, this page 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.
+
+This optimization is not required for running a Java application or applet in the browser but it enhances performance. Before doing any compilation it is recommended to first run your application without the AOT optimization to ensure everything works.
+
+## CheerpJ AOT compiler installation
+
+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 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.
+
+## Compiling from `.jar` to `.jar.js`
+
+`cheerpjfy.py` is an helper script that automatically takes care of unpacking, compiling and optimising a whole `.jar` archive, you can find it under your CheerpJ installation directory. Using `cheerpjfy.py` is the recommended way of compiling applications and libraries using CheerpJ.
+
+### Compiling a `.jar` file
+
+```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 our application on a web page are provided in our tutorials for running a [Java application](/cheerpj2/getting-started/Java-app) and a [Java applet](/cheerpj2/getting-started/Java-applet)
+
+> **Important:** The files _must_ be accessed through a Web server. Trying to open the HTML page directly from the disk is not supported. The URL must look like `http://127.0.0.1:8080/cheerpj_test.html`, if it looks like `file://c/users/Test/cheerpj_test.html` CheerpJ won't be able to start.
+
+**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
+```
+
+### Compiling 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:
+
+```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`.
+
+It is in general safe to put the target `.jar` in the `--deps` list, although it is not required. If you have an application composed of many `.jar` you can do something like this:
+
+```
+for f in one.jar two.jar three.jar
+do
+ ~/cheerpj_2.3/cheerpjfy.py --deps one.jar:two.jar:three.jar $f
+done
+```
+
+> **Important:** Please have in mind that `.jar.js` file(s) are not passed as an argument of `cheerpjRunJar()` or `cheerpjRunMain()`; only the location of the original `.jar` files are passed but both `.jar` and `.jar.js` files should exist together under the same directory.
+
+## Further reading
+
+- [Command line options](/cheerpj2/reference/Command-Line-Options)
+- [Startup time optimization](/cheerpj2/guides/Startup-time-optimization)
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 c3a01906..4b0385ef 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
@@ -2,11 +2,7 @@
title: DOM and JavaScript interoperability
---
-CheerpJ allows users to interact with the browser DOM directly from Java, without overhead. To achieve this we provide an additional jar (`cheerpj-dom.jar`) in the CheerpJ downloadable archive.
-
-This JAR provides declarations for all of the relevant Java interfaces and classes. In particular you will find them wrapped in the `com.leaningtech.client` package, for example the `Document` interface of the browser (documented [here](https://developer.mozilla.org/en-US/docs/Web/API/Document)) becomes `com.leaningtech.client.Document` with CheerpJ.
-
-The `com.leaningtech.client.Global` is a representation of the global namespace in the browser context. It only contains static methods and fields
+CheerpJ allows users to interact with the browser DOM directly from Java, without overhead. To achieve this you will need to use the CheerpJ [Java API](/cheerpj2/reference/Java-API) (`cheerpj-dom.jar`) and found at the CheerpJ [downloadable archive](https://leaningtech.com/download-cheerpj/). Usage examples are shown below.
## Basic example
@@ -41,18 +37,11 @@ public class DomExample
## Using Strings
-It's important to keep in mind that Java Strings are not JavaScript Strings. To avoid confusion, in CheerpJ the `JSString` name is used for the JS version. The static `Global.JSString` utility function can be used to create `JSString`s from Java `String`s. If a `JSString` needs to be used many times it could be useful to cache it. Similarly the `Global.JavaString` function can be used to convert back from `JSString` to normal Java `String`.
+It's important to keep in mind that Java Strings are not JavaScript Strings. To avoid confusion, in CheerpJ the `JSString` name is used for the JS version. The static `Global.JSString` utility function can be used to create `JSString`s from Java `String`s. If a `JSString` needs to be used many times it could be useful to cache it. Similarly the `Global.JavaString` function can be used to convert back from `JSString` to normal Java `String`. See [Global.JSString](/cheerpj2/reference/Java-API#globaljsstring) and [Global.JavaString](/cheerpj2/reference/Java-API#globaljavastring).
## Calling JS methods
-The `Global` class provides a few static methods that can be used to call arbitrary JS functions in the global scope.
-
-```java
-public static Object jsCall(String funcName, Object... arg);
-public static int jsCallI(String funcName, Object... arg);
-public static double jsCallD(String funcName, Object... arg);
-public static JSString jsCallS(String funcName, Object... arg);
-```
+The `Global` class provides a few static methods that can be used to call arbitrary JS functions in the global scope, See [Global.jsCall](/cheerpj2/reference/Java-API#globaljscall--jscalli-j-scalld--jscalls)
The various methods behave the same, with the only difference being the expected return type. As JavaScript functions are untyped CheerpJ does not have enough information to auto-box the returned values, so you need to use the right return type on the call site. Java Strings parameters will be automatically converted to JavaScript Strings.
@@ -66,3 +55,7 @@ javac -cp $CHEERPJ_INSTALL_PATH/cheerpj-dom.jar DomExample.java
jar cvf domexample.jar DomExample.class
$CHEERPJ_INSTALL_PATH/cheerpjfy.py --deps $CHEERPJ_INSTALL_PATH/cheerpj-dom.jar domexample.jar
```
+
+## Further reading
+
+- [Java API](/cheerpj2/reference/Java-API) (Reference)
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 3d770639..805745e7 100644
--- a/src/content/docs/cheerpj2/04-guides/File-System-support.md
+++ b/src/content/docs/cheerpj2/04-guides/File-System-support.md
@@ -18,10 +18,12 @@ CheerpJ implements three main filesystem concepts:
CheerpJ filesystems are implemented as UNIX-style virtual filesystems with multiple mount points. The default mount points are defined as follows:
-1. `/app/` → An HTTP-based read-only filesystem, used to access JARs and data from your local server.
-2. `/files/` → An IndexedDB-based, persistent read-write file system
-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
+| Mount | Description |
+| --------- | --------------------------------------------------------------------------------------------------------- |
+| `/app/` | An HTTP-based read-only filesystem, used to access JARs and data from your local server |
+| `/files/` | An IndexedDB-based, persistent read-write file system |
+| `/lt/` | Another HTTP-based read-only filesystem, pointing to the CheerpJ runtime |
+| `/str/` | A read-only filesystem to easily share JavaScript Strings or binary data (an `Uint8Array`) with Java code |
## `/app/` mount point
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 5bbcd68a..6640e68b 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
@@ -37,7 +37,16 @@ mkdir native/
cheerpjfy.py --stub-natives=native/ some.jar
```
-This will generate a tree of directories under the `native` folder, which will replicate the Java package structure. Each class with at least one native method will generate a `ClassName_native.js` stub file with ready to be implemented.
+This will generate a tree of directories under the `native` folder, which will replicate the Java package structure. Each class with at least one native method will generate a `ClassName_native.js` stub file ready to be implemented.
+
+```js title= "Someclass_native.js"
+function _CHEERPJ_COMPRESS(ZN9Someclass16someNativeMethodEVEI)(a0,p)
+{
+ /*instance*/
+ debugger
+}
+
+```
Once all have been implemented, native methods can be packaged with the compiled code using the following command:
@@ -45,14 +54,4 @@ Once all have been implemented, native methods can be packaged with the compiled
cheerpjfy.py --natives=native/ some.jar
```
-## `CHEERPJ_COMPRESS(x)` macro
-
-CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS(x)` macro will encode the argument in parenthesis following such scheme. This macro is used automatically by the `cheerpjfy.py --stub-natives=` command, but can also be used manually.
-
-## `CHEERPJ_SET_CLASS(x)` macro
-
-Set the current internal class for resolving fields when using `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` macros.
-
-## `CHEERPJ_FIELD(x)` and `CHEERPJ_STATIC_FIELD(x)` macro
-
-The compiler replaces this macro with the encoded field name, it assumes the current class has been set by `CHEERPJ_SET_CLASS`.
+CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS` macro is used automatically by the `cheerpjfy.py --stub-natives=` command, but can also be used manually. For more information about macros visit [this page](/cheerpj2/reference/Command-Line-Options#--stub-nativesnativespath).
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 290c7c3d..5f9e85d7 100644
--- a/src/content/docs/cheerpj2/04-guides/Startup-time-optimization.md
+++ b/src/content/docs/cheerpj2/04-guides/Startup-time-optimization.md
@@ -42,7 +42,19 @@ When initialized with this option CheerpJ will keep track of the classes used at
`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.
+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. This optimisation can be used with our without AOT compiling.
+
+Usage example:
+
+```shell
+
+/cheerpj_2.3/cheerpjfy.py yourInput.jar --pack-jar yourOutput.jar
+
+```
+
+> It is important to use the same name on your input and output `.jar` files for your application to work. This action will overwrite your original `.jar` file with the packed one. We recommend backing up your original files somewhere else to keep their state in case you need to use them again.
+
+To use this command you will require to have java installed on your machine.
More details are available [here](/cheerpj2/reference/Command-Line-Options#pack-jarpackjar)
@@ -68,6 +80,12 @@ The result will look like this:
["/lts/file1", "/lt/file2"];
```
+If the output is not visible fully, you can use:
+
+```js
+document.write(cjGetRuntimeResources());
+```
+
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:
diff --git a/src/content/docs/cheerpj2/04-guides/Using-web-workers.md b/src/content/docs/cheerpj2/04-guides/Using-web-workers.md
new file mode 100644
index 00000000..b77fd37e
--- /dev/null
+++ b/src/content/docs/cheerpj2/04-guides/Using-web-workers.md
@@ -0,0 +1,72 @@
+---
+title: Using Web Workers
+---
+
+## Using the JavaScript Web Workers API
+
+CheerpJ supports running Java code in the background using Web Workers. To use this functionality you need to include the `loader.js` script as usual (e.g. `https://cjrtnc.leaningtech.com/latest/loader.js`). The script exposes the APIs described in [JavaScript Web Worker API](/cheerpj2/reference/WebWorker-API#javascript-web-worker-api). You can use CheerpJ in the main thread at the same time.
+
+All code in a Worker runs in parallel and asynchronously with the main thread. All the methods below return standard JavaScript `Promise`s, and you can use `.then(...)`, `.catch(...)` and `async/await` with them.
+
+### Creating and initializing a CheerpJ worker
+
+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");
+});
+```
+
+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.
+
+### Parameters and return values
+
+Web Workers do not share any memory with the main threads, and all interactions happen through messages. This imposes limitations on the type of data that can be passed around.
+
+| Data type | Limitations |
+| -------------------------------------------- | ------------------------------------------- |
+| byte/short/char/int/float/double | Fully supported in params and return values |
+| byte[]/short[]/char[]/int[]/float[]/double[] | Fully supported in params and return values |
+| JavaScript String | Supported in params, not return values |
+| Any Java object | Not supported in params or return values |
+
+Java arrays can either come from another Java method or they can be generated from a JS TypedArray using [cjTypedArrayToJava](/cheerpj2/reference/Runtime-API#cjtypedarraytojava).
+
+It is possible to move Java arrays from the main thread and others `CheerpJWorker`s. Please note that Java arrays are not copied, but _transferred_ across contexts. This increases efficiency, but also means that the data is not available any more from the calling thread. If the data needs be preserved you must manually make a copy.
+
+Java Strings, being Java objects, cannot be passed or returned. But JavaScript strings can be used as parameters and will be converted to Java Strings directly in the WebWorker context.
+
+## Using the Java API for Web 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.
+
+The Java version of the API is also extended to support `long`s in parameters and returned values. Currently they are converted to native JS values when passed to Workers, so their range is limited to +/-2^52.
+
+See the reference for [Java Web Worker API](/cheerpj2/reference/WebWorker-API#java-web-worker-api)
+
+Example usage:
+
+```java title="WW.java"
+import com.leaningtech.cheerpj.Worker;
+
+public class WW
+{
+ public static void main(String[] args)
+ {
+ Worker w = new Worker();
+ w.runMain("Hello", "");
+ }
+}
+```
+
+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
+```
+
+## Further reading
+
+- [Web Worker APIs (reference)](/cheerpj2/reference/WebWorker-API)
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 5964ef3e..fa293689 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
@@ -8,36 +8,96 @@ The basic usage of the `cheerpjfy.py` build script is:
./cheerpjfy.py application.jar
```
-The script also accept various command line options to customize the JAR.JS compilation process.
+For more information about this script, see [AOT optimization](/cheerpj2/guides/AOT-optimization).
-### --help
+### `--help`
Shows all the command line options
-### -v
+### `-v`
-Shows the CheerpJ version and the recommend `loader.js` to use in deployment
+Shows the CheerpJ version and the recommend `loader.js` to use in deployment.
-### --deps=DEPSPATHS
+### `--split`
-List of `:` separated JARs that this JAR depends on. Please note that all the listed JAR paths should be either relative to the target JAR or absolute.
+Splits generated JS into smaller modules.
-### --pack-jar=PACKJAR
+### `--no-runtime`
-Generate a packed version of the input JAR. Debug information and all code are removed.
+Do not automatically add the runtime to the class path.
-### -j NUMJOBS
+### `--natives=NATIVESPATH`
-Number of parallel compilation jobs
+Root of the native JS implementations for classes in this JAR file.
+Assuming the `/natives` directory exists:
+
+```shell
+cheerpjfy.py --natives=native/ some.jar
+```
+
+### `--deps=DEPSPATHS`
+
+List of `:` separated JARs that this JAR depends on. Please note that all the listed JAR paths should be either relative to the target JAR or absolute.
+
+```shell
+cheerpjfy.py --deps dependency1.jar:dependency2.jar my_application_archive.jar
+```
-### --work-dir=WORKDIRPATH
+### `--work-dir=WORKDIRPATH`
A directory where all the JARs are unpacked. This is useful to speed up multiple compilations of the same JARs and to select a different disk when not enough free space is available in the temporary directory. Keep in mind that the directory passed to the option must be manually created _before_ the command is run.
-### --natives=NATIVESPATH
+### `--core-classes-list=CORECLASSESLIST`
+
+File containing a list of classes that should be in the core module.
+
+### `--strip-jar=STRIPJAR`
+
+Generates a stripped version of the input JAR with all code replaced by nops for improved compression
-Root of the native JS implementations for classes in this JAR file
+### `--pack-jar=PACKJAR`
+
+Generate a packed version of the input JAR using the pack200 utility. Debug information and code are removed.
+To use this command you will require to have java installed on your machine.
+
+```shell
+cheerpjfy.py yourInput.jar --pack-jar yourOutput.jar
+```
-### --stub-natives=NATIVESPATH
+> This action will overwrite your original .jar file with the packed one when using the same filename (necessary for your app to work). We recommend backing up your original files somewhere else to keep their state in case you need to use them again.
-Generate stubs for all native methods from classes in this JAR. The parameter must be an existing directory, it will be populated with new JavaScript files for each class having native methods. **Note**: Existing files in the passed directory will be overwritten.
+### `--stub-natives=NATIVESPATH`
+
+Generates stubs for all native methods from classes in this JAR. The parameter must be an existing directory, it will be populated with new JavaScript files for each class having native methods.
+
+```shell
+mkdir native/
+cheerpjfy.py --stub-natives=native/ some.jar
+
+```
+
+> **Note**: Existing files in the passed directory will be overwritten.
+
+CheerpJ uses a compression scheme to encode mangled signatures. The `CHEERPJ_COMPRESS` macro is used automatically by this command, but can also be used manually.
+
+| macro | Description |
+| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
+| `CHEERPJ_COMPRESS` | Encode the argument in parenthesis following such scheme. |
+| `CHEERPJ_SET_CLASS` | Set the current internal class for resolving fields when using `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` macros. |
+| `CHEERPJ_FIELD` and `CHEERPJ_STATIC_FIELD` | The compiler replaces this macro with the encoded field name, it assumes the current class has been set by `CHEERPJ_SET_CLASS`. |
+
+### `--pack-classes-list=PACKCLASSESLIST`
+
+File containing a list of classes that should be compacted to the beginning and end of JAR file
+
+### `--pack-strip-binaries`
+
+Drop all dll/so/jnilib files from the JAR
+
+### `--ignore-classes=IGNORECLASSES`
+
+List of ',' separated classes that should not be compiled. Example --ignore-classes com.a.b.ClassOne,org.c.d.ClassTwo
+
+### `-j NUMJOBS`
+
+Number of parallel compilation jobs
diff --git a/src/content/docs/cheerpj2/05-reference/Java-API.md b/src/content/docs/cheerpj2/05-reference/Java-API.md
new file mode 100644
index 00000000..d81172d4
--- /dev/null
+++ b/src/content/docs/cheerpj2/05-reference/Java-API.md
@@ -0,0 +1,41 @@
+---
+title: Java API
+---
+
+An additional jar (`cheerpj-dom.jar`) in the CheerpJ [downloadable archive](https://leaningtech.com/download-cheerpj/) has been provided to allow interactions with the browser DOM directly from Java.
+
+This JAR provides declarations for all of the relevant Java interfaces and classes. In particular you will find them wrapped in the `com.leaningtech.client` package, for example the `Document` interface of the browser (documented [here](https://developer.mozilla.org/en-US/docs/Web/API/Document)) becomes `com.leaningtech.client.Document` with CheerpJ.
+
+The `com.leaningtech.client.Global` is a representation of the global namespace in the browser context. It only contains static methods and fields.
+
+Usage examples can be found at [DOM and JavaScript interoperability](/cheerpj2/guides/DOM-and-JavaScript-interoperability).
+
+## Global.JSString
+
+Converts a Java String to a JSString.
+
+```java
+JSString myjsstring = Global.JSString("Hi!");
+```
+
+## Global.JavaString
+
+Converts a JSString to a Java String.
+
+```java
+String mystring = Global.JavaString("Hello!");
+```
+
+## Global.jsCall / jsCallI / jsCallD / jsCallS
+
+Calls an arbitrary JavaScript function.
+| Method | Parameters | Output |
+| ------ | ------------------------------------ | ------ |
+| jsCall | String funcName, Object... arg | Object |
+| jsCallI | String funcName, Object... arg | Int |
+| jsCallD | String funcName, Object... arg | Double |
+| jsCallS | String funcName, Object... arg | JSString |
+
+## Further reading
+
+- [DOM and JavaScript interoperability](/cheerpj2/guides/DOM-and-JavaScript-interoperability)
diff --git a/src/content/docs/cheerpj2/05-reference/Runtime-API.md b/src/content/docs/cheerpj2/05-reference/Runtime-API.md
index 31f5e0e4..71a9c925 100644
--- a/src/content/docs/cheerpj2/05-reference/Runtime-API.md
+++ b/src/content/docs/cheerpj2/05-reference/Runtime-API.md
@@ -2,49 +2,13 @@
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
-
-A basic HTML file to load a CheerpJ application will look as follows:
-
-```html title="index.html"
-
-
-
-
- CheerpJ test
-
-
-
-
-
-```
-
-## Loading the CheerpJ runtime
-
-To load the most recent runtime, use the following link:
+CheerpJ exposes a simple JavaScript 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.
-```html
-
-```
-
-More in general, you can use this line:
+## Runtime initialization
-```html
-
-```
+### cheerpjInit
-where version is the specific runtime version you want to link to.
-
-## cheerpjInit
+`cheerpjInit(options)`
`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.
@@ -56,7 +20,7 @@ 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:
@@ -72,7 +36,7 @@ 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.
@@ -82,7 +46,7 @@ Example:
cheerpjInit({ disableErrorReporting: true });
```
-### `disableLoadTimeReporting`
+#### `disableLoadTimeReporting`
CheerpJ automatically get data about loading time. Setting this option to `true` disables this system.
@@ -92,15 +56,23 @@ Example:
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`
+```js
+cheerpjInit({ enableInputMethods: true });
+```
+
+#### `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.
-### `javaProperties`
+```js
+cheerpjInit({ enableProguardTrace: true });
+```
+
+#### `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.
@@ -110,35 +82,43 @@ Example usage:
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)`
+```js
+cheerpjInit({ listener: cheerpjListener });
+```
+
+#### `jsLoadReason`
-**Please note that enabling this listener may have significant performance impact and should not be used in production**
+> **Warning:** enabling this listener may have significant performance impact and should not be used in production.
For each new .jar.js to be loaded, CheerpJ will call this function. This can be useful to debug the reason why some parts of the runtime are loaded, if unexpected.
+**Parameters:**
+
- `scriptName`: The name of the JS file being loaded
- `directReason`: A CheerpJ uncompressed and mangled symbol. The method that most directly caused the load. This might not be very useful since it will most often be a `java.lang.ClassLoader` method. Can be `(Internal)` if it could not be detected.
- `userReason`: A CheerpJ uncompressed and mangled symbol. The last non-runtime method in the stack before the loading. This should be more useful in understanding the user code that introduces the dependency. Can be `(Internal)` if it could not be detected.
-Example usage:
+Example:
```js
var cheerpjListener = {jsLoadReason:function(scriptName, directReason, userReason){ ... }};
cheerpjInit({listener:cheerpjListener});
```
-#### `preloadProgress(loadedFiles, totalFiles)`
+#### `preloadProgress`
+
+This listener may be used in combination with [`preloadResources`](#preloadresources) 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.
+**Parameters:**
- `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:
+Example:
```js
function showPreloadProgress(loadedFiles, totalFiles) {
@@ -148,7 +128,7 @@ 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.
@@ -158,7 +138,7 @@ Example:
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.
@@ -181,7 +161,7 @@ cheerpjInit({
});
```
-### `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.
@@ -193,7 +173,7 @@ 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.
@@ -201,7 +181,13 @@ 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`
+Example:
+
+```js
+cheerpjInit({ status: "splash" });
+```
+
+#### `appletParamFilter`
Some applications may need to have some parameter modified before getting those inside the applet.
@@ -216,7 +202,21 @@ cheerpjInit({
});
```
-## cheerpjCreateDisplay
+#### `enablePreciseAppletArchives`
+
+Boolean option which makes the classloader behavior similar to the native Java plugin. For better performance it is recommended to upgrade to CheerpJ 3.
+
+Example:
+
+```js
+cheerpjInit({ enablePreciseAppletArchives: true });
+```
+
+## Graphics
+
+### cheerpjCreateDisplay
+
+`cheerpjCreateDisplay(w, h, oldElem, useLoadingAnimation)`
This method will create the HTML element that will contain all Java windows. It is only required to run graphical applications.
@@ -226,10 +226,14 @@ 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 `.jar`(s)
**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.
+### cheerpjRunMain
+
+`cheerpjRunMain(className, classPath, ...)`
+
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.
```js
@@ -241,12 +245,20 @@ cheerpjRunMain(
);
```
+### cheerpjRunJar
+
+`cheerpjRunJar(jarName, ...)`
+
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);
```
+### cheerpjRunJarWithClasspath
+
+`cheerpjRunJarWithClasspath(jarName, classPath, ...)`
+
Optionally, if your JAR also need additional dependencies, you can use.
```js
@@ -260,18 +272,19 @@ cheerpjRunJarWithClasspath(
In all cases the arguments should be JavaScript Strings.
-## cjCall / cjNew
+## Calling Java from JS
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.
-Calling Java constructors from JavaScript:
+Both `cjNew` and `cjCall` return standard JavaScript `Promise`s. They can be transparently used in other calls to `cjNew/cjCall` or you can use `.then(...)` and `.catch(...)` to access the resulting value and handle errors. It is also possible to use `async/await` (either natively or through a JS transpiler) to write sync-like code using `cjNew/cjCall` as async primitives.
-```js
-/* Equivalent Java code: myClass object = com.my.Java.package.myClass(argument1) */
-var object = cjNew("com.my.Java.package.myClass", argument1);
-```
+### cjCall
+
+`cjCall(objOrClassNameOrInvoker, methodName, ...)`
-Call static Java methods from JavaScript:
+Call static Java methods from JavaScript.
+
+Example 1:
```js
/* Equivalent Java code: int returnVal = com.my.Java.package.myClass.method(argument1, argument2, argument3); */
@@ -284,16 +297,31 @@ var returnVal = cjCall(
);
```
-Call Java methods from JavaScript:
+Example 2:
```js
/* Equivalent Java code: int returnVal = object.method(argument1, argument2, argument3); */
var returnVal = cjCall(object, "method", argument1, argument2, argument3);
```
-Both `cjNew` and `cjCall` return standard JavaScript `Promise`s. They can be transparently used in other calls to `cjNew/cjCall` or you can use `.then(...)` and `.catch(...)` to access the resulting value and handle errors. It is also possible to use `async/await` (either natively or through a JS transpiler) to write sync-like code using `cjNew/cjCall` as async primitives.
+### cjNew
+
+`cjNew(classNameOrInvoker, ...)`
+
+Calls Java constructors from JavaScript.
+
+Example:
+
+```js
+/* Equivalent Java code: myClass object = com.my.Java.package.myClass(argument1) */
+var object = cjNew("com.my.Java.package.myClass", argument1);
+```
+
+### cjResolveCall / cjResolveNew
-## cjResolveCall / cjResolveNew
+`cjResolveCall(className, methodName, types)`
+
+`cjResolveNew(className, types)`
Using `cjCall/cjNew` is convenient, but under the hood Java reflection APIs are used, which may have a significant performance impact if used heavily. If you plan to use `cjCall/cjNew` many times it is convenient to go through reflection APIs only once by using the `cjResolveCall/cjResolveNew` API.
@@ -346,7 +374,9 @@ Please note that this convenient form can unfortunately only be used on the main
## Data conversion
-### cjStringJavaToJs(str) / cjStringJsToJava(str)
+### cjStringJavaToJs
+
+`cjStringJavaToJs(javaString)`
```js
var jsString = cjStringJavaToJs(javaString);
@@ -354,6 +384,10 @@ var jsString = cjStringJavaToJs(javaString);
This converts a Java string into a JavaScript string. This operation implies a copy.
+### cjStringJsToJava
+
+`cjStringJsToJava(jsString)`
+
```java
String javaString = cjStringJStoJava(jsString);
```
@@ -362,6 +396,8 @@ This converts a JavaScript string into a Java string. This operations also impli
### cjTypedArrayToJava
+`cjTypedArrayToJava(array)`
+
Converts a TypedArray to a Java compatible primitive array. This operation implies a copy. Data is converted as follows:
| Typed Array | Java array |
@@ -375,8 +411,34 @@ Converts a TypedArray to a Java compatible primitive array. This operation impli
| Float32Array | float[] |
| Float64Array | double[] |
-## Preloading APIs
+## Preloading
### 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.
+
+## Filesystem
+
+### cjFileBlob
+
+`cjFileBlob(fileName)`
+
+Used to download files from the CheerpJ filesystem. It returns a promise that eventually resolve to a Blob object, which can be downloaded with standard HTML5 techniques.
+
+### cheerpjAddStringFile
+
+`cheerpjAddStringFile(fileName, str)`
+
+Used to add files into the `/str/` mount point filesystem.
+
+Example:
+
+```js
+cheerpjAddStringFile("/str/fileName.txt", "Some text in a JS String");
+```
+
+## Tracing
+
+### cjGetProguardConfiguration
+
+To be used on the browser console to download a ProGuard configuration file (`cheerpj.pro`). See [enableProguardTrace](/cheerpj2/reference/Runtime-API#enableproguardtrace).
diff --git a/src/content/docs/cheerpj2/05-reference/WebWorker-API.md b/src/content/docs/cheerpj2/05-reference/WebWorker-API.md
index be60903d..faa2f8f1 100644
--- a/src/content/docs/cheerpj2/05-reference/WebWorker-API.md
+++ b/src/content/docs/cheerpj2/05-reference/WebWorker-API.md
@@ -1,12 +1,10 @@
---
-title: Web Worker API
+title: Web Worker APIs
---
-CheerpJ supports running Java code in the background using Web Workers. To use this functionality you need to include the `loader.js` script as usual (e.g. `https://cjrtnc.leaningtech.com/latest/loader.js`). The script exposes the APIs described below. You can use CheerpJ in the main thread at the same time.
+## JavaScript Web Worker API
-All code in a Worker runs in parallel and asynchronously with the main thread. All the methods below return standard JavaScript `Promise`s, and you can use `.then(...)`, `.catch(...)` and `async/await` with them.
-
-## Creating and initializing a CheerpJ worker
+### CheerpJWorker
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.
@@ -17,26 +15,11 @@ w.cheerpjInit().then(function (e) {
});
```
-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.
-
-## Parameters and return values
-
-WebWorkers do not share any memory with the main threads, and all interactions happen through messages. This imposes limitations on the type of data that can be passed around.
-
-| Data type | Limitations |
-| -------------------------------------------- | ------------------------------------------- |
-| byte/short/char/int/float/double | Fully supported in params and return values |
-| byte[]/short[]/char[]/int[]/float[]/double[] | Fully supported in params and return values |
-| JavaScript String | Supported in params, not return values |
-| Any Java object | Not supported in params or return values |
+For more information visit the [Using Web Workers](/cheerpj2/guides/Using-web-workers) guide.
-Java arrays can either come from another Java method or they can be generated from a JS TypedArray using [cjTypedArrayToJava](/cheerpj2/reference/Runtime-API#cjtypedarraytojava).
+### CheerpJWorker.cheerpjRunMain
-It is possible to move Java arrays from the main thread and others `CheerpJWorker`s. Please note that Java arrays are not copied, but _transferred_ across contexts. This increases efficiency, but also means that the data is not available any more from the calling thread. If the data needs be preserved you must manually make a copy.
-
-Java Strings, being Java objects, cannot be passed or returned. But JavaScript strings can be used as parameters and will be converted to Java Strings directly in the WebWorker context.
-
-## CheerpJWorker.cheerpjRunMain
+`cheerpjRunMain(className, classPath, ...)`
Runs a Java main method in the WebWorker context
@@ -44,7 +27,9 @@ Runs a Java main method in the WebWorker context
w.cheerpjRunMain("ClassName", classPath, arg1, arg2).then(...)
```
-## CheerpJWorker.cjCall
+### CheerpJWorker.cjCall
+
+`cjCall(objOrClassNameOrInvoker, methodName, ...)`
Executes a static Java method in the WebWorker content
@@ -52,7 +37,9 @@ Executes a static Java method in the WebWorker content
w.cjCall("ClassName", "methodName", arg1, arg2).then(...)
```
-## CheerpJWorker.cjResolveCall
+### CheerpJWorker.cjResolveCall
+
+`cjResolveCall(className, methodName, types)`
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.
@@ -65,54 +52,72 @@ w.cjResolveCall("ClassName", "methodName", null).then( // or array of parameter
);
```
-## 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 title="Worker.java"
-package com.leaningtech.cheerpj;
-
-public class Worker
-{
- // Initialize the Worker object, this method is blocking
- public Worker();
- // Runs the main method of the given class in the Web Worker context, this method is blocking
- public void runMain(String className, String classPath, Object... arg);
- // Runs the given static method in the Web Worker context, this method is blocking
- public Object call(String className, String methodName, Object... arg);
- // Same as "call". These should be used when primitives are expected.
- public int callI(String className, String methodName, Object... arg);
- public double callD(String className, String methodName, Object... arg);
- public long callL(String className, String methodName, Object... arg);
- // Returns an handle to a resolved method, this method is blocking
- public Object resolveCall(String className, String methodName, String[] types);
- // Run the given resolved method handle in the Web Worker context, this method is blocking
- public Object call(Object resolvedFunc, Object... arg);
- public int callI(Object resolvedFunc, Object... arg);
- public double callD(Object resolvedFunc, Object... arg);
- public long callL(Object resolvedFunc, Object... arg);
-}
-```
+### CheerpJWorker.cjFileBlob
-The Java version of the API is also extended to support `long`s in parameters and returned values. Currently they are converted to native JS values when passed to Workers, so their range is limited to +/-2^52.
+`cjFileBlob(fileName)`
-Example usage:
+Used to download files from the CheerpJ filesystem. It returns a promise that eventually resolve to a Blob object, which can be downloaded with standard HTML5 techniques.
-```java title="WW.java"
-import com.leaningtech.cheerpj.Worker;
+### CheerpJWorkercheerpj.AddStringFile
+
+`AddStringFile(fileName, str)`
+
+Used to add files into the `/str/` mount point filesystem.
+
+## Java Web Worker API
+
+### Worker
+
+Initializes the Worker object, this method is blocking.
+
+```java
+Worker w = new Worker();
-public class WW
-{
- public static void main(String[] args)
- {
- Worker w = new Worker();
- w.runMain("Hello", "");
- }
-}
```
-To build the class you need to add `cheerpj-public.jar` to the classpath
+### runMain
+
+Runs the main method of the given class in the Web Worker context, this method is blocking.
+
+| Parameters | Output |
+| ------------------------------------------------- | ------ |
+| String className, String classPath, Object... arg | None |
+
+```java
-```shell
-javac -cp cheerpj_install_dir/cheerpj-public.jar WW.java
+w.runMain("Hello", "");
```
+
+### call / callI / callD / callL (for static method)
+
+Runs the given static method in the Web Worker context, this method is blocking
+
+callI, callD and callL should be used when primitives are expected.
+| Method | Parameters | Output |
+| ------ | ------------------------------------ | ------ |
+| call | String className, String methodName, Object... arg | Object |
+| callI | String className, String methodName, Object... arg | Int |
+| callD | String className, String methodName, Object... arg | Double |
+| callL | String className, String methodName, Object... arg | Long |
+
+### resolveCall
+
+Returns an handle to a resolved method, this method is blocking.
+| Parameters | Output |
+| ------------------------------------------------- | ------ |
+| String className, String methodName, String[] types | Object |
+
+### call / callI / WcallD / callL (for resolved method)
+
+Runs the given resolved method handle in the Web Worker context, this method is blocking
+
+| Method | Parameters | Output |
+| ------ | ------------------------------------ | ------ |
+| call | Object resolvedFunc, , Object... arg | Object |
+| callI | Object resolvedFunc, , Object... arg | Int |
+| callD | Object resolvedFunc, , Object... arg | Double |
+| callL | Object resolvedFunc, , Object... arg | Long |
+
+## Further reading
+
+- [Using Web Workers (guide)](/cheerpj2/guides/Using-web-workers)
diff --git a/src/content/docs/cheerpj2/index.mdx b/src/content/docs/cheerpj2/index.mdx
index 35addee3..97b8c829 100644
--- a/src/content/docs/cheerpj2/index.mdx
+++ b/src/content/docs/cheerpj2/index.mdx
@@ -1,59 +1,69 @@
---
title: CheerpJ
-subtitle: Convert Java to WebAssembly and JavaScript
+subtitle: JVM replacement for the browser
---
import LatestBlogPostPill from "@/components/LatestBlogPostPill.astro";
-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.
+CheerpJ is a **drop-in replacement** for the JVM, and is compatible with 100% of Java 8, including Swing, reflection and dynamic class loading.
-Please visit the project [website](https://leaningtech.com/cheerpj/).
+![](/cheerpj2/assets/cheerpj_visual_2.png)
-**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)
+With CheerpJ, you can:
-**Link to latest runtime**
+- Run existing **Java applications** in the browser with no changes
+- Include **Java applets** in webpages without legacy plugins
+- Migrate **Java Web Start / JNLP** applications to work on modern systems
+- Use Java libraries in JavaScript/TypeScript seamlessly
-```
-https://cjrtnc.leaningtech.com/2.3/loader.js
-```
+## Getting started
-If you are unsure how to start, try our [tutorial](/cheerpj2/getting-started/Tutorial).
+Know what you're building? Jump straight to the relevant tutorial:
-## What is CheerpJ?
+
-![](/cheerpj2/assets/cheerpj_visual_2.png)
+## What is CheerpJ?
**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.
-3. The CheerpJ on-the-fly Java-to-JavaScript compiler, a reduced JavaScript version of the CheerpJ compiler that can be distributed with applications converted with CheerpJ to enable dynamic features of Java such as reflection.
+1. The CheerpJ AOT compiler, an LLVM-based Java-bytecode to JavaScript compiler. 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. The CheerpJ runtime is cloud-hosted and accessed by the community free of charge for non-commercial purposes only. For self-hosting and commercial please visit our [licensing page](https://cheerpj.com/licensing/).
+3. The CheerpJ on-the-fly Java-to-JavaScript compiler, a reduced JavaScript version of the CheerpJ compiler that can be distributed with applications compiled with CheerpJ to enable dynamic features of Java such as reflection.
## What is unique about CheerpJ?
-1. CheerpJ can convert 100% of Java including reflection and proxy class creation, with no manual intervention on the code.
+1. CheerpJ can handle 100% of Java 8, including Swing, reflection and dynamic class loading with no manual intervention on the code.
2. CheerpJ works directly on Java bytecode, and does not require access to the Java source code.
-3. CheerpJ comes with a full Java SE runtime, inclusive of Swing/AWT. It supports audio, printing, and any other Java SE component. The runtime supports WebAssembly for optimal performance and size.
+3. CheerpJ comes with a full Java SE runtime, inclusive of Swing/AWT. It supports audio, printing, and any other Java SE features. The runtime supports WebAssembly for optimal performance and size.
4. The JavaScript code generated by CheerpJ is highly optimised and garbage-collectible.
5. CheerpJ enables bidirectional Java-JavaScript interoperability. JavaScript libraries, as well as the DOM, can be called and manipulated from Java. Converted Java modules can be invoked from JavaScript.
6. CheerpJ supports Java multi-threading. In addition, it allows to create concurrent applications by using WebWorkers.
-## Getting Started
+## Licensing
-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:
-
-1. [CheerpJ Tutorial](/cheerpj2/getting-started/Tutorial)
-2. [Getting Started](/cheerpj2/getting-started/Getting-Started)
-3. [Command Line Options](/cheerpj2/reference/Command-Line-Options)
+CheerpJ is free for technical evaluation and non-commercial use. See [licensing](https://cheerpj.com/licensing/) for details.
## Demos
-Several demos of CheerpJ can be found [here](https://leaningtech.com/demo/?cheerpjfilter).
+Several demos of CheerpJ can be found [here](https://leaningtech.com/demo/).
+
+## Feedback
-## Bugs and Questions
+[Report issues on GitHub](https://github.com/leaningtech/cheerpj-meta/issues)
-We welcome any feedback and bug report on it through our [Issue Tracking](https://github.com/leaningtech/cheerpj-meta/issues).
+[Join the Discord server](https://discord.leaningtech.com/)
diff --git a/src/layouts/DocsArticle.astro b/src/layouts/DocsArticle.astro
index f5a8c105..43fe52c6 100644
--- a/src/layouts/DocsArticle.astro
+++ b/src/layouts/DocsArticle.astro
@@ -72,8 +72,10 @@ const contributeLinks = [
)
}
-
-
+
+
{headings &&
}
diff --git a/src/lib/products.ts b/src/lib/products.ts
index 86a51b85..5b865a7b 100644
--- a/src/lib/products.ts
+++ b/src/lib/products.ts
@@ -30,8 +30,9 @@ export const products: { [product in Product]: ProductData } = {
href: "/cheerpj2",
logotype: cheerpjLogotype,
favicon: "/cheerpj2/favicon.ico",
- subtitle: "Run Java in the browser",
- description: "Compile Java bytecode to WebAssembly and JavaScript.",
+ subtitle: "Java Virtual Machine replacement for the browser",
+ description:
+ "Run Java 8 applications, libraries, applets, Java Web Start, and Oracle Forms on the web without legacy plugins.",
},
cheerpj3: {
id: "cheerpj3",
diff --git a/tailwind.config.cjs b/tailwind.config.cjs
index f1de8c55..c526e4e6 100644
--- a/tailwind.config.cjs
+++ b/tailwind.config.cjs
@@ -22,6 +22,9 @@ const exportColorsAsCssVariables = plugin(({ addBase, theme }) => {
/** @type {import('tailwindcss').Config} */
const disabledCss = {
+ pre: false,
+ code: false,
+ "pre code": false,
"code::before": false,
"code::after": false,
"blockquote p:first-of-type::before": false,