Skip to content

Wire validation into the @Bindable annotation framework#5062

Merged
shai-almog merged 2 commits into
masterfrom
binding-validation-annotations
May 28, 2026
Merged

Wire validation into the @Bindable annotation framework#5062
shai-almog merged 2 commits into
masterfrom
binding-validation-annotations

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

  • Adds field-level validation annotations (@Required, @Length, @Regex, @Email, @Url, @Numeric, @ExistIn, @Validate) that compose with @Bind on a @Bindable model.
  • The build-time binder reads them, constructs the matching com.codename1.ui.validation.Constraint instances at bind() time, and exposes a populated Validator through Binding#getValidator() (never null).
  • Multiple annotations on a single field combine via the existing Validator.addConstraint(Component, Constraint...) varargs overload (GroupConstraint, first failure wins).
  • @Validate(MyClass.class) is the escape hatch for hand-written Constraint implementations with a public no-arg constructor.

Example

@Bindable
public class SignupModel {
    @Bind(name = "userField")  @Required @Length(min = 3)
    private String user;

    @Bind(name = "emailField") @Required @Email
    private String email;

    @Bind(name = "ageField")   @Numeric(min = 13, max = 120)
    private String age;

    @Bind(name = "roleField")  @ExistIn({ "admin", "editor", "viewer" })
    private String role;
}

Binding b = Binders.bind(model, form);
b.getValidator().addSubmitButtons(submitBtn);

Docs

  • New Validation annotations section in docs/developer-guide/Annotation-Component-Binding.asciidoc with the full reference table, worked example, and runtime-use pattern.
  • Cross-link from the existing Validation section in The-Components-Of-Codename-One.asciidoc.
  • New scripts/initializr/common/src/main/resources/skill/references/binding-and-validation.md covering binding + validation for the initializr agent skill; SKILL.md updated to point at it.

Test plan

  • cd maven/codenameone-maven-plugin && mvn test -Dtest=BindingAnnotationProcessorTest — 9 tests (4 pre-existing + 5 new: validator generation, no-annotations safe case, empty @Regex/@ExistIn rejection, custom @Validate constraint).
  • Full plugin test suite — 109 tests pass.
  • mvn test -Dtest='Validator*Test,*Binding*Test' in maven/core-unittests — 32 binding/validation tests pass.
  • Sample end-to-end run in the simulator with a form bound to a validated model (recommended before merge).

🤖 Generated with Claude Code

Adds @required, @Length, @regex, @Email, @url, @Numeric, @existin, and
@Validate as field-level annotations that compose with @Bind. The
build-time binder generator collects them, constructs the matching
com.codename1.ui.validation.Constraint instances at bind() time, and
exposes a populated Validator through Binding#getValidator().

Multiple validation annotations on the same field combine into a
GroupConstraint via the existing addConstraint(Component, Constraint...)
varargs overload (first failure wins). @Validate(MyClass.class) is the
escape hatch for hand-written Constraint implementations.

Docs: new "Validation annotations" section in
Annotation-Component-Binding.asciidoc, cross-link from the existing
Validation section in The-Components-Of-Codename-One.asciidoc, and a
new references/binding-and-validation.md in the initializr agent skill.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@github-actions
Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 116 screenshots: 116 matched.

