commit 5f0724e283c0d59230b2b42985eeef6d3db36b5a Author: Reimar Date: Tue Aug 5 17:14:23 2025 +0200 Initial commit diff --git a/.env b/.env new file mode 100644 index 0000000..9e68512 --- /dev/null +++ b/.env @@ -0,0 +1 @@ + # Scrubbed by Glitch 2021-02-28T13:49:10+0000 diff --git a/README.md b/README.md new file mode 100644 index 0000000..96036fb --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +Welcome to Glitch +================= + +Click `Show` in the header to see your app live. Updates to your code will instantly deploy and update live. + +**Glitch** is the friendly community where you'll build the app of your dreams. Glitch lets you instantly create, remix, edit, and host an app, bot or site, and you can invite collaborators or helpers to simultaneously edit code with you. + +Find out more [about Glitch](https://glitch.com/about). + + +Your Project +------------ + +### ← README.md + +That's this file, where you can tell people what your cool website does and how you built it. + +### ← index.html + +Where you'll write the content of your website. + +### ← style.css + +CSS files add styling rules to your content. + +### ← script.js + +If you're feeling fancy you can add interactivity to your site with JavaScript. + +### ← assets + +Drag in `assets`, like images or music, to add them to your project + +Made by [Glitch](https://glitch.com/) +------------------- + +\ ゜o゜)ノ diff --git a/assets/JetBrainsMono-Regular.ttf b/assets/JetBrainsMono-Regular.ttf new file mode 100644 index 0000000..4781cc7 Binary files /dev/null and b/assets/JetBrainsMono-Regular.ttf differ diff --git a/assets/JetBrainsMono-Regular.woff2 b/assets/JetBrainsMono-Regular.woff2 new file mode 100644 index 0000000..80c62dd Binary files /dev/null and b/assets/JetBrainsMono-Regular.woff2 differ diff --git a/assets/fa-solid-900.eot b/assets/fa-solid-900.eot new file mode 100644 index 0000000..ccebb26 Binary files /dev/null and b/assets/fa-solid-900.eot differ diff --git a/assets/fa-solid-900.svg b/assets/fa-solid-900.svg new file mode 100644 index 0000000..efbef6e --- /dev/null +++ b/assets/fa-solid-900.svg @@ -0,0 +1,1015 @@ + + + + +Created by FontForge 20200314 at Wed Jan 13 11:57:55 2021 + By Robert Madole +Copyright (c) Font Awesome + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/fa-solid-900.ttf b/assets/fa-solid-900.ttf new file mode 100644 index 0000000..bc64092 Binary files /dev/null and b/assets/fa-solid-900.ttf differ diff --git a/assets/fa-solid-900.woff b/assets/fa-solid-900.woff new file mode 100644 index 0000000..7a14a11 Binary files /dev/null and b/assets/fa-solid-900.woff differ diff --git a/assets/fa-solid-900.woff2 b/assets/fa-solid-900.woff2 new file mode 100644 index 0000000..9a4633d Binary files /dev/null and b/assets/fa-solid-900.woff2 differ diff --git a/assets/fa-solid.min.css b/assets/fa-solid.min.css new file mode 100644 index 0000000..4555555 --- /dev/null +++ b/assets/fa-solid.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(/assets/fa-solid-900.eot);src:url(/assets/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(/assets/fa-solid-900.woff2) format("woff2"),url(/assets/fa-solid-900.woff) format("woff"),url(/assets/fa-solid-900.ttf) format("truetype"),url(/assets/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} \ No newline at end of file diff --git a/assets/fontawesome-solid.min.css b/assets/fontawesome-solid.min.css new file mode 100644 index 0000000..d61a2d3 --- /dev/null +++ b/assets/fontawesome-solid.min.css @@ -0,0 +1,5 @@ +/*! + * Font Awesome Free 5.15.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;font-display:block;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.fas{font-family:"Font Awesome 5 Free";font-weight:900} \ No newline at end of file diff --git a/bookmark/index.html b/bookmark/index.html new file mode 100644 index 0000000..8f16efc --- /dev/null +++ b/bookmark/index.html @@ -0,0 +1,16 @@ + + + + + + + + + + + + Press CTRL + D / CMD + D or click the Star Icon to add this to your bookmarks. +

