summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-11-15 23:17:34 -0500
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-11-15 23:17:34 -0500
commit9ce190aeb919b675ec9e3a3485018b7e8f7ca1bd (patch)
treef369de90240920916532488b9697c38c93f573a0
parent2889f326334a23196dbf283d4c8e6fdb044df954 (diff)
downloadaskbot-9ce190aeb919b675ec9e3a3485018b7e8f7ca1bd.tar.gz
askbot-9ce190aeb919b675ec9e3a3485018b7e8f7ca1bd.tar.bz2
askbot-9ce190aeb919b675ec9e3a3485018b7e8f7ca1bd.zip
edit comment form shows signs of life
-rw-r--r--askbot/skins/default/media/js/post.js83
-rw-r--r--askbot/skins/default/media/js/utils.js12
-rw-r--r--askbot/skins/default/templates/base.html1
-rw-r--r--askbot/skins/default/templates/question.html621
-rw-r--r--askbot/urls.py10
-rw-r--r--askbot/utils/http.py34
-rw-r--r--askbot/views/readers.py19
-rw-r--r--askbot/views/writers.py2
8 files changed, 443 insertions, 339 deletions
diff --git a/askbot/skins/default/media/js/post.js b/askbot/skins/default/media/js/post.js
index acc63d5c..e809886c 100644
--- a/askbot/skins/default/media/js/post.js
+++ b/askbot/skins/default/media/js/post.js
@@ -891,14 +891,17 @@ var EditCommentForm = function(){
this._comment_widget = null;
this._element = null;
this._text = '';
+ this._id = 'edit-comment-form';
};
inherits(EditCommentForm, WrappedElement);
-EditCommentForm.prototype.setComment = function(comment, text){
+EditCommentForm.prototype.getElement = function(){
+ EditCommentForm.superClass_.getElement.call(this);
+ this._textarea.val(this._text);
+ return this._element;
};
EditCommentForm.prototype.attachTo = function(comment){
- var form = editCommentForm.setComment(comment);
this._comment = comment;
this._comment_widget = comment.getContainerWidget();
this._text = comment.getText();
@@ -906,7 +909,8 @@ EditCommentForm.prototype.attachTo = function(comment){
comment.getElement().hide();
this._comment_widget.hideButton();
this.getElement().show();
- this._textarea.focus();
+ this.focus();
+ putCursorAtEnd(this._textarea);
};
EditCommentForm.prototype.makeCounterUpdater = function(){
@@ -935,13 +939,14 @@ EditCommentForm.prototype.canCancel = function(){
if (this._element === null){
return true;
}
- if ($.trim(this._textarea.val()) == ''){
+ var ctext = $.trim(this._textarea.val());
+ if (ctext == this._text){
return true;
}
else if (this.confirmAbandon()){
return true;
}
- this._textarea.focus();
+ this.focus();
return false;
}
@@ -978,6 +983,7 @@ EditCommentForm.prototype.createDom = function(){
var div = $('<div></div>');
this._textarea = $('<textarea></textarea>');
+ this._textarea.attr('id', this._id);
this._element.append(div);
@@ -1002,6 +1008,7 @@ EditCommentForm.prototype.createDom = function(){
.focus(update_counter)
.keyup(update_counter)
.keyup(escape_handler);
+ this._textarea.val(this._text);
setupFormValidation(
this._element,
@@ -1023,12 +1030,22 @@ EditCommentForm.prototype.disableButtons = function(){
EditCommentForm.prototype.reset = function(){
this._comment = null;
+ this._text = '';
this._textarea.val('');
};
EditCommentForm.prototype.confirmAbandon = function(){
+ this.focus();
+ debugger;
+ this._textarea.addClass('highlight');
+ var answer = confirm($.i18n._('confirm abandon comment'));
+ this._textarea.removeClass('highlight');
+ return answer;
+};
+
+EditCommentForm.prototype.focus = function(){
this._textarea.focus();
- return confirm($.i18n._('confirm abandon comment'));
+ window.location.hash = this._id;
};
EditCommentForm.prototype.save = function(){
@@ -1047,7 +1064,7 @@ EditCommentForm.prototype.save = function(){
this.disableButtons();
- $.ajax({
+ /*$.ajax({
type: "POST",
url: post_url,
dataType: "json",
@@ -1068,7 +1085,12 @@ EditCommentForm.prototype.save = function(){
showMessage(this._element, xhr.responseText);
this.enableButtons();
}
- });
+ });*/
+};
+
+EditCommentForm.prototype.editComment = function(comment){
+ this.detach();
+ this.attachTo(comment);
};
//a single instance to reuse
@@ -1077,7 +1099,7 @@ var editCommentForm = new EditCommentForm();
var Comment = function(widget, data){
WrappedElement.call(this);
this._container_widget = widget;
- this._data = data;
+ this._data = data || {};
this._blank = true;//set to false by setContent
this._element = null;
this._delete_prompt = $.i18n._('delete this comment');
@@ -1110,23 +1132,33 @@ Comment.prototype.decorate = function(element){
this._element.mouseover(function(){edit_link.getElement().show()});
this._element.mouseout(function(){edit_link.getElement().hide()});
}
+ this._blank = false;
};
Comment.prototype.isBlank = function(){
return this._blank;
};
+Comment.prototype.hasContent = function(){
+ return ('id' in this._data);
+ //shortcut for 'user_url' 'html' 'user_display_name' 'comment_age'
+};
+
+Comment.prototype.hasText = function(){
+ return ('text' in this._data);
+}
+
Comment.prototype.getContainerWidget = function(){
return this._container_widget;
};
Comment.prototype.setContent = function(data){
- this._data = data;
+ this._data = data || this._data;
this._element.html('');
this._element.attr('class', 'comment');
this._element.attr('id', 'comment-' + this._data['id']);
- this._element.append(data['text']);
+ this._element.append(data['html']);
this._element.append(' - ');
this._user_link = $('<a></a>').attr('class', 'author');
@@ -1173,8 +1205,8 @@ Comment.prototype.dispose = function(){
Comment.prototype.getElement = function(){
Comment.superClass_.getElement.call(this);
- if (this._blank && this._data){
- this.setContent(this._data);
+ if (this.isBlank() && this.hasContent()){
+ this.setContent();
if (enableMathJax === true){
MathJax.Hub.Queue(['Typeset', MathJax.Hub]);
}
@@ -1183,12 +1215,13 @@ Comment.prototype.getElement = function(){
};
Comment.prototype.loadText = function(on_load_handler){
+ var me = this;
$.ajax({
type: "GET",
- url: askbot['urls']['commentGetText'],
+ url: askbot['urls']['getCommentText'],
data: {id: this._data['id']},
success: function(json){
- this._data['text'] = json['text'];
+ me._data['text'] = json['text'];
on_load_handler()
}
});
@@ -1208,14 +1241,18 @@ Comment.prototype.getEditHandler = function(){
var parent_post_id = this._data['post_id'];
var comment = this;
return function(){
- comment.loadText(
- function(){
- if (editCommentForm.canCancel()){
- editCommentForm.detach();
- editCommentForm.attachTo(comment);
- }
+ if (editCommentForm.canCancel()){
+ if (comment.hasText()){
+ editCommentForm.editComment(comment);
}
- );
+ else {
+ comment.loadText(
+ function(){
+ editCommentForm.editComment(comment);
+ }
+ );
+ }
+ }
};
};
@@ -1343,7 +1380,7 @@ PostCommentsWidget.prototype.reloadAllComments = function(callback){
var post_data = {post_id: this._post_id, post_type: this._post_type};
$.ajax({
type: "GET",
- url: askbot['urls']['post_comments'],
+ url: askbot['urls']['postComments'],
data: post_data,
success: callback,
dataType: "json"
diff --git a/askbot/skins/default/media/js/utils.js b/askbot/skins/default/media/js/utils.js
index aec04ffd..2b88f49e 100644
--- a/askbot/skins/default/media/js/utils.js
+++ b/askbot/skins/default/media/js/utils.js
@@ -29,6 +29,18 @@ var setupButtonEventHandlers = function(button, callback){
button.click(callback);
};
+var putCursorAtEnd = function(element){
+ var el = element.get()[0];
+ if (el.setSelectionRange){
+ var len = element.val().length * 2;
+ el.setSelectionRange(len, len);
+ }
+ else{
+ element.val(element.val());
+ }
+ element.scrollTop = 999999;
+};
+
var setCheckBoxesIn = function(selector, value){
return $(selector + '> input[type=checkbox]').attr('checked', value);
};
diff --git a/askbot/skins/default/templates/base.html b/askbot/skins/default/templates/base.html
index 4d23cc60..c8d7ab76 100644
--- a/askbot/skins/default/templates/base.html
+++ b/askbot/skins/default/templates/base.html
@@ -24,6 +24,7 @@
var askbot = {};
askbot['data'] = {};
askbot['urls'] = {};
+ askbot['settings'] = {};
</script>
{% block forejs %}
{% endblock %}
diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html
index 2af509cd..e9b3f7f1 100644
--- a/askbot/skins/default/templates/question.html
+++ b/askbot/skins/default/templates/question.html
@@ -16,347 +16,347 @@
</div>
<div id="main-body" class="">
<div id="askform">
- <table style="width:100%;" id="question-table" {% if question.deleted %}class="deleted"{%endif%}>
- <tr>
- <td style="width:30px;vertical-align:top">
- <div class="vote-buttons">
- {% if question_vote %}
- <img id="question-img-upvote-{{ question.id }}" class="question-img-upvote"
- {% if question_vote.is_upvote() %}
- src="{{"/images/vote-arrow-up-on.png"|media}}"
- {% else %}
- src="{{"/images/vote-arrow-up.png"|media}}"
- {% endif %}
- alt="{% trans %}i like this post (click again to cancel){% endtrans %}"
- title="{% trans %}i like this post (click again to cancel){% endtrans %}" />
- <div id="question-vote-number-{{ question.id }}" class="vote-number"
- title="{% trans %}current number of votes{% endtrans %}">
- {{ question.score }}
- </div>
- <img id="question-img-downvote-{{ question.id }}" class="question-img-downvote"
- {% if question_vote.is_downvote() %}
- src="{{"/images/vote-arrow-down-on.png"|media}}"
- {% else %}
- src="{{"/images/vote-arrow-down.png"|media}}"
- {% endif %}
- alt="{% trans %}i dont like this post (click again to cancel){% endtrans %}"
- title="{% trans %}i dont like this post (click again to cancel){% endtrans %}" />
+ <table style="width:100%;" id="question-table" {% if question.deleted %}class="deleted"{%endif%}>
+ <tr>
+ <td style="width:30px;vertical-align:top">
+ <div class="vote-buttons">
+ {% if question_vote %}
+ <img id="question-img-upvote-{{ question.id }}" class="question-img-upvote"
+ {% if question_vote.is_upvote() %}
+ src="{{"/images/vote-arrow-up-on.png"|media}}"
{% else %}
- <img id="question-img-upvote-{{ question.id }}" class="question-img-upvote"
- alt="{% trans %}i like this post (click again to cancel){% endtrans %}"
src="{{"/images/vote-arrow-up.png"|media}}"
- title="{% trans %}i like this post (click again to cancel){% endtrans %}" />
- <div id="question-vote-number-{{ question.id }}" class="vote-number"
- title="{% trans %}current number of votes{% endtrans %}">
- {{ question.score }}
- </div>
- <img id="question-img-downvote-{{ question.id }}" class="question-img-downvote"
- src="{{"/images/vote-arrow-down.png"|media}}"
- alt="{% trans %}i dont like this post (click again to cancel){% endtrans %}"
- title="{% trans %}i dont like this post (click again to cancel){% endtrans %}" />
{% endif %}
- {% if favorited %}
- <img class="question-img-favorite" src="{{"/images/vote-favorite-on.png"|media}}"
- alt="{% trans %}mark this question as favorite (click again to cancel){% endtrans %}"
- title="{% trans %}mark this question as favorite (click again to cancel){% endtrans %}" />
- <div id="favorite-number" class="favorite-number my-favorite-number">
- {{ question.favourite_count }}
- </div>
+ alt="{% trans %}i like this post (click again to cancel){% endtrans %}"
+ title="{% trans %}i like this post (click again to cancel){% endtrans %}" />
+ <div id="question-vote-number-{{ question.id }}" class="vote-number"
+ title="{% trans %}current number of votes{% endtrans %}">
+ {{ question.score }}
+ </div>
+ <img id="question-img-downvote-{{ question.id }}" class="question-img-downvote"
+ {% if question_vote.is_downvote() %}
+ src="{{"/images/vote-arrow-down-on.png"|media}}"
{% else %}
- <img class="question-img-favorite" src="{{"/images/vote-favorite-off.png"|media}}"
- alt="{% trans %}remove favorite mark from this question (click again to restore mark){% endtrans %}"
- title="{% trans %}remove favorite mark from this question (click again to restore mark){% endtrans %}" />
- <div id="favorite-number" class="favorite-number">
- {% if question.favourite_count != 0 %}{{ question.favourite_count }}{% endif %}
- </div>
- {% endif %}
- {% if settings.ENABLE_SOCIAL_SHARING %}
- <a class="twitter-share" alt="{% trans %}Share this question on twitter{% endtrans %}"></a>
- <a class="fb-share" alt="{% trans %}Share this question on facebook{% endtrans %}"></a>
+ src="{{"/images/vote-arrow-down.png"|media}}"
{% endif %}
+ alt="{% trans %}i dont like this post (click again to cancel){% endtrans %}"
+ title="{% trans %}i dont like this post (click again to cancel){% endtrans %}" />
+ {% else %}
+ <img id="question-img-upvote-{{ question.id }}" class="question-img-upvote"
+ alt="{% trans %}i like this post (click again to cancel){% endtrans %}"
+ src="{{"/images/vote-arrow-up.png"|media}}"
+ title="{% trans %}i like this post (click again to cancel){% endtrans %}" />
+ <div id="question-vote-number-{{ question.id }}" class="vote-number"
+ title="{% trans %}current number of votes{% endtrans %}">
+ {{ question.score }}
</div>
- </td>
- <td>
- <div id="item-right">
- <div class="question-body">
- {{question.html}}
- </div>
- <div id="question-tags" class="post-tags tags">
- {% for tag in question.get_tag_names() %}
- <a href="{% url questions %}?tags={{tag|urlencode}}&amp;start_over=true"
- class="post-tag"
- title="{% trans %}see questions tagged '{{tag}}'{% endtrans %}" rel="tag">{{ tag }}</a>
- {% endfor %}
- </div>
- <div id="question-controls" class="post-controls">
- {% set pipe=joiner('<span class="sep">|</span>') %}
- {% if request.user|can_edit_post(question) %}{{ pipe() }}
- <a href="{% url edit_question question.id %}">{% trans %}edit{% endtrans %}</a>
- {% endif %}
- {% if request.user|can_retag_question(question) %}{{ pipe() }}
- <a id="retag" href="{% url retag_question question.id %}">{% trans %}retag{% endtrans %}</a>
- <script type="text/javascript">
- var retagUrl = "{% url retag_question question.id %}";
- </script>
- {% endif %}
- {% if question.closed %}
- {% if request.user|can_reopen_question(question) %}{{ pipe() }}
- <a href="{% url reopen question.id %}">{% trans %}reopen{% endtrans %}</a>
- {% endif %}
- {% else %}
- {% if request.user|can_close_question(question) %}{{ pipe() }}
- <a href="{% url close question.id %}">{% trans %}close{% endtrans %}</a>
- {% endif %}
+ <img id="question-img-downvote-{{ question.id }}" class="question-img-downvote"
+ src="{{"/images/vote-arrow-down.png"|media}}"
+ alt="{% trans %}i dont like this post (click again to cancel){% endtrans %}"
+ title="{% trans %}i dont like this post (click again to cancel){% endtrans %}" />
+ {% endif %}
+ {% if favorited %}
+ <img class="question-img-favorite" src="{{"/images/vote-favorite-on.png"|media}}"
+ alt="{% trans %}mark this question as favorite (click again to cancel){% endtrans %}"
+ title="{% trans %}mark this question as favorite (click again to cancel){% endtrans %}" />
+ <div id="favorite-number" class="favorite-number my-favorite-number">
+ {{ question.favourite_count }}
+ </div>
+ {% else %}
+ <img class="question-img-favorite" src="{{"/images/vote-favorite-off.png"|media}}"
+ alt="{% trans %}remove favorite mark from this question (click again to restore mark){% endtrans %}"
+ title="{% trans %}remove favorite mark from this question (click again to restore mark){% endtrans %}" />
+ <div id="favorite-number" class="favorite-number">
+ {% if question.favourite_count != 0 %}{{ question.favourite_count }}{% endif %}
+ </div>
+ {% endif %}
+ {% if settings.ENABLE_SOCIAL_SHARING %}
+ <a class="twitter-share" alt="{% trans %}Share this question on twitter{% endtrans %}"></a>
+ <a class="fb-share" alt="{% trans %}Share this question on facebook{% endtrans %}"></a>
+ {% endif %}
+ </div>
+ </td>
+ <td>
+ <div id="item-right">
+ <div class="question-body">
+ {{question.html}}
+ </div>
+ <div id="question-tags" class="post-tags tags">
+ {% for tag in question.get_tag_names() %}
+ <a href="{% url questions %}?tags={{tag|urlencode}}&amp;start_over=true"
+ class="post-tag"
+ title="{% trans %}see questions tagged '{{tag}}'{% endtrans %}" rel="tag">{{ tag }}</a>
+ {% endfor %}
+ </div>
+ <div id="question-controls" class="post-controls">
+ {% set pipe=joiner('<span class="sep">|</span>') %}
+ {% if request.user|can_edit_post(question) %}{{ pipe() }}
+ <a href="{% url edit_question question.id %}">{% trans %}edit{% endtrans %}</a>
+ {% endif %}
+ {% if request.user|can_retag_question(question) %}{{ pipe() }}
+ <a id="retag" href="{% url retag_question question.id %}">{% trans %}retag{% endtrans %}</a>
+ <script type="text/javascript">
+ var retagUrl = "{% url retag_question question.id %}";
+ </script>
+ {% endif %}
+ {% if question.closed %}
+ {% if request.user|can_reopen_question(question) %}{{ pipe() }}
+ <a href="{% url reopen question.id %}">{% trans %}reopen{% endtrans %}</a>
{% endif %}
- {% if request.user|can_flag_offensive(question) %}{{ pipe() }}
- <span id="question-offensive-flag-{{ question.id }}" class="offensive-flag"
- title="{% trans %}report as offensive (i.e containing spam, advertising, malicious text, etc.){% endtrans %}">
- <a>{% trans %}flag offensive{% endtrans %}</a>
- {% if request.user|can_see_offensive_flags(question) %}
- <span class="darkred">{% if question.offensive_flag_count > 0 %}({{ question.offensive_flag_count }}){% endif %}</span>
- {% endif %}
- </span>
+ {% else %}
+ {% if request.user|can_close_question(question) %}{{ pipe() }}
+ <a href="{% url close question.id %}">{% trans %}close{% endtrans %}</a>
{% endif %}
- {% if request.user|can_delete_post(question) %}{{ pipe() }}
- <a id="question-delete-link-{{question.id}}">{% trans %}delete{% endtrans %}</a>
+ {% endif %}
+ {% if request.user|can_flag_offensive(question) %}{{ pipe() }}
+ <span id="question-offensive-flag-{{ question.id }}" class="offensive-flag"
+ title="{% trans %}report as offensive (i.e containing spam, advertising, malicious text, etc.){% endtrans %}">
+ <a>{% trans %}flag offensive{% endtrans %}</a>
+ {% if request.user|can_see_offensive_flags(question) %}
+ <span class="darkred">{% if question.offensive_flag_count > 0 %}({{ question.offensive_flag_count }}){% endif %}</span>
{% endif %}
- </div>
- </div>
- <div class="post-update-info-container">
- {{
- macros.post_contributor_info(
- question,
- "original_author",
- question.wiki,
- settings.MIN_REP_TO_EDIT_WIKI
- )
- }}
- {{
- macros.post_contributor_info(
- question,
- "last_updater",
- question.wiki,
- settings.MIN_REP_TO_EDIT_WIKI,
- )
- }}
+ </span>
+ {% endif %}
+ {% if request.user|can_delete_post(question) %}{{ pipe() }}
+ <a id="question-delete-link-{{question.id}}">{% trans %}delete{% endtrans %}</a>
+ {% endif %}
</div>
- {{
- macros.post_comments_widget(
- post = question,
- user = request.user,
- max_comments = settings.MAX_COMMENTS_TO_SHOW
- )
- }}
</div>
- </td>
- </tr>
- </table>
- {% if question.closed %}
- <div class="question-status" style="margin-bottom:15px">
- <h3>{% trans close_reason=question.get_close_reason_display() %}The question has been closed for the following reason "{{ close_reason }}" by{% endtrans %}
- <a href="{{ question.closed_by.get_profile_url() }}">{{ question.closed_by.username }}</a>
- {% trans closed_at=question.closed_at %}close date {{closed_at}}{% endtrans %}</h3>
- </div>
- {% endif %}
- {% if answers %}
- <hr/>
- <div class="tabBar">
- <a name="sort-top"></a>
- <div class="headUsers">
- {% trans counter=answers|length %}
- {{counter}} Answer:
- {% pluralize %}
- {{counter}} Answers:
- {% endtrans %}
- </div>
- <div class="tabsA">
- <a id="oldest" href="{% url question question.id %}?sort=oldest#sort-top"
- title="{% trans %}oldest answers will be shown first{% endtrans %}">{% trans %}oldest answers{% endtrans %}</a>
- <a id="latest" href="{% url question question.id %}?sort=latest#sort-top"
- title="{% trans %}newest answers will be shown first{% endtrans %}">{% trans %}newest answers{% endtrans %}</a>
- <a id="votes" href="{% url question question.id %}?sort=votes#sort-top"
- title="{% trans %}most voted answers will be shown first{% endtrans %}">{% trans %}popular answers{% endtrans %}</a>
+ <div class="post-update-info-container">
+ {{
+ macros.post_contributor_info(
+ question,
+ "original_author",
+ question.wiki,
+ settings.MIN_REP_TO_EDIT_WIKI
+ )
+ }}
+ {{
+ macros.post_contributor_info(
+ question,
+ "last_updater",
+ question.wiki,
+ settings.MIN_REP_TO_EDIT_WIKI,
+ )
+ }}
+ </div>
+ {{
+ macros.post_comments_widget(
+ post = question,
+ user = request.user,
+ max_comments = settings.MAX_COMMENTS_TO_SHOW
+ )
+ }}
</div>
+ </td>
+ </tr>
+ </table>
+ {% if question.closed %}
+ <div class="question-status" style="margin-bottom:15px">
+ <h3>{% trans close_reason=question.get_close_reason_display() %}The question has been closed for the following reason "{{ close_reason }}" by{% endtrans %}
+ <a href="{{ question.closed_by.get_profile_url() }}">{{ question.closed_by.username }}</a>
+ {% trans closed_at=question.closed_at %}close date {{closed_at}}{% endtrans %}</h3>
+ </div>
+ {% endif %}
+ {% if answers %}
+ <hr/>
+ <div class="tabBar">
+ <a name="sort-top"></a>
+ <div class="headUsers">
+ {% trans counter=answers|length %}
+ {{counter}} Answer:
+ {% pluralize %}
+ {{counter}} Answers:
+ {% endtrans %}
</div>
- {{ macros.paginator(paginator_context) }}
-
- {% for answer in answers %}
- <a name="{{ answer.id }}"></a>
- <div id="answer-container-{{ answer.id }}" class="answer {% if answer.accepted %}accepted-answer{% endif %} {% if answer.author_id==question.author_id %} answered-by-owner{% endif %} {% if answer.deleted %}deleted{% endif %}">
- <table style="width:100%;">
- <tr>
- <td style="width:30px;vertical-align:top">
- <div class="vote-buttons">
- <img id="answer-img-upvote-{{ answer.id }}" class="answer-img-upvote"
- {% if user_answer_votes[answer.id] == 1 %}
- src="{{"/images/vote-arrow-up-on.png"|media}}"
- {% else %}
- src="{{"/images/vote-arrow-up.png"|media}}"
- {% endif %}
- alt="{% trans %}i like this answer (click again to cancel){% endtrans %}"
- title="{% trans %}i like this answer (click again to cancel){% endtrans %}"/>
- <div id="answer-vote-number-{{ answer.id }}" class="vote-number" title="{% trans %}current number of votes{% endtrans %}">
- {{ answer.score }}
- </div>
- <img id="answer-img-downvote-{{ answer.id }}" class="answer-img-downvote"
- {% if user_answer_votes[answer.id] == -1 %}
- src="{{"/images/vote-arrow-down-on.png"|media}}"
- {% else %}
- src="{{"/images/vote-arrow-down.png"|media}}"
- {% endif %}
- alt="{% trans %}i dont like this answer (click again to cancel){% endtrans %}"
- title="{% trans %}i dont like this answer (click again to cancel){% endtrans %}" />
- {% if request.user == question.author %}
+ <div class="tabsA">
+ <a id="oldest" href="{% url question question.id %}?sort=oldest#sort-top"
+ title="{% trans %}oldest answers will be shown first{% endtrans %}">{% trans %}oldest answers{% endtrans %}</a>
+ <a id="latest" href="{% url question question.id %}?sort=latest#sort-top"
+ title="{% trans %}newest answers will be shown first{% endtrans %}">{% trans %}newest answers{% endtrans %}</a>
+ <a id="votes" href="{% url question question.id %}?sort=votes#sort-top"
+ title="{% trans %}most voted answers will be shown first{% endtrans %}">{% trans %}popular answers{% endtrans %}</a>
+ </div>
+ </div>
+ {{ macros.paginator(paginator_context) }}
+
+ {% for answer in answers %}
+ <a name="{{ answer.id }}"></a>
+ <div id="answer-container-{{ answer.id }}" class="answer {% if answer.accepted %}accepted-answer{% endif %} {% if answer.author_id==question.author_id %} answered-by-owner{% endif %} {% if answer.deleted %}deleted{% endif %}">
+ <table style="width:100%;">
+ <tr>
+ <td style="width:30px;vertical-align:top">
+ <div class="vote-buttons">
+ <img id="answer-img-upvote-{{ answer.id }}" class="answer-img-upvote"
+ {% if user_answer_votes[answer.id] == 1 %}
+ src="{{"/images/vote-arrow-up-on.png"|media}}"
+ {% else %}
+ src="{{"/images/vote-arrow-up.png"|media}}"
+ {% endif %}
+ alt="{% trans %}i like this answer (click again to cancel){% endtrans %}"
+ title="{% trans %}i like this answer (click again to cancel){% endtrans %}"/>
+ <div id="answer-vote-number-{{ answer.id }}" class="vote-number" title="{% trans %}current number of votes{% endtrans %}">
+ {{ answer.score }}
+ </div>
+ <img id="answer-img-downvote-{{ answer.id }}" class="answer-img-downvote"
+ {% if user_answer_votes[answer.id] == -1 %}
+ src="{{"/images/vote-arrow-down-on.png"|media}}"
+ {% else %}
+ src="{{"/images/vote-arrow-down.png"|media}}"
+ {% endif %}
+ alt="{% trans %}i dont like this answer (click again to cancel){% endtrans %}"
+ title="{% trans %}i dont like this answer (click again to cancel){% endtrans %}" />
+ {% if request.user == question.author %}
+ <img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept"
+ {% if answer.accepted %}
+ src="{{"/images/vote-accepted-on.png"|media}}"
+ {% else %}
+ src="{{"/images/vote-accepted.png"|media}}"
+ {% endif %}
+ alt="{% trans %}mark this answer as favorite (click again to undo){% endtrans %}"
+ title="{% trans %}mark this answer as favorite (click again to undo){% endtrans %}" />
+ {% else %}
+ {% if answer.accepted %}
<img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept"
{% if answer.accepted %}
src="{{"/images/vote-accepted-on.png"|media}}"
{% else %}
- src="{{"/images/vote-accepted.png"|media}}"
- {% endif %}
- alt="{% trans %}mark this answer as favorite (click again to undo){% endtrans %}"
- title="{% trans %}mark this answer as favorite (click again to undo){% endtrans %}" />
- {% else %}
- {% if answer.accepted %}
- <img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept"
- {% if answer.accepted %}
- src="{{"/images/vote-accepted-on.png"|media}}"
- {% else %}
- src="{{"/images/vote-accepted.png"|media}}"
- {% endif %}
- alt="{% trans question_author=question.author.username %}{{question_author}} has selected this answer as correct{% endtrans %}"
- title="{% trans questsion_author=question.author.username%}{{question_author}} has selected this answer as correct{% endtrans %}"
+ src="{{"/images/vote-accepted.png"|media}}"
{% endif %}
+ alt="{% trans question_author=question.author.username %}{{question_author}} has selected this answer as correct{% endtrans %}"
+ title="{% trans questsion_author=question.author.username%}{{question_author}} has selected this answer as correct{% endtrans %}"
{% endif %}
+ {% endif %}
+ </div>
+ </td>
+ <td>
+ <div class="item-right">
+ <div class="answer-body">
+ {{ answer.html }}
</div>
- </td>
- <td>
- <div class="item-right">
- <div class="answer-body">
- {{ answer.html }}
- </div>
- <div class="answer-controls post-controls">
- {% set pipe=joiner('<span class="sep">|</span>') %}
- <span class="linksopt">{{ pipe() }}
- <a
- href="#{{ answer.id }}"
- title="{% trans %}answer permanent link{% endtrans %}">
- {% trans %}permanent link{% endtrans %}
- </a>
- </span>
- {% if request.user|can_edit_post(answer) %}{{ pipe() }}
- <span class="action-link"><a href="{% url edit_answer answer.id %}">{% trans %}edit{% endtrans %}</a></span>
+ <div class="answer-controls post-controls">
+ {% set pipe=joiner('<span class="sep">|</span>') %}
+ <span class="linksopt">{{ pipe() }}
+ <a
+ href="#{{ answer.id }}"
+ title="{% trans %}answer permanent link{% endtrans %}">
+ {% trans %}permanent link{% endtrans %}
+ </a>
+ </span>
+ {% if request.user|can_edit_post(answer) %}{{ pipe() }}
+ <span class="action-link"><a href="{% url edit_answer answer.id %}">{% trans %}edit{% endtrans %}</a></span>
+ {% endif %}
+ {% if request.user|can_flag_offensive(answer) %}{{ pipe() }}
+ <span id="answer-offensive-flag-{{ answer.id }}" class="offensive-flag"
+ title="{% trans %}report as offensive (i.e containing spam, advertising, malicious text, etc.){% endtrans %}">
+ <a>{% trans %}flag offensive{% endtrans %}</a>
+ {% if request.user|can_see_offensive_flags(answer) %}
+ <span class="darkred">{% if answer.offensive_flag_count > 0 %}({{ answer.offensive_flag_count }}){% endif %}</span>
{% endif %}
- {% if request.user|can_flag_offensive(answer) %}{{ pipe() }}
- <span id="answer-offensive-flag-{{ answer.id }}" class="offensive-flag"
- title="{% trans %}report as offensive (i.e containing spam, advertising, malicious text, etc.){% endtrans %}">
- <a>{% trans %}flag offensive{% endtrans %}</a>
- {% if request.user|can_see_offensive_flags(answer) %}
- <span class="darkred">{% if answer.offensive_flag_count > 0 %}({{ answer.offensive_flag_count }}){% endif %}</span>
- {% endif %}
+ </span>
+ {% endif %}
+ {% if request.user|can_delete_post(answer) %}{{ pipe() }}
+ {% spaceless %}
+ <span class="action-link">
+ <a id="answer-delete-link-{{answer.id}}">
+ {% if answer.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
</span>
- {% endif %}
- {% if request.user|can_delete_post(answer) %}{{ pipe() }}
- {% spaceless %}
- <span class="action-link">
- <a id="answer-delete-link-{{answer.id}}">
- {% if answer.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
- </span>
- {% endspaceless %}
- {% endif %}
- </div>
- <div class="post-update-info-container">
- {{
- macros.post_contributor_info(
- answer,
- "original_author",
- answer.wiki,
- settings.MIN_REP_TO_EDIT_WIKI
- )
- }}
- {{
- macros.post_contributor_info(
- answer,
- "last_updater",
- answer.wiki,
- settings.MIN_REP_TO_EDIT_WIKI
- )
- }}
- </div>
- {{
- macros.post_comments_widget(
- post = answer,
- user = request.user,
- max_comments = settings.MAX_COMMENTS_TO_SHOW
+ {% endspaceless %}
+ {% endif %}
+ </div>
+ <div class="post-update-info-container">
+ {{
+ macros.post_contributor_info(
+ answer,
+ "original_author",
+ answer.wiki,
+ settings.MIN_REP_TO_EDIT_WIKI
+ )
+ }}
+ {{
+ macros.post_contributor_info(
+ answer,
+ "last_updater",
+ answer.wiki,
+ settings.MIN_REP_TO_EDIT_WIKI
)
- }}
+ }}
</div>
- </td>
- </tr>
- </table>
- </div>
- {% endfor %}
- <div class="paginator-container-left">
- {{ macros.paginator(paginator_context) }}
+ {{
+ macros.post_comments_widget(
+ post = answer,
+ user = request.user,
+ max_comments = settings.MAX_COMMENTS_TO_SHOW
+ )
+ }}
+ </div>
+ </td>
+ </tr>
+ </table>
</div>
+ {% endfor %}
+ <div class="paginator-container-left">
+ {{ macros.paginator(paginator_context) }}
+ </div>
+ {% endif %}
+ <form id="fmanswer" action="{% url answer question.id %}" method="post">
+ {% if request.user.is_authenticated() %}
+ <p style="padding-left:3px">
+ {{ answer.email_notify }}
+ <label for="question-subscribe-updates">
+ {% if request.user.get_q_sel_email_feed_frequency()=='n' %}
+ {% trans %}Notify me once a day when there are any new answers{% endtrans %}
+ {% elif request.user.get_q_sel_email_feed_frequency()=='d' %}
+ {% trans %}Notify me once a day when there are any new answers{% endtrans %}
+ {% elif request.user.get_q_sel_email_feed_frequency()=='w' %}
+ {% trans %}Notify me weekly when there are any new answers{% endtrans %}
{% endif %}
- <form id="fmanswer" action="{% url answer question.id %}" method="post">
- {% if request.user.is_authenticated() %}
- <p style="padding-left:3px">
- {{ answer.email_notify }}
- <label for="question-subscribe-updates">
- {% if request.user.get_q_sel_email_feed_frequency()=='n' %}
- {% trans %}Notify me once a day when there are any new answers{% endtrans %}
- {% elif request.user.get_q_sel_email_feed_frequency()=='d' %}
- {% trans %}Notify me once a day when there are any new answers{% endtrans %}
- {% elif request.user.get_q_sel_email_feed_frequency()=='w' %}
- {% trans %}Notify me weekly when there are any new answers{% endtrans %}
- {% endif %}
- </label>
- {% trans profile_url=request.user.get_profile_url() %}You can always adjust frequency of email updates from your {{profile_url}}{% endtrans %}
- </p>
+ </label>
+ {% trans profile_url=request.user.get_profile_url() %}You can always adjust frequency of email updates from your {{profile_url}}{% endtrans %}
+ </p>
+ {% else %}
+ <p style="padding-left:3px">
+ <input class="nomargin" type="checkbox" disabled="disabled" />
+ <label>{% trans %}once you sign in you will be able to subscribe for any updates here{% endtrans %}</label>
+ </p>
+ {% endif %}
+ <div style="clear:both">
+ </div>
+ {% if not question.closed %}
+ <div style="padding:10px 0 0 0;">
+ {% spaceless %}
+ <div class="headNormal">
+ {% if answers %}
+ {% trans %}Your answer{% endtrans %}
+ {% else %}
+ {% trans %}Be the first one to answer this question!{% endtrans %}
+ {% endif %}
+ </div>
+ {% endspaceless %}
+ </div>
+ {% if not request.user.is_authenticated() %}
+ <div class="message">{% trans %}you can answer anonymously and then login{% endtrans %}</div>
{% else %}
- <p style="padding-left:3px">
- <input class="nomargin" type="checkbox" disabled="disabled" />
- <label>{% trans %}once you sign in you will be able to subscribe for any updates here{% endtrans %}</label>
+ <p class="message">
+ {% if request.user==question.author %}
+ {% trans %}answer your own question only to give an answer{% endtrans %}
+ {% else %}
+ {% trans %}please only give an answer, no discussions{% endtrans %}
+ {% endif %}
</p>
{% endif %}
- <div style="clear:both">
- </div>
- {% if not question.closed %}
- <div style="padding:10px 0 0 0;">
- {% spaceless %}
- <div class="headNormal">
- {% if answers %}
- {% trans %}Your answer{% endtrans %}
- {% else %}
- {% trans %}Be the first one to answer this question!{% endtrans %}
- {% endif %}
- </div>
- {% endspaceless %}
- </div>
- {% if not request.user.is_authenticated() %}
- <div class="message">{% trans %}you can answer anonymously and then login{% endtrans %}</div>
+ {{macros.edit_post(answer, settings.WIKI_ON)}}
+ <input type="submit"
+ {% if user.is_anonymous() %}
+ value="{% trans %}Login/Signup to Post Your Answer{% endtrans %}"
{% else %}
- <p class="message">
- {% if request.user==question.author %}
- {% trans %}answer your own question only to give an answer{% endtrans %}
- {% else %}
- {% trans %}please only give an answer, no discussions{% endtrans %}
- {% endif %}
- </p>
- {% endif %}
- {{macros.edit_post(answer, settings.WIKI_ON)}}
- <input type="submit"
- {% if user.is_anonymous() %}
- value="{% trans %}Login/Signup to Post Your Answer{% endtrans %}"
+ {% if user == question.author %}
+ value="{% trans %}Answer Your Own Question{% endtrans %}"
{% else %}
- {% if user == question.author %}
- value="{% trans %}Answer Your Own Question{% endtrans %}"
- {% else %}
- value="{% trans %}Answer the question{% endtrans %}"
- {% endif %}
+ value="{% trans %}Answer the question{% endtrans %}"
{% endif %}
- class="submit after-editor" style="float:left"/>
+ {% endif %}
+ class="submit after-editor" style="float:left"/>
{% endif %}
</form>
</div>
@@ -413,7 +413,8 @@
var codeFriendlyMarkdown = false;
{% endif %}
var maxCommentLength = {{settings.MAX_COMMENT_LENGTH}};
- askbot['urls']['post_comments'] = '{% url post_comments %}';
+ askbot['urls']['postComments'] = '{% url post_comments %}';
+ askbot['urls']['getCommentText'] = '{% url get_comment_text %}';
</script>
<script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
diff --git a/askbot/urls.py b/askbot/urls.py
index 11b63ba1..18d8a7ec 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -116,11 +116,11 @@ urlpatterns = patterns('',
app.writers.delete_comment,
name='delete_comment'
),
- #url(
- # r'^comment/get_text/$',
- # app.commands.get_comment_text,
- # name='comment_get_text'
- #),
+ url(
+ r'^comment/get_text/$',
+ app.readers.get_comment_text,
+ name='get_comment_text'
+ ),
#place general question item in the end of other operations
url(
r'^%s(?P<id>\d+)/' % _('question/'),
diff --git a/askbot/utils/http.py b/askbot/utils/http.py
new file mode 100644
index 00000000..a3aea72d
--- /dev/null
+++ b/askbot/utils/http.py
@@ -0,0 +1,34 @@
+"""http utils similar to django's but with more
+specific properties
+"""
+import logging
+from django.http import HttpResponse
+from django.utils import simplejson
+
+class JsonResponse(HttpResponse):
+ """response class that receives a dictionary
+ and returns it serialized with simplejson
+ and response type application/json
+ """
+ def __init__(self, *args, **kwargs):
+ mimetype = kwargs.pop('mimetype', None)
+ if mimetype:
+ raise KeyError('JsonResponse does not accept mimetype variable')
+ kwargs['mimetype'] = 'application/json'
+ string_data = simplejson.dumps(kwargs.pop('data', ''))
+ super(JsonResponse, self).__init__(string_data, *args, **kwargs)
+
+class JsonLoggingErrorResponse(JsonResponse):
+ """like json response, only with empty content
+ and status=500, plus logs an error message
+ """
+ def __init__(self, error, *args, **kwargs):
+ status = kwargs.pop('status', None)
+ if status:
+ raise KeyError('JsonLoggingErrorResponse does not accept status')
+ log_level = kwargs.pop('log_level', 'debug')
+ assert(log_level in ('debug', 'critical'))
+ log = getattr(logging, log_level)
+ log('ajax error ' + unicode(error))
+ kwargs['status'] = 500
+ super(JsonLoggingErrorResponse, self).__init__(*args, **kwargs)
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index 2191dd8b..7e6b1691 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -37,6 +37,7 @@ from askbot.utils import markup
from askbot.utils.forms import get_next_url
from askbot.utils.functions import not_a_robot_request
from askbot.utils.decorators import profile
+from askbot.utils.http import JsonResponse, JsonLoggingErrorResponse
from askbot.search.state_manager import SearchState
from askbot.templatetags import extra_tags
from askbot.templatetags import extra_filters
@@ -555,3 +556,21 @@ def revisions(request, id, object_name=None):
context = RequestContext(request, data)
template = ENV.get_template('revisions.html')
return HttpResponse(template.render(context))
+
+def get_comment_text(request):
+ """returns text of a comment by id
+ via ajax response requires request method get
+ and request must be ajax
+ """
+ if request.is_ajax():
+ if request.method == "GET":
+ try:
+ id = int(request.GET['id'])
+ comment = Comment.objects.get(id = id)
+ return JsonResponse(data={'text': comment.comment})
+ except Exception, e:
+ return JsonLoggingErrorResponse(e)
+ else:
+ return JsonResponse(status=400)
+ else:
+ raise Http404()
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index 6d304e45..27ba5099 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -414,7 +414,7 @@ def __generate_comments_json(obj, user):#non-view generates json data for the po
json_comments.append({'id' : comment.id,
'object_id': obj.id,
'comment_age': diff_date(comment.added_at),
- 'text': comment.html,
+ 'html': comment.html,
'user_display_name': comment_owner.username,
'user_url': comment_owner.get_profile_url(),
'user_id': comment_owner.id,