added other units

This commit is contained in:
Benjamin Adovasio
2025-11-16 22:54:34 -05:00
parent 5bd461229a
commit ca92b603be
46 changed files with 2779 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
(function (window) {
class Dismissible {
/**
*
* @param {HTMLElement} root Root Element
*/
constructor(root, config = {
icons: {
dismiss: ['lni', 'lni-16', 'lni-close'],
info: ['lni', 'lni-32', 'lni-popup'],
success: ['lni', 'lni-32', 'lni-checkmark-circle'],
error: ['lni', 'lni-32', 'lni-warning']
}
}) {
this._container = root;
this._config = config;
this._container.classList.add('dismissible-container');
}
show(level, message, icon) {
this.dismiss();
const dismissible = this._createDismissible(level, message, icon);
this._container.appendChild(dismissible);
}
dismiss() {
while (this._container.firstChild) {
this._container.firstChild.remove();
}
}
error(message) {
this.show('error', message, this._config.icons.error);
}
info(message) {
this.show('info', message, this._config.icons.info);
}
success(message) {
this.show('success', message, this._config.icons.success);
}
_createDismissible(level, message, icon) {
const dismissible = document.createElement('div');
dismissible.classList.add('dismissible');
dismissible.classList.add(level);
dismissible.appendChild(this._createIcon(icon));
dismissible.appendChild(this._createMessage(message));
dismissible.appendChild(this._createDismissButton());
return dismissible;
}
_createDismissButton() {
const {
icons
} = this._config;
const button = document.createElement('button');
button.classList.add('dismiss');
button.addEventListener('click', () => this.dismiss());
const buttonIcon = document.createElement('i');
buttonIcon.classList.add(...icons.dismiss);
button.appendChild(buttonIcon);
return button;
}
_createMessage(message) {
const element = document.createElement('div');
element.classList.add('dismissible-message');
element.innerText = message;
return element;
}
_createIcon(icon, text) {
const element = document.createElement('i');
element.classList.add(...icon, 'dismissible-icon');
return element;
}
}
window.Dismissible = Dismissible;
})(window);

View File

