canvas-lms/public/javascripts/submissions.js

292 lines
12 KiB
JavaScript
Raw Normal View History

/**
* Copyright (C) 2011 Instructure, Inc.
*
* This file is part of Canvas.
*
* Canvas is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, version 3 of the License.
*
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
define([
'i18n!submissions',
'jquery',
remove circular dependency in ajaxJSON/instructure_forms circular requirement dependencies break qunit for some reason now (recently started). they appear to be fine in production, but we lose test coverage. this circular dependency was one of the worst offenders. each defined methods that made more sense in the other, and depended on things from the other. since only one of the methods moved actually depended on anything from the current host, this resolves the dependency. most of the files that needed one or more of these three methods already included both, so it was just a comment change in which file is providing which method. a handful added a new require. one file dropped a dependency (yay). jquery.ajaxJSON no longer pulls in jquery.instructure_forms, so if something was depending on instructure_forms implicitly through ajaxJSON, that may be broken (and should be fixed by making the requirement explicit). meanwhile, take advantage of touching the zip_file_import_form partial to extract its js into a bundle. Change-Id: I3b85ab267748a7492662e4e3281820d749d3fe08 test-plan: - primarily a refactor. no new behavior, just check for regressions, particularly around zip_file_import_form - rake js:test should include most if not all javascript specs now (a large percentage didn't run before) Reviewed-on: https://gerrit.instructure.com/15411 Reviewed-by: Ethan Vizitei <ethan@12spokes.com> Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Clare Hetherington <clare@instructure.com> Reviewed-by: Brian Palmer <brianp@instructure.com>
2012-11-16 03:21:27 +08:00
'jquery.ajaxJSON' /* ajaxJSON */,
'jquery.instructure_forms' /* ajaxJSONFiles */,
'jquery.instructure_date_and_time' /* parseFromISO */,
'jquery.instructure_misc_plugins' /* fragmentChange, showIf */,
'jquery.loadingImg' /* loadingImg, loadingImage */,
'jquery.templateData' /* fillTemplateData, getTemplateData */,
Use html5 to show videos by default using a library called mediaElement.js, try to show all kaltura video and audio using html5 and fall back on flash if needed. Test Plan: * in all the different browsers (including mobile safari/chrome) * try recording webcam videos (as homework submission, as content in a wiki page, etc) * view those same pages * view recorded submission in speedgrader use the playlist urls to get kaltura urls This will get CDN-configured links from Kaltura instead of direct Kaltura links. It also allows for the case where a MediaObject does not exist. When one is requested, it will be created in the database and details fetched. Test Plan for cdn urls: * Make sure kaltura is enabled * Open your web inspector's network tab * Browse to a recorded media file in Canvas, and play it * Ensure that the file is streamed from kaltura's configured CDN (s3 in the case of instructure). Test Plan for nonexistent MediaObjects: * Make sure kaltura is enabled * In a wiki page, record a media comment * Destroy that MediaObject from the database (use Inspect Element to find the media_id which looks like 0_1234abcd) * Reload the page, and verify that you can still view the video fix error when viewing a video file that has an unknown source type There are some videos that have valid sources that don't have an extension for some reason. This fixes handling of those correctly. There was also a bug that would sort by bitrate as strings, instead of as integers. The sort function was refactored out and tests written to ensure that's fixed. Test Plan * find a video in kaltura that has an asset with no extension, and make sure you can view that video in a wiki page refs #CNVS-324 Change-Id: I8ff24a94b8af11fc29b84e45545f8a8b639eeaff Reviewed-on: https://gerrit.instructure.com/16824 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Bracken Mosbacker <bracken@instructure.com> QA-Review: Adam Phillipps <adam@instructure.com>
2013-01-16 05:14:29 +08:00
'media_comments' /* mediaComment */,
'compiled/jquery/mediaCommentThumbnail',
'vendor/jquery.scrollTo' /* /\.scrollTo/ */
], function(I18n, $) {
$("#content").addClass('padless');
var fileIndex = 1;
var submissionLoaded = function(data) {
if(data.submission) {
var d = [];
d.push(data);
data = d;
}
for(var jdx in data) {
var submission = data[jdx].submission;
var comments = submission.visible_submission_comments || submission.submission_comments;
if(submission.user_id != ENV.SUBMISSION.user_id) { continue; }
for(var idx in comments) {
var comment = comments[idx].submission_comment;
if($("#submission_comment_" + comment.id).length > 0) { continue; }
var $comment = $("#comment_blank").clone(true).removeAttr('id');
comment.posted_at = $.parseFromISO(comment.created_at).datetime_formatted;
$comment.fillTemplateData({
data: comment,
id: 'submission_comment_' + comment.id
});
if(comment.media_comment_id) {
$media_comment_link = $("#comment_media_blank").clone(true).removeAttr('id');
$media_comment_link.fillTemplateData({
data: comment
});
$comment.find(".comment").empty().append($media_comment_link.show());
} else {
for(var jdx in comment.attachments) {
var attachment = comment.attachments[jdx].attachment;
var $attachment = $("#comment_attachment_blank").clone(true).removeAttr('id');
attachment.comment_id = comment.id;
$attachment.fillTemplateData({
data: attachment,
hrefValues: ['comment_id', 'id']
});
$comment.find(".comment_attachments").append($attachment.show());
}
}
$(".comments .comment_list").append($comment.show()).scrollTop(10000);
}
$(".comments .comment_list .play_comment_link").mediaCommentThumbnail('small');
if(submission) {
showGrade(submission);
$(".submission_details").fillTemplateData({
data: submission
});
$(".grading_comment").val(""); //submission.comment);
$("#add_comment_form .comment_attachments").empty();
}
}
$(".submission_header").loadingImage('remove');
}
var showGrade = function(submission) {
$(".grading_box").val(submission.grade != undefined && submission.grade !== null ? submission.grade : "");
$(".score").text(submission.score != undefined && submission.score !== null ? submission.score : "");
$(".published_score").text(submission.published_score != undefined && submission.published_score !== null ? submission.published_score : "");
}
$(document).ready(function() {
$(".comments .comment_list .play_comment_link").mediaCommentThumbnail('small');
$(window).bind('resize', function() {
var $frame = $("#preview_frame");
var top = $frame.offset().top;
var height = $(window).height() - top;
$frame.height(height);
$("#rubric_holder").css('maxHeight', height - 50).css('overflow', 'auto').css('zIndex', 5);
$(".comments").height(height);
}).triggerHandler('resize');
$(".comments_link").click(function(event) {
event.preventDefault();
$(".comments").slideToggle(function() {
$(".comments .media_comment_content").empty();
$(".comments textarea:visible").focus().select();
});
});
$(".save_comment_button").click(function(event) {
$(document).triggerHandler('grading_change');
});
$(".cancel_comment_button").click(function(event) {
$(".grading_comment").val("");
$(".comments_link").click();
});
$(".grading_value").change(function(event) {
$(document).triggerHandler('grading_change');
});
$(document).bind('grading_change', function(event) {
// $(".grading_value,.grading_comment").bind('change', function(event) {
$(".submission_header").loadingImage();
var url = $(".update_submission_url").attr('href');
var method = $(".update_submission_url").attr('title');
var formData = {
'submission[assignment_id]': ENV.SUBMISSION.assignment_id,
'submission[user_id]': ENV.SUBMISSION.user_id,
'submission[group_comment]': ($("#submission_group_comment").attr('checked') ? "1" : "0")
};
if($(".grading_value:visible").length > 0) {
formData['submission[grade]'] = $(".grading_value").val();
}
if($("#media_media_recording:visible").length > 0) {
var comment_id = $("#media_media_recording").data('comment_id');
var comment_type = $("#media_media_recording").data('comment_type');
formData['submission[media_comment_type]'] = comment_type || 'video';
formData['submission[media_comment_id]'] = comment_id;
} else {
if($(".grading_comment").val() && $(".grading_comment").val != "") {
formData['submission[comment]'] = $(".grading_comment").val();
}
if(!formData['submission[comment]'] && $("#add_comment_form input[type='file']").length > 0) {
formData['submission[comment]'] = formData['submission[comment]'] || I18n.t("see_attached_files", "See attached files");
}
}
if(!formData['submission[comment]'] && !formData['submission[grade]'] && !formData['submission[media_comment_id]']) {
return;
}
if($("#add_comment_form input[type='file']").length > 0) {
$.ajaxJSONFiles(url + ".text", method, formData, $("#add_comment_form input[type='file']"), submissionLoaded);
} else {
$.ajaxJSON(url, method, formData, submissionLoaded);
}
});
$(".attach_comment_file_link").click(function(event) {
event.preventDefault();
var $attachment = $("#comment_attachment_input_blank").clone(true).removeAttr('id');
$attachment.find("input").attr('name', 'attachments[' + (fileIndex++) + '][uploaded_data]');
$("#add_comment_form .comment_attachments").append($attachment.slideDown());
});
$(".delete_comment_attachment_link").click(function(event) {
event.preventDefault();
$(this).parents(".comment_attachment_input").slideUp(function() {
$(this).remove();
});
});
$(".save_rubric_button").click(function() {
var $rubric = $(this).parents("#rubric_holder").find(".rubric");
var data = rubricAssessment.assessmentData($rubric);
var url = $(".update_rubric_assessment_url").attr('href');
var method = "POST";
$rubric.loadingImage();
$.ajaxJSON(url, method, data, function(data) {
$rubric.loadingImage('remove');
var assessment = data;
var found = false;
if(assessment.rubric_association) {
rubricAssessment.updateRubricAssociation($rubric, data.rubric_association);
delete assessment.rubric_association;
}
for(var idx in rubricAssessments) {
var a = rubricAssessments[idx].rubric_assessment;
if(a && assessment && assessment.id == a.id) {
rubricAssessments[idx].rubric_assessment = assessment;
found = true;
}
}
if(!found) {
rubricAssessments.push(data);
var $option = $(document.createElement('option'));
$option.val(assessment.id).text(assessment.assessor_name).attr('id', 'rubric_assessment_option_' + assessment.id);
$("#rubric_assessments_select").prepend($option).val(assessment.id);
}
$("#rubric_assessment_option_" + assessment.id).text(assessment.assessor_name);
$("#new_rubric_assessment_option").remove();
$("#rubric_assessments_list").show();
rubricAssessment.populateRubric($rubric, assessment);
submission = assessment.artifact;
if (submission) {
showGrade(submission);
}
$("#rubric_holder").fadeOut();
});
});
$("#rubric_holder .rubric").css('width', 'auto').css('marginTop', 0);
$(".hide_rubric_link").click(function(event) {
event.preventDefault();
$("#rubric_holder").fadeOut();
});
$(".assess_submission_link").click(function(event) {
event.preventDefault();
$("#rubric_assessments_select").change();
$("#rubric_holder").fadeIn();
});
$("#rubric_assessments_select").change(function() {
var id = $(this).val();
var found = null;
for(var idx in rubricAssessments) {
var assessment = rubricAssessments[idx].rubric_assessment;
if(assessment.id == id) {
found = assessment;
}
}
rubricAssessment.populateRubric($("#rubric_holder .rubric"), found);
var current_user = (!found || found.assessor_id == ENV.RUBRIC_ASSESSMENT.assessor_id);
$("#rubric_holder .rubric").toggleClass('assessing', current_user && ENV.RUBRIC_ASSESSMENT.assessor_id != ENV.RUBRIC_ASSESSMENT.assessment_user_id);
$("#rubric_holder .save_rubric_button").showIf(current_user);
}).change();
$(".media_comment_link").click(function(event) {
event.preventDefault();
$("#add_comment_form").hide();
$("#media_media_recording").show();
$recording = $("#media_media_recording").find(".media_recording");
$recording.mediaComment('create', 'any', function(id, type) {
$("#media_media_recording").data('comment_id', id).data('comment_type', type);
$(document).triggerHandler('grading_change');
$("#add_comment_form").show();
$("#media_media_recording").hide();
$recording.empty();
}, function() {
$("#add_comment_form").show();
$("#media_media_recording").hide();
});
});
$("#media_recorder_container a").live('click', function(event) {
$("#add_comment_form").show();
$("#media_media_recording").hide();
});
$(".comments .comment_list")
.delegate(".play_comment_link", 'click', function(event) {
event.preventDefault();
var comment_id = $(this).parents(".comment_media").getTemplateData({textValues: ['media_comment_id']}).media_comment_id;
if(comment_id) {
Use html5 to show videos by default using a library called mediaElement.js, try to show all kaltura video and audio using html5 and fall back on flash if needed. Test Plan: * in all the different browsers (including mobile safari/chrome) * try recording webcam videos (as homework submission, as content in a wiki page, etc) * view those same pages * view recorded submission in speedgrader use the playlist urls to get kaltura urls This will get CDN-configured links from Kaltura instead of direct Kaltura links. It also allows for the case where a MediaObject does not exist. When one is requested, it will be created in the database and details fetched. Test Plan for cdn urls: * Make sure kaltura is enabled * Open your web inspector's network tab * Browse to a recorded media file in Canvas, and play it * Ensure that the file is streamed from kaltura's configured CDN (s3 in the case of instructure). Test Plan for nonexistent MediaObjects: * Make sure kaltura is enabled * In a wiki page, record a media comment * Destroy that MediaObject from the database (use Inspect Element to find the media_id which looks like 0_1234abcd) * Reload the page, and verify that you can still view the video fix error when viewing a video file that has an unknown source type There are some videos that have valid sources that don't have an extension for some reason. This fixes handling of those correctly. There was also a bug that would sort by bitrate as strings, instead of as integers. The sort function was refactored out and tests written to ensure that's fixed. Test Plan * find a video in kaltura that has an asset with no extension, and make sure you can view that video in a wiki page refs #CNVS-324 Change-Id: I8ff24a94b8af11fc29b84e45545f8a8b639eeaff Reviewed-on: https://gerrit.instructure.com/16824 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Bracken Mosbacker <bracken@instructure.com> QA-Review: Adam Phillipps <adam@instructure.com>
2013-01-16 05:14:29 +08:00
$(this).parents(".comment_media").find(".media_comment_content").mediaComment('show', comment_id, 'video');
}
})
// this is to prevent the default behavior of loading the video inline from happening
// the .delegate(".play_comment_link"... and the .delegate('a.instructure_inline_media_comment'...
// are actually selecting the same links I just wanted to use the different selectors because
// instructure.js uses 'a.instructure_inline_media_comment' as the selector for its .live handler
// to show things inline.
.delegate('a.instructure_inline_media_comment', 'click', function(e){
// dont let it bubble past this so it doesnt get to the .live handler to show the video inline
e.preventDefault();
e.stopPropagation();
});
showGrade(ENV.SUBMISSION.submission);
});
$(document).fragmentChange(function(event, hash) {
if(hash == '#rubric') {
$(".assess_submission_link:visible:first").click();
} else if(hash.match(/^#comment/)) {
var params = null;
try {
params = JSON.parse(hash.substring(8));
} catch(e) { }
if(params && params.comment) {
$(".grading_comment").val(params.comment);
}
$(".grading_comment").focus().select();
}
});
INST.refreshGrades = function() {
var url = $(".submission_data_url").attr('href');
setTimeout(function() {
$.ajaxJSON(url, 'GET', {}, submissionLoaded);
}, 500);
};
});