Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/website-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ jobs:
env:
GITHUB_TOKEN: ${{ github.token }}

- name: Check redirect rule ordering
run: python3 scripts/website/test_redirect_order.py

- name: Test developer guide chapter generation
run: ruby scripts/website/test_generate_developer_guide.rb

- name: Test developer guide PDF redirect resolver
run: scripts/website/test_update_developer_guide_redirect.sh

Expand Down Expand Up @@ -383,6 +389,7 @@ jobs:
set -euo pipefail
test -f docs/website/public/_redirects
test -f docs/website/public/developer-guide/index.html
python3 scripts/website/check_developer_guide.py docs/website/public
grep -Eq '^/files/developer-guide\.pdf https://github\.com/codenameone/CodenameOne/releases/download/.+/developer-guide\.pdf 302$' docs/website/public/_redirects
grep -Eq '^/manual /developer-guide/ 301$' docs/website/public/_redirects
grep -Eq '^/manual/ /developer-guide/ 301$' docs/website/public/_redirects
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,8 @@ cn1-build-hints.json
# runs `xcodegen generate` from the checked-in project.yml. A committed pbxproj
# would be a second source of truth for the same target.
/scripts/input-validation-app/ios-tests/*.xcodeproj/

# Chapter Markdown and navigation are regenerated from the AsciiDoc book.
/docs/website/content/developer-guide/chapters/
/docs/website/data/developer-guide.json
/docs/website/data/guide-links.json
8 changes: 4 additions & 4 deletions docs/developer-guide/developer-guide.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ include::Maven-Project-Workflow.asciidoc[]

include::The-EDT---Event-Dispatch-Thread.asciidoc[]

include::Promises.asciidoc[]

include::Plugins.asciidoc[]

include::Events.asciidoc[]

include::Device-Input-And-Form-Factors.asciidoc[]
Expand Down Expand Up @@ -249,6 +245,10 @@ include::Skin-Designer.asciidoc[]

= Appendices

include::Promises.asciidoc[]

include::Plugins.asciidoc[]

include::Maven-Appendix-Archetypes.adoc[]

include::Maven-Appendix-Goals.adoc[]
Expand Down
79 changes: 79 additions & 0 deletions docs/website/assets/css/extended/cn1-guide-pages.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* The guide uses one documentation shell for its contents and every chapter. */
.main:has(> .cn1-guide-layout) { max-width: min(1320px, calc(100vw - 32px)); padding-inline: 24px; }
.cn1-guide-layout { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 3rem; max-width: var(--cn1-shell); margin: auto; }
.cn1-guide-sidebar { position: sticky; top: 5.5rem; align-self: start; max-height: calc(100vh - 6.5rem); overflow-y: auto; overscroll-behavior: contain; padding: .25rem 1.25rem 1rem 0; border-right: 1px solid var(--cn1-border); font-size: .85rem; }
.cn1-guide-home { display: block; font-size: 1rem; font-weight: 700; margin-bottom: .8rem; }
.cn1-guide-sidebar-tools { display: grid; gap: .6rem; padding-bottom: 1rem; margin-bottom: 1rem; border-bottom: 1px solid var(--cn1-border); }
.cn1-guide-part { margin: .85rem 0; }
.cn1-guide-sidebar summary, .cn1-guide-toc summary { cursor: pointer; font-weight: 600; line-height: 1.5; }
.cn1-guide-sidebar ul { list-style: none; padding: .3rem 0 0 .8rem; }
.cn1-guide-sidebar li { margin: .55rem 0; line-height: 1.5; }
.cn1-guide-sidebar a { display: block; color: var(--cn1-muted); }
.cn1-guide-sidebar .cn1-guide-home, .cn1-guide-sidebar [aria-current=page] { color: var(--cn1-accent); }
.cn1-guide-sidebar [aria-current=page] { font-weight: 600; border-left: 2px solid var(--cn1-accent); padding-left: .65rem; }
.cn1-guide-menu > summary { margin-bottom: .75rem; }
.cn1-guide-layout .post-single { min-width: 0; width: 100%; }
.cn1-guide-layout .post-single .post-title { font-size: clamp(30px, 3vw, 42px); line-height: 1.18; }
.cn1-guide-layout .post-header { margin-bottom: 1rem; }
.cn1-guide-crumbs { font-size: .82rem; color: var(--cn1-muted); margin: 0 0 .75rem; }
.cn1-guide-tools { display: flex; flex-wrap: wrap; gap: .6rem 1.4rem; margin: 1rem 0 1.5rem; font-size: .85rem; }
.cn1-guide-tools a, .cn1-guide-crumbs a, .cn1-guide-pagination a, .cn1-guide-contents a, .cn1-guide-topic-index a { color: var(--cn1-accent); }
.cn1-guide-layout a:hover { text-decoration: underline; }
.cn1-guide-layout a:focus-visible, .cn1-guide-layout summary:focus-visible { outline: 2px solid var(--cn1-accent); outline-offset: 4px; }
.cn1-guide-pagination { display: flex; justify-content: space-between; gap: 1.5rem; font-size: .85rem; line-height: 1.45; }
.cn1-guide-pagination a { display: flex; flex-direction: column; gap: .25rem; max-width: 47%; }
.cn1-guide-pagination [rel=next] { margin-left: auto; text-align: right; }
.cn1-guide-pagination-label { color: var(--cn1-muted); font-size: .75rem; font-weight: 600; }
.cn1-guide-pagination-label [aria-hidden] { font-size: 1.15rem; color: var(--cn1-accent); }
.cn1-guide-pagination--top { padding: 0 0 1rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--cn1-border); }
.cn1-guide-pagination--bottom { padding: 1.25rem 0; margin-top: 2rem; border-top: 1px solid var(--cn1-border); }
.cn1-guide-topic-index { margin: 2rem 0 2.5rem; }
.cn1-guide-topic-index h2, .cn1-guide-contents h2 { font-size: 1.2rem; font-weight: 600; margin-bottom: .8rem; }
.cn1-guide-topic-index ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 2rem; row-gap: .5rem; padding-left: 1rem; font-size: .88rem; }
.cn1-guide-contents section { margin: 0 0 1.75rem; scroll-margin-top: 6rem; }
.cn1-guide-contents h2 { padding-bottom: .55rem; border-bottom: 1px solid var(--cn1-border); }
.cn1-guide-contents ol { padding-left: 2rem; }
.cn1-guide-contents li { padding-left: .4rem; margin: .55rem 0; font-size: .95rem; line-height: 1.5; }
.cn1-guide-contents li::marker { color: var(--cn1-muted); font-size: .8rem; }
.cn1-guide-toc { padding: .75rem 0; margin: 1.25rem 0; border-top: 1px solid var(--cn1-border); border-bottom: 1px solid var(--cn1-border); font-size: .85rem; }
.cn1-guide-toc ul { padding-left: 1.2rem; }
.cn1-guide-toc li { margin: .4rem 0; }
.cn1-guide-toc nav { margin: .75rem 0 .25rem; max-height: 15rem; overflow: auto; }
.cn1-guide-content { overflow-wrap: anywhere; }
.cn1-guide-content :is(h2,h3,h4,h5,h6,[id]) { scroll-margin-top: 6rem; }
.cn1-guide-content .title { font-weight: 600; margin: .5rem 0; }
.cn1-guide-content .imageblock { margin: 1.5rem 0; }
.cn1-guide-content .imageblock .title { font-size: .85rem; color: var(--cn1-muted); }
.cn1-guide-content .admonitionblock, .cn1-guide-content .sidebarblock { border-left: 3px solid var(--cn1-accent); background: var(--entry); padding: .75rem 1rem; margin: 1.5rem 0; border-radius: 6px; }
.cn1-guide-content .admonitionblock { display: flex; align-items: flex-start; gap: .85rem; }
.cn1-guide-admonition-icon { flex: 0 0 24px; color: var(--cn1-accent); margin-top: .2rem; }
.cn1-guide-admonition-icon svg { display: block; }
.cn1-guide-content .admonitionblock > .content { min-width: 0; flex: 1; }
.cn1-guide-content .admonitionblock .content > :first-child { margin-top: 0; }
.cn1-guide-content .admonitionblock .content > :last-child { margin-bottom: 0; }
.cn1-guide-content .tableblock { max-width: 100%; }
.cn1-guide-content pre { overflow: auto; overflow-wrap: normal; }
.cn1-guide-content pre code { white-space: pre; }
.cn1-guide-content .colist td { border: 0; padding: .25rem .5rem; }
.cn1-guide-content .conum { font-style: normal; font-weight: 700; }
.cn1-guide-content .conum[data-value]::after { content: attr(data-value); }
.cn1-guide-content .footnotes { border-top: 1px solid var(--cn1-border); padding-top: 1rem; font-size: .85rem; }
.cn1-guide-content pre code { font-size: .85rem; }
@media (max-width: 1000px) {
.cn1-guide-layout { grid-template-columns: 220px minmax(0, 1fr); gap: 1.5rem; }
.cn1-guide-topic-index ul { grid-template-columns: 1fr; }
}
@media (min-width: 721px) { .cn1-guide-menu > summary { display: none; } }
@media (max-width: 720px) {
.main:has(> .cn1-guide-layout) { padding-inline: 0; }
.cn1-guide-layout { grid-template-columns: 1fr; gap: 1.5rem; }
.cn1-guide-sidebar { position: static; max-height: none; padding: .5rem 0; border-right: 0; border-bottom: 1px solid var(--cn1-border); }
.cn1-guide-menu > nav { max-height: 55vh; overflow-y: auto; padding: .5rem; }
.cn1-guide-menu > summary { margin: 0; }
.cn1-guide-pagination { gap: 1rem; font-size: .8rem; }
.cn1-guide-pagination a { overflow-wrap: anywhere; }
}
@media print {
.cn1-guide-sidebar, .cn1-guide-tools, .cn1-guide-pagination, .cn1-guide-toc, .cn1-guide-topic-index { display: none; }
.cn1-guide-layout { display: block; }
}
38 changes: 38 additions & 0 deletions docs/website/assets/js/cn1-guide-links.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* Fragments never reach the server. Resolve old book bookmarks in the browser. */
(() => {
const menu = document.querySelector('.cn1-guide-menu');
const desktop = window.matchMedia('(min-width: 721px)');
const updateMenu = () => {
if (!menu) return;
menu.open = desktop.matches;
if (desktop.matches) {
const sidebar = document.querySelector('.cn1-guide-sidebar');
const current = menu.querySelector('[aria-current="page"]');
if (sidebar && current) {
const below = current.getBoundingClientRect().bottom - sidebar.getBoundingClientRect().bottom;
if (below > 0) sidebar.scrollTop += below + 24;
}
}
};
updateMenu();
desktop.addEventListener('change', updateMenu);
async function resolveBookmark() {
if (!location.hash) return;
let id;
try { id = decodeURIComponent(location.hash.slice(1)); } catch (_) { return; }
if (document.getElementById(id)) return;
try {
const response = await fetch('/developer-guide/anchors.json');
if (!response.ok) return;
const anchors = await response.json();
const target = anchors[id];
if (target && target.startsWith('/developer-guide/') && target !== location.pathname + location.hash) {
const next = new URL(target, location.origin);
next.search = location.search;
location.replace(next.href);
}
} catch (_) { /* Leave the chapter directory usable when offline. */ }
}
resolveBookmark();
window.addEventListener('hashchange', resolveBookmark);
})();
2 changes: 1 addition & 1 deletion docs/website/content/about-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ https://youtu.be/rl6z7DD2-vg