Native Android coverage

  • 📊 Line coverage: 12.45% (7218/57972 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.16% (36294/357360), branch 4.28% (1449/33836), complexity 5.31% (1725/32486), method 9.24% (1406/15210), class 15.16% (321/2117)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 12.45% (7218/57972 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.16% (36294/357360), branch 4.28% (1449/33836), complexity 5.31% (1725/32486), method 9.24% (1406/15210), class 15.16% (321/2117)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 600.000 ms
Base64 CN1 encode 171.000 ms
Base64 encode ratio (CN1/native) 0.285x (71.5% faster)
Base64 native decode 971.000 ms
Base64 CN1 decode 230.000 ms
Base64 decode ratio (CN1/native) 0.237x (76.3% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 47 screenshots: 47 matched.
✅ JavaScript-port screenshot tests passed.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 115 screenshots: 115 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 298 seconds

Build and Run Timing

Metric Duration
Simulator Boot 70000 ms
Simulator Boot (Run) 1000 ms
App Install 14000 ms
App Launch 8000 ms
Test Execution 355000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1844.000 ms
Base64 CN1 encode 2237.000 ms
Base64 encode ratio (CN1/native) 1.213x (21.3% slower)
Base64 native decode 523.000 ms
Base64 CN1 decode 1871.000 ms
Base64 decode ratio (CN1/native) 3.577x (257.7% slower)
Base64 SIMD encode 783.000 ms
Base64 encode ratio (SIMD/native) 0.425x (57.5% faster)
Base64 encode ratio (SIMD/CN1) 0.350x (65.0% faster)
Base64 SIMD decode 571.000 ms
Base64 decode ratio (SIMD/native) 1.092x (9.2% slower)
Base64 decode ratio (SIMD/CN1) 0.305x (69.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 115.000 ms
Image createMask (SIMD on) 15.000 ms
Image createMask ratio (SIMD on/off) 0.130x (87.0% faster)
Image applyMask (SIMD off) 238.000 ms
Image applyMask (SIMD on) 103.000 ms
Image applyMask ratio (SIMD on/off) 0.433x (56.7% faster)
Image modifyAlpha (SIMD off) 458.000 ms
Image modifyAlpha (SIMD on) 72.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.157x (84.3% faster)
Image modifyAlpha removeColor (SIMD off) 287.000 ms
Image modifyAlpha removeColor (SIMD on) 88.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.307x (69.3% faster)
Image PNG encode (SIMD off) 1868.000 ms
Image PNG encode (SIMD on) 1358.000 ms
Image PNG encode ratio (SIMD on/off) 0.727x (27.3% faster)
Image JPEG encode 808.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 115 screenshots: 115 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 233 seconds

Build and Run Timing

Metric Duration
Simulator Boot 65000 ms
Simulator Boot (Run) 1000 ms
App Install 10000 ms
App Launch 12000 ms
Test Execution 322000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 457.000 ms
Base64 CN1 encode 1301.000 ms
Base64 encode ratio (CN1/native) 2.847x (184.7% slower)
Base64 native decode 272.000 ms
Base64 CN1 decode 1317.000 ms
Base64 decode ratio (CN1/native) 4.842x (384.2% slower)
Base64 SIMD encode 738.000 ms
Base64 encode ratio (SIMD/native) 1.615x (61.5% slower)
Base64 encode ratio (SIMD/CN1) 0.567x (43.3% faster)
Base64 SIMD decode 559.000 ms
Base64 decode ratio (SIMD/native) 2.055x (105.5% slower)
Base64 decode ratio (SIMD/CN1) 0.424x (57.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 57.000 ms
Image createMask (SIMD on) 8.000 ms
Image createMask ratio (SIMD on/off) 0.140x (86.0% faster)
Image applyMask (SIMD off) 176.000 ms
Image applyMask (SIMD on) 54.000 ms
Image applyMask ratio (SIMD on/off) 0.307x (69.3% faster)
Image modifyAlpha (SIMD off) 130.000 ms
Image modifyAlpha (SIMD on) 55.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.423x (57.7% faster)
Image modifyAlpha removeColor (SIMD off) 255.000 ms
Image modifyAlpha removeColor (SIMD on) 75.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.294x (70.6% faster)
Image PNG encode (SIMD off) 1120.000 ms
Image PNG encode (SIMD on) 895.000 ms
Image PNG encode ratio (SIMD on/off) 0.799x (20.1% faster)
Image JPEG encode 432.000 ms

…rule

The dev-guide CI Vale step rejects the hyphenated form per the
Microsoft style guide. Replace with the unmodified noun "generated"
since the surrounding sentence already establishes the generator
context.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog merged commit 88cc945 into master May 28, 2026
27 checks passed
shai-almog added a commit that referenced this pull request May 29, 2026
Final consolidated follow-up to the May 29 weekly index. Pulls
together six PRs that share the same architectural shape: emit Java
at build time, validate at build time, fail fast, and let R8 /
ParparVM rename the generated code together with the rest of the app.

- PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin,
  the declarative router that is its first consumer (@route with
  guards, redirects, per-tab navigation shell, location listeners),
  the unified cold + warm DeepLink API, iOS Universal Links /
  Android App Links JSON generators, and the JavaScript-port
  window.history bridge.
- PR #5047: three more processors on the same SPI -- SQLite ORM
  (@entity / @id / @column), JSON / XML mapping (@mapped /
  @JsonProperty / @xmlelement), and component binding (@bindable /
  @Bind with the new BindAttr enum).
- PR #5062: validation annotations (@required, @Length, @regex,
  @Email, @url, @Numeric, @existin, @Validate) that compose with
  @Bind and surface through Binding.getValidator().
- PR #5055: the Immich-port baseline -- Map default methods,
  BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List),
  URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter,
  modern animated tab indicator + arc-spinner pull-to-refresh,
  MorphTransition.snapshotMode, WebSocket in core, and the new
  cn1:generate-openapi-client mojo.
- PR #5042: build-time SVG transcoder that lowers SVG (and SMIL
  animations) into Codename One Image subclasses via the shape API.
- PR #5066: Lottie / Bodymovin transcoder reusing the same
  SVGDocument model, JavaCodeGenerator, and SVGRegistry.
- PR #5049: the iOS Metal stencil-clip + drawString and Android
  LinearGradientPaint fixes the SVG screenshot tests exposed.

Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2
path does not have the shape coverage) -- a non-issue on most apps
now that Metal is the default.
shai-almog added a commit that referenced this pull request May 29, 2026
Final consolidated follow-up to the May 29 weekly index. Pulls
together six PRs that share the same architectural shape: emit Java
at build time, validate at build time, fail fast, and let R8 /
ParparVM rename the generated code together with the rest of the app.

- PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin,
  the declarative router that is its first consumer (@route with
  guards, redirects, per-tab navigation shell, location listeners),
  the unified cold + warm DeepLink API, iOS Universal Links /
  Android App Links JSON generators, and the JavaScript-port
  window.history bridge.
- PR #5047: three more processors on the same SPI -- SQLite ORM
  (@entity / @id / @column), JSON / XML mapping (@mapped /
  @JsonProperty / @xmlelement), and component binding (@bindable /
  @Bind with the new BindAttr enum).
- PR #5062: validation annotations (@required, @Length, @regex,
  @Email, @url, @Numeric, @existin, @Validate) that compose with
  @Bind and surface through Binding.getValidator().
