From aa3880f4428a315c9f23d83faa5aa3aac9ac5c59 Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 3 Feb 2016 16:48:49 +0100 Subject: [PATCH] up to date --- www/vdom/index.html | 14 ++++++- www/vdom/main.js | 96 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/www/vdom/index.html b/www/vdom/index.html index 95c2b6907..220d57822 100644 --- a/www/vdom/index.html +++ b/www/vdom/index.html @@ -26,16 +26,28 @@ top: 0px; right: 0px; border: 0px; - height: 100vh; + height: 50vh; width: 50vw; background-color: #222; color: #ccc; } + #problemo { + position: fixed; + top: 50vh; + right: 0px; + height: 50vh; + width: 50vw; + background: #999; + color: #111; + border: none; + overflow-y: auto; + } +

 
 
 
diff --git a/www/vdom/main.js b/www/vdom/main.js
index e74f0cf32..613104189 100644
--- a/www/vdom/main.js
+++ b/www/vdom/main.js
@@ -45,34 +45,93 @@ define([
             var inner = ifrw.$('iframe')[0].contentDocument.body;
             window.inner = inner;
 
-            var $textarea = $('#feedback');
+            var $textarea = $('#feedback'),
+                $problem = $('#problemo');
+
+            var debug = function (info) {
+                $problem.text(JSON.stringify(info,null,2));
+            };
 
             var vdom1 = Convert.dom.to.vdom(inner);
 
-            var applyHjson = function (shjson) {
+            var cursor = {
+                startEl: null,
+                startOffset: 0,
+                endEl: null,
+                endOffset: 0
+            };
+
+            var getCursor = function () {
                 // where is your cursor?
                 // TODO optimize this if it works
-                /*
                 var sel = editor.getSelection(); // { rev, document, root, isLocked, _ }
+
                 var element = sel.getStartElement();
-                var ranges = sel.getRanges(); // [0] // {startContainer, startOffset, endContainer, endOffset, collapsed, document, root}
-                */
+                var ranges = sel.getRanges();
+
+                if (!ranges.length) { return; }
+                var range = ranges[0]; // {startContainer, startOffset, endContainer, endOffset, collapsed, document, root}
+
+                cursor.startEl = range.startContainer;
+                cursor.startOffset = range.startOffset;
+
+                cursor.endEl = range.endContainer;
+                cursor.endOffset = range.endOffset;
+
+                debug(cursor);
+            };
+
+            window.rangeElements = {};
+
+            var setCursor = function () {
+                try {
+                    var sel = editor.getSelection(); // { rev, document, root, isLocked, _ }
+
+                    // correct the cursor after doing dom stuff
+                //    sel.selectElement(element);
+                    var ranges = sel.getRanges();
+                    if (!ranges.length) { return; }
+                    var range = ranges[0]; // {startContainer, startOffset, endContainer, endOffset, collapsed, document, root}
+
+                    range.setStart(cursor.startEl, cursor.startOffset);
+                    range.setEnd(cursor.endEl, cursor.endOffset);
+                    sel.selectRanges([range]);
+                    /* FIXME TODO
+                        This fails because the element that we're operating on
+                        can stop existing because vdom determines that we should
+                        get rid of it. if it doesn't exist anymore, we should
+                        walk up the tree or something. Or just not try to
+                        relocate the cursor. Default behaviour might be ok.
+                        DONT FIGHT THE DOM
+                    */
+                } catch (err) {
+                    console.log("junk cursor:");
+                    console.log(cursor);
+                    debug(cursor);
+                    console.error(err);
+                    console.error(err.stack);
+                }
+            };
+
+            var applyHjson = function (shjson) {
+                // before integrating external changes, check in your own
+                vdom1 = Convert.dom.to.vdom(inner);
+
+                // remember where the cursor is
+                getCursor()
+
+                // the authoritative document is hyperjson, parse it
                 var authDoc = JSON.parse(shjson);
+                // use the authdoc to construct a second vdom
                 var vdom2 = Convert.hjson.to.vdom(authDoc);
+                // diff it against your version
                 var patches = Vdom.diff(vdom1, vdom2);
-                Vdom.patch(inner, patches);
-                // try resyncing the dom?
-                vdom1 = Convert.dom.to.vdom(inner);
-                // vdom1 = vdom2;
 
-/*
-                // correct the cursor after doing dom stuff
-                sel.selectElement(element);
-                ranges[0].setStart(element.getFirst(), ranges[0].startOffset); // 
-                ranges[0].setEnd(element.getFirst(), ranges[0].endOffset);
-                sel.selectRanges([ranges[0]]);
-*/
+                // apply the resulting patches               
+                Vdom.patch(inner, patches);
 
+                // put the cursor back where you left it
+                setCursor();
             };
 
             window.rti = realtimeInput.start($textarea[0], // synced element
@@ -116,6 +175,10 @@ define([
                                         */
                                     });
 
+            $(inner).on('keyup', function () {
+                getCursor();
+            });
+
             $textarea.val(JSON.stringify(Convert.dom.to.hjson(inner)));
 
             editor.on('change', function () {
@@ -132,6 +195,7 @@ define([
 
                 $textarea.val(JSON.stringify(hjson));
                 rti.bumpSharejs();
+                getCursor()
             });
         });
     };