PHPIndex

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`).

images
index.html
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/index.html'
View Content
<!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>
manifest.json
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/manifest.json'
View Content
{
  "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"
}
notice-board.css
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/notice-board.css'
View Content
/* (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;
}
notice-board.js
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/notice-board.js'
View Content
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);
worker.js
wget 'https://sme10.lists2.roe3.org/mdrone/noticeboard/worker.js'
View Content
// (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); })
  );
});