liaison - Synthetic change record

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>
<div><input type="button" value="Change values and show change records below" onclick="change();" /></div>
<pre></pre>
<pre></pre>

CSS

@font-face{
	font-family: Helvetica Neue;
	src: local("Helvetica Neue Light"), local("HelveticaNeue-Light");
}

template, * [template] {
	display: none;
}

body, input {
	font-family: Segoe UI, Helvetica Neue, Helvetica, arial, sans-serif;
	-webkit-font-smoothing: antialiased;
}

.cell {
	width: 16ex;
	display: inline-block;
}

JavaScript

require.config({baseUrl: "http://ibm-js.github.io/libraries/master/"});
require(["deliteful-build/layer"], function () {
    require(["decor/Observable"], function (Observable) {
        function Point(x, y) {
            Observable.assign(this, {x: x, y: y});
            this.move = function (distance, angle) {
                Observable.getNotifier(this).performChange("move", function () {
                    this.set("x", this.x + distance * Math.cos(angle));
                    this.set("y", this.y + distance * Math.sin(angle));
                    return {
                        distance: distance,
                        angle: angle
                    };
                }.bind(this));
            };
        }
    
        Point.prototype = Object.create(Observable.prototype);
    
        Point.observe = function (point, callback) {
            return Observable.observe(point, callback, ["add", "update", "delete", "move"]);
        };
    
        var point = new Point(0, 0);
        Observable.observe(point, function (records) {
            document.getElementsByTagName("pre")[0].innerHTML
                = "Observable.observe():\n" + JSON.stringify(records, null, 4);
        });
        Point.observe(point, function (records) {
            document.getElementsByTagName("pre")[1].innerHTML
                = "Point.observe():\n" + JSON.stringify(records, null, 4);
        });
    
        window.change = function () {
            point.move(1, Math.PI / 4);
        };
    });
});