]> git.za3k.com Git - flowy.git/commitdiff
Make indent preserve focus
authorZachary Vance <vanceza@gmail.com>
Thu, 28 May 2015 00:44:02 +0000 (17:44 -0700)
committerZachary Vance <vanceza@gmail.com>
Thu, 28 May 2015 00:44:02 +0000 (17:44 -0700)
dist/flowy.js
dist/flowy.unwrapped.js
src/library/shortcut.js
src/library/viewShortcuts.js
src/views/app.js
src/views/todo.js

index 36a70234c8fa39c2871dd965a347c9fd9aa0f7a7..da82859cb09413313eff6b9326906208dfa4a079 100644 (file)
@@ -223,6 +223,10 @@ var Shortcut = (function(document, _) {
         },
         addObject: function(element, type, options) {
             var manager = this;
+            if (!element) {
+                console.log("addObject called with no element");
+                return;
+            }
             object = {
                 element:element,
                 type:type,
@@ -355,11 +359,12 @@ var Shortcut = (function(document, _) {
             } ); 
         }, this);
         this.shortcutObjects = this.shortcutObjects || [];
+        var el = this.el;
         if (objectType === "global") {
-            Shortcut.globalObject = this.el;
+            Shortcut.globalObject = el;
             this._shortcutObject = Shortcut.globalObject;
         } else {
-            this._shortcutObject = Shortcut.addObject(this.el, objectType, { view: this });
+            this._shortcutObject = Shortcut.addObject(el, objectType, { view: this });
         }
     }
     View.delegateEvents = function(events) {
@@ -407,6 +412,8 @@ var TodoView = Backbone.View.extend({
     'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext",
     'Shortcut("next", "Next", "down") > .text': 'focusNext',
     'Shortcut("previous", "Previous", "up") > .text': 'focusPrevious',
+    'Shortcut("right", "Right", "right") > .text': 'rightPressed',
+    'Shortcut("left", "Left", "left") > .text': 'leftPressed',
     'Shortcut("zoomIn", "Not Done - Zoom in", "alt+right") > .text': 'zoomIn',
     'Shortcut("zoomOut", "Not Done - Zoom out", "alt+left") > .text': 'zoomOut',
     'Shortcut("expand", "Not Done - Expand / collapse", "ctrl+space") > .text': 'expand',
@@ -480,6 +487,19 @@ var TodoView = Backbone.View.extend({
     previousNode.getView().startEditingText();
     return false;
   },
+  leftPressed: function() {
+    if (!this.duringEditing()) return; // Filter out irrelevant nodes. TODO: Just pay attention to .text to begin with so I can remove this, this is tricky because render takes place after shortcut binding currently
+    if (!this.isFocusAtBeginning()) return;
+    var previousNode = this.model.previousNode({ childrenAllowed: true });
+    if (!previousNode) return false;
+    this.stopEditingText();
+    previousNode.getView().startEditingText({ atEnd: true });
+    return false;
+  },
+  rightPressed: function() {
+    if (!this.isFocusAtEnd()) return;
+    return this.focusNext();
+  },
   combinePrevious: function() {
     if (this.model.hasChildren()) {
         return;
@@ -522,11 +542,23 @@ var TodoView = Backbone.View.extend({
     }   
   },
   _maintainingFocus: function(f) {
-    var el = this.$el.find(".text")[0];
-    var start = el.selectionStart, end = el.selectionEnd;
-    var retVal = f();
-    el.focus();
-    el.setSelectionRange(start, end);
+    var el = this.$el.find("> .text")[0];
+    var sel = window.getSelection();
+    var retVal;
+    if (sel.rangeCount >= 1) {
+        var range = sel.getRangeAt(0);
+        var start = range.startOffset, end = range.endOffset;
+        retVal = f();
+        el = this.$el.find("> .text")[0];
+        sel.removeAllRanges();
+        range = document.createRange();//Create a range (a range is a like the selection but invisible)
+        range.setStart(el.childNodes[0], start);
+        range.setEnd(el.childNodes[0], end);
+        sel.addRange(range);
+    } else {
+        retVal = f();
+        sel.removeAllRanges();
+    }
     return retVal;
   },
   "delete": function() {
@@ -636,8 +668,11 @@ var TodoView = Backbone.View.extend({
   removeChild: function(position) {
      return this.$el.find("> .bullets > *").eq(position).detach();
   },
+  duringEditing: function() {
+    return this.$el.find("> .text").is(":focus");
+  },
   render: function() {
-    if (this.$el.find("> .text").is(":focus")) {
+    if (this.duringEditing()) {
         // Don't re-render during editing
         return this;
     }
@@ -974,7 +1009,7 @@ var AppView = Backbone.View.extend({
                 e.save();
             });
         });
-        Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous'] });
+        Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous', 'left', 'right'] });
         this.views = {}; // A list of views for each element in the collection
         this.list.fetch();
         this.render();
index eec138a1e3e8586614cee0c75df0a7f76f3f90fd..995c2b656e953d6946fd021c942f6024115adb1d 100644 (file)
@@ -222,6 +222,10 @@ var Shortcut = (function(document, _) {
         },
         addObject: function(element, type, options) {
             var manager = this;
+            if (!element) {
+                console.log("addObject called with no element");
+                return;
+            }
             object = {
                 element:element,
                 type:type,
@@ -354,11 +358,12 @@ var Shortcut = (function(document, _) {
             } ); 
         }, this);
         this.shortcutObjects = this.shortcutObjects || [];
+        var el = this.el;
         if (objectType === "global") {
-            Shortcut.globalObject = this.el;
+            Shortcut.globalObject = el;
             this._shortcutObject = Shortcut.globalObject;
         } else {
-            this._shortcutObject = Shortcut.addObject(this.el, objectType, { view: this });
+            this._shortcutObject = Shortcut.addObject(el, objectType, { view: this });
         }
     }
     View.delegateEvents = function(events) {
@@ -406,6 +411,8 @@ var TodoView = Backbone.View.extend({
     'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext",
     'Shortcut("next", "Next", "down") > .text': 'focusNext',
     'Shortcut("previous", "Previous", "up") > .text': 'focusPrevious',
+    'Shortcut("right", "Right", "right") > .text': 'rightPressed',
+    'Shortcut("left", "Left", "left") > .text': 'leftPressed',
     'Shortcut("zoomIn", "Not Done - Zoom in", "alt+right") > .text': 'zoomIn',
     'Shortcut("zoomOut", "Not Done - Zoom out", "alt+left") > .text': 'zoomOut',
     'Shortcut("expand", "Not Done - Expand / collapse", "ctrl+space") > .text': 'expand',
@@ -479,6 +486,19 @@ var TodoView = Backbone.View.extend({
     previousNode.getView().startEditingText();
     return false;
   },
+  leftPressed: function() {
+    if (!this.duringEditing()) return; // Filter out irrelevant nodes. TODO: Just pay attention to .text to begin with so I can remove this, this is tricky because render takes place after shortcut binding currently
+    if (!this.isFocusAtBeginning()) return;
+    var previousNode = this.model.previousNode({ childrenAllowed: true });
+    if (!previousNode) return false;
+    this.stopEditingText();
+    previousNode.getView().startEditingText({ atEnd: true });
+    return false;
+  },
+  rightPressed: function() {
+    if (!this.isFocusAtEnd()) return;
+    return this.focusNext();
+  },
   combinePrevious: function() {
     if (this.model.hasChildren()) {
         return;
@@ -521,11 +541,23 @@ var TodoView = Backbone.View.extend({
     }   
   },
   _maintainingFocus: function(f) {
-    var el = this.$el.find(".text")[0];
-    var start = el.selectionStart, end = el.selectionEnd;
-    var retVal = f();
-    el.focus();
-    el.setSelectionRange(start, end);
+    var el = this.$el.find("> .text")[0];
+    var sel = window.getSelection();
+    var retVal;
+    if (sel.rangeCount >= 1) {
+        var range = sel.getRangeAt(0);
+        var start = range.startOffset, end = range.endOffset;
+        retVal = f();
+        el = this.$el.find("> .text")[0];
+        sel.removeAllRanges();
+        range = document.createRange();//Create a range (a range is a like the selection but invisible)
+        range.setStart(el.childNodes[0], start);
+        range.setEnd(el.childNodes[0], end);
+        sel.addRange(range);
+    } else {
+        retVal = f();
+        sel.removeAllRanges();
+    }
     return retVal;
   },
   "delete": function() {
@@ -635,8 +667,11 @@ var TodoView = Backbone.View.extend({
   removeChild: function(position) {
      return this.$el.find("> .bullets > *").eq(position).detach();
   },
+  duringEditing: function() {
+    return this.$el.find("> .text").is(":focus");
+  },
   render: function() {
-    if (this.$el.find("> .text").is(":focus")) {
+    if (this.duringEditing()) {
         // Don't re-render during editing
         return this;
     }
@@ -973,7 +1008,7 @@ var AppView = Backbone.View.extend({
                 e.save();
             });
         });
-        Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous'] });
+        Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous', 'left', 'right'] });
         this.views = {}; // A list of views for each element in the collection
         this.list.fetch();
         this.render();
index 7ab8fbacfa604406a1f40a386512528a396d4f48..7235568179140aaeb732fc248c46f886f6e75631 100644 (file)
@@ -161,6 +161,10 @@ var Shortcut = (function(document, _) {
         },
         addObject: function(element, type, options) {
             var manager = this;
+            if (!element) {
+                console.log("addObject called with no element");
+                return;
+            }
             object = {
                 element:element,
                 type:type,
index d0048642d1ab1d53bfe43fb772a432f523d7be69..260d3504b2ea592b73dfbc08257feec2f813362b 100644 (file)
             } ); 
         }, this);
         this.shortcutObjects = this.shortcutObjects || [];
+        var el = this.el;
         if (objectType === "global") {
-            Shortcut.globalObject = this.el;
+            Shortcut.globalObject = el;
             this._shortcutObject = Shortcut.globalObject;
         } else {
-            this._shortcutObject = Shortcut.addObject(this.el, objectType, { view: this });
+            this._shortcutObject = Shortcut.addObject(el, objectType, { view: this });
         }
     }
     View.delegateEvents = function(events) {
index d641806d98aeb62ac2c096175d19e86c3c0726ef..c1a0c35a526c1c05f2f27dd04a6b29bd7baf6359 100644 (file)
@@ -85,7 +85,7 @@ var AppView = Backbone.View.extend({
                 e.save();
             });
         });
-        Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous'] });
+        Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous', 'left', 'right'] });
         this.views = {}; // A list of views for each element in the collection
         this.list.fetch();
         this.render();
index 2c7307a09258b94329c624cae2609cb149b475a8..9dc97a99f42404431cc4d41192b356a8b6037d92 100644 (file)
@@ -15,6 +15,8 @@ var TodoView = Backbone.View.extend({
     'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext",
     'Shortcut("next", "Next", "down") > .text': 'focusNext',
     'Shortcut("previous", "Previous", "up") > .text': 'focusPrevious',
+    'Shortcut("right", "Right", "right") > .text': 'rightPressed',
+    'Shortcut("left", "Left", "left") > .text': 'leftPressed',
     'Shortcut("zoomIn", "Not Done - Zoom in", "alt+right") > .text': 'zoomIn',
     'Shortcut("zoomOut", "Not Done - Zoom out", "alt+left") > .text': 'zoomOut',
     'Shortcut("expand", "Not Done - Expand / collapse", "ctrl+space") > .text': 'expand',
@@ -88,6 +90,19 @@ var TodoView = Backbone.View.extend({
     previousNode.getView().startEditingText();
     return false;
   },
+  leftPressed: function() {
+    if (!this.duringEditing()) return; // Filter out irrelevant nodes. TODO: Just pay attention to .text to begin with so I can remove this, this is tricky because render takes place after shortcut binding currently
+    if (!this.isFocusAtBeginning()) return;
+    var previousNode = this.model.previousNode({ childrenAllowed: true });
+    if (!previousNode) return false;
+    this.stopEditingText();
+    previousNode.getView().startEditingText({ atEnd: true });
+    return false;
+  },
+  rightPressed: function() {
+    if (!this.isFocusAtEnd()) return;
+    return this.focusNext();
+  },
   combinePrevious: function() {
     if (this.model.hasChildren()) {
         return;
@@ -130,11 +145,23 @@ var TodoView = Backbone.View.extend({
     }   
   },
   _maintainingFocus: function(f) {
-    var el = this.$el.find(".text")[0];
-    var start = el.selectionStart, end = el.selectionEnd;
-    var retVal = f();
-    el.focus();
-    el.setSelectionRange(start, end);
+    var el = this.$el.find("> .text")[0];
+    var sel = window.getSelection();
+    var retVal;
+    if (sel.rangeCount >= 1) {
+        var range = sel.getRangeAt(0);
+        var start = range.startOffset, end = range.endOffset;
+        retVal = f();
+        el = this.$el.find("> .text")[0];
+        sel.removeAllRanges();
+        range = document.createRange();//Create a range (a range is a like the selection but invisible)
+        range.setStart(el.childNodes[0], start);
+        range.setEnd(el.childNodes[0], end);
+        sel.addRange(range);
+    } else {
+        retVal = f();
+        sel.removeAllRanges();
+    }
     return retVal;
   },
   "delete": function() {
@@ -244,8 +271,11 @@ var TodoView = Backbone.View.extend({
   removeChild: function(position) {
      return this.$el.find("> .bullets > *").eq(position).detach();
   },
+  duringEditing: function() {
+    return this.$el.find("> .text").is(":focus");
+  },
   render: function() {
-    if (this.$el.find("> .text").is(":focus")) {
+    if (this.duringEditing()) {
         // Don't re-render during editing
         return this;
     }