UNPKG

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

Version:
135 lines (126 loc) 6.83 kB
define(['jquery', 'util/typeCaster', 'taoTests/runner/plugin', 'taoQtiTest/runner/helpers/verticalWriting'], function ($, typeCaster, pluginFactory, verticalWriting) { 'use strict'; $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; typeCaster = typeCaster && Object.prototype.hasOwnProperty.call(typeCaster, 'default') ? typeCaster['default'] : typeCaster; pluginFactory = pluginFactory && Object.prototype.hasOwnProperty.call(pluginFactory, 'default') ? pluginFactory['default'] : pluginFactory; /** * 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) 2020 (original work) Open Assessment Technologies SA; */ /** * Creates the loading bar plugin. * Displays a loading bar when a blocking task is running */ var itemScrolling = pluginFactory({ name: 'itemScrolling', /** * Initializes the plugin (called during runner's init) */ init: function init() { const testRunner = this.getTestRunner(); const $contentArea = testRunner.getAreaBroker().getContentArea(); testRunner.on('renderitem', function () { const isVerticalWritingMode = verticalWriting.getIsItemWritingModeVerticalRl(); if (isVerticalWritingMode) { // qti-itemBody is item scroll container in vertical writing mode (but not in horizontal); // window resize is not enough, because if review-panel is used, it can be closed/opened, and that affects qti-itemBody width. const $itemBody = $('.qti-itemBody'); this.itemBodyResizeObserver = new ResizeObserver(() => requestAnimationFrame(adaptItemBlockSize)); this.itemBodyResizeObserver.observe($itemBody.get(0)); } else { adaptItemBlockSize(); $(window).on('resize.adaptItemHeight', adaptItemBlockSize); } }).on('unloaditem', function () { $(window).off('resize.adaptItemHeight'); if (this.itemBodyResizeObserver) { this.itemBodyResizeObserver.disconnect(); } }); function adaptItemBlockSize() { const isVerticalWritingMode = verticalWriting.getIsItemWritingModeVerticalRl(); const gridRowBlockEndMargin = 12; const qtiItemPadding = (isVerticalWritingMode ? 15 : 30) * 2; const $itemContainer = $contentArea.find('[data-scrolling="true"]'); const contentBlockSize = getItemRunnerBlockSize(isVerticalWritingMode) - getExtraGridRowBlockSize(isVerticalWritingMode) - getSpaceAroundQtiContent(isVerticalWritingMode) - gridRowBlockEndMargin - qtiItemPadding - 2; $itemContainer.each(function () { const $item = $(this); const isScrollable = typeCaster.strToBool($item.attr('data-scrolling') || 'false'); const selectedBlockSize = parseFloat($item.attr('data-scrolling-height')) || 100; const containerParent = $item.parent().closest('[data-scrolling="true"]'); const containerBlockSize = isVerticalWritingMode ? containerParent.width() : containerParent.height(); const overflowCssProp = isVerticalWritingMode ? 'overflow-x' : 'overflow-y'; if ($item.length && isScrollable) { $item.data('scrollable', true); $item.css({ [overflowCssProp]: 'scroll' }); if (containerParent.length > 0) { $item.css('max-block-size', `${containerBlockSize * (selectedBlockSize * 0.01)}px`); } else { $item.css('max-block-size', `${contentBlockSize * (selectedBlockSize * 0.01)}px`); } } }); } // depending on the context (item preview, new/old test runner...) available height is computed differently function getItemRunnerBlockSize(isVerticalWritingMode) { var $testRunnerSections = $('.test-runner-sections'); // exists only in the new test runner if ($testRunnerSections.length) { const rect = $testRunnerSections.get(0).getBoundingClientRect(); return isVerticalWritingMode ? rect.width : rect.height; } // otherwise, we assume that we are in an iframe with all space available (= item preview, old test runner) return isVerticalWritingMode ? $(window).width() : $(window).height(); } // extra grid row are there in case of a vertical layout (item on top/bottom of the question) function getExtraGridRowBlockSize(isVerticalWritingMode) { var $gridRows = $('.qti-itemBody > .grid-row'), extraBlockSize = 0; $gridRows.each(function () { var $gridRow = $(this), $itemContainer = $gridRow.find('[data-scrolling="true"]'); if (!$itemContainer.length) { extraBlockSize += isVerticalWritingMode ? $gridRow.outerWidth(true) : $gridRow.outerHeight(true); } }); return extraBlockSize; } // most of the time this will be rubrick's block height in the new test runner; // if vertical-writing, can also be review-panel on the left function getSpaceAroundQtiContent(isVerticalWritingMode) { var $testRunnerSections = $('.test-runner-sections'), $qtiContent = $('#qti-content'); if ($testRunnerSections.length && $qtiContent.length) { const qtiContentRect = $qtiContent.get(0).getBoundingClientRect(); const testRunnerSectionsRect = $testRunnerSections.get(0).getBoundingClientRect(); if (isVerticalWritingMode) { return testRunnerSectionsRect.width - qtiContentRect.width; } return qtiContentRect.top - testRunnerSectionsRect.top; } return 0; } }, destroy: function destroy() { $(window).off('resize.adaptItemHeight'); if (this.itemBodyResizeObserver) { this.itemBodyResizeObserver.disconnect(); } } }); return itemScrolling; });