code-playpad 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/JAVA-COMPATIBILITY.md +7 -7
- package/README.md +50 -5
- package/dist/cdn.js +2 -2
- package/dist/{element-Bh4TdnGA.js → element-yit-fyhg.js} +1 -1
- package/dist/element.js +1 -1
- package/dist/index.js +1 -1
- package/dist/java-BHbRkfsQ.js +1 -0
- package/dist/java-BuW8Eeg_.js +6 -0
- package/dist/{java-library.generated-Bg_JSWb_.js → java-library.generated-I0MB-4YJ.js} +1 -1
- package/dist/{javascript-C1_thu8i.js → javascript-krS-hdur.js} +1 -1
- package/dist/{pyodide-CqcU3YGb.js → pyodide-C9S4Me6g.js} +1 -1
- package/dist/react.js +1 -1
- package/dist/runtime/java-library.generated.d.ts +3 -3
- package/dist/runtime/java-worker.generated.d.ts +3 -3
- package/dist/standalone.js +1 -1
- package/dist/{worker-runtime-Kjkt5ChF.js → worker-runtime-B64HCt-B.js} +1 -1
- package/package.json +1 -1
- package/dist/java-CDMXnFT7.js +0 -6
- package/dist/java-DrWI9a5Q.js +0 -1
package/JAVA-COMPATIBILITY.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<!-- GENERATED by scripts/sync-java.mjs from java-online-compiler@0.
|
|
1
|
+
<!-- GENERATED by scripts/sync-java.mjs from java-online-compiler@0.27.0 (5ad78d01e8516969bd4d501fdf0f4857cedb49ad). Do not edit. -->
|
|
2
2
|
|
|
3
|
-
> This is the compatibility table of the Java engine that code-playpad ships (engine 0.
|
|
3
|
+
> This is the compatibility table of the Java engine that code-playpad ships (engine 0.27.0).
|
|
4
4
|
> Paths such as `tests/…`, `SPEC.md` and `docs/…` refer to the engine's source (`java-engine/` in code-playpad's repository), which is not part of the package.
|
|
5
5
|
|
|
6
|
-
# Compatibility — engine 0.
|
|
6
|
+
# Compatibility — engine 0.27.0 (Stage A, compact source files, objects, numbers and control flow, collections, lambdas, practice mode, String, format, regex, Math, Random, System, Scanner and IO.readln, inheritance, interfaces, Object, instanceof, enums, records, exceptions, hash order, fixed collections, TreeMap, TreeSet, LinkedList, Stack, lambdas, method references, generic classes and methods, var, annotations, varargs, anonymous classes, streams, subList, local classes, raw types, float, byte and short, pattern matching, sealed classes, BigInteger, BigDecimal, EnumMap, EnumSet, fast I/O, static imports, initializer blocks, text blocks, enum constant bodies, Interface.super)
|
|
7
7
|
|
|
8
8
|
This document records what the engine accepts, what it rejects, and the evidence that it behaves like Java. Every method of every library class, with its status and the tests that call it, is in docs/feature-manifest.json (`npm run manifest`). The reference is Java SE 25 (SPEC.md §4), and what the engine implements is **a documented subset of Java 25**, not "Java 25".
|
|
9
9
|
|
|
@@ -15,7 +15,7 @@ Every feature has one status:
|
|
|
15
15
|
|
|
16
16
|
> **Evidence:** everything below is checked against the pinned JDK, Temurin 25.0.4.1 (docs/reference-jdk.md).
|
|
17
17
|
> - **Golden programs:** all 47 in `tests/programs` (the SPEC.md §4.1 Stage A corpus among them) match byte for byte: stdout, stderr, and exit code.
|
|
18
|
-
> - **Recorded snippets:** all
|
|
18
|
+
> - **Recorded snippets:** all 1558 cases in `tests/jdk-cases` match. 1537 match byte for byte (once the JDK's own stack frames are removed, as *Known divergences* explains); the other 21 are listed under *Known divergences*, each with the narrower comparison the tests apply to it.
|
|
19
19
|
> - **Practice corpus:** all 10 Stage 4 programs in `tests/corpus` (docs/practice-corpus.md) run and match.
|
|
20
20
|
> - **Field corpus:** 212 of 223 programs written as learners and solvers write Java, kept whether or not the engine supports them, match the JDK exactly. None runs differently; 10 are rejected as unsupported, 1 stops on an engine limitation and none on the instruction limit (`corpus/REPORT.md`, docs/corpus-harness.md).
|
|
21
21
|
|
|
@@ -36,12 +36,12 @@ Every feature has one status:
|
|
|
36
36
|
| `toString()`, `equals(Object)`, `hashCode()` | Supported | Declared or inherited, they are used wherever the JDK uses them: string conversion and `println`, `HashMap` and `HashSet` keys, `List.contains`. Without them, `Object`'s: `Node@hash` and identity. `super.toString()` is `Object`'s own. `@Override` is checked with javac's reasons. |
|
|
37
37
|
| **Inheritance** (`extends`, JLS 8.1.4) | Supported with limits | A class extends one class of the program: inherited fields and methods, overriding with dispatch on the object's class, `super(...)` (or the implicit `super()`), `super.f()` and `super.x`, covariant return types, field hiding, static methods inherited and hidden. Superclass constructors and field initializers run first, so a superclass constructor calling an overridden method sees the subclass's fields at their defaults, as on the JDK. `abstract` classes and methods, `final` classes and methods, `protected`. javac's errors: `B is not abstract and does not override abstract method f() in A`, `A is abstract; cannot be instantiated`, `cannot inherit from final A`, `f() in B cannot override f() in A` (with `overridden method is final`, `attempting to assign weaker access privileges; was public`, `return type long is not compatible with int`, `overriding method is static`), `cyclic inheritance involving A`, `abstract method f() in A cannot be accessed directly`, `x has private access in A` for a superclass's private member. NPE messages name the receiver's static type (`Cannot invoke "Main$B.f()"`), as the JDK does. A class may also extend the JDK's exception classes (*Exceptions* below). Extending other library classes, extending an inner (non-static) class, and statements before `super(...)` (Java 25's flexible constructor bodies) are unsupported. |
|
|
38
38
|
| **Interfaces** (JLS 9) | Supported with limits | Interfaces of the program, nested or top-level: abstract methods, `default` methods, `static` methods, `private` methods, constants; `extends` among interfaces; a class implementing several. Implementing methods must be `public` (`g() in C cannot implement g() in I`), and two unrelated defaults conflict (`types I and J are incompatible;`). A class may also implement the library's `Comparable<T>`, `Comparator<T>`, `Iterable<T>` and `Iterator<T>`: then sorting, `PriorityQueue`, `Collections.sort`, for-each and `Objects.compare` call its methods as Java code. `Interface.super.f()` calls a direct superinterface's default method (JLS 15.12.3), also from an interface extending it and inside a lambda, with javac's errors: `not an enclosing class: I` (not a direct superinterface, or a static context), `bad type qualifier I in default super call` (`redundant interface I is extended by J`), `abstract method m() in I cannot be accessed directly`, `illegal static interface method call`. `Main.super.f()` in Main is `super.f()`; `Outer.super.f()` for an enclosing class and implementing other library interfaces are unsupported. |
|
|
39
|
-
| The `Object` type | Supported | Variables, parameters, fields, arrays (`Object[]`), returns. Any value converts to `Object` (primitives box). Its methods on any value: `toString()`, `equals(Object)`, `hashCode()` (each dispatched on the value's class: a String compares by content, an `Integer` by value) and `getClass()`. `new Object()
|
|
39
|
+
| The `Object` type | Supported | Variables, parameters, fields, arrays (`Object[]`), returns. Any value converts to `Object` (primitives box). Its methods on any value: `toString()`, `equals(Object)`, `hashCode()` (each dispatched on the value's class: a String compares by content, an `Integer` by value) and `getClass()`. `new Object()` makes an object with nothing but identity (`java.lang.Object@…`, equal only to itself). `wait`, `notify` and `clone` are unsupported. |
|
|
40
40
|
| Casts and `instanceof` (JLS 15.16, 15.20.2) | Supported | Casts between classes, interfaces, library types and arrays, checked as javac checks them (`incompatible types: A cannot be converted to B` for impossible ones) and when they run: `ClassCastException: class Main$A cannot be cast to class Main$B (…)`, as the JDK words it. `(int) object` checks for an `Integer`, then unboxes. `x instanceof T`, raw types included (`x instanceof List`), and the type pattern `x instanceof T t`, whose variable is in scope where the test is true: in `&&`, the `if` or `while` body, after `if (!(x instanceof T t)) return;` (JLS 6.3.1). A store into an array seen through a supertype is checked: `ArrayStoreException: java.lang.String`. A cast the run cannot fully check (`(T) o`, `(T[]) new Object[n]`, `(List<Integer>) o`) checks the erasure and gives javac's `[unchecked] unchecked cast` warning (with `required:`, `found:` and a `where` clause); a cast between different parameterizations (`(List<String>) intList`) is javac's `incompatible types`. Record patterns: `o instanceof Line(Point(int a, int b), var to)`, their variables in scope as a type pattern's are. `instanceof` with a parameterized type (`x instanceof List<Integer>`) is unsupported. |
|
|
41
41
|
| **Enums** (JLS 8.9) | Supported with limits | Nested or top-level, with fields, constructors (with the hidden name and ordinal, so NPE messages say `<parameter3>`), methods, static members, and `implements`. `values()` (a new array each time), `valueOf(String)` (`IllegalArgumentException: No enum constant Main.Color.PURPLE`, `NullPointerException: Name is null`, with the enum's own frame), `name()`, `ordinal()`, `compareTo` (by ordinal), `toString()` (overridable), `getDeclaringClass()`, `equals` and `hashCode` (identity). The constants are made when the enum initializes, before its other static fields; an exception there is `ExceptionInInitializerError`. `switch` on an enum, with simple or qualified labels (`case RED`, `case Color.RED`); a switch expression naming every constant needs no `default`; a null selector fails as the JDK's does (`Cannot invoke "Main$Color.ordinal()"`). Enums are Comparable, so they sort and queue in declaration order. javac's errors: `enum classes may not be instantiated`, `modifier public not allowed here`, `name() in E cannot override name() in Enum`. `EnumMap` and `EnumSet` are supported (see *Library*). Constants with a class body (`PLUS { int apply(int a, int b) { return a + b; } }`): each is an anonymous subclass of the enum (`Main$Op$1`, numbered with the anonymous classes of the constants' arguments, before the members'), with its own fields, methods, `super` calls and initializer blocks; `getClass()` is the body's class and `getDeclaringClass()` the enum, also in EnumMap and EnumSet. An enum may leave abstract methods to its constants' bodies. javac's errors: `<anonymous Main$Op$2> is not abstract and does not override abstract method apply(int,int) in Op`, `Op is abstract; cannot be instantiated` (a constant without a body), `non-static variable symbol cannot be referenced from a static context` (the enum's private members are not inherited by a body), `equals(Object) in <anonymous Main$Op$1> cannot override equals(Object) in Enum`. |
|
|
42
42
|
| **Records** (JLS 8.10) | Supported with limits | Nested or top-level, with components, accessors (generated, or declared: `invalid accessor method in record R`), the canonical constructor (generated, compact `R { ... }` with the fields assigned after its body, or explicit), other constructors (which must call another: `constructor is not canonical, so it must invoke another constructor of class R`), static fields and methods, instance methods, and `implements`. `toString()` (`Point[x=1, y=2]`, components as String.valueOf shows them, with the record's own frame when one fails), `equals` (doubles compared as `Double.compare` does) and `hashCode` (`31 * h + hash(component)`) as the JDK computes them, unless declared. javac's errors: `field declaration must be static`, `cannot assign a value to final variable v`. Generic records (`record Pair<A, B>(A first, B second)`) are supported; so are local records and record patterns (see *Pattern matching*). |
|
|
43
43
|
| `getClass()`, `X.class` | Supported with limits | A `Class` value per class: `getName()` (`Main$Node`, `[I`), `getSimpleName()` (`Node`, `int[]`), `isInterface()`, `isArray()`, printing as `class Main$Node`, and `==` between classes, as `equals` methods use it. `X.class` is a `Class<X>` (so `new EnumMap<>(Day.class)` infers its key type); `Class<?>` may be declared. The reflection methods are unsupported. |
|
|
44
|
-
| Running a file | Supported with limits | Behaves like `java <entry>` in source-file mode.
|
|
44
|
+
| Running a file, and programs in several files (JEP 458) | Supported with limits | Behaves like `java <entry>` in source-file mode. The program's other `.java` files (`Session.java` beside `Main.java`) are compiled as the JDK's launcher compiles them: a file when the program first names the class it is named after, so a file nothing names is never compiled, and its errors never reported. Each file has its own imports. A class of the entry file wins over another file's of the same name. Errors and stack traces name each file (`Session.java:2: error: …`, `at Session.describe(Session.java:5)`); where the JDK prints another file's absolute path on disk, the engine prints its name. A file's warnings print again when the program first uses one of its classes, as the launcher's second compilation prints them (a class literal, `Helper.class`, is not counted as a use). Limits: 32 files, 500,000 characters per file and 1,000,000 together. Unsupported: `package` declarations, folders, another compact source file with a `main`, and using another file's secondary class (one not named after its file) from outside that file, which the JDK finds only if that file happened to be compiled first. |
|
|
45
45
|
| No class / no usable main | Supported | `error: no class declared in source file`; `error: can't find main(String[]) or main() method in class: Main`; `error: can't find class: Main`; for a compact file, `compact source file does not have main method in the form of void main() or void main(String[] args)` |
|
|
46
46
|
| `import`: single-type and on-demand | Supported with limits | `import java.util.List;` and `import java.util.*;` for the supported java.util classes (see *Library*); the java.lang ones need no import. A compact source file sees java.util without imports, as Java 25's implicit `import module java.base` gives it. A wrong name gets javac's error: `package java.utill does not exist`, or `cannot find symbol` with `location: package java.util`. Real JDK classes outside the subset (`BitSet`, `LocalDate`, …) are unsupported where they are used. Classes of java.io, java.math, java.util.function and java.util.stream that the subset has are imported the same way. |
|
|
47
47
|
| `import static`: single and on-demand (JLS 7.5.3, 7.5.4) | Supported | Methods and fields of the supported classes: `import static java.lang.Math.*;`, `import static java.lang.System.out;`, `import static java.util.stream.Collectors.*;`, `import static java.util.Map.entry;`, and member types (`import static java.util.Map.Entry;`). A simple name means the program's own local, field or method first, then a single import, then an on-demand one (JLS 6.4.1). A method of the class or an enclosing one, Object's included, hides every import of that name, so `toString(a)` with `Arrays.*` imported is javac's `method toString in class Object cannot be applied`. Overloads from several on-demand imports are resolved together (`sort(int[])` from Arrays, `sort(List)` from Collections). javac's errors: `reference to MAX_VALUE is ambiguous` (fields, and methods equally specific in two classes), `cannot find symbol` with `symbol: static foo`, a missing class or package, `static import only from classes and interfaces`. Imported constants are constants (switch labels). Importing from a JDK class outside the subset (`TimeUnit`) is fine until a name from it is used, which is unsupported. |
|
|
@@ -114,7 +114,7 @@ Every feature has one status:
|
|
|
114
114
|
| `System.out` / `System.err` as values; `flush()`, `close()`, `checkError()` | Supported | Passed to `PrintWriter` or `OutputStreamWriter` as the `OutputStream` they are. `System.out` prints at once, so `flush()` has nothing to do. Closing it, directly or through a writer over it, drops everything printed to it afterwards, as on the JDK; a closed `System.err` drops an uncaught exception's trace too. `PrintStream` as a declared type, `write` and `append` are unsupported. |
|
|
115
115
|
| `System.out` / `System.err`: `printf(String, Object...)`, `format(String, Object...)` | Supported with limits | As `String.format`, below. The call is a statement: the `PrintStream` it returns cannot be used (`System.out.printf(...).println()` is unsupported). The `Locale` overloads are unsupported. |
|
|
116
116
|
| `String.length()`, `charAt(int)`, `equals(Object)`, `isEmpty()`, `toCharArray()`, `compareTo(String)` | Supported | `equals` boxes primitives, so `"x".equals(5)` is `false`, as in Java. `compareTo` gives the JDK's values (the first differing character's difference, else the length difference) and its NPE messages. These need no Java library. |
|
|
117
|
-
| Other `String` methods | Supported | `substring`, `indexOf` and `lastIndexOf` (of a `String` or a character, from an index), `contains`, `startsWith`, `endsWith`, `toUpperCase`, `toLowerCase`, `trim`, `strip`, `stripLeading`, `stripTrailing`, `isBlank`, `repeat`, `lines` (a `Stream<String>`, lines ended by `\n`, `\r` or `\r\n`), `stripIndent`, `translateEscapes` (`Invalid escape sequence: \q \\u0071`), `indent`, `replace` (chars or strings), `equalsIgnoreCase`, `compareToIgnoreCase`, `concat`, `hashCode`, `toString`, `split` (with and without a limit), `replaceAll`, `replaceFirst`, `matches`, `formatted`; statics `valueOf` (every supported type, `char[]` and a range of one), `copyValueOf`, `format`, `join` (varargs, an array, or an `Iterable` such as a `List<String>`); constructors `()`, `(String)`, `(char[])`, `(char[], int, int)`, `(StringBuilder)`. The JDK's exceptions and NPE messages: `Range [4, 3) out of bounds for length 3` (from `"abc".substring(4)`), `Range [1, 1 + 5) out of bounds for length 2`, `count is negative: -1`, `Cannot invoke "String.isEmpty()" because "this.pattern" is null`. `split` follows Java's rules (no leading empty string from a zero-width match, trailing empty strings removed when the limit is 0). Case mapping is the JDK's root-locale mapping (`"straße".toUpperCase()` is `STRASSE`). Parameters the JDK declares as `CharSequence` take a `String` here. `chars`, `lines`, `getBytes`, `
|
|
117
|
+
| Other `String` methods | Supported | `substring`, `indexOf` and `lastIndexOf` (of a `String` or a character, from an index), `contains`, `startsWith`, `endsWith`, `toUpperCase`, `toLowerCase`, `trim`, `strip`, `stripLeading`, `stripTrailing`, `isBlank`, `repeat`, `lines` (a `Stream<String>`, lines ended by `\n`, `\r` or `\r\n`), `stripIndent`, `translateEscapes` (`Invalid escape sequence: \q \\u0071`), `indent`, `replace` (chars or strings), `equalsIgnoreCase`, `compareToIgnoreCase`, `concat`, `hashCode`, `toString`, `split` (with and without a limit), `replaceAll`, `replaceFirst`, `matches`, `formatted`; statics `valueOf` (every supported type, `char[]` and a range of one), `copyValueOf`, `format`, `join` (varargs, an array, or an `Iterable` such as a `List<String>`); constructors `()`, `(String)`, `(char[])`, `(char[], int, int)`, `(StringBuilder)`. The JDK's exceptions and NPE messages: `Range [4, 3) out of bounds for length 3` (from `"abc".substring(4)`), `Range [1, 1 + 5) out of bounds for length 2`, `count is negative: -1`, `Cannot invoke "String.isEmpty()" because "this.pattern" is null`. `split` follows Java's rules (no leading empty string from a zero-width match, trailing empty strings removed when the limit is 0). Case mapping is the JDK's root-locale mapping (`"straße".toUpperCase()` is `STRASSE`). Parameters the JDK declares as `CharSequence` take a `String` here. `intern()` returns the run's one String of that value, the same object as an equal literal. `chars`, `lines`, `getBytes`, `codePointAt` and the other methods are unsupported. |
|
|
118
118
|
| Regular expressions (`split`, `replaceAll`, `replaceFirst`, `matches`) | Supported with limits | Java's syntax, translated to JavaScript's engine with Java's meanings: `.` and `$` know Java's line terminators (including `\r\n` and U+0085), `\s` is ASCII whitespace, `\h`, `\v`, `\R`, `\A`, `\z`, `\Z`, `\Q…\E`, POSIX classes (`\p{Alpha}`, `\p{Upper}`, …), named groups and back references, a leading `(?i)` or `(?s)`. Replacements as Java reads them: `$1`, `${name}`, `\$`, with `IllegalArgumentException: Illegal group reference` and `No group 2`. Malformed patterns are `PatternSyntaxException` with the JDK's description, index and caret (`Unclosed group near index 1`, `Dangling meta character '*' near index 0`). Constructs that do not translate exactly are engine limitations (below). `java.util.regex.Pattern` and `Matcher` are unsupported. |
|
|
119
119
|
| `String.format`, `formatted` | Supported with limits | Conversions `%d %o %x %X %s %S %c %C %b %B %h %H %e %E %f %g %G %n %%`, with argument indexes (`%2$s`, `%<s`), flags (`-#+ 0,(`), width and precision. Floating point rounds as Java's Formatter does, half-up on the shortest decimal: `%.2f` of `1.005` is `1.01` (C's printf gives `1.00`). The JDK's exceptions: `IllegalFormatConversionException: d != java.lang.String`, `MissingFormatArgumentException: Format specifier '%d'`, `UnknownFormatConversionException: Conversion = 'q'`, `FormatFlagsConversionMismatchException`, and others. Date and time (`%t`) and hexadecimal floating point (`%a`) are engine limitations; the `Locale` overloads are unsupported. |
|
|
120
120
|
| `Math.abs`, `max`, `min` (int, long, double), `sqrt`, `floor`, `ceil`, `round(double)`, `Math.PI`, `Math.E` | Supported | Resolved against all of Math's overloads, so `Math.max(1, 2L)` is the long one and errors list every candidate as javac does. `Math.abs(Integer.MIN_VALUE)` is `MIN_VALUE`; `Math.round` rounds half up and saturates. These need no Java library. |
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ entirely in the reader's browser. No backend, no iframe, no sign-up.
|
|
|
9
9
|
**[Live demo →](https://code-playpad.swengr.com)**
|
|
10
10
|
|
|
11
11
|
```html
|
|
12
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.
|
|
12
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.5.0/dist/standalone.js"></script>
|
|
13
13
|
|
|
14
14
|
<code-playpad height="auto">
|
|
15
15
|
print("hello from a static page")
|
|
@@ -30,7 +30,7 @@ entirely in the reader's browser. No backend, no iframe, no sign-up.
|
|
|
30
30
|
| `python` (default) | Python 3.14 via Pyodide — full standard library, `input()`, real tracebacks, `numpy` on demand | ~6 MB (13.5 MB unpacked), once, cached |
|
|
31
31
|
| `javascript` | The browser's own engine, in a Worker | nothing |
|
|
32
32
|
| `typescript` | Same engine, types stripped before running | ~70 KB, once, cached |
|
|
33
|
-
| `java` | A documented subset of Java 25, compiled and interpreted in a Worker by an engine built for this package — see [Java](#java) | nothing: the engine is a ~
|
|
33
|
+
| `java` | A documented subset of Java 25, compiled and interpreted in a Worker by an engine built for this package — see [Java](#java) | nothing: the engine is a ~105 KB (gzipped) chunk of this package, loaded with the first Java widget, and its library a ~75 KB chunk loaded the first time a program uses it |
|
|
34
34
|
|
|
35
35
|
```html
|
|
36
36
|
<code-playpad height="auto">print("python is the default")</code-playpad>
|
|
@@ -144,7 +144,10 @@ documented subset of Java 25 and checks its behaviour against a real JDK 25:
|
|
|
144
144
|
Anything outside the subset (`java.time`, `Pattern` and `Matcher`, parallel
|
|
145
145
|
streams, `outer.new Inner()`) is reported as *not supported in this
|
|
146
146
|
version* rather than run with a different meaning. The file is `Main.java`
|
|
147
|
-
unless `entry` says otherwise.
|
|
147
|
+
unless `entry` says otherwise. Since engine 0.27, other `.java` files in the
|
|
148
|
+
widget are compiled as the JDK's launcher compiles them, when the program first
|
|
149
|
+
uses their class (see [Several files](#several-files)). Packages are not
|
|
150
|
+
supported.
|
|
148
151
|
|
|
149
152
|
**Speed.** In loop-heavy code the engine runs roughly 150–300 million
|
|
150
153
|
bytecode instructions a second on a laptop. A typical practice solution (10⁵–10⁶
|
|
@@ -201,7 +204,7 @@ actually sent.
|
|
|
201
204
|
### From a CDN — nothing to install
|
|
202
205
|
|
|
203
206
|
```html
|
|
204
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.
|
|
207
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/code-playpad@0.5.0/dist/standalone.js"></script>
|
|
205
208
|
```
|
|
206
209
|
|
|
207
210
|
This is the `standalone` build: CodeMirror is bundled in, so a static blog post
|
|
@@ -365,6 +368,39 @@ JavaScript and TypeScript work the same way, including `.json` imported as data:
|
|
|
365
368
|
</code-playpad>
|
|
366
369
|
```
|
|
367
370
|
|
|
371
|
+
Java compiles the other files as `java Main.java` does (JDK 25's source
|
|
372
|
+
launcher): `Main.java` runs, and `Session.java` is compiled when `Main` first
|
|
373
|
+
uses `Session`. Each file is named after its class and has its own imports, and
|
|
374
|
+
errors and stack traces name the file. Write `<` as `<` inside the markup
|
|
375
|
+
(`List<String>`), since it is HTML:
|
|
376
|
+
|
|
377
|
+
```html
|
|
378
|
+
<code-playpad language="java" entry="Main.java" height="auto">
|
|
379
|
+
<playpad-file name="Main.java">
|
|
380
|
+
public class Main {
|
|
381
|
+
public static void main(String[] args) {
|
|
382
|
+
Session s = new Session("loops", 30);
|
|
383
|
+
System.out.println(s.describe());
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
</playpad-file>
|
|
387
|
+
|
|
388
|
+
<playpad-file name="Session.java">
|
|
389
|
+
public class Session {
|
|
390
|
+
private final String topic;
|
|
391
|
+
private final int minutes;
|
|
392
|
+
|
|
393
|
+
Session(String topic, int minutes) {
|
|
394
|
+
this.topic = topic;
|
|
395
|
+
this.minutes = minutes;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
String describe() { return topic + ": " + minutes + " min"; }
|
|
399
|
+
}
|
|
400
|
+
</playpad-file>
|
|
401
|
+
</code-playpad>
|
|
402
|
+
```
|
|
403
|
+
|
|
368
404
|
A tab bar appears once there is more than one file, with `▸` marking the entry
|
|
369
405
|
point, and each file keeps its own undo history. Editing a module takes effect
|
|
370
406
|
on the next run — the import cache is cleared between runs.
|
|
@@ -795,7 +831,16 @@ warms every other page on the site.
|
|
|
795
831
|
## Version history
|
|
796
832
|
|
|
797
833
|
No breaking changes so far: markup and API written against 0.1.3 still work on
|
|
798
|
-
0.
|
|
834
|
+
0.5.0.
|
|
835
|
+
|
|
836
|
+
### 0.5.0
|
|
837
|
+
|
|
838
|
+
- **Java: programs in several files** (engine 0.27.0). `Main.java` can use
|
|
839
|
+
`Session.java` from another tab, as `java Main.java` does on JDK 25 (JEP 458).
|
|
840
|
+
A file is compiled when the program first uses its class, and each file has
|
|
841
|
+
its own imports. Errors and stack traces name the right file and line. See
|
|
842
|
+
[Several files](#several-files).
|
|
843
|
+
- **Java: `new Object()` and `String.intern()`.**
|
|
799
844
|
|
|
800
845
|
### 0.4.0
|
|
801
846
|
|
package/dist/cdn.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! code-playpad 0.
|
|
2
|
-
export * from "https://cdn.jsdelivr.net/npm/code-playpad@0.
|
|
1
|
+
/*! code-playpad 0.5.0: CDN entry, loads dist/standalone.js of this exact version */
|
|
2
|
+
export * from "https://cdn.jsdelivr.net/npm/code-playpad@0.5.0/dist/standalone.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
async function e(e){try{return await t(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),n(e)}}async function t(e){let[t,n,r,i,a,o]=await Promise.all([import(`@codemirror/view`),import(`@codemirror/state`),import(`@codemirror/commands`),import(`@codemirror/language`),import(`@codemirror/autocomplete`),import(`@codemirror/theme-one-dark`)]),{EditorView:s,keymap:c,lineNumbers:l,highlightActiveLine:u,highlightActiveLineGutter:d,highlightSpecialChars:f,drawSelection:p,rectangularSelection:m,crosshairCursor:h}=t,{EditorState:g,Compartment:_}=n,{defaultKeymap:v,history:y,historyKeymap:b,indentWithTab:x}=r,{syntaxHighlighting:S,defaultHighlightStyle:C,indentOnInput:w,bracketMatching:T,foldGutter:E,foldKeymap:D}=i,{autocompletion:O,closeBrackets:k,closeBracketsKeymap:A,completionKeymap:j}=a,M=new _,N=new _,P=new _,F=[s.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),S(C,{fallback:!0})],I=e=>e?o.oneDark:F,L=c.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),R=e.dark,z=e.readOnly,B=e.language??[],V=t=>g.create({doc:t,extensions:[l(),d(),f(),y(),E(),p(),g.allowMultipleSelections.of(!0),w(),T(),k(),O(),m(),h(),u(),L,c.of([...A,...v,...b,...D,...j,x]),s.lineWrapping,P.of(B),M.of(I(R)),N.of(g.readOnly.of(z)),s.updateListener.of(t=>{t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),H=new s({parent:e.parent,state:V(e.doc)}),U=new Map,W=e.name??``;return{fallback:!1,getCode:()=>H.state.doc.toString(),setCode(e){H.dispatch({changes:{from:0,to:H.state.doc.length,insert:e}})},openFile(e,t){if(e===W)return;U.set(W,H.state);let n=U.get(e);H.setState(n??V(t)),W=e,n&&H.dispatch({effects:[M.reconfigure(I(R)),N.reconfigure(g.readOnly.of(z)),P.reconfigure(B)]})},fileCode(e,t){if(e===W)return H.state.doc.toString();let n=U.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...U.keys()])e.includes(t)||U.delete(t)},setTheme(e){R=e,H.dispatch({effects:M.reconfigure(I(R))})},setReadOnly(e){z=e,H.dispatch({effects:N.reconfigure(g.readOnly.of(z))})},setLanguage(e){B=e,H.dispatch({effects:P.reconfigure(B)})},focus:()=>H.focus(),destroy:()=>H.destroy()}}function n(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var r=new Map,i=new Map;function a(e,t){r.set(e,t)}function o(){return[...r.keys()]}function s(e){let t=i.get(e);if(t)return t;let n=r.get(e);if(!n)return Promise.reject(Error(`Unknown runtime "${e}". Registered: ${o().join(`, `)||`none`}`));let a=n().catch(t=>{throw i.delete(e),t});return i.set(e,a),a}a(`python`,()=>import(`./pyodide-
|
|
1
|
+
async function e(e){try{return await t(e)}catch(t){return console.warn(`[code-playpad] CodeMirror unavailable, using plain textarea:`,t),n(e)}}async function t(e){let[t,n,r,i,a,o]=await Promise.all([import(`@codemirror/view`),import(`@codemirror/state`),import(`@codemirror/commands`),import(`@codemirror/language`),import(`@codemirror/autocomplete`),import(`@codemirror/theme-one-dark`)]),{EditorView:s,keymap:c,lineNumbers:l,highlightActiveLine:u,highlightActiveLineGutter:d,highlightSpecialChars:f,drawSelection:p,rectangularSelection:m,crosshairCursor:h}=t,{EditorState:g,Compartment:_}=n,{defaultKeymap:v,history:y,historyKeymap:b,indentWithTab:x}=r,{syntaxHighlighting:S,defaultHighlightStyle:C,indentOnInput:w,bracketMatching:T,foldGutter:E,foldKeymap:D}=i,{autocompletion:O,closeBrackets:k,closeBracketsKeymap:A,completionKeymap:j}=a,M=new _,N=new _,P=new _,F=[s.theme({"&":{color:`#1f2328`,backgroundColor:`#ffffff`},".cm-gutters":{backgroundColor:`#f6f8fa`,color:`#8b949e`,border:`none`},".cm-activeLine":{backgroundColor:`#f6f8fa88`},".cm-activeLineGutter":{backgroundColor:`#eaeef2`},".cm-cursor":{borderLeftColor:`#1f2328`},"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, ::selection":{backgroundColor:`#cfe3ff`}}),S(C,{fallback:!0})],I=e=>e?o.oneDark:F,L=c.of([{key:`Mod-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)},{key:`Shift-Enter`,preventDefault:!0,run:()=>(e.onRun?.(),!0)}]),R=e.dark,z=e.readOnly,B=e.language??[],V=t=>g.create({doc:t,extensions:[l(),d(),f(),y(),E(),p(),g.allowMultipleSelections.of(!0),w(),T(),k(),O(),m(),h(),u(),L,c.of([...A,...v,...b,...D,...j,x]),s.lineWrapping,P.of(B),M.of(I(R)),N.of(g.readOnly.of(z)),s.updateListener.of(t=>{t.docChanged&&e.onChange?.(t.state.doc.toString())})]}),H=new s({parent:e.parent,state:V(e.doc)}),U=new Map,W=e.name??``;return{fallback:!1,getCode:()=>H.state.doc.toString(),setCode(e){H.dispatch({changes:{from:0,to:H.state.doc.length,insert:e}})},openFile(e,t){if(e===W)return;U.set(W,H.state);let n=U.get(e);H.setState(n??V(t)),W=e,n&&H.dispatch({effects:[M.reconfigure(I(R)),N.reconfigure(g.readOnly.of(z)),P.reconfigure(B)]})},fileCode(e,t){if(e===W)return H.state.doc.toString();let n=U.get(e);return n?n.doc.toString():t},forgetFiles(e){for(let t of[...U.keys()])e.includes(t)||U.delete(t)},setTheme(e){R=e,H.dispatch({effects:M.reconfigure(I(R))})},setReadOnly(e){z=e,H.dispatch({effects:N.reconfigure(g.readOnly.of(z))})},setLanguage(e){B=e,H.dispatch({effects:P.reconfigure(B)})},focus:()=>H.focus(),destroy:()=>H.destroy()}}function n(e){let t=document.createElement(`textarea`);t.className=`cp-fallback-editor`,t.spellcheck=!1,t.value=e.doc,t.readOnly=e.readOnly,t.addEventListener(`input`,()=>e.onChange?.(t.value)),t.addEventListener(`keydown`,t=>{(t.metaKey||t.ctrlKey)&&t.key===`Enter`&&(t.preventDefault(),e.onRun?.())}),e.parent.appendChild(t);let n=new Map,r=e.name??``;return{fallback:!0,getCode:()=>t.value,setCode:e=>{t.value=e},openFile(e,i){e!==r&&(n.set(r,t.value),t.value=n.get(e)??i,r=e)},fileCode(e,i){return e===r?t.value:n.get(e)??i},forgetFiles(e){for(let t of[...n.keys()])e.includes(t)||n.delete(t)},setTheme:()=>{},setReadOnly:e=>{t.readOnly=e},setLanguage:()=>{},focus:()=>t.focus(),destroy:()=>t.remove()}}var r=new Map,i=new Map;function a(e,t){r.set(e,t)}function o(){return[...r.keys()]}function s(e){let t=i.get(e);if(t)return t;let n=r.get(e);if(!n)return Promise.reject(Error(`Unknown runtime "${e}". Registered: ${o().join(`, `)||`none`}`));let a=n().catch(t=>{throw i.delete(e),t});return i.set(e,a),a}a(`python`,()=>import(`./pyodide-C9S4Me6g.js`).then(e=>e.pythonRuntime)),a(`javascript`,()=>import(`./javascript-krS-hdur.js`).then(e=>e.javascriptRuntime)),a(`typescript`,()=>import(`./javascript-krS-hdur.js`).then(e=>e.typescriptRuntime)),a(`java`,()=>import(`./java-BHbRkfsQ.js`).then(e=>e.javaRuntime));var c=class extends Error{constructor(e=`Execution stopped`){super(e),this.name=`RunStopped`}},l=class extends Error{constructor(e=`Web Workers are unavailable in this page`){super(e),this.name=`WorkerUnavailable`}},u=new WeakSet,d=String.raw`
|
|
2
2
|
:host {
|
|
3
3
|
--cp-bg: #ffffff;
|
|
4
4
|
--cp-fg: #1f2328;
|
package/dist/element.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,t}from"./element-
|
|
1
|
+
import{n as e,t}from"./element-yit-fyhg.js";export{t as CodePlayPadElement,e as defineCodePlayPad};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,h as i,i as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./element-
|
|
1
|
+
import{a as e,c as t,d as n,f as r,h as i,i as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./element-yit-fyhg.js";import{n as m,o as h,r as g,t as _}from"./config-DZqcFPEP.js";export{f as CodePlayPadElement,_ as PYODIDE_VERSION,p as RunStopped,n as WorkerUnavailable,u as allProgress,a as clearSnippet,m as configurePython,g as configureTypeScript,i as createEditor,s as defineCodePlayPad,e as getProgress,r as getRuntime,l as listRuntimes,c as loadSnippet,h as pyodideAssetUrls,o as registerRuntime,d as saveSnippet,t as setProgress};
|