UNPKG

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

Version:
235 lines (219 loc) 8.53 kB
define(['lodash', 'i18n', 'taoTests/runner/plugin', 'ui/hider', 'util/shortcut', 'util/namespace', 'taoQtiTest/runner/helpers/map', 'taoQtiTest/runner/plugins/tools/lineReader/compoundMask'], function (_, __, pluginFactory, hider, shortcut, namespaceHelper, mapHelper, compoundMaskFactory) { 'use strict'; _ = _ && Object.prototype.hasOwnProperty.call(_, 'default') ? _['default'] : _; __ = __ && 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; compoundMaskFactory = compoundMaskFactory && Object.prototype.hasOwnProperty.call(compoundMaskFactory, 'default') ? compoundMaskFactory['default'] : compoundMaskFactory; /** * 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 ; */ /** * The public name of the plugin * @type {String} */ var pluginName = 'line-reader'; /** * The prefix of actions triggered through the event loop * @type {String} */ var actionPrefix = `tool-${pluginName}-`; /** * Options for the compoundMask factory * @type {Object} */ var maskOptions = { dragMinWidth: 17, dragMinHeight: 7, resizeHandleSize: 7, innerDragHeight: 20 }; var dimensions, position; /** * These functions are a first effort to place the mask on the first line on the item * They make a lot of assumptions: * - the item starts with a text * - the padding is set on the .qti-item container * - the padding is consistent with the minWidth/minHeight configuration of the mask * - and some other... * @param {jQuery} $container - where the mask is appended */ function getDimensions($container) { var $qtiContent = $container.find('#qti-content'), $qtiItem = $qtiContent.find('.qti-item'), lineHeight = Math.ceil(parseFloat($qtiContent.css('line-height'))) || 20; // reasonable default line height return { outerWidth: $qtiItem.width() + maskOptions.resizeHandleSize * 4 + maskOptions.dragMinWidth * 2, outerHeight: 175, // reasonable default height innerWidth: $qtiItem.width(), innerHeight: lineHeight }; } function getPosition($container) { var $qtiContent = $container.find('#qti-content'), $qtiItem = $qtiContent.find('.qti-item'), itemPosition = $qtiItem.position() || {}, paddingLeft = parseInt($qtiItem.css('padding-left'), 10), paddingTop = parseInt($qtiItem.css('padding-top'), 10), textPadding = 3, // this is to let the text breathe a bit innerX = parseInt(itemPosition.left, 10) + paddingLeft - textPadding, innerY = parseInt(itemPosition.top, 10) + paddingTop - textPadding; return { outerX: innerX - maskOptions.resizeHandleSize * 2 - maskOptions.dragMinWidth, outerY: 0, innerX: innerX, innerY: innerY }; } function containerWidthHasChanged($container) { var newDimensions = getDimensions($container); return newDimensions.outerWidth !== dimensions.outerWidth; } /** * 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 pluginShortcuts = (testRunnerOptions.shortcuts || {})[pluginName] || {}; const $container = testRunner.getAreaBroker().getContentArea().parent(); this.compoundMask = compoundMaskFactory(maskOptions).init().render($container).on('close', function () { closeMask(); }).hide(); /** * Checks if the plugin is currently available * @returns {Boolean} */ function isEnabled() { //to be activated with the special category x-tao-option-lineReader return mapHelper.hasItemCategory(testRunner.getTestMap(), testRunner.getTestContext().itemIdentifier, 'lineReader', true); } function toggleButton() { if (isEnabled()) { self.show(); } else { self.hide(); } } function toggleMask() { if (self.compoundMask.getState('hidden')) { if (containerWidthHasChanged($container)) { transformMask($container); } openMask(); } else { closeMask(); } } function openMask() { self.compoundMask.show(); self.trigger('start'); self.button.turnOn(); } function closeMask() { if (!self.compoundMask.getState('hidden')) { self.compoundMask.hide(); } self.trigger('end'); self.button.turnOff(); } function transformMask($maskContainer) { dimensions = getDimensions($maskContainer); position = getPosition($maskContainer); self.compoundMask.setTransforms(_.clone(dimensions), _.clone(position)); } // create button this.button = this.getAreaBroker().getToolbox().createEntry({ title: __('Line Reader'), icon: 'insert-horizontal-line', control: 'line-reader', text: __('Line Reader') }); // 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', toggleButton).on('renderitem', function () { transformMask($container); }).on('enabletools renderitem', function () { self.enable(); }).on('disabletools unloaditem', function () { self.disable(); closeMask(); }).on(`${actionPrefix}toggle`, function () { if (isEnabled()) { toggleMask(); } }); }, /** * Called during the runner's destroy phase */ destroy: function destroy() { this.compoundMask.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; });