@@ -0,0 +1,301 @@
/**
* <md-block> custom element
* @author Lea Verou
*/
let marked = window.marked;
let DOMPurify = window.DOMPurify;
let Prism = window.Prism;
export const URLs = {
marked: "https://cdn.jsdelivr.net/npm/marked/src/marked.min.js",
DOMPurify: "https://cdn.jsdelivr.net/npm/dompurify@2.3.3/dist/purify.es.min.js"
}
// Fix indentation
function deIndent(text) {
let indent = text.match(/^[\r\n]*([\t ]+)/);
if (indent) {
indent = indent[1];
text = text.replace(RegExp("^" + indent, "gm"), "");
}
return text;
}
export class MarkdownElement extends HTMLElement {
constructor() {
super();
this.renderer = Object.assign({}, this.constructor.renderer);
for (let property in this.renderer) {
this.renderer[property] = this.renderer[property].bind(this);
}
}
get rendered() {
return this.getAttribute("rendered");
}
get mdContent () {
return this._mdContent;
}
set mdContent (html) {
this._mdContent = html;
this._contentFromHTML = false;
this.render();
}
connectedCallback() {
Object.defineProperty(this, "untrusted", {
value: this.hasAttribute("untrusted"),
enumerable: true,
configurable: false,
writable: false
});
if (this._mdContent === undefined) {
this._contentFromHTML = true;
this._mdContent = deIndent(this.innerHTML);
}
this.render();
}
async render () {
if (!this.isConnected || this._mdContent === undefined) {
return;
}
if (!marked) {
marked = import(URLs.marked).then(m => m.marked);
}
marked = await marked;
marked.setOptions({
gfm: true,
smartypants: true,
langPrefix: "language-",
});
marked.use({renderer: this.renderer});
let html = this._parse();
if (this.untrusted) {
let mdContent = this._mdContent;
html = await MarkdownElement.sanitize(html);
if (this._mdContent !== mdContent) {
// While we were running this async call, the content changed
// We dont want to overwrite with old data. Abort mission!
return;
}
}
this.innerHTML = html;
if (!Prism && URLs.Prism && this.querySelector("code")) {
Prism = import(URLs.Prism);
if (URLs.PrismCSS) {
let link = document.createElement("link");
link.rel = "stylesheet";
link.href = URLs.PrismCSS;
document.head.appendChild(link);
}
}
if (Prism) {
await Prism; // in case it's still loading
Prism.highlightAllUnder(this);
}
if (this.src) {
this.setAttribute("rendered", this._contentFromHTML? "fallback" : "remote");
}
else {
this.setAttribute("rendered", this._contentFromHTML? "content" : "property");
}
// Fire event
let event = new CustomEvent("md-render", {bubbles: true, composed: true});
this.dispatchEvent(event);
}
static async sanitize(html) {
if (!DOMPurify) {
DOMPurify = import(URLs.DOMPurify).then(m => m.default);
}
DOMPurify = await DOMPurify; // in case it's still loading
return DOMPurify.sanitize(html);
}
};
export class MarkdownSpan extends MarkdownElement {
constructor() {
super();
}
_parse () {
return marked.parseInline(this._mdContent);
}
static renderer = {
codespan (code) {
if (this._contentFromHTML) {
// Inline HTML code needs to be escaped to not be parsed as HTML by the browser
// This results in marked double-escaping it, so we need to unescape it
code = code.replace(/&amp;(?=[lg]t;)/g, "&");
}
else {
// Remote code may include characters that need to be escaped to be visible in HTML
code = code.replace(/</g, "&lt;");
}
return `<code>${code}</code>`;
}
}
}
export class MarkdownBlock extends MarkdownElement {
constructor() {
super();
}
get src() {
return this._src;
}
set src(value) {
this.setAttribute("src", value);
}
get hmin() {
return this._hmin || 1;
}
set hmin(value) {
this.setAttribute("hmin", value);
}
get hlinks() {
return this._hlinks ?? null;
}
set hlinks(value) {
this.setAttribute("hlinks", value);
}
_parse () {
return marked.parse(this._mdContent);
}
static renderer = Object.assign({
heading (text, level, _raw, slugger) {
level = Math.min(6, level + (this.hmin - 1));
const id = slugger.slug(text);
const hlinks = this.hlinks;
let content;
if (hlinks === null) {
// No heading links
content = text;
}
else {
content = `<a href="#${id}" class="anchor">`;
if (hlinks === "") {
// Heading content is the link
content += text + "</a>";
}
else {
// Headings are prepended with a linked symbol
content += hlinks + "</a>" + text;
}
}
return `
<h${level} id="${id}">
${content}
</h${level}>`;
},
code (code, language, escaped) {
if (this._contentFromHTML) {
// Inline HTML code needs to be escaped to not be parsed as HTML by the browser
// This results in marked double-escaping it, so we need to unescape it
code = code.replace(/&amp;(?=[lg]t;)/g, "&");
}
else {
// Remote code may include characters that need to be escaped to be visible in HTML
code = code.replace(/</g, "&lt;");
}
return `<pre class="language-${language}"><code>${code}</code></pre>`;
}
}, MarkdownSpan.renderer);
static get observedAttributes() {
return ["src", "hmin", "hlinks"];
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue === newValue) {
return;
}
switch (name) {
case "src":
let url;
try {
url = new URL(newValue, location);
}
catch (e) {
return;
}
let prevSrc = this.src;
this._src = url;
if (this.src !== prevSrc) {
fetch(this.src)
.then(response => {
if (!response.ok) {
throw new Error(`Failed to fetch ${this.src}: ${response.status} ${response.statusText}`);
}
return response.text();
})
.then(text => {
this.mdContent = text;
})
.catch(e => {});
}
break;
case "hmin":
if (newValue > 0) {
this._hmin = +newValue;
this.render();
}
break;
case "hlinks":
this._hlinks = newValue;
this.render();
}
}
}
customElements.define("md-block", MarkdownBlock);
customElements.define("md-span", MarkdownSpan);

View File

@@ -0,0 +1,75 @@
toggleCounter = 1;
toggleHelp();
if((localStorage.length % 4 === 0) && (localStorage.length > 1)) {
if (confirm('Previous todo-list data was found. Do you want to restore this data?')) {
console.log('Restored from localStorage');
new Dismissible(document.querySelector('#dismissible-container')).success('Previous todo-list data was restored.');
} else {
console.log('Local Storage cleared');
localStorage.clear();
}
}
else if(localStorage.getItem("ID: 1 - Item ID:") == "1"){
new Dismissible(document.querySelector('#dismissible-container')).error('Previous todo-list data was found but appears to be corrupted. Previous data will not be restored.');
localStorage.clear();
}
else if(localStorage.length > 0) {
if (confirm('Local Storage data, unreleated to your todo-list, was found in your cache. This needs to be cleared for the website to function properly.')) {
console.log('Local Storage cleared');
localStorage
} else {
console.log('Local Storage NOT cleared!');
console.log('Website may not function properly!');
new Dismissible(document.querySelector('#dismissible-container')).info('Local storage not cleared, website may not function properly!');
}
}
function enterKeyPressed(event){
var key = event.key || event.keyCode;
if (key === 'Enter' || key === 13) {
console.log("enter");
document.getElementById(content.id).focus();
new Dismissible(document.querySelector('#dismissible-container')).success('Name saved!');
}
else
{
console.log("not enter");
}
};
function enterKeyPressedTask(event){
var key = event.key || event.keyCode;
if (key === 'Enter' || key === 13) {
console.log("enter");
document.getElementById('category1').focus();
}
else
{
console.log("not enter");
}
};
function toggleHelp(){
toggleCounter ++;
if (toggleCounter % 2 == 0) {
for (var i = 0; i < document.getElementsByClassName("help").length; i ++) {
document.getElementsByClassName("help")[i].style.display = 'none';
}
} else {
for (var i = 0; i < document.getElementsByClassName("help").length; i ++) {
document.getElementsByClassName("help")[i].style.display = 'initial';
}
}
}
function todoViewer(choice){
if (choice == 'popup'){
newwindow=window.open(href='todoOnly.html','name','height=700,width=700');
if (window.focus) {newwindow.focus()}
return false;
}
else if(choice == 'tab'){
window.open(href='todoOnly.html');
}
}

