Skip to content

Instantly share code, notes, and snippets.

@thysultan
Last active December 14, 2017 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thysultan/82062cce3a344771671382004f356b95 to your computer and use it in GitHub Desktop.
Save thysultan/82062cce3a344771671382004f356b95 to your computer and use it in GitHub Desktop.
DIO running in a web worker.
<script id="worker" type="worker">
importScripts('https://unpkg.com/dio.js')
const shared = {memory: {}, address: 0}
const allocateMemory = (object) => {
shared.memory[shared.address] = object
return shared.address++
}
const deleteMemory = (address) => {
delete shared.memory[address]
return address
}
const getObjectFromAddress = (address) => {
return shared.memory[address]
}
const getAddressFromObject = (object) => {
return object.DOM
}
const hasAddress = (address) => {
return address in shared.memory
}
const config = {
setProps(element, name, value, xmlns) {
switch (name) {
default:
postMessage({
type: 'setAttribute',
element: getAddressFromObject(element),
name: name,
value: value
})
}
},
setText(element, value) {
postMessage({
action: 'setTextContent',
element: getAddressFromObject(element),
})
},
setEvent(element, type, listener) {
postMessage({
action: 'addEventListener',
element: getAddressFromObject(element),
event: type,
})
},
insertNode(element, sibling, parent) {
postMessage({
action: 'insertNode',
element: getAddressFromObject(element),
sibling: getAddressFromObject(sibling),
parent: getAddressFromObject(parent)
})
},
appendNode(element, parent) {
postMessage({
action: 'appendChild',
element: getAddressFromObject(element),
parent: getAddressFromObject(parent)
})
},
removeNode(element, parent) {
postMessage({
action: 'removeChild',
element: deleteMemory(getAddressFromObject(element)),
parent: getAddressFromObject(parent)
})
},
createElement(element) {
const address = allocateMemory(element)
postMessage({
action: 'createElementNode',
element: address,
type: element.type
})
return address
},
createText(element) {
const address = allocateMemory(element)
postMessage({
action: 'createTextNode',
element: address,
type: element.type,
children: element.children
})
return address
},
createEmpty(element) {
const address = allocateMemory(element)
postMessage({
action: 'createEmptyNode',
element: address
})
return address
},
isValidNode(node) {
return true
},
getDocument() {
return new Number(-1)
},
setContent(element) {
postMessage({
action: 'setContent',
element: getAddressFromObject(element)
})
}
}
let {h, render} = dio.createFactory(config)
render(h('h1', 'Hello'))
</script>
<script>
const blob = new Blob([document.querySelector('#worker').textContent], {type: "text/javascript"})
const worker = new Worker(window.URL.createObjectURL(blob))
const shared = {memory: {'-1': document.documentElement}, address: 0}
worker.onmessage = ({data}) => {
console.log("Received: ", data)
switch (data.action) {
case 'createTextNode':
shared.memory[data.element] = document.createTextNode(data.children)
break
case 'createElementNode':
shared.memory[data.element] = document.createElement(data.type)
break
case 'appendChild':
shared.memory[data.parent].appendChild(shared.memory[data.element])
break
case 'appendChild':
shared.memory[data.parent].insertBefore(shared.memory[data.element], shared.memory[data.sibling])
break
case 'setContent':
shared.memory[data.element].textContent = ''
break
case 'setAttribute':
shared.memory[data.element].setAttribute(data.name, data.value)
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment