From 881403ddb3f6b739778e69a226ab02e400c1a835 Mon Sep 17 00:00:00 2001 From: Zachary Vance Date: Fri, 22 May 2015 19:05:45 -0700 Subject: [PATCH] Add fake versions of all shortcuts, make 'delete' key at end of line work --- dist/flowy.css | 2 +- dist/flowy.js | 69 +++++++++++++++++++++++++++++++++++------ dist/flowy.unwrapped.js | 69 +++++++++++++++++++++++++++++++++++------ src/css/flowy.less | 2 +- src/library/shortcut.js | 4 +-- src/views/app.js | 16 +++++++++- src/views/todo.js | 49 ++++++++++++++++++++++++----- 7 files changed, 179 insertions(+), 32 deletions(-) diff --git a/dist/flowy.css b/dist/flowy.css index 1ae3cd2..7cdb9fd 100644 --- a/dist/flowy.css +++ b/dist/flowy.css @@ -39,7 +39,7 @@ body { position: fixed; bottom: -2px; left: 10px; - width: 200px; + width: 230px; background: #ffffff; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.6); } diff --git a/dist/flowy.js b/dist/flowy.js index 0542e72..ddb473c 100644 --- a/dist/flowy.js +++ b/dist/flowy.js @@ -281,7 +281,7 @@ var Shortcut = (function(document, _) { displayMultiple: true, // Display multiple shortcuts or just the canonical one? allowRebind: false, // Insert javascript to allow rebinding shortcuts highlightRepeats: true, // Warn about shortcuts which are bound to multiple actions (if user can remap shortcuts) // TODO - shortcuts: _.sortBy(this.shortcuts, 'description'), + shortcuts: this.shortcuts,//_.sortBy(this.shortcuts, 'description'), noDisplay: [], // ids not to display includeElement: true, }); @@ -308,7 +308,7 @@ var Shortcut = (function(document, _) { var keybindingHTML = _.map(keybindings, function(keybinding) { return _.template("<%= keybinding %>")({keybinding: _.escape(keybinding)}); - }).join("
"); + }).join(",
"); if (options.allowRebind) { // Ugh, way too magic, how do I use an actual function here return _.template('
<%= keybindingHTML %>
')({ @@ -401,11 +401,19 @@ var TodoView = Backbone.View.extend({ "input > .text": "textChange", "blur > .text": "render", // Because the model shouldn't update the view during active editing, add a re-render at the end "keydown > .text": "keydown", - 'Shortcut("toggleComplete", "Complete", "ctrl+enter") > .text': "toggleComplete", - 'Shortcut("backspace", "Combine an item with the previous item", "backspace") > .text': "backspace", - 'Shortcut("delete", "Combine an item with the next item", "del") > .text': "delete", + 'Shortcut("combinePrevious", "Combine an item with the previous item", "backspace") > .text': "combinePrevious", + 'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext", 'Shortcut("next", "Next", "down") > .text': 'next', 'Shortcut("previous", "Previous", "up") > .text': 'previous', + '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', + 'Shortcut("indent", "Not Done - Indent", "tab,alt+shift+right") > .text': 'indent', + 'Shortcut("outdent", "Not Done - Outdent", "shift+tab,alt+shift+left") > .text': 'outdent', + 'Shortcut("moveDown", "Not Done - Move", "alt+shift+down") > .text': 'moveDown', + 'Shortcut("moveUp", "Not Done - Move", "alt+shift+up") > .text': 'moveUp', + 'Shortcut("toggleComplete", "Complete", "ctrl+enter") > .text': "toggleComplete", + 'Shortcut("delete", "Not Done - Delete", "ctrl+shift+del") > .text': 'delete', }, initialize: function() { this.childViewPositions = []; @@ -436,7 +444,7 @@ var TodoView = Backbone.View.extend({ return getCaretPosition(this.$el.find("> .text")[0]) === 0; }, isFocusAtEnd: function() { - return false; // TODO + return getCaretPosition(this.$el.find("> .text")[0]) === this.$el.find("> .text").text().length; }, decodeText: function(encodedText) { return $("
").html(encodedText).text(); @@ -469,7 +477,7 @@ var TodoView = Backbone.View.extend({ previousNode.getView().startEditingText(); return false; }, - backspace: function() { + combinePrevious: function() { if (this.model.hasChildren()) { return; } @@ -489,7 +497,7 @@ var TodoView = Backbone.View.extend({ return false; } }, - "delete": function(e) { + combineNext: function(e) { if (this.model.hasChildren()) { return; } @@ -510,6 +518,30 @@ var TodoView = Backbone.View.extend({ return false; } }, + "delete": function() { + console.log("Delete not implemented"); // TODO + }, + indent: function() { + console.log("Indent not implemented"); // TODO + }, + outdent: function() { + console.log("Outdent not implemented"); // TODO + }, + expand: function() { + console.log("Expand not implemented"); // TODO + }, + zoomIn: function() { + console.log("Zoom not implemented"); // TODO + }, + zoomOut: function() { + console.log("Zoom not implemented"); // TODO + }, + moveDown: function() { + console.log("Move not implemented"); // TODO + }, + moveUp: function() { + console.log("Move not implemented"); // TODO + }, textChange: function(e) { var collection = this.model.collection; var lines = $(e.target).html().split(//); @@ -531,7 +563,10 @@ var TodoView = Backbone.View.extend({ // 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[0] === "" && lines[1] === "") || (lines.length === 3 && lines[0] === "" && lines[1] === "" && lines[2] === "")) { // Enter pressed on empty line + this.model.setText(this.decodeText(lines[0])); + this.stopEditingText(); + this.outdent(); } 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])); var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection); // Child or not depending on whether this has children @@ -815,6 +850,11 @@ var appDefaults = { list: todos }; var AppView = Backbone.View.extend({ el: $("#todo-app"), shortcutObject: "global", + events: { + 'Shortcut("toggleShortcuts", "Keyboard Shortcuts", "ctrl+?") > .text': 'toggleShortcuts', + 'Shortcut("toggleShowCompleted", "Not Done - Show/hide completed", "ctrl+o") > .text': 'toggleShowCompleted', + 'Shortcut("search", "Not Done - Search", "esc") > .text': 'search', + }, initialize: function(options) { options = _.defaults({}, options, appDefaults); this.list = options.list || new FlowyDocModel(); @@ -832,7 +872,7 @@ var AppView = Backbone.View.extend({ e.save(); }); }); - Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['backspace', 'delete', 'next', 'previous'] }); + Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous'] }); this.views = {}; // A list of views for each element in the collection this.list.fetch(); this.render(); @@ -843,6 +883,15 @@ var AppView = Backbone.View.extend({ addOne: function(todo) { this.renderTodo(todo); }, + toggleShortcuts: function() { + this.$(".shortcuts").toggle(); + }, + toggleShowCompleted: function() { + console.log("Toggling show/hide not yet implemented"); // TODO + }, + search: function() { + console.log("Search not yet implemented"); // TODO + }, renderTodo: function(todo) { if (this.getView(todo)) { console.log("View rendered more than once for todo #" + todo.id); diff --git a/dist/flowy.unwrapped.js b/dist/flowy.unwrapped.js index 7aa1761..7f61de8 100644 --- a/dist/flowy.unwrapped.js +++ b/dist/flowy.unwrapped.js @@ -280,7 +280,7 @@ var Shortcut = (function(document, _) { displayMultiple: true, // Display multiple shortcuts or just the canonical one? allowRebind: false, // Insert javascript to allow rebinding shortcuts highlightRepeats: true, // Warn about shortcuts which are bound to multiple actions (if user can remap shortcuts) // TODO - shortcuts: _.sortBy(this.shortcuts, 'description'), + shortcuts: this.shortcuts,//_.sortBy(this.shortcuts, 'description'), noDisplay: [], // ids not to display includeElement: true, }); @@ -307,7 +307,7 @@ var Shortcut = (function(document, _) { var keybindingHTML = _.map(keybindings, function(keybinding) { return _.template("<%= keybinding %>")({keybinding: _.escape(keybinding)}); - }).join("
"); + }).join(",
"); if (options.allowRebind) { // Ugh, way too magic, how do I use an actual function here return _.template('
<%= keybindingHTML %>
')({ @@ -400,11 +400,19 @@ var TodoView = Backbone.View.extend({ "input > .text": "textChange", "blur > .text": "render", // Because the model shouldn't update the view during active editing, add a re-render at the end "keydown > .text": "keydown", - 'Shortcut("toggleComplete", "Complete", "ctrl+enter") > .text': "toggleComplete", - 'Shortcut("backspace", "Combine an item with the previous item", "backspace") > .text': "backspace", - 'Shortcut("delete", "Combine an item with the next item", "del") > .text': "delete", + 'Shortcut("combinePrevious", "Combine an item with the previous item", "backspace") > .text': "combinePrevious", + 'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext", 'Shortcut("next", "Next", "down") > .text': 'next', 'Shortcut("previous", "Previous", "up") > .text': 'previous', + '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', + 'Shortcut("indent", "Not Done - Indent", "tab,alt+shift+right") > .text': 'indent', + 'Shortcut("outdent", "Not Done - Outdent", "shift+tab,alt+shift+left") > .text': 'outdent', + 'Shortcut("moveDown", "Not Done - Move", "alt+shift+down") > .text': 'moveDown', + 'Shortcut("moveUp", "Not Done - Move", "alt+shift+up") > .text': 'moveUp', + 'Shortcut("toggleComplete", "Complete", "ctrl+enter") > .text': "toggleComplete", + 'Shortcut("delete", "Not Done - Delete", "ctrl+shift+del") > .text': 'delete', }, initialize: function() { this.childViewPositions = []; @@ -435,7 +443,7 @@ var TodoView = Backbone.View.extend({ return getCaretPosition(this.$el.find("> .text")[0]) === 0; }, isFocusAtEnd: function() { - return false; // TODO + return getCaretPosition(this.$el.find("> .text")[0]) === this.$el.find("> .text").text().length; }, decodeText: function(encodedText) { return $("
").html(encodedText).text(); @@ -468,7 +476,7 @@ var TodoView = Backbone.View.extend({ previousNode.getView().startEditingText(); return false; }, - backspace: function() { + combinePrevious: function() { if (this.model.hasChildren()) { return; } @@ -488,7 +496,7 @@ var TodoView = Backbone.View.extend({ return false; } }, - "delete": function(e) { + combineNext: function(e) { if (this.model.hasChildren()) { return; } @@ -509,6 +517,30 @@ var TodoView = Backbone.View.extend({ return false; } }, + "delete": function() { + console.log("Delete not implemented"); // TODO + }, + indent: function() { + console.log("Indent not implemented"); // TODO + }, + outdent: function() { + console.log("Outdent not implemented"); // TODO + }, + expand: function() { + console.log("Expand not implemented"); // TODO + }, + zoomIn: function() { + console.log("Zoom not implemented"); // TODO + }, + zoomOut: function() { + console.log("Zoom not implemented"); // TODO + }, + moveDown: function() { + console.log("Move not implemented"); // TODO + }, + moveUp: function() { + console.log("Move not implemented"); // TODO + }, textChange: function(e) { var collection = this.model.collection; var lines = $(e.target).html().split(//); @@ -530,7 +562,10 @@ var TodoView = Backbone.View.extend({ // 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[0] === "" && lines[1] === "") || (lines.length === 3 && lines[0] === "" && lines[1] === "" && lines[2] === "")) { // Enter pressed on empty line + this.model.setText(this.decodeText(lines[0])); + this.stopEditingText(); + this.outdent(); } 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])); var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection); // Child or not depending on whether this has children @@ -814,6 +849,11 @@ var appDefaults = { list: todos }; var AppView = Backbone.View.extend({ el: $("#todo-app"), shortcutObject: "global", + events: { + 'Shortcut("toggleShortcuts", "Keyboard Shortcuts", "ctrl+?") > .text': 'toggleShortcuts', + 'Shortcut("toggleShowCompleted", "Not Done - Show/hide completed", "ctrl+o") > .text': 'toggleShowCompleted', + 'Shortcut("search", "Not Done - Search", "esc") > .text': 'search', + }, initialize: function(options) { options = _.defaults({}, options, appDefaults); this.list = options.list || new FlowyDocModel(); @@ -831,7 +871,7 @@ var AppView = Backbone.View.extend({ e.save(); }); }); - Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['backspace', 'delete', 'next', 'previous'] }); + Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous'] }); this.views = {}; // A list of views for each element in the collection this.list.fetch(); this.render(); @@ -842,6 +882,15 @@ var AppView = Backbone.View.extend({ addOne: function(todo) { this.renderTodo(todo); }, + toggleShortcuts: function() { + this.$(".shortcuts").toggle(); + }, + toggleShowCompleted: function() { + console.log("Toggling show/hide not yet implemented"); // TODO + }, + search: function() { + console.log("Search not yet implemented"); // TODO + }, renderTodo: function(todo) { if (this.getView(todo)) { console.log("View rendered more than once for todo #" + todo.id); diff --git a/src/css/flowy.less b/src/css/flowy.less index 9092e00..617e7ae 100644 --- a/src/css/flowy.less +++ b/src/css/flowy.less @@ -48,7 +48,7 @@ body { position: fixed; bottom: -2px; left: 10px; - width: 200px; + width: 230px; background: #ffffff; .with-dropshadow; .title { diff --git a/src/library/shortcut.js b/src/library/shortcut.js index a5bf946..8c97dbd 100644 --- a/src/library/shortcut.js +++ b/src/library/shortcut.js @@ -219,7 +219,7 @@ var Shortcut = (function(document, _) { displayMultiple: true, // Display multiple shortcuts or just the canonical one? allowRebind: false, // Insert javascript to allow rebinding shortcuts highlightRepeats: true, // Warn about shortcuts which are bound to multiple actions (if user can remap shortcuts) // TODO - shortcuts: _.sortBy(this.shortcuts, 'description'), + shortcuts: this.shortcuts,//_.sortBy(this.shortcuts, 'description'), noDisplay: [], // ids not to display includeElement: true, }); @@ -246,7 +246,7 @@ var Shortcut = (function(document, _) { var keybindingHTML = _.map(keybindings, function(keybinding) { return _.template("<%= keybinding %>")({keybinding: _.escape(keybinding)}); - }).join("
"); + }).join(",
"); if (options.allowRebind) { // Ugh, way too magic, how do I use an actual function here return _.template('
<%= keybindingHTML %>
')({ diff --git a/src/views/app.js b/src/views/app.js index ee325d8..dc92050 100644 --- a/src/views/app.js +++ b/src/views/app.js @@ -62,6 +62,11 @@ var appDefaults = { list: todos }; var AppView = Backbone.View.extend({ el: $("#todo-app"), shortcutObject: "global", + events: { + 'Shortcut("toggleShortcuts", "Keyboard Shortcuts", "ctrl+?") > .text': 'toggleShortcuts', + 'Shortcut("toggleShowCompleted", "Not Done - Show/hide completed", "ctrl+o") > .text': 'toggleShowCompleted', + 'Shortcut("search", "Not Done - Search", "esc") > .text': 'search', + }, initialize: function(options) { options = _.defaults({}, options, appDefaults); this.list = options.list || new FlowyDocModel(); @@ -79,7 +84,7 @@ var AppView = Backbone.View.extend({ e.save(); }); }); - Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['backspace', 'delete', 'next', 'previous'] }); + Shortcut.bindShortcutsDisplay(this.$("#shortcuts-wrapper")[0], {allowRebind: true, noDisplay: ['combineNext', 'combinePrevious', 'next', 'previous'] }); this.views = {}; // A list of views for each element in the collection this.list.fetch(); this.render(); @@ -90,6 +95,15 @@ var AppView = Backbone.View.extend({ addOne: function(todo) { this.renderTodo(todo); }, + toggleShortcuts: function() { + this.$(".shortcuts").toggle(); + }, + toggleShowCompleted: function() { + console.log("Toggling show/hide not yet implemented"); // TODO + }, + search: function() { + console.log("Search not yet implemented"); // TODO + }, renderTodo: function(todo) { if (this.getView(todo)) { console.log("View rendered more than once for todo #" + todo.id); diff --git a/src/views/todo.js b/src/views/todo.js index e4be2e5..91fd153 100644 --- a/src/views/todo.js +++ b/src/views/todo.js @@ -11,11 +11,19 @@ var TodoView = Backbone.View.extend({ "input > .text": "textChange", "blur > .text": "render", // Because the model shouldn't update the view during active editing, add a re-render at the end "keydown > .text": "keydown", - 'Shortcut("toggleComplete", "Complete", "ctrl+enter") > .text': "toggleComplete", - 'Shortcut("backspace", "Combine an item with the previous item", "backspace") > .text': "backspace", - 'Shortcut("delete", "Combine an item with the next item", "del") > .text': "delete", + 'Shortcut("combinePrevious", "Combine an item with the previous item", "backspace") > .text': "combinePrevious", + 'Shortcut("combineNext", "Combine an item with the next item", "del") > .text': "combineNext", 'Shortcut("next", "Next", "down") > .text': 'next', 'Shortcut("previous", "Previous", "up") > .text': 'previous', + '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', + 'Shortcut("indent", "Not Done - Indent", "tab,alt+shift+right") > .text': 'indent', + 'Shortcut("outdent", "Not Done - Outdent", "shift+tab,alt+shift+left") > .text': 'outdent', + 'Shortcut("moveDown", "Not Done - Move", "alt+shift+down") > .text': 'moveDown', + 'Shortcut("moveUp", "Not Done - Move", "alt+shift+up") > .text': 'moveUp', + 'Shortcut("toggleComplete", "Complete", "ctrl+enter") > .text': "toggleComplete", + 'Shortcut("delete", "Not Done - Delete", "ctrl+shift+del") > .text': 'delete', }, initialize: function() { this.childViewPositions = []; @@ -46,7 +54,7 @@ var TodoView = Backbone.View.extend({ return getCaretPosition(this.$el.find("> .text")[0]) === 0; }, isFocusAtEnd: function() { - return false; // TODO + return getCaretPosition(this.$el.find("> .text")[0]) === this.$el.find("> .text").text().length; }, decodeText: function(encodedText) { return $("
").html(encodedText).text(); @@ -79,7 +87,7 @@ var TodoView = Backbone.View.extend({ previousNode.getView().startEditingText(); return false; }, - backspace: function() { + combinePrevious: function() { if (this.model.hasChildren()) { return; } @@ -99,7 +107,7 @@ var TodoView = Backbone.View.extend({ return false; } }, - "delete": function(e) { + combineNext: function(e) { if (this.model.hasChildren()) { return; } @@ -120,6 +128,30 @@ var TodoView = Backbone.View.extend({ return false; } }, + "delete": function() { + console.log("Delete not implemented"); // TODO + }, + indent: function() { + console.log("Indent not implemented"); // TODO + }, + outdent: function() { + console.log("Outdent not implemented"); // TODO + }, + expand: function() { + console.log("Expand not implemented"); // TODO + }, + zoomIn: function() { + console.log("Zoom not implemented"); // TODO + }, + zoomOut: function() { + console.log("Zoom not implemented"); // TODO + }, + moveDown: function() { + console.log("Move not implemented"); // TODO + }, + moveUp: function() { + console.log("Move not implemented"); // TODO + }, textChange: function(e) { var collection = this.model.collection; var lines = $(e.target).html().split(//); @@ -141,7 +173,10 @@ var TodoView = Backbone.View.extend({ // 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[0] === "" && lines[1] === "") || (lines.length === 3 && lines[0] === "" && lines[1] === "" && lines[2] === "")) { // Enter pressed on empty line + this.model.setText(this.decodeText(lines[0])); + this.stopEditingText(); + this.outdent(); } 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])); var emptyAfter = this.model.addTodoAfter({text: this.decodeText(lines[1])}, collection); // Child or not depending on whether this has children -- 2.47.3