function BonarooTimer(defaultTime, persist) {
this.rootElement = document.createElement("div");
this.rootElement.innerHTML = BonarooTimer.TEMPLATE;
this.inputElement = this.rootElement.querySelector("[data-input]");
this.inputElement.addEventListener("change", (function (event) {
event.preventDefault();
this.setTime(this.inputElement.value);
}).bind(this))
this.startStopButton = this.rootElement.querySelector("[data-toggle]");
this.startStopButton.addEventListener("click", this.toggle.bind(this));
this.resetButton = this.rootElement.querySelector("[data-reset]");
this.resetButton.addEventListener("click", this.reset.bind(this));
this.resetButton.textContent = BonarooTimer.RESET_LABEL;
this.defaultTime = typeof defaultTime === "undefined" ? 60 : BonarooTimer.parseTime(defaultTime);
this.time = this.defaultTime;
this.running = false;
this.timeoutId = null;
this.persist = persist !== false;
if (this.persist) {
this.restore();
}
this.updateGuiLater();
}
BonarooTimer.prototype.setTime = function setTime(val) {
this.time = BonarooTimer.parseTime(val);
if (this.running) {
this.start();
}
}
BonarooTimer.prototype.updateGui = function updateGui() {
if (this.updateTimeoutId) {
clearTimeout(this.updateTimeoutId);
this.updateTimeoutId = null;
}
this.startStopButton.textContent = this.running ? BonarooTimer.STOP_LABEL : BonarooTimer.START_LABEL;
if (this.inputElement !== document.activeElement) {
this.inputElement.value = BonarooTimer.formatTime(this.time);
}
}
BonarooTimer.prototype.write = function write() {
if (document.currentScript) {
document.currentScript.insertAdjacentElement("beforebegin", this.rootElement);
} else {
throw new Error("BonarooTimer.write can only be called inside SCRIPT element");
}
};
BonarooTimer.prototype.toggle = function toggle() {
if (this.running) {
this.stop();
} else {
this.start();
}
}
BonarooTimer.prototype.stop = function stop() {
if (this.timeoutId) {
clearInterval(this.timeoutId);
this.timeoutId = null;
}
this.running = false;
this.updateGuiLater();
if (this.persist) {
window.localStorage.removeItem("timer-time-end");
}
}
BonarooTimer.prototype.start = function start() {
this.stop();
this.running = true;
this.timeoutId = setInterval(this.next.bind(this), 1000);
this.updateGuiLater();
if (this.persist) {
window.localStorage.setItem("timer-time-end", `${Math.round(new Date().getTime() / 1000 + this.time)}`);
}
}
BonarooTimer.prototype.restore = function restore() {
if (this.persist) {
var endTimeStr = window.localStorage.getItem("timer-time-end");
if (endTimeStr) {
var endTime = parseInt(endTimeStr, 10);
var currentTime = Math.round(new Date().getTime() / 1000);
var timeRemaining = endTime - currentTime;
if (timeRemaining > 0) {
this.time = timeRemaining;
this.start();
} else {
this.time = 0;
}
}
this.updateGuiLater();
}
}
BonarooTimer.prototype.reset = function reset() {
this.stop();
this.time = this.defaultTime;
this.updateGuiLater();
}
BonarooTimer.prototype.updateGuiLater = function updateGuiLater() {
if (!this.updateTimeoutId) {
this.updateTimeoutId = setTimeout(this.updateGui.bind(this), 0);
}
}
BonarooTimer.prototype.next = function next() {
this.time--;
this.updateGui();
if (this.time <= 0) {
this.stop();
}
}
BonarooTimer.TEMPLATE = "<input data-input><button data-toggle type=button /><button data-reset type=button />";
BonarooTimer.STOP_LABEL = "Stop";
BonarooTimer.START_LABEL = "Start";
BonarooTimer.RESET_LABEL = "Reset";
BonarooTimer.parseTime = function parseTime(val) {
if (typeof val === "number") {
return val;
}
if (!val) {
return 0;
}
var match = val.match(/(?:(?:(\d+)?:)?(\d+)?:)?(\d+)/);
if (!match) {
return 0;
}
var hours = parseInt(match[1] || "0", 10);
var minutes = parseInt(match[2] || "0", 10);
var seconds = parseInt(match[3] || "0", 10);
return hours * 3600 + minutes * 60 + seconds;
}
BonarooTimer.formatTime = function formatTime(time) {
if (time < 0) {
time = 0;
}
const hours = Math.floor(time / 3600);
const minutes = Math.floor((time / 60) % 60);
const seconds = Math.floor(time % 60);
if (hours > 0) {
return BonarooTimer.lpad(hours) + ":" + BonarooTimer.lpad(minutes) + ":" + BonarooTimer.lpad(seconds)
} else {
return BonarooTimer.lpad(minutes) + ":" + BonarooTimer.lpad(seconds);
}
}
BonarooTimer.lpad = function lpad(num) {
num = Math.round(num);
return num < 10 ? `0${num}` : `${num}`;
}