Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
a84a640
Modernize developer guide demos and snippets
shai-almog Jul 1, 2026
af43c11
Fix developer guide CI snapshot setup
shai-almog Jul 1, 2026
b0c3ef7
Speed up developer guide CI bootstrap
shai-almog Jul 1, 2026
d9af0e9
Address developer guide PR feedback
shai-almog Jul 1, 2026
a47d940
Remove obsolete CSharp native snippets
shai-almog Jul 1, 2026
3b79fe1
Fix developer guide quality gate findings
shai-almog Jul 1, 2026
d876b01
Fix advanced topic guide snippets
shai-almog Jul 2, 2026
325df1e
Fix Android demo source compile check
shai-almog Jul 2, 2026
45bfd74
Use staged Android jars for guide compile check
shai-almog Jul 2, 2026
c185d74
Address wallet snippet quality findings
shai-almog Jul 2, 2026
ac48cef
Stop treating guide snippet bundles as Java sources
shai-almog Jul 2, 2026
5af8230
Include Android module classes in guide compile check
shai-almog Jul 2, 2026
5aab3f8
Stub missing Android helpers for guide source check
shai-almog Jul 2, 2026
2a44f97
Update developer guide snippets after master merge
shai-almog Jul 2, 2026
2e11719
Fix media guide anchor collision
shai-almog Jul 2, 2026
bb0852d
Move platform native guide snippets out of common
shai-almog Jul 2, 2026
2c49d81
Move Android native stub out of common demos
shai-almog Jul 2, 2026
8c28211
Move JavaScript guide snippets out of common demos
shai-almog Jul 2, 2026
ef67bf2
Compile developer guide Java snippets in demos
shai-almog Jul 2, 2026
81820bc
Fix developer guide callouts and screenshots
shai-almog Jul 2, 2026
d1567ad
Restore CI guide screenshot baselines
shai-almog Jul 2, 2026
de8b17d
Validate guide CSS and restore OpenAPI snippet
shai-almog Jul 2, 2026
bf53e33
Prove developer guide screenshot capture in CI
shai-almog Jul 2, 2026
19de6fa
Expand developer guide screenshot coverage
shai-almog Jul 3, 2026
efabba9
Avoid ripgrep in guide screenshot manifest check
shai-almog Jul 3, 2026
8f9a8ea
Render transition screenshot frames directly
shai-almog Jul 3, 2026
d3c4ff3
Update generated guide screenshot baselines
shai-almog Jul 3, 2026
47b92fc
Stabilize guide animation screenshots
shai-almog Jul 3, 2026
3cdd4c6
Merge remote-tracking branch 'origin/master' into codex/modernize-dev…
shai-almog Jul 3, 2026
71c1b94
Move VideoIO guide snippets into demos
shai-almog Jul 3, 2026
92d5a1d
Render guide screenshots from real frames
shai-almog Jul 3, 2026
3ce866e
Keep website redirect update green on PRs
shai-almog Jul 3, 2026
5278ab2
Expand developer guide screenshot coverage
shai-almog Jul 3, 2026
b660065
Update guide screenshot baselines from CI
shai-almog Jul 3, 2026
641aa58
Stabilize interaction dialog guide screenshot
shai-almog Jul 3, 2026
47b292c
Refine interaction dialog guide screenshot
shai-almog Jul 3, 2026
365fd6b
Prevent interaction dialog guide screenshot clipping
shai-almog Jul 3, 2026
316572e
Widen interaction dialog guide example
shai-almog Jul 3, 2026
597e696
Keep interaction dialog host controls visible
shai-almog Jul 3, 2026
e3faf66
Clean interaction dialog screenshot host label
shai-almog Jul 3, 2026
89003e8
Update interaction dialog screenshot baseline
shai-almog Jul 3, 2026
ff83077
Refresh developer guide screenshot demos
shai-almog Jul 3, 2026
b562d9d
Tune developer guide screenshot baselines
shai-almog Jul 3, 2026
7f9814d
Tighten developer guide screenshot crops
shai-almog Jul 3, 2026
a693246
Validate developer guide snippets and screenshots
shai-almog Jul 4, 2026
9f84a02
Use CI guide screenshot baselines
shai-almog Jul 4, 2026
bd0f5d0
Add missing compiled guide snippets
shai-almog Jul 4, 2026
b1f32e6
Generate layout guide screenshots from snippets
shai-almog Jul 4, 2026
cbc2038
Update generated layout screenshot baselines
shai-almog Jul 4, 2026
58364ce
Generate missing layout guide screenshots
shai-almog Jul 5, 2026
217c84a
Upload guide screenshot diffs for review
shai-almog Jul 5, 2026
fabf8c7
Use CI-rendered guide layout screenshots
shai-almog Jul 5, 2026
545b183
Remove committed guide image audit table
shai-almog Jul 5, 2026
177ba0a
Generate remaining guide runtime screenshots
shai-almog Jul 5, 2026
e1a13f7
Expose guide screenshot diffs
shai-almog Jul 5, 2026
0ac4a5e
Use Linux guide screenshot baselines
shai-almog Jul 5, 2026
96dfebc
Reduce guide update to demo extraction
shai-almog Jul 6, 2026
6c78eac
Merge remote-tracking branch 'origin/master' into codex/modernize-dev…
shai-almog Jul 6, 2026
05e8ac2
Extract new guide snippets from master
shai-almog Jul 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
64 changes: 35 additions & 29 deletions .github/workflows/developer-guide-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
paths:
- 'docs/developer-guide/**'
- 'docs/demos/**'
- 'scripts/developer-guide/**'
- '.github/workflows/developer-guide-docs.yml'
release:
types: [published]
Expand Down Expand Up @@ -33,6 +34,9 @@ jobs:
- '.github/workflows/developer-guide-docs.yml'
docs:
- 'docs/developer-guide/**'
- 'docs/demos/common/src/main/snippets/**'
- 'scripts/developer-guide/migrate-inline-guide-snippets.py'
- 'scripts/developer-guide/validate-guide-snippets.py'
- '.github/workflows/developer-guide-docs.yml'
workflow:
- '.github/workflows/developer-guide-docs.yml'
Expand All @@ -41,47 +45,49 @@ jobs:
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '11'
java-version: '17'

