* builtin slide switching added to the team forms * parts of team form made conditional * fixed keyboard slide switching when not in slideshow * slideshow slide management totally reworked into linked list * Date.getDay() -> Date.getDate() as it was originally meant to be
117 lines
2.5 KiB
TypeScript
Executable File
117 lines
2.5 KiB
TypeScript
Executable File
|
|
export class TwoWayLinkedList<T> {
|
|
private count = 0;
|
|
private entryNode: Node<T> = null;
|
|
private lastNode: Node<T> = null;
|
|
private nodePtr: Node<T> = null;
|
|
|
|
public push(newNode: T): TwoWayLinkedList<T> {
|
|
if (null === this.lastNode) {
|
|
this.entryNode = new Node<T>(newNode);
|
|
this.lastNode = this.entryNode;
|
|
this.nodePtr = this.entryNode;
|
|
this.entryNode
|
|
.setPrev(this.entryNode)
|
|
.setNext(this.entryNode);
|
|
} else {
|
|
const prevPtr = this.lastNode;
|
|
const nodeToAdd = new Node(newNode);
|
|
nodeToAdd.setNext(this.entryNode).setPrev(prevPtr);
|
|
prevPtr.setNext(nodeToAdd);
|
|
this.lastNode = nodeToAdd;
|
|
}
|
|
this.count++;
|
|
return this;
|
|
}
|
|
|
|
public pop(): T {
|
|
if (null === this.lastNode) {
|
|
throw new Error('No items in list');
|
|
}
|
|
|
|
let returnData: T;
|
|
if (this.entryNode === this.lastNode) {
|
|
returnData = this.lastNode.getData();
|
|
this.lastNode.setPrev(null).setNext(null);
|
|
this.entryNode = null;
|
|
this.lastNode = null;
|
|
this.nodePtr = null;
|
|
} else {
|
|
const newLast = this.lastNode.getPrev();
|
|
if (this.nodePtr === this.lastNode) {
|
|
this.nodePtr = newLast;
|
|
}
|
|
newLast.setNext(this.entryNode);
|
|
returnData = this.lastNode.getData();
|
|
this.lastNode.setPrev(null).setNext(null);
|
|
this.lastNode = newLast;
|
|
}
|
|
this.count--;
|
|
return returnData;
|
|
}
|
|
|
|
public clear() {
|
|
while (this.count > 0) {
|
|
this.pop();
|
|
}
|
|
}
|
|
|
|
public prev(): T {
|
|
this.nodePtr = this.nodePtr.getPrev();
|
|
return this.nodePtr.getData();
|
|
}
|
|
|
|
public next(): T {
|
|
this.nodePtr = this.nodePtr.getNext();
|
|
return this.nodePtr.getData();
|
|
}
|
|
|
|
public isFirst(): boolean {
|
|
return this.nodePtr === this.lastNode;
|
|
}
|
|
|
|
public isLast(): boolean {
|
|
return this.nodePtr === this.lastNode;
|
|
}
|
|
|
|
public get first(): T {
|
|
return this.entryNode.getData();
|
|
}
|
|
|
|
public get last(): T {
|
|
return this.lastNode.getData();
|
|
}
|
|
}
|
|
|
|
export class Node<T> {
|
|
private prev: Node<T> = null;
|
|
private next: Node<T> = null;
|
|
private readonly data: T = null;
|
|
|
|
constructor(data: T) {
|
|
this.data = data;
|
|
}
|
|
|
|
public getPrev(): Node<T> {
|
|
return this.prev;
|
|
}
|
|
|
|
public setPrev(node: Node<T>): Node<T> {
|
|
this.prev = node;
|
|
return this;
|
|
}
|
|
|
|
public getNext(): Node<T> {
|
|
return this.next;
|
|
}
|
|
|
|
public setNext(node: Node<T>): Node<T> {
|
|
this.next = node;
|
|
return this;
|
|
}
|
|
|
|
public getData(): T {
|
|
return this.data;
|
|
}
|
|
}
|