+ Back   Open Popup Now + + \ No newline at end of file diff --git a/bookmark/script.js b/bookmark/script.js new file mode 100644 index 0000000..571111b --- /dev/null +++ b/bookmark/script.js @@ -0,0 +1,28 @@ +var link = location.protocol + "//" + location.host + "/link" + location.search; +var popupLink = location.protocol + "//" + location.host + "/popup" + location.search; + +history.replaceState(null, "", link); +document.title = parseQueryParams().name + " - Popup Timer"; + +document.getElementById("open-popup").onclick = function() { + + window.open( + popupLink, + "PopupTimer" + Date.now(), + "width=250,height=100,menubar=no,toolbar=no,location=no,status=no,resizable=no,scrollbars=no" + ); + +} + +function parseQueryParams() { + if (location.search === "" || location.search.indexOf("?") !== 0) return {}; + var result = {}; + location.search.substr(1).split("&").forEach(function(str) { + var key = str.split("=")[0]; + var value; + if (str.split("=").length > 1) value = str.split("=")[1]; + else value = null; + result[key] = value; + }); + return result +} diff --git a/bookmark/style.css b/bookmark/style.css new file mode 100644 index 0000000..1599030 --- /dev/null +++ b/bookmark/style.css @@ -0,0 +1,13 @@ +body { + margin: 1em; + font-family: helvetica, arial, sans-serif; + font-size: 18px; + text-align: center; +} +a, a:visited { + color: #43A047; + outline: none; +} +a:hover { + text-decoration: none; +} \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..ce1cdfa Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..400bf2c --- /dev/null +++ b/index.html @@ -0,0 +1,70 @@ + + + + + + + Popup Timer + + + + + + + + +

Popup Timer

+ +
+ +

Create new

+ + + + + + + + +

+ +
+ +
+    h +    m +    s +
+
+ +
+
+
+ +
+
+ + +
+
+ +

+ +
+ Create Bookmark +
+ +
+ +

+ + +
+ + + + diff --git a/link/index.html b/link/index.html new file mode 100644 index 0000000..e42d7a0 --- /dev/null +++ b/link/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/link/script.js b/link/script.js new file mode 100644 index 0000000..4b8d9e7 --- /dev/null +++ b/link/script.js @@ -0,0 +1,20 @@ +// Open timer popup +var result = window.open( + location.protocol + "//" + location.host + "/popup" + location.search, + "PopupTimer" + Date.now(), + "width=250,height=100,menubar=no,toolbar=no,location=no,status=no,resizable=no,scrollbars=no" +); + +// Show warning if it didn't work +if (!result) { + + document.getElementById("popup-warning").style.display = "block"; + document.getElementById("refresh").onclick = function() { + location.reload(); + } + +} else { + window.onfocus = function() { + history.back(); + } +} \ No newline at end of file diff --git a/link/style.css b/link/style.css new file mode 100644 index 0000000..9323127 --- /dev/null +++ b/link/style.css @@ -0,0 +1,25 @@ +::selection, ::-moz-selection { + color: white; + background-color: #F57F17; +} +#popup-warning { + font-family: helvetica, arial, sans-serif; + margin: auto; + margin-top: 50px; + width: 100%; + max-width: 400px; + display: none; + background-color: #FFEE58; + color: #F57F17; + border-left: 2px solid #F57F17; + font-size: 14px; + text-align: left; + padding: 10px; +} +#refresh { + text-decoration: underline; +} +#refresh:hover { + text-decoration: none; + cursor: pointer; +} \ No newline at end of file diff --git a/popup/index.html b/popup/index.html new file mode 100644 index 0000000..0ea7dff --- /dev/null +++ b/popup/index.html @@ -0,0 +1,31 @@ + + + + + + + Popup Timer + + + + + + + + + +
+ + 00h 00m 00s + +
+ +   + +
+ +
+
+ + + \ No newline at end of file diff --git a/popup/script.js b/popup/script.js new file mode 100644 index 0000000..061b543 --- /dev/null +++ b/popup/script.js @@ -0,0 +1,303 @@ +var params = parseQueryParams(); + +// Set window title +if (params.name) document.title = params.name + " - Popup Timer"; + +var hours, minutes, seconds; +var secondsElem = document.getElementById("seconds"); +var minutesElem = document.getElementById("minutes"); +var hoursElem = document.getElementById("hours"); +var playBtn = document.getElementById("play"); +var progressBar = document.getElementById("progress-fg"); +var timeout; +var timesUpStr = "[ TIME'S UP! ] "; +var lastPaused = -1; + +// Init audio +var oscillator, audioContext; +if (params.beep === "true") { + try { + audioContext = new (window.AudioContext || window.webkitAudioContext); + } catch(e) {} +} + +// Autostart +if (params.autostart === "true") { + + switch (params.type) { + + case "timer": + initTimer(); + startTimer(1000); + break; + + case "stopwatch": + initStopwatch(); + startStopwatch(1000); + break; + + default: + location.href = "/"; + } + +} + +// Reset timer/stopwatch +document.getElementById("restart").onclick = function() { + + if (timeout) clearTimeout(timeout); + + var paused = playBtn.classList.contains("fa-play"); + + switch (params.type) { + case "timer": + + // Reset progress bar + // TODO + progressBar.animationName = ""; + progressBar.animationName = "progress"; + + initTimer(); + if (!paused) startTimer(1000); + + break; + case "stopwatch": + + // Reset displayed time + secondsElem.innerText = "00s"; + secondsElem.classList.remove("highlighted"); + minutesElem.innerText = "00m"; + minutesElem.classList.remove("highlighted"); + hoursElem.innerText = "00h"; + hoursElem.classList.remove("highlighted"); + + initStopwatch(); + if (!paused) startStopwatch(1000); + + break; + } +} + +// Pause / Resume +playBtn.onclick = function() { + + if (!timeout) return; + + // Pause + if (playBtn.classList.contains("fa-pause")) { + + lastPaused = Date.now(); + if (params.type === "timer") progressBar.style.animationPlayState = "paused"; + clearTimeout(timeout); + + // Change icon + playBtn.classList.remove("fa-pause"); + playBtn.classList.add("fa-play"); + + // Resume + } else { + + var startOffset = lastPaused % 1000; + + switch (params.type) { + case "timer": + if (hours === 0 && minutes == 0 && seconds === 0) return; + progressBar.style.animationPlayState = "running"; + startTimer(startOffset); + break; + case "stopwatch": + startStopwatch(startOffset); + break; + } + + // Change icon + playBtn.classList.remove("fa-play"); + playBtn.classList.add("fa-pause"); + + } + +} + +function initTimer() { + + hours = parseInt(params.h); + minutes = parseInt(params.m); + seconds = parseInt(params.s); + + if (hours === 0 && minutes === 0 && seconds === 0) return; + + // Only highlight relevant parts + if (hours > 0) { + hoursElem.classList.add("highlighted"); + minutesElem.classList.add("highlighted"); + secondsElem.classList.add("highlighted"); + } else if (minutes > 0) { + minutesElem.classList.add("highlighted"); + secondsElem.classList.add("highlighted"); + } else { + secondsElem.classList.add("highlighted"); + } + + // Print initial time + hoursElem.innerText = pad(hours) + "h"; + minutesElem.innerText = pad(minutes) + "m"; + secondsElem.innerText = pad(seconds) + "s"; + + // Animate progress bar + var totalSeconds = (hours * 60 * 60) + (minutes * 60) + seconds; + progressBar.style.animationDuration = totalSeconds + "s"; + progressBar.style.animationName = "progress"; + +} + +function startTimer(startOffset) { + + playBtn.classList.remove("fa-play"); + playBtn.classList.add("fa-pause"); + + // Wait the starting offset + timeout = setTimeout(updateTimer, startOffset); + + document.getElementById("progress-fg").style.animationPlayState = "running"; + +} + +function updateTimer() { + + seconds--; + if (seconds === 0 && minutes === 0 && hours === 0) secondsElem.classList.remove("highlighted"); + if (seconds <= -1) { + seconds = 59; + + minutes--; + if (minutes === 0 && hours === 0) minutesElem.classList.remove("highlighted"); + if (minutes <= -1) { + minutes = 59; + + hours--; + if (hours === 0) hoursElem.classList.remove("highlighted"); + + hoursElem.innerText = pad(hours) + "h"; + } + minutesElem.innerText = pad(minutes) + "m"; + } + secondsElem.innerText = pad(seconds) + "s"; + + if (hours === 0 && minutes === 0 && seconds == 0) timeUp(); + else timeout = setTimeout(updateTimer, 1000); + +} + +// Makes the numbers blink red etc. +function timeUp() { + + var timeUpInterval = setInterval(function() { + + // Blink red + [].slice.call(document.querySelectorAll("main > span")).forEach(function(elem) { + elem.classList.toggle("red"); + }); + //document.querySelector + + // Blink title + if (document.title.indexOf(timesUpStr) === -1) document.title = timesUpStr + document.title; + else document.title = document.title.substr(timesUpStr.length); + + // Play beep + if (params.beep === "true" && audioContext) { + try { + oscillator = audioContext.createOscillator(); + oscillator.type = "sine"; + oscillator.frequency.value = 1000; + oscillator.connect(audioContext.destination); + oscillator.start(); + oscillator.stop(audioContext.currentTime + 0.25); + } catch(e) {} + } + + }, 500); + + // Stop when user clicks + document.onclick = function() { + + if (oscillator) oscillator.stop(); + + // Reset color + [].slice.call(document.querySelectorAll("main > span")).forEach(function(elem) { + elem.classList.remove("red"); + }); + + // Remove "TIME UP" from title + if (document.title.indexOf(timesUpStr) !== -1) document.title = document.title.substr(timesUpStr.length); + + // Clean up + clearInterval(timeUpInterval); + document.onclick = null; + + } + +} + +function initStopwatch() { + hours = 0; + minutes = 0; + seconds = 0; +} + +function startStopwatch(startOffset) { + + playBtn.classList.remove("fa-play"); + playBtn.classList.add("fa-pause"); + + timeout = setTimeout(updateStopwatch, startOffset); + +} + +function updateStopwatch() { + + // Update seconds + seconds++; + if (hours === 0 && minutes === 0 && seconds === 1) secondsElem.classList.add("highlighted"); + if (seconds >= 60) { + seconds = 0; + + // Update minutes + minutes++; + if (hours === 0 && minutes === 1) minutesElem.classList.add("highlighted"); + if (minutes >= 60) { + minutes = 0; + + // Update hours + hours++; + if (hours === 1) hoursElem.classList.add("highlighted"); + hoursElem.innerText = pad(hours) + "h"; + + } + // Minutes + minutesElem.innerText = pad(minutes) + "m"; + + } + // Seconds + secondsElem.innerText = pad(seconds) + "s"; + + timeout = setTimeout(updateStopwatch, 1000); + +} + +function parseQueryParams() { + if (location.search === "" || location.search.indexOf("?") !== 0) return {}; + var result = {}; + location.search.substr(1).split("&").forEach(function(str) { + var key = str.split("=")[0]; + var value; + if (str.split("=").length > 1) value = str.split("=")[1]; + else value = null; + result[key] = value; + }); + return result; +} + +// Adds one leading zero if necessary +function pad(num) { + return ("00" + num).substr(-2); +} \ No newline at end of file diff --git a/popup/style.css b/popup/style.css new file mode 100644 index 0000000..4e27476 --- /dev/null +++ b/popup/style.css @@ -0,0 +1,63 @@ +@font-face { + font-family: "Jetbrains Mono"; + src: url("/assets/JetBrainsMono-Regular.woff2") format("woff2"), + url("/assets/JetBrainsMono-Regular.ttf") format("truetype"); +} +body { + margin: 0; + padding: 0; + overflow: hidden; + background-color: #FAFAFA; + color: #424242; + font-family: "Jetbrains Mono", helvetica, arial, sans-serif; +} +main { + position: absolute; + width: 100vw; + text-align: center; + top: 50%; + transform: translate(0, -50%); +} +main > span { + font-size: 15vw; /* Browsers that don't support min() */ + font-size: min(15vw, 50vh); + color: #9E9E9E; +} +main > span.highlighted { + color: #424242; +} +main > span.red { + color: #F4511E; +} +.progress { + position: absolute; + bottom: 0; + left: 0; + height: 5px; + width: 0; +} +#progress-bg { + background-color: #9E9E9E; +} +#progress-fg { + background-color: #43A047; + animation-timing-function: linear; + animation-fill-mode: forwards; +} +@keyframes progress { + from { + width: 0; + } + to { + width: 100vw; + } +} +/* FontAwesome */ +i { + font-size: 12px; + color: #9E9E9E; +} +i:hover { + cursor: pointer; + color: #424242; +} \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..6cd5bbf --- /dev/null +++ b/script.js @@ -0,0 +1,213 @@ +// Make checkboxes green on Chrome +/*if (navigator.vendor === "Google Inc.") { + [].slice.call(document.querySelectorAll("input[type='checkbox']")).forEach(function(checkbox) { + checkbox.style.filter = "invert(100%) hue-rotate(70deg) brightness(0.8)"; + }); +}*/ + +// Only show bookmark button if supported +// Check if AddFavorite() exists, addPanel() exists or replaceState() exists which is used in /bookmark/script.js +if ((window.external && typeof window.external.AddFavorite === "function") || (window.sidebar && typeof window.sidebar.addPanel === "function") || (history && typeof history.replaceState === "function")) { + document.getElementById("bookmark").style.display = "inline-block"; +} + +// Open new window when clicking create +document.getElementById("create").onclick = function(event) { + + var popup = window.open( + createLink("popup"), + "PopupTimer" + Date.now(), + "popup,width=250,height=100,menubar=no,toolbar=no,location=no,status=no,resizable=no,scrollbars=no" + ); + + // Probably not going to work on any modern browser but worth a try + popup.onblur = function() { + popup.focus(); + } + +}; + +// When clicking Create bookmark +document.getElementById("bookmark").onclick = function(event) { + if (event.target.classList.contains("disabled")) return; + + // Some older browsers include built-in functions for adding a bookmark, attempt to use this if user didn't perform shift click + if (!event.shiftKey) { + + var link = createLink("link"); + var title = document.getElementById("name").value; + + // Internet explorer + if (window.external && typeof window.external.AddFavorite === "function") { + + window.external.AddFavorite(link, title); + showBookmarkAdded(); + return; + + // Old Firefox, SeaMonkey + } else if (window.sidebar && typeof window.sidebar.addPanel === "function") { + + window.sidebar.addPanel(title, link, ""); + showBookmarkAdded(); + return; + + } + + } + + // Show bookmark instructions in new tab + window.open( + createLink("bookmark"), + "_blank", + "" + ); + +} + +// Show a green "Bookmark added" message for a second +function showBookmarkAdded() { + + var bookmarkBtn = document.getElementById("bookmark"); + bookmarkBtn.innerHTML = " Bookmark added"; + bookmarkBtn.style.color = "#66BB6A"; + bookmarkBtn.classList.add("disabled"); + + setTimeout(function() { + + bookmarkBtn.innerText = "Create bookmark"; + bookmarkBtn.style.color = "inherit"; + bookmarkBtn.classList.remove("disabled"); + + }, 1000); + +} + +// When clicking Timer/Stopwatch +[].slice.call(document.querySelectorAll("#popup-type td")).forEach(function(elem) { + elem.onclick = function(event) { + + var elem = event.target; + if (elem.classList.contains("selected")) return; + elem.classList.add("selected"); + + switch (elem.id) { + case "timer": + document.getElementById("stopwatch").classList.remove("selected"); + document.getElementById("input-timer").style.display = "block"; + document.getElementById("name").value = "Timer"; + break; + case "stopwatch": + document.getElementById("timer").classList.remove("selected"); + document.getElementById("input-timer").style.display = "none"; + document.getElementById("name").value = "Stopwatch"; + break; + } + + document.getElementById("input-common").style.display = "block"; + + var linkElem = document.getElementById("link"); + linkElem.innerText = createLink("link"); + linkElem.style.display = "inline-block"; + + } +}); + +// Disable buttons on invalid input +[].slice.call(document.getElementsByTagName("input")).forEach(function(input) { + input.oninput = function(event) { + + var createBtn = document.getElementById("create"); + var bookmarkBtn = document.getElementById("bookmark"); + var isInvalid = document.querySelectorAll("input:invalid").length > 0; + + if (isInvalid) { + createBtn.disabled = true; + bookmarkBtn.classList.add("disabled"); + } else { + createBtn.disabled = false; + bookmarkBtn.classList.remove("disabled"); + document.getElementById("link").innerText = createLink("link"); + } + + } +}); + +// Copy link to clipboard when clicked +document.getElementById("link").onclick = function() { + + var link = createLink("link"); + var linkElem = document.getElementById("link"); + + // Catch is called both on promise rejection (insufficient permissons) and if the function doesn't exist + try { + + navigator.clipboard.writeText(link); + linkShowMessage("Copied to clipboard!", "#66BB6A"); + + } catch(e) { + try { + + // Alternatively, just select the text and copy it + var range = document.createRange(); + range.setStart(linkElem, 0); + range.setEnd(linkElem, 1); + + var selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + + document.execCommand("copy"); + + linkShowMessage("Copied to clipboard!", "#66BB6A"); + + } catch(e) { + // Browser doesn't support copying + console.error(e); + linkShowMessage("Couldn't copy link :(", "#EF5350"); + } + } + +} + +// Displays a message where the link is for one second +function linkShowMessage(message, color) { + + var linkElem = document.getElementById("link"); + + linkElem.style.backgroundColor = color; + linkElem.style.width = linkElem.offsetWidth + "px"; + linkElem.style.color = "white"; + linkElem.style.fontFamily = "helvetica, arial, sans-serif"; + linkElem.style.fontWeight = "bold"; + linkElem.innerText = message; + + setTimeout(function() { + linkElem.style.backgroundColor = "#E0E0E0"; + linkElem.style.color = "black"; + linkElem.style.fontFamily = "'Jetbrains Mono', monospace"; + linkElem.style.width = "auto"; + linkElem.style.fontWeight = "normal"; + linkElem.innerText = createLink("link"); + }, 1000); + +} + +function createLink(type) { + + // Get user input + var input = {}; + ["hours", "minutes", "seconds", "name"].forEach(function(name) { + input[name] = document.getElementById(name).value; + }); + ["autostart", "beep"].forEach(function(name) { + input[name] = !!document.getElementById(name).checked; + }); + if (document.getElementById("timer").classList.contains("selected")) input.type = "timer"; + else input.type = "stopwatch"; + + // Create URL + var url = location.protocol + "//" + location.host + "/" + type + "?type=" + input.type + "&name=" + encodeURIComponent(input.name) + "&autostart=" + input.autostart; + if (input.type === "timer") url += "&h=" + input.hours + "&m=" + input.minutes + "&s=" + input.seconds + "&beep=" + input.beep; + return url; + +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..95c40f0 --- /dev/null +++ b/style.css @@ -0,0 +1,125 @@ +@font-face { + font-family: "Jetbrains Mono"; + src: url("/assets/JetBrainsMono-Regular.woff2") format("woff2"), + url("/assets/JetBrainsMono-Regular.ttf") format("truetype"); +} +body { + margin: 2em; + background-color: #FAFAFA; + color: #424242; + text-align: center; +} +::selection, ::-moz-selection { + background-color: #43A047; + color: white; +} +body, input, button { + font-family: helvetica, arial, sans-serif; + font-size: 18px; +} +main { + display: block; /* IE */ + margin: auto; + margin-top: 50px; + width: 100%; + max-width: 400px; +} +#popup-blocked::warning, #popup-warning *::selection, #popup-warning::-moz-selection, #popup-warning *::-moz-selection { + background-color: #F57F17; +} +#popup-type { + margin: auto; +} +#popup-type td { + width: 50vw; + color: #9E9E9E; + border-bottom: 1px solid #9E9E9E; + padding-top: 1px; + padding-bottom: 5px; + user-select: none; +} +#popup-type td:not(.selected):hover { + padding-top: 0; + color: #424242; + border-bottom: 2px solid #424242; + cursor: pointer; +} +#popup-type td.selected { + padding-top: 0; + color: #43A047; + border-bottom: 2px solid #43A047; +} +#input-common, #input-timer { + display: none; +} +input { + background-color: white; + border: none; + outline: none; + border-bottom: 1px solid #9E9E9E; + transition-duration: 0.2s; +} +input:focus { + border-bottom: 1px solid #43A047; +} +input:invalid { + border-bottom: 1px solid #E53935; + background-color: #FFCDD2; + outline: none; + box-shadow: none; +} +input[type=checkbox] { + filter: hue-rotate(290deg); +} +#time-input-container { + display: flex; +} +.time-input { + width: 33%; + text-align: right; + flex: 1; + min-width: 0; /* SeaMonkey */ +} +#create { + width: 100%; + background-color: #43A047; + color: white; + padding: 10px; + border: none; + outline: none; + transition-duration: 0.2s; + cursor: default; +} +#create:not(:disabled):hover { + cursor: pointer; + box-shadow: 2px 2px 2px #BDBDBD; +} +#create:active { + background-color: #2E7D32; +} +#create:disabled { + background-color: #9E9E9E; +} +#bookmark { + font-size: 15px; + margin-top: 10px; + display: none; + color: inherit; + text-decoration: inherit; + cursor: default; + border: none; + outline: none; +} +#bookmark:not(.disabled):hover { + text-decoration: underline; + cursor: pointer; +} +#link { + display: none; + background-color: #E0E0E0; + padding: 3px; + font-family: "Jetbrains Mono", monospace; + font-size: 12px; + cursor: pointer; + word-break: break-all; +}