Skip to content
Snippets Groups Projects
Commit a01229f8 authored by rhenck's avatar rhenck
Browse files

Fix Sanitizer logic issues and add plus-one method

parent e79ea606
No related branches found
No related tags found
No related merge requests found
import { Editor } from '@tiptap/core'; import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit'; import StarterKit from '@tiptap/starter-kit';
import { Unit } from '../interfaces/unit'; import { Page, Unit } from '../interfaces/unit';
import { DragNDropValueObject, DropListElement, UIElement } from '../interfaces/elements'; import {
DragNDropValueObject, DropListElement, PlayerElement, UIElement, UIElementValue
} from '../interfaces/elements';
import ToggleButtonExtension from '../tiptap-editor-extensions/toggle-button'; import ToggleButtonExtension from '../tiptap-editor-extensions/toggle-button';
import DropListExtension from '../tiptap-editor-extensions/drop-list'; import DropListExtension from '../tiptap-editor-extensions/drop-list';
import TextFieldExtension from '../tiptap-editor-extensions/text-field'; import TextFieldExtension from '../tiptap-editor-extensions/text-field';
import { IdService } from '../../editor/src/app/services/id.service'; import { IdService } from '../../editor/src/app/services/id.service';
export abstract class UnitDefinitionSanitizer { export abstract class UnitDefinitionSanitizer {
private static unitVersion: [number, number, number] = [0, 0, 0];
static campatibilityHandlers: { (s: UIElement[]): void; }[] = [ static campatibilityHandlers: { (s: UIElement[]): void; }[] = [
UnitDefinitionSanitizer.handlePositionProps, UnitDefinitionSanitizer.handlePositionProps,
UnitDefinitionSanitizer.handleFontProps, UnitDefinitionSanitizer.handleFontProps,
...@@ -15,13 +19,18 @@ export abstract class UnitDefinitionSanitizer { ...@@ -15,13 +19,18 @@ export abstract class UnitDefinitionSanitizer {
UnitDefinitionSanitizer.handlePlayerProps, UnitDefinitionSanitizer.handlePlayerProps,
UnitDefinitionSanitizer.handleTextElements, UnitDefinitionSanitizer.handleTextElements,
UnitDefinitionSanitizer.handleClozeElements, UnitDefinitionSanitizer.handleClozeElements,
UnitDefinitionSanitizer.handleDropListElements UnitDefinitionSanitizer.handleDropListElements,
UnitDefinitionSanitizer.handlePlusOne
]; ];
static sanitize(unitDefinition: Unit): Unit { static sanitize(unitDefinition: Partial<Unit> & { pages: Page[], veronaModuleVersion?: string }): Unit {
const elementList = UnitDefinitionSanitizer.getElementList(unitDefinition); UnitDefinitionSanitizer.unitVersion = unitDefinition.unitDefinitionType?.split('.')
.map(el => Number(el)) as [number, number, number] ||
unitDefinition.veronaModuleVersion?.split('.')
.map(el => Number(el)) as [number, number, number];
const elementList = UnitDefinitionSanitizer.getElementList(unitDefinition as Unit);
UnitDefinitionSanitizer.campatibilityHandlers.forEach(handler => handler(elementList)); UnitDefinitionSanitizer.campatibilityHandlers.forEach(handler => handler(elementList));
return unitDefinition; return unitDefinition as Unit;
} }
private static getElementList(unitDefinition: Unit): UIElement[] { private static getElementList(unitDefinition: Unit): UIElement[] {
...@@ -29,20 +38,25 @@ export abstract class UnitDefinitionSanitizer { ...@@ -29,20 +38,25 @@ export abstract class UnitDefinitionSanitizer {
} }
private static handlePositionProps(elementList: UIElement[]): void { private static handlePositionProps(elementList: UIElement[]): void {
const positionProps = ['fixedSize', 'dynamicPositioning', 'xPosition', 'yPosition', const positionProps = ['xPosition', 'yPosition',
'useMinHeight', 'gridColumnStart', 'gridColumnEnd', 'gridRowStart', 'gridRowEnd', 'marginLeft', 'useMinHeight', 'gridColumnStart', 'gridColumnEnd', 'gridRowStart', 'gridRowEnd', 'marginLeft',
'marginRight', 'marginTop', 'marginBottom', 'zIndex']; 'marginRight', 'marginTop', 'marginBottom', 'zIndex', 'fixedSize', 'dynamicPositioning'];
UnitDefinitionSanitizer.movePropertiesToSubObject(elementList, 'positionProps', positionProps); UnitDefinitionSanitizer.movePropertiesToSubObject(elementList, 'positionProps', positionProps);
} }
private static handleFontProps(elementList: UIElement[]): void { private static handleFontProps(elementList: UIElement[]): void {
const fontProps = ['fontColor', 'font', 'fontSize', 'lineHeight', 'bold', 'italic', 'underline']; const fontProps = ['fontColor', 'font', 'fontSize', 'lineHeight', 'bold', 'italic', 'underline'];
UnitDefinitionSanitizer.movePropertiesToSubObject(elementList, 'fontProps', fontProps); UnitDefinitionSanitizer.movePropertiesToSubObject(elementList,
'styles',
fontProps,
'fontProps');
} }
private static handleSurfaceProps(elementList: UIElement[]): void { private static handleSurfaceProps(elementList: UIElement[]): void {
const surfaceProps = ['backgroundColor']; UnitDefinitionSanitizer.movePropertiesToSubObject(elementList,
UnitDefinitionSanitizer.movePropertiesToSubObject(elementList, 'surfaceProps', surfaceProps); 'styles',
['backgroundColor'],
'surfaceProps');
} }
private static handlePlayerProps(elementList: UIElement[]): void { private static handlePlayerProps(elementList: UIElement[]): void {
...@@ -50,22 +64,41 @@ export abstract class UnitDefinitionSanitizer { ...@@ -50,22 +64,41 @@ export abstract class UnitDefinitionSanitizer {
'progressBar', 'interactiveProgressbar', 'volumeControl', 'defaultVolume', 'minVolume', 'progressBar', 'interactiveProgressbar', 'volumeControl', 'defaultVolume', 'minVolume',
'muteControl', 'interactiveMuteControl', 'hintLabel', 'hintLabelDelay', 'activeAfterID', 'muteControl', 'interactiveMuteControl', 'hintLabel', 'hintLabelDelay', 'activeAfterID',
'minRuns', 'maxRuns', 'showRestRuns', 'showRestTime', 'playbackTime']; 'minRuns', 'maxRuns', 'showRestRuns', 'showRestTime', 'playbackTime'];
UnitDefinitionSanitizer.movePropertiesToSubObject(elementList, 'playerProps', playerProps); const filteredElementList: PlayerElement[] =
elementList.filter(element => ['audio', 'video'].includes(element.type)) as PlayerElement[];
UnitDefinitionSanitizer.movePropertiesToSubObject(filteredElementList,'playerProps', playerProps);
filteredElementList.forEach((element: PlayerElement) => {
element.playerProps.defaultVolume = element.playerProps.defaultVolume || 0.8;
element.playerProps.minVolume = element.playerProps.minVolume || 0;
});
} }
/* Use the first prop as indicator for existence of all. */
private static movePropertiesToSubObject(elementList: UIElement[], private static movePropertiesToSubObject(elementList: UIElement[],
propertyName: string, targetPropertyGroup: string,
propertyList: string[]): void { propertyList: string[],
alternativeSourceGroup?: string): void {
elementList.forEach((element: UIElement) => { elementList.forEach((element: UIElement) => {
if (element[propertyList[0]] !== undefined) { let actualValues: Record<string, UIElementValue> = {};
if (!element[propertyName]) { if (element[targetPropertyGroup]) {
element[propertyName] = {}; actualValues = element[targetPropertyGroup] as Record<string, UIElementValue>;
Object.keys(propertyList).forEach(prop => { } else if (alternativeSourceGroup && alternativeSourceGroup in element) {
(element[propertyName] as Record<string, unknown>)[prop] = element[prop]; actualValues = element[alternativeSourceGroup] as Record<string, UIElementValue>;
delete element[prop]; delete element[alternativeSourceGroup];
}); } else {
} actualValues = Object.keys(element)
.filter(key => propertyList.includes(key))
.reduce((obj, key) => {
(obj as any)[key] = element[key];
return obj;
}, {});
}
// delete old values
if (alternativeSourceGroup) delete element[alternativeSourceGroup];
propertyList.forEach(prop => delete element[prop]);
if (Object.keys(actualValues).length > 0) {
(element[targetPropertyGroup] as Record<string, UIElementValue>) = actualValues;
} }
}); });
} }
...@@ -150,5 +183,17 @@ export abstract class UnitDefinitionSanitizer { ...@@ -150,5 +183,17 @@ export abstract class UnitDefinitionSanitizer {
}); });
} }
// TODO dropdown + 1 // version 1.1.0 is the only version where there was a plus one for values, which we rolled back afterwards
private static handlePlusOne(elementList: UIElement[]): void {
if (UnitDefinitionSanitizer.unitVersion === [1, 1, 0]) {
elementList.filter(el => (
['dropdown', 'radio', 'likert-row', 'radio-group-images', 'toggle-button'].includes(el.type)
))
.forEach(element => {
if (element.value && element.value > 0) {
(element.value as number) -= 1;
}
});
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment