░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
pplmvsvm
LOCATION:
/datadrive/moodledata/filedir/00/6f
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: 006f1d2d615a1da4b44f341be126e0cb268937db
H5P.FindTheWords = (function ($, UI) { const ELEMENT_MIN_SIZE = 32; // PX const ELEMENT_MAX_SIZE = 64; // PX const MARGIN = 8; //PX const VOCABULARY_INLINE_WIDTH = 200;// PX /** * FindTheWords. * @class H5P.FindTheWords * @extends H5P.EventDispatcher * @param {Object} options * @param {number} id * @param {Object} extras */ function FindTheWords(options, id, extras) { /** @alias H5P.FindTheWords# */ this.id = id; this.extras = extras; this.numFound = 0; this.isAttempted = false; this.isGameStarted = false; // Only take the unique words const vocabulary = options.wordList .split(',') .map(function (word) { return word.trim(); }) .filter(function (word, pos, self) { return self.indexOf(word) === pos; }); this.options = $.extend(true, { vocabulary: vocabulary, height: 5, width: 5, fillBlanks: true, maxAttempts: 5, l10n: { wordListHeader: 'Find the words' } }, options); H5P.EventDispatcher.call(this); this.gridParams = { height: this.options.height, width: this.options.width, orientations: filterOrientations(options.behaviour.orientations), fillBlanks: this.options.fillBlanks, maxAttempts: this.options.maxAttempts, preferOverlap: options.behaviour.preferOverlap, vocabulary: this.options.vocabulary, gridActive: true, fillPool: this.options.behaviour.fillPool }; this.grid = new FindTheWords.WordGrid(this.gridParams); this.vocabulary = new FindTheWords.Vocabulary( this.options.vocabulary, this.options.behaviour.showVocabulary, this.options.l10n.wordListHeader ); this.registerDOMElements(); // responsive functionality this.on('resize', function () { const currentSize = this.elementSize; const currentVocMod = this.isVocModeBlock; this.calculateElementSize(); this.setVocabularyMode(); if (this.elementSize !== currentSize) { this.$puzzleContainer.empty(); this.grid.appendTo(this.$puzzleContainer, this.elementSize ); this.grid.drawGrid(MARGIN); // If there are already marked elements on the grid mark them if (!this.grid.options.gridActive) { this.grid.enableGrid(); this.grid.mark(this.vocabulary.getFound()); this.grid.disableGrid(); this.grid.mark(this.vocabulary.getSolved()); } else { this.grid.mark(this.vocabulary.getFound()); } this.registerGridEvents(); } // vocabulary adjustments on resize if (this.options.behaviour.showVocabulary) { if (currentVocMod !== this.isVocModeBlock ) { this.vocabulary.setMode(this.isVocModeBlock); if (this.isVocModeBlock) { this.$puzzleContainer.removeClass('puzzle-inline').addClass('puzzle-block'); } else { //initial update has to be done manually this.$playArea.css({'width': parseInt(this.$gameContainer.width()) + VOCABULARY_INLINE_WIDTH}); this.$puzzleContainer.removeClass('puzzle-block').addClass('puzzle-inline'); } } } // Make the playarea just to fit its content if (! this.isVocModeBlock) { this.$playArea.css({'width': parseInt(this.$gameContainer.width()) + 2}); } else { this.$playArea.css({'width': parseInt(this.$puzzleContainer.width()) + 2}); } }); } FindTheWords.prototype = Object.create(H5P.EventDispatcher.prototype); FindTheWords.prototype.constructor = FindTheWords; // private and all prototype function goes there /** * filterOrientations - Mapping of directions from semantics to those used by algorithm. * @param {Object} directions * @return {Object[]} */ const filterOrientations = function (directions) { return Object.keys(directions).filter(function (key) { return directions[key]; }); }; /** * registerDOMElements. */ FindTheWords.prototype.registerDOMElements = function () { const that = this; this.$playArea = $('<div />', { class: 'h5p-play-area' }); this.$taskDescription = $('<div />', { class: 'h5p-task-description', html: this.options.taskDescription, tabIndex: 0, }); // timer part this.$timer = $('<div/>', { class: 'time-status', tabindex: 0, html: '<span role="term" ><em class="fa fa-clock-o" ></em>' + this.options.l10n.timeSpent + '</span >:' + '<span role="definition" class="h5p-time-spent" >0:00</span>' }); this.timer = new FindTheWords.Timer(this.$timer.find('.h5p-time-spent')); // counter part const counterText = that.options.l10n.found .replace('@found', '<span class="h5p-counter">0</span>') .replace('@totalWords', '<span><strong>' + this.vocabulary.words.length + '</strong></span>'); this.$counter = $('<div/>', { class: 'counter-status', tabindex: 0, html: '<div role="term"><span role="definition">' + counterText + '</span></div>' }); this.counter = new FindTheWords.Counter(this.$counter.find('.h5p-counter')); // feedback plus progressBar this.$feedback = $('<div/>', { class: 'feedback-element', tabindex: '0' }); this.$progressBar = UI.createScoreBar(this.vocabulary.words.length, 'scoreBarLabel'); // buttons section that.$submitButton = that.createButton('submit', 'check', that.options.l10n.check, that.gameSubmitted); if (this.options.behaviour.enableShowSolution) { this.$showSolutionButton = this.createButton('solution', 'eye', this.options.l10n.showSolution, that.showSolutions); } if (this.options.behaviour.enableRetry) { this.$retryButton = this.createButton('retry', 'undo', this.options.l10n.tryAgain, that.resetTask); } // container elements this.$gameContainer = $('<div class="game-container"/>'); this.$puzzleContainer = $('<div class="puzzle-container puzzle-inline" tabIndex="0" role="grid" />'); this.$vocabularyContainer = $('<div class="vocabulary-container" tabIndex="0" />'); this.$footerContainer = $('<div class="footer-container" />'); this.$statusContainer = $('<div />', { class: 'game-status', 'aria-label': 'game-status', role: 'group', tabindex: '0' }); this.$feedbackContainer = $('<div class="feedback-container"/>'); this.$buttonContainer = $('<div class="button-container" />'); }; /** * createButton - creating all buttons used in this game. * @param {string} name Buttonname. * @param {string} icon Fa icon name. * @param {string} param Button text parameter. * @param {function} callback Callback function. * @return {H5P.JoubelUI.Button} Joubel ui button object. */ FindTheWords.prototype.createButton = function (name, icon, param, callback) { const cfunction = callback.bind(this); return UI.createButton({ title: name, click: cfunction, html: '<span><i class="fa fa-' + icon + '" aria-hidden="true"></i></span>' + param }); }; /** * calculateElementSize - calculate the grid element size according to the container width. */ FindTheWords.prototype.calculateElementSize = function () { const containerWidth = this.$container.width(); const gridCol = this.grid.wordGrid[0].length; const gridMaxWidth = gridCol * ELEMENT_MAX_SIZE + 2 * MARGIN; const gridElementStdSize = (containerWidth - 2 * MARGIN) / gridCol; if (gridMaxWidth < containerWidth) { this.elementSize = ELEMENT_MAX_SIZE; } else if (gridElementStdSize > ELEMENT_MIN_SIZE) { this.elementSize = gridElementStdSize; } else { this.elementSize = ELEMENT_MAX_SIZE; } }; /** * setVocabularyMode - set vocabulary mode (either inline or block). */ FindTheWords.prototype.setVocabularyMode = function () { const gridCol = this.grid.wordGrid[0].length; this.isVocModeBlock = (this.$container.width() - (gridCol * this.elementSize + 2 * MARGIN) > VOCABULARY_INLINE_WIDTH) ? false : true; }; /** * gameSubmitted - callback function for check button. */ FindTheWords.prototype.gameSubmitted = function () { const totalScore = this.vocabulary.words.length; const scoreText = this.options.l10n.score .replace('@score', this.numFound) .replace('@total', totalScore); this.timer.stop(); this.$progressBar.setScore(this.numFound); this.$feedback.html(scoreText); this.$submitButton = this.$submitButton.detach(); this.grid.disableGrid(); if (totalScore !== this.numFound) { if (this.options.behaviour.enableShowSolution) { this.$showSolutionButton.appendTo(this.$buttonContainer); } } if (this.options.behaviour.enableRetry) { this.$retryButton.appendTo(this.$buttonContainer); } this.$feedbackContainer.addClass('feedback-show'); //show feedbackMessage this.$feedback.focus(); const xAPIEvent = this.createXAPIEventTemplate('answered'); this.addQuestionToXAPI(xAPIEvent); this.addResponseToXAPI(xAPIEvent); this.trigger(xAPIEvent); this.trigger('resize'); }; /** * showSolutions - call back function for show solution button. */ FindTheWords.prototype.showSolutions = function () { this.grid.disableGrid(); this.grid.mark(this.vocabulary.getNotFound()); this.vocabulary.solveWords(); this.$showSolutionButton.detach(); this.$vocabularyContainer.focus(); this.trigger('resize'); }; /** * resetTask - resetting the game. */ FindTheWords.prototype.resetTask = function () { this.numFound = 0; this.timer.reset(); this.counter.reset(); this.$progressBar.reset(); this.$puzzleContainer.empty(); this.vocabulary.reset(); if (this.$showSolutionButton) { this.$showSolutionButton.detach(); } this.$retryButton.detach(); this.$feedbackContainer.removeClass('feedback-show'); this.grid = new FindTheWords.WordGrid(this.gridParams); this.grid.appendTo(this.$puzzleContainer, this.elementSize); this.grid.drawGrid(MARGIN); this.grid.enableGrid(); this.registerGridEvents(); this.$submitButton.appendTo(this.$buttonContainer); this.$puzzleContainer.focus(); this.trigger('resize'); }; /** * Check whether user is able to play the game. * @return {boolean} */ FindTheWords.prototype.getAnswerGiven = function () { return this.isAttempted; }; /** * getScore - Return the score obtained. * @return {number} */ FindTheWords.prototype.getScore = function () { return this.numFound; }; /** * Turn the maximum possible score that can be obtained. * @return {number} */ FindTheWords.prototype.getMaxScore = function () { return this.vocabulary.words.length; }; /** * getXAPIData - Get xAPI data. * @see contract at {@link https://h5p.org/documentation/developers/contracts#guides-header-6} * @return {Object} xApi data statement */ FindTheWords.prototype.getXAPIData = function () { const xAPIEvent = this.createXAPIEventTemplate('answered'); this.addQuestionToXAPI(xAPIEvent); this.addResponseToXAPI(xAPIEvent); return { statement: xAPIEvent.data.statement }; }; /** * addQuestionToXAPI - Add the question to the definition part of an xAPIEvent. * @param {H5P.XAPIEvent} xAPIEvent */ FindTheWords.prototype.addQuestionToXAPI = function (xAPIEvent) { const definition = xAPIEvent.getVerifiedStatementValue( ['object', 'definition'] ); definition.description = { 'en-US': this.options.taskDescription }; definition.type = 'http://adlnet.gov/expapi/activities/cmi.interaction'; definition.interactionType = 'choice'; definition.correctResponsesPattern = []; definition.correctResponsesPattern[0] = this.vocabulary.words.join([',']); }; /** * Add the response part to an xAPI event. * @param {H5P.XAPIEvent} xAPIEvent */ FindTheWords.prototype.addResponseToXAPI = function (xAPIEvent) { const maxScore = this.getMaxScore(); const score = this.getScore(); const success = (score === maxScore); const response = this.vocabulary.getFound().join('[,]'); xAPIEvent.setScoredResult(score, maxScore, this, true, success); xAPIEvent.data.statement.result.response = response; }; /** * registerGridEvents. */ FindTheWords.prototype.registerGridEvents = function () { const that = this; this.grid.on('drawStart', function () { if (!that.isGameStarted) { that.timer.play(); that.triggerXAPI('interacted'); that.isGameStarted = true; } }); this.grid.on('drawEnd', function (event) { that.isAttempted = true; if (that.vocabulary.checkWord(event.data['markedWord'])) { that.numFound++; that.counter.increment(); that.grid.markWord(event.data['wordObject']); if (that.numFound === that.vocabulary.words.length) { that.gameSubmitted(); } } }); }; /** * attach - main attach function. * @param {H5P.jQuery} $container Description. */ FindTheWords.prototype.attach = function ($container) { this.$container = $container.addClass('h5p-find-the-words'); this.triggerXAPI('attempted'); if (this.grid) { this.calculateElementSize(); this.grid.appendTo(this.$puzzleContainer, this.elementSize ); this.$puzzleContainer.appendTo(this.$gameContainer); if (this.options.behaviour.showVocabulary) { this.setVocabularyMode(); this.vocabulary.appendTo(this.$vocabularyContainer, this.isVocModeBlock); this.$vocabularyContainer.appendTo(this.$gameContainer); } } this.$timer.appendTo(this.$statusContainer); this.$counter.appendTo(this.$statusContainer); this.$feedback.appendTo(this.$feedbackContainer); this.$progressBar.appendTo(this.$feedbackContainer); this.$submitButton.appendTo(this.$buttonContainer); //append status and feedback and button containers to footer this.$statusContainer.appendTo(this.$footerContainer); this.$feedbackContainer.appendTo(this.$footerContainer); this.$buttonContainer.appendTo(this.$footerContainer); //append description , cards and footer to main container. this.$taskDescription.appendTo(this.$playArea); this.$gameContainer.appendTo(this.$playArea); this.$footerContainer.appendTo(this.$playArea); this.$playArea.appendTo(this.$container); this.grid.drawGrid(MARGIN); this.registerGridEvents(); this.trigger('resize'); }; return FindTheWords; }) (H5P.jQuery, H5P.JoubelUI);
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 006f1d2d615a1da4b44f341be126e0cb268937db
?
14.5 KB
2023-08-03 13:30
EDIT