Skip to content

Commit

Permalink
Removing Reactive
Browse files Browse the repository at this point in the history
  • Loading branch information
timothyylim committed Nov 6, 2024
1 parent e084f23 commit 1607a76
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 148 deletions.
34 changes: 0 additions & 34 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"scripts": {
"test": "npx ava",
"build": "webpack --mode=development && cp node_modules/ractive/ractive.min.js ./dist",
"build": "webpack --mode=development",
"watch": "webpack --watch --mode=development"
},
"repository": {
Expand All @@ -26,7 +26,6 @@
"@babel/preset-env": "^7.18.10",
"@types/diff": "^5.0.3",
"@types/jquery": "^3.5.16",
"@types/ractive": "^0.7.27",
"autoprefixer": "^10.4.14",
"ava": "^4.3.3",
"babel-loader": "^8.2.5",
Expand All @@ -41,7 +40,5 @@
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"ractive": "^1.4.2"
}
}
"dependencies": {}
}
187 changes: 89 additions & 98 deletions src/scripts/controllers/cloze-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import { ClozeType, SelectAlternatives } from "../models/enums";
import { Highlight } from "../models/highlight";
import { Blank } from "../models/blank";
import { Correctness } from '../models/answer';

import highlightTemplate from '../views/highlight.ractive.html';
import blankTemplate from '../views/blank.ractive.html';

import * as RactiveEventsKeys from '../../lib/ractive-events-keys';
import { highlightTemplate, blankTemplate } from '../views/templates';

