},
addObject: function(element, type, options) {
var manager = this;
+ if (!element) {
+ console.log("addObject called with no element");
+ return;
+ }
object = {
element:element,
type:type,
} );
}, 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) {
'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',
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;
}
},
_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() {
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;
}
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();
},
addObject: function(element, type, options) {
var manager = this;
+ if (!element) {
+ console.log("addObject called with no element");
+ return;
+ }
object = {
element:element,
type:type,
} );
}, 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) {
'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',
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;
}
},
_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() {
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;
}
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();
},
addObject: function(element, type, options) {
var manager = this;
+ if (!element) {
+ console.log("addObject called with no element");
+ return;
+ }
object = {
element:element,
type:type,
} );
}, 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) {
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();
'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',
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;
}
},
_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() {
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;
}