From: Zachary Vance Date: Thu, 14 May 2015 04:06:52 +0000 (-0700) Subject: Keep focus in correct place when combining lines X-Git-Url: https://git.za3k.com/?a=commitdiff_plain;h=8b333bbb5d9fd0c84dbc09dda746c43a1efb85a8;p=flowy.git Keep focus in correct place when combining lines --- diff --git a/dist/flowy.js b/dist/flowy.js index bf81f86..87a4d5f 100644 --- a/dist/flowy.js +++ b/dist/flowy.js @@ -45,6 +45,21 @@ function getCaretPosition(editableDiv) { return caretPos; } +function setRangeAtMarker(markerElement, options) { + options = options || {}; + if (window.getSelection && document.createRange) { + var range = document.createRange(); + range.setStartBefore(markerElement); + range.setEndBefore(markerElement); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + if (options.remove) { + markerElement.parentNode.removeChild(markerElement); + } +} + /** * @depend ../library/cursorToEnd.js */ @@ -71,10 +86,17 @@ var TodoView = Backbone.View.extend({ }, startEditingText: function(options) { options = options || {}; - if (!options.atEnd) { - this.$el.find("> .text").focus(); - } else { + if (options.atEnd) { setEndOfContenteditable(this.$el.find("> .text")[0]); + } else if (options.atMarker) { + var marker = this.$el.find("> .text").find(options.atMarker)[0]; + if (!marker) { + console.log("Marker not found"); + return; + } + setRangeAtMarker(marker, {"remove": true}); + } else { + this.$el.find("> .text").focus(); } return this; }, @@ -99,18 +121,17 @@ var TodoView = Backbone.View.extend({ if (!previousNode) { return; } - if (this.model.get("text") === "") { // Or focus is at the beginning + if (this.model.get("text") === "") { e.preventDefault(); this.model.remove(this.model.collection); previousNode.getView().startEditingText({"atEnd":true}); - } else if (this.isFocusAtBeginning()) { + } else if (this.isFocusAtBeginning() && e.keyCode !== 8 /* backspace only */) { e.preventDefault(); var text = this.model.get("text"); this.model.remove(this.model.collection); - // TODO: Keep focus between the two halves - // var focusReminderElement = this.$("") - previousNode.setText(previousNode.get("text")/* + focusReminderElement*/ + text); - previousNode.getView().startEditingText(/*{"atMarker": focusReminderElement}*/); + var focusReminderElement = $(''); + previousNode.setText(previousNode.get("text") + '' + text); + previousNode.getView().startEditingText({"atMarker": ".focus"}); } }, textChange: function(e) { @@ -160,7 +181,7 @@ var TodoView = Backbone.View.extend({ } return this; }, - template: "
{{text}}
", + template: "
{{{text}}}
", addChild: function(el, position) { if(typeof position === 'undefined' || position === -1) { console.log("TodoView:addChild called without a position"); diff --git a/dist/flowy.unwrapped.js b/dist/flowy.unwrapped.js index ff2a6ac..4cf5f15 100644 --- a/dist/flowy.unwrapped.js +++ b/dist/flowy.unwrapped.js @@ -44,6 +44,21 @@ function getCaretPosition(editableDiv) { return caretPos; } +function setRangeAtMarker(markerElement, options) { + options = options || {}; + if (window.getSelection && document.createRange) { + var range = document.createRange(); + range.setStartBefore(markerElement); + range.setEndBefore(markerElement); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + if (options.remove) { + markerElement.parentNode.removeChild(markerElement); + } +} + /** * @depend ../library/cursorToEnd.js */ @@ -70,10 +85,17 @@ var TodoView = Backbone.View.extend({ }, startEditingText: function(options) { options = options || {}; - if (!options.atEnd) { - this.$el.find("> .text").focus(); - } else { + if (options.atEnd) { setEndOfContenteditable(this.$el.find("> .text")[0]); + } else if (options.atMarker) { + var marker = this.$el.find("> .text").find(options.atMarker)[0]; + if (!marker) { + console.log("Marker not found"); + return; + } + setRangeAtMarker(marker, {"remove": true}); + } else { + this.$el.find("> .text").focus(); } return this; }, @@ -98,18 +120,17 @@ var TodoView = Backbone.View.extend({ if (!previousNode) { return; } - if (this.model.get("text") === "") { // Or focus is at the beginning + if (this.model.get("text") === "") { e.preventDefault(); this.model.remove(this.model.collection); previousNode.getView().startEditingText({"atEnd":true}); - } else if (this.isFocusAtBeginning()) { + } else if (this.isFocusAtBeginning() && e.keyCode !== 8 /* backspace only */) { e.preventDefault(); var text = this.model.get("text"); this.model.remove(this.model.collection); - // TODO: Keep focus between the two halves - // var focusReminderElement = this.$("") - previousNode.setText(previousNode.get("text")/* + focusReminderElement*/ + text); - previousNode.getView().startEditingText(/*{"atMarker": focusReminderElement}*/); + var focusReminderElement = $(''); + previousNode.setText(previousNode.get("text") + '' + text); + previousNode.getView().startEditingText({"atMarker": ".focus"}); } }, textChange: function(e) { @@ -159,7 +180,7 @@ var TodoView = Backbone.View.extend({ } return this; }, - template: "
{{text}}
", + template: "
{{{text}}}
", addChild: function(el, position) { if(typeof position === 'undefined' || position === -1) { console.log("TodoView:addChild called without a position"); diff --git a/src/library/cursorToEnd.js b/src/library/cursorToEnd.js index cddf800..fae7948 100644 --- a/src/library/cursorToEnd.js +++ b/src/library/cursorToEnd.js @@ -43,3 +43,18 @@ function getCaretPosition(editableDiv) { } return caretPos; } + +function setRangeAtMarker(markerElement, options) { + options = options || {}; + if (window.getSelection && document.createRange) { + var range = document.createRange(); + range.setStartBefore(markerElement); + range.setEndBefore(markerElement); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + if (options.remove) { + markerElement.parentNode.removeChild(markerElement); + } +} diff --git a/src/views/todo.js b/src/views/todo.js index e2ff583..979d998 100644 --- a/src/views/todo.js +++ b/src/views/todo.js @@ -24,10 +24,17 @@ var TodoView = Backbone.View.extend({ }, startEditingText: function(options) { options = options || {}; - if (!options.atEnd) { - this.$el.find("> .text").focus(); - } else { + if (options.atEnd) { setEndOfContenteditable(this.$el.find("> .text")[0]); + } else if (options.atMarker) { + var marker = this.$el.find("> .text").find(options.atMarker)[0]; + if (!marker) { + console.log("Marker not found"); + return; + } + setRangeAtMarker(marker, {"remove": true}); + } else { + this.$el.find("> .text").focus(); } return this; }, @@ -52,18 +59,17 @@ var TodoView = Backbone.View.extend({ if (!previousNode) { return; } - if (this.model.get("text") === "") { // Or focus is at the beginning + if (this.model.get("text") === "") { e.preventDefault(); this.model.remove(this.model.collection); previousNode.getView().startEditingText({"atEnd":true}); - } else if (this.isFocusAtBeginning()) { + } else if (this.isFocusAtBeginning() && e.keyCode !== 8 /* backspace only */) { e.preventDefault(); var text = this.model.get("text"); this.model.remove(this.model.collection); - // TODO: Keep focus between the two halves - // var focusReminderElement = this.$("") - previousNode.setText(previousNode.get("text")/* + focusReminderElement*/ + text); - previousNode.getView().startEditingText(/*{"atMarker": focusReminderElement}*/); + var focusReminderElement = $(''); + previousNode.setText(previousNode.get("text") + '' + text); + previousNode.getView().startEditingText({"atMarker": ".focus"}); } }, textChange: function(e) { @@ -113,7 +119,7 @@ var TodoView = Backbone.View.extend({ } return this; }, - template: "
{{text}}
", + template: "
{{{text}}}
", addChild: function(el, position) { if(typeof position === 'undefined' || position === -1) { console.log("TodoView:addChild called without a position");