Skip to content

Commit

Permalink
Merge pull request #7252 from nextcloud/send-comment-on-enter
Browse files Browse the repository at this point in the history
Submit comments with Enter and use Shift+Enter for new lines
  • Loading branch information
MorrisJobke authored Dec 8, 2017
2 parents bb8acc5 + 9b1f3b9 commit 5724e75
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 12 deletions.
8 changes: 6 additions & 2 deletions apps/comments/js/commentstabview.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,9 +530,13 @@
$field.toggleClass('error', limitExceeded);
$submitButton.prop('disabled', limitExceeded);

//submits form on ctrl+Enter or cmd+Enter
if (ev.keyCode === 13 && (ev.ctrlKey || ev.metaKey)) {
// Submits form with Enter, but Shift+Enter is a new line. If the
// autocomplete popover is being shown Enter does not submit the
// form either; it will be handled by At.js which will add the
// currently selected item to the message.
if (ev.keyCode === 13 && !ev.shiftKey && !$field.atwho('isSelecting')) {
$submitButton.click();
ev.preventDefault();
}
},

Expand Down
96 changes: 86 additions & 10 deletions apps/comments/tests/js/commentstabviewSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ describe('OCA.Comments.CommentsTabView tests', function() {
describe('posting comments', function() {
var createStub;
var currentUserStub;
var $newCommentForm;

beforeEach(function() {
view.collection.set(testComments);
Expand All @@ -229,6 +230,8 @@ describe('OCA.Comments.CommentsTabView tests', function() {
displayName: 'Test User'
});

$newCommentForm = view.$el.find('.newCommentForm');

// Required for the absolute selector used to find the new comment
// after a successful creation in _onSubmitSuccess.
$('#testArea').append(view.$el);
Expand All @@ -239,8 +242,23 @@ describe('OCA.Comments.CommentsTabView tests', function() {
});

it('creates a new comment when clicking post button', function() {
view.$el.find('.message').text('New message');
view.$el.find('form').submit();
$newCommentForm.find('.message').text('New message');
$newCommentForm.submit();

expect(createStub.calledOnce).toEqual(true);
expect(createStub.lastCall.args[0]).toEqual({
actorId: 'testuser',
actorDisplayName: 'Test User',
actorType: 'users',
verb: 'comment',
message: 'New message',
creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
});
});
it('creates a new comment when typing enter', function() {
$newCommentForm.find('.message').text('New message');
var keydownEvent = new $.Event('keydown', {keyCode: 13});
$newCommentForm.find('.message').trigger(keydownEvent);

expect(createStub.calledOnce).toEqual(true);
expect(createStub.lastCall.args[0]).toEqual({
Expand All @@ -251,10 +269,68 @@ describe('OCA.Comments.CommentsTabView tests', function() {
message: 'New message',
creationDateTime: new Date(Date.UTC(2016, 1, 3, 10, 5, 9)).toUTCString()
});
expect(keydownEvent.isDefaultPrevented()).toEqual(true);
});
it('creates a new mention when typing enter in the autocomplete popover', function() {
var autoCompleteStub = sinon.stub(view, '_onAutoComplete');
autoCompleteStub.callsArgWith(1, [{"id":"userId", "label":"User Name", "source":"users"}]);

// Force the autocomplete to be initialized
view._initAutoComplete($newCommentForm.find('.message'));

// PhantomJS does not seem to handle typing in a contenteditable, so
// some tricks are needed to show the autocomplete popover.
//
// Instead of sending key events to type "@u" the characters are
// programatically set in the input field.
$newCommentForm.find('.message').text('Mention to @u');

// When focusing on the input field the caret is not guaranteed to
// be at the end; instead of calling "focus()" on the input field
// the caret is explicitly set at the end of the input field, that
// is, after "@u".
var range = document.createRange();
range.selectNodeContents($newCommentForm.find('.message')[0]);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);

// As PhantomJS does not handle typing in a contenteditable the key
// typed here is in practice ignored by At.js, but despite that it
// will cause the popover to be shown.
$newCommentForm.find('.message').trigger(new $.Event('keydown', {keyCode: 's'}));
$newCommentForm.find('.message').trigger(new $.Event('keyup', {keyCode: 's'}));

expect(autoCompleteStub.calledOnce).toEqual(true);

var keydownEvent = new $.Event('keydown', {keyCode: 13});
$newCommentForm.find('.message').trigger(keydownEvent);

expect(createStub.calledOnce).toEqual(false);
expect($newCommentForm.find('.message').html()).toContain('Mention to <span');
expect($newCommentForm.find('.message').html()).toContain('<div class="avatar"');
expect($newCommentForm.find('.message').html()).toContain('<strong>User Name</strong>');
expect($newCommentForm.find('.message').text()).not.toContain('@');
// In this case the default behaviour is prevented by the
// "onKeydown" event handler of At.js.
expect(keydownEvent.isDefaultPrevented()).toEqual(true);
});
it('creates a new line when typing shift+enter', function() {
$newCommentForm.find('.message').text('New message');
var keydownEvent = new $.Event('keydown', {keyCode: 13, shiftKey: true});
$newCommentForm.find('.message').trigger(keydownEvent);

expect(createStub.calledOnce).toEqual(false);
// PhantomJS does not seem to handle typing in a contenteditable, so
// instead of looking for a new line the best that can be done is
// checking that the default behaviour would have been executed.
expect($newCommentForm.find('.message').text()).toContain('New message');
expect(keydownEvent.isDefaultPrevented()).toEqual(false);
});
it('creates a new comment with mentions when clicking post button', function() {
view.$el.find('.message').text('New message @anotheruser');
view.$el.find('form').submit();
$newCommentForm.find('.message').text('New message @anotheruser');
$newCommentForm.submit();

var createStubExpectedData = {
actorId: 'testuser',
Expand Down Expand Up @@ -297,8 +373,8 @@ describe('OCA.Comments.CommentsTabView tests', function() {
expect($message.find('.avatar[data-user=anotheruser] ~ .contactsmenu-popover').length).toEqual(1);
});
it('does not create a comment if the field is empty', function() {
view.$el.find('.message').val(' ');
view.$el.find('form').submit();
$newCommentForm.find('.message').val(' ');
$newCommentForm.submit();

expect(createStub.notCalled).toEqual(true);
});
Expand All @@ -307,8 +383,8 @@ describe('OCA.Comments.CommentsTabView tests', function() {
for (var i = 0; i < view._commentMaxLength * 2; i++) {
bigMessage += 'a';
}
view.$el.find('.message').val(bigMessage);
view.$el.find('form').submit();
$newCommentForm.find('.message').val(bigMessage);
$newCommentForm.submit();

expect(createStub.notCalled).toEqual(true);
});
Expand All @@ -319,8 +395,8 @@ describe('OCA.Comments.CommentsTabView tests', function() {

beforeEach(function() {
tooltipStub = sinon.stub($.fn, 'tooltip');
$message = view.$el.find('.message');
$submitButton = view.$el.find('.submit');
$message = $newCommentForm.find('.message');
$submitButton = $newCommentForm.find('.submit');
});
afterEach(function() {
tooltipStub.restore();
Expand Down

0 comments on commit 5724e75

Please sign in to comment.