@oat-sa/tao-test-runner-qti
Version:
TAO Test Runner QTI implementation
304 lines (271 loc) • 9.37 kB
JavaScript
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; under version 2
* of the License (non-upgradable).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Copyright (c) 2016 (original work) Open Assessment Technologies SA ;
*/
/**
* Test Runner Tool Plugin : item Theme Switcher
*
* @author
*/
import $ from 'jquery';
import _ from 'lodash';
import __ from 'i18n';
import pluginFactory from 'taoTests/runner/plugin';
import 'ui/hider';
import themeHandler from 'ui/themes';
import shortcut from 'util/shortcut';
import namespaceHelper from 'util/namespace';
import themeLoader from 'ui/themeLoader';
/**
* Returns the configured plugin
*/
export default pluginFactory({
name: 'itemThemeSwitcher',
/**
* Install step, add behavior before the lifecycle.
*/
install: function install() {
//define the "itemThemeSwitcher" store as "volatile" (removed on browser change).
this.getTestRunner()
.getTestStore()
.setVolatile(this.getName());
},
/**
* Initialize the plugin (called during runner's init)
*/
init: function init() {
var self = this;
var pluginName = this.getName();
var testRunner = this.getTestRunner();
var testRunnerOptions = testRunner.getOptions();
var pluginShortcuts = (testRunnerOptions.shortcuts || {})[this.getName()] || {};
const pluginConfig = this.getConfig();
this.oldNamespace = themeHandler.getActiveNamespace();
const state = {
availableThemes: [],
defaultTheme: '',
selectedTheme: ''
};
const allMenuEntries = [];
if (pluginConfig.activeNamespace) {
themeHandler.setActiveNamespace(pluginConfig.activeNamespace);
}
const themesConfig = themeHandler.get('items') || {};
if (pluginConfig.activeNamespace !== this.oldNamespace && !_.isEmpty(themesConfig)) {
reloadThemes();
}
/**
* Tells if the component is enabled
* @returns {Boolean}
*/
function isPluginAllowed() {
return themesConfig && _.size(themesConfig.available) > 1;
}
/**
* Reloads theme config and changes theme
*/
function reloadThemes() {
var themeConfig = themeHandler.get('items');
themeLoader(themeConfig).load();
if (state && state.selectedTheme) {
changeTheme(state.selectedTheme);
} else {
changeTheme(themeConfig.default);
}
}
/**
* Load the selected theme
* @param themeId
*/
function changeTheme(themeId) {
var $qtiItem = $('.qti-item');
var previousTheme = state.selectedTheme;
state.selectedTheme = themeId;
if ($qtiItem) {
_.defer(function() {
$qtiItem.trigger('themechange', [state.selectedTheme]);
});
}
if (self.storage) {
self.storage.setItem('itemThemeId', themeId);
}
if (previousTheme !== state.selectedTheme) {
testRunner.trigger('themechange', state.selectedTheme, previousTheme);
}
allMenuEntries.forEach(function(menuEntry) {
if (menuEntry.getId() === themeId) {
menuEntry.turnOn();
} else {
menuEntry.turnOff();
}
});
}
//init plugin state
if (themesConfig) {
if (themesConfig.default) {
state.defaultTheme = themesConfig.default;
state.selectedTheme = themesConfig.default;
changeTheme(themesConfig.default);
}
if (themesConfig.available) {
_.forEach(themesConfig.available, function(theme) {
state.availableThemes.push({
id: theme.id,
label: __(theme.name)
});
});
}
}
// register toolbox button
this.menuButton = this.getAreaBroker()
.getToolbox()
.createMenu({
control: 'color-contrast',
title: __('Change the current color preset'),
icon: 'contrast',
text: __('Contrast')
})
.after('render', () => {
if (!isPluginAllowed()) {
self.hide();
}
})
.on('click', function(e) {
e.preventDefault();
testRunner.trigger('tool-themeswitcher-toggle');
})
.on('openmenu', function() {
testRunner.trigger(`plugin-open.${pluginName}`, state.selectedTheme);
})
.on('closemenu', function() {
testRunner.trigger(`plugin-close.${pluginName}`, state.selectedTheme);
});
// register menu entries
state.availableThemes.forEach(function(theme) {
var themeEntry = self
.getAreaBroker()
.getToolbox()
.createEntry({
role: 'option',
control: theme.id,
title: theme.label,
icon: 'preview',
text: __(theme.label)
});
themeEntry.setMenuId('color-contrast');
themeEntry.on('click', function(e) {
var themeId = this.config.control;
e.preventDefault();
self.menuButton.turnOffAll();
this.turnOn();
changeTheme(themeId);
});
if (state.defaultTheme === theme.id) {
themeEntry.on('render', function() {
this.turnOn();
});
}
allMenuEntries.push(themeEntry);
});
if (testRunnerOptions.allowShortcuts) {
if (pluginShortcuts.toggle) {
shortcut.add(
namespaceHelper.namespaceAll(pluginShortcuts.toggle, this.getName(), true),
function() {
testRunner.trigger('tool-themeswitcher-toggle');
},
{
avoidInput: true
}
);
}
}
if (!isPluginAllowed()) {
this.hide();
}
//start disabled
this.disable();
//update plugin state based on changes
testRunner
.on('loaditem', function() {
if (isPluginAllowed()) {
self.show();
} else {
self.hide();
}
})
.on('renderitem', function() {
self.enable();
changeTheme(state.selectedTheme);
})
.on('enabletools', function() {
self.enable();
})
.on('disabletools unloaditem', function() {
self.disable();
})
.on('tool-themeswitcher-toggle', function() {
if (self.getState('enabled') !== false) {
self.menuButton.toggleMenu();
}
})
.on('tool-themeswitcher-setnavtype', function(type) {
self.menuButton.setNavigationType(type);
});
return testRunner.getPluginStore(this.getName()).then(function(itemThemesStore) {
self.storage = itemThemesStore;
self.storage.getItem('itemThemeId').then(function(itemThemeId) {
if (itemThemeId && state.selectedTheme !== itemThemeId) {
changeTheme(itemThemeId);
}
});
});
},
/**
* Called during the runner's destroy phase
*/
destroy: function destroy() {
themeHandler.setActiveNamespace(this.oldNamespace);
shortcut.remove(`.${this.getName()}`);
return this.getTestRunner().getPluginStore(this.getName()).then(function(itemThemesStore) {
return itemThemesStore.removeItem('itemThemeId');
});
},
/**
* Enable the button
*/
enable: function enable() {
this.menuButton.enable();
},
/**
* Disable the button
*/
disable: function disable() {
this.menuButton.disable();
},
/**
* Show the button
*/
show: function show() {
this.menuButton.show();
},
/**
* Hide the button
*/
hide: function hide() {
this.menuButton.hide();
}
});