lordwelch 6fab6022d0 Remove grab
Switch to using bootstrap-table
Add DownThemAll plugin
Remove Firefox plugin
2021-01-09 16:36:18 -08:00

222 lines
5.8 KiB
TypeScript

"use strict";
// License: MIT
/* eslint-disable no-unused-vars */
import {CellTypes} from "./constants";
import {Row} from "./row";
import {addClass} from "./util";
/* eslint-enable no-unused-vars */
export class Cell {
public type: CellTypes;
public table: any;
public row: Row;
public colid: number;
public icon: string | null;
public cell: HTMLTableCellElement;
public container: HTMLDivElement;
public iconElem: HTMLSpanElement;
constructor(type: CellTypes, row: any, colid: number) {
this.type = type;
this.table = row.table;
this.row = row;
this.colid = colid;
this.icon = null;
this.cell = document.createElement("td");
this.container = document.createElement("div");
addClass(this.container, "cell-container");
this.cell.appendChild(this.container);
this.cell.dataset.col = colid.toString();
this.row.addCellClasses(colid, this.cell);
this.icon = this.getCellIcon();
if (this.icon) {
this.iconElem = document.createElement("span");
this.iconElem.className = this.icon;
addClass(this.iconElem, "icon");
this.container.appendChild(this.iconElem);
}
}
static makeCell(type: CellTypes, row: any, colid: number) {
/* eslint-disable @typescript-eslint/no-use-before-define */
switch (type) {
case CellTypes.TYPE_TEXT:
return new TextCell(row, colid);
case CellTypes.TYPE_CHECK:
return new CheckCell(row, colid);
case CellTypes.TYPE_PROGRESS:
return new ProgressCell(row, colid);
default:
throw new Error(`Invalid cell type: ${type}`);
}
/* eslint-enable @typescript-eslint/no-use-before-define */
}
getCellIcon() {
return this.table.getCellIcon(this.row.rowid, this.colid);
}
getCellText() {
return this.table.getCellText(this.row.rowid, this.colid);
}
invalidate() {
if (this.iconElem) {
const icon = this.getCellIcon() || "";
if (icon !== this.icon) {
this.icon = icon;
this.iconElem.className = this.icon || "";
addClass(this.iconElem, "icon");
}
}
}
}
class TextCell extends Cell {
public value: string;
public textElem: HTMLSpanElement;
constructor(row: any, colid: number) {
super(CellTypes.TYPE_TEXT, row, colid);
this.textElem = document.createElement("span");
addClass(this.textElem, "cell-text");
this.container.appendChild(this.textElem);
this.value = this.textElem.textContent = this.getCellText();
if (!this.table.hover) {
this.textElem.setAttribute("title", this.value);
}
Object.seal(this);
}
invalidate() {
super.invalidate();
const text = this.getCellText();
if (text === this.value) {
return;
}
this.value = this.textElem.textContent = text;
if (!this.table.hover) {
this.textElem.setAttribute("title", text);
}
}
}
export class CheckCell extends Cell {
public value: boolean;
public text: string;
public lblElem: HTMLLabelElement;
public cbElem: HTMLInputElement;
public textElem: HTMLSpanElement;
constructor(row: any, colid: number) {
super(CellTypes.TYPE_CHECK, row, colid);
this.lblElem = document.createElement("label");
this.cbElem = document.createElement("input");
this.cbElem.setAttribute("type", "checkbox");
addClass(this.cbElem, "check-box");
this.lblElem.appendChild(this.cbElem);
this.textElem = document.createElement("span");
addClass(this.textElem, "check-text");
this.lblElem.appendChild(this.textElem);
addClass(this.lblElem, "check-label");
this.container.appendChild(this.lblElem);
this.text = this.textElem.textContent = this.getCellText();
if (!this.table.hover) {
this.cell.setAttribute("title", this.text);
}
this.cbElem.checked = this.value = this.getCellCheck();
addClass(this.cell, "check");
}
getCellCheck() {
return !!this.table.getCellCheck(this.row.rowid, this.colid);
}
invalidate() {
super.invalidate();
const text = this.getCellText();
if (text !== this.text) {
this.text = this.textElem.textContent = text;
if (!this.table.hover) {
this.cell.setAttribute("title", text);
}
}
const value = this.getCellCheck();
if (value !== this.value) {
this.cbElem.checked = this.value = value;
}
}
}
const PROGRESS_MAX = 100;
class ProgressCell extends Cell {
public value: number;
public contElem: HTMLDivElement;
public meterElem: HTMLSpanElement;
constructor(row: any, colid: number) {
super(CellTypes.TYPE_PROGRESS, row, colid);
this.value = this.getCellProgress();
this.contElem = document.createElement("div");
addClass(this.contElem, "progress-container");
this.meterElem = document.createElement("span");
if (!isFinite(this.value) || this.value < 0) {
addClass(this.meterElem, "progress-bar", "progress-undetermined");
}
else {
addClass(this.meterElem, "progress-bar");
const progress = Math.min(
PROGRESS_MAX, Math.max(0, this.value * PROGRESS_MAX));
this.meterElem.style.width = `${progress.toFixed(2)}%`;
}
this.contElem.appendChild(this.meterElem);
this.container.appendChild(this.contElem);
addClass(this.cell, "progress");
}
getCellProgress() {
return this.table.getCellProgress(this.row.rowid, this.colid);
}
invalidate() {
super.invalidate();
const value = this.getCellProgress();
if (value === this.value) {
return;
}
this.value = value;
if (!isFinite(value) || value < 0) {
this.meterElem.classList.add("virtualtable-progress-undetermined");
this.meterElem.style.width = "";
}
else {
this.meterElem.classList.remove("virtualtable-progress-undetermined");
const progress = Math.min(
PROGRESS_MAX, Math.max(0, value * PROGRESS_MAX));
this.meterElem.style.width = `${progress.toFixed(2)}%`;
}
}
}