diff --git a/pages/scripts/sharedworker.js b/pages/scripts/sharedworker.js new file mode 100644 index 0000000..7c4c4c7 --- /dev/null +++ b/pages/scripts/sharedworker.js @@ -0,0 +1,36 @@ +const mutations = { + ADD: 'ADD', + SET: 'SET' +}; + +let browserInstances = []; +let messages = []; + +onconnect = function(e) { + const port = e.ports[0]; + + browserInstances.push(port); + + port.onmessage = function({ data }) { + switch(data.mutation) { + case mutations.ADD: + messages = [...messages, data.value]; + break; + case mutations.SET: + messages = data.value; + break; + } + + postMessage({ ...data, messages }); + } +} + +function postMessage(message) { + if (!Array.isArray(message.value)) { + message.value = [message.value]; + } + + browserInstances.map(instance => { + instance.postMessage(message); + }); +} diff --git a/pages/sharedworker/index.html b/pages/sharedworker/index.html index 7b3c4b7..861972a 100644 --- a/pages/sharedworker/index.html +++ b/pages/sharedworker/index.html @@ -32,8 +32,6 @@

SharedWorker Cross-Tab Communication

-
Not Yet Completed
-
@@ -65,9 +63,114 @@ const messagesKey = 'messages'; const senderIdKey = 'senderId'; const tabSenderId = getSenderId(); + const mutations = { + ADD: 'ADD', + SET: 'SET' + }; /* FUNCTIONALITY CODE */ + const worker = new SharedWorker('scripts/sharedworker.js'); + worker.port.onmessage = handleNewMessage; + + loadMessages(); + + document.forms.sendMessageForm.addEventListener('submit', handleSendMessage); + document.forms.clearMessagesForm.addEventListener('submit', handleClearMessages); + + function handleSendMessage(event) { + event.preventDefault(); + + const value = event.target.message.value; + const message = makeMessage(value); + + postMessage(mutations.ADD, message); + + event.target.reset(); + event.target.message.focus(); + } + + function handleClearMessages(event) { + if (event) event.preventDefault(); + + postMessage(mutations.SET, []); + } + + function handleNewMessage({ data }) { + const { mutation, value, messages } = data; + + setStringifiedStorageItem(messagesKey, messages); + + messages.length + ? hideEl(messagesPlaceholderEl) + : showEl(messagesPlaceholderEl); + + switch(mutation) { + case mutations.ADD: + displayMessages(value); + break; + case mutations.SET: + messagesEl.innerHTML = ''; + displayMessages(value); + break; + } + } + + function addMessage(message) { + let messages = getMessages(); + messages.push(message); + return messages; + } + + function makeMessage(message) { + return { + id: getUniqueId(), + senderId: tabSenderId, + message, + }; + } + + function makeMessageEl({ message, id, senderId }) { + const li = document.createElement('li'); + const baseClassName = 'px-3 py-1 rounded'; + + li.id = id; + li.textContent = message; + li.className = + senderId == tabSenderId + ? `${baseClassName} bg-blue-600 text-white place-self-end` + : `${baseClassName} bg-gray-700 text-white place-self-start`; + + return li; + } + + function loadMessages() { + const messages = getMessages(); + + postMessage(mutations.SET, messages); + + if (messages.length) { + hideEl(messagesPlaceholderEl); + } + + displayMessages(messages); + } + + function displayMessages(messages = []) { + messages.forEach((msg) => messagesEl.appendChild(makeMessageEl(msg))); + } + + function getMessages() { + const messages = getParsedStorageItem(messagesKey); + return !Array.isArray(messages) ? [] : messages; + } + + function postMessage(mutation, value) { + worker.port.postMessage({ mutation, value }); + } + + + /* UTILITIES */ function hideEl(el) { @@ -83,19 +186,13 @@ return !Array.isArray(item) ? JSON.parse(item) : item; } - function getArrayDifference(primary, secondary, key) { - return key - ? primary.filter((x) => !secondary.find((y) => x[key] === y[key])) - : primary.filter((item) => !secondary.includes(item)); - } - function setStringifiedStorageItem(key, value) { localStorage.setItem(key, value ? JSON.stringify(value) : value); } function getParsedStorageItem(storageKey) { let stringValue = localStorage.getItem(storageKey); - return stringValue ? JSON.parse(stringValue) : defaultValue; + return stringValue ? JSON.parse(stringValue) : stringValue; } function getSenderId() {