From 773055cf54d4b974118d7198df5697b2ef069576 Mon Sep 17 00:00:00 2001 From: Kyle Fiedler Date: Thu, 23 Aug 2012 10:28:31 -0400 Subject: [PATCH 01/13] fix wiki falsh message --- lms/static/sass/course/wiki/_wiki.scss | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lms/static/sass/course/wiki/_wiki.scss b/lms/static/sass/course/wiki/_wiki.scss index bcc2c8855d..d15f408e13 100644 --- a/lms/static/sass/course/wiki/_wiki.scss +++ b/lms/static/sass/course/wiki/_wiki.scss @@ -885,8 +885,7 @@ section.wiki { .alert { position: relative; - top: -15px; - margin-bottom: 24px; + margin: 24px 40px; padding: 8px 12px; border: 1px solid #EBE8BF; border-radius: 3px; @@ -903,6 +902,10 @@ section.wiki { } } + .main-article .alert { + margin: 0 0 24px; + } + .missing { max-width: 400px; margin: lh(2) auto; From 3e6f3430b6ac6ccb0c66ea3b1b33ea7bb04e6aab Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Thu, 23 Aug 2012 10:06:27 -0700 Subject: [PATCH 02/13] remove blank slate after new post --- common/djangoapps/student/models.py | 2 +- lms/static/coffee/src/discussion/discussion.coffee | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index 55204f19f6..9cde878d21 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -273,7 +273,7 @@ def add_user_to_default_group(user, group): utg.users.add(User.objects.get(username=user)) utg.save() -# @receiver(post_save, sender=User) +@receiver(post_save, sender=User) def update_user_information(sender, instance, created, **kwargs): try: cc_user = cc.User.from_django_user(instance) diff --git a/lms/static/coffee/src/discussion/discussion.coffee b/lms/static/coffee/src/discussion/discussion.coffee index d4b6a8a9c4..8f9639d344 100644 --- a/lms/static/coffee/src/discussion/discussion.coffee +++ b/lms/static/coffee/src/discussion/discussion.coffee @@ -109,6 +109,7 @@ if Backbone? @$(".discussion-cancel-post").click $.proxy(@cancelNewPost, @) + @$el.children(".blank").hide() @$(".new-post-form").show() submitNewPost: (event) -> @@ -136,6 +137,8 @@ if Backbone? $thread = $(response.html) @$el.children(".threads").prepend($thread) + @$el.children(".blank").remove() + @$(".new-post-similar-posts").empty() @$(".new-post-similar-posts-wrapper").hide() @$(".new-post-title").val("").attr("prev-text", "") @@ -154,6 +157,7 @@ if Backbone? @$(".new-post-form").addClass("collapsed") else if @$el.hasClass("forum-discussion") @$(".new-post-form").hide() + @$el.children(".blank").show() search: (event) -> event.preventDefault() From 8274aa112fc36932fa7797668b4903713c5a7b6d Mon Sep 17 00:00:00 2001 From: ichuang Date: Thu, 23 Aug 2012 13:12:46 -0400 Subject: [PATCH 03/13] the admin page should be loaded based on settings.DEBUG, not askbot --- lms/urls.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lms/urls.py b/lms/urls.py index ca5b01fa2c..4e4eee4f43 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -197,7 +197,6 @@ if settings.QUICKEDIT: if settings.ASKBOT_ENABLED: urlpatterns += (url(r'^%s' % settings.ASKBOT_URL, include('askbot.urls')), \ - url(r'^admin/', include(admin.site.urls)), \ url(r'^settings/', include('askbot.deps.livesettings.urls')), \ url(r'^followit/', include('followit.urls')), \ # url(r'^robots.txt$', include('robots.urls')), @@ -206,8 +205,10 @@ if settings.ASKBOT_ENABLED: if settings.DEBUG: - ## Jasmine - urlpatterns=urlpatterns + (url(r'^_jasmine/', include('django_jasmine.urls')),) + ## Jasmine and admin + urlpatterns=urlpatterns + (url(r'^_jasmine/', include('django_jasmine.urls')), + url(r'^admin/', include(admin.site.urls)), + ) if settings.MITX_FEATURES.get('AUTH_USE_OPENID'): urlpatterns += ( From bc63b99a10e60de67e37dd6933323e6fa15cb5d7 Mon Sep 17 00:00:00 2001 From: ichuang Date: Thu, 23 Aug 2012 13:13:58 -0400 Subject: [PATCH 04/13] disable subdomain filtering in dev_ike (should allow non-fall2012 courses) --- lms/envs/dev_ike.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lms/envs/dev_ike.py b/lms/envs/dev_ike.py index 3ae141a037..297b179fae 100644 --- a/lms/envs/dev_ike.py +++ b/lms/envs/dev_ike.py @@ -16,6 +16,8 @@ WIKI_ENABLED = False MITX_FEATURES['ENABLE_TEXTBOOK'] = False MITX_FEATURES['ENABLE_DISCUSSION'] = False MITX_FEATURES['ACCESS_REQUIRE_STAFF_FOR_COURSE'] = True # require that user be in the staff_* group to be able to enroll +MITX_FEATURES['SUBDOMAIN_COURSE_LISTINGS'] = False +MITX_FEATURES['SUBDOMAIN_BRANDING'] = False MITX_FEATURES['DISABLE_START_DATES'] = True # MITX_FEATURES['USE_DJANGO_PIPELINE']=False # don't recompile scss From ca09c7427bd3733df8eac045288b3a5b9112fc74 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Thu, 23 Aug 2012 11:43:05 -0700 Subject: [PATCH 05/13] some tiny bug fixes --- lms/static/coffee/src/discussion/content.coffee | 6 +++++- lms/static/coffee/src/discussion/utils.coffee | 2 -- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index f7e7bcc5dc..8ae22ccf73 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -191,6 +191,8 @@ if Backbone? comment = @model.addComment response.content commentView = new CommentView el: $comment[0], model: comment comment.updateInfo response.annotated_content_info + if autowatch + @model.get('thread').set('subscribed', true) @cancelReply() cancelReply: -> @@ -330,9 +332,11 @@ if Backbone? DiscussionUtil.safeAjax $elem: $elem url: url + type: "POST" success: (response, textStatus) => @$el.remove() - @model.get('thread').removeComment(@model) + if @model.get('type') == 'comment' + @model.get('thread').removeComment(@model) events: "click .discussion-follow-thread": "toggleFollow" diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index e156b09a63..727b43b348 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -72,12 +72,10 @@ class @DiscussionUtil params["beforeSend"] = -> $elem.attr("disabled", "disabled") if params["$loading"] - console.log "loading" params["$loading"].loading() $.ajax(params).always -> $elem.removeAttr("disabled") if params["$loading"] - console.log "loaded" params["$loading"].loaded() @get: ($elem, url, data, success) -> From 3761b02ce8e69e4552ce763316d1e091458a5298 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Thu, 23 Aug 2012 15:12:02 -0700 Subject: [PATCH 06/13] hide reply button after closing thread --- .../django_comment_client/base/views.py | 6 +++++- lms/djangoapps/django_comment_client/utils.py | 19 +++++++++++-------- .../coffee/src/discussion/content.coffee | 5 ++++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py index dd9da857c6..d1e428ef9c 100644 --- a/lms/djangoapps/django_comment_client/base/views.py +++ b/lms/djangoapps/django_comment_client/base/views.py @@ -156,7 +156,11 @@ def openclose_thread(request, course_id, thread_id): thread = cc.Thread.find(thread_id) thread.closed = request.POST.get('closed', 'false').lower() == 'true' thread.save() - return JsonResponse(thread.to_dict()) + thread = thread.to_dict() + return JsonResponse({ + 'content': thread, + 'ability': utils.get_ability(course_id, thread, request.user), + }) @require_POST @login_required diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index fded387462..4908ee91b5 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -164,6 +164,16 @@ class QueryCountDebugMiddleware(object): logging.info('%s queries run, total %s seconds' % (len(connection.queries), total_time)) return response +def get_ability(course_id, content, user): + return { + 'editable': check_permissions_by_view(user, course_id, content, "update_thread" if content['type'] == 'thread' else "update_comment"), + 'can_reply': check_permissions_by_view(user, course_id, content, "create_comment" if content['type'] == 'thread' else "create_sub_comment"), + 'can_endorse': check_permissions_by_view(user, course_id, content, "endorse_comment") if content['type'] == 'comment' else False, + 'can_delete': check_permissions_by_view(user, course_id, content, "delete_thread" if content['type'] == 'thread' else "delete_comment"), + 'can_openclose': check_permissions_by_view(user, course_id, content, "openclose_thread") if content['type'] == 'thread' else False, + 'can_vote': check_permissions_by_view(user, course_id, content, "vote_for_thread" if content['type'] == 'thread' else "vote_for_comment"), + } + def get_annotated_content_info(course_id, content, user, user_info): voted = '' if content['id'] in user_info['upvoted_ids']: @@ -173,14 +183,7 @@ def get_annotated_content_info(course_id, content, user, user_info): return { 'voted': voted, 'subscribed': content['id'] in user_info['subscribed_thread_ids'], - 'ability': { - 'editable': check_permissions_by_view(user, course_id, content, "update_thread" if content['type'] == 'thread' else "update_comment"), - 'can_reply': check_permissions_by_view(user, course_id, content, "create_comment" if content['type'] == 'thread' else "create_sub_comment"), - 'can_endorse': check_permissions_by_view(user, course_id, content, "endorse_comment") if content['type'] == 'comment' else False, - 'can_delete': check_permissions_by_view(user, course_id, content, "delete_thread" if content['type'] == 'thread' else "delete_comment"), - 'can_openclose': check_permissions_by_view(user, course_id, content, "openclose_thread") if content['type'] == 'thread' else False, - 'can_vote': check_permissions_by_view(user, course_id, content, "vote_for_thread" if content['type'] == 'thread' else "vote_for_comment"), - }, + 'ability': get_ability(course_id, content, user), } def get_annotated_content_infos(course_id, thread, user, user_info): diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index 8ae22ccf73..d94f79ac25 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -90,7 +90,9 @@ if Backbone? ability: (ability) -> for action, elemSelector of @model.actions if not ability[action] - @$(elemSelector).parent().remove() + @$(elemSelector).parent().hide() + else + @$(elemSelector).parent().show() $discussionContent: -> @_discussionContent ||= @$el.children(".discussion-content") @@ -271,6 +273,7 @@ if Backbone? data: data success: (response, textStatus) => @model.set('closed', not closed) + @model.set('ability', response.ability) edit: (event) -> @$(".discussion-content-wrapper").hide() From 7e6656f2df174eb369b571acbe9f274a59301d86 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Thu, 23 Aug 2012 15:21:27 -0700 Subject: [PATCH 07/13] fixed profiled user id (toggle moderator status) --- lms/templates/discussion/user_profile.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/templates/discussion/user_profile.html b/lms/templates/discussion/user_profile.html index 98d7ddedfd..a0a64deeb7 100644 --- a/lms/templates/discussion/user_profile.html +++ b/lms/templates/discussion/user_profile.html @@ -36,6 +36,6 @@ From 88a3e828f691b4ae0143239a0657c519d24e4028 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Fri, 24 Aug 2012 01:04:11 -0700 Subject: [PATCH 08/13] don't use raw html when rendering --- lms/static/coffee/src/discussion/content.coffee | 8 ++++---- lms/templates/discussion/mustache/_content.mustache | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index d94f79ac25..95eef8cda8 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -284,11 +284,11 @@ if Backbone? view = {} view.id = @model.id if @model.get('type') == 'thread' - view.title = @$(".thread-raw-title").html() - view.body = @$(".thread-raw-body").html() - view.tags = @$(".thread-raw-tags").html() + view.title = @model.get('title') + view.body = @model.get('body') + view.tags = @model.get('tags') else - view.body = @$(".comment-raw-body").html() + view.body = @model.get('body') @$discussionContent().append Mustache.render DiscussionUtil.getTemplate("_edit_#{@model.get('type')}"), view DiscussionUtil.makeWmdEditor @$el, $.proxy(@$, @), "#{@model.get('type')}-body-edit" @$(".thread-tags-edit").tagsInput DiscussionUtil.tagsInputOptions() diff --git a/lms/templates/discussion/mustache/_content.mustache b/lms/templates/discussion/mustache/_content.mustache index 91330dd0d8..a5089793e7 100644 --- a/lms/templates/discussion/mustache/_content.mustache +++ b/lms/templates/discussion/mustache/_content.mustache @@ -16,19 +16,16 @@ {{#thread}} {{content.displayed_title}} - {{/thread}}
{{content.displayed_body}}
- {{#thread}}
{{#content.tags}} {{.}} {{/content.tags}}
- {{/thread}}
From 80195176e99893e9f045476f3f71f22ac179af2b Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Fri, 24 Aug 2012 01:45:55 -0700 Subject: [PATCH 09/13] use escape html everywhere and only send discussion data relavent --- .../django_comment_client/base/views.py | 26 +++++++++---------- .../django_comment_client/forum/views.py | 12 ++++----- lms/djangoapps/django_comment_client/utils.py | 14 ++++++++++ .../coffee/src/discussion/discussion.coffee | 2 +- .../discussion/_content_renderer.html | 2 +- .../discussion/_discussion_module.html | 2 +- lms/templates/discussion/_forum.html | 2 +- lms/templates/discussion/_inline.html | 2 +- lms/templates/discussion/_paginator.html | 4 +-- .../discussion/_recent_active_posts.html | 2 +- lms/templates/discussion/_search_bar.html | 4 +-- lms/templates/discussion/_similar_posts.html | 2 +- lms/templates/discussion/_single_thread.html | 2 +- lms/templates/discussion/_sort.html | 2 +- lms/templates/discussion/_trending_tags.html | 2 +- .../discussion/_user_active_threads.html | 2 +- lms/templates/discussion/_user_profile.html | 6 ++--- lms/templates/discussion/index.html | 2 +- lms/templates/discussion/user_profile.html | 2 +- 19 files changed, 53 insertions(+), 39 deletions(-) diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py index d1e428ef9c..68250a035e 100644 --- a/lms/djangoapps/django_comment_client/base/views.py +++ b/lms/djangoapps/django_comment_client/base/views.py @@ -55,7 +55,7 @@ def ajax_content_response(request, course_id, content, template_name): annotated_content_info = utils.get_annotated_content_info(course_id, content, request.user, user_info) return JsonResponse({ 'html': html, - 'content': content, + 'content': utils.safe_content(content), 'annotated_content_info': annotated_content_info, }) @@ -78,7 +78,7 @@ def create_thread(request, course_id, commentable_id): if request.is_ajax(): return ajax_content_response(request, course_id, thread.to_dict(), 'discussion/ajax_create_thread.html') else: - return JsonResponse(thread.to_dict()) + return JsonResponse(utils.safe_content(thread.to_dict())) @require_POST @login_required @@ -90,7 +90,7 @@ def update_thread(request, course_id, thread_id): if request.is_ajax(): return ajax_content_response(request, course_id, thread.to_dict(), 'discussion/ajax_update_thread.html') else: - return JsonResponse(thread.to_dict()) + return JsonResponse(utils.safe_content(thread.to_dict())) def _create_comment(request, course_id, thread_id=None, parent_id=None): post = request.POST @@ -109,7 +109,7 @@ def _create_comment(request, course_id, thread_id=None, parent_id=None): if request.is_ajax(): return ajax_content_response(request, course_id, comment.to_dict(), 'discussion/ajax_create_comment.html') else: - return JsonResponse(comment.to_dict()) + return JsonResponse(utils.safe_content(comment.to_dict())) @require_POST @login_required @@ -126,7 +126,7 @@ def create_comment(request, course_id, thread_id): def delete_thread(request, course_id, thread_id): thread = cc.Thread.find(thread_id) thread.delete() - return JsonResponse(thread.to_dict()) + return JsonResponse(utils.safe_content(thread.to_dict())) @require_POST @login_required @@ -138,7 +138,7 @@ def update_comment(request, course_id, comment_id): if request.is_ajax(): return ajax_content_response(request, course_id, comment.to_dict(), 'discussion/ajax_update_comment.html') else: - return JsonResponse(comment.to_dict()), + return JsonResponse(utils.safe_content(comment.to_dict())) @require_POST @login_required @@ -147,7 +147,7 @@ def endorse_comment(request, course_id, comment_id): comment = cc.Comment.find(comment_id) comment.endorsed = request.POST.get('endorsed', 'false').lower() == 'true' comment.save() - return JsonResponse(comment.to_dict()) + return JsonResponse(utils.safe_content(comment.to_dict())) @require_POST @login_required @@ -158,7 +158,7 @@ def openclose_thread(request, course_id, thread_id): thread.save() thread = thread.to_dict() return JsonResponse({ - 'content': thread, + 'content': utils.safe_content(thread), 'ability': utils.get_ability(course_id, thread, request.user), }) @@ -177,7 +177,7 @@ def create_sub_comment(request, course_id, comment_id): def delete_comment(request, course_id, comment_id): comment = cc.Comment.find(comment_id) comment.delete() - return JsonResponse(comment.to_dict()) + return JsonResponse(utils.safe_content(comment.to_dict())) @require_POST @login_required @@ -186,7 +186,7 @@ def vote_for_comment(request, course_id, comment_id, value): user = cc.User.from_django_user(request.user) comment = cc.Comment.find(comment_id) user.vote(comment, value) - return JsonResponse(comment.to_dict()) + return JsonResponse(utils.safe_content(comment.to_dict())) @require_POST @login_required @@ -195,7 +195,7 @@ def undo_vote_for_comment(request, course_id, comment_id): user = cc.User.from_django_user(request.user) comment = cc.Comment.find(comment_id) user.unvote(comment) - return JsonResponse(comment.to_dict()) + return JsonResponse(utils.safe_content(comment.to_dict())) @require_POST @login_required @@ -204,7 +204,7 @@ def vote_for_thread(request, course_id, thread_id, value): user = cc.User.from_django_user(request.user) thread = cc.Thread.find(thread_id) user.vote(thread, value) - return JsonResponse(thread.to_dict()) + return JsonResponse(utils.safe_content(thread.to_dict())) @require_POST @login_required @@ -213,7 +213,7 @@ def undo_vote_for_thread(request, course_id, thread_id): user = cc.User.from_django_user(request.user) thread = cc.Thread.find(thread_id) user.unvote(thread) - return JsonResponse(thread.to_dict()) + return JsonResponse(utils.safe_content(thread.to_dict())) @require_POST diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py index eda574cb6e..62055f0ab7 100644 --- a/lms/djangoapps/django_comment_client/forum/views.py +++ b/lms/djangoapps/django_comment_client/forum/views.py @@ -83,7 +83,7 @@ def render_discussion(request, course_id, threads, *args, **kwargs): 'base_url': base_url, 'query_params': strip_blank(strip_none(extract(query_params, ['page', 'sort_key', 'sort_order', 'tags', 'text']))), 'annotated_content_info': json.dumps(annotated_content_info), - 'discussion_data': json.dumps({ (discussion_id or user_id): threads }) + 'discussion_data': json.dumps({ (discussion_id or user_id): map(utils.safe_content, threads) }) } context = dict(context.items() + query_params.items()) return render_to_string(template, context) @@ -128,7 +128,7 @@ def inline_discussion(request, course_id, discussion_id): return utils.JsonResponse({ 'html': html, - 'discussionData': threads, + 'discussion_data': map(utils.safe_content, threads), }) def render_search_bar(request, course_id, discussion_id=None, text=''): @@ -149,7 +149,7 @@ def forum_form_discussion(request, course_id): if request.is_ajax(): return utils.JsonResponse({ 'html': content, - 'discussionData': threads, + 'discussion_data': map(utils.safe_content, threads), }) else: recent_active_threads = cc.search_recent_active_threads( @@ -186,7 +186,7 @@ def render_single_thread(request, discussion_id, course_id, thread_id): 'annotated_content_info': json.dumps(annotated_content_info), 'course_id': course_id, 'request': request, - 'discussion_data': json.dumps({ discussion_id: [thread] }), + 'discussion_data': json.dumps({ discussion_id: [utils.safe_content(thread)] }), } return render_to_string('discussion/_single_thread.html', context) @@ -202,7 +202,7 @@ def single_thread(request, course_id, discussion_id, thread_id): return utils.JsonResponse({ 'html': html, - 'content': thread.to_dict(), + 'content': utils.safe_content(thread.to_dict()), 'annotated_content_info': annotated_content_info, }) @@ -252,7 +252,7 @@ def user_profile(request, course_id, user_id): if request.is_ajax(): return utils.JsonResponse({ 'html': content, - 'discussionData': threads, + 'discussion_data': map(utils.safe_content, threads), }) else: context = { diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index 4908ee91b5..45e0fc196c 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -219,3 +219,17 @@ def extend_content(content): 'permalink': permalink(content), } return merge_dict(content, content_info) + +def safe_content(content): + fields = [ + 'id', 'body', 'course_id', 'anonymous', 'endorsed', + 'parent_id', 'thread_id', 'votes', 'closed', + 'created_at', 'updated_at', 'depth', 'type', + 'commentable_id', 'comments_count', 'at_position_list', + 'children', 'highlighted_title', 'highlighted_body', + ] + + if content.get('anonymous') is False: + fields += ['username', 'user_id'] + + return strip_none(extract(content, fields)) diff --git a/lms/static/coffee/src/discussion/discussion.coffee b/lms/static/coffee/src/discussion/discussion.coffee index 8f9639d344..d30fdc70a8 100644 --- a/lms/static/coffee/src/discussion/discussion.coffee +++ b/lms/static/coffee/src/discussion/discussion.coffee @@ -48,7 +48,7 @@ if Backbone? $parent = @$el.parent() @$el.replaceWith(response.html) $discussion = $parent.find("section.discussion") - @model.reset(response.discussionData, { silent: false }) + @model.reset(response.discussion_data, { silent: false }) view = new DiscussionView el: $discussion[0], model: @model DiscussionUtil.bulkUpdateContentInfo(window.$$annotated_content_info) $("html, body").animate({ scrollTop: 0 }, 0) diff --git a/lms/templates/discussion/_content_renderer.html b/lms/templates/discussion/_content_renderer.html index 54371bf4dd..ac2b0b4897 100644 --- a/lms/templates/discussion/_content_renderer.html +++ b/lms/templates/discussion/_content_renderer.html @@ -5,7 +5,7 @@ <%def name="render_content_with_comments(content, *args, **kwargs)"> -
+
${render_content(content, *args, **kwargs)} ${render_comments(content.get('children', []), *args, **kwargs)}
diff --git a/lms/templates/discussion/_discussion_module.html b/lms/templates/discussion/_discussion_module.html index 3d92f242a1..b9e69cc0ad 100644 --- a/lms/templates/discussion/_discussion_module.html +++ b/lms/templates/discussion/_discussion_module.html @@ -1,3 +1,3 @@ diff --git a/lms/templates/discussion/_forum.html b/lms/templates/discussion/_forum.html index 0a812fd1bb..b43efae666 100644 --- a/lms/templates/discussion/_forum.html +++ b/lms/templates/discussion/_forum.html @@ -1,6 +1,6 @@ <%namespace name="renderer" file="_content_renderer.html"/> -
+
diff --git a/lms/templates/discussion/_inline.html b/lms/templates/discussion/_inline.html index aa90e4e6ba..abef7f39e8 100644 --- a/lms/templates/discussion/_inline.html +++ b/lms/templates/discussion/_inline.html @@ -1,6 +1,6 @@ <%namespace name="renderer" file="_content_renderer.html"/> -
+
diff --git a/lms/templates/discussion/_paginator.html b/lms/templates/discussion/_paginator.html index dd9bd2d43d..bb94b64289 100644 --- a/lms/templates/discussion/_paginator.html +++ b/lms/templates/discussion/_paginator.html @@ -9,7 +9,7 @@ %> <%def name="link_to_page(_page, text)"> - ${text} + ${text} <%def name="div_page(_page)"> @@ -36,7 +36,7 @@ % endfor -
+
% if page > 1: ${link_to_page(page - 1, "< Previous page")} diff --git a/lms/templates/discussion/_recent_active_posts.html b/lms/templates/discussion/_recent_active_posts.html index baf505838d..b787df2fcf 100644 --- a/lms/templates/discussion/_recent_active_posts.html +++ b/lms/templates/discussion/_recent_active_posts.html @@ -8,7 +8,7 @@
    % for thread in recent_active_threads: -
  1. ${thread['title']} ${thread['votes']['point']}
  2. +
  3. ${thread['title'] | h} ${thread['votes']['point'] | h}
  4. % endfor
      diff --git a/lms/templates/discussion/_search_bar.html b/lms/templates/discussion/_search_bar.html index e93b46efb2..1f46a8e3c8 100644 --- a/lms/templates/discussion/_search_bar.html +++ b/lms/templates/discussion/_search_bar.html @@ -10,9 +10,9 @@ def base_url_for_search():
      % if query_params.get('tags', None): - + % else: - + % endif
      diff --git a/lms/templates/discussion/_similar_posts.html b/lms/templates/discussion/_similar_posts.html index f68964acec..ef6eedee2e 100644 --- a/lms/templates/discussion/_similar_posts.html +++ b/lms/templates/discussion/_similar_posts.html @@ -3,7 +3,7 @@ Hide
      % for thread in threads: - ${thread['title']} + ${thread['title'] | h} % endfor
      % endif diff --git a/lms/templates/discussion/_single_thread.html b/lms/templates/discussion/_single_thread.html index 395eb72e46..bfbf7b069e 100644 --- a/lms/templates/discussion/_single_thread.html +++ b/lms/templates/discussion/_single_thread.html @@ -1,6 +1,6 @@ <%namespace name="renderer" file="_content_renderer.html"/> -
      +
      Discussion
      ${renderer.render_content_with_comments(thread)} diff --git a/lms/templates/discussion/_sort.html b/lms/templates/discussion/_sort.html index 934973a966..7ba10eab7b 100644 --- a/lms/templates/discussion/_sort.html +++ b/lms/templates/discussion/_sort.html @@ -26,7 +26,7 @@ else: return base_url + '?' + urlencode(merge(query_params, {'page': 1, 'sort_key': key, 'sort_order': order})) %> - ${title} + ${title}
      diff --git a/lms/templates/discussion/_trending_tags.html b/lms/templates/discussion/_trending_tags.html index fea18c02dc..509516c2d5 100644 --- a/lms/templates/discussion/_trending_tags.html +++ b/lms/templates/discussion/_trending_tags.html @@ -7,7 +7,7 @@
        % for tag, count in trending_tags: -
      1. ${tag}×${count}
      2. +
      3. ${tag | h}×${count | h}
      4. % endfor
          diff --git a/lms/templates/discussion/_user_active_threads.html b/lms/templates/discussion/_user_active_threads.html index ad72ccdd5e..1844009466 100644 --- a/lms/templates/discussion/_user_active_threads.html +++ b/lms/templates/discussion/_user_active_threads.html @@ -1,6 +1,6 @@ <%namespace name="renderer" file="_content_renderer.html"/> -
          +
          diff --git a/lms/templates/discussion/_user_profile.html b/lms/templates/discussion/_user_profile.html index a092a97951..8660d8035f 100644 --- a/lms/templates/discussion/_user_profile.html +++ b/lms/templates/discussion/_user_profile.html @@ -7,12 +7,12 @@ <% role_names = sorted(map(attrgetter('name'), django_user.roles.all())) %> - + - - + + % if check_permissions_by_view(user, course.id, content=None, name='update_moderator_status'): % if "Moderator" in role_names: Revoke Moderator provileges diff --git a/lms/templates/discussion/index.html b/lms/templates/discussion/index.html index 43291b6f9b..1160a14d90 100644 --- a/lms/templates/discussion/index.html +++ b/lms/templates/discussion/index.html @@ -1,7 +1,7 @@ <%inherit file="../main.html" /> <%namespace name='static' file='../static_content.html'/> <%block name="bodyclass">discussion -<%block name="title">Discussion – ${course.number} +<%block name="title">Discussion – ${course.number | h} <%block name="headextra"> <%static:css group='course'/> diff --git a/lms/templates/discussion/user_profile.html b/lms/templates/discussion/user_profile.html index a0a64deeb7..4c067db710 100644 --- a/lms/templates/discussion/user_profile.html +++ b/lms/templates/discussion/user_profile.html @@ -3,7 +3,7 @@ <%inherit file="../main.html" /> <%namespace name='static' file='../static_content.html'/> <%block name="bodyclass">discussion -<%block name="title">Discussion – ${course.number} +<%block name="title">Discussion – ${course.number | h} <%block name="headextra"> <%static:css group='course'/> From cc5fbdd5a78f8beaffb44e84366dac8f7596113c Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Fri, 24 Aug 2012 02:05:11 -0700 Subject: [PATCH 10/13] fixed appearance of loading icon near sort bar --- lms/static/coffee/src/discussion/discussion.coffee | 5 +++++ lms/static/coffee/src/discussion/utils.coffee | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lms/static/coffee/src/discussion/discussion.coffee b/lms/static/coffee/src/discussion/discussion.coffee index d30fdc70a8..272a4949e0 100644 --- a/lms/static/coffee/src/discussion/discussion.coffee +++ b/lms/static/coffee/src/discussion/discussion.coffee @@ -42,9 +42,14 @@ if Backbone? DiscussionUtil.safeAjax $elem: $elem $loading: $elem + loadingCallback: -> + $(this).parent().append("") + loadedCallback: -> + $(this).parent().children(".discussion-loading").remove() url: url type: "GET" success: (response, textStatus) => + return $parent = @$el.parent() @$el.replaceWith(response.html) $discussion = $parent.find("section.discussion") diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index 727b43b348..94807654c9 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -72,11 +72,17 @@ class @DiscussionUtil params["beforeSend"] = -> $elem.attr("disabled", "disabled") if params["$loading"] - params["$loading"].loading() + if params["loadingCallback"]? + params["loadingCallback"].apply(params["$loading"]) + else + params["$loading"].loading() $.ajax(params).always -> $elem.removeAttr("disabled") if params["$loading"] - params["$loading"].loaded() + if params["loadedCallback"]? + params["loadedCallback"].apply(params["$loading"]) + else + params["$loading"].loaded() @get: ($elem, url, data, success) -> @safeAjax From fe74f9bc85e6a7b458d2ecdfdc526b69ef1de9f0 Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Fri, 24 Aug 2012 02:17:58 -0700 Subject: [PATCH 11/13] reconstruct after editing --- lms/djangoapps/django_comment_client/utils.py | 2 +- lms/static/coffee/src/discussion/content.coffee | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index 45e0fc196c..516344d79b 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -222,7 +222,7 @@ def extend_content(content): def safe_content(content): fields = [ - 'id', 'body', 'course_id', 'anonymous', 'endorsed', + 'id', 'title', 'body', 'course_id', 'anonymous', 'endorsed', 'parent_id', 'thread_id', 'votes', 'closed', 'created_at', 'updated_at', 'depth', 'type', 'commentable_id', 'comments_count', 'at_position_list', diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index 95eef8cda8..13d6f1094f 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -316,8 +316,12 @@ if Backbone? success: (response, textStatus) => DiscussionUtil.clearFormErrors @$(".discussion-update-errors") @$discussionContent().replaceWith(response.html) - @model.set response.content - @model.updateInfo response.annotated_content_info + if @model.get('type') == 'thread' + @model = new Thread response.content + else + @model = new Comment $.extend {}, response.content, { thread: @model.get('thread') } + @reconstruct() + @model.updateInfo response.annotated_content_info, { forceUpdate: true } cancelEdit: (event) -> @$(".discussion-content-edit").hide() @@ -388,6 +392,14 @@ if Backbone? @initTitle() @initBody() @initCommentViews() + + reconstruct: -> + @initBindings() + @initLocal() + @initTimeago() + @initTitle() + @initBody() + @delegateEvents() class @Thread extends @Content urlMappers: From eb65b95232034305de3cf4b54d698aa7c0d48455 Mon Sep 17 00:00:00 2001 From: Arjun Singh Date: Fri, 24 Aug 2012 03:06:44 -0700 Subject: [PATCH 12/13] Removing stray return statement --- lms/static/coffee/src/discussion/discussion.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/lms/static/coffee/src/discussion/discussion.coffee b/lms/static/coffee/src/discussion/discussion.coffee index 272a4949e0..d8df704d1c 100644 --- a/lms/static/coffee/src/discussion/discussion.coffee +++ b/lms/static/coffee/src/discussion/discussion.coffee @@ -49,7 +49,6 @@ if Backbone? url: url type: "GET" success: (response, textStatus) => - return $parent = @$el.parent() @$el.replaceWith(response.html) $discussion = $parent.find("section.discussion") From eb4068cc11a396e2e8a20f1d0e9fe0abc72d5b04 Mon Sep 17 00:00:00 2001 From: Arjun Singh Date: Fri, 24 Aug 2012 03:14:42 -0700 Subject: [PATCH 13/13] Make profile page look reasonable --- lms/static/sass/_discussion.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lms/static/sass/_discussion.scss b/lms/static/sass/_discussion.scss index 717770f459..bcda46a0bb 100644 --- a/lms/static/sass/_discussion.scss +++ b/lms/static/sass/_discussion.scss @@ -150,6 +150,10 @@ $tag-text-color: #5b614f; //user profile + .user-profile{ + margin-top: 24px; + } + .sidebar-username { font-size: 1.5em; font-weight: bold;