- name: Install local Codename One Maven artifacts
if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
run: |
set -euo pipefail
xvfb-run -a mvn -B -ntp -f maven/pom.xml \
-pl core,javase,android,css-compiler,codenameone-maven-plugin \
-am install \
-Plocal-dev-javase \
-DskipTests \
-Dmaven.javadoc.skip=true \
-Dmaven.source.skip=true \
-Dspotbugs.skip=true \
-Dpmd.skip=true \
-Dcheckstyle.skip=true

- name: Build Codename One demos
if: github.event_name != 'pull_request' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
run: |
set -euo pipefail
mkdir -p "$HOME/.codenameone"
touch "$HOME/.codenameone/guibuilder.jar"
cp maven/CodeNameOneBuildClient.jar "$HOME/.codenameone/CodeNameOneBuildClient.jar"
xvfb-run -a mvn -B -ntp -Dgenerate-gui-sources-done=true -pl common -am -f docs/demos/pom.xml install
xvfb-run -a mvn -B -ntp -Dgenerate-gui-sources-done=true -Dcodename1.platform=javase -f docs/demos/pom.xml process-classes

- name: Install ImageMagick for screenshot comparison
if: github.event_name != 'pull_request' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
- name: Verify developer guide images are referenced
if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y --no-install-recommends imagemagick
python3 scripts/developer-guide/find_unused_images.py docs/developer-guide

