Skip to content

Instantly share code, notes, and snippets.

@JamesNZL
Last active June 22, 2022 21:51
Show Gist options
  • Save JamesNZL/e98f2adb9ca0bb44fbf89f9e0038dbb9 to your computer and use it in GitHub Desktop.
Save JamesNZL/e98f2adb9ca0bb44fbf89f9e0038dbb9 to your computer and use it in GitHub Desktop.
intervaltimer.com Exam Interval Timer Script
/**
* * Usage instructions in comments below
* https://gist.github.com/JamesNZL/e98f2adb9ca0bb44fbf89f9e0038dbb9?permalink_comment_id=4197883#gistcomment-4197883
*/
/**
* ! You shouldn't need to change this, unless there have been breaking changes
*/
const SITE = {
COLOURS: {
GREY: '0',
RED: '1',
ORANGE: '2',
YELLOW: '3',
GREEN: '4',
TEAL: '5',
BLUE: '6',
PURPLE: '7',
MAGENTA: '8',
DEEP_PURPLE: '9',
},
};
/**
* ! ----------------------------------------------------------------------------------------------
* ! You shouldn't need to change anything above this line, unless there have been breaking changes
* ! ----------------------------------------------------------------------------------------------
*/
/**
* * Update the `NAME`, `SECONDS`, and `SECTIONS` properties in this object
*/
const EXAM_CONFIGURATION = {
/**
* * Update this property if necessary
* Name of the exam
*/
NAME: 'ENGSCI 211 Exam',
/**
* * Update this property if necessary
* Seconds in the exam
*/
SECONDS: 3 * 60 * 60,
/**
* * Update this property if necessary
* Sections in the exam
*
* @type {{
* name: string,
* marks: number,
* colour: string,
* }[]}
*/
SECTIONS: [
{
name: 'ODE',
marks: 20,
colour: SITE.COLOURS.ORANGE,
},
{
name: 'MVC',
marks: 20,
colour: SITE.COLOURS.PURPLE,
},
{
name: 'DA',
marks: 15,
colour: SITE.COLOURS.BLUE,
},
{
name: 'LAFS',
marks: 25,
colour: SITE.COLOURS.GREEN,
},
],
};
/**
* ! ----------------------------------------------------------------------------------------------
* ! You shouldn't need to change anything below this line, unless there have been breaking changes
* ! ----------------------------------------------------------------------------------------------
*/
console.time('Elapsed');
const DOCUMENT = {
SELECTORS: {
TIMER_NAME: '[ng-model="timer.name"]',
ADD_INTERVALS_BUTTON: 'input.form-control[value="Add Interval"]',
INTERVAL: '[ng-repeat="interval in timer.intervals"]',
INTERVAL_NAME: '[ng-model="interval.name"]',
INTERVAL_DURATION: '[ng-model="interval.duration"]',
INTERVAL_COLOUR: '[ng-model="interval.color"]',
},
getIntervals() {
return [...document.querySelectorAll(DOCUMENT.SELECTORS.INTERVAL)];
},
/**
* `getIntervalInputs()` gets the `HTMLInputElement`s of the name, duration,
* and colour inputs of the specified `interval`
*
* @param interval {Element} The interval element
* @returns {{
* nameInput: HTMLInputElement,
* durationInput: HTMLInputElement,
* colourInput: HTMLInputElement,
* }} The input elements for the specified `interval`
*/
getIntervalInputs(interval) {
return {
nameInput: interval.querySelector(DOCUMENT.SELECTORS.INTERVAL_NAME),
durationInput: interval.querySelector(DOCUMENT.SELECTORS.INTERVAL_DURATION),
colourInput: interval.querySelector(DOCUMENT.SELECTORS.INTERVAL_COLOUR),
};
},
/**
* `dispatchChangeEvent()` dispatches the `'change'` event on the specified `element`
* @param element {Element} The element for which to dispatch the event
*/
dispatchChangeEvent(element) {
element.dispatchEvent(new Event('change', { bubbles: true }));
},
};
const EXAM = {
...EXAM_CONFIGURATION,
get TOTAL_MARKS() {
delete this.TOTAL_MARKS;
return this.TOTAL_MARKS = this.SECTIONS.reduce((total, { marks }) => total + marks, 0);
},
get SECONDS_PER_MARK() {
delete this.SECONDS_PER_MARK;
return this.SECONDS_PER_MARK = Math.round(this.SECONDS / this.TOTAL_MARKS);
},
/**
* `resolveMarkSection()` resolves a specified mark interval `index`
* to the exam section that interval belongs within
*
* @param index {number} The index of the mark interval to resolve
* @returns {{
* name: string,
* marks: number,
* colour: string,
* previousMarks: number,
* }} The section the mark interval belongs to
*/
resolveMarkSection(index) {
/** The count of marks contained within previous sections */
let previousMarks = 0;
for (const section of this.SECTIONS) {
const upperIndex = (section.marks - 1) + previousMarks;
if (upperIndex < index) {
previousMarks = upperIndex + 1;
continue;
}
return {
...section,
previousMarks,
};
}
},
};
console.timeLog('Elapsed', '\n\nUpdating timer name...');
// Update timer name
const timerNameInput = document.querySelector(DOCUMENT.SELECTORS.TIMER_NAME);
timerNameInput.value = EXAM.NAME;
DOCUMENT.dispatchChangeEvent(timerNameInput);
console.timeLog('Elapsed', '\n\nCreating intervals...');
// Add an interval for each mark in the exam
const addIntervalsBtn = document.querySelector(DOCUMENT.SELECTORS.ADD_INTERVALS_BUTTON);
for (let i = 1; i < EXAM.TOTAL_MARKS; i++) {
addIntervalsBtn.click();
}
// Wait until all intervals are added to the DOM before proceeding
let intervals = DOCUMENT.getIntervals();
while (intervals.length < EXAM.TOTAL_MARKS) {
intervals = DOCUMENT.getIntervals();
}
console.timeLog('Elapsed', '\n\nConfiguring intervals...');
intervals.forEach((interval, index) => {
const section = EXAM.resolveMarkSection(index);
const { nameInput, durationInput, colourInput } = DOCUMENT.getIntervalInputs(interval);
// Update the input field values for each interval
nameInput.value = `${section.name} ${(index - section.previousMarks) + 1}`;
durationInput.value = EXAM.SECONDS_PER_MARK;
colourInput.value = section.colour;
// Dispatch the change event so the Angular app registers the updates
console.timeLog('Elapsed', `\n\nConfiguring ${nameInput.value}...`);
[nameInput, durationInput, colourInput].forEach(DOCUMENT.dispatchChangeEvent);
});
console.timeEnd('Elapsed');
console.log('Waiting for the DOM to finish updating...');
'Done!';
@JamesNZL
Copy link
Author

JamesNZL commented Jun 12, 2022

Usage

  1. Create a new Custom Interval Timer on intervaltimer.com
  2. Paste the script into the developer console on the interval timer webpage
  3. Update EXAM_CONFIGURATION.NAME, EXAM_CONFIGURATION.SECONDS, and EXAM_CONFIGURATION.SECTIONS if necessary
  4. Hit Enter
  5. Click Create Timer
  6. Done!

Example

Example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment