Fix shortcuts after changing streams

This commit is contained in:
Steffen van Bergerem 2015-10-05 22:07:57 +02:00 committed by Jonne Haß
parent c5819b9c57
commit 25e4d8c365
5 changed files with 32 additions and 61 deletions

View file

@ -92,6 +92,7 @@ app.Router = Backbone.Router.extend({
app.stream.fetch(); app.stream.fetch();
app.page = new app.views.Stream({model : app.stream}); app.page = new app.views.Stream({model : app.stream});
app.publisher = app.publisher || new app.views.Publisher({collection : app.stream.items}); app.publisher = app.publisher || new app.views.Publisher({collection : app.stream.items});
app.shortcuts = app.shortcuts || new app.views.StreamShortcuts({el: $(document)});
var streamFacesView = new app.views.StreamFaces({collection : app.stream.items}); var streamFacesView = new app.views.StreamFaces({collection : app.stream.items});

View file

@ -1,21 +1,11 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
app.views.StreamShortcuts = { app.views.StreamShortcuts = Backbone.View.extend({
_headerSize: 50, _headerSize: 50,
events: {
setupShortcuts : function() { "keydown": "_onHotkeyDown",
$(document).on('keydown', _.bind(this._onHotkeyDown, this)); "keyup": "_onHotkeyUp"
$(document).on('keyup', _.bind(this._onHotkeyUp, this));
this.on('hotkey:gotoNext', this.gotoNext, this);
this.on('hotkey:gotoPrev', this.gotoPrev, this);
this.on('hotkey:likeSelected', this.likeSelected, this);
this.on('hotkey:commentSelected', this.commentSelected, this);
this.on('hotkey:reshareSelected', this.reshareSelected, this);
this.on('hotkey:expandSelected', this.expandSelected, this);
this.on('hotkey:openFirstLinkSelected', this.openFirstLinkSelected, this);
}, },
_onHotkeyDown: function(event) { _onHotkeyDown: function(event) {
@ -28,10 +18,10 @@ app.views.StreamShortcuts = {
// trigger the events based on what key was pressed // trigger the events based on what key was pressed
switch (String.fromCharCode( event.which ).toLowerCase()) { switch (String.fromCharCode( event.which ).toLowerCase()) {
case "j": case "j":
this.trigger('hotkey:gotoNext'); this.gotoNext();
break; break;
case "k": case "k":
this.trigger('hotkey:gotoPrev'); this.gotoPrev();
break; break;
default: default:
} }
@ -47,19 +37,19 @@ app.views.StreamShortcuts = {
// trigger the events based on what key was pressed // trigger the events based on what key was pressed
switch (String.fromCharCode( event.which ).toLowerCase()) { switch (String.fromCharCode( event.which ).toLowerCase()) {
case "c": case "c":
this.trigger('hotkey:commentSelected'); this.commentSelected();
break; break;
case "l": case "l":
this.trigger('hotkey:likeSelected'); this.likeSelected();
break; break;
case "r": case "r":
this.trigger('hotkey:reshareSelected'); this.reshareSelected();
break; break;
case "m": case "m":
this.trigger('hotkey:expandSelected'); this.expandSelected();
break; break;
case "o": case "o":
this.trigger('hotkey:openFirstLinkSelected'); this.openFirstLinkSelected();
break; break;
default: default:
} }
@ -132,6 +122,5 @@ app.views.StreamShortcuts = {
//add the selection and selected-class to new post //add the selection and selected-class to new post
element.className+=" shortcut_selected highlighted"; element.className+=" shortcut_selected highlighted";
}, },
}; });
// @license-end // @license-end

View file

@ -1,10 +1,7 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
//= require ./stream/shortcuts app.views.Stream = app.views.InfScroll.extend({
app.views.Stream = app.views.InfScroll.extend(_.extend(
app.views.StreamShortcuts, {
initialize: function() { initialize: function() {
this.stream = this.model; this.stream = this.model;
this.collection = this.stream.items; this.collection = this.stream.items;
@ -14,7 +11,6 @@ app.views.Stream = app.views.InfScroll.extend(_.extend(
this.setupNSFW(); this.setupNSFW();
this.setupLightbox(); this.setupLightbox();
this.setupInfiniteScroll(); this.setupInfiniteScroll();
this.setupShortcuts();
this.markNavSelected(); this.markNavSelected();
}, },
@ -38,5 +34,5 @@ app.views.Stream = app.views.InfScroll.extend(_.extend(
streamSelection.find("[data-stream]").removeClass("selected"); streamSelection.find("[data-stream]").removeClass("selected");
streamSelection.find("[data-stream='" + activeStream + "']").addClass("selected"); streamSelection.find("[data-stream='" + activeStream + "']").addClass("selected");
} }
})); });
// @license-end // @license-end

View file

@ -22,6 +22,19 @@ Feature: Keyboard navigation
Then post 2 should be highlighted Then post 2 should be highlighted
And I close the publisher And I close the publisher
Scenario: navigate downwards after changing the stream
When I go to the activity stream page
And I click on selector "[data-stream='stream'] a"
Then I should see "Stream" within ".stream_title"
When I press the "J" key somewhere
Then post 1 should be highlighted
And I should have navigated to the highlighted post
When I press the "J" key somewhere
Then post 2 should be highlighted
And I should have navigated to the highlighted post
Scenario: navigate upwards Scenario: navigate upwards
When I scroll to post 3 When I scroll to post 3
And I press the "K" key somewhere And I press the "K" key somewhere

View file

@ -6,25 +6,16 @@ describe("app.views.StreamShortcuts", function () {
this.stream = new app.models.Stream(); this.stream = new app.models.Stream();
this.stream.add([this.post1, this.post2]); this.stream.add([this.post1, this.post2]);
this.view = new app.views.Stream({model : this.stream}); this.streamView = new app.views.Stream({model : this.stream});
spec.content().html(this.streamView.render().el);
this.view = new app.views.StreamShortcuts({el: $(document)});
this.view.render(); expect(spec.content().find("div.stream_element.loaded").length).toBe(2);
expect(this.view.$('div.stream_element.loaded').length).toBe(2);
});
describe("loading the stream", function(){
it("should setup the shortcuts", function(){
spyOn(this.view, 'setupShortcuts');
this.view.initialize();
expect(this.view.setupShortcuts).toHaveBeenCalled();
});
}); });
describe("pressing 'j'", function(){ describe("pressing 'j'", function(){
it("should call 'gotoNext' if not pressed in an input field", function(){ it("should call 'gotoNext' if not pressed in an input field", function(){
spyOn(this.view, 'gotoNext'); spyOn(this.view, 'gotoNext');
this.view.initialize();
var e = $.Event("keydown", { which: 74, target: {type: "div"} }); var e = $.Event("keydown", { which: 74, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('j'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('j');
@ -41,7 +32,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'gotoNext'); spyOn(this.view, 'gotoNext');
spyOn(this.view, 'selectPost'); spyOn(this.view, 'selectPost');
this.view.initialize();
var e = $.Event("keydown", { which: 74, target: {type: "textarea"} }); var e = $.Event("keydown", { which: 74, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('j'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('j');
@ -52,10 +42,8 @@ describe("app.views.StreamShortcuts", function () {
}); });
describe("pressing 'k'", function(){ describe("pressing 'k'", function(){
it("should call 'gotoPrev' if not pressed in an input field", function(){ it("should call 'gotoPrev' if not pressed in an input field", function(){
spyOn(this.view, 'gotoPrev'); spyOn(this.view, 'gotoPrev');
this.view.initialize();
var e = $.Event("keydown", { which: 75, target: {type: "div"} }); var e = $.Event("keydown", { which: 75, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('k'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('k');
@ -72,7 +60,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'gotoPrev'); spyOn(this.view, 'gotoPrev');
spyOn(this.view, 'selectPost'); spyOn(this.view, 'selectPost');
this.view.initialize();
var e = $.Event("keydown", { which: 75, target: {type: "textarea"} }); var e = $.Event("keydown", { which: 75, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('k'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('k');
@ -83,10 +70,8 @@ describe("app.views.StreamShortcuts", function () {
}); });
describe("pressing 'c'", function(){ describe("pressing 'c'", function(){
it("should click on the comment-button if not pressed in an input field", function(){ it("should click on the comment-button if not pressed in an input field", function(){
spyOn(this.view, 'commentSelected'); spyOn(this.view, 'commentSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 67, target: {type: "div"} }); var e = $.Event("keyup", { which: 67, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('c'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('c');
@ -96,7 +81,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'commentSelected'); spyOn(this.view, 'commentSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 67, target: {type: "textarea"} }); var e = $.Event("keyup", { which: 67, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('c'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('c');
@ -106,10 +90,8 @@ describe("app.views.StreamShortcuts", function () {
}); });
describe("pressing 'l'", function(){ describe("pressing 'l'", function(){
it("should click on the like-button if not pressed in an input field", function(){ it("should click on the like-button if not pressed in an input field", function(){
spyOn(this.view, 'likeSelected'); spyOn(this.view, 'likeSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 76, target: {type: "div"} }); var e = $.Event("keyup", { which: 76, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('l'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('l');
@ -119,7 +101,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'likeSelected'); spyOn(this.view, 'likeSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 76, target: {type: "textarea"} }); var e = $.Event("keyup", { which: 76, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('l'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('l');
@ -129,10 +110,8 @@ describe("app.views.StreamShortcuts", function () {
}); });
describe("pressing 'r'", function(){ describe("pressing 'r'", function(){
it("should click on the reshare-button if not pressed in an input field", function(){ it("should click on the reshare-button if not pressed in an input field", function(){
spyOn(this.view, 'reshareSelected'); spyOn(this.view, 'reshareSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 82, target: {type: "div"} }); var e = $.Event("keyup", { which: 82, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('r'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('r');
@ -142,7 +121,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'reshareSelected'); spyOn(this.view, 'reshareSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 82, target: {type: "textarea"} }); var e = $.Event("keyup", { which: 82, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('r'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('r');
@ -152,10 +130,8 @@ describe("app.views.StreamShortcuts", function () {
}); });
describe("pressing 'm'", function(){ describe("pressing 'm'", function(){
it("should click on the more-button if not pressed in an input field", function(){ it("should click on the more-button if not pressed in an input field", function(){
spyOn(this.view, 'expandSelected'); spyOn(this.view, 'expandSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 77, target: {type: "div"} }); var e = $.Event("keyup", { which: 77, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('m'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('m');
@ -165,7 +141,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'expandSelected'); spyOn(this.view, 'expandSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 77, target: {type: "textarea"} }); var e = $.Event("keyup", { which: 77, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('m'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('m');
@ -175,10 +150,8 @@ describe("app.views.StreamShortcuts", function () {
}); });
describe("pressing 'o'", function(){ describe("pressing 'o'", function(){
it("should click on the more-button if not pressed in an input field", function(){ it("should click on the more-button if not pressed in an input field", function(){
spyOn(this.view, 'openFirstLinkSelected'); spyOn(this.view, 'openFirstLinkSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 79, target: {type: "div"} }); var e = $.Event("keyup", { which: 79, target: {type: "div"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('o'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('o');
@ -188,7 +161,6 @@ describe("app.views.StreamShortcuts", function () {
it("shouldn't do anything if the user types in an input field", function(){ it("shouldn't do anything if the user types in an input field", function(){
spyOn(this.view, 'openFirstLinkSelected'); spyOn(this.view, 'openFirstLinkSelected');
this.view.initialize();
var e = $.Event("keyup", { which: 79, target: {type: "textarea"} }); var e = $.Event("keyup", { which: 79, target: {type: "textarea"} });
//verify that the test is correct //verify that the test is correct
expect(String.fromCharCode( e.which ).toLowerCase()).toBe('o'); expect(String.fromCharCode( e.which ).toLowerCase()).toBe('o');