StoreFront Client UI Customization API
This document lists CSS and Javascript extension points for Citrix Workspace app. Unless otherwise specified, these extensions apply to both web and native apps.
To ensure that customizations work across StoreFront upgrades, it is strongly recommended that you only modify styles, elements, and objects that are described in this document.
CSS Classes for Customization
.logo-container
Marker for elements containing the default logo, or a company logo to replace it. These containers are DIVs and the logo is set by indicating a background image.
.logo-container { background-image: url('WCOO_logo_white.png'); background-size: 100px 50px; }
<!--NeedCopy-->
Note:
If you want to specify a High DPI variant, you must ensure that the size of the image is reduced. Typically, the image size must be half of its pixel size.
.highdpi .logo-container { background-image: url('WCOO_logo_white@2x.png'); background-size: 100px 50px; }
<!--NeedCopy-->
.logon-logo-container
Company logo to replace the default logo in the main UI and authentication screens. Should specify a background image and background size.
.theme-header-color
Primary colors used for the header foreground. Should specify a ‘color’ attribute.
.theme-highlight-color
Highlight color used for clickable text / icons. Should specify a ‘color’ attribute.
.theme-header-bgcolor
Primary color (or fill) used for header region.
.button
The styles for buttons shown in popup messages. Often you want these to match the theme.
.default
Used in combination with the button
class to define the style for the default button. Note that if there is only one button it is the ‘default’, which is more often the case than not.
.large
This class indicates if the UI is the ‘large’ desktop/tablet UI as opposed to the ‘small’ phone UI. Many elements are affected by customizations to this class.
.small
This class indicates if the UI is the ‘small’ phone UI as opposed to the ‘large’ desktop/tablet UI. Many elements are affected by customizations to this class.
.largeTiles
This class indicates applications are displayed on large tiles, which occurs on the desktop/tablet UI.
.smallTiles
This class indicates applications are displayed on smaller tiles which occurs on the phone UI.
.highdpi
This class indicates we are using High DPI graphics – i.e. images twice their normal size. This is to ensure smooth display on a ‘retina’ or similar display.
.myhome-view
This class indicates that the page is on the Home
tab. Applies to StoreFront 1811 and newer.
.myapps-view
This class indicates that the page is on the Favorites
tab. This applies to versions prior to 1811 when the Favorites
tab was replaced with the Home
tab.
.store-view
This class indicates that the page is on the Apps tab.
.desktops-view
This class indicates that the page is on the Desktops tab.
.search-view
This class indicates that the page is displaying search results.
Areas for Custom Content
There are various custom areas within the UI, each of which is indicated by an ID that can be referenced from CSS and JavaScript. These elements are initially empty, but are expected to be used by extensions that need to add UI.
Typically changing the content of any of these is done with JavaScript from within the custom\script.js file. For example:
document.getElementById('customScrollTop').innerHTML = "<div class='wwco-hello'>Hello World</div>";
<!--NeedCopy-->
Note that the HTML added includes its own custom class. It is recommended that you prefix all new classes with a company name to avoid clashes with the (many) CSS classes defined and used by StoreFront.
To go with this you might add some CSS (in custom\style.css)
.wwco-hello { font-size: 20px; color: red; }
<!--NeedCopy-->
Note:
If you inspect the HTML you will find that these areas are inside containers called plugin[name]. These elements should not be used directly in customization code.
# CustomTop
An area in the top header region of the home screen, currently below the top bar and above the toolbar.
# CustomScrollTop
Area at the top of the scrolling region of the home page.
# CustomBottom
An area in the footer region of the home screen.
# CustomInfoTop
Area at the top of the app details (info) page.
# CustomInfo
Area on the app details (info) page.
# CustomExplicitAuthHeader
Header area on the explicit authentication screen.
# CustomExplicitAuthFooter
Footer area on the explicit authentication screen.
# CustomExplicitAuthTop
Area at the top of the explicit authentication screen.
# CustomExplicitAuthBottom
Area at the bottom of the explicit authentication screen.
# CustomAuthHeader
Header area on the general authentication screen (when shown).
# CustomAuthFooter
Footer area on the general authentication screen (when shown).
# CustomAuthTop
Area at the top of the general authentication screen (when shown).
# CustomAuthBottom
Area at the bottom of the general authentication screen (when shown).
.customAuthHeader
Header area on all authentication screens.
.customAuthFooter
Footer area on all authentication screens.
.customAuthTop
Area at the top of all authentication screens.
.customAuthBottom
Area at the bottom of all authentication screens.
Script Objects
The various script APIs pass, or use a number of JavaScript objects.
app
{
name, // Name of app.
description, // Description.
iconurl, // Icon for app (once loaded)
subscriptionstatus, // Current status, if subscription is supported
mandatory, // True if app is required
store, // Store object for this app
}
<!--NeedCopy-->
bundle
A bundle represents a Featured App Group.
{
title, // Name of the Featured App Group.
description, // Description of the Featured App Group.
tileid // Tile id.
}
<!--NeedCopy-->
Script Extension Points
These are called at various times during execution and can either pause or modify the behavior of Citrix. To use an extension point, define a function on CTXS.Extensions.
Where a function defines a callback, the callback should be called to continue normal operation. For example:
CTXS.Extensions.preInitialize = function(callback) {
alert("just starting");
callback();
};
<!--NeedCopy-->
Notifications of progress
These functions inform of UX changes and allow custom UX (e.g. message boxes) before proceeding. The callback() function is called when the client should continue.
For APIs passing a callback, you must call the callback function, though you may delay calling it until code of your own has run.
preInitialize(callback)
CTXS.Extensions.preInitialize = function(callback) {
// do stuff
callback();
};
<!--NeedCopy-->
postInitialize(callback)
CTXS.Extensions.postInitialize = function(callback) {
// do stuff
callback();
};
<!--NeedCopy-->
postConfigurationLoaded()
Called once we are configured to show the UI, but before the UI is visible.
CTXS.Extensions.postConfigurationLoaded = function() {
// do stuff
};
<!--NeedCopy-->
postAppListLoaded()
Note that during these calls, the UI may be hidden by native Citrix Workspace apps, so it is not safe to show UI.
beforeLogon(callback)
Web browsers only. Called prior to displaying any logon dialogs. You may call showMessage
here, or add your own UI.
CTXS.Extensions.beforeLogon = function(callback) {
// do stuff
callback();
};
<!--NeedCopy-->
beforeDisplayHomeScreen(callback)
Called prior to displaying the main UI. This is the ideal place to add custom startup UI.
Note that for native clients, the user may not have logged in at this stage, as some clients allow offline access to the UI.
CTXS.Extensions.beforeDisplayHomeScreen = function(callback) {
// do stuff
callback();
};
<!--NeedCopy-->
afterDisplayHomeScreen()
Called once the UI is loaded and displayed. The ideal place to call APIs to adjust the initial UI, for example to start in a different tab.
APIs used to monitor Workspace app environment
noteNativeClient(properties)
This is used when embedded in a native client to get details of the environment it is in.
CTXS.Extensions.noteNativeClient = function(properties) {
// do stuff
};
<!--NeedCopy-->
The properties
parameter has the following definition:
{
apiversion, // currently always 1.1
platform { id /* Platform id, eg windows */ },
preferredLanguages //Array of locales
}
<!--NeedCopy-->
noteNativeStore(store)
This passes information about the store being accessed. It returns a JavaScript object with properties id, baseUrl, type and workOffline.
CTXS.Extensions.noteNativeStore = function(properties) {
// do stuff
};
<!--NeedCopy-->
APIs used to modify the applications shown
preProcessAppData(store,json)
This is a low level and powerful call that gives the raw data returned from the server in response to a resources enumeration request. It can be used to modify the application list before any of the preceding processing takes place. However, it is generally preferable to use the preceding safe methods.
For a definition of the data, see the Web API specifications.
CTXS.Extensions.preProcessAppData = function(store,json) {
// Process resourcesList in place
};
<!--NeedCopy-->
noteStartLoadApps(store)
This is called at the beginning of processing apps for a given store. It is a good time to clear any cached lists.
CTXS.Extensions.noteStartLoadApps = function(store) {};
<!--NeedCopy-->
noteApp(app)
This is called for each app object that is to be included in the store. An extension might choose to modify an app here (for example to mark it as a desktop) or to remember the app object to add to a category or bundle later.
Useful if you want to remember specific apps (for example to launch them yourself). This is called during initialization, so you should not immediately attempt to use the app object until initialization completes.
CTXS.Extensions.noteApp = function(app) {};
<!--NeedCopy-->
excludeApp(app)
Exclude an application completely from all UI, even if it would normally be included.
CTXS.Extensions.excludeApp = function(app) {
// return true or false
};
<!--NeedCopy-->
If both includeApp and excludeApp return ‘false’ then the default policy is used.
includeApp(app)
Include an application, even if it would normally be excluded. For example, a platform might exclude applications intended for a different platform.
CTXS.Extensions.includeApp = function(app) {
// return true or false
};
<!--NeedCopy-->
If both includeApp and excludeApp return ‘false’ then the default policy is used.
includeInMyApps(app)
Force an app to be included in the “Favorites” view.
CTXS.Extensions.includeInMyApps = function(app) {
// return true or false
};
<!--NeedCopy-->
excludeFromMyApps(app)
Force an app to be excluded from the “Favorites” view.
CTXS.Extensions.excludeFromMyApps = function(app) {
// return true or false
};
<!--NeedCopy-->
APIs to arrange icons
sortCategoryAppList(app_array, category, defaultSortFn)
This API all allow the apps shown in category view to be sorted. You should modify the array of apps in place.
category is an object with the following properties:
{
fname, // Name of the leaf folder.
pname // Full path to folder.
}
<!--NeedCopy-->
CTXS.Extensions.sortCategoryAppList = function(appArray,category,
defaultSortFn) {
// Process appArray in place
};
<!--NeedCopy-->
sortBundleAppList(app_array, bundle, defaultSortFn)
This API allows the apps shown in a feature app group view to be sorted. You should modify the array of apps in place.
CTXS.Extensions.sortBundleAppList = function(appArray,bundle,
defaultSortFn) {
// Process appArray in place
};
<!--NeedCopy-->
sortMyAppList(app_array,defaultSortFn)
This API allows the favourites list to be sorted. You should modify the array of apps in place.
Note that the “Favorites” view supports user rearrangement by default, so sorting the list here may be confusing unless you also disable the user rearrangement.
CTXS.Extensions.sortMyAppList = function(appArray,defaultSortFn) {
// Process appArray in place
};
<!--NeedCopy-->
filterAllAppsDisplay(app_array,defaultSortFn)
This API allows the apps in the all apps view to be filtered. You should modify the array of apps in place.
CTXS.Extensions.filterAllAppsDisplay = function(appArray,defaultSortFn) {
// Process appArray in place
};
<!--NeedCopy-->
filterDesktops(app_array,defaultSortFn)
This API allows the apps in the desktop apps view to be filtered. You should modify the array of apps in place.
CTXS.Extensions.filterDesktops = function(desktopArray,defaultSortFn) {
// Process appArray in place
};
<!--NeedCopy-->
APIs related to UI updates
preRedraw()
This is a low-level catch-all functions intended to help tweak a UI that misbehaves. Normally the browser renders the UI correctly however occasionally this isn’t the case. In particular if you have added/removed elements that change the size of the scrolling area, then it is likely that the UI will be incorrect. To help handle these cases this warns you of significant UI changes which you can handle in postRedraw
. Generally, there are more specific callbacks on UI change.
CTXS.Extensions.preRedraw = function() {
// useful for logging
};
<!--NeedCopy-->
postRedraw()
This is a low-level catch-all function intended to help tweak a UI that misbehaves. Normally the browser renders the UI correctly however occasionally this isn’t the case. In particular if you have added/removed elements that change the size of the scrolling area, then it is likely that the UI will be incorrect. To help handle these cases you can call CTXS.ExtensionAPI.resize(). Generally, there are more specific callbacks on UI change.
CTXS.Extensions.postRedraw = function() {
// consider forcing a re-layout
};
<!--NeedCopy-->
beforeShowAppInfo(app)
Called prior to displaying the details page for an app. Useful to tweak the buttons/information to be displayed.
onFolderChange(folder path)
Called on the Store view if the folder is changed, passing the path. Also called passing “” if a non-folder view is selected on the store view.
onViewChange(view name)
Called if the view changes.
onAppHTMLGeneration(element)
Called when HTML is generated for one or more app tiles, passing the parent container. Intended for deep customization. Warning: this sort of change is likely to be version specific.
useNativeMessageBox(message id title or text)
Called whenever the UI is considering showing a native dialog, rather than a web dialog for a message. You can return false to force the web dialog to be used. Note that some error messages originate in native code and cannot be redirected to the web UI.
showMessageBox(params,defaultMessageBoxFn)
Allow override of the (web) dialog used for all error and similar messages, to enable a replacement function to be used.
getAppTileMarkup(app, appDisplayName, defaultMarkupFn)
Overrides the HTML markup for app tiles. You can call the default function and then modify the markup, or return custom markup. The return value must be a string. (StoreFront 3.5 and later).
getBundleMarkup(bundle, index, isFirst)
Provide custom HTML markup for Featured App Group tiles. The return value must be a string. (StoreFront 3.5 and later).
getFolderMarkup(folder, folderDisplayName, defaultMarkupFn)
Overrides the HTML markup for folder tiles. You can call the default function and then modify the markup, or return custom markup. The return value must be a string. (StoreFront 3.5 and later).
APIs related to user initiated operations
Calling the supplied function will allow the operation to proceed. Not calling it will cancel the action.
doLaunch(app,launchFn)
CTXS.Extensions.doLaunch = function(app, action) {
// call 'action' function if/when action should proceed
action();
};
<!--NeedCopy-->
postLaunch(app,status)
CTXS.Extensions.postLaunch = function(app,status) {
// do something
};
<!--NeedCopy-->
doSubscribe(app,subscribeFn)
CTXS.Extensions.doSubscribe = function(app, subscribeFn) {
// call 'action' function if/when action should proceed
subscribeFn();
};
<!--NeedCopy-->
postSubscribe(app)
Inform that a subscription has just taken place. (User clicked ‘Add’).
CTXS.Extensions.postSubscribe = function(app) {
// do something
};
<!--NeedCopy-->
doRemove(app, removeFn)
CTXS.Extensions.doRemove = function(app, removeFn) {
// call 'removeFn' function if/when remove should proceed
removeFn();
};
<!--NeedCopy-->
postRemove(app)
Inform that an app was removed (User clicked ‘Remove’).
CTXS.Extensions.postRemove = function(app) {
// do something
};
<!--NeedCopy-->
doInstall(app,installFn)
CTXS.Extensions.doInstall = function(app, action) {
// call 'action' function if/when action should proceed
action();
};
<!--NeedCopy-->
postInstall(app)
Inform that a previously subscribed app was added to this machine.
CTXS.Extensions.postInstall = function(app) {
// do something
};
<!--NeedCopy-->
APIs that only apply to web browsers
includeAuthenticationMethod(authenticationMethod)
Force inclusion of an authentication method, by returning true.
CTXS.Extensions.includeAuthenticationMethod = function(authMethod) {
// return true or false
};
<!--NeedCopy-->
excludeAuthenticationMethod(authenticationMethod)
Force exclusion of an authentication method, by returning true.
CTXS.Extensions.excludeAuthenticationMethod = function(authMethod) {
// return true or false
};
<!--NeedCopy-->
showWebReconnectMenu(bool_showByDefault)
Return true/false to enable/disable the menu item.
showWebDisconnectMenu(bool_showByDefault)
Return true/false to enable/disable the menu item.
webReconnectAtStartup(bool_ReconnectByDefault)
Return true/false to enable/disable reconnection at startup. Note that reconnection at startup is not supported on all platforms.
webLogoffIcaAction(string_defaultAction)
Return the action to be taken with regard to ICA sessions during logoff.
Return one of “disconnect”, “terminate” or “none”.
beforeWebLogoffIca(string_defaultAction)
The first phase of logoff is to handle ICA sessions.
Return one of “disconnect”, “terminate” or “none”.
beforeWebLogoffWebSession()
The second phase of logoff is to exit the web session from the server.
Return false to prevent web session termination.
beforeWebLogoffGateway
The third and final phase of logoff is to terminate any gateway session.
Return false to prevent gateway session termination.
afterWebLogoffComplete
Called once logoff has completed.
Action APIs
These are functions that can be called to make something happen, for example to launch an app or show a message box. These APIs are all defined on the CTXS.ExtensionAPI object.
showMessage(data)
Show a message box. ‘data’ is an object with the following parameters:
{
localize, // If true, then any string matching a key in the localization dictionary will be localized.
messageText, // Text to show
messageTitle, // Title for message box
okButtonText, // Optional button text (defaults to ok)
cancelButtonText, // Optional button text for a second button (defaults to cancel)
okAction, // Function to call if OK is clicked
cancelAction // Function to call if Cancel is clicked. (If omitted, only a single button is shown)
}
<!--NeedCopy-->
CTXS.ExtensionAPI.showMessage({
localize: true,
messageText: "Hello",
messageTitle: "Title",
okButtonText: "go",
cancelButtonText: "stop",
isalert: true,
okButtonAction: function() {},
cancelButtonAction: function(){}
});
<!--NeedCopy-->
Note that if cancelAction is null, then the cancel button is not shown.
resize()
Inform Workspace app that custom elements have changed size, and that it may need to update the UI layout. For example after adding/displaying new elements that might affect dynamically calculated layout (such as size of scrolling regions).
trace(message)
Send a trace message to the underlying trace system.
refresh()
Refresh application lists from server. May have side effects, such as reconnection and/or causing authentication prompts.
changeView(view,view title)
Change the current view being displayed. View can be one of the built in views (currently myapps, store, updates, appinfo) or a custom view. For custom views, also indicate the name of the view in case this forms part of the display (as it currently does on the phone).
Note that changing to the “appinfo” view will show the app info of the last app for which info was displayed - or return to the home screen if this is no longer valid. Changing to the “search” view is not supported.
navigateToFolder(path)
Change the current folder being displayed. View should be “store”.
addToolbarButton(text,button_class,optional_htmlContent,optional_onClickFn)
Add a button to the toolbar. The toolbar is currently shown only on the ‘apps’ view, though that may change, and it is possible to override this via CSS customization.
-
Class
is a class for the button itself. This should be provided to enable styling (for example to show/hide the button). Each button must have a unique class. -
Text
is the text to show on the button face. -
Content
is optional HTML content to display when this button is clicked. If provided, then the button is modal and will be highlighted when clicked (and other buttons unhighlighted). If omitted (null) then the button is not modal. Typically this HTML will itself include class references to enable styling. -
Action
is an optional function to call when the button is clicked.
CTXS.ExtensionAPI.addToolbarButton(
"wwco-button",
"Test",
"<div class='wwco-page'>Do not click this button again</div>");
<!--NeedCopy-->
addViewButton(view class,button text,view title)
Add an additional view button alongside Favorites, Desktops, and Apps.
-
Class
is the class for both the button and the view. If the name is ‘foo’ then the button class will be ‘foo-view’ and this class will also be added to when the view is selected. This is then used to control the display by providing custom content triggered by this class. -
Text
is text for the button face. -
Name
is the name of the view, in case it is shown in the UI (as is the case with the phone UI today).
CTXS.ExtensionAPI.addViewButton("wwco-help","Help", "WWCO Help");
<!--NeedCopy-->
Typically used with additional script such as:
document.getElementById("customScrollTop").innerHTML = "Call 911";
<!--NeedCopy-->
And additional style such as:
.wwco-helpPage { display:none; }
.wwco-help-view .wwco-helpPage { display:block; }
<!--NeedCopy-->
addInfoButton(text label, button class,onClickFn)
Add a button to the app info view.
addHelpButton(onClickFn)
Add a help button to the UI header.
For example:
CTXS.ExtensionAPI.addHelpButton(
function onClick() {
CTXS.ExtensionAPI.openUrl("https://example.com/helppage");
}
);
<!--NeedCopy-->
localStorageGetItem(name,callback fn)
Get an item from web local storage or the native equivalent. The callback function will be called passing the value, and this may return asynchronously.
localStorageSetItem(name,value,optional callback fn)
Set an item in web local storage or the native equivalent. The name and value should be strings. The callback is called once the value has been stored.
openUrl(url)
This opens a web page in a browser. If running in a browser then it will open in another tab in the same browser. If running in a native client it will open in the default browser.
proxyRequest(options,bool_loginFirst)
Proxy a request to a web service.
‘options’ is a subset of the jQuery ajax() request options. It is an object of the form:
{
data, // Optional data to send (string)
headers, // Optional header dictionary
type, // Request type (GET or POST)
url, // URL to call (relative to page)
dataType, // Type of returned data 'text'/'XML'/'json' (string, optional)
success, // Function to call on success
error // Function to call on error
}
<!--NeedCopy-->
Note that this is recommended only for access to the StoreFront server hosting the UI. Access to other servers may be limited by browser or native security policies.
enableSubscriptionProperties()
Enable subscription (and extended app) properties when communicating with the server.
updateSubscriptionProperties(app,callback)
Update the subscription properties stored on the server for an app to match the in memory object. The callback function is called on completion, passing a status string.
launch(app)
Launch an app or desktop.
showSelectedApps(apps)
Given an array of app objects, displays the corresponding app icons in the UI. (StoreFront 3.5 and later).
In this article
- CSS Classes for Customization
- Areas for Custom Content
- Script Objects
- Script Extension Points
- Notifications of progress
- APIs used to monitor Workspace app environment
- APIs used to modify the applications shown
- APIs to arrange icons
- APIs related to UI updates
- APIs related to user initiated operations
- APIs that only apply to web browsers
- Action APIs