Skip to content

Commit

Permalink
Merge pull request #2 from otacke/rewrite
Browse files Browse the repository at this point in the history
Add minor cleanup
  • Loading branch information
otacke authored Jul 4, 2023
2 parents 483067f + 63679fe commit 3138343
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 108 deletions.
113 changes: 5 additions & 108 deletions src/scripts/h5p-personality-quiz.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Globals from '@services/globals';
import Screenreader from '@services/screenreader';
import Content from '@components/content';
import QuestionTypeContract from '@mixins/question-type-contract';
import Sanitization from '@mixins/sanitization';
import XAPI from '@mixins/xapi';
import Color from 'color';
import '@styles/h5p-personality-quiz.scss';
Expand All @@ -18,7 +19,7 @@ export default class PersonalityQuiz extends H5P.EventDispatcher {
constructor(params, contentId, extras = {}) {
super();

Util.addMixins(PersonalityQuiz, [QuestionTypeContract, XAPI]);
Util.addMixins(PersonalityQuiz, [QuestionTypeContract, Sanitization, XAPI]);

// Sanitize parameters
this.params = Util.extend({
Expand Down Expand Up @@ -110,6 +111,9 @@ export default class PersonalityQuiz extends H5P.EventDispatcher {

/**
* Run content.
* Can be uset to puppeteer content with the parameter
* `params.behaviour.delegateResults=true` that will hand over control to the
* parent content.
* @param {object} [params] Parameters.
* @param {boolean} [params.focus] If true. set focus.
*/
Expand Down Expand Up @@ -168,113 +172,6 @@ export default class PersonalityQuiz extends H5P.EventDispatcher {
return this.params.questions.length ?? 0;
}

/**
* Sanitize parameters.
*/
sanitizeParameters() {
// Personalities
this.params.personalities = this.params.personalitiesGroup.personalities
.reduce((results, personality) => {
if (!personality.name || personality.name.length === 0) {
return results;
}

// Can't use toLowerCase(), because this will be printed
personality.name = personality.name.trim();

if (results.some((result) => result.name === personality.name)) {
return results; // Duplicate
}

return [...results, personality];
}, []);
delete this.params.personalitiesGroup;

// answer-personalities-relation
this.params.questions = this.params.questionsGroup.questions
.map((question) => {
question.answers = this.filterAnswers(question.answers);
question.answers = question.answers.map((option) => {
option.text = option.text ?? '\u3164';
return option;
});

return question;
})
.filter((question) => question.answers.length !== 0);
delete this.params.questionsGroup;
}

/**
* Filter answers to only keep valid answers.
* @param {object[]} answers Answers.
* @returns {object[]} Filtered answers.
*/
filterAnswers(answers) {
return answers
.map((answer) => {
answer.personality =
this.sanitizeOptionPersonalities(answer.personality);
return answer;
})
.filter((answer) => answer.personality !== '');
}

/**
* Sanitize list of personalities of answer option.
* @param {string} personalities Personalities.
* @returns {string} Sanitized list of personalities of answer option.
*/
sanitizeOptionPersonalities(personalities) {
if (typeof personalities !== 'string') {
return '';
}

return personalities
.split(',')
.map((personality) => {
return this.sanitizePersonalityOption(personality);
})
.filter((personality) => personality !== null)
.join(',');
}

/**
* Sanitize personality option.
* @param {string} value Personality name and potentially score.
* @returns {string|null} Sanitized personality option or `null` on error.
*/
sanitizePersonalityOption(value) {
let name, score;
if (value.match(/=[-+]?\d+$/)) {
const segments = value.split('=');
score = segments.pop();
name = segments.join('=');
}
else {
score = 1;
name = value;
}

name = name.trim().toLowerCase();

if (!this.isPersonalityNameValid(name)) {
return null;
}

return `${name}=${score}`;
}

/**
* Determine whether personality name is valid.
* @param {string} value Personality name.
* @returns {boolean} True if valid, else false.
*/
isPersonalityNameValid(value) {
return this.params.personalities
.some((personality) => personality.name.toLowerCase() === value);
}

/**
* Setup color scheme.
*/
Expand Down
108 changes: 108 additions & 0 deletions src/scripts/mixins/sanitization.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
export default class Sanitization {
/**
* Sanitize parameters.
*/
sanitizeParameters() {
// Personalities
this.params.personalities = this.params.personalitiesGroup.personalities
.reduce((results, personality) => {
if (!personality.name || personality.name.length === 0) {
return results;
}

// Can't use toLowerCase(), because this will be printed
personality.name = personality.name.trim();

if (results.some((result) => result.name === personality.name)) {
return results; // Duplicate
}

return [...results, personality];
}, []);
delete this.params.personalitiesGroup;

// answer-personalities-relation
this.params.questions = this.params.questionsGroup.questions
.map((question) => {
question.answers = this.filterAnswers(question.answers);
question.answers = question.answers.map((option) => {
option.text = option.text ?? '\u3164';
return option;
});

return question;
})
.filter((question) => question.answers.length !== 0);
delete this.params.questionsGroup;
}

/**
* Filter answers to only keep valid answers.
* @param {object[]} answers Answers.
* @returns {object[]} Filtered answers.
*/
filterAnswers(answers) {
return answers
.map((answer) => {
answer.personality =
this.sanitizeOptionPersonalities(answer.personality);
return answer;
})
.filter((answer) => answer.personality !== '');
}

/**
* Sanitize list of personalities of answer option.
* @param {string} personalities Personalities.
* @returns {string} Sanitized list of personalities of answer option.
*/
sanitizeOptionPersonalities(personalities) {
if (typeof personalities !== 'string') {
return '';
}

return personalities
.split(',')
.map((personality) => {
return this.sanitizePersonalityOption(personality);
})
.filter((personality) => personality !== null)
.join(',');
}

/**
* Sanitize personality option.
* @param {string} value Personality name and potentially score.
* @returns {string|null} Sanitized personality option or `null` on error.
*/
sanitizePersonalityOption(value) {
let name, score;
if (value.match(/=[-+]?\d+$/)) {
const segments = value.split('=');
score = segments.pop();
name = segments.join('=');
}
else {
score = 1;
name = value;
}

name = name.trim().toLowerCase();

if (!this.isPersonalityNameValid(name)) {
return null;
}

return `${name}=${score}`;
}

/**
* Determine whether personality name is valid.
* @param {string} value Personality name.
* @returns {boolean} True if valid, else false.
*/
isPersonalityNameValid(value) {
return this.params.personalities
.some((personality) => personality.name.toLowerCase() === value);
}
}

0 comments on commit 3138343

Please sign in to comment.