- name: Compare animation screenshots
id: compare_animation_screenshots
if: github.event_name != 'pull_request' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
continue-on-error: true
- name: Compile Android demo sources
if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
run: |
set -euo pipefail
ARTIFACT_DIR="build/developer-guide/animation-screenshots"
mkdir -p "${ARTIFACT_DIR}"
.github/scripts/compare-animation-screenshots.sh "${ARTIFACT_DIR}"
scripts/developer-guide/compile-android-demo-sources.sh

- name: Upload animation screenshot mismatches
if: steps.compare_animation_screenshots.outcome == 'failure'
uses: actions/upload-artifact@v7
with:
name: developer-guide-animation-screenshots
path: build/developer-guide/animation-screenshots
if-no-files-found: warn

- name: Fail when animation screenshots differ
if: steps.compare_animation_screenshots.outcome == 'failure'
- name: Validate developer guide snippets
if: github.event_name != 'pull_request' || steps.changes.outputs.docs == 'true' || steps.changes.outputs.demos == 'true' || steps.changes.outputs.workflow == 'true'
run: |
echo "Animation demo screenshots differ from developer guide assets." >&2
exit 1
set -euo pipefail
python3 scripts/developer-guide/validate-guide-snippets.py

- name: Determine publication metadata
run: |
Expand Down Expand Up @@ -407,7 +413,7 @@ jobs:
if-no-files-found: warn

- name: Upload AsciiDoc linter report
if: always()
if: always() && env.ASCII_DOC_LINT_REPORT != ''
uses: actions/upload-artifact@v7
with:
name: developer-guide-asciidoc-lint
Expand Down Expand Up @@ -435,15 +441,15 @@ jobs:
if-no-files-found: warn

- name: Upload paragraph capitalization report
if: always()
if: always() && env.PARAGRAPH_CAP_REPORT != ''
uses: actions/upload-artifact@v7
with:
name: developer-guide-paragraph-capitalization
path: ${{ env.PARAGRAPH_CAP_REPORT }}
if-no-files-found: warn

- name: Upload LanguageTool report
if: always()
if: always() && env.LANGUAGETOOL_REPORT != ''
uses: actions/upload-artifact@v7
with:
name: developer-guide-languagetool
Expand Down
4 changes: 2 additions & 2 deletions docs/demos/android/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<codename1.platform>android</codename1.platform>
<codename1.projectPlatform>android</codename1.projectPlatform>
<codename1.defaultBuildTarget>android-device</codename1.defaultBuildTarget>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.list.MultiButton;
import com.codename1.components.MultiButton;
import com.codename1.impl.android.AndroidNativeUtil;
import com.codename1.impl.android.PermissionPromptCallback;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,16 @@
import android.content.Context;
import com.codename1.impl.android.AndroidNativeUtil;

// tag::mobihelpNativeImplContext[]
class MobihelpNativeImpl {
// tag::mobihelpNativeContext[]
private static Context context() {
return AndroidNativeUtil.getActivity().getApplicationContext();
}
// end::mobihelpNativeContext[]

// tag::mobihelpNativeClearUserData[]
public void clearUserData() {
com.freshdesk.mobihelp.Mobihelp.clearUserData(context());
}
// end::mobihelpNativeClearUserData[]

private static AndroidActivityWrapper activity() {
return new AndroidActivityWrapper();
Expand Down Expand Up @@ -47,7 +44,6 @@ public void onResult(com.freshdesk.mobihelp.MobihelpCallbackStatus status, Integ
}
// end::mobihelpNativeGetUnreadCountAsync[]
}
// end::mobihelpNativeImplContext[]

// Helper wrapper to simulate Android Activity runOnUiThread for compilation
class AndroidActivityWrapper {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.example.wallet;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import java.lang.ref.WeakReference;

// tag::walletBridgeActivity[]
public class WalletBridgeActivity extends Activity {
private static WeakReference<WalletBridgeActivity> active;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
active = new WeakReference<>(this);

Intent in = getIntent();
String caller = getCallingPackage();
String payload = in == null ? null : in.getStringExtra("payload");

Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName());
if (launch == null) {
finish();
return;
}
launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
launch.putExtra("wallet_payload", payload);
launch.putExtra("wallet_caller", caller == null ? "" : caller);
startActivity(launch);
// Do not finish yet. CN1 will finish this activity via native callback once verification completes.
}

@Override
protected void onDestroy() {
WalletBridgeActivity current = getActive();
if (current == this) {
active = null;
}
super.onDestroy();
}

public static WalletBridgeActivity getActive() {
return active == null ? null : active.get();
}
}
// end::walletBridgeActivity[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.wallet;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Set;

