Skip to content

Instantly share code, notes, and snippets.

@ara4n
Last active September 23, 2018 23:49
Show Gist options
  • Save ara4n/016fbf92cc0f651abfe685d5dca81ddd to your computer and use it in GitHub Desktop.
Save ara4n/016fbf92cc0f651abfe685d5dca81ddd to your computer and use it in GitHub Desktop.
<html>
<style type="text/css">
#timeline {
list-style: none;
}
.sender {
float: left;
width: 200px;
padding-right: 10px;
text-align: right;
}
</style>
<script type="text/javascript">
window.addEventListener("message", onMessage, false);
function onMessage(event) {
let timeline = document.getElementById("timeline");
// do if (event.origin) check here to stop other JS sources injecting events
console.log("received: " + JSON.stringify(event.data));
switch (event.data.method) {
case "setEvents":
// args: event.data.events: an array of JSON event objects
if (!event.data.args.append) {
// vape the timeline by replacing it with a shallow-clone of itself
// TODO: would be even faster to maintain a simple shadow DOM rather than
// editing the DOM directly, but this is probably premature optimisation
let newTimeline = timeline.cloneNode(false);
timeline.parentNode.replaceChild(newTimeline, timeline);
timeline = newTimeline;
}
for (const ev of event.data.args.events) {
const tile = document.createElement("li");
const sender = document.createElement("div");
sender.className = "sender";
sender.appendChild(document.createTextNode(`<${ev.sender}>`));
// WARNING: assumes the event's body has already been HTML-sanitised
const body = document.createElement("div");
body.className = "body";
body.innerHTML = ev.contents.formatted_body || ev.contents.body;
tile.appendChild(sender);
tile.appendChild(body);
timeline.appendChild(tile);
}
break;
default:
console.warn("Unrecognised method " + event.data.method);
}
}
</script>
<script type="text/javascript">
// Fake postmessage client pretending to be Swift
window.postMessage({
method: 'setEvents',
args: {
events: [
{ sender: "@matthew:matrix.org", contents: { body: "Hello world!" } },
{ sender: "@matthew:matrix.org", contents: { formatted_body: "I am a <b>fish</b>" } },
],
},
}, '*');
setTimeout(()=>{
window.postMessage({
method: 'setEvents',
args: {
events: [
{ sender: "@neil:sandbox.modular.im", contents: { formatted_body: "Mr Flibble is very cross!" } },
],
append: true,
},
}, '*');
}, 1000);
</script>
<body>
<!-- unintuitively lists seem to be better than tables for chat timelines,
at least for accessibility purposes (but dunno how macOS handles that) -->
<ol id="timeline">
</ol>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment