import * as edist from './protocol';
import * as websocket from './websocket';
import * as doc from './document';
function error(msg: string): void {
document.body.setAttribute('style', "background-color: mistyrose;");
console.error(msg);
}
function connected(url: string): void {
document.body.setAttribute('style', "background-color: honeydew;");
console.log(`WebSocket connection to ${url} established.`);
}
function loaded(): void {
const documentNameInput = document.getElementById("documentname") as HTMLInputElement;
if (!documentNameInput) {
error("Unable to find document name input element");
return;
}
const form = document.getElementById("form") as HTMLFormElement;
if (!form) {
error("Unable to find form element");
return;
}
const content = document.getElementById("content") as HTMLDivElement;
if (!content) {
error("Unable to find content element");
return;
}
const clientId = BigInt(1 + Math.round(4294967294 * Math.random()));
const websocketManager = new websocket.WebSocketManager();
form.onsubmit = (event) => {
event.preventDefault();
event.stopPropagation();
const documentName = documentNameInput.value;
if (connect(content, clientId, websocketManager, documentName)) {
documentNameInput.value = "";
documentNameInput.placeholder = documentName;
}
};
const documentNameDefault = "hello world";
if (connect(content, clientId, websocketManager, documentNameDefault)) {
documentNameInput.value = "";
documentNameInput.placeholder = documentNameDefault;
}
}
function connect(content: HTMLDivElement, clientId: bigint, websocketManager: websocket.WebSocketManager, documentName: string): boolean {
if (documentName === "") {
return false;
}
if (!websocketManager.connect(websocket.documentNameToURL(documentName))) {
return false;
}
content.replaceChildren();
let awaitingFirstMessage = true;
websocketManager.onopen = (url: string, conn: WebSocket) => {
connected(url);
awaitingFirstMessage = true;
};
const docu = new doc.Document(clientId, websocketManager);
websocketManager.ondata = (url: string, conn: WebSocket, msg: MessageEvent) => {
const data: Blob = msg.data;
data.arrayBuffer().then(buffer => {
const array = new Uint8Array(buffer);
const imessage = edist.Message.decode(array);
if (imessage.updates) {
docu.applyUpdates(imessage.updates);
docu.render(content);
if (awaitingFirstMessage) {
awaitingFirstMessage = false;
docu.markAllDirty();
const selection = window.getSelection();
if (selection !== null && content.firstChild !== null) {
selection.setBaseAndExtent(content.firstChild, 0, content.firstChild, 0);
}
}
}
});
};
websocketManager.onclose = (url: string) => {
error(`WebSocket connection to ${url} lost`);
};
return true;
}
window.addEventListener('DOMContentLoaded', loaded);