var disableTouchZooming = function() {
'use strict';
var head = document.head || document.querySelector( 'head' );
var firstChild = head.firstChild;
var meta = document.createElement( 'meta' );
meta.setAttribute( 'name', 'viewport' );
meta.setAttribute( 'content', 'initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width' );
if ( firstChild ) {
head.insertBefore( meta, firstChild );
}
else {
head.appendChild( meta );
}
};
(function($) {
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
this.replaceWith(function() {
return $("<" + newType + "/>", attrs).append($(this).contents());
});
};
})(jQuery);
var Activity_custom = Activity_manuscript_type.extend({
// for testing purposes
/*
is_instructor: function() {
return false;
},
*/
/* brb: need to override this method so we can remove the grade percentage
from the completed message pop-up */
ARGA_initialization_alert: function() {
// This overrides the standard ARGA initialization message, which doesn't
// tell the user he/she can resubmit (or tell him his grade)
// brb: get the correct arga grade (also, see first "if" below)
//var grade = Get_ARGA_Grade();
var grade = Get_Correct_ARGA_Grade();
var due_date_passed = (Get_ARGA_Data("due_date_has_passed") == "1");
var msg = "";
var buttons;
due_date_passed = false;
// brb: first comparison must use strict equality otherwise "" is converted
// to 0 which will return false if grade is actually 0
if (grade !== "" && grade != null && grade >= 0) {
// if resubmissions are allowed...
if (player.md.allow_resubmission == "true") {
// if due date has not passed, give the student the option of resubmitting or reviewing
if (!due_date_passed) {
msg = "
You have completed this activity, and your grade (" + grade + "%) has been submitted. Would you like to:
"
+ "
Keep your current grade and review your previous answers
"
+ "
Or reset your submission and try the activity again?
You have completed this activity, and your grade (" + grade + "%) has been submitted. Since the due date for the activity has now passed, you cannot re-submit answers to the activity questions.
"
buttons = [ {text:"OK", click: player.activity.ARGA_initialization_final} ];
}
// resubmissions are not allowed
} else {
// brb: Don't show grade percentage in this message since the
// instructor may have manually changed the grade in the grade
// book and we currently have no way of knowing what it is.
msg = "
You have completed this activity.
"
;
buttons = [ {text:"OK", click: player.activity.ARGA_initialization_final} ];
}
// grade has not been submitted
} else {
// if due date has passed, tell the user "tough luck". Otherwise show nothing.
if (due_date_passed) {
msg = "
The due date for this activity has passed. You can still review the activity, but no answers will be submitted and no grade will be recorded.
"
;
buttons = [ {text:"OK", click: player.activity.ARGA_initialization_final} ];
}
}
// if we need a message, show it in a jquery UI dialog
if (msg != "") {
msg = "
" + msg + "
";
$("body").append(msg);
$("#arga_init_dialog").dialog({title:"Please Note", width:450, modal:true, buttons: buttons});
} else {
player.activity.ARGA_initialization_final();
}
},
question_submit_button: function(q) {
var button_html = "";
return button_html;
},
get_points_awarded_html: function(question_index) {
var question = this.questions[question_index];
// calculate points_awarded and points_possible
var points_awarded = 0;
var points_possible = 0;
var points_provisional = false;
for (var i = 0; i < question.queries.length; ++i) {
var query = question.queries[i];
points_awarded += query.getPointsAwarded();
points_possible += query.getPointsPossible();
if (query.pointsAreProvisional() == true) {
points_provisional = true;
}
}
// round to at most two decimal places
points_awarded = Math.round(points_awarded * 100) / 100;
points_possible = Math.round(points_possible * 100) / 100;
var points_html = "Points awarded: " + points_awarded + " out of " + points_possible;
if (points_provisional) {
points_html += " (provisional)";
}
points_html += "";
return points_html;
},
show_question_feedback: function(question, is_correct, try_again, text) {
//safe_log("show_question_feedback");
if (text !== undefined) {
text += " ";
}
else {
text = "";
}
// remove prior feedback if there
$("#question_feedback_" + question.index).remove();
// if question is not answered correctly and they get to try again, show
// hint above question
if (!is_correct && try_again) {
var hint_mesg = "";
if (question.queries[0].getQueryTypeForARGA() === "multiple choice" && question.queries[0].choices_hint[question.queries[0].user_answer_index]) {
hint_mesg += question.queries[0].choices_hint[question.queries[0].user_answer_index] + " ";
}
else if (question.md.feedback_hint) {
hint_mesg += question.md.feedback_hint + " ";
}
question.display_alert_mesg(hint_mesg, "hint");
return;
}
// if this is an MC question then get specific feeback for answer
var mc_fb = "";
if (question.queries[0].getQueryTypeForARGA() == "multiple choice") {
mc_fb = question.queries[0].correct_incorrect_feedback(null, is_correct);
}
// if we don't have any feedback at all, return
if (!question.md.feedback && !question.md.feedback_correct && !question.md.feedback_incorrect && !question.md.feedback_hint && mc_fb === "") {
return;
}
//var html = "
";
// if this is an MC question then get specific feeback for answer
if (question.queries[0].getQueryTypeForARGA() == "multiple choice") {
html += question.queries[0].correct_incorrect_feedback(null, is_correct);
}
// include correct feedback if there and the answer is correct
if (is_correct && question.md.feedback_correct) {
if (question.queries[0].getQueryTypeForARGA() == "multiple choice") {
html += "
" + question.md.feedback_correct + "
";
}
else {
html += "
" + question.md.feedback_correct + "
";
}
}
// include incorrect or hint feedback if there and the answer is incorrect
if (!is_correct) {
var found_feedback_string = false;
// if user gets to try again...
if (try_again) {
// check for feedback_conditional's
if (question.md.feedback_conditional.length > 0) {
for (var i in question.md.feedback_conditional) {
var fbc = question.check_conditional(question.md.feedback_conditional[i]);
if (fbc != "") {
html += "
" + fbc + "
";
found_feedback_string = true;
break;
}
}
}
// if we didn't find a feedback string to use above, check
// for feedback_hint
/*
if (!found_feedback_string && question.md.feedback_hint) {
html += "
" + question.md.feedback_hint + "
";
found_feedback_string = true;
}
*/
}
// if we didn't find a feedback string to use above, check for
// feedback_incorrect
if (!found_feedback_string && question.md.feedback_incorrect) {
if (question.queries[0].getQueryTypeForARGA() == "multiple choice") {
html += "
" + question.md.feedback_incorrect /*+ " The correct answer is " + question.queries[0].choice_ids[question.queries[0].correct_answer_index]*/ /*+ ". You answered " + question.queries[0].choice_ids[question.queries[0].user_answer_index]*/ + "
";
}
else {
html += "
" + question.md.feedback_incorrect + "
";
}
}
}
// include general feedback if there
if (question.md.feedback) {
html += "
" + text + question.md.feedback + "
";
if (question.queries[0].getQueryTypeForARGA() == "essay") {
html += "
Please note: Your answer has been provisionally accepted. You will receive full credit at this time, but your instructor may update your grade later after evaluating your answer.
";
}
}
// brb: Do we need to display points?
//html += player.activity.get_points_awarded_html(question.index);
// close question_feedback div
html += "
";
// brb: use display_feedback_mesg to add feedback to question
// append the div, then fade it in
/*
$("#question_action_div_" + question.index).prepend(html);
$("#question_feedback_" + question.index).fadeIn("fast", function() {
//$(this).css("display", "table");
});
*/
question.display_feedback_mesg(html);
},
restore_saved_answers: function() {
//safe_log("restore_saved_answers");
// skip page queries (questions[0])
for (var i = 1; i < this.questions.length; ++i) {
var question = this.questions[i];
// prepare for question_report_text questions
var query_responses;
if (question.md_set("question_report_text")) {
query_responses = "" + Get_ARGA_QuestionData(this.get_question_number(question))
query_responses = query_responses.split(this.query_responses_separator);
}
var restored_all_answers = true;
var all_answers_correct = true;
for (var j = 0; j < question.queries.length; ++j) {
var query = question.queries[j];
var saved_answer, saved_grade;
// get saved answer and grade out of the questionData for question_report_text questions
if (question.md_set("question_report_text")) {
if (query_responses[j] != null) {
var arr = query_responses[j].split(this.query_responses_grade_separator);
saved_answer = arr[0];
saved_grade = arr[1];
} else {
saved_grade = saved_answer = "";
}
// or out of learnerResponse / questionData for single-query questions
} else {
var ARGA_question_number = this.get_query_number(question, j);
saved_answer = Get_ARGA_LearnerResponse(ARGA_question_number);
// we stored the original grade in questionData
saved_grade = Get_ARGA_QuestionData(ARGA_question_number)
}
// if we found a grade...
if (saved_grade !== "" && saved_grade >= 0) {
//safe_log("restoring answer for " + j);
// restore the answer
query.restoreAnswerFromARGA(saved_answer);
query.setGrade(saved_grade);
// then re-render the query in review mode
query.jq.html(query.getHTML("review"));
if (query.isCorrect() == false) {
all_answers_correct = false;
}
} else {
restored_all_answers = false;
}
} // end for query
//safe_log("restored_all_answers = " + restored_all_answers);
if (restored_all_answers) {
// update the submit div for the question
this.update_question_action_div(i);
// Show appropriate feedback. If the question responses were submitted,
// the student must have finished the question, so we don't have to worry
// about hints.
this.show_question_feedback(question, all_answers_correct, false);
// if the item is in a sequence, show the next question
this.show_next_question(question);
// NEED TO CHECK TO MAKE SURE THIS IS WORKING PROPERLY
// If the question is in a sequence and the sequence is complete, call show_closing_material
var qs = question.question_sequence;
if (qs != null && qs.sequence_complete == "partial") {
this.show_closing_material(qs.index);
}
// update section status
//safe_log("calling update_section_status from restore_saved_answers");
//player.update_section_status();
// brb: if there is a video with this question then show it
player.activity.hide_submit_button(i);
/* brb: there do not appear to be any "reveal_video"s in
these activities so I'm not sure why this was in here? */
/*
var $video = question.jq.siblings( '[data-block_type="reveal_video"]' );
if ($video.length > 0) {
//question.jq.after(video);
//video.show();
$video.addClass("watched");
}
*/
} // end restored_all_answers
} // end for question
//resize_iframe();
},
submit_question: function(question_index){
// the arg may be a number or an event object; in the latter case...
if (typeof question_index == "object") {
// extract the question_index from the object
question_index = question_index.data.question_index;
}
var question = player.activity.questions[question_index];
//force all queries to be answered before doing anything
for (var i=0; i < player.activity.questions[question_index].queries.length; i++) {
var query = player.activity.questions[question_index].queries[i];
var answered = query.user_has_answered();
if (!answered) {
question.display_alert_mesg(question.md.submit_error);
return false;
}
}
// if we made it here then remove any alert messages
question.remove_alert_mesg();
this._super(question_index);
// set focus on feedback
var $fb_div = $("#question_" + question_index + "_fb_mesg");
if ($fb_div) {
$fb_div.attr("role","alert");
$fb_div.focus();
}
// brb: hide submit button
player.activity.hide_submit_button(question_index);
},
hide_submit_button: function(q_idx) {
var $submit_button = $("#question_submit_button_" + q_idx);
$submit_button.attr('aria-disabled','true').attr('disabled','disabled').addClass('visually-hidden');
$submit_button.parent().addClass('visually-hidden');
},
// brb: we aren't going to use this one any more
update_question_action_div: function(question_index) {
return;
}
});
// HTML5 video player upgrade
Figures = Figures.extend({
bcVideo: {}, // holds all of the video players (by ID)
bcPlayerData: { 'accountId': '1500315202001', 'playerId': 'B1AhVYg4l' },
count: 1,
process_media: function() {
var context = this;
// Process each video
$("[data-mmtype='mov']").each(function() {
var $this = $(this);
var $parent = $this.parent("[data-type='figure']");
var video_mmsrc = $this.attr("data-mmsrc");
var parent_id = $parent.attr("data-figure-id");
var video_id = "vidPlayerID_" + parent_id;
/*
if (context.count == 0) {
$(this).remove();
playerHTML = "";
$parent.before(playerHTML);
$parent.remove();
context.count++;
return;
}
else {
$(this).remove();
context.count++;
return;
}
*/
var cap = "";
var $caption = $parent.find("[data-type='caption']");
if ($caption.length == 1) {
var cap_text = $caption.html();
if (/\S/.test(cap_text)) {
cap = "
" + $caption.html() + "
";
}
}
// Replace the current figure HTML with the new HTML5 video HTML
playerHTML = '
' + cap + '
';
$parent.before(playerHTML);
$parent.remove();
// instantiate the player
bc(document.getElementById(video_id));
// create player instance
videojs(video_id).ready(function() {
context.bcVideo[video_id] = this;
// reset the video to the beginning after it ends
context.bcVideo[video_id].on("ended", function() {
context.bcVideo[video_id].currentTime(0);
context.bcVideo[video_id].pause();
$("#" + video_id).removeClass("vjs-has-started");
});
context.bcVideo[video_id].on("play", function() {
$("#" + video_id).addClass("vjs-has-started");
});
}); //end ready
});
}
});
var Player_devtk = Player_manuscript_type.extend({
ACTIVITY_COMPLETED: false,
DUE_DATE_HAS_PASSED: false,
FIRST_PAGE: true,
SHOWN_INSTRUCTOR_MESG: false,
show_toc: function() {
$("#toc_dialog").remove();
var html = "";
for (var i = 0; i < this.sections.length; ++i) {
var s = this.sections[i];
var extra_style = "";
if (this.md.sequenced_sections == "true" && i > this.last_available_section && !player.activity.is_instructor() && !this.DUE_DATE_HAS_PASSED) {
extra_style = "toc_section_not_available";
}
if (extra_style === "toc_section_not_available") {
html += "
Note: slides are not accessible until preceding slides have been viewed or completed.
"
+ html;
html = "
" + html + "
";
$("body").append(html);
$("#toc_dialog")
.dialog({resizable: false, title:"Table of Contents", width:450, modal:true,
open: function() {
$("#toc_link_" + player.section_currently_showing).children("a").attr('autofocus', '');
},
close: function(e) {
//safe_log("close");
//safe_log(e);
// only put focus back on menu button if we didn't jump to a new
// page
//if (e.which == 1 || e.which == 27 || e.keyCode == 1 || e.keyCode == 27) {
if (e.which !== undefined || e.keyCode !== undefined) {
//safe_log("setting focus to menu button");
$("#menu").focus();
}
} /*, buttons: [ {text:"Close", click: function() {$("#toc_dialog").dialog("close");}}]*/ });
$('.ui-dialog')
.attr('aria-labelledby', 'ui-dialog-title-toc_dialog toc_head')
.attr('aria-live', 'polite');
$(".ui-dialog").keydown(function(e) {
//safe_log(e);
var key = e.which || e.keyCode;
// up arrow
if (key == 38 || (key == 9 && e.shiftKey)) {
e.preventDefault();
if ($(e.target).hasClass("ui-dialog-titlebar-close")) {
$(e.target).removeClass("ui-state-focus");
$("#toc_dialog").find("p.toc_section_title:not(.toc_section_not_available)").last().find("a").focus();
}
else {
var $prev_a = $(e.target).parent("p").prev("p").find("a");
if ($prev_a.length) {
$prev_a.focus();
}
else {
$(".ui-dialog-titlebar-close").focus();
}
}
}
// down arrow
else if (key == 40 || key == 9) {
e.preventDefault();
if ($(e.target).hasClass("ui-dialog-titlebar-close")) {
$(e.target).removeClass("ui-state-focus");
$("#toc_dialog").find("p.toc_section_title").first().find("a").focus();
}
else {
var $next_a = $(e.target).parent("p").next("p").find("a");
if ($next_a.length) {
$next_a.focus();
}
else {
$(".ui-dialog-titlebar-close").focus();
}
}
}
});
},
add_question: function(index, element) {
var a = player.activity; // this fn gets called within the scope of a jquery each, so we can't refer to "this"
var jq = $(element);
// see if we're in a question_pool or question_sequence block
var qs_parent = jq.parents("[data-block_type=question_sequence], [data-block_type=question_sequence_one_at_a_time]");
var q = a.questions[a.questions.length] = new Question({
"index": a.questions.length
, "number": jQuery.trim($("[data-type='number']", jq).html())
, "title": jQuery.trim($("[data-type='title']", jq).html())
, "jq": jq
, "points_possible": 0
});
// store the question index in the DOM too
jq.attr("data-question_index", q.index);
// get question queries
a.question_being_initialized = q;
$("[data-type='query']", jq).each(a.add_query);
// if the question has queries, add bling to the bottom
if (q.queries.length > 0) {
var html = "
";
var submit_handler;
// add a submit button if we're supposed to have one
// (image map and matching questions, which should contain one and only one query, don't have submit buttons)
if (q.queries[0].hasSubmitButton === true) {
// "answer_one" pool mode (yet to be fully implemented...)
if (q.pool_mode == 'answer_one') {
html += "";
submit_handler = player.activity.Show_Submit.bind( this, q.index );
} else {
html += a.question_submit_button(q);
submit_handler = player.activity.submit_question.bind( this, q.index);
}
}
// add a "give up" button if we're supposed to have one
// (image map questions, which should contain one and only one query, should have this button)
if (q.queries[0].hasGiveUpButton === true) {
html += "";
submit_handler = player.activity.give_up_question;
}
html += "
";
jq.append(html);
var nAgt = navigator.userAgent
var Mobile = nAgt.match( /(iPhone|iPod|iPad|Android|BlackBerry)/ );
var PC = !Mobile;
var mousedown = ( Mobile ) ? "touchstart" : "mousedown";
document.querySelector( "#question_submit_button_" + q.index ).addEventListener( mousedown, submit_handler );
// bind the submit_handler function to the button, passing in the question_index
//$("#question_submit_button_" + q.index).click({question_index:q.index}, );
// float instructor controls to right of action button
jq.prepend(a.instructor_question_controls(q));
// also, determine question points and weight at this time
for (var i = 0; i < q.queries.length; ++i) {
q.points_possible += q.queries[i].getPointsPossible();
}
// round to two decimal places, in case there are decimals
q.points_possible = Math.round(q.points_possible * 100) / 100;
}
// now that the question has been created, deal with sequences and pools
if (qs_parent.length > 0) {
// get sequence index and item
var qs_index = qs_parent.attr("question_sequence_index") * 1;
var qs = a.question_sequences[qs_index];
// place in sequence
var sequence_num = qs.questions.length;
qs.questions[sequence_num] = q;
// place reference to sequence in question
q.question_sequence = qs;
q.question_sequence_index = sequence_num;
// if this isn't #1, hide the question
if (sequence_num > 0) {
jq.hide();
}
// update the sequence navigator if it's there
$("#question_sequence_max_index_" + qs.index).html(sequence_num+1);
}
},
submit_question: function (question_index) {
this._super(question_index);
},
start_activity: function() {
var src = $( "[data-block_type=activity_iframe] iframe" ).attr( "src" );
var window_width = screen.width;
var window_height = screen.height;
player.activity_window = window.open( src, "activity_window", "width=" + window_width + ",height=" + window_height + ", left=0, top=0, toolbar=no, location=no, directories=no, status=no, scrollbars=no, resizable=no, copyhistory=no" );
},
create_start_activity_button: function() {
var button = $( "[data-block_type=start_activity_button]" );
if( button.length )
{
var button_html = "
" + button.text() + "
";
button.after( button_html );
}
},
check_activity_availability: function () {
//check URL. If on websterfw.com, then show content (do nothing), if not, then determine if content should show or if coming soon message should show
//safe_log("checking availability");
if (document.URL.indexOf('digfir-published') == -1) {
var isViewable = $("[key=activity_is_viewable]").html();
if (isViewable != null) {
isViewable = $.trim(isViewable);
isViewable = isViewable.toLowerCase();
if (document.URL.indexOf('show_activity') == -1) {
if (isViewable == "false") {
this.show_coming_soon_message();
}
}
}
}
},
show_coming_soon_message: function () {
var message = "This activity will be available soon.";
var html = "
" + message + "
";
$("#manuscript").before(html);
},
show_completion_message: function () {
// player.activity.grade_activity will always have been called before this fn
// so we'll have access to the properly-calculated activity properties below
var html = ""
+ "
"
+ "Congratulations! You have completed this activity."
+ "
You have received a provisional score for your essay answers, which have been submitted to your instructor.
"
+ "
"
+ "
Your grade has been submitted to your instructor.
"
+ ""
;
// section should have a block_type=activity_report paragraph to receive this info
$("[data-block_type=activity_report]").html(html).show();
$("html, body").animate({ scrollTop: $("[data-block_type=activity_report]").offset().top +12 }, {duration: 800, queue: false});
// show the grade submitted message if user_has_received_completion_alert is true
if (player.user_has_received_completion_alert == true) {
$("#grade_submitted_message").show();
}
},
show_section: function (section_to_show) {
var direction = "right";
var set_h2_focus = true;
if (section_to_show == "previous") {
section_to_show = this.section_currently_showing - 1;
direction = "left";
}
else if (section_to_show == "next") {
section_to_show = this.section_currently_showing + 1;
}
if (section_to_show == null || isNaN(section_to_show) || section_to_show < 0 || section_to_show >= this.sections.length) {
return;
}
// if user has to view sections in sequence and hasn't gotten up to this one, don't allow it
if (this.md.sequenced_sections == "true" && section_to_show > this.last_available_section) {
// but let instructors through
if (player.activity.is_instructor()) {
// only show this message once
if (!this.SHOWN_INSTRUCTOR_MESG) {
set_h2_focus = false;
var $cur_sec_h2 = $("#digfir_section_" + section_to_show).find("h2.section-title");
Standard_Dialog.alert("Please note: Students need to read and complete each section of the activity before moving on to the next section. Instructors, however, can skip around between sections as they choose.", {'title': 'Instructor Message', close: function(e) { $cur_sec_h2.focus(); }, h2_close: $cur_sec_h2, from: $cur_sec_h2 });
this.SHOWN_INSTRUCTOR_MESG = true;
}
}
else {
set_h2_focus = false;
Standard_Dialog.alert(this.md.section_sequence_message, {'title': 'Next Button Not Permitted' });
return;
}
}
this.show_section_animate(section_to_show, direction);
// process iframes for the section, unless all were preloaded
if (player.md.preload_all_iframes != "true") {
this.figures.process_iframes(this.get_current_section().jq);
}
this.update_section_status();
this.update_navigation();
// brb: set focus on h2
//safe_log("FIRST_PAGE = " + this.FIRST_PAGE + " and set_h2_focus = " + set_h2_focus);
if (!this.FIRST_PAGE && set_h2_focus) {
$("#digfir_section_" + this.section_currently_showing).find("h2.section-title").focus();
}
this.FIRST_PAGE = false;
},
show_section_animate: function (section_to_show, direction) {
//log with Google Analytics
this.log_section_view(section_to_show);
// make sure modal window is closed
//$("#step_button").blur();
$("#toc_dialog").dialog("close");
// slide in using parent function
//this._super(section_to_show, direction);
// hide currently showing section
/*
if (this.section_currently_showing != null) {
this.get_current_section_jq().hide();
}
*/
//$("#digfir_section_" + this.section_currently_showing).attr("aria-hidden", "true");
this.section_currently_showing = section_to_show;
//$("#digfir_section_" + this.section_currently_showing).attr("aria-hidden", "false");
//this.get_current_section_jq().show();
// Only show h1 to browsers on first slide
if (this.section_currently_showing == 0) {
$("h1.section-title").removeClass("v-h");
}
else {
$("h1.section-title").addClass("v-h");
}
// update slide_number and title
//safe_log("show_section_anim");
//$("#slide_title").html(this.get_current_section().title);
$("#slide_number").html((section_to_show + 1) + " of " + this.sections.length + " ");
$("[data-type='section']").each(function() {
var $this = $(this);
var sec_idx = $this.attr("data-section-index");
if (player.section_currently_showing == sec_idx) {
//safe_log("showing section " + sec_idx);
//$this.css("display", "block").attr("aria-hidden", "false");
//$this.attr("aria-hidden", "false");
}
else {
//safe_log("hiding section " + sec_idx);
$this.css("display", "none").attr("aria-hidden", "true");
//$this.attr("aria-hidden", "true");
}
});
this.get_current_section_jq().fadeIn("slow").attr("aria-hidden", "false");
// if this is the first/last section, dim the previous/next button
if (this.section_currently_showing == 0) {
$(".prev_button").addClass("disabled_prev_button").attr("aria-hidden", "true");
} else {
$(".prev_button").removeClass("disabled_prev_button").attr("aria-hidden", "false");
}
if (this.section_currently_showing < this.sections.length - 1) {
$(".next_button").addClass("active_next_button").attr("aria-hidden", "false").removeClass("disabled_next_button");
} else {
$(".next_button").removeClass("active_next_button").attr("aria-hidden", "true").addClass("disabled_next_button");
}
/*
$("#overlay-left .prev_button").unbind("click").click(function(e) {
e.preventDefault();
player.show_section("previous");
});
$("#overlay-right .next_button").unbind("click").click(function(e) {
e.preventDefault();
player.show_section("next");
});
*/
/*
if (this.section_currently_showing == 0) {
$(".getstarted_button").addClass("active_getstarted_button");
}
else {
$(".getstarted_button").removeClass("active_getstarted_button");
}
*/
//apply click handler to termref items in the section - the global call done on init doesn't get the content in queries
//player.glossary.set_click_event_for_terms_in_section(this.get_current_section_jq());
//this.get_current_section_jq().show();
},
show_navigation: function () {
//safe_log("show_navigation");
var chaptertitle = $("h1.section-title").html();
/*var html = ""*/ /*
";
if (this.activity_thumbnail_src != null) {
html += "";
}
html += "
" + this.md.activity_type_title + "
"
+ "
" + this.activity_title + "
"
+ "
" //titles
*/
/*
+ "
"
+ "
MENU
"
+ "
" //top_nav
*/
/*
+ "
"
+ "
"+chaptertitle+"
"
+ ""
+ "
"
*/
//+ ""
//+ ""
//+ "" // top_banner
// ;
// $("[data-type=chapter]").before(html);
//stg
//console.log(chaptertitle);
html = "";
if (this.sections.length > 1 && this.md.hide_toolbar != "true") {
//html += ""
// brb: don't think pagination div is being use
//+ ""
/*
+ "
" // toolbar
;
}
$("[data-type=chapter]").after(html);
$("#overlay-left .prev_button").click(function(e) {
//e.preventDefault();
player.show_section("previous");
});
$("#overlay-right .next_button").click(function(e) {
//e.preventDefault();
player.show_section("next");
});
/* Hiding the next button
// button at the bottom of the manuscript to go on to the next step
$("[data-type=chapter]").append(UI_Elements.get_button_html({
id: "step_button",
label: "Next",
fn: 'player.show_section("next")'
}));
*/
/*
// icons for toolbar and next buttons...
$('#previous_button').button({
icons: {
primary: "ui-icon-circle-triangle-w"
}
});
$('#next_button').button({
icons: {
secondary: "ui-icon-circle-triangle-e"
}
});
//$('#slide_number').button({
// icons: {
// secondary: "ui-icon-circle-triangle-s"
// }
//});
$('#step_button').button({
icons: {
secondary: "ui-icon-circle-triangle-e"
}
});
// activate all other buttons
UI_Elements.activate_buttons();
*/
},
initialize: function () {
var fontHTML = '';
$("body").append(fontHTML);
//stg
$("[data-type=chapter][data-block_type=no-menu]").siblings("#top_banner").find("#top_nav").hide(0);
//$("div[data-type=section] span[data-type=title]").find("continued").wrap("");
/*
$("h2.section-title span[data-type=title]").each(function() {
var newText = $(this).html().replace("(continued)", "(continued)");
$(this).html(newText);
});
*/
// brb: set up h1
$("h1.section-title").each(function() {
var $this = $(this);
var title = $this.find("[data-type='title']").html();
$this.html(title);
$this.css('display', 'block');
});
$("[data-block_type='activity_title']").remove();
// brb: header
var chaptertitle = $("h1.section-title").html();
var html = ""
+ "
"
+ "
"+chaptertitle+"
"
+ ""
+ "
"
+ ""
+ "";
$("[data-type=chapter]").before(html);
/*
$("#menu").click(function(e) {
player.show_toc();
});
*/
// brb: move h1 into header
$("h1.section-title").appendTo("#top_banner");
//$("[data-type='chapter']").changeElementType("main");
$("[data-type='section']").changeElementType("section");
$("[data-type='question']").each(function() {
var $this = $(this);
$this.changeElementType("form");
});
// fix up question numbers
$("[data-type='question'] h3 [data-type='number']").each(function() {
var $this = $(this);
var $h3 = $this.parent();
var number = $this.text().trim().replace(/\d+\./, '');
// add aria-labelledby to question div
//$section.attr("aria-labelledby","question_header_" + number);
$h3.html("Question " + number + ".");
// add id to h3
$h3.attr("id", "question_header_" + number);
// add
for question text
// brb: uncomment to go back to question text outside of legend
$h3.after("
");
});
// brb: make all sections hidden
$("[data-type='section']").attr("aria-hidden", "true");
this._super();
this.activity = new Activity_custom();
this.check_activity_availability();
//player.glossary.set_click_event_for_terms_in_section = function (sectionjq) {
/*
safe_log("doing click event for terms");
$(sectionjq).find("[data-type='termref']").each(function (index, element) {
// opening with a click event, as in the following line, doesn't work for queries;
// in any case I think a "real" link is probably better anyway.
// $(element).click(t.open_link).css("cursor", "pointer");
var jq = $(element);
jq.unbind("click");
safe_log("found term " + jq.html());
jq.click(function () { player.glossary.show_definition(this); });
});
*/
// }
//disableTouchZooming();
this.create_start_activity_button();
},
initialize2: function () {
this._super();
if (player.ARGA_running) {
try {
var dejs_arr = ARGA_API.dejs_data;
for (var i=0; iSlide " + slide_num + " of " + player.sections.length + ": " + h2_html);
$h2.css('display', 'inline-block');
});
// brb: determine if due date has passed for assignment
// Note: If you don't want all the due date fixes for this activity then
// just comment out this if statement.
if (player.ARGA_running) {
if (Get_ARGA_Data("due_date_has_passed") == 1) {
this.DUE_DATE_HAS_PASSED = true;
}
}
// brb: Need to set allowfullscreen to true on parent iframe so videos
// can go to full screen
$('#document-body-iframe', window.parent.document).attr('allowfullscreen', 'true').attr('mozallowfullscreen', 'true').attr('webkitallowfullscreen', 'true');
// brb: make first h2 visibly hidden
//$("#digfir_section_0 > h2.section-title").addClass("v-h");
// brb: convert subtitles to h3
$("[data-block_type='subtitle'] p").each(function() {
var $this = $(this);
$this.addClass("subtitle");
$this.changeElementType("h3");
});
// brb: Remove 'References' button, make it a sub-header instead
$("[data-block_type='references']").each(function() {
var $this = $(this);
var $ref_button = $this.find("[data-onclick_trigger]");
$ref_button.before("
References
");
$ref_button.remove();
});
// brb: All figures will be hidden from screen readers
$("[data-type='figure']").each(function() {
var $this = $(this);
var $img = $this.find("img");
if ($img.length == 0) {
return;
}
var alt_text = $img.attr("alt");
if (!(/\S/.test(alt_text))) {
$this.attr("aria-hidden", "true");
$this.attr("role", "presentation");
$img.attr("aria-hidden", "true");
$img.attr("role", "presentation");
}
$this.changeElementType("figure");
});
// brb: fix up termrefs
/*
$("[data-type='termref']").each(function() {
var $this = $(this);
$this.attr('tabindex', '0');
$this.attr('role', 'button');
});
$('[data-type="termref"]').keydown(function (e) {
var key = e.keyCodse || e.which;
if (key === 32 || key === 13) {
e.preventDefault();
player.glossary.show_definition(this);
}
});
*/
// brb: various handlers
/*
$("#top_nav").delegate("#menu", "click keydown", function(e) {
//safe_log(e);
if (e.type === "keydown") {
if (e.which == 32 || e.keyCode == 32 || e.which == 13 || e.keyCode == 13) {
e.preventDefault();
player.show_toc();
}
}
else {
player.show_toc();
}
});
*/
// brb: fix up forms
$("form").each(function() {
var $this = $(this);
$this.attr("action","#");
var q_idx = $this.attr("data-question_index");
});
//set up Google Analytics
//get the url without the querystring parts
var url = location.pathname;
//now get user info only if ARGA is initialized
var userID = "anonymous";
if (player.ARGA_running) {
userID = Get_ARGA_Data("learner_id")
}
// brb: click_button for Childhood Obesity page 4
$("[data-block_type='click_button']").each(function() {
var $this = $(this);
var $button = $(this).find("[data-type='button']");
var $target = $(this).find("[data-type='target']");
$button.attr("role", "button").attr("tabindex", "0").attr("aria-expanded", "false");
// all targets start as hidden
$target.attr("aria-hidden", "true").attr("tabindex", "-1");
$button.bind("click keydown", function(e) {
// if keydown, make sure it is either return or space
if (e.type === "keydown") {
var key = e.keyCode || e.which;
if (key !== 32 && key !== 13) {
return;
}
}
var $this = $(this);
var expanded = $this.attr("aria-expanded");
if (expanded == "false") {
$target.attr("aria-hidden", "false").css("display", "block");
$this.attr("aria-expanded", "true");
$target.focus();
}
else {
$target.attr("aria-hidden", "true").css("display", "none");
$this.attr("aria-expanded", "false");
}
});
});
$("[data-block_type='bigger_text_block']").each(function() {
var $this = $(this);
var $h3 = $this.children("[data-type='box_inner']").children("h3[data-type='title']");
if ($h3.length == 1) {
var html = $h3.html();
if (html == "") {
$h3.remove();
}
}
});
// if there is a block_type=question_text in the form then use
// that for the question text
$("form").each(function() {
var $this = $(this);
var $q_text = $this.find("[data-block_type='question_text']");
if ($q_text.length === 1) {
var text = $q_text.children("p").html();
$this.children(".question_text").html(text);
$q_text.attr("aria-hidden", "true").css("display", "none");
}
});
ga('create', 'UA-52432131-1', { 'userId': userID });
ga('set', 'page', url);
ga("send", "pageview");
},
log_section_view: function (sectionNum) {
ga("send", "event", "Navigation", "LoadSection", sectionNum);
}
});
player = new Player_devtk();
Question = Question.extend({
// type = 'feedback' or 'points'
display_feedback_mesg: function(html, type) {
var $question = $("[data-question_index='" + this.index + "']");
var fb_mesg_id = "question_" + this.index + "_fb_mesg";
// remove current fb
$("#" + fb_mesg_id).remove();
var $query_wrap = $("#query_wrap_" + this.index);
if ($query_wrap.length == 1) {
$query_wrap.append("
" + html + "
");
}
else {
$question.append("
" + html + "
");
}
// change the h3 question header to read 'completed'
var $h3 = $question.find("h3");
if (!/Completed/.test($h3.text())) {
var new_html = $h3.html() + " [Completed]";
}
$h3.html(new_html);
},
remove_alert_mesg: function() {
var $question = $("[data-question_index='" + this.index + "']");
var alert_mesg_id = "question_" + this.index + "_alert_mesg";
$("#" + alert_mesg_id).remove();
},
display_alert_mesg: function(mesg, type) {
if (mesg === undefined || mesg === "") {
mesg = "You must answer the question before submitting.";
}
if (type === undefined) {
type = "error";
}
var $question = $("[data-question_index='" + this.index + "']");
var alert_mesg_id = "question_" + this.index + "_alert_mesg";
// remove current alert
$("#" + alert_mesg_id).remove();
var alert_mesg = "";
if (type === "hint") {
alert_mesg += this.create_hint_mesg(mesg);
}
else if (type === "manual") {
alert_mesg += mesg;
}
else {
alert_mesg += this.create_error_mesg(mesg);
}
var $query_wrap = $("#query_wrap_" + this.index);
if ($query_wrap.length == 1) {
$query_wrap.append("
" + alert_mesg + " Please try again.
");
}
else {
$question.append("
" + alert_mesg + " Please try again.
");
}
},
display_info_mesg: function(mesg) {
var $question = $("[data-question_index='" + this.index + "']");
var alert_mesg_id = "question_" + this.index + "_alert_mesg";
// remove current alert
$("#" + alert_mesg_id).remove();
var alert_mesg = mesg;
var $query_wrap = $("#query_wrap_" + this.index);
if ($query_wrap.length == 1) {
$query_wrap.append("
" + alert_mesg + "
");
}
else {
$question.append("
" + alert_mesg + "
");
}
},
create_error_mesg: function(mesg) {
return "Submission error. " + mesg;
},
create_hint_mesg: function(mesg) {
return "Sorry, your answer is incorrect. " + mesg;
}
});
MC_Query = MC_Query.extend({
getQueryTextForARGA: function() {
if (this.query_text_for_ARGA != null && this.query_text_for_ARGA != "") {
return this.query_text_for_ARGA;
}
else if (this.query_text != null && this.query_text != "") {
var cleaned_text = clean_query_text(this.query_text);
return cleaned_text;
}
else {
return "see page for question context";
}
},
user_has_answered: function () {
if ($('input:radio[name=query_answer_' + this.query_index + ']:checked').val() !== undefined) {
return true;
}
else {
return false;
}
},
parseSource: function() {
// initialize vars
this.choices = new Array();
this.choices_fb = new Array();
this.choices_hint = new Array();
this.choice_ids = new Array();
this.correct_answer_index = null;
this.user_answer_index = null;
// lines might start with "MC:"; if so, strip it out
var s = this.query_source.replace(/^MC:\s*/, "");
// split and go through the lines
var lines = s.split(this.line_separator);
this.query_text = "";
// the first choice has to be "a" or "A"
var choice_re = /^[\*]?([aA])[\.:\)]/;
for (var i = 0; i < lines.length; ++i) {
// get line and trim whitespace
var l = $.trim(lines[i]);
// choice
if (l.search(choice_re) > -1) {
var ident = RegExp.$1;
var choice_text = l.replace(/^[\*]?\w[\.:\)]\s*/, "");
ident = ident.toUpperCase();
// extract feedback for the choice, if there
var choice_fb = null;
if (/\[\[/.test(choice_text)) {
choice_text = choice_text.replace(/\s*\[\[(.*?)\]\]\s*/, "");
choice_fb = RegExp.$1;
// if feedback is simply "correct" or "incorrect", ignore it.
if (choice_fb.toLowerCase() == 'correct' || choice_fb.toLowerCase() == 'incorrect') {
choice_fb = null;
}
}
// extract choice hint
var choice_hint = null;
if (/{{/.test(choice_text)) {
choice_text = choice_text.replace(/\s*{{(.*?)}}\s*/, "");
choice_hint = RegExp.$1;
}
this.choices.push(choice_text);
this.choices_fb.push(choice_fb);
this.choices_hint.push(choice_hint);
this.choice_ids.push(ident);
// if line started with *, it's the correct answer
if (l.search(/^[\*]/) > -1) {
correct_choice = ident;
this.correct_answer_index = this.choice_ids.length - 1;
}
// update choice_re so that any letter is OK from here on
choice_re = /^[\*]?(\w)[\.:\)]/;
// points_possible
} else if (l.search(/^_points:\s*(\d+)/i) > -1) {
this.points_possible = RegExp.$1;
// metadata -- starts with "_[a-zA-Z]"
} else if (l.search(/^\_[a-zA-Z]/) > -1) {
this.extractMetadata(l);
// by default add it to the query text
} else {
this.query_text += l + "\n";
}
}
// if the query starts with \d\.\s*, strip it out
// *no, this version doesn't work; it also strips out "1." from "5TB-1.png"*//
// this.query_text = this.query_text.replace(/(\n?)\d+\.\s*/, "\1");
// now we should be done with the query text. Strip trailing white space
this.query_text = this.query_text.replace(/\s*$/, "");
// shuffle choices, unless md.never_scramble is true
this.choice_order = new Array();
for (var j = 0; j < this.choices.length; ++j) this.choice_order[j] = j;
if (this.md.never_scramble != "true") {
this.choice_order.shuffle();
}
// if no correct answer was given, we need to explicitly note that.
if (this.correct_answer_index == null) {
this.md.no_correct_answer = "true";
}
// replace any remaining \n's with
// NO: we're doing this in getHTML instead now
// this.query_text = this.query_text.replace(/\n/g, "
");
},
correct_incorrect_feedback: function(mode, is_correct) {
var html = "";
// get correct answer as presented to user
for (var i = 0; i < this.choices.length; ++i) {
if (this.choice_order[i] == this.correct_answer_index) {
break;
}
}
// if the question explicitly defines feedback for the user's answer, use it as the feedback
if (this.user_answer_index != null && this.choices_fb[this.user_answer_index] != null) {
html += this.choices_fb[this.user_answer_index];
}
// the correct answer will be highlighted in green, so there's no reason to say anything more.
// now, if we got any feedback, enclose it in a div
if (html != "") {
html = "" + html + "";
}
return html;
},
getHTML: function(mode) {
var label_tag = "label";
/*
if (mode === "review_correct_incorrect" || mode === "review") {
label_tag = "p";
}
*/
// initialize imagemap elements
if (this.imagemap_initialized === false) {
var question_jq = this.jq.parent();
this.im_init(question_jq);
this.imagemap_initialized = true;
}
// start with the query text, if there
var html = "";
// get a possible feedback string; this fn will take account of mode
//html += this.correct_incorrect_feedback(mode, is_correct);
// side effect: update the question text
for this question
var $q_text_p = $("#question_text_" + this.parent_question.index);
var q_text = this.query_text;
// brb: remove question number at beginning of question text
q_text = q_text.replace(/^\d+\. /, "");
// check if this is a fill-in-the-blank
if (/__/.test(q_text)) {
q_text = q_text.replace(/(_[_]+)/g, "$1BLANK");
q_text = "Fill in the blank: " + q_text;
}
// brb: uncomment to go back to question text outside of legend
$q_text_p.html(q_text);
return html;
},
query_text_html_mc: function() {
if (this.query_text != "" && this.md._hide_query_text != "true") {
// replace newlines with
var qt = jQuery.trim(this.query_text).replace(/\n/g, " ")
//return ""
//return "";
return "";
}
else {
return "";
}
}
});
DD_Query = DD_Query.extend({
parseSource: function() {
// initialize vars
this.choices = new Array();
this.correct_answer_index = null;
this.user_answer_index = null;
// DD's are always one line only -- if query_text is specified, it's via metadata (see below)
this.query_text = "";
// the line might start with "DD:"; if so, strip it out
var s = jQuery.trim(this.query_source.replace(/^DD:\s*/, ""));
// if line ends with "~~\d+", that's points
if (s.search(/(.*)~~([\.\d]+)$/) > -1) {
s = RegExp.$1;
this.points_possible = RegExp.$2;
}
// if the line starts with "!!", don't scramble
if (s.substr(0, 2) == "!!") {
this.md.never_scramble = "true";
// strip the !! out of answer
s = s.replace(/^\!\!/, "");
}
// if the line ends with "??", any answer is correct
if (s.substr(-2, 2) == "??") {
this.md.no_correct_answer = "true";
// strip the ?? out of answer
s = s.replace(/\?\?$/, "");
}
// brb: check for label text
if (s.search(/(.*)\[\[(.*?)\]\]$/) > -1) {
s = RegExp.$1;
this.label_text = RegExp.$2;
}
// if any commas were sent in as "\,", turn them into ,
s = s.replace(/\\,/g, ",");
// likewise, turn "\*" into *
s = s.replace(/\\\*/g, "*");
// we might have "'s indicating double quotes in the answers;
// convert these to actual double quotes so that they display properly (though it might not matter)
s = s.replace(/\"/g, '"');
// answer string should be something like "choice 1, choice2, *correct choice"
// so split it and find the correct answer
var answers = s.split(/,\s*/);
var correctChoice = -1;
for (var i = 0; i < answers.length; ++i) {
var ans = answers[i];
// look for points...
if (ans.search(/^_points:\s*(\d+)/i) > -1) {
this.points_possible = RegExp.$1;
// skip to the next answer
continue;
// or query text
} else if (ans.search(/^_query_text:\s*(.*)/i) > -1) {
this.query_text = RegExp.$1;
// skip to the next answer
continue;
// or metadata -- starts with "_[a-zA-Z]"
} else if (ans.search(/^\_[a-zA-Z]/) > -1) {
this.extractMetadata(ans);
// skip to the next answer
continue;
// if we've found the correct answer...
} else if (ans.substr(0,1) == "*") {
// if we already got a correctChoice, there's an error
if (this.correct_answer_index != null) {
return "error in pulldown answer (too many correct answers): " + s + "";
}
// otherwise this one is correct
this.correct_answer_index = i;
// strip the leading *
ans = ans.substr(1);
}
// convert *s to literal *'s now; also convert commas
ans = ans.replace(/\*/g, '*');
ans = ans.replace(/\,/g, ',');
// transfer to choices, trimming in the process
this.choices.push(jQuery.trim(ans));
}
// note: answers will be coded 0, 1, 2, 3, etc., with correctChoice numbered accordingly
// (e.g. if first answer is correct, correctChoice is 0)
// if we didn't get a correct choice, or if there aren't enough items,
// that's an error
if (this.correct_answer_index == null) {
return "error in pull down answer (no correct answer specified): " + s + "";
} else if (this.choices.length <= 1) {
return "error in pulldown answer (0 or 1 choices specified): " + s + "";
}
// shuffle choices, unless md.never_scramble is true
this.choice_order = new Array();
for (var j = 0; j < this.choices.length; ++j) this.choice_order[j] = j;
if (this.md.never_scramble != "true") {
this.choice_order.shuffle();
}
// deal with error handling...
},
finish_inline_query: function(correct_answer, mode) {
// if mode is "delivery" (default) or this.md.no_correct_answer is true,
// don't show this at all
if (mode == 'delivery' || mode == '' || mode == null || this.md.no_correct_answer == "true") {
return "";
}
var s = "";
// image that indicates if the query is correct or incorrect
if (mode == 'review' || mode == 'review_correct_incorrect') {
var fbclass, alt;
if (this.isCorrect()) {
fbclass = 'query_correct_feedback_span';
alt = 'Correct';
} else {
fbclass = 'query_incorrect_feedback_span';
alt = 'Incorrect';
}
s += "";
//s += "";
}
// correct answer -- we show this in both review and preview mode,
// but not in review_correct_incorrect mode
// also don't show it if there *is* no correct answer
if (mode != 'review_correct_incorrect' && this.md.no_correct_answer != "true") {
var preface = "";
if (this.isCorrect()) {
preface += "Correct. The answer is: ";
}
else {
preface += "Your answer is incorrect. The correct answer is: ";
}
s += '' + preface + correct_answer + '';
}
s += "";
return s;
},
user_has_answered: function () {
var answer = $("#query_answer_" + this.query_index).val();
if (answer == "-1") {
return false;
}
return true;
},
// mode should be "delivery" or "review" or "review_correct_incorrect"; "delivery" is assumed
getHTML: function(mode) {
var html = "";
// DD's never have query text
// Start a nobr tag for the item
html = '';
// if we're in preview mode or
// (a student answer has been given and we're not in review_correct_incorrect mode),
// or the student got it correct
// disable the select
var disabled = "";
if (mode == 'preview' || (mode != 'review_correct_incorrect' && this.user_answer_index != null) || this.isCorrect()) {
disabled = "disabled";
}
if (this.label_text) {
html += "";
}
else {
html += "";
}
html += ''
html += this.finish_inline_query(this.choices[this.correct_answer_index], mode);
// Close off the nobr tag for the item
html += '';
return html;
}
});
//Overriding default essay query feedback text
Essay_Query = Essay_Query.extend({
getQueryTextForARGA: function() {
if (this.query_text_for_ARGA != null && this.query_text_for_ARGA != "") {
return this.query_text_for_ARGA;
}
else if (this.query_text != null && this.query_text != "") {
var cleaned_text = clean_query_text(this.query_text);
return cleaned_text;
}
else {
return "see page for question context";
}
},
parseSource: function() {
// set points_are_provisional metadata default; it can be overridden by
// an explicit metadata line (_points_are_provisional: false)
this.md.points_are_provisional = "true";
// lines might start with "EQ:" or "ES:"; if so, strip it out
var s = this.query_source.replace(/^EQ:\s*/, "");
s = s.replace(/^ES:\s*/, "");
// split and go through the lines
var lines = s.split(this.line_separator);
this.query_text = "";
this.label = undefined;
for (var i = 0; i < lines.length; ++i) {
// get line and trim
var l = jQuery.trim(lines[i]);
// points_possible
if (l.search(/^_points:\s*(\d+)/i) > -1) {
this.points_possible = RegExp.$1;
// metadata -- starts with "_[a-zA-Z]"
}
else if (l.search(/^_label:\s*(.*)/i) > -1) {
this.label = RegExp.$1;
// metadata -- starts with "_[a-zA-Z]"
}
else if (l.search(/^\_[a-zA-Z]/) > -1) {
this.extractMetadata(l);
// by default add it to the query text
}
else {
this.query_text += l + "\n";
}
}
// now we should be done with the query text. Strip spaces
this.query_text = jQuery.trim(this.query_text);
// replace any remaining \n's with
this.query_text = this.query_text.replace(/\n/g, " ");
},
user_has_answered: function () {
var answer = $("#query_answer_" + this.query_index).val();
if (/\S/.test(answer)) {
return true;
}
return false;
},
query_text_html_es: function() {
if (this.query_text != "" && this.md._hide_query_text != "true") {
// replace newlines with
var qt = jQuery.trim(this.query_text).replace(/\n/g, " ")
return qt;
}
else {
return "";
}
},
getHTML: function (mode) {
// start with the query text, if there
//var html = this.query_text_html();
var html = "";
var val, disabled;
if (!this.userHasAnswered() || mode == 'preview') {
val = "";
disabled = "";
// otherwise we have an answer, so fill it in
} else {
// make sure we convert double quotes to " for placement in 'value="xxx"' attributes
val = this.user_answer;
// convert breaks to newlines
val = val.replace(/ /g, "\n");
// also disable the input if we're not in review_correct_incorrect mode
if (mode != "review_correct_incorrect") {
disabled = "disabled";
}
}
var label_text = "";
if (this.label !== undefined) {
label_text = this.label;
}
else {
label_text = "Answer box for question " + this.parent_question.index;
}
html += "";
html += "";
// if answer was just entered and grade is 100, also show the "provisional" message
// (unless for this question it isn't provisional)
/*
if (this.answer_was_just_entered && this.grade == 100 && this.md.points_are_provisional == "true") {
html += "
Your answer has been provisionally accepted. You will receive full credit at this time, but your instructor may update your grade later after evaluating your answer.
";
}
*/
if (mode === undefined) {
// side effect: update the question text
for this question
var $q_text_p = $("#question_text_" + this.parent_question.index);
var q_text = this.query_text_html_es();
// brb: remove question number at beginning of question text
q_text = q_text.replace(/^\d+\. /, "");
$q_text_p.html(q_text);
}
return html;
}
});
function Get_Correct_ARGA_Grade() {
if (!ARGA_API || ARGA_API.grade === null || ARGA_API.grade === "") {
return -1
}
else {
return ARGA_API.grade
}
}
/*
function onTemplateLoaded(theID) {
safe_log("template loaded " + theID);
player.videoIsReady[theID] = true;
var vidplayer = brightcove.api.getExperience(theID);
safe_log("got player");
var playerModule = vidplayer.getModule(brightcove.api.modules.APIModules.VIDEO_PLAYER);
safe_log("god module");
playerModule.addEventListener(brightcove.api.events.MediaEvent.COMPLETE, player.onVideoComplete);
}
*/
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
WebFontConfig = {
google: { families: [ 'Open+Sans:400,300:latin', 'Montserrat:400,700:latin', 'Josefin+Slab:400,600,700:latin' ] }
};
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
var Standard_Dialog = function () {
// PRIVATE VARS AND FUNCTIONS
var private_var = 5;
function private_method() {
// do stuff here
}
// PUBLIC VARS AND FUNCTIONS
return {
public_var: 10,
// other common options:
// title: "Foo"
// close: function
// buttons: [{text:"OK", click: Standard_Dialog.close}]
open: function (html, options) {
if (options == null) {
options = {};
}
if (options.width == "auto") {
options.width = null;
} else if (options.width == null) {
options.width = 450;
}
options.modal = true;
if (options.draggable == null) {
options.draggable = false;
}
if (options.resizable == null) {
options.resizable = false;
}
if (options.buttons == "none") {
options.buttons = null;
} else if (options.buttons == "OK" || options.buttons == null) {
options.buttons = [{
text: "OK",
click: function () {
Standard_Dialog.close();
}
}];
}
if (options.from) {
options.buttons = [
{
text: "OK",
click: function () {
Standard_Dialog.close();
options.from.focus();
}
}
];
options.close = function () {
Standard_Dialog.close();
options.from.focus();
}
}
options.dialogClass = "noclose";
var $standardDialog = $("#standard_dialog_div");
$standardDialog.dialog("close");
$standardDialog.remove();
$standardDialog = $('
')
.attr('id','standard_dialog_div')
// .attr('aria-live', 'polite');
.html(html);
// //if we want to only listen to content but not buttons
// //we add timeout to let reader view this content changes
// setTimeout(function(){
// $standardDialog.html(html);
// });
$("body").append($standardDialog);
$standardDialog.dialog(options);
$('.ui-dialog')
.attr('aria-labelledby', 'ui-dialog-title-standard_dialog_div standard_dialog_div')
.attr('aria-live', 'polite');
if (document.all) {
$('.ui-dialog').css('top', '255px');
}
$(".ui-dialog-buttonset button").keydown(function (e) {
if ((e.keyCode || e.which) === 9 && !e.shiftKey) {
$("#standard_dialog_div").focus();
$('.ui-dialog-buttonset button').removeClass('ui-state-focus');
e.preventDefault();
}
}
);
$standardDialog.keydown(function (e) {
if ((e.keyCode || e.which) === 9 && e.shiftKey) {
$(".ui-dialog-buttonset button").focus();
//$('.ui-dialog').find('.ui-dialog-titlebar-close').removeClass('ui-state-focus');
e.preventDefault();
}
}
);
},
// for now alert is just like any other dialog; we could change that later.
wait: function (html, options) {
if (options == null) {
options = {};
}
options.buttons = "none";
this.open(html, options);
},
alert: function (html, options) {
this.open(html, options);
},
close: function (html, options) {
// when we close from here, we *don't* call the .dialog("close") fn, so if you need to call the fn defined
// as the onclose event when you called Standard_Dialog.open(), you should do that separately
// $("#standard_dialog_div").dialog("close");
$("#standard_dialog_div").remove();
}
// Remember: no comma after last item
}; // end return for public vars and functions
}();
var Glossary = Class.extend({
terms: {},
show_definition: function (el) {
var jq = $(el);
var index = jq.attr("data-term");
if (index == "" || index == null) {
index = jq.html();
}
if (index != "" && index != null) {
index = index.toLowerCase();
var term = player.glossary.terms[index];
var html;
if (term == null) {
html = "No definition found for " + index;
} else {
html = "" + term.term + ": " + term.definition;
}
Standard_Dialog.open(html, {
"title": "Glossary Term",
// "modal": false,
// "draggable": true,
"buttons": "OK",
from: jq
});
}
},
init: function () {
var terms = this.terms;
// find all terms
$("[data-type='glossaryentry']").each(function (index, element) {
var jq = $(element);
var term = jq.find("[data-type='term']").html();
var definition = jq.find("[data-type='definition']").html();
if (term != "" && definition != "" && term != null && definition != null) {
// index terms object by lower-case, html-stripped version of term
var index = term.toLowerCase();
index = index.replace(/<[^>]+>/, "");
terms[index] = {'term': term, 'definition': definition};
}
});
$('[data-type="termref"]').attr('tabindex', '0').attr('role', 'button');
$("[data-type='termref']").each(function (index, element) {
// opening with a click event, as in the following line, doesn't work for queries;
// in any case I think a "real" link is probably better anyway.
// $(element).click(t.open_link).css("cursor", "pointer");
var jq = $(element);
jq.click(function () {
player.glossary.show_definition(this);
});
});
$('[data-type="termref"]').keyup(function (e) {
var key = e.keyCode || e.which;
if (key === 32) {
player.glossary.show_definition(this);
}
});
$('[data-type="termref"]').keydown(function (e) {
var key = e.keyCode || e.which;
if (key === 32) {
e.preventDefault();
}
if (key === 13) {
e.preventDefault();
player.glossary.show_definition(this);
}
});
}
});
MA_Query = MA_Query.extend({
// ========================================
// define and set defaults for variables specific to this query type
pairs: null,//new Array(), //MT (2013-10-11): need to instantiate that this with parseSource function() below see DF-152
right_side_order: new Array(),
correct_answer: "",
query_complete: false,
hasSubmitButton: false,
last_clicked_side: null,
last_clicked_index: null,
answers_correct: 0,
//choices: new Array(),
//choice_ids: new Array(),
//correct_answer_index: null,
//user_answer_index: null,
getQueryTextForARGA: function() {
if (this.query_text_for_ARGA != null && this.query_text_for_ARGA != "") {
return this.query_text_for_ARGA;
}
else if (this.query_text != null && this.query_text != "") {
var cleaned_text = clean_query_text(this.query_text);
return cleaned_text;
}
else {
return "see page for question context";
}
},
user_has_answered: function() {
return true;
},
// ========================================
// initialization
parseSource: function() {
// initialize vars
// lines might start with "MA:"; if so, strip it out
var s = this.query_source.replace(/^MA:\s*/, "");
//MT (2013-10-11): need to re-instantiate a new Array with each new object/query.
this.pairs = new Array();
// split and go through the lines
var lines = s.split(this.line_separator);
this.query_text = "";
var points_explicitly_specified = false;
// the first choice has to be "a" or "A"
var choice_re = /^([aA])[\.:\)]/;
for (var i = 0; i < lines.length; ++i) {
// get line and trim whitespace
var l = $.trim(lines[i]);
// pair
if (l.search(choice_re) > -1) {
// remove opening letter
l = l.replace(/^\w[\.:\)]\s*/, "");
// split at ::
var pair = l.split(/\s*::\s*/);
if (pair.length < 0) {
pair = [l, "Bad matching pair"];
}
this.pairs.push(pair);
if (this.correct_answer != "") this.correct_answer += "; ";
this.correct_answer += pair[0] + " → " + pair[1];
// update choice_re so that any letter is OK from here on
choice_re = /^(\w)[\.:\)]/;
// points_possible
} else if (l.search(/^_points:\s*(\d+)/i) > -1) {
this.points_possible = RegExp.$1;
points_explicitly_specified = true;
// metadata -- starts with "_[a-zA-Z]"
} else if (l.search(/^\_[a-zA-Z]/) > -1) {
this.extractMetadata(l);
// by default add it to the query text
} else {
this.query_text += l + "\n";
}
}
// now we should be done with the query text. Strip trailing white space
this.query_text = this.query_text.replace(/\s*$/, "");
// shuffle right_side_order
this.right_side_order = new Array();
for (var j = 0; j < this.pairs.length; ++j) this.right_side_order[j] = j;
this.right_side_order.shuffle();
// if points weren't explicitly specified, set to the number of pairs
if (!points_explicitly_specified) {
this.points_possible = this.pairs.length;
}
},
// ========================================
// extend query functions
setQueryData: function(qd) {
this._super(qd);
// for MA queries, if we get query_data, that's whether or not the user has completed the question
if (qd != "" && qd != null) {
this.query_complete = ((qd + "") == "true");
}
},
restoreAnswerFromARGA: function(answer) {
if (answer == 'Completed') {
this.query_complete = true;
}
},
getQueryTypeForARGA: function() {
return 'matching';
},
getCorrectAnswerForARGA: function() {
// not sure what to do here...
return this.correct_answer;
},
getUserAnswerForARGA: function() {
if (this.query_complete == false) {
return 'Not complete';
} else {
return 'Completed';
}
},
// mode should be "delivery" or "review"; "delivery" is assumed
getHTML: function(mode) {
// start with the query text, if there
var html = this.query_text_html();
html += "
"
+ "
TermDescription
";
var left_column = "";
var right_column = "";
// if we're in review mode and the student has completed the query, show the answers...
if (mode == 'review' || mode == 'review_correct_incorrect' || mode == 'preview') {
//html += "
"
;
}
// close off the table and enclosing div
html += "
";
// side effect: update the question text
for this question
var $q_text_p = $("#question_text_" + this.parent_question.index);
var q_text = this.query_text;
// brb: remove question number at beginning of question text
q_text = q_text.replace(/^\d+\. /, "");
// brb: uncomment to go back to question text outside of legend
$q_text_p.html(q_text);
// brb: add keyboard instructions
/*
$q_text_p.after("
Keyboard accessibility: Use tab or up/down arrow to navigate to an item, and return or space bar to select the item. Use escape to exit the matching activity. Begin the matching activity.
");
*/
return html;
},
reset_activity: function(text) {
if (text === undefined) {
text = "";
}
$(".ma_query_wrap").attr("role", "application").attr("aria-hidden", "false");
var terms_remaining = 0;
$(".query_matching_table .activity .query_matching_table_td_left .query_matching_item").each(function() {
var $this = $(this);
$this.removeClass("chosen");
if ($this.hasClass("answered")) {
$this.removeAttr("role").removeAttr("tabindex");
}
else {
$this.attr("role", "button").attr("tabindex", "-1");
terms_remaining++;
}
});
$(".query_matching_table .activity .query_matching_table_td_right .query_matching_item").each(function() {
var $this = $(this);
$this.removeAttr("role").removeAttr("tabindex");
});
// adjust label for left td
var remaining_text = terms_remaining + " terms";
if (terms_remaining == 1) {
remaining_text = terms_remaining + " term";
}
$(".query_matching_table_td_left").attr("aria-label", text + " Choose a term. " + remaining_text + " remaining.");
$(".query_matching_table_td_left").focus();
},
postInit: function() {
var qjq = $("#query_matching_div" + this.query_index);
var tq = this;
var $form = qjq.parents("[data-type='question']");
var question_index = $form.attr("data-question_index");
// brb: add keyboard instructions
//$form.find(".question_text").after("
For keyboard users: Use the tab key or up/down arrows to navigate to an item, and the return key or space bar to select the item. Use the escape key to exit the matching activity. Begin the matching activity.
");
var curr_question_text = $form.find(".question_text").html();
$form.find(".question_text").html(curr_question_text + " Keyboard instructions: Use the tab or arrow keys to scroll through the items, and the return key or space bar to select an item. Use the escape key to exit the matching activity at any time. Enter the matching activity.")
$form.find("[data-type='query']").wrap("");
$form.changeElementType("div");
qjq.find(".query_matching_table_td_left").each(function(index, element) {
var jq = $(element);
jq.find('.query_matching_item').click(function() { tq.left_clicked(this); }).addClass("active");
// jq.find('.query_matching_item').click({"tq": tq}, tq.left_clicked(this); }).addClass("active");
});
qjq.find(".query_matching_table_td_right").each(function(index, element) {
var jq = $(element);
jq.find('.query_matching_item').click(function() { tq.right_clicked(this); });
});
var context = this;
qjq.keydown(function(e) {
var key = e.which || e.keyCode;
// escape
if (key == 27) {
e.preventDefault();
$(".ma_info").html(" ");
$(".ma_query_wrap").attr("role","presentation").attr("aria-hidden","true");
$form = $(e.target).parents("[data-type='question']");
//$form.find(".begin_ma").text("Continue the matching activity.");
$form.find(".begin_ma").focus();
}
// tab/arrow keys
if (key == 9 || key == 40 || key == 38) {
e.preventDefault();
$(".ma_info").html(" ");
// if the target is a td then we aren't in the active
// items list yet
if ($(e.target).hasClass("query_matching_column")) {
if ($(e.target).hasClass("query_matching_table_td_left")) {
$(e.target).attr("aria-label", "");
}
else {
$(e.target).attr("aria-label", "");
}
var $active_items = $(e.target).children(".query_matching_item").not(".answered");
$active_items.first().focus();
return;
}
// get all active items in list
var $parent_td = $(e.target).parent();
var $active_items = $parent_td.children(".query_matching_item").not(".answered");
// if there is only one active item left the nothing to do
if ($active_items.length < 2) {
return;
}
// tab or down arrow
if ((key == 9 && e.shiftKey == false) || key == 40) {
var $next = $(e.target).nextAll(".query_matching_item").not(".answered").first();
if ($next.length == 1) {
$next.focus();
}
else {
$active_items.first().focus();
}
}
// tab/shift or up arrow
else {
var $prev = $(e.target).prevAll(".query_matching_item").not(".answered").first();
if ($prev.length == 1) {
$prev.focus();
}
else {
$active_items.last().focus();
}
}
}
// return/space keys
if (key == 32 || key == 13) {
e.preventDefault();
if (e.target.nodeName == "TD" || e.target.nodeName == "td") {
return;
}
var $target = $(e.target);
var $parent = $target.parent();
if ($parent.hasClass("query_matching_table_td_left")) {
$target.click();
// make right column active
$(".query_matching_table .activity .query_matching_table_td_right .query_matching_item").each(function() {
var $this = $(this);
if (!$this.hasClass("answered")) {
$(this).attr("role", "button").attr("tabindex", "-1");
}
});
// make left column inactive
$(".query_matching_table .activity .query_matching_table_td_left .query_matching_item").each(function() {
var $this = $(this);
$(this).removeAttr("tabindex");
});
// set label for right td
$(".query_matching_table .activity .query_matching_table_td_right").attr("aria-label", "Choose a description for the term" + $target.text());
// focus on first entry in right column
//$(".query_matching_table .activity .query_matching_table_td_right .query_matching_item").not(".answered").first().focus();
// focuse on right td
$(".query_matching_table .activity .query_matching_table_td_right").focus();
}
else {
$target.click();
}
}
});
$("#manuscript").delegate("a.begin_ma", "click keydown", function(e) {
// we only want to handle Enter key
if (e.type === "keydown") {
var key = e.keyCode || e.which;
if (key != 13) {
return;
}
}
e.preventDefault();
var q_idx = $(e.target).parents("[data-type='question']").attr("data-question_index");
player.activity.questions[q_idx].queries[0].reset_activity("To choose an item, use the tab or arrow keys to scroll through the items, and the return key or space bar to select an item. Use the escape key to exit the matching activity at any time.");
});
},
left_clicked: function(el) {
var jq = $(el);
var left_side = jq.parent();
var right_side = jq.parent().parent().find(".query_matching_table_td_right");
$(".ma_info").html(" ");
// get index of this item
var answer_index = jq.attr("answer_index");
// de-highlight all left-side items and right-side items
left_side.find(".query_matching_item").removeClass("chosen");
right_side.find(".query_matching_item").not(".answered").removeClass("incorrect").addClass("active");
// highlight this item
jq.addClass("chosen");
// note that it's chosen
this.last_clicked_side = "left";
this.last_clicked_index = answer_index;
},
right_clicked: function(el) {
$(".ma_info").html(" ");
if (this.last_clicked_side != "left") {
Standard_Dialog.alert("Select on an item in the left column first.");
return;
}
var jq = $(el);
var q_idx = jq.parents("[data-type='question']").attr("data-question_index");
var right_side = jq.parent();
var left_side = jq.parent().parent().find(".query_matching_table_td_left");
// get index of this item
var answer_index = jq.attr("answer_index");
// get handle to the item on the left side
var left_side_item = left_side.find("[answer_index=" + answer_index + "]");
var clicked_term = jq.parents("[data-type='question']").find(".query_matching_table_td_left").find("[answer_index=" + this.last_clicked_index + "]").text();
clicked_term = clicked_term.replace("Term: ", "");
var def = jq.text();
def = def.replace(/\.$/, "");
def = def.replace("Description: ", "");
var curr_left_clicked_index = this.last_clicked_index;
// incorrect answer
if (answer_index != this.last_clicked_index) {
jq.addClass("incorrect");
right_side.find(".query_matching_item").removeClass("active");
var t = this;
//player.activity.questions[q_idx].display_alert_mesg("Sorry, the term " + clicked_term + " does not match the description " + def + ".", "manual");
this.last_clicked_side = "";
$(".ma_info").html("Sorry, that is not a correct match. Please try again.");
setTimeout(function() {
jq.removeClass("incorrect");
if (this.last_clicked_index == null) {
left_side.find(".query_matching_item").removeClass("chosen");
}
t.reset_activity("Sorry, the term " + clicked_term + " does not match the description " + def + ". Please try again.");
}, 1000);
}
// correct answer
else {
this.last_clicked_side = "right";
// right-side items aren't active anymore and shouldn't have the "incorrect" class.
right_side.find(".query_matching_item").removeClass("active").removeClass("incorrect").removeAttr("role").removeAttr("tabindex");
// this item isn't clickable ever anymore
jq.unbind();
// kill the "chosen" class on the left side; it shouldn't be clickable either
left_side_item.removeClass("chosen").unbind().removeClass("active").removeAttr("role").removeAttr("tabindex");
// move the correct item down
var table = right_side.parent().parent();
table.find(".query_matching_table_td_correct").show();
table.find(".query_matching_table_td_left_bottom").show();
table.find(".query_matching_table_td_right_bottom").show();
var left_side_bottom = table.find(".query_matching_table_td_left_bottom");
var right_side_bottom = table.find(".query_matching_table_td_right_bottom");
var new_left = left_side_item.clone().addClass("correct");
var new_right = jq.clone().addClass("correct");
new_left.prepend("➜");
//left_side_bottom.append(new_left);
//right_side_bottom.append(new_right);
var new_string = new_left.html() + new_right.html();
/*
var new_left_2 = $('
');
new_left_2.append(new_left);
var new_right_2 = $('
');
new_right_2.append(new_right);
*/
var new_row = $("").append("
" + new_left.html() + "" + new_right.html() + "
");
new_row.appendTo(table);
//var _height = right_side_bottom.height();
//window.alert(_height)
//left_side_bottom.height(_height);
++this.answers_correct;
// add the "answered" class to both sides
left_side_item.addClass("correct");
jq.addClass("correct");
var t = this;
// activity complete
if (t.answers_correct == t.pairs.length) {
player.activity.questions[q_idx].remove_alert_mesg();
var $q = $("[data-question_index='" + q_idx + "']");
// remove keyboard instructions
$q.find(".key_instr").remove();
// remove table caption
$q.find(".query_matching_table").find("caption").html("Matching activity correct answers");
player.activity.show_question_feedback(player.activity.questions[q_idx], true, false);
$("#query_wrap_" + q_idx).removeAttr("role");
setTimeout(function() {
left_side_item.removeClass("correct").addClass("answered").attr("aria-hidden", "true").css("display", "none");
jq.removeClass("correct").addClass("answered").attr("aria-hidden", "true").css("display", "none");
if (t.answers_correct == t.pairs.length) {
t.question_done(table);
}
//t.reset_activity(-1);
}, 100);
}
// terms remaining
else {
//player.activity.questions[q_idx].display_info_mesg("Correct. The term " + clicked_term + " matches the description " + def + ".");
setTimeout(function() {
left_side_item.removeClass("correct").addClass("answered").attr("aria-hidden", "true").css("display", "none");
jq.removeClass("correct").addClass("answered").attr("aria-hidden", "true").css("display", "none");
if (t.answers_correct == t.pairs.length) {
t.question_done(table);
}
t.reset_activity("Correct. The term " + clicked_term + " matches the description " + def + ".");
}, 100);
}
}
},
question_done: function(table) {
table.find(".query_matching_table_td_correct").css("border-top","0px");
table.find(".query_matching_table_td_left").hide();
table.find(".query_matching_table_td_right").hide();
// set query_complete to true, then call the parent question's submit function
// which will in turn call evaluateAnswer below.
this.query_complete = true;
player.activity.submit_question(this.parent_question.index);
},
evaluateAnswer: function() {
// if query_complete is still false, user hasn't finished
if (this.query_complete == true) {
this.setGrade(100);
return true;
} else {
this.setGrade(0);
return false;
}
}
});
function clean_query_text(query_text) {
query_text = query_text.replace(/]+>/g, "");
query_text = query_text.replace(/<\/span>/g, "");
query_text = query_text.replace(//g, "");
query_text = query_text.replace(/<\/em>/g, "");
query_text = query_text.replace(//g, "");
query_text = query_text.replace(/<\/strong>/g, "");
query_text = query_text.replace(/ /g, "");
query_text = query_text.replace(/ /g, "");
query_text = query_text.replace(/’/g, "'");
query_text = query_text.replace(/“/g, "\"");
query_text = query_text.replace(/”/g, "\"");
query_text = query_text.replace(/—/g, "--");
return query_text;
}