This page lists files in the current directory. You can view content, get download/execute commands for Wget, Curl, or PowerShell, or filter the list using wildcards (e.g., `*.sh`).
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/index.html'
<!DOCTYPE html>
<html>
<head>
<!-- META -->
<title>Notice Board</title>
<meta charset="utf-8">
<meta name="description" content="Experimental JS Signage">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.5">
<!-- ICONS -->
<link rel="icon" href="images/favicon.png" type="image/png">
<meta name="mobile-web-app-capable" content="yes">
<meta name="theme-color" content="white">
<link rel="apple-touch-icon" href="images/icon-512.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="JS POS">
<meta name="msapplication-TileImage" content="images/icon-512.png">
<meta name="msapplication-TileColor" content="#ffffff">
<!-- MANIFEST & WORKER -->
<link rel="manifest" href="manifest.json">
<script>
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("worker.js");
}
</script>
<!-- CSS & JS -->
<link rel="stylesheet" href="notice-board.css"/>
<!-- Uses JS localStorage methods to store and retrieve user data:
https://www.tiny.cloud/blog/javascript-localstorage/ -->
<script src="notice-board.js"></script>
</head>
<body>
<!-- (A) ADD/UPDATE NOTE -->
<form id="noteform">
<input type="text" id="notetxt" required disabled/>
<input type="submit" id="notego" value="Add" disabled/>
</form>
<!-- (B) NOTICE BOARD -->
<div id="board"></div>
<!-- (C) SIMPLE INSTRUCTIONS
Enter text and "add" to create a new note.
Drag-and-drop a note to rearrange.
Double click on a note to edit.
Hover over a note and click on "X" to delete it.
-->
</body>
</html>
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/manifest.json'
{
"short_name": "JS Board",
"name": "JS Notice Board",
"icons": [{
"src": "images/favicon.png",
"sizes": "64x64",
"type": "image/png"
}, {
"src": "images/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}],
"start_url": "notice-board.html",
"scope": "/",
"background_color": "white",
"theme_color": "white",
"display": "standalone"
}
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/notice-board.css'
/* (A) ENTIRE PAGE */
* {
font-family: arial, sans-serif;
box-sizing: border-box;
}
body {
padding: 20px;
margin: 0;
background: url(images/cork.jpg);
}
/* (B) ADD NEW NOTE */
#noteform {
display: flex;
margin-bottom: 20px;
}
#notetxt { flex-grow: 1; }
#notetxt, #notego { border: 0; }
#notetxt { padding: 10px; }
#notego {
padding: 10px 20px;
font-size: 18px;
color: #fff;
background: #0e5ce9;
}
/* (C) NOTICE BOARD WRAPPER */
#board {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
}
/* (D) NOTES */
div.note {
position: relative;
padding: 15px;
border: 2px solid #fdff8a;
background: #fdff8a;
box-shadow: 9px 11px 11px -2px rgba(0,0,0,0.4);
}
/* (E) DELETE BUTTON */
div.note .del {
position: absolute;
top: 5px; right: 5px;
color: #ff5a5a;
font-size: 20px;
font-weight: 700;
display: none;
}
div.note:hover .del { display: block; }
/* (F) EDIT NOTE */
div.note .txt input {
padding: 5px;
border: 0;
background: #fff;
}
div.note .txt input:focus { outline-width: 0; }
/* (G) LOCK DRAG & DELETE WHEN EDITING */
#board div.lock {
pointer-events: none;
color: #818181;
border: 1px solid #d3d3d3;
background: #d3d3d3;
}
#board div.lock .del { display: none; }
/* (H) PREVENT DRAG LEAVE EVENT ON NOTE CHILD ELEMENTS */
#board div.drag .txt, #board div.drag .del { pointer-events: none; }
#board div.drag .del { display: none; }
/* (I) DRAG HIGHLIGHT */
#board div.hint {
border: 2px dashed #ff8e68;
background: #feffc5;
}
#board div.active {
border: 2px dashed #ff0000;
background: #fcff00;
}
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/notice-board.js'
var board = {
// (A) PROPERTIES
notes : [], // current list of notes
hwrap : null, // html notice board wrapper
hform: null, // html add/update note form
hadd : null, // html add/update note text field
hgo : null, // html add/update note button
hsel : null, // current note being dragged or edited
// (B) INITIALIZE NOTICE BOARD
init : () => {
// (B1) GET HTML ELEMENTS
board.hwrap = document.getElementById("board");
board.hform = document.getElementById("noteform");
board.hadd = document.getElementById("notetxt");
board.hgo = document.getElementById("notego");
// (B2) LOAD & DRAW HTML NOTES
let data = localStorage.getItem("notes");
if (data !== null) { for (let n of JSON.parse(data)) {
board.draw(n);
}}
// (B3) ENABLE ADD NEW NOTE
board.hform.onsubmit = () => { return board.add(); };
board.hadd.disabled = false;
board.hgo.disabled = false;
},
// (C) HELPER - CREATE HTML NOTE
draw : (note, first) => {
// (C1) CREATE HTML NOTE
let div = document.createElement("div");
div.className = "note";
div.draggable = true;
div.innerHTML = `<div class="del" onclick="board.del(this.parentElement)">X</div> <div class="txt">${note}</div>`;
// (C2) ON DRAG START - ADD DROPPABLE HINTS
div.ondragstart = (e) => {
board.hsel = e.target;
for (let n of board.notes) {
n.classList.add("drag");
if (n != board.hsel) { n.classList.add("hint"); }
}
};
// (C3) ON DRAG ENTER - HIGHLIGHT DROPZONE
div.ondragenter = (e) => {
if (div != board.hsel) { div.classList.add("active"); }
};
// (C4) DRAG LEAVE - REMOVE HIGHLIGHT DROPZONE
div.ondragleave = (e) => {
div.classList.remove("active");
};
// (C5) DRAG END - REMOVE ALL HIGHLIGHTS
div.ondragend = (e) => { for (let n of board.notes) {
n.classList.remove("drag");
n.classList.remove("hint");
n.classList.remove("active");
}};
// (C6) DRAG OVER - PREVENT DEFAULT "DROP", SO WE CAN DO OUR OWN
div.ondragover = (e) => { e.preventDefault(); };
// (C7) ON DROP - REORDER NOTES & SAVE
div.ondrop = (e) => {
// (C7-1) PREVENT DEFAULT BROWSER DROP ACTION
e.preventDefault();
if (e.target != board.hsel) {
// (C7-2) GET CURRENT & DROPPED POSITIONS
let idrag = 0, // index of currently dragged
idrop = 0; // index of dropped location
for (let i=0; i<board.notes.length; i++) {
if (board.hsel == board.notes[i]) { idrag = i; }
if (e.target == board.notes[i]) { idrop = i; }
}
// (C7-3) REORDER HTML NOTES
if (idrag > idrop) {
board.hwrap.insertBefore(board.hsel, e.target);
} else {
board.hwrap.insertBefore(board.hsel, e.target.nextSibling);
}
// (C7-4) REORDER & SAVE NOTES ARRAY
board.save();
}
};
// (C8) DOUBLE CLICK TO EDIT NOTE
div.ondblclick = () => {
// (C8-1) SELECTED NOTE
board.hsel = div.querySelector(".txt");
// (C8-2) LOCK - NO DRAG NO DELETE WHILE EDITING
for (let n of board.notes) { n.classList.add("lock"); }
// (C8-3) UPDATE NOTE FORM
board.hadd.value = board.hsel.innerHTML;
board.hgo.value = "Update";
board.hform.onsubmit = () => { return board.update(); };
// board.hadd.focus();
board.hadd.select();
};
// (C9) DONE - PUSH INTO ARRAY & ATTACH TO CONTAINER
if (first) {
board.notes.unshift(div);
board.hwrap.insertBefore(div, board.hwrap.firstChild);
} else {
board.notes.push(div);
board.hwrap.appendChild(div);
}
},
// (D) ADD NEW NOTE
add : () => {
board.draw(board.hadd.value, true);
board.hadd.value = "";
board.save();
return false;
},
// (E) DELETE NOTE
del : (note) => { if (confirm("Delete note?")) {
note.remove();
board.save();
}},
// (F) UPDATE NOTE
update : () => {
// (F1) UPDATE NOTE
board.hsel.innerHTML = board.hadd.value;
board.hadd.value = "";
board.hgo.value = "Add";
// (F2) "RESTORE" ADD NOTE FORM
board.hform.onsubmit = () => { return board.add(); };
// (F3) SAVE
board.save();
// (F4) UNLOCK - ALLOW DRAG & DELETE
for (let n of board.notes) { n.classList.remove("lock"); }
return false;
},
// (G) UPDATE & SAVE NOTES
save : () => {
// (G1) REORDER NOTES ARRAY
let data = [];
board.notes = [];
for (let n of board.hwrap.getElementsByClassName("note")) {
board.notes.push(n);
data.push(n.querySelector(".txt").innerHTML);
}
// (G2) SAVE DATA
localStorage.setItem("notes", JSON.stringify(data));
}
};
window.addEventListener("DOMContentLoaded", board.init);
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/worker.js'
// (A) FILES TO CACHE
const cName = "js-notice",
cFiles = [
// (A1) STATIC FILES
"notice-board.html",
"notice-board.css",
"notice-board.js",
// (A2) IMAGES
"images/cork.jpg",
"images/favicon.png",
"images/icon-512.png"
];
// (B) CREATE/INSTALL CACHE
self.addEventListener("install", (evt) => {
evt.waitUntil(
caches.open(cName)
.then((cache) => { return cache.addAll(cFiles); })
.catch((err) => { console.error(err) })
);
});
// (C) LOAD FROM CACHE FIRST, FALLBACK TO NETWORK IF NOT FOUND
self.addEventListener("fetch", (evt) => {
evt.respondWith(
caches.match(evt.request)
.then((res) => { return res || fetch(evt.request); })
);
});