Bootstrapping ushell_abap for variant persistence - sapui5

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.

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?

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

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.

Bootstraping OpenUI5 from single JS file

OpenUI5 documentation suggests starting work by using a library loaded from CDN:
<script id="sap-ui-bootstrap"
type="text/javascript"
src="https://openui5.hana.ondemand.com/1.42.6/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m,sap.ui.table"></script>
Unfortunately, this approach means load cascading 4 scripts on startup:
sap-ui-core.js
sap/ui/core/library.js (why ?)
sap/m/library.js
sap/ui/table/library.js
Is there way to bundle this four libraries into one script file?
Unfortunately, this approach means load cascading multiple scripts on startup:
The cascading behavior is mostly due to missing an option that tells the framework to load UI5-libraries and other modules asynchronously. In order to fix it, please add the following attribute too:
data-sap-ui-async="true" // available since 1.58.2 --> Replaces preload="async" *
data-sap-ui-preload="async" // for 1.58.1 and below
* Prerequisite: Is Your Application Ready for Asynchronous Loading?
Is there way to bundle these four libraries into one script file?
Yes; with a self-contained build (e.g. ui5 build self-contained --all ), you can reduce the size of your application as well as number of requests by bundling the required modules into a single file sap-ui-custom.js
In the above screenshot, for example, sap-ui-custom.js contains only the required modules from sap.ui.core-, sap.m-, sap.ui.table-, and sap.ui.unified-library, in addition to application related resources such as the controllers, views, etc..
See openui5-sample-app and the UI5 tooling for official documentation.

Umbraco with Windsor Castle error after adding nuPickers plugin

With an existing Umbraco site running fine we added the nuPickers plugin which does not seem to like Castle. In the browser console we are seeing a lot of 404 / 500 errors being generated for the embedded resources within the plugin. (The plugin is a single DLL with css and js files embedded in it.)
The site continues running fine (back and front ends), except for the plugin.
The Event log is showing: "No component for supporting the service nuPickers.EmbeddedResourceController was found"
We have tried route.ignoreroute in our route config, and also adding a handler in web.config, both unsuccessfully, as we do not think the resource requests should be getting to castle?
Any help or pointers gratefully accepted!
Just in case anyone comes across this ticket, we 'solved' this by
Getting all of the embedded resources, (html, js & css - not the classes)
Physically placing them inside the App_plugins folder in the correct structure (as they were being requested),
Renaming the js and css files (by adding the .nu after the file
extension), and,
Adding the following mime types into the web.config
mimeMap fileExtension=".css.nu" mimeType="text/css"
mimeMap fileExtension=".js.nu" mimeType="application/javascript"
Then, everything seems to work - but there MUST be a better solution, surely?

Standalone GWT Deployment

So, this is a pretty trivial thing to accomplish apparently, but for some reason it just will not work for me. I created a VERY SIMPLE GWT app. It uses UIBinder just to display a label and a button, no actual processing or handling takes place. I did this to test deploying the app using strictly JS and html that is not hosted by Eclipse and Jetty or whatever.
I compile my app, run it in eclipse, and it works fine. However, when I try to run the html page directly from the WAR directory, it does not work.
Do I need this running on a webserver for it to work? It is just html and js, so I shouldn't? I've been to the GWT site about deploying, and surfed quite a few forums. They seem to always mention the necessity of a server, but it seems like it should not be necessary?
Since it is a pure JavaScript and HTML it should work properly without server. Checkout this link: Compile and run in Production Mode with Eclipse
In your EntryPoint class, in onModuleLoad() there's a RootPanel.get("someDivId") call somewhere. Make sure your html page (=the host page) contains a div with that id.
Also make sure your host page calls the right java script file. It's easy to forget to edit the host page after you renamed your GWT module (see rename-to in your .gwt.xml), as the generated JavaScript file matches your module name.
This will work locally on all browsers except Chrome for security reasons.
See http://code.google.com/p/chromium/issues/detail?id=31068
and http://code.google.com/p/chromium/issues/detail?id=70088