/**
* Android-native security helper snippets for wallet bridge examples.
*/
public final class WalletBridgeSecurity {
private WalletBridgeSecurity() {
}

// tag::walletTrustedCallerSignature[]
public static boolean isTrustedCallerSignature(Context ctx, String packageName, Set<String> allowedSha256) {
if (ctx == null || packageName == null || packageName.isEmpty() || allowedSha256 == null || allowedSha256.isEmpty()) {
return false;
}
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo info;
if (Build.VERSION.SDK_INT >= 28) {
info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES);
Signature[] sigs = info.signingInfo != null
? info.signingInfo.getApkContentsSigners()
: null;
return hasAllowedFingerprint(sigs, allowedSha256);
} else {
info = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
return hasAllowedFingerprint(info.signatures, allowedSha256);
}
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException ex) {
return false;
}
}

private static boolean hasAllowedFingerprint(Signature[] sigs, Set<String> allowedSha256)
throws NoSuchAlgorithmException {
if (sigs == null) {
return false;
}
MessageDigest md = MessageDigest.getInstance("SHA-256");
for (Signature s : sigs) {
String fp = toHex(md.digest(s.toByteArray()));
if (allowedSha256.contains(fp)) {
return true;
}
}
return false;
}

private static String toHex(byte[] data) {
char[] digits = "0123456789ABCDEF".toCharArray();
StringBuilder out = new StringBuilder(data.length * 2);
for (byte b : data) {
int value = b & 0xff;
out.append(digits[value >>> 4]);
out.append(digits[value & 0x0f]);
}
return out.toString();
}
// end::walletTrustedCallerSignature[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.example.wallet;

import com.codename1.ui.Display;

/**
* Compilable launch-handling snippets for Android wallet handoff examples.
*/
public class WalletLaunchHandlerSnippet {
// tag::walletLaunchStart[]
public void start() {
Display d = Display.getInstance();
String action = d.getProperty("android.intent.action", null);
if ("com.example.wallet.ACTION_VERIFY".equals(action)) {
boolean callerVerified = "true".equals(d.getProperty("android.intent.caller.verified", "false"));
String payload = d.getProperty("android.intent.extra.wallet_payload", d.getProperty("AppArg", null));
String caller = d.getProperty("android.intent.caller", "");

if (!callerVerified || !isAllowedCaller(caller)) {
failClosed(); // return declined/canceled via bridge completion API
return;
}

verifyWalletPayload(payload, caller);
return;
}
showMainForm();
}
// end::walletLaunchStart[]

private boolean isAllowedCaller(String caller) {
return caller != null && caller.length() > 0;
}

private void failClosed() {
// Complete the native bridge with a declined/canceled result.
}

private void verifyWalletPayload(String payload, String caller) {
// Run authentication + back end verification, then call native bridge completion API.
}

private void showMainForm() {
// Show the normal application UI.
}
}
2 changes: 1 addition & 1 deletion docs/demos/common/codenameone_settings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ codename1.android.keystore=
codename1.android.keystoreAlias=
codename1.android.keystorePassword=
codename1.arg.ios.newStorageLocation=true
codename1.arg.java.version=8
codename1.arg.java.version=17
codename1.displayName=DemoCode
codename1.icon=icon.png
codename1.ios.appid=Q5GHSKAL2F.com.codenameone.developerguide
Expand Down
4 changes: 2 additions & 2 deletions docs/demos/common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
Expand Down
Loading
Loading