diff --git a/docs/.vitepress/playground.mjs b/docs/.vitepress/playground.mjs
index c0aa9ba6..e75b3079 100644
--- a/docs/.vitepress/playground.mjs
+++ b/docs/.vitepress/playground.mjs
@@ -105,6 +105,16 @@ const NEEDS_MORE_THAN_A_BROWSER = [
why: 'calls a function module, and there is no application server to call one on',
what: /\bCALL\s+FUNCTION\b/i,
},
+ {
+ /* Not a transpiler question - whatever AUTHORITY-CHECK compiles to, the
+ * page in the browser has no user, no roles and no authorization objects,
+ * so sy-subrc after it means nothing. An example whose whole point is
+ * which branch the check takes cannot take either one here. Reasoned
+ * rather than watched, unlike the lines above it, and it fails towards no
+ * button like the rest. */
+ why: 'runs an authority check, and the browser has no user and no roles for one',
+ what: /\bAUTHORITY-CHECK\b/i,
+ },
];
/*
diff --git a/docs/advanced/extensibility/custom_control.md b/docs/advanced/extensibility/custom_control.md
index f208534b..4a55e723 100644
--- a/docs/advanced/extensibility/custom_control.md
+++ b/docs/advanced/extensibility/custom_control.md
@@ -29,8 +29,8 @@ view->ele( n = `View` ns = `mvc`
)->a( n = `onEvent` v = client->_event( `MY_EVENT` ) ).
```
-The wrapper class the previous builder needed for this
-([`z2ui5_cl_xml_view_cc`](https://github.com/abap2UI5/abap2UI5/blob/main/src/99/z2ui5_cl_xml_view_cc.clas.abap))
-is frozen along with the builder itself, and adding a method to it is no longer
-part of shipping a custom control.
+Nothing else is needed on the ABAP side. The builder writes whatever element
+and namespace you pass, verbatim, so a custom control is just another tag —
+there is no wrapper class to extend and no method to add before it can be
+used.
diff --git a/docs/advanced/extensibility/user_exits.md b/docs/advanced/extensibility/user_exits.md
index 37179ef4..19ead5ce 100644
--- a/docs/advanced/extensibility/user_exits.md
+++ b/docs/advanced/extensibility/user_exits.md
@@ -3,7 +3,7 @@ outline: [2, 4]
---
# User Exits
-abap2UI5 offers predefined user exits for tweaking the standard behavior. The interface [`Z2UI5_IF_EXIT`](https://github.com/abap2UI5/abap2UI5/blob/main/src/99/z2ui5_if_exit.intf.abap) exposes the user exits. To use them on your system, build a class that implements the interface and its methods. The abap2UI5 class [`Z2UI5_CL_UI5_USER_EXIT`](https://github.com/abap2UI5/abap2UI5/blob/main/src/01/04/z2ui5_cl_ui5_user_exit.clas.abap) calls them dynamically. Put your class in a custom package — **not** in the abap2UI5 packages.
+abap2UI5 offers predefined user exits for tweaking the standard behavior. The interface [`Z2UI5_IF_UI5_EXIT`](https://github.com/abap2UI5/abap2UI5/blob/main/src/02/z2ui5_if_ui5_exit.intf.abap) exposes the user exits. To use them on your system, build a class that implements the interface and its methods. The abap2UI5 class [`Z2UI5_CL_UI5_USER_EXIT`](https://github.com/abap2UI5/abap2UI5/blob/main/src/01/04/z2ui5_cl_ui5_user_exit.clas.abap) calls them dynamically. Put your class in a custom package — **not** in the abap2UI5 packages.
The interface exposes two exit methods:
- **`set_config_http_get`** — called on the initial HTTP GET request (page load). Use it to set frontend properties like the UI5 theme, the UI5 version, or the inline CSS.
@@ -15,19 +15,19 @@ Both methods take a `cs_config` changing parameter whose fields you can set as n
CLASS zcl_a2ui5_user_exit DEFINITION PUBLIC.
PUBLIC SECTION.
- INTERFACES z2ui5_if_exit.
+ INTERFACES z2ui5_if_ui5_exit.
ENDCLASS.
CLASS zcl_a2ui5_user_exit IMPLEMENTATION.
- METHOD z2ui5_if_exit~set_config_http_get.
+ METHOD z2ui5_if_ui5_exit~set_config_http_get.
cs_config-theme = `sap_belize`.
ENDMETHOD.
- METHOD z2ui5_if_exit~set_config_http_post.
+ METHOD z2ui5_if_ui5_exit~set_config_http_post.
cs_config-draft_exp_time_in_hours = 8.
@@ -47,21 +47,4 @@ CLASS zcl_a2ui5_user_exit IMPLEMENTATION.
ENDCLASS.
```
-::: tip The interface is being renamed
-`z2ui5_if_exit` becomes
-[`z2ui5_if_ui5_exit`](https://github.com/abap2UI5/abap2UI5/blob/main/src/02/z2ui5_if_ui5_exit.intf.abap),
-following the framework's naming. Both work — abap2UI5 looks up both
-interfaces, so an existing exit keeps running — and the examples here move to
-the new name once it is in a release. On `main` the old interface has already
-moved to the frozen `src/99` package, which is why the link above points
-there; it still ships and is still called. See
-[Deprecations](/resources/deprecations).
-:::
-
-::: warning The tab title is not set here
-`cs_config-title` is still on the structure — an exit that assigns it compiles
-and runs — but nothing reads it any more. The generated page always carries
-`
abap2UI5`, and the title the user sees is set by the running
-app with the `set_title` frontend event: see
-[Title](/cookbook/browser_interaction/title).
-:::
+
diff --git a/docs/advanced/renaming.md b/docs/advanced/renaming.md
index 497acc54..d21de96b 100644
--- a/docs/advanced/renaming.md
+++ b/docs/advanced/renaming.md
@@ -52,7 +52,7 @@ alone would let them collide; the segment is what keeps them apart.
| Segment | Meaning |
|---|---|
-| *(none)* — `z2ui5_if_app`, `z2ui5_if_client`, `z2ui5_if_exit` | **The public API.** The three interfaces carry no segment on purpose: they are the contract, and a contract does not move between layers. `z2ui5_if_types` carries none either and is the exception that proves the rule: it is retired, ships unchanged so existing apps keep compiling, and every type it held now sits on the object that uses it — see [Deprecations](/resources/deprecations) |
+| *(none)* — `z2ui5_if_app`, `z2ui5_if_client` | **The public API.** Both interfaces carry no segment on purpose: they are the contract, and a contract does not move between layers. `z2ui5_if_types` carries none either and is the exception that proves the rule: it is retired, ships unchanged so existing apps keep compiling, and every type it held now sits on the object that uses it — see [Deprecations](/resources/deprecations) |
| `ui5` | The framework itself — the engine and the shipped apps (`z2ui5_cl_ui5_handler`, `z2ui5_cl_ui5_srv_draft`, `z2ui5_cl_ui5_app_start`), plus the two public classes `z2ui5_cl_ui5_http_handler` and `z2ui5_cl_ui5_view_builder` |
| `ui5f` | The UI5 **f**rontend, embedded as ABAP string constants and **generated** — never edit one by hand, the next build overwrites it |
| `ajson`, `srt` | [ajson](/technical/tools/ajson) and [S-RTTI](/technical/tools/srtti), mirrored from their upstream projects under this namespace |
diff --git a/docs/configuration/authorization.md b/docs/configuration/authorization.md
index 15d77da3..0f7d698f 100644
--- a/docs/configuration/authorization.md
+++ b/docs/configuration/authorization.md
@@ -73,34 +73,63 @@ Alternatively, handle authorization within individual app classes. This approach
### Example: Authorization Check in an App Class
In this approach, each app checks the user's permissions, like traditional ABAP apps.
-
+
```abap
CLASS z2ui5_cl_app DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES z2ui5_if_app.
+ DATA mv_status TYPE string.
+
+ PROTECTED SECTION.
+ PRIVATE SECTION.
ENDCLASS.
CLASS z2ui5_cl_app IMPLEMENTATION.
METHOD z2ui5_if_app~main.
- " Run an authorization check before launching the app
- AUTHORITY-CHECK OBJECT `Z_APP_AUTH`
- ID `APP` FIELD `Z2UI5_APP_001`.
- IF sy-subrc <> 0.
- " Authorization failed, refuse access
- RETURN.
+ IF client->check_on_navigated( ).
+
+ " Run an authorization check before showing anything
+ AUTHORITY-CHECK OBJECT `Z_APP_AUTH`
+ ID `APP` FIELD `Z2UI5_APP_001`.
+
+ IF sy-subrc <> 0.
+ " Refuse, and SAY so - a blank screen looks like a broken app
+ mv_status = `You are not authorized to use this app.`.
+ client->message_box_display( text = mv_status
+ type = `error`
+ title = `Not authorized` ).
+ ELSE.
+ mv_status = |Authorized as { sy-uname }|.
+ ENDIF.
+
+ DATA(view) = z2ui5_cl_ui5_view_builder=>factory(
+ )->ele( n = `View` ns = `mvc`
+ )->a( n = `xmlns` v = `sap.m`
+ )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc`
+
+ )->ele( `Page`
+ )->a( n = `title` v = `Authorization`
+
+ )->tag( `Text`
+ )->a( n = `text` v = client->_bind( mv_status ) ) ).
+
+ client->view_display( view->stringify( ) ).
+
ENDIF.
- " Continue with app processing if authorized
- " (App logic goes here)
ENDMETHOD.
ENDCLASS.
```
+The refusal branch matters as much as the check. Returning without displaying
+anything leaves the user on an empty frame with nothing to go on — indistinguishable
+from an app that crashed. Say what happened, then return.
+
::: warning
If you don't add authorization checks at the app level, make sure users can't bypass service-level checks by navigating between apps.
:::
diff --git a/docs/configuration/performance.md b/docs/configuration/performance.md
index e466607f..c92950c5 100644
--- a/docs/configuration/performance.md
+++ b/docs/configuration/performance.md
@@ -48,18 +48,12 @@ METHOD z2ui5_if_app~main.
ENDMETHOD.
```
-::: tip You may see `client->view_model_update( )` in older code
-It used to be the way to ask for that push. It is a **no-op** now — the
-framework does it unconditionally — and it is scheduled for removal. Delete
-the call; nothing replaces it.
-:::
-
## Suggestions
Want to tune your app further? A few tips:
- Call `client->view_display` only when needed — on initialization and when the view structure changes. For a pure data change, set the attribute and return; the framework pushes the delta and UI5 re-renders only the controls that changed.
-- Bind data with `client->_bind` — the framework sends only the paths the user actually edited back to ABAP (a delta), so read-only and untouched fields cost nothing on the return trip. (`_bind_edit` is an obsolete alias of `_bind`.)
+- Bind data with `client->_bind` — the framework sends only the paths the user actually edited back to ABAP (a delta), so read-only and untouched fields cost nothing on the return trip.
- Declare public attributes in your app class only for variables shown on the frontend. This keeps the framework from reading unused values.
- Follow standard ABAP best practices, like cutting loops and choosing sorted tables, just like in any other ABAP project.
diff --git a/docs/configuration/security.md b/docs/configuration/security.md
index 82e1c579..8654a500 100644
--- a/docs/configuration/security.md
+++ b/docs/configuration/security.md
@@ -44,7 +44,7 @@ By default, abap2UI5 uses the CSP below (defined in `z2ui5_cl_ui5_user_exit`):
If needed, adjust the CSP in the [user exit](/advanced/extensibility/user_exits). The exit runs after the framework fills in the defaults, so whatever you set there overrides the default policy:
```abap
-METHOD z2ui5_if_exit~set_config_http_get.
+METHOD z2ui5_if_ui5_exit~set_config_http_get.
cs_config-content_security_policy = ``.
@@ -55,7 +55,7 @@ ENDMETHOD.
`'unsafe-eval'` weakens the protection CSP provides against script injection. The default keeps it only because OpenUI5 `1.71` — the oldest supported release — still executes fetched modules via `eval()` in its module loader. If you pin a modern UI5 release, no `eval()` is involved and you can remove `'unsafe-eval'` in the same exit where you set the bootstrap source. The example below is the default policy without `'unsafe-eval'`:
```abap
-METHOD z2ui5_if_exit~set_config_http_get.
+METHOD z2ui5_if_ui5_exit~set_config_http_get.
cs_config-src = `https://ui5.sap.com/resources/sap-ui-core.js`.
cs_config-theme = `sap_horizon`.
@@ -113,7 +113,7 @@ They live in `cs_config-t_security_header` and are set in the same
behind a proxy that already sets one of them can drop or change it:
```abap
-METHOD z2ui5_if_exit~set_config_http_get.
+METHOD z2ui5_if_ui5_exit~set_config_http_get.
" keep everything the framework set, override one entry
DELETE cs_config-t_security_header WHERE n = `Referrer-Policy`.
@@ -129,7 +129,7 @@ Every state-changing request in abap2UI5 is a POST, so the framework ships its o
**CSRF protection is active by default.** A fresh install rejects cross-origin POSTs without any configuration. If your endpoint must accept cross-origin POSTs (for example, behind a proxy setup where the origin legitimately differs), opt out in the [user exit](/advanced/extensibility/user_exits):
```abap
-METHOD z2ui5_if_exit~set_config_http_post.
+METHOD z2ui5_if_ui5_exit~set_config_http_post.
" escape hatch - only disable this if your endpoint must accept cross-origin POSTs
cs_config-check_csrf_active = abap_false.
diff --git a/docs/configuration/setup.md b/docs/configuration/setup.md
index 473f3b81..81d94a5a 100644
--- a/docs/configuration/setup.md
+++ b/docs/configuration/setup.md
@@ -3,19 +3,19 @@ outline: [2, 4]
---
# Setup
-Every UI5 application has an `index.html` that bootstraps the framework, picks a theme, loads a UI5 version and so on. With abap2UI5 you don't maintain that file by hand — the framework generates it on every page load. To change what ends up in it, implement the `z2ui5_if_exit` interface in your own ABAP class:
+Every UI5 application has an `index.html` that bootstraps the framework, picks a theme, loads a UI5 version and so on. With abap2UI5 you don't maintain that file by hand — the framework generates it on every page load. To change what ends up in it, implement the `z2ui5_if_ui5_exit` interface in your own ABAP class:
```abap
CLASS zcl_a2ui5_user_exit DEFINITION PUBLIC.
PUBLIC SECTION.
- INTERFACES z2ui5_if_exit.
+ INTERFACES z2ui5_if_ui5_exit.
ENDCLASS.
CLASS zcl_a2ui5_user_exit IMPLEMENTATION.
- METHOD z2ui5_if_exit~set_config_http_get.
+ METHOD z2ui5_if_ui5_exit~set_config_http_get.
" your configuration goes here
ENDMETHOD.
@@ -36,9 +36,9 @@ ENDCLASS.
Security-relevant headers and the Content Security Policy meta tag are configured separately — see [Security](/configuration/security).
-The tab title is **not** on this list. The generated page always carries `abap2UI5`, and the title the user sees is set by the running app with the `set_title` frontend event — see [Title](/cookbook/browser_interaction/title). The field `cs_config-title` still exists on `cs_config` so that existing exits compile, but nothing reads it.
+The tab title is **not** on this list. The generated page always carries `abap2UI5`, and the title the user sees is set by the running app with the `set_title` frontend event — see [Title](/cookbook/browser_interaction/title).
## See Also
- Official SAP documentation on [UI5 bootstrapping](https://sapui5.hana.ondemand.com/#/topic/91f2cebe7c8e4d289fd80a4f0c0bd2ca) and [configuration options](https://sapui5.hana.ondemand.com/#/topic/91f2d03b6f4d1014b6dd926db0e91070).
-- The [User Exit](/advanced/extensibility/user_exits) page documents every hook on `z2ui5_if_exit`.
+- The [User Exit](/advanced/extensibility/user_exits) page documents every hook on `z2ui5_if_ui5_exit`.
diff --git a/docs/configuration/setup/bootstrap_attributes.md b/docs/configuration/setup/bootstrap_attributes.md
index e3bac8cf..0835a72e 100644
--- a/docs/configuration/setup/bootstrap_attributes.md
+++ b/docs/configuration/setup/bootstrap_attributes.md
@@ -23,7 +23,7 @@ The UI5 bootstrap script tag in `index.html` accepts a long list of `data-sap-ui
To add an attribute — or override one of the defaults — append a row to `cs_config-t_add_config`. Each row contributes one `name='value'` pair to the script tag:
```abap
-METHOD z2ui5_if_exit~set_config_http_get.
+METHOD z2ui5_if_ui5_exit~set_config_http_get.
cs_config-t_add_config = VALUE #(
( n = `data-sap-ui-libs` v = `sap.m,sap.ui.table` )
diff --git a/docs/configuration/setup/logon_language.md b/docs/configuration/setup/logon_language.md
index 0eb11667..8fb59445 100644
--- a/docs/configuration/setup/logon_language.md
+++ b/docs/configuration/setup/logon_language.md
@@ -31,7 +31,7 @@ Most apps don't need this — the browser locale and the SAP logon language agre
You can also pin the UI5 locale via the bootstrap, instead of relying on a URL parameter:
```abap
-METHOD z2ui5_if_exit~set_config_http_get.
+METHOD z2ui5_if_ui5_exit~set_config_http_get.
cs_config-t_add_config = VALUE #(
( n = `data-sap-ui-language` v = `en` ) ).
diff --git a/docs/configuration/setup/style_css.md b/docs/configuration/setup/style_css.md
index 0d77a57c..30b11efb 100644
--- a/docs/configuration/setup/style_css.md
+++ b/docs/configuration/setup/style_css.md
@@ -6,7 +6,7 @@ outline: [2, 4]
UI5 supports app-specific CSS in addition to the theme. abap2UI5 injects whatever string you assign to `cs_config-styles_css` directly into a `