- PR #5055: the Immich-port baseline -- Map default methods,
  BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List),
  URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter,
  modern animated tab indicator + arc-spinner pull-to-refresh,
  MorphTransition.snapshotMode, WebSocket in core, and the new
  cn1:generate-openapi-client mojo.
- PR #5042: build-time SVG transcoder that lowers SVG (and SMIL
  animations) into Codename One Image subclasses via the shape API.
- PR #5066: Lottie / Bodymovin transcoder reusing the same
  SVGDocument model, JavaCodeGenerator, and SVGRegistry.
- PR #5049: the iOS Metal stencil-clip + drawString and Android
  LinearGradientPaint fixes the SVG screenshot tests exposed.

Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2
path does not have the shape coverage) -- a non-issue on most apps
now that Metal is the default.
shai-almog added a commit that referenced this pull request May 29, 2026
Final consolidated follow-up to the May 29 weekly index. Pulls
together six PRs that share the same architectural shape: emit Java
at build time, validate at build time, fail fast, and let R8 /
ParparVM rename the generated code together with the rest of the app.

- PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin,
  the declarative router that is its first consumer (@route with
  guards, redirects, per-tab navigation shell, location listeners),
  the unified cold + warm DeepLink API, iOS Universal Links /
  Android App Links JSON generators, and the JavaScript-port
  window.history bridge.
- PR #5047: three more processors on the same SPI -- SQLite ORM
  (@entity / @id / @column), JSON / XML mapping (@mapped /
  @JsonProperty / @xmlelement), and component binding (@bindable /
  @Bind with the new BindAttr enum).
- PR #5062: validation annotations (@required, @Length, @regex,
  @Email, @url, @Numeric, @existin, @Validate) that compose with
  @Bind and surface through Binding.getValidator().
- PR #5055: the Immich-port baseline -- Map default methods,
  BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List),
  URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter,
  modern animated tab indicator + arc-spinner pull-to-refresh,
  MorphTransition.snapshotMode, WebSocket in core, and the new
  cn1:generate-openapi-client mojo.
- PR #5042: build-time SVG transcoder that lowers SVG (and SMIL
  animations) into Codename One Image subclasses via the shape API.
- PR #5066: Lottie / Bodymovin transcoder reusing the same
  SVGDocument model, JavaCodeGenerator, and SVGRegistry.
- PR #5049: the iOS Metal stencil-clip + drawString and Android
  LinearGradientPaint fixes the SVG screenshot tests exposed.

Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2
path does not have the shape coverage) -- a non-issue on most apps
now that Metal is the default.
shai-almog added a commit that referenced this pull request May 29, 2026
Final consolidated follow-up to the May 29 weekly index. Pulls
together six PRs that share the same architectural shape: emit Java
at build time, validate at build time, fail fast, and let R8 /
ParparVM rename the generated code together with the rest of the app.

- PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin,
  the declarative router that is its first consumer (@route with
  guards, redirects, per-tab navigation shell, location listeners),
  the unified cold + warm DeepLink API, iOS Universal Links /
  Android App Links JSON generators, and the JavaScript-port
  window.history bridge.
- PR #5047: three more processors on the same SPI -- SQLite ORM
  (@entity / @id / @column), JSON / XML mapping (@mapped /
  @JsonProperty / @xmlelement), and component binding (@bindable /
  @Bind with the new BindAttr enum).