interface ScoreChanged {
(score: number, maxScore: number): void;
Expand All @@ -32,7 +28,7 @@ interface Typed {
}

interface TextChanged {
() : void;
(): void;
}

export class ClozeController {
Expand All @@ -47,10 +43,6 @@ export class ClozeController {
public onTyped: Typed;
public onTextChanged: TextChanged;

// Storage of the ractive objects that link models and views
private highlightRactives: { [id: string]: Ractive.Ractive } = {};
private blankRactives: { [id: string]: Ractive.Ractive } = {};

public get maxScore(): number {
return this.cloze.blanks.length;
}
Expand Down Expand Up @@ -106,18 +98,15 @@ export class ClozeController {
}

/**
* Sets up all blanks, the cloze itself and the ractive bindings.
* Sets up all blanks, the cloze itself, and binds event listeners using jQuery.
* @param {HTMLElement} root
*/
initialize(root: HTMLElement, jquery: JQuery) {
this.jquery = jquery;
this.isSelectCloze = this.settings.clozeType === ClozeType.Select ? true : false;
this.isSelectCloze = this.settings.clozeType === ClozeType.Select;

var blanks = this.repository.getBlanks();

// Stop ractive debug mode
Ractive.DEBUG = false;

if (this.isSelectCloze && this.settings.selectAlternatives === SelectAlternatives.All) {
for (var blank of blanks) {
let otherBlanks = blanks.filter(v => v !== blank);
Expand All @@ -131,8 +120,8 @@ export class ClozeController {
this.cloze = ClozeLoader.createCloze(this.repository.getClozeText(), blanks);

var containers = this.createAndAddContainers(root);
containers.cloze.innerHTML = this.cloze.html;
this.createRactiveBindings();
this.jquery.find(containers.cloze).html(this.cloze.html);
this.createBindings();
}

checkAll = () => {
Expand All @@ -145,37 +134,46 @@ export class ClozeController {
this.checkAndNotifyCompleteness();
}

textTyped = (event, blank: Blank) => {
blank.onTyped();
if (this.onTyped)
this.onTyped();
this.refreshCloze();
}
textTyped = (blank: Blank) => {
// Persist the current value from the input field to the Blank model
const newValue = this.jquery.find(`#${blank.id}`).val() as string;
blank.enteredText = newValue; // Store the new value in the Blank model

blank.onTyped(); // Trigger any typed event
if (this.onTyped) this.onTyped();

focus = (event, blank: Blank) => {
// Refresh only this specific blank field
this.refreshCloze(blank);
};

focus = (blank: Blank) => {
blank.onFocused();
this.refreshCloze();
}
this.refreshCloze(blank);
};

displayFeedback = (event, blank: Blank) => {
displayFeedback = (blank: Blank) => {
blank.onDisplayFeedback();
this.refreshCloze();
}
this.refreshCloze(blank);
};

showHint = (event, blank: Blank) => {
showHint = (blank: Blank) => {
this.cloze.hideAllHighlights();
blank.showHint();
this.refreshCloze();
}
this.refreshCloze(blank);
};

requestCloseTooltip = (event, blank: Blank) => {
requestCloseTooltip = (blank: Blank) => {
blank.removeTooltip();
this.refreshCloze();
this.jquery.find("#" + blank.id).focus();
}
this.refreshCloze(blank);
this.jquery.find(`#${blank.id}`).focus();
};

checkBlank = (blank: Blank, cause: string) => {
// Persist the current value before checking
const newValue = this.jquery.find(`#${blank.id}`).val() as string;
blank.enteredText = newValue; // Store the new value in the Blank model

checkBlank = (event, blank: Blank, cause: string) => {
if ((cause === 'blur' || cause === 'change')) {
if (cause === 'blur' || cause === 'change') {
blank.lostFocus();
}

Expand All @@ -184,31 +182,29 @@ export class ClozeController {
}

if (this.settings.autoCheck) {
if (!blank.enteredText || blank.enteredText === "")
return;
if (!blank.enteredText || blank.enteredText === "") return;

this.cloze.hideAllHighlights();
blank.evaluateAttempt(false);
this.checkAndNotifyCompleteness();
this.refreshCloze();
this.refreshCloze(blank); // Refresh only this blank field
this.onAutoChecked();
}
if ((cause === 'enter')
&& ((this.settings.autoCheck && blank.isCorrect && !this.isSolved)
|| !this.settings.autoCheck)) {
// move to next blank
&& ((this.settings.autoCheck && blank.isCorrect && !this.cloze.isSolved) || !this.settings.autoCheck)
) {
var index = this.cloze.blanks.indexOf(blank);
var nextId;
while (index < this.cloze.blanks.length - 1 && !nextId) {
index++;
if (!this.cloze.blanks[index].isCorrect)
nextId = this.cloze.blanks[index].id;
}

if (nextId)
if (nextId) {
this.jquery.find("#" + nextId).focus();
}
}
}
};

reset = () => {
this.cloze.reset();
Expand All @@ -235,64 +231,60 @@ export class ClozeController {
};
}

private createHighlightBinding(highlight: Highlight) {
this.highlightRactives[highlight.id] = new Ractive({
el: '#container_' + highlight.id,
template: highlightTemplate,
data: {
object: highlight
}
private createBindings() {
this.cloze.highlights.forEach((highlight) => {
this.bindHighlight(highlight);
});
}

private createBlankBinding(blank: Blank) {
var ractive = new Ractive({
el: '#container_' + blank.id,
template: blankTemplate,
data: {
isSelectCloze: this.isSelectCloze,
blank: blank
},
events: {
enter: RactiveEventsKeys.enter,
escape: RactiveEventsKeys.escape,
anykey: RactiveEventsKeys.anykey
}
this.cloze.blanks.forEach((blank) => {
this.bindBlank(blank);
});
ractive.on("checkBlank", this.checkBlank);
ractive.on("showHint", this.showHint);
ractive.on("textTyped", this.textTyped);
ractive.on("textChanged", this.onTextChanged);
ractive.on("closeMessage", this.requestCloseTooltip);
ractive.on("focus", this.focus);
ractive.on("displayFeedback", this.displayFeedback);

this.blankRactives[blank.id] = ractive;
}

private createRactiveBindings() {
for (var highlight of this.cloze.highlights) {
this.createHighlightBinding(highlight);
}
private bindHighlight(highlight: Highlight) {
const highlightContainer = this.jquery.find(`#container_${highlight.id}`);
highlightContainer.html(highlightTemplate(highlight.id, highlight.isHighlighted, highlight.text));
}

for (var blank of this.cloze.blanks) {
this.createBlankBinding(blank);
private bindBlank(blank: Blank) {
const blankContainer = this.jquery.find(`#container_${blank.id}`);
blankContainer.html(blankTemplate(blank, this.isSelectCloze));

const blankInput = blankContainer.find(`#${blank.id}`);
if (this.isSelectCloze) {
blankInput.on('change', () => this.checkBlank(blank, 'change'));
} else {
blankInput.on('keyup', () => this.textTyped(blank));
blankInput.on('blur', () => this.checkBlank(blank, 'blur'));
blankInput.on('focus', () => this.focus(blank));
}
}

/**
* Updates all views of highlights and blanks. Can be called when a model
* was changed
*/
private refreshCloze() {
for (var highlight of this.cloze.highlights) {
var highlightRactive = this.highlightRactives[highlight.id];
highlightRactive.set("object", highlight);
}
private createSelectOptions(blank: Blank) {
let optionsHTML = '';
blank.choices.forEach((choice) => {
optionsHTML += `<option value="${choice}">${choice}</option>`;
});
return `<select id="${blank.id}">${optionsHTML}</select>`;
}

for (var blank of this.cloze.blanks) {
var blankRactive = this.blankRactives[blank.id];
blankRactive.set("blank", blank);
// Modify refreshCloze to update only specific blanks if needed
private refreshCloze(blank?: Blank) {
if (blank) {
// Update only the specific blank input field
const blankContainer = this.jquery.find(`#container_${blank.id}`);
blankContainer.html(blankTemplate(blank, this.isSelectCloze));
} else {
// Update all blanks and highlights (if needed)
this.cloze.highlights.forEach((highlight) => {
const highlightContainer = this.jquery.find(`#container_${highlight.id}`);
highlightContainer.html(highlightTemplate(highlight.id, highlight.isHighlighted, highlight.text));
});

this.cloze.blanks.forEach((blank) => {
const blankContainer = this.jquery.find(`#container_${blank.id}`);
blankContainer.html(blankTemplate(blank, this.isSelectCloze));
});
}
}

Expand Down Expand Up @@ -325,10 +317,9 @@ export class ClozeController {
if (!this.cloze || this.cloze.blanks.length === 0)
return [[]];
let result = [];
for (var blank of this.cloze.blanks) {
this.cloze.blanks.forEach((blank) => {
result.push(blank.getCorrectAnswers());
}

});
return result;
}
}
Loading

0 comments on commit 1607a76

Please sign in to comment.