View File

@@ -0,0 +1,69 @@
submissionCounter = 0;
if (localStorage.length % 4 === 0) {
if(localStorage.length >0 ){
submissionCounter = localStorage.length / 4 ;
console.log(submissionCounter);
for(i = 1; i < submissionCounter + 1; i++ ){
var tbodyRef = document.getElementById('todoTable').getElementsByTagName('tbody')[0];
var newRow = tbodyRef.insertRow();
var newCell = newRow.insertCell();
var newCell2 = newRow.insertCell();
var newCell3 = newRow.insertCell();
var newCell4 = newRow.insertCell();
var newText = document.createTextNode("Item ID: " + localStorage.getItem("ID: " + i + " - Item ID:"));
newCell.appendChild(newText);
var newText2 = document.createTextNode("Name: " + localStorage.getItem("ID: " + i + " - Name:"));
newCell2.appendChild(newText2);
var newText3 = document.createTextNode("Task: " + localStorage.getItem("ID: " + i + " - Task:"));
newCell3.appendChild(newText3);
var newText4 = document.createTextNode("Priorty: " + localStorage.getItem("ID: " + i + " - Priority:"));
newCell4.appendChild(newText4);
}
}
}
function submission(){
submissionCounter ++;
localStorage.setItem("ID: " + submissionCounter + " - Item ID:", submissionCounter);
localStorage.setItem("ID: " + submissionCounter + " - Name:", document.getElementById('name').value);
localStorage.setItem("ID: " + submissionCounter + " - Task:", document.getElementById('content').value);
if(document.getElementById('category1').checked){
localStorage.setItem("ID: " + submissionCounter + " - Priority:", "High");
}
else {
localStorage.setItem("ID: " + submissionCounter + " - Priority:", "Low");
}
var tbodyRef = document.getElementById('todoTable').getElementsByTagName('tbody')[0];
var newRow = tbodyRef.insertRow();
var newCell = newRow.insertCell();
var newCell2 = newRow.insertCell();
var newCell3 = newRow.insertCell();
var newCell4 = newRow.insertCell();
var newCell5 = newRow.insertCell();
var newText = document.createTextNode("Item ID: " + localStorage.getItem("ID: " + submissionCounter + " - Item ID:"));
newCell.appendChild(newText);
var newText2 = document.createTextNode("Name: " + localStorage.getItem("ID: " + submissionCounter + " - Name:"));
newCell2.appendChild(newText2);
var newText3 = document.createTextNode("Task: " + localStorage.getItem("ID: " + submissionCounter + " - Task:"));
newCell3.appendChild(newText3);
var newText4 = document.createTextNode("Priorty: " + localStorage.getItem("ID: " + submissionCounter + " - Priority:"));
newCell4.appendChild(newText4);
var newText5 = document.createElement("button");
newText5.innerHTML = "test";
newText5.onclick = function(){
newRow.remove();
localStorage.removeItem("ID: " + submissionCounter + " - Item ID:");
localStorage.removeItem("ID: " + submissionCounter + " - Name:");
localStorage.removeItem("ID: " + submissionCounter + " - Task:");
};
newCell5.appendChild(newText5);
document.getElementById('content').value="";
document.getElementById('content').placeholder="e.g. Clean Room";
for(var i=0;i<document.getElementsByName("category").length;i++){
document.getElementsByName("category")[i].checked = false;
}
}
function deleteElement(){
console.log("test");
}

View File

@@ -0,0 +1,28 @@
submissionCounter = 0;
if (localStorage.length % 4 === 0) {
if(localStorage.length >0 ){
submissionCounter = localStorage.length / 4 ;
console.log(submissionCounter);
for(i = 1; i < submissionCounter + 1; i++ ){
var tbodyRef = document.getElementById('todoTableReadOnly').getElementsByTagName('tbody')[0];
var newRow = tbodyRef.insertRow();
var newCell = newRow.insertCell();
var newCell2 = newRow.insertCell();
var newCell3 = newRow.insertCell();
var newCell4 = newRow.insertCell();
var newText = document.createTextNode("Item ID: " + localStorage.getItem("ID: " + i + " - Item ID:"));
newCell.appendChild(newText);
var newText2 = document.createTextNode("Name: " + localStorage.getItem("ID: " + i + " - Name:"));
newCell2.appendChild(newText2);
var newText3 = document.createTextNode("Task: " + localStorage.getItem("ID: " + i + " - Task:"));
newCell3.appendChild(newText3);
var newText4 = document.createTextNode("Priorty: " + localStorage.getItem("ID: " + i + " - Priority:"));
newCell4.appendChild(newText4);
}
}
}
setInterval(function(){
location.reload();
}, 5000);