Last active
January 17, 2021 23:23
-
-
Save generalmimon/0a7cdb1c112885025d4d84b5412bedab to your computer and use it in GitHub Desktop.
User JS to automatically save <textarea> contents into browser localStorage (intended for GitHub)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Not working version right now, grab an older one from Revisions | |
(function(storageKey) { | |
'use strict'; | |
const IDLE_DELAY = 10 * 1000; // in miliseconds | |
let timeout; | |
let currentPageKey = null; | |
class UrlSync { | |
constructor() { | |
} | |
getPageKey(url) { | |
const urlObj = new URL(url); | |
urlObj.hash = ''; | |
return urlObj.toString(); | |
} | |
// should be called ASAP to ensure that no call escapes | |
observeHistoryManipulation(history) { | |
history.replaceState = function(...args) { | |
History.prototype.replaceState.call(this, ...args); | |
console.log('replaceState', args); | |
}; | |
history.pushState = function(...args) { | |
History.prototype.pushState.call(this, ...args); | |
console.log('pushState', args); | |
}; | |
} | |
} | |
function getPageKey() { | |
const url = new URL(location.href); | |
url.hash = ''; | |
return url.toString(); | |
} | |
function loadStorage(storageKey) { | |
const savedData = localStorage.getItem(storageKey); | |
if (savedData) { | |
try { | |
return JSON.parse(savedData); | |
} catch (e) {} | |
} | |
return {}; | |
} | |
function getConflictText(editedText, savedText) { | |
return ( | |
`<<<<<< Edited text | |
${editedText} | |
======= | |
${savedText} | |
>>>>>>> Saved draft in localStorage` | |
); | |
} | |
function restoreSession(data) { | |
for (let id in data) { | |
if (!data.hasOwnProperty(id)) continue; | |
const el = document.getElementById(id); | |
if (!el) continue; | |
if (!el.tagName || el.tagName.toLowerCase() !== 'textarea') { | |
console.warn(el, 'with id =', id, 'is not <textarea>, skipping'); | |
continue; | |
} | |
if (el.value === data[id]) continue; | |
el.value = el.value ? getConflictText(el.value, data[id]) : data[id]; | |
} | |
} | |
function initSession(storage, pageKey) { | |
const data = storage[pageKey]; | |
if (!data) { | |
storage[pageKey] = {}; | |
return; | |
} | |
restoreSession(data); | |
} | |
const {saveDraft, syncPageKey} = (function(storageKey) { | |
const storage = loadStorage(storageKey); | |
let isAlarm = false; | |
function saveDraft(id, content, el, pageKey) { | |
storage[pageKey][id] = content; | |
localStorage.setItem(storageKey, JSON.stringify(storage)); | |
el.style.transition = 'background-color .5s'; | |
el.style.backgroundColor = '#01ff707f'; | |
setTimeout(() => { | |
el.style.backgroundColor = ''; | |
}, 500); | |
} | |
function syncPageKey() { | |
const pageKey = getPageKey(); | |
if (pageKey !== currentPageKey) { | |
initSession(storage, currentPageKey); | |
} | |
} | |
return {saveDraft, syncPageKey}; | |
})(storageKey); | |
const {addSaveTask, resolveTasks} = (function(saveDraft) { | |
let todoTasks = {}; | |
function addSaveTask(args, id) { | |
todoTasks[id] = args; | |
} | |
function resolveTasks() { | |
for (let id in todoTasks) { | |
saveDraft.apply(null, todoTasks[id]); | |
} | |
todoTasks = {}; | |
} | |
return {addSaveTask, resolveTasks}; | |
})(saveDraft); | |
document.addEventListener('input', (e) => { | |
const el = e.target; | |
if (!el.tagName || el.tagName.toLowerCase() !== 'textarea') return true; | |
addSaveTask([el.id, el.value, el], el.id); | |
if (timeout) clearTimeout(timeout); | |
timeout = setTimeout(resolveTasks, IDLE_DELAY); | |
}); | |
window.addEventListener('load', onPageLoad); | |
})('textareaDrafts'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment