UNPKG

@oat-sa/tao-test-runner-qti

Version:
203 lines (189 loc) 7.42 kB
define(['i18n', 'taoTests/runner/plugin', 'ui/hider', 'util/shortcut', 'util/namespace', 'taoQtiTest/runner/helpers/map', 'taoQtiTest/runner/plugins/tools/answerMasking/answerMasking'], function (__, pluginFactory, hider, shortcut, namespaceHelper, mapHelper, answerMaskingFactory) { 'use strict'; __ = __ && Object.prototype.hasOwnProperty.call(__, 'default') ? __['default'] : __; pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory; shortcut = shortcut && Object.prototype.hasOwnProperty.call(shortcut, 'default') ? shortcut['default'] : shortcut; namespaceHelper = namespaceHelper && Object.prototype.hasOwnProperty.call(namespaceHelper, 'default') ? namespaceHelper['default'] : namespaceHelper; mapHelper = mapHelper && Object.prototype.hasOwnProperty.call(mapHelper, 'default') ? mapHelper['default'] : mapHelper; answerMaskingFactory = answerMaskingFactory && Object.prototype.hasOwnProperty.call(answerMaskingFactory, 'default') ? answerMaskingFactory['default'] : answerMaskingFactory; /* * 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) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); * */ /** * The public name of the plugin * @type {String} */ var pluginName = 'answer-masking'; /** * The prefix of actions triggered through the event loop * @type {String} */ var actionPrefix = `tool-${pluginName}-`; /** * Stores the masking state for each item in the test * @type {Object} */ var itemStates = {}; /** * Default Configuration */ var defaultConfig = { restoreStateOnToggle: true, restoreStateOnMove: true }; /** * Returns the configured plugin */ var plugin = pluginFactory({ name: pluginName, /** * Initialize the plugin (called during runner's init) */ init: function init() { const self = this; const testRunner = this.getTestRunner(); const testRunnerOptions = testRunner.getOptions(); const pluginConfig = Object.assign({}, defaultConfig, this.getConfig()); const pluginShortcuts = (testRunnerOptions.shortcuts || {})[pluginName] || {}; const $contentArea = this.getAreaBroker().getContentArea(); var answerMasking = answerMaskingFactory($contentArea); function isPluginEnabled() { //to be activated with the special category x-tao-option-answerMasking const answerMaskingCategory = mapHelper.hasItemCategory(testRunner.getTestMap(), testRunner.getTestContext().itemIdentifier, 'answerMasking', true); return answerMaskingCategory && itemContainsChoiceInteraction(); } function itemContainsChoiceInteraction() { var $container = self.getAreaBroker().getContentArea().parent(); return $container.find('.qti-choiceInteraction').length; } function togglePluginButton() { if (isPluginEnabled()) { self.show(); } else { self.hide(); } } function togglePlugin() { if (!answerMasking.getState('enabled')) { enableMasking(); } else { disableMasking(); } } function enableMasking() { var testContext = testRunner.getTestContext(), itemId = testContext.itemIdentifier; answerMasking.enable(); if (pluginConfig.restoreStateOnToggle) { answerMasking.setMasksState(itemStates[itemId]); } self.button.turnOn(); self.trigger('start'); } function disableMasking() { var testContext = testRunner.getTestContext(), itemId = testContext.itemIdentifier; if (answerMasking.getState('enabled')) { itemStates[itemId] = answerMasking.getMasksState(); } answerMasking.disable(); self.button.turnOff(); self.trigger('end'); } // create buttons this.button = this.getAreaBroker().getToolbox().createEntry({ title: __('Answer Masking'), icon: 'result-nok', control: 'answer-masking', text: __('Answer Masking') }); // attach user events this.button.on('click', function (e) { e.preventDefault(); testRunner.trigger(`${actionPrefix}toggle`); }); if (testRunnerOptions.allowShortcuts) { if (pluginShortcuts.toggle) { shortcut.add(namespaceHelper.namespaceAll(pluginShortcuts.toggle, this.getName(), true), function () { testRunner.trigger(`${actionPrefix}toggle`); }, { avoidInput: true, prevent: true }); } } //start disabled this.disable(); //update plugin state based on changes testRunner.on('loaditem', function () { var testContext = testRunner.getTestContext(), itemId = testContext.itemIdentifier; if (!pluginConfig.restoreStateOnMove) { itemStates[itemId] = []; } togglePluginButton(); }).on('enabletools renderitem', function () { togglePluginButton(); // we repeat this here as we need the rendered item markup in order to decide whether the plugin is enabled self.enable(); }).on('beforeunloaditem', function () { disableMasking(); }).on('disabletools unloaditem', function () { self.disable(); disableMasking(); }).on(`${actionPrefix}toggle`, function () { if (isPluginEnabled()) { togglePlugin(); } }) // Answer-eliminator and Answer-masking are mutually exclusive tools .on('tool-eliminator-toggle', function () { disableMasking(); }); }, /** * Called during the runner's destroy phase */ destroy: function destroy() { shortcut.remove(`.${this.getName()}`); }, /** * Enable the button */ enable: function enable() { this.button.enable(); }, /** * Disable the button */ disable: function disable() { this.button.disable(); }, /** * Show the button */ show: function show() { this.button.show(); }, /** * Hide the button */ hide: function hide() { this.button.hide(); } }); return plugin; });