summaryrefslogtreecommitdiff
path: root/src/history.js
diff options
context:
space:
mode:
authorLV-426 <lv-426@taproot.org.il>2014-11-13 17:41:57 +0200
committerLV-426 <lv-426@taproot.org.il>2014-11-13 17:41:57 +0200
commit76d1de512a58f023ae348ae8500100490fba9915 (patch)
tree87a3df058d3aaf1a3f2c408a784ffe63209cdaac /src/history.js
parent4a303d5a7a7e1f8327bb18a2ef3e3093a30a50b6 (diff)
rename scripts/ -> src/
Diffstat (limited to 'src/history.js')
-rw-r--r--src/history.js135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/history.js b/src/history.js
new file mode 100644
index 00000000..b46dd260
--- /dev/null
+++ b/src/history.js
@@ -0,0 +1,135 @@
+// Once upon a time we shall have a versioned property graph from which history
+// will be one extractable aspect, much like a git for graphs. Now we just have
+// a plain list of events for a specific user.
+
+// Enums and chrome don't play along well. Object.freeze I guess? actually rhizi code cuases
+// exceptions but that shouldn't break the console, as evidenced by the '__commandLineAPI is not defined'
+// error below.
+//
+// Uncaught TypeError: Can't add property addednodes, object is not extensible rz_core.js:4
+// Uncaught TypeError: Can't add property text, object is not extensible textanalysis.js:3
+// Uncaught TypeError: Can't add property key, object is not extensible buttons.js:5
+// Uncaught ReferenceError: sentence is not defined robot.js:11
+// Resource interpreted as Font but transferred with MIME type application/font-sfnt: "http://localhost:8000/external/Lato300.ttf". jquery.js:2
+// > document
+// ReferenceError: __commandLineAPI is not defined
+//var ActionEnum = Enum();
+
+define(['jquery', 'FileSaver', 'consts', 'signal'],
+ function($, saveAs, consts, signal) {
+
+/* user - username (string)
+ * svg - svg element for catching zoom events (jquery DOMNode wrapper)
+ */
+function History(user, transform_element) {
+ var that = this;
+ this.records = [];
+ this.user = user;
+ this.transform_element = transform_element;
+ signal.slot(consts.APPLIED_GRAPH_DIFF, function(obj) {
+ return that.record_graph_diff(obj)
+ });
+ signal.slot(consts.KEYSTROKES, function(obj) {
+ return that.record_keystrokes(obj);
+ });
+ // XXX create zoom behavior - then proof to event name change
+ $(window).on('wheel.history', function(obj) {
+ that.record_zoom(obj);
+ return true;
+ });
+}
+
+var ACTION_KEYSTROKES = 'ACTION_KEYSTROKES';
+var ACTION_GRAPH_DIFF = 'ACTION_GRAPH_DIFF';
+var ACTION_ZOOM = 'ACTION_ZOOM';
+
+var KEYSTROKE_WHERE_TEXTANALYSIS = 'KEYSTROKE_WHERE_TEXTANALYSIS';
+var KEYSTROKE_WHERE_DOCUMENT = 'KEYSTROKE_WHERE_DOCUMENT';
+var KEYSTROKE_WHERE_EDIT_NODE = 'KEYSTROKE_WHERE_EDIT_NODE';
+
+History.prototype.record = function(action, d)
+{
+ if (d === undefined || action === undefined) {
+ throw "Invalid arguments";
+ }
+ d['action'] = action;
+ d['user'] = this.user;
+ d['timestamp'] = new Date();
+ this.records.push(d);
+ $('.history-timeline').html('<pre>' + JSON.stringify(d) + '</pre>');
+};
+
+function svg_extract_translate_and_scale(e)
+{
+ // See: http://stackoverflow.com/questions/10349811/how-to-manipulate-translate-transforms-on-a-svg-element-with-javascript-in-chrom
+ // Using the regexp option right now, did only firefox testing 36
+ var str = e.attributes['transform'].value;
+ var parts = /translate\(\s*([^\s,)]+)[ ,]([^\s,)]+)/.exec(str);
+ var scale = /scale\(\s*([^\s)]+)\)/.exec(str);
+ if (scale) {
+ var x = parts[1], y = parts[2];
+ return {scale:+scale[1], translate: [+x, +y]};
+ } else {
+ return {scale:1.0, translate: [0.0, 0.0]};
+ }
+}
+
+History.prototype.record_zoom = function(d)
+{
+ var transform = svg_extract_translate_and_scale(this.transform_element);
+
+ if (transform === undefined) {
+ console.log('record_zoom: bug: transform_element has no transform attribute');
+ return;
+ }
+ this.record(ACTION_ZOOM, {transform: transform});
+}
+
+History.prototype.save_to_file = function()
+{
+ var json = JSON.stringify(this.records, function (k, v) { return v; }, 2);
+
+ saveAs(new Blob([json], {type: 'application/json'}), 'history.json');
+};
+
+History.prototype.clear_history = function()
+{
+ this.records = [];
+}
+
+History.prototype.record_graph_diff = function(obj)
+{
+ this.record(ACTION_GRAPH_DIFF, {
+ nodes: {add: obj.nodes && obj.nodes.add, remove: obj.nodes && obj.nodes.remove,
+ change: obj.nodes && obj.nodes.change},
+ links: {add: obj.links && obj.links.add, remove: obj.links && obj.links.remove,
+ change: obj.links && obj.links.change},
+ });
+}
+
+History.prototype.record_keystrokes = function(obj)
+{
+ var where = obj.where,
+ keys = obj.keys;
+
+ if (where === undefined || keys === undefined || keys.length === undefined ||
+ keys.length <= 0) {
+ throw "Invalid arguments";
+ }
+ keys = keys.filter(function(k) { return k !== undefined; });
+ if (keys.length == 0) {
+ return;
+ }
+ this.record(ACTION_KEYSTROKES, {
+ 'keys': keys,
+ 'where': where
+ });
+}
+
+return {
+ History:History,
+ KEYSTROKE_WHERE_TEXTANALYSIS:KEYSTROKE_WHERE_TEXTANALYSIS,
+ KEYSTROKE_WHERE_DOCUMENT:KEYSTROKE_WHERE_DOCUMENT,
+ KEYSTROKE_WHERE_EDIT_NODE:KEYSTROKE_WHERE_EDIT_NODE
+};
+}); // define