diff --git a/app/assets/javascripts/app/views/comment_stream_view.js b/app/assets/javascripts/app/views/comment_stream_view.js
index c6374a301..ec3f126c1 100644
--- a/app/assets/javascripts/app/views/comment_stream_view.js
+++ b/app/assets/javascripts/app/views/comment_stream_view.js
@@ -9,8 +9,8 @@ app.views.CommentStream = app.views.Base.extend({
events: {
"keydown .comment_box": "keyDownOnCommentBox",
"submit form": "createComment",
- "focus .comment_box": "commentTextareaFocused",
- "click .toggle_post_comments": "expandComments"
+ "click .toggle_post_comments": "expandComments",
+ "click form": "openForm"
},
initialize: function() {
@@ -21,6 +21,7 @@ app.views.CommentStream = app.views.Base.extend({
setupBindings: function() {
this.model.comments.bind("add", this.appendComment, this);
this.model.comments.bind("remove", this.removeComment, this);
+ $(document.body).click(this.onFormBlur.bind(this));
},
postRenderTemplate : function() {
@@ -28,6 +29,13 @@ app.views.CommentStream = app.views.Base.extend({
this.commentBox = this.$(".comment_box");
this.commentSubmitButton = this.$("input[name='commit']");
new app.views.CommentMention({el: this.$el, postId: this.model.get("id")});
+
+ this.mdEditor = new Diaspora.MarkdownEditor(this.$(".comment_box"), {
+ onPreview: function($mdInstance) {
+ return "
" + app.helpers.textFormatter($mdInstance.getContent()) + "
";
+ },
+ onFocus: this.openForm.bind(this)
+ });
},
presenter: function(){
@@ -53,11 +61,14 @@ app.views.CommentStream = app.views.Base.extend({
success: function() {
this.commentBox.val("");
this.enableCommentBox();
+ this.mdEditor.hidePreview();
+ this.closeForm();
autosize.update(this.commentBox);
}.bind(this),
error: function() {
this.enableCommentBox();
- this.commentBox.focus();
+ this.mdEditor.hidePreview();
+ this.openForm();
}.bind(this)
});
},
@@ -122,10 +133,6 @@ app.views.CommentStream = app.views.Base.extend({
this.$("#" + comment.get("guid")).closest(".comment.media").remove();
},
- commentTextareaFocused: function(){
- this.$("form").removeClass('hidden').addClass("open");
- },
-
expandComments: function(evt){
this.$(".loading-comments").removeClass("hidden");
if(evt){ evt.preventDefault(); }
@@ -135,6 +142,29 @@ app.views.CommentStream = app.views.Base.extend({
this.$(".loading-comments").addClass("hidden");
}.bind(this)
});
+ },
+
+ openForm: function() {
+ this.$("form").addClass("open");
+ this.$(".md-editor").addClass("active");
+ },
+
+ closeForm: function() {
+ this.$("form").removeClass("open");
+ this.$(".md-editor").removeClass("active");
+ autosize.update(this.commentBox);
+ },
+
+ onFormBlur: function(evt) {
+ if (this.mdEditor !== undefined && this.mdEditor.isPreviewOrTexareaNotEmpty()) {
+ return;
+ }
+
+ var $target = $(evt.target);
+ var isForm = $target.hasClass("new-comment") || $target.parents(".new-comment").length !== 0;
+ if (!isForm && !$target.hasClass("focus_comment_textarea")) {
+ this.closeForm();
+ }
}
});
// @license-end
diff --git a/app/assets/javascripts/app/views/conversations_form_view.js b/app/assets/javascripts/app/views/conversations_form_view.js
index e3b553b7a..54cb86435 100644
--- a/app/assets/javascripts/app/views/conversations_form_view.js
+++ b/app/assets/javascripts/app/views/conversations_form_view.js
@@ -24,6 +24,14 @@ app.views.ConversationsForm = app.views.Base.extend({
remoteRoute: {url: "/contacts", extraParameters: "mutual=true"}
});
+ this.newConversationMdEditor = this.renderMarkdownEditor("#new-message-text");
+
+ // Creates another markdown editor in case of displaying conversation
+ var responseTextarea = $("#conversation-show .conversation-message-text");
+ if (responseTextarea.length === 1) {
+ this.renderMarkdownEditor(responseTextarea);
+ }
+
this.bindTypeaheadEvents();
this.tagListElement.empty();
@@ -31,10 +39,18 @@ app.views.ConversationsForm = app.views.Base.extend({
this.prefill(opts.prefill);
}
- this.$("form#new-conversation").on("ajax:success", this.conversationCreateSuccess);
+ this.$("form#new-conversation").on("ajax:success", this.conversationCreateSuccess.bind(this));
this.$("form#new-conversation").on("ajax:error", this.conversationCreateError);
},
+ renderMarkdownEditor: function(element) {
+ return new Diaspora.MarkdownEditor($(element), {
+ onPreview: function($mdInstance) {
+ return "" + app.helpers.textFormatter($mdInstance.getContent()) + "
";
+ }
+ });
+ },
+
addRecipient: function(person) {
this.conversationRecipients.push(person);
this.updateContactIdsListInput();
@@ -84,6 +100,7 @@ app.views.ConversationsForm = app.views.Base.extend({
},
conversationCreateSuccess: function(evt, data) {
+ this.newConversationMdEditor.hidePreview();
app._changeLocation(Routes.conversation(data.id));
},
diff --git a/app/assets/javascripts/app/views/conversations_inbox_view.js b/app/assets/javascripts/app/views/conversations_inbox_view.js
index 67292cc75..bf8a323e2 100644
--- a/app/assets/javascripts/app/views/conversations_inbox_view.js
+++ b/app/assets/javascripts/app/views/conversations_inbox_view.js
@@ -9,7 +9,7 @@ app.views.ConversationsInbox = app.views.Base.extend({
},
initialize: function() {
- new app.views.ConversationsForm();
+ this.conversationForm = new app.views.ConversationsForm();
this.setupConversation();
},
@@ -23,6 +23,7 @@ app.views.ConversationsInbox = app.views.Base.extend({
self.$el.find("#conversation-show").removeClass("hidden").html(data);
self.selectConversation(conversationId);
self.setupConversation();
+ self.conversationForm.renderMarkdownEditor("#conversation-show .conversation-message-text");
}
});
},
diff --git a/app/assets/javascripts/helpers/markdown_editor.js b/app/assets/javascripts/helpers/markdown_editor.js
index 5706888a1..5de028fec 100644
--- a/app/assets/javascripts/helpers/markdown_editor.js
+++ b/app/assets/javascripts/helpers/markdown_editor.js
@@ -130,6 +130,13 @@ Diaspora.MarkdownEditor.prototype = {
}
},
+ isPreviewOrTexareaNotEmpty: function() {
+ if (this.instance === undefined) {
+ return false;
+ }
+ return (this.instance.$editor.find(".md-preview").length > 0) || (this.instance.getContent().length > 0);
+ },
+
localize: function() {
var locale = Diaspora.I18n.language;
diff --git a/app/assets/javascripts/mobile/mobile_comments.js b/app/assets/javascripts/mobile/mobile_comments.js
index 49858bc1c..0dbfa662f 100644
--- a/app/assets/javascripts/mobile/mobile_comments.js
+++ b/app/assets/javascripts/mobile/mobile_comments.js
@@ -35,7 +35,7 @@
self.scrollToOffset(commentContainer);
});
- this.stream().on("submit", ".new_comment", this.submitComment);
+ this.stream().on("submit", ".new-comment", this.submitComment);
},
submitComment: function(evt){
diff --git a/app/assets/stylesheets/comments.scss b/app/assets/stylesheets/comments.scss
index 4fae714a7..1c111d57f 100644
--- a/app/assets/stylesheets/comments.scss
+++ b/app/assets/stylesheets/comments.scss
@@ -52,7 +52,6 @@
float: right;
}
padding-left: 12px;
- display: none;
}
.comment_box {
height: 35px;
@@ -60,8 +59,6 @@
}
textarea.comment_box:focus, textarea.comment_box:valid, textarea.comment_box:active {
border-color: $border-dark-grey;
- ~ .submit-button { display: block; }
- min-height: 35px;
box-shadow: none;
}
@@ -73,3 +70,16 @@
// scss-lint:enable ImportantRule
}
}
+
+.new-comment {
+ &:not(.open) .submit-button,
+ &:not(.open) .md-header {
+ display: none;
+ }
+
+ // The rule for .md-preview is required until we switch to the newer release of bootstrap-markdown with
+ // the following commit in:
+ // https://github.com/toopay/bootstrap-markdown/commit/14a21c3837140144b27efc19c795d1a37fad70fb
+ .md-preview,
+ &.open .md-editor textarea { min-height: 70px; }
+}
diff --git a/app/assets/stylesheets/conversations.scss b/app/assets/stylesheets/conversations.scss
index 7c0bf90c5..f627e8059 100644
--- a/app/assets/stylesheets/conversations.scss
+++ b/app/assets/stylesheets/conversations.scss
@@ -238,3 +238,9 @@
}
.new-conversation.form-horizontal .form-group:last-of-type { margin-bottom: 0; }
+
+// This rule is required until we switch to the newer release of bootstrap-markdown with
+// the following commit in: https://github.com/toopay/bootstrap-markdown/commit/14a21c3837140144b27efc19c795d1a37fad70fb
+.conversations-form-container .md-preview {
+ min-height: 105px;
+}
diff --git a/app/assets/stylesheets/markdown-editor.scss b/app/assets/stylesheets/markdown-editor.scss
index b077a7b44..462ab2b31 100644
--- a/app/assets/stylesheets/markdown-editor.scss
+++ b/app/assets/stylesheets/markdown-editor.scss
@@ -1,3 +1,18 @@
+.md-editor {
+ border: 1px solid $border-grey;
+ border-radius: $border-radius-small;
+ overflow: hidden;
+
+ &.active { border: 1px solid $border-dark-grey; }
+
+ textarea,
+ textarea:focus {
+ border: 0;
+ box-shadow: none;
+ margin: 0;
+ }
+}
+
.md-footer,
.md-header {
background: $white;
@@ -83,7 +98,6 @@
// scss-lint:disable ImportantRule
height: auto !important;
// scss-lint:enable ImportantRule
- min-height: 90px;
overflow: auto;
position: relative;
// !important is needed to override the CSS rules dynamically added to the element
@@ -91,6 +105,8 @@
width: 100% !important;
// scss-lint:enable ImportantRule
z-index: 10;
+
+ .preview-content { padding: 10px; }
}
.md-controls {
diff --git a/app/assets/stylesheets/publisher.scss b/app/assets/stylesheets/publisher.scss
index 83be3b015..5887a76c4 100644
--- a/app/assets/stylesheets/publisher.scss
+++ b/app/assets/stylesheets/publisher.scss
@@ -78,9 +78,7 @@
textarea {
background: transparent;
border: 0 solid $light-grey;
- box-shadow: none;
height: 50px;
- margin: 0;
resize: none;
}
@@ -193,6 +191,16 @@
margin-bottom: 0;
}
}
+
+ .md-editor,
+ .md-editor.active {
+ border: 0;
+ }
+
+ // This rule is required until we switch to the newer release of bootstrap-markdown with
+ // the following commit in:
+ // https://github.com/toopay/bootstrap-markdown/commit/14a21c3837140144b27efc19c795d1a37fad70fb
+ .md-preview { min-height: 90px; }
}
.publisher-textarea-wrapper {
diff --git a/app/assets/templates/comment-stream_tpl.jst.hbs b/app/assets/templates/comment-stream_tpl.jst.hbs
index cf3bb4652..592cf408b 100644
--- a/app/assets/templates/comment-stream_tpl.jst.hbs
+++ b/app/assets/templates/comment-stream_tpl.jst.hbs
@@ -25,7 +25,8 @@
{{/with}}
- ");
+ var mdEditor = this.target.renderMarkdownEditor("#new-message-text");
+ expect(mdEditor).toEqual(jasmine.any(Diaspora.MarkdownEditor));
+ expect($("#new-message-text")).toHaveClass("md-input");
+ });
});
describe("addRecipient", function() {
@@ -253,6 +275,12 @@ describe("app.views.ConversationsForm", function() {
$("#new-conversation").trigger("ajax:success", [{id: 23}]);
expect(app._changeLocation).toHaveBeenCalledWith(Routes.conversation(23));
});
+
+ it("hides the preview", function() {
+ spyOn(Diaspora.MarkdownEditor.prototype, "hidePreview");
+ $("#new-conversation").trigger("ajax:success", [{id: 23}]);
+ expect(Diaspora.MarkdownEditor.prototype.hidePreview).toHaveBeenCalled();
+ });
});
describe("conversationCreateError", function() {
diff --git a/spec/javascripts/app/views/conversations_inbox_view_spec.js b/spec/javascripts/app/views/conversations_inbox_view_spec.js
index 841f189f0..9de43403b 100644
--- a/spec/javascripts/app/views/conversations_inbox_view_spec.js
+++ b/spec/javascripts/app/views/conversations_inbox_view_spec.js
@@ -34,6 +34,7 @@ describe("app.views.ConversationsInbox", function() {
spyOn($, "ajax").and.callThrough();
spyOn(app.views.ConversationsInbox.prototype, "selectConversation");
spyOn(app.views.ConversationsInbox.prototype, "setupConversation");
+ spyOn(app.views.ConversationsForm.prototype, "renderMarkdownEditor");
this.target.renderConversation(this.conversationId);
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
@@ -44,6 +45,7 @@ describe("app.views.ConversationsInbox", function() {
expect(jasmine.Ajax.requests.mostRecent().url).toBe("/conversations/" + this.conversationId + "/raw");
expect(app.views.ConversationsInbox.prototype.selectConversation).toHaveBeenCalledWith(this.conversationId);
expect(app.views.ConversationsInbox.prototype.setupConversation).toHaveBeenCalled();
+ expect(app.views.ConversationsForm.prototype.renderMarkdownEditor).toHaveBeenCalled();
expect($("#conversation-new")).toHaveClass("hidden");
expect($("#conversation-show")).not.toHaveClass("hidden");
expect($("#conversation-show #fake-conversation-content").length).toBe(1);
diff --git a/spec/javascripts/helpers/markdown_editor_spec.js b/spec/javascripts/helpers/markdown_editor_spec.js
index 9c2ab4cff..d834571b3 100644
--- a/spec/javascripts/helpers/markdown_editor_spec.js
+++ b/spec/javascripts/helpers/markdown_editor_spec.js
@@ -220,6 +220,27 @@ describe("Diaspora.MarkdownEditor", function() {
});
});
+ describe("isPreviewOrTexareaNotEmpty", function() {
+ beforeEach(function() {
+ this.target = new Diaspora.MarkdownEditor(this.$el, {onPreview: $.noop, onPostPreview: $.noop()});
+ });
+
+ it("return false if editor is not visible yet", function() {
+ this.target.instance = undefined;
+ expect(this.target.isPreviewOrTexareaNotEmpty()).toBe(false);
+ });
+
+ it("returns true if editor is in preview mode", function() {
+ this.target.showPreview();
+ expect(this.target.isPreviewOrTexareaNotEmpty()).toBe(true);
+ });
+
+ it("returns true if editor has content", function() {
+ $("textarea").text("Yolo");
+ expect(this.target.isPreviewOrTexareaNotEmpty()).toBe(true);
+ });
+ });
+
describe("localize", function() {
beforeEach(function() {
this.target = new Diaspora.MarkdownEditor(this.$el, {});
diff --git a/spec/javascripts/mobile/mobile_comments_spec.js b/spec/javascripts/mobile/mobile_comments_spec.js
index e87a81adc..af12f644c 100644
--- a/spec/javascripts/mobile/mobile_comments_spec.js
+++ b/spec/javascripts/mobile/mobile_comments_spec.js
@@ -10,7 +10,7 @@ describe("Diaspora.Mobile.Comments", function(){
spyOn(Diaspora.Mobile.Comments, "submitComment").and.returnValue(false);
Diaspora.Mobile.Comments.initialize();
Diaspora.Mobile.Comments.showCommentBox($(".stream .comment-action").first());
- $(".stream .new_comment").first().submit();
+ $(".stream .new-comment").first().submit();
expect(Diaspora.Mobile.Comments.submitComment).toHaveBeenCalled();
});
});
@@ -97,28 +97,28 @@ describe("Diaspora.Mobile.Comments", function(){
});
it("doesn't submit an empty comment", function() {
- $(".stream .new_comment").first().submit();
+ $(".stream .new-comment").first().submit();
expect(jasmine.Ajax.requests.count()).toBe(0);
});
it("submits comments with text", function() {
- $(".stream .new_comment textarea").val("comment text");
- $(".stream .new_comment").first().submit();
+ $(".stream .new-comment textarea").val("comment text");
+ $(".stream .new-comment").first().submit();
expect(jasmine.Ajax.requests.mostRecent().data().text).toEqual(["comment text"]);
});
it("calls updateStream on success", function() {
spyOn(Diaspora.Mobile.Comments, "updateStream");
- $(".stream .new_comment textarea").val("comment text");
- $(".stream .new_comment").first().submit();
+ $(".stream .new-comment textarea").val("comment text");
+ $(".stream .new-comment").first().submit();
jasmine.Ajax.requests.mostRecent().respondWith({status: 200, responseText: "foo"});
- expect(Diaspora.Mobile.Comments.updateStream).toHaveBeenCalledWith($(".stream .new_comment").first(), "foo");
+ expect(Diaspora.Mobile.Comments.updateStream).toHaveBeenCalledWith($(".stream .new-comment").first(), "foo");
});
it("lets Diaspora.Mobile.Alert handle AJAX errors", function() {
spyOn(Diaspora.Mobile.Alert, "handleAjaxError");
- $(".stream .new_comment textarea").val("comment text");
- $(".stream .new_comment").first().submit();
+ $(".stream .new-comment textarea").val("comment text");
+ $(".stream .new-comment").first().submit();
jasmine.Ajax.requests.mostRecent().respondWith({status: 400, responseText: "oh noez! comment failed!"});
expect(Diaspora.Mobile.Alert.handleAjaxError).toHaveBeenCalled();
expect(Diaspora.Mobile.Alert.handleAjaxError.calls.argsFor(0)[0].responseText).toBe("oh noez! comment failed!");
@@ -126,10 +126,10 @@ describe("Diaspora.Mobile.Comments", function(){
it("calls resetCommentBox on errors", function() {
spyOn(Diaspora.Mobile.Comments, "resetCommentBox");
- $(".stream .new_comment textarea").val("comment text");
- $(".stream .new_comment").first().submit();
+ $(".stream .new-comment textarea").val("comment text");
+ $(".stream .new-comment").first().submit();
jasmine.Ajax.requests.mostRecent().respondWith({status: 400, responseText: "oh noez! comment failed!"});
- expect(Diaspora.Mobile.Comments.resetCommentBox).toHaveBeenCalledWith($(".stream .new_comment").first());
+ expect(Diaspora.Mobile.Comments.resetCommentBox).toHaveBeenCalledWith($(".stream .new-comment").first());
});
});