define([
'core/js/api/Listenable',
'layout.dt/js/spi/ThemeProvider',
'layout.dt/layouts.builtin/alta/js/AltaThemeProvider',
'layout.dt/layouts.builtin/fuse/js/FuseThemeProvider',
'layout.dt/layouts.builtin/fuse-r13/js/FuseThemeProviderR13'
], function(
Listenable,
ThemeProvider,
AltaThemeProvider,
FuseThemeProvider,
FuseThemeProviderR13) {
'use strict';
/**
* Registry of all ThemeProviders available to the system. New themes should
* include an {@Link extensions.dt/js/spi/ExtensionManager ExtensionManager
* SPI} implementation which will register and unregister them here.
*
* @AbcsExtension stable
* @version 17.1.5
*
* @private
* @singleton
* @exports layout.dt/js/api/ThemeProviderRegistry
* @constructor
*
* @example <caption>An example of a theme extension manager with methods to
* register (initialise) and unregister (destroy) theme providers.</caption>
* define([
* 'layout.dt/js/api/ThemeProviderRegistry',
* 'API.Example/js/SimpleThemeProvider'
* ], function(
* ThemeProviderRegistry,
* SimpleThemeProvider
* ) {
*
* 'use strict';
*
* var ThemeExtensionManager = function () {
* };
*
* ThemeExtensionManager.prototype.initialise = function (dependencies) {
* ThemeProviderRegistry.registerThemeProvider(SimpleThemeProvider);
* };
*
* ThemeExtensionManager.prototype.destroy = function (dependencies) {
* ThemeProviderRegistry.unregisterThemeProvider(SimpleThemeProvider);
* };
*
* ThemeExtensionManager.prototype.generateRuntimeCode = function(dependencies) {
* };
*
* return new ThemeExtensionManager();
* });
* @see {@Link extensions.dt/js/spi/ExtensionManager SPI providing hook
* points for extensions (e.g. a theme) initialization and destruction}
*/
var ThemeProviderRegistry = function() {
AbcsLib.checkThis(this);
AbcsLib.checkSingleton(ThemeProviderRegistry);
Listenable.apply(this);
var self = this;
self._initialize();
};
AbcsLib.mixin(ThemeProviderRegistry, Listenable);
ThemeProviderRegistry._LOGGER = Logger.get('ThemeProviderRegistry');
/**
* Theme provider registered event.
*
* @event layout.dt/js/api/ThemeProviderRegistry#EVENT_THEME_PROVIDER_REGISTERED
* @property {String} theme ID of the registered provider
*/
ThemeProviderRegistry.EVENT_THEME_PROVIDER_REGISTERED = 'themeProviderRegistered';
/**
* Theme provider unregistered event.
*
* @event layout.dt/js/api/ThemeProviderRegistry#EVENT_THEME_PROVIDER_UNREGISTERED
* @property {String} theme ID of the unregistered provider
*/
ThemeProviderRegistry.EVENT_THEME_PROVIDER_UNREGISTERED = 'themeProviderUnregistered';
// Bundled internal themes. The intention is to move these out to be
// bundled extensions.
ThemeProviderRegistry._BUNDLED_THEME_PROVIDERS = [AltaThemeProvider, FuseThemeProviderR13, FuseThemeProvider];
/**
* Gets all registered theme providers
*
* @returns {layout.dt/js/api/ThemeProvider[]} array of available theme providers
*/
ThemeProviderRegistry.prototype.getThemeProviders = function() {
return this._registry;
};
/**
* Gets array of descriptors for all registered theme providers
*
* @param filter value to filter by, or undefined
* @returns {layout.dt/js/api/ThemeDescriptor[]} array of available descriptors
*/
ThemeProviderRegistry.prototype.getThemeDescriptors = function(filter) {
var themeDescriptors = [];
for (var i = 0; i < this._registry.length; i++) {
var descriptor = this._registry[i].getDescriptor();
if (filter) {
filter = filter.toLowerCase();
if (descriptor.getId().toLowerCase().indexOf(filter) > -1 ||
descriptor.getTitle().toLowerCase().indexOf(filter) > -1 ||
(descriptor.getDescription() && descriptor.getDescription().toLowerCase().indexOf(filter) > -1)) {
themeDescriptors.push(descriptor);
}
} else {
themeDescriptors.push(descriptor);
}
}
return themeDescriptors;
};
/**
* Returns the provider for the requested theme ID
*
* @param {String} themeId Theme ID to check
* @returns {ThemeDescriptor} the descriptor for the themeId, if registered,
* otherwise null
*/
ThemeProviderRegistry.prototype.getThemeDescriptorForTheme = function(themeId) {
var i;
for (i = 0; i < this.getThemeProviders().length; i++) {
if (this._registry[i].getDescriptor().getId() === themeId) {
return this._registry[i].getDescriptor();
}
}
return null;
};
/**
* Determines whether a theme with the supplied ID is registered.
*
* @param {String} themeId Theme ID to check
* @returns {Boolean} true if the theme is supported, false otherwise
*/
ThemeProviderRegistry.prototype.isSupportedThemeId = function(themeId) {
var i;
for (i = 0; i < this.getThemeProviders().length; i++) {
if (this._registry[i].getDescriptor().getId() === themeId) {
return true;
}
}
return false;
};
/**
* Returns the provider for the requested theme ID
*
* @param {String} themeId Theme ID to check
* @returns {ThemeProvider} the provider for the themeId, if registered, otherwise null
*/
ThemeProviderRegistry.prototype.getThemeProviderForTheme = function(themeId) {
var i;
for (i = 0; i < this.getThemeProviders().length; i++) {
if (this._registry[i].getDescriptor().getId() === themeId) {
return this._registry[i];
}
}
return null;
};
/**
* Registers the given theme provider.
*
* @AbcsExtension stable
* @version 17.1.5
*
* @param {layout.dt/js/spi/ThemeProvider} themeProvider The theme provider
* to register
*/
ThemeProviderRegistry.prototype.registerThemeProvider = function(themeProvider) {
AbcsLib.checkParameterCount(arguments, 1);
AbcsLib.checkDataType(themeProvider, AbcsLib.Type.OBJECT);
// Temporary fix until BUFP-10314 is solved ----------------------------
// to allow use of theme providers including public fields
// AbcsLib.checkSPIImpl(themeProvider, ThemeProvider); // Commented out
if (!(themeProvider instanceof ThemeProvider)) {
var themeSpiFunctionKeys = Object.keys(ThemeProvider.prototype);
AbcsLib._checkSPIFunctions(themeProvider, themeSpiFunctionKeys);
}
// Temporary fix until BUFP-10314 is solved - END ----------------------
var self = this;
var themeId = themeProvider.getDescriptor().getId();
var existingProvider = self.getThemeProviderForTheme(themeId);
if (existingProvider) {
ThemeProviderRegistry._LOGGER.debug('Replacing existing theme provider: ' + themeId);
self.unregisterThemeProvider(existingProvider);
}
self._registry.push(themeProvider);
ThemeProviderRegistry._LOGGER.debug('Registered theme provider: ' + themeProvider.getDescriptor().getId());
self.fireEvent(ThemeProviderRegistry.EVENT_THEME_PROVIDER_REGISTERED, themeId);
};
/**
* Unregister the supplied theme provider, if it's registered.
*
* @AbcsExtension stable
* @version 17.1.5
*
* @param {layout.dt/js/spi/ThemeProvider} themeProvider the theme provider
* to unregister
*/
ThemeProviderRegistry.prototype.unregisterThemeProvider = function(themeProvider) {
AbcsLib.checkParameterCount(arguments, 1);
AbcsLib.checkDataType(themeProvider, AbcsLib.Type.OBJECT);
// Temporary fix until BUFP-10314 is solved ----------------------------
// to allow use of theme providers including public fields
// AbcsLib.checkSPIImpl(themeProvider, ThemeProvider); // Commented out
if (!(themeProvider instanceof ThemeProvider)) {
var themeSpiFunctionKeys = Object.keys(ThemeProvider.prototype);
AbcsLib._checkSPIFunctions(themeProvider, themeSpiFunctionKeys);
}
// Temporary fix until BUFP-10314 is solved - END ----------------------
var themeId = themeProvider.getDescriptor().getId();
var self = this;
var i, nextDescriptor;
var location = -1;
for (i = 0; i < self._registry.length; i++) {
nextDescriptor = self._registry[i].getDescriptor();
if (nextDescriptor && nextDescriptor.getId() === themeId) {
location = i;
}
}
if (location !== -1) {
self._registry.splice(location, 1);
ThemeProviderRegistry._LOGGER.debug('Unregistered theme provider: ' + themeProvider.getDescriptor().getId());
self.fireEvent(ThemeProviderRegistry.EVENT_THEME_PROVIDER_UNREGISTERED, themeId);
} else {
ThemeProviderRegistry._LOGGER.debug('Couldn\'t unregister unexisting theme provider: ' + themeProvider.getDescriptor().getId());
}
};
/**
* Initialize the registry.
* @returns {undefined}
*/
ThemeProviderRegistry.prototype._initialize = function() {
this._registry = [];
this._loadBundledThemes();
};
/**
* Register any themes bundled with ABCS.
*
* @returns {undefined}
*/
ThemeProviderRegistry.prototype._loadBundledThemes = function() {
var self = this;
ThemeProviderRegistry._BUNDLED_THEME_PROVIDERS.forEach(function(provider) {
self.registerThemeProvider(provider);
ThemeProviderRegistry._LOGGER.debug('Added bundled theme provider: ' + provider.getDescriptor().getId());
});
};
return AbcsLib.initSingleton(ThemeProviderRegistry);
});