- PR #5062: validation annotations (@required, @Length, @regex,
  @Email, @url, @Numeric, @existin, @Validate) that compose with
  @Bind and surface through Binding.getValidator().
- PR #5055: the Immich-port baseline -- Map default methods,
  BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List),
  URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter,
  modern animated tab indicator + arc-spinner pull-to-refresh,
  MorphTransition.snapshotMode, WebSocket in core, and the new
  cn1:generate-openapi-client mojo.
- PR #5042: build-time SVG transcoder that lowers SVG (and SMIL
  animations) into Codename One Image subclasses via the shape API.
- PR #5066: Lottie / Bodymovin transcoder reusing the same
  SVGDocument model, JavaCodeGenerator, and SVGRegistry.
- PR #5049: the iOS Metal stencil-clip + drawString and Android
  LinearGradientPaint fixes the SVG screenshot tests exposed.

Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2
path does not have the shape coverage) -- a non-issue on most apps
now that Metal is the default.
shai-almog added a commit that referenced this pull request May 29, 2026
Final consolidated follow-up to the May 29 weekly index. Pulls
together six PRs that share the same architectural shape: emit Java
at build time, validate at build time, fail fast, and let R8 /
ParparVM rename the generated code together with the rest of the app.

- PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin,
  the declarative router that is its first consumer (@route with
  guards, redirects, per-tab navigation shell, location listeners),
  the unified cold + warm DeepLink API, iOS Universal Links /
  Android App Links JSON generators, and the JavaScript-port
  window.history bridge.
- PR #5047: three more processors on the same SPI -- SQLite ORM
  (@entity / @id / @column), JSON / XML mapping (@mapped /
  @JsonProperty / @xmlelement), and component binding (@bindable /
  @Bind with the new BindAttr enum).
- PR #5062: validation annotations (@required, @Length, @regex,
  @Email, @url, @Numeric, @existin, @Validate) that compose with
  @Bind and surface through Binding.getValidator().
- PR #5055: the Immich-port baseline -- Map default methods,
  BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List),
  URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter,
  modern animated tab indicator + arc-spinner pull-to-refresh,
  MorphTransition.snapshotMode, WebSocket in core, and the new
  cn1:generate-openapi-client mojo.
- PR #5042: build-time SVG transcoder that lowers SVG (and SMIL
  animations) into Codename One Image subclasses via the shape API.
- PR #5066: Lottie / Bodymovin transcoder reusing the same
  SVGDocument model, JavaCodeGenerator, and SVGRegistry.
- PR #5049: the iOS Metal stencil-clip + drawString and Android
  LinearGradientPaint fixes the SVG screenshot tests exposed.

Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2
path does not have the shape coverage) -- a non-issue on most apps
now that Metal is the default.
shai-almog added a commit that referenced this pull request May 29, 2026
Final consolidated follow-up to the May 29 weekly index. Pulls
together six PRs that share the same architectural shape: emit Java
at build time, validate at build time, fail fast, and let R8 /
ParparVM rename the generated code together with the rest of the app.

- PR #5037: bytecode AnnotationProcessor SPI in the Maven plugin,
  the declarative router that is its first consumer (@route with
  guards, redirects, per-tab navigation shell, location listeners),
  the unified cold + warm DeepLink API, iOS Universal Links /
  Android App Links JSON generators, and the JavaScript-port
  window.history bridge.
- PR #5047: three more processors on the same SPI -- SQLite ORM
  (@entity / @id / @column), JSON / XML mapping (@mapped /
  @JsonProperty / @xmlelement), and component binding (@bindable /
  @Bind with the new BindAttr enum).
- PR #5062: validation annotations (@required, @Length, @regex,
  @Email, @url, @Numeric, @existin, @Validate) that compose with
  @Bind and surface through Binding.getValidator().
- PR #5055: the Immich-port baseline -- Map default methods,
  BiFunction, atomics, Rest.fetchAsJsonList / fetchAsMapped(List),
  URLImage.RequestDecorator / setDefaultBearerToken, JSONWriter,
  modern animated tab indicator + arc-spinner pull-to-refresh,
  MorphTransition.snapshotMode, WebSocket in core, and the new
  cn1:generate-openapi-client mojo.
- PR #5042: build-time SVG transcoder that lowers SVG (and SMIL
  animations) into Codename One Image subclasses via the shape API.
- PR #5066: Lottie / Bodymovin transcoder reusing the same
  SVGDocument model, JavaCodeGenerator, and SVGRegistry.
- PR #5049: the iOS Metal stencil-clip + drawString and Android
  LinearGradientPaint fixes the SVG screenshot tests exposed.

Calls out the Metal-only caveat on iOS for SVG / Lottie (the GL ES 2
path does not have the shape coverage) -- a non-issue on most apps
now that Metal is the default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant