UI5 parameters: data-sap-ui-xx-waitfortheme and data-sap-ui-xx-componentpreload - sapui5

The UI5 HTML-bootstrapper has two parameters which I don't really understand:
data-sap-ui-xx-componentpreload
data-sap-ui-xx-waitfortheme
I've checked the official documentation and didn't get some straightforward description.
My questions:
When should I use data-sap-ui-xx-componentpreload and what are its benefits?
When should I use data-sap-ui-xx-waitfortheme and what are its benefits?

⚠️ First things first ...
xx- options are experimental. They may be removed in future UI5 versions or their behavior may change in an incompatible way.
Option sap-ui-xx-componentPreload
By default, UI5 requests the app bundle Component-preload.js automatically when creating ComponentContainer (e.g. via data-sap-ui-oninit="module:sap/ui/core/ComponentSupport").
The bundle is generated by UI5 tooling for deployment so that users finally use the optimized version of the app. Therefore, avoid shipping the standalone app with data-sap-ui-xx-componentpreload in index.html! Otherwise, users will end up using unnecessarily the unminified, unbundled developer version of the app.
Options in index.html (data-sap-ui-*) don't affect typical Fiori launchpad (FLP) apps as FLP uses its own HTML page.
Using sap-ui-xx-componentPreload makes only sense for previewing, testing, or demo scenarios where there is no Node.js environment (unable to use UI5 tooling) so that 404-errors can be avoided. SAP Web IDE, for example, used to append the option sap-ui-xx-componentPreload=off in the URL so that the preview runs without the 404-error.
Values
async or sync by default depending on the sap-ui-preload / sap-ui-async settings.
off to load Component.js instead of Component-preload.js despite having a ComponentContainer.
Option sap-ui-xx-waitForTheme
The xx-waitForTheme option helps to avoid FOUC (Flash Of Unstyled Content) and, in some cases, to reduce sync XHRs. The option tells the app to postpone certain tasks until the theme has been loaded and applied.
Values (since UI5 1.63)
init waits for the theme → executes Core's init handler (attachInit(fn)) → renders the app.
Use this if some controls try to access theme-dependent parameters via sap/ui/core/theming/Parameters.get synchronously (deprecated) too soon.
rendering (formerly true until 1.62) executes Core's init handler first → waits for the theme → initializes the rendering.
If there is no value set, Core's init and initial rendering are executed immediately without waiting for the theme → FOUC.
For more options and information, see Configuration Options and URL Parameters and its parent topics.

Related

How to make UI5 content compatible with the FLP setting "Asynchronous Module Loading"?

