Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit 697ddaa

Browse files
committed
Handle 'updateDOM' messages.
1 parent 893445e commit 697ddaa

File tree

3 files changed

+184
-3
lines changed

3 files changed

+184
-3
lines changed

SpecRunner.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<p id="testParaID">This is a test paragraph, with an id.</p>
2424
<p class="testParaClass">This is a test paragrapch, with a class.</p>
2525
<button id="testButton">Click Me</button>
26+
<div id="testMutate"></div>
2627
</div>
2728
</body>
2829
</html>

polyplug.js

Lines changed: 141 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ const polyplug = function() {
345345
Event handling functions for PolyPlug.
346346
**************************************************************************/
347347

348-
function registerEvent(query, type, listener) {
348+
function registerEvent(query, eventType, listener) {
349349
/*
350350
Register an event listener, given:
351351
@@ -362,7 +362,7 @@ const polyplug = function() {
362362
*/
363363
const elements = getElements(query);
364364
elements.forEach(function(element) {
365-
element.addEventListener(type, function(e) {
365+
element.addEventListener(eventType, function(e) {
366366
const detail = JSON.stringify({
367367
type: e.type,
368368
target: toJS(e.target),
@@ -374,12 +374,150 @@ const polyplug = function() {
374374
});
375375
}
376376

377+
/**************************************************************************
378+
Message handling functions for PolyPlug.
379+
**************************************************************************/
380+
381+
function receiveMessage(raw) {
382+
/*
383+
Receive a raw message string (containing JSON). Deserialize it and
384+
dispatch the message to the appropriate handler function.
385+
*/
386+
const message = JSON.parse(raw);
387+
switch (message.type) {
388+
case "updateDOM":
389+
onUpdateDOM(message);
390+
break;
391+
case "registerEvent":
392+
onRegisterEvent(message);
393+
break;
394+
case "stdout":
395+
onStdout(message);
396+
break;
397+
case "stderr":
398+
onStderr(message);
399+
break;
400+
case "error":
401+
onError(message);
402+
break;
403+
default:
404+
console.log("Unknown message type.")
405+
console.log(message)
406+
break;
407+
}
408+
}
409+
410+
function onUpdateDOM(msg) {
411+
/*
412+
Handle messages from an interpreter to update the DOM.
413+
414+
Given a query to identify a target element, mutate it to the target
415+
state (encoded as JSON).
416+
417+
Sample message:
418+
419+
msg = {
420+
type: "updateDOM",
421+
query: {
422+
id: "idOfDomElementToMutate"
423+
},
424+
target: {
425+
... JSON representation of the target state ...
426+
}
427+
}
428+
*/
429+
const elements = getElements(msg.query);
430+
if (elements.length === 1) {
431+
// Update the single valid match to
432+
const oldElement = elements[0];
433+
const newElement = toNode(msg.target)
434+
mutate(oldElement, newElement);
435+
}
436+
}
437+
438+
function onRegisterEvent(msg) {
439+
/*
440+
Handle requests from an interpreter to register an event listener.
441+
442+
Given a query to identify target element[s], listen for the event type
443+
and handle with the referenced listener function in the remote
444+
interpreter.
445+
446+
Sample message:
447+
448+
msg = {
449+
type: "registerEvent",
450+
query: {
451+
id: "idOfDomElement"
452+
},
453+
eventType: "click",
454+
listener: "my_on_click_function"
455+
}
456+
*/
457+
registerEvent(msg.query, msg.eventType, msg.listener);
458+
}
459+
460+
function onStdout(msg) {
461+
/*
462+
Handle "normal" STDOUT output.
463+
464+
Simply dispatch a "polyplugStdout" custom event with the event's detail
465+
containing the emitted characters.
466+
467+
Sample message:
468+
469+
msg = {
470+
type: "stdout",
471+
content: "Some stuff to print to the terminal"
472+
}
473+
*/
474+
const polyplugStdout = new CustomEvent("polyplugStdout", {detail: msg.content});
475+
}
476+
477+
function onStderr(msg) {
478+
/*
479+
Handle "normal" STDERR output.
480+
481+
Simply dispatch a "polyplugStderr" custom event with the event's detail
482+
containing the emitted characters.
483+
484+
Sample message:
485+
486+
msg = {
487+
type: "stderr",
488+
content: "Some stuff from stderr"
489+
}
490+
*/
491+
const polyplugStderr = new CustomEvent("polyplugStderr", {detail: msg.content});
492+
}
493+
494+
function onError(msg) {
495+
/*
496+
Handle generic error conditions from the interpreter.
497+
498+
Dispatch a "polyplugError" custom event with the event detail set to
499+
the error context.
500+
501+
Sample message:
502+
503+
msg = {
504+
type: "error",
505+
context: {
506+
... arbitrary data about the error condition ...
507+
(e.g. Exception name, line number, stack trace etc)
508+
}
509+
}
510+
*/
511+
const polyplugError = new CustomEvent("polyplugError", {detail: msg});
512+
}
513+
377514
return {
378515
toJSON: toJSON,
379516
toDOM: toDOM,
380517
mutate: mutate,
381518
getElements: getElements,
382-
registerEvent: registerEvent
519+
registerEvent: registerEvent,
520+
receiveMessage: receiveMessage
383521
}
384522
};
385523

spec/polyplugSpec.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,4 +308,46 @@ describe("When working with PolyPlug,", function() {
308308
button.dispatchEvent(clickEvent);
309309
});
310310
});
311+
describe("when handling incoming messages,", function() {
312+
it("the updateDOM message calls the expected mutate", function() {
313+
const target = {
314+
"nodeType": 1,
315+
"tagName": "div",
316+
"attributes": {
317+
"id": "testMutate"
318+
},
319+
"childNodes": [
320+
{
321+
"nodeType": 1,
322+
"tagName": "h1",
323+
"attributes": {
324+
"class": "testClass"
325+
},
326+
"childNodes": [
327+
{
328+
"nodeType": 3,
329+
"nodeName": "#text",
330+
"nodeValue": "This is a test, updated via morphing.",
331+
"childNodes": []
332+
}
333+
]
334+
}
335+
]
336+
};
337+
const msg = JSON.stringify({
338+
type: "updateDOM",
339+
query: {
340+
id: "testMutate"
341+
},
342+
target: target
343+
});
344+
// Process the message.
345+
plug.receiveMessage(msg);
346+
// The DOM has been updated as expected.
347+
const updatedDIV = plug.getElements({id: "testMutate"})[0];
348+
const actual = plug.toJSON(updatedDIV);
349+
const expected = JSON.stringify(target);
350+
expect(actual).toEqual(expected);
351+
});
352+
});
311353
});

0 commit comments

Comments
 (0)