### How does Codename One work?

To understand how Codename One works, its history etc. check the [developer guide](/manual/) (also available as a [PDF](/files/developer-guide.pdf)). It provide a birds eye view in the first chapter.
To understand how Codename One works, its history etc. check the [developer guide](/developer-guide/introduction/) (also available as a [PDF](/files/developer-guide.pdf)). It provide a birds eye view in the first chapter.

You can also refer to [this stackoverflow answer](http://stackoverflow.com/questions/10639766/how-codename-one-works/10646336). There is a video that goes into further details [here](https://www.youtube.com/watch?v=MrwbpdMALig) (it's a bit long).

Expand Down
2 changes: 1 addition & 1 deletion docs/website/content/advanced-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Build hints/arguments allow us to manipulate the build process on the build serv

When sending a build to the server you can provide additional parameters to the build which will be incorporated into the build process on the server to hint on multiple different build time options.You can do this by right clicking the Codename One project and entering the project properties. There you will find the "Build Hints" tab in which you can just type the arguments and the appropriate values from the list below.

We removed this page since it duplicates content from the developer guide and we should probably maintain only one **authoritative** list. The up to date list is [here](/manual/advanced-topics/#_sending_arguments_to_the_build_server).
We removed this page since it duplicates content from the developer guide and we should probably maintain only one **authoritative** list. The up to date list is [here](/developer-guide/advanced-topics-under-the-hood/#_sending_arguments_to_the_build_server).
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ I barely wrote 100 lines of code (not the best ones). Even worse than that, I fe

### What Really Helped?

I found the [Codename One developer guide](/developer-guide) to be the best learning resource. It’s great for learning your way around the tool and understanding its components.
I found the [Codename One developer guide](/developer-guide/) to be the best learning resource. It’s great for learning your way around the tool and understanding its components.

In the [How Do I](/how-do-i/) section I found some very helpful video tutorials that also helped a lot with learning common use cases, like the [Layout basics](/how_di_i/how-do-i-positioning-components-using-layout-managers/) video, and the [How to convert a PSD Design into a Native Mobile App](/video/how-to-convert-a-psd-design-into-a-native-mobile-app/).

Expand Down
2 changes: 1 addition & 1 deletion docs/website/content/blog/app-hardening-cross-platform.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ The security lead we are building comes from covering these boundaries together.

App Hardening still cannot stop a determined attacker who controls the device. It does not replace authorization, rate limits, secure key custody, or review of the operation your backend performs. It makes static analysis and casual tampering more expensive across every artifact you ship, which is the job an obfuscation layer can defend.

Start with `standard`, submit a release cloud build, and check the hardening report before moving to a stronger profile. The [App Hardening guide](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/App-Hardening.asciidoc) documents every hint, exclusion, and local-build boundary.
Start with `standard`, submit a release cloud build, and check the hardening report before moving to a stronger profile. The [App Hardening guide](/developer-guide/app-hardening/) documents every hint, exclusion, and local-build boundary.

---

Expand Down
2 changes: 1 addition & 1 deletion docs/website/content/blog/app-shield-server-attestation.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ It also cannot cover traffic it cannot see. `ConnectionRequest`-based APIs get a

Certificate pinning has its own operational risk. App Shield pins public keys rather than whole certificates, so a certificate renewal on the same key does not break the app. You should still roll out the server policy in monitor mode first, measure the `would_deny` traffic, and only then reject requests.

The complete wire format, failure statuses, transport boundaries, pin lifecycle, and backend examples are in the [App Shield developer guide](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/App-Shield.asciidoc).
The complete wire format, failure statuses, transport boundaries, pin lifecycle, and backend examples are in the [App Shield developer guide](/developer-guide/app-shield/).

## OpenType fonts now work without renaming

Expand Down
4 changes: 2 additions & 2 deletions docs/website/content/blog/avoiding-lists.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ The problem with this approach becomes obvious when we try to add an event liste

We can make `name` into a `Button` but then what happens when a user clicks `email`?

We can make all the entries into buttons but that isn’t practical. That’s what [lead component](/manual/components/#lead-component-sidebar) is for, we can make one component into a button and it "takes the lead". If we make name into a button and set it as the lead of the `Container` it will handle all the events and state changes for the entire row!
We can make all the entries into buttons but that isn’t practical. That’s what [lead component](/developer-guide/the-components-of-codename-one/#lead-component-sidebar) is for, we can make one component into a button and it "takes the lead". If we make name into a button and set it as the lead of the `Container` it will handle all the events and state changes for the entire row!

__ | For more information on lead components check out [the sidebar](/manual/components/#lead-component-sidebar) in the developer guide.
__ | For more information on lead components check out [the sidebar](/developer-guide/the-components-of-codename-one/#lead-component-sidebar) in the developer guide.\
---|---

We can change the code above like this and support lead components:
Expand Down
4 changes: 2 additions & 2 deletions docs/website/content/blog/back-vacation.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ During the month of August Google finally removed their old GCM servers. We’ve

Users who still used the old style of push notifications (prior to the `google-services.json` file approach) had push messages blocked. That was expected.

__ | You can read about the modern approach to push [here](/manual/push/)
__ | You can read about the modern approach to push [here](/developer-guide/push-notifications/)\
---|---

Because that no longer works anyway we switched the default build mode to FCM. This solves an issue for developers who neglected to define the `android.messagingService=fcm` build hint (which you no longer need). However, this causes a build error if you don’t have that JSON file in place. You can get this to compile for now by explicitly stating the build hint `android.messagingService=gcm`. However, push won’t work if you do that since the Google run GCM push servers are no longer there. But it will compile which is a start.

To migrate to the new FCM approach check out the [developer guide section on push](/manual/push/).
To migrate to the new FCM approach check out the [developer guide section on push](/developer-guide/push-notifications/).

### API Level 28 and HTTPS Requirement

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ There are many Codename One resources for building native mobile apps but they a
### Written Docs and Tutorials

* [• Create an Uber Clone in 7 Days](https://uber.cn1.co/) – Even if you don’t purchase the full book, the free chapters available to download will help you get started quickly.
* * [• Developer Guide](https://www.codenameone.com/manual/) – if you haven’t read the developer guide you should! Notice that it also comes in a [PDF](https://www.codenameone.com/files/developer-guide.pdf).
* * [• Developer Guide](/developer-guide/) – if you haven’t read the developer guide you should! Notice that it also comes in a [PDF](https://www.codenameone.com/files/developer-guide.pdf).
* * [• JavaDocs](https://www.codenameone.com/javadoc/) – our JavaDocs include some hidden features such as the [component gallery](/javadoc/com/codename1/ui/package-summary/) & [layout gallery](/javadoc/com/codename1/ui/layouts/package-summary/).
* * [• Sviluppare app multipiattaforma – Indice del corso introduttivo](https://www.informatica-libera.net/content/sviluppare-app-multipiattaforma-indice-del-corso-introduttivo) – Italian language free course for mobile cross-platform development by Francesco Galgani.
* * [• Port an Android app to iOS (iPhone)](/blog/port-native-android-app-ios-iphone-guide.html) – a step by step guide on porting a real world Android app to Codename One and getting it onto all the major stores.
Expand Down
Loading
Loading