Loading Changelog.md +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ Note: Although this is a minor release, the configuration file changed because t * Refactored post interactions on the single post view [#7089](https://github.com/diaspora/diaspora/pull/7089) * Extract inline JavaScript [#7113](https://github.com/diaspora/diaspora/pull/7113) * Port conversations inbox to backbone.js [#7108](https://github.com/diaspora/diaspora/pull/7108) * Refactored stream shortcuts for more flexibility [#7127](https://github.com/diaspora/diaspora/pull/7127) ## Bug fixes * Post comments no longer get collapsed when interacting with a post [#7040](https://github.com/diaspora/diaspora/pull/7040) Loading app/assets/javascripts/app/helpers/shortcuts.js 0 → 100644 +31 −0 Original line number Diff line number Diff line // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later (function() { app.helpers.Shortcuts = function(evtname, fn) { var textAcceptingInputTypes = [ "color", "date", "datetime", "datetime-local", "email", "month", "number", "password", "range", "search", "select", "text", "textarea", "time", "url", "week" ]; $("body").on(evtname, function(event) { // make sure that the user is not typing in an input field if (textAcceptingInputTypes.indexOf(event.target.type) === -1) { fn(event); } }); }; })(); // @license-end app/assets/javascripts/app/views/stream/shortcuts.js +3 −15 Original line number Diff line number Diff line Loading @@ -3,18 +3,12 @@ app.views.StreamShortcuts = Backbone.View.extend({ _headerSize: 60, events: { "keydown": "_onHotkeyDown", "keyup": "_onHotkeyUp" initialize: function() { app.helpers.Shortcuts("keydown", this._onHotkeyDown.bind(this)); app.helpers.Shortcuts("keyup", this._onHotkeyUp.bind(this)); }, _onHotkeyDown: function(event) { //make sure that the user is not typing in an input field var textAcceptingInputTypes = ["textarea", "select", "text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color"]; if(jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1){ return; } // trigger the events based on what key was pressed switch (String.fromCharCode( event.which ).toLowerCase()) { case "j": Loading @@ -28,12 +22,6 @@ app.views.StreamShortcuts = Backbone.View.extend({ }, _onHotkeyUp: function(event) { //make sure that the user is not typing in an input field var textAcceptingInputTypes = ["textarea", "select", "text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color"]; if(jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1){ return; } // trigger the events based on what key was pressed switch (String.fromCharCode( event.which ).toLowerCase()) { case "c": Loading spec/javascripts/app/helpers/shortcuts_spec.js 0 → 100644 +17 −0 Original line number Diff line number Diff line describe("app.helpers.Shortcuts", function() { it("calls the function when the event has been fired outside of an input field", function() { var spy = jasmine.createSpy(); spec.content().append("<div class='hotkey-div'></div>"); app.helpers.Shortcuts("keydown", spy); $(".hotkey-div").trigger("keydown"); expect(spy).toHaveBeenCalled(); }); it("doesn't call the function when the event has been fired in an input field", function() { var spy = jasmine.createSpy(); spec.content().append("<textarea class='hotkey-textarea'></textarea>"); app.helpers.Shortcuts("keydown", spy); $(".hotkey-textarea").trigger("keydown"); expect(spy).not.toHaveBeenCalled(); }); }); spec/javascripts/app/views/stream/shortcuts_spec.js +58 −94 Original line number Diff line number Diff line Loading @@ -13,131 +13,95 @@ describe("app.views.StreamShortcuts", function () { expect(spec.content().find("div.stream-element.loaded").length).toBe(2); }); describe("pressing 'j'", function(){ it("should call 'gotoNext' if not pressed in an input field", function(){ spyOn(this.view, 'gotoNext'); describe("initialize", function() { it("setups the shortcuts", function() { spyOn(app.helpers, "Shortcuts").and.callThrough(); spyOn(app.views.StreamShortcuts.prototype, "_onHotkeyDown"); spyOn(app.views.StreamShortcuts.prototype, "_onHotkeyUp"); this.view = new app.views.StreamShortcuts({el: $(document)}); expect(app.helpers.Shortcuts.calls.count()).toBe(2); $("body").trigger($.Event("keydown", {which: Keycodes.J, target: {type: "textarea"}})); $("body").trigger($.Event("keyup", {which: Keycodes.J, target: {type: "textarea"}})); expect(app.views.StreamShortcuts.prototype._onHotkeyDown).not.toHaveBeenCalled(); expect(app.views.StreamShortcuts.prototype._onHotkeyUp).not.toHaveBeenCalled(); var e = $.Event("keydown", {which: Keycodes.J, target: {type: "div"}}); this.view._onHotkeyDown(e); expect(this.view.gotoNext).toHaveBeenCalled(); }); $("body").trigger(e); expect(app.views.StreamShortcuts.prototype._onHotkeyDown).toHaveBeenCalledWith(e); it("'gotoNext' should call 'selectPost'", function(){ spyOn(this.view, 'selectPost'); this.view.gotoNext(); expect(this.view.selectPost).toHaveBeenCalled(); e = $.Event("keyup", {which: Keycodes.J, target: {type: "div"}}); $("body").trigger(e); expect(app.views.StreamShortcuts.prototype._onHotkeyUp).toHaveBeenCalledWith(e); }); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'gotoNext'); spyOn(this.view, 'selectPost'); var e = $.Event("keydown", { which: Keycodes.J, target: {type: "textarea"} }); describe("_onHotkeyDown", function() { it("calls goToNext when the user pressed 'J'", function() { spyOn(this.view, "gotoNext"); var e = $.Event("keydown", {which: Keycodes.J, target: {type: "div"}}); this.view._onHotkeyDown(e); expect(this.view.gotoNext).not.toHaveBeenCalled(); expect(this.view.selectPost).not.toHaveBeenCalled(); }); expect(this.view.gotoNext).toHaveBeenCalled(); }); describe("pressing 'k'", function(){ it("should call 'gotoPrev' if not pressed in an input field", function(){ spyOn(this.view, 'gotoPrev'); it("calls gotoPrev when the user pressed 'K'", function() { spyOn(this.view, "gotoPrev"); var e = $.Event("keydown", {which: Keycodes.K, target: {type: "div"}}); this.view._onHotkeyDown(e); expect(this.view.gotoPrev).toHaveBeenCalled(); }); it("'gotoPrev' should call 'selectPost'", function(){ spyOn(this.view, 'selectPost'); this.view.gotoPrev(); expect(this.view.selectPost).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'gotoPrev'); spyOn(this.view, 'selectPost'); var e = $.Event("keydown", { which: Keycodes.K, target: {type: "textarea"} }); this.view._onHotkeyDown(e); expect(this.view.gotoPrev).not.toHaveBeenCalled(); expect(this.view.selectPost).not.toHaveBeenCalled(); }); }); describe("pressing 'c'", function(){ it("should click on the comment-button if not pressed in an input field", function(){ spyOn(this.view, 'commentSelected'); describe("_onHotkeyUp", function() { it("calls commentSelected when the user pressed 'C'", function() { spyOn(this.view, "commentSelected"); var e = $.Event("keyup", {which: Keycodes.C, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.commentSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'commentSelected'); var e = $.Event("keyup", { which: Keycodes.C, target: {type: "textarea"} }); this.view._onHotkeyUp(e); expect(this.view.commentSelected).not.toHaveBeenCalled(); }); }); describe("pressing 'l'", function(){ it("should click on the like-button if not pressed in an input field", function(){ spyOn(this.view, 'likeSelected'); it("calls likeSelected when the user pressed 'L'", function() { spyOn(this.view, "likeSelected"); var e = $.Event("keyup", {which: Keycodes.L, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.likeSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'likeSelected'); var e = $.Event("keyup", { which: Keycodes.L, target: {type: "textarea"} }); it("calls expandSelected when the user pressed 'M'", function() { spyOn(this.view, "expandSelected"); var e = $.Event("keyup", {which: Keycodes.M, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.likeSelected).not.toHaveBeenCalled(); }); expect(this.view.expandSelected).toHaveBeenCalled(); }); describe("pressing 'r'", function(){ it("should click on the reshare-button if not pressed in an input field", function(){ spyOn(this.view, 'reshareSelected'); var e = $.Event("keyup", { which: Keycodes.R, target: {type: "div"} }); it("calls openFirstLinkSelected when the user pressed 'O'", function() { spyOn(this.view, "openFirstLinkSelected"); var e = $.Event("keyup", {which: Keycodes.O, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.reshareSelected).toHaveBeenCalled(); expect(this.view.openFirstLinkSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'reshareSelected'); var e = $.Event("keyup", { which: Keycodes.R, target: {type: "textarea"} }); it("calls reshareSelected when the user pressed 'R'", function() { spyOn(this.view, "reshareSelected"); var e = $.Event("keyup", {which: Keycodes.R, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.reshareSelected).not.toHaveBeenCalled(); }); expect(this.view.reshareSelected).toHaveBeenCalled(); }); describe("pressing 'm'", function(){ it("should click on the more-button if not pressed in an input field", function(){ spyOn(this.view, 'expandSelected'); var e = $.Event("keyup", { which: Keycodes.M, target: {type: "div"} }); this.view._onHotkeyUp(e); expect(this.view.expandSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'expandSelected'); var e = $.Event("keyup", { which: Keycodes.M, target: {type: "textarea"} }); this.view._onHotkeyUp(e); expect(this.view.expandSelected).not.toHaveBeenCalled(); }); describe("gotoNext", function() { it("calls selectPost", function() { spyOn(this.view, "selectPost"); this.view.gotoNext(); expect(this.view.selectPost).toHaveBeenCalled(); }); describe("pressing 'o'", function(){ it("should click on the more-button if not pressed in an input field", function(){ spyOn(this.view, 'openFirstLinkSelected'); var e = $.Event("keyup", { which: Keycodes.O, target: {type: "div"} }); this.view._onHotkeyUp(e); expect(this.view.openFirstLinkSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'openFirstLinkSelected'); var e = $.Event("keyup", { which: Keycodes.O, target: {type: "textarea"} }); this.view._onHotkeyUp(e); expect(this.view.openFirstLinkSelected).not.toHaveBeenCalled(); describe("gotoPrev", function() { it("calls selectPost", function() { spyOn(this.view, "selectPost"); this.view.gotoPrev(); expect(this.view.selectPost).toHaveBeenCalled(); }); }); }); Loading
Changelog.md +1 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ Note: Although this is a minor release, the configuration file changed because t * Refactored post interactions on the single post view [#7089](https://github.com/diaspora/diaspora/pull/7089) * Extract inline JavaScript [#7113](https://github.com/diaspora/diaspora/pull/7113) * Port conversations inbox to backbone.js [#7108](https://github.com/diaspora/diaspora/pull/7108) * Refactored stream shortcuts for more flexibility [#7127](https://github.com/diaspora/diaspora/pull/7127) ## Bug fixes * Post comments no longer get collapsed when interacting with a post [#7040](https://github.com/diaspora/diaspora/pull/7040) Loading
app/assets/javascripts/app/helpers/shortcuts.js 0 → 100644 +31 −0 Original line number Diff line number Diff line // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later (function() { app.helpers.Shortcuts = function(evtname, fn) { var textAcceptingInputTypes = [ "color", "date", "datetime", "datetime-local", "email", "month", "number", "password", "range", "search", "select", "text", "textarea", "time", "url", "week" ]; $("body").on(evtname, function(event) { // make sure that the user is not typing in an input field if (textAcceptingInputTypes.indexOf(event.target.type) === -1) { fn(event); } }); }; })(); // @license-end
app/assets/javascripts/app/views/stream/shortcuts.js +3 −15 Original line number Diff line number Diff line Loading @@ -3,18 +3,12 @@ app.views.StreamShortcuts = Backbone.View.extend({ _headerSize: 60, events: { "keydown": "_onHotkeyDown", "keyup": "_onHotkeyUp" initialize: function() { app.helpers.Shortcuts("keydown", this._onHotkeyDown.bind(this)); app.helpers.Shortcuts("keyup", this._onHotkeyUp.bind(this)); }, _onHotkeyDown: function(event) { //make sure that the user is not typing in an input field var textAcceptingInputTypes = ["textarea", "select", "text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color"]; if(jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1){ return; } // trigger the events based on what key was pressed switch (String.fromCharCode( event.which ).toLowerCase()) { case "j": Loading @@ -28,12 +22,6 @@ app.views.StreamShortcuts = Backbone.View.extend({ }, _onHotkeyUp: function(event) { //make sure that the user is not typing in an input field var textAcceptingInputTypes = ["textarea", "select", "text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color"]; if(jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1){ return; } // trigger the events based on what key was pressed switch (String.fromCharCode( event.which ).toLowerCase()) { case "c": Loading
spec/javascripts/app/helpers/shortcuts_spec.js 0 → 100644 +17 −0 Original line number Diff line number Diff line describe("app.helpers.Shortcuts", function() { it("calls the function when the event has been fired outside of an input field", function() { var spy = jasmine.createSpy(); spec.content().append("<div class='hotkey-div'></div>"); app.helpers.Shortcuts("keydown", spy); $(".hotkey-div").trigger("keydown"); expect(spy).toHaveBeenCalled(); }); it("doesn't call the function when the event has been fired in an input field", function() { var spy = jasmine.createSpy(); spec.content().append("<textarea class='hotkey-textarea'></textarea>"); app.helpers.Shortcuts("keydown", spy); $(".hotkey-textarea").trigger("keydown"); expect(spy).not.toHaveBeenCalled(); }); });
spec/javascripts/app/views/stream/shortcuts_spec.js +58 −94 Original line number Diff line number Diff line Loading @@ -13,131 +13,95 @@ describe("app.views.StreamShortcuts", function () { expect(spec.content().find("div.stream-element.loaded").length).toBe(2); }); describe("pressing 'j'", function(){ it("should call 'gotoNext' if not pressed in an input field", function(){ spyOn(this.view, 'gotoNext'); describe("initialize", function() { it("setups the shortcuts", function() { spyOn(app.helpers, "Shortcuts").and.callThrough(); spyOn(app.views.StreamShortcuts.prototype, "_onHotkeyDown"); spyOn(app.views.StreamShortcuts.prototype, "_onHotkeyUp"); this.view = new app.views.StreamShortcuts({el: $(document)}); expect(app.helpers.Shortcuts.calls.count()).toBe(2); $("body").trigger($.Event("keydown", {which: Keycodes.J, target: {type: "textarea"}})); $("body").trigger($.Event("keyup", {which: Keycodes.J, target: {type: "textarea"}})); expect(app.views.StreamShortcuts.prototype._onHotkeyDown).not.toHaveBeenCalled(); expect(app.views.StreamShortcuts.prototype._onHotkeyUp).not.toHaveBeenCalled(); var e = $.Event("keydown", {which: Keycodes.J, target: {type: "div"}}); this.view._onHotkeyDown(e); expect(this.view.gotoNext).toHaveBeenCalled(); }); $("body").trigger(e); expect(app.views.StreamShortcuts.prototype._onHotkeyDown).toHaveBeenCalledWith(e); it("'gotoNext' should call 'selectPost'", function(){ spyOn(this.view, 'selectPost'); this.view.gotoNext(); expect(this.view.selectPost).toHaveBeenCalled(); e = $.Event("keyup", {which: Keycodes.J, target: {type: "div"}}); $("body").trigger(e); expect(app.views.StreamShortcuts.prototype._onHotkeyUp).toHaveBeenCalledWith(e); }); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'gotoNext'); spyOn(this.view, 'selectPost'); var e = $.Event("keydown", { which: Keycodes.J, target: {type: "textarea"} }); describe("_onHotkeyDown", function() { it("calls goToNext when the user pressed 'J'", function() { spyOn(this.view, "gotoNext"); var e = $.Event("keydown", {which: Keycodes.J, target: {type: "div"}}); this.view._onHotkeyDown(e); expect(this.view.gotoNext).not.toHaveBeenCalled(); expect(this.view.selectPost).not.toHaveBeenCalled(); }); expect(this.view.gotoNext).toHaveBeenCalled(); }); describe("pressing 'k'", function(){ it("should call 'gotoPrev' if not pressed in an input field", function(){ spyOn(this.view, 'gotoPrev'); it("calls gotoPrev when the user pressed 'K'", function() { spyOn(this.view, "gotoPrev"); var e = $.Event("keydown", {which: Keycodes.K, target: {type: "div"}}); this.view._onHotkeyDown(e); expect(this.view.gotoPrev).toHaveBeenCalled(); }); it("'gotoPrev' should call 'selectPost'", function(){ spyOn(this.view, 'selectPost'); this.view.gotoPrev(); expect(this.view.selectPost).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'gotoPrev'); spyOn(this.view, 'selectPost'); var e = $.Event("keydown", { which: Keycodes.K, target: {type: "textarea"} }); this.view._onHotkeyDown(e); expect(this.view.gotoPrev).not.toHaveBeenCalled(); expect(this.view.selectPost).not.toHaveBeenCalled(); }); }); describe("pressing 'c'", function(){ it("should click on the comment-button if not pressed in an input field", function(){ spyOn(this.view, 'commentSelected'); describe("_onHotkeyUp", function() { it("calls commentSelected when the user pressed 'C'", function() { spyOn(this.view, "commentSelected"); var e = $.Event("keyup", {which: Keycodes.C, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.commentSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'commentSelected'); var e = $.Event("keyup", { which: Keycodes.C, target: {type: "textarea"} }); this.view._onHotkeyUp(e); expect(this.view.commentSelected).not.toHaveBeenCalled(); }); }); describe("pressing 'l'", function(){ it("should click on the like-button if not pressed in an input field", function(){ spyOn(this.view, 'likeSelected'); it("calls likeSelected when the user pressed 'L'", function() { spyOn(this.view, "likeSelected"); var e = $.Event("keyup", {which: Keycodes.L, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.likeSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'likeSelected'); var e = $.Event("keyup", { which: Keycodes.L, target: {type: "textarea"} }); it("calls expandSelected when the user pressed 'M'", function() { spyOn(this.view, "expandSelected"); var e = $.Event("keyup", {which: Keycodes.M, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.likeSelected).not.toHaveBeenCalled(); }); expect(this.view.expandSelected).toHaveBeenCalled(); }); describe("pressing 'r'", function(){ it("should click on the reshare-button if not pressed in an input field", function(){ spyOn(this.view, 'reshareSelected'); var e = $.Event("keyup", { which: Keycodes.R, target: {type: "div"} }); it("calls openFirstLinkSelected when the user pressed 'O'", function() { spyOn(this.view, "openFirstLinkSelected"); var e = $.Event("keyup", {which: Keycodes.O, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.reshareSelected).toHaveBeenCalled(); expect(this.view.openFirstLinkSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'reshareSelected'); var e = $.Event("keyup", { which: Keycodes.R, target: {type: "textarea"} }); it("calls reshareSelected when the user pressed 'R'", function() { spyOn(this.view, "reshareSelected"); var e = $.Event("keyup", {which: Keycodes.R, target: {type: "div"}}); this.view._onHotkeyUp(e); expect(this.view.reshareSelected).not.toHaveBeenCalled(); }); expect(this.view.reshareSelected).toHaveBeenCalled(); }); describe("pressing 'm'", function(){ it("should click on the more-button if not pressed in an input field", function(){ spyOn(this.view, 'expandSelected'); var e = $.Event("keyup", { which: Keycodes.M, target: {type: "div"} }); this.view._onHotkeyUp(e); expect(this.view.expandSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'expandSelected'); var e = $.Event("keyup", { which: Keycodes.M, target: {type: "textarea"} }); this.view._onHotkeyUp(e); expect(this.view.expandSelected).not.toHaveBeenCalled(); }); describe("gotoNext", function() { it("calls selectPost", function() { spyOn(this.view, "selectPost"); this.view.gotoNext(); expect(this.view.selectPost).toHaveBeenCalled(); }); describe("pressing 'o'", function(){ it("should click on the more-button if not pressed in an input field", function(){ spyOn(this.view, 'openFirstLinkSelected'); var e = $.Event("keyup", { which: Keycodes.O, target: {type: "div"} }); this.view._onHotkeyUp(e); expect(this.view.openFirstLinkSelected).toHaveBeenCalled(); }); it("shouldn't do anything if the user types in an input field", function(){ spyOn(this.view, 'openFirstLinkSelected'); var e = $.Event("keyup", { which: Keycodes.O, target: {type: "textarea"} }); this.view._onHotkeyUp(e); expect(this.view.openFirstLinkSelected).not.toHaveBeenCalled(); describe("gotoPrev", function() { it("calls selectPost", function() { spyOn(this.view, "selectPost"); this.view.gotoPrev(); expect(this.view.selectPost).toHaveBeenCalled(); }); }); });