]> git.za3k.com Git - flowy.git/commitdiff
Make deleting blank nodes focus the end, rather than the beginning of the previous...
authorZachary Vance <vanceza@gmail.com>
Thu, 14 May 2015 02:55:34 +0000 (19:55 -0700)
committerZachary Vance <vanceza@gmail.com>
Thu, 14 May 2015 02:55:40 +0000 (19:55 -0700)
Focus end of a (non-nested) contenteditable div is complicated

dist/flowy.js
dist/flowy.unwrapped.js
src/library/cursorToEnd.js [new file with mode: 0644]
src/views/todo.js

index d4213e8f600a871779f2de70f53261cb48ae08d0..4881eb970ed2a38fe6b36e67e4b1e5c53ebdfe6d 100644 (file)
@@ -1,4 +1,30 @@
 $(function(){
+function setEndOfContenteditable(contentEditableElement)
+{
+    var range,selection;
+    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
+    {
+        range = document.createRange();//Create a range (a range is a like the selection but invisible)
+        range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
+        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
+        selection = window.getSelection();//get the selection object (allows you to change selection)
+        selection.removeAllRanges();//remove any selections already made
+        selection.addRange(range);//make the range you have just created the visible selection
+    }
+    else if(document.selection)//IE 8 and lower
+    { 
+        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
+        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
+        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
+        range.select();//Select the range (make it the visible selection
+    }
+}
+
+/**
+ * @depend ../library/cursorToEnd.js
+ */
+
+
 var TodoView = Backbone.View.extend({
   tagName: 'div',
   className: 'todo',
@@ -23,8 +49,7 @@ var TodoView = Backbone.View.extend({
     if (!options.atEnd) {
         this.$el.find("> .text").focus();
     } else {
-        this.$el.find("> .text").focus();
-        this.$el.find("> .text").val(this.$el.find("> .text"));
+        setEndOfContenteditable(this.$el.find("> .text")[0]);
     }
     return this;
   },
@@ -44,7 +69,6 @@ var TodoView = Backbone.View.extend({
         if (this.model.hasChildren()) {
             return;
         }
-        // TODO: Focus end of previous node
         var previousNode = this.model.previousNode(this.model.collection);
         if (!previousNode) {
             return;
@@ -74,6 +98,7 @@ var TodoView = Backbone.View.extend({
     //  - If there are children, make the new node the first child. Focus the second node.
     // NOTE: Copy-paste is overridden so there can't be more than one line break.
     // NOTE: Shift-enter is overridden and handled seperately, to allow "notes" spanning multiple lines.
+    // NOTE: Line break on empty bullet should shift it up the tree for perfect imitation; this is stupid so I ignored it.
 
      } else if ((lines.length === 2 && lines[1].length === 0) || (lines.length === 3 && lines[1].length === 0 && lines[2].length === 0)) { // Line break at end
         this.model.setText(this.decodeText(lines[0]));
index aafe4636020f85a146c16f9fedcfa9d7f8fa3849..98ddff2ce80d343b58f555a162b9d5c29245f908 100644 (file)
@@ -1,3 +1,29 @@
+function setEndOfContenteditable(contentEditableElement)
+{
+    var range,selection;
+    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
+    {
+        range = document.createRange();//Create a range (a range is a like the selection but invisible)
+        range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
+        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
+        selection = window.getSelection();//get the selection object (allows you to change selection)
+        selection.removeAllRanges();//remove any selections already made
+        selection.addRange(range);//make the range you have just created the visible selection
+    }
+    else if(document.selection)//IE 8 and lower
+    { 
+        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
+        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
+        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
+        range.select();//Select the range (make it the visible selection
+    }
+}
+
+/**
+ * @depend ../library/cursorToEnd.js
+ */
+
+
 var TodoView = Backbone.View.extend({
   tagName: 'div',
   className: 'todo',
@@ -22,8 +48,7 @@ var TodoView = Backbone.View.extend({
     if (!options.atEnd) {
         this.$el.find("> .text").focus();
     } else {
-        this.$el.find("> .text").focus();
-        this.$el.find("> .text").val(this.$el.find("> .text"));
+        setEndOfContenteditable(this.$el.find("> .text")[0]);
     }
     return this;
   },
@@ -43,7 +68,6 @@ var TodoView = Backbone.View.extend({
         if (this.model.hasChildren()) {
             return;
         }
-        // TODO: Focus end of previous node
         var previousNode = this.model.previousNode(this.model.collection);
         if (!previousNode) {
             return;
@@ -73,6 +97,7 @@ var TodoView = Backbone.View.extend({
     //  - If there are children, make the new node the first child. Focus the second node.
     // NOTE: Copy-paste is overridden so there can't be more than one line break.
     // NOTE: Shift-enter is overridden and handled seperately, to allow "notes" spanning multiple lines.
+    // NOTE: Line break on empty bullet should shift it up the tree for perfect imitation; this is stupid so I ignored it.
 
      } else if ((lines.length === 2 && lines[1].length === 0) || (lines.length === 3 && lines[1].length === 0 && lines[2].length === 0)) { // Line break at end
         this.model.setText(this.decodeText(lines[0]));
diff --git a/src/library/cursorToEnd.js b/src/library/cursorToEnd.js
new file mode 100644 (file)
index 0000000..555dc60
--- /dev/null
@@ -0,0 +1,20 @@
+function setEndOfContenteditable(contentEditableElement)
+{
+    var range,selection;
+    if(document.createRange)//Firefox, Chrome, Opera, Safari, IE 9+
+    {
+        range = document.createRange();//Create a range (a range is a like the selection but invisible)
+        range.selectNodeContents(contentEditableElement);//Select the entire contents of the element with the range
+        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
+        selection = window.getSelection();//get the selection object (allows you to change selection)
+        selection.removeAllRanges();//remove any selections already made
+        selection.addRange(range);//make the range you have just created the visible selection
+    }
+    else if(document.selection)//IE 8 and lower
+    { 
+        range = document.body.createTextRange();//Create a range (a range is a like the selection but invisible)
+        range.moveToElementText(contentEditableElement);//Select the entire contents of the element with the range
+        range.collapse(false);//collapse the range to the end point. false means collapse to end rather than the start
+        range.select();//Select the range (make it the visible selection
+    }
+}
index dd66f4cb108838dc393c24002a9776fbadee25cb..119d7f6514f9d8b421f6fd9fbdf9f1cf45ee3ec4 100644 (file)
@@ -1,3 +1,8 @@
+/**
+ * @depend ../library/cursorToEnd.js
+ */
+
+
 var TodoView = Backbone.View.extend({
   tagName: 'div',
   className: 'todo',
@@ -22,8 +27,7 @@ var TodoView = Backbone.View.extend({
     if (!options.atEnd) {
         this.$el.find("> .text").focus();
     } else {
-        this.$el.find("> .text").focus();
-        this.$el.find("> .text").val(this.$el.find("> .text"));
+        setEndOfContenteditable(this.$el.find("> .text")[0]);
     }
     return this;
   },
@@ -43,7 +47,6 @@ var TodoView = Backbone.View.extend({
         if (this.model.hasChildren()) {
             return;
         }
-        // TODO: Focus end of previous node
         var previousNode = this.model.previousNode(this.model.collection);
         if (!previousNode) {
             return;
@@ -73,6 +76,7 @@ var TodoView = Backbone.View.extend({
     //  - If there are children, make the new node the first child. Focus the second node.
     // NOTE: Copy-paste is overridden so there can't be more than one line break.
     // NOTE: Shift-enter is overridden and handled seperately, to allow "notes" spanning multiple lines.
+    // NOTE: Line break on empty bullet should shift it up the tree for perfect imitation; this is stupid so I ignored it.
 
      } else if ((lines.length === 2 && lines[1].length === 0) || (lines.length === 3 && lines[1].length === 0 && lines[2].length === 0)) { // Line break at end
         this.model.setText(this.decodeText(lines[0]));