The "Site Settings" page available via "Manage Site" from the launchpad now allows enabling "Asynchronous Module Loading".
But once it's enabled, some of the SAPUI5 applications or FLP plugins fail to start. The browser reports in the console:
Failed to execute '<JavaScript module>.js': Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-scr * 'unsafe-inline' data: blob:".
How is CSP related to the "Asynchronous Module Loading" setting in this case and what can we do to avoid evaluating "string as JavaScript" in UI5?
Cause
If "Asynchronous Module Loading" is activated, not only does SAP Fiori launchpad (FLP) bootstrap SAPUI5 with data-sap-ui-async="true" but serves also its HTML document with the content-security-policy (CSP) response header that contains a set of CSP directives omitting unsafe-eval in script-src. Hence, UI5 applications and FLP plugins that initiate calling eval (and thus violating the CSP) won't be processed by the browser. In the future, stricter CSP directives might apply such as the script-src omitting unsafe-inline additionally.
In the legacy UI5 code, eval is called typically due to the application synchronously fetching JS modules via deprecated APIs. For other causes, see the table below.
Resolution
UI5 has already deprecated legacy/synchronous APIs and - with the 1.96 release - largely improved the support for strict CSP. UI5 content owners should adjust their code accordingly:
❌ UI5 content violating the CSP
✅ Making the UI5 content more CSP-compliant
Application's HTML document bootstrapping SAPUI5 without data-sap-ui-async="true" or with the debug mode activated.
Ensure that the HTML document bootstraps SAPUI5 with data-sap-ui-async="true" and that no debug mode is activated unnecessarily. Review Is Your Application Ready for Asynchronous Loading?
Using inline scripts (<script>...</script>) within the application's HTML document.
Use only <script src="..." ...></script> to comply with the CSP without unsafe-inline. Define the initial component declaratively via sap/ui/core/ComponentSupport.
Using deprecated APIs and libs such as jQuery.sap.*, sap.ui.requireSync, sap.ui.commons, sap.ca.scfld, ...
Review the documented API reference to learn about newer asynchronous APIs that replace the deprecated ones. Most importantly, use only sap.ui.define when defining new modules. When requiring, use sap.ui.require.
Fetching UI5 libs and components manually but still synchronously despite using non-deprecated APIs
Review the documented API reference to learn how to enable loading such resources asynchronously. E.g. when loading a UI5 lib manually:Core.loadLibrary("that.lib",/*async:*/true);
Creating the component content such as the root view, routed views, and nested views synchronously in runtime despite having them defined declaratively.
Implement the "sap.ui.core.IAsyncContentCreation" marker interface in Component.js to implicitly create the component content asynchronously.
Component-preload.js bundling JS modules as string due to:Using the outdated standard Grunt build task. Result:"my/Component.js":'sap.ui.define([...'Global instructions before calling sap.ui.define. Result:"my/Component.js":'var appID...'
Generate the Component-preload.js bundle by leveraging UI5 Tooling with e.g. ui5 build -a --clean-dest.When defining a UI5 module, avoid global instructions but only use sap.ui.define at top-level of the JS file.Result:"my/Component.js":function(){//...
For more detailed information about the current state of CSP in UI5 and which restrictions there are, see the documentation topic Content Security Policy.
Related Q&As
How to avoid "Synchronous XMLHttpRequest on the main thread" warning in UI5?
data-sap-ui-preload vs data-sap-ui-async?
How to detect eval calls when addressing UI5 modules in runtime?

Bootstrapping ushell_abap for variant persistence

I have a FIORI application (lunched from launchpad) in which I am using unified shell to persist variants.
In my index.html, I first bootstrap the ushell_abap and then ui bootstrap like this
<script id="sap-ushell-bootstrap" src="https://sapui5.hana.ondemand.com/1.90.0/resources/sap/ushell_abap/bootstrap/abap.js"></script>
<script id="sap-ui-bootstrap" src="https://sapui5.hana.ondemand.com/1.90.0/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ushell, sap.collaboration, sap.m, sap.ui.layout, sap.ui.ux3"
data-sap-ui-theme="sap_belize"
data-sap-ui-resourceroots='{"cvg.wallapp": "./"}'
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true"
data-sap-ui-frameOptions="trusted"
data-sap-ui-bindingSyntax="complex"
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport">
</script>
My app works fine, including variant persistence when running in localhost.
I now deploy the APP to my Fiori server and the bootstrapping process falls apart.
It completely fails to load my theme and associated styling (no custom styling just using the belize theme).
In the console I get the following errors:
includeStylesheet-dbg.js:77 GET https://xxxx:yyyy/sap/public/bc/themes/~client-810/~cache-Bo-MdJE9H9k-CMXXsBrbgsL9ZXQ/UI5/sap/suite/ui/commons/themes/Fiori_LP_Home_Theme/library.css net::ERR_ABORTED 404 (Not found)
One or more parameters could not be found. - sap.ui.core.theming.Parameters
As soon as I remove the bootstrapping of ushell_abap everything works (except the persistence of variants of course).
I have exhausted google searches and reading through the ushell documentation here https://sapui5.hana.ondemand.com/sdk/#/api/sap.ushell
Anyone with an idea on why bootstrapping is failing when truing to use ushell_abap ?
The main issue here was that the app was using a different version of the css libraries than the bootstrap libraries which caused errors (in this case core had new elements in css styling not available in the old css library for core).
If your APP is set up as a standalone APP as explained by Benedikt Kromer and you bootstrap to a specific sapui5 version in the index.html, you can force the app to use the same version css libraries by applying the style to the core on init of the main app.
In on init I just added:
sap.ui.getCore().applyTheme("sap_belize");
This forced the app to load css libraries from the same version I used to bootstrap.
You can see this by watching the network tab in developer tools.
I think you missed one key aspect of the launchpad.
"launched from launchpad" could mean:
It is opening a new tab - standalone -> no need to mention launchpad in the question.
Staying in the same tab - standard/desired setup.
If (1) and you try to load the launchpad theme in your 1.90.0 app. Make sure the ui5 version match exactly.
"parameters could not be found" Could indicate your Theme was create for an older UI5 version.
Possible solutions:
You could generate a theme, matching the standalone ui5 version upload it into an own BSP.
You can ignore the error, there may be some
ui-glitches.
In any case 404 errors indicate also that you didn't link the theme correct in the first place.
If (2), then your index.html is never called. UI5 is starting from the component.js. Hence all your bootstrapping there dosen't count.
In this case index.html is only the playground for local development.
For the shell, this is already in place. I'm not sure why you want to load it again.

Aurelia - How to do composite applications that can be loaded at runtime

What I'm trying to do in Aurelia, is something like Prism is doing in WPF- Composite applications.
So lets say I have a "shell" application that defines the main application layout, then i have modules that I can plugin at run-time. Those modules can be an Aurelia application per se or Aurelia plugin (don't know what to use - need recommendation).
When loaded, the module needs to add it's menu items to the main application menu to expose it's features.
This is a mockup of the application:
Each module can have multiple menu items and can be pretty complex.
I'm using latest Typescript, Aurelia-CLI to create the application, and I'm using the built-in bundler : Aurelia's new built-in bundler.
So What I don't know is:
Those modules/features - what must they be? (Maybe Aurelia Plugins, or another Aurelia application?)
How to load those modules/features at run-time? (like deploy it in some plugins folder and tell the main shell application to load them)
How to modify the main menu and add new menu items from the loaded module?
Please help
Aurelia supports ultra dynamic applications. Also, there have been other community members who have had similar requirements and was able to resolve it. So I think the scenario is possible.
It seems the sub-application can just be a route.How/where to load the route should be determined based on the application URL
Those modules doesn't need to do anything specific, they can just be a normal, plain JS/TS class with lifecycle methods to handle activation/deactivation. I guess that main shell and all sub-applications need to share a common URL, you cannot have more than one router.
There could be a singleton/central store for new route to register information about loaded features, or it can be loaded upfront by a configuration file/metadata file or a database fetch.
Here is a similar question from another community member that I think can help you see how to glue things to https://discourse.aurelia.io/t/dynamicaly-load-routes/1906

Why WebIde shows error for alert and console.log?

I am using WebIde of SAPUI5 development.
If I write a console.log or alert it shows error of unexpected Alert and so on inside of the editor.
While the code works and I prefer to not see these errors inside of the editor.
How can I customize WebIde to not show these kind of errors.
While it is discouraged to use console.log and alert statements in your code because
[...] such messages are considered to be for debugging purposes and therefore not suitable to ship to the client [...]
http://eslint.org/docs/rules/no-console
and
[...] JavaScripts’ alert, confirm, and prompt functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation [...]
http://eslint.org/docs/rules/no-alert
you can have your Linter configured to bypass these checks (although I would not recommend to do so)
But keep in mind these checks are not specific to SAPUI5 or Web IDE, rather for every Javascript project!
Anyway, since Web IDE uses ESLint, to disable the check, add the following on top of the affected Javascript file:
/*eslint-disable no-console, no-alert */

In GWT, which javascript function run when you click on a button?

GWT auto generate the JavaScript code.
I could not understand the generated code event mechanism.
for instance, which function run when I click on a button?
I would love to see the javascript that GWT generates for button with explanations
For event handling, GWT attaches a EventListener (generally, your widget) as an expando property (called __listener) of the elements. The events are then all handled by a single dispatch method that looks at the __listener expando of the event's target and dispatches the event to it. Of course, the dispatch method does a bit more (event previewing, entry/finally scheduled commands, etc.)
This dance is (or at least was) required to avoid memory leaks in browsers (mainly IE). You can find more details in the GWT wiki: https://code.google.com/p/google-web-toolkit/wiki/DomEventsAndMemoryLeaks
When you develop in GWT, you don't care about JavaScript.
You should look at the Java code, and search for a function that handles the click event for your button.
When you compile the code Compiler will generate the autoamted Javascript functions ...And that too in compressed (thats depends on your compile type).
It is very hard to find the corresponding function and widget id because those are generated by compiler ..So its better to debug your gwt code is hosted mode ..
Even you want to read the generated code while compiling give the compilation type to
DETAILED, which improves on PRETTY with even more detail (such as very verbose variable names)
Still more details available here .
You should use GWT Compiler options STYLE whenever you need to understand the GWT's output js. GWT by default compresses and obfuscates the javascript output as it uses OBF as default value for STYLE.
To prevent compression and obfuscation you can use PRETTY or DETAILED as the parameter to STYLE argument.
NOTE: You should always use OBF mode for production as it ensures smallest bandwidth usage along with obfuscation.
Reference - https://developers.google.com/web-toolkit/doc/latest/DevGuideCompilingAndDebugging#DevGuideCompilerOptions