function ______Figures() {} // comment so that BBEdit's function menu works better // PW: Define Figures as a class, so that it can be extended // by varieties of the standard player. var Figures = Class.extend({ // see http://code.google.com/p/swfobject/wiki/documentation // for documentation on swfobject process_swfs: function() { // we're not currently using this (swfobject is not being included) $("[data-mmtype='swf']").each(function(index, element) { var jq = $(element); var id = jq.attr("data-figure-id"); var src = jq.attr("data-mmsrc"); var attr = jq.attr("data-attr"); if (attr == null) attr = ""; attr = attr.split(/\s*,\s*/); // get default width and height from the placeholder image var width = jq.width(); var height = jq.height(); var version = "9.0.0"; var params = new Object(); for (var i = 0; i < attr.length; ++i) { var a = attr[i].split(/\s*=\s*/); if (a[0] == 'width') { width = a[1]; } else if (a[0] == 'height') { height = a[1]; } else if (a[0] == 'version') { version = a[1]; } else { params[a[0]] = a[1]; } } // set the id attribute to the id value from data-figure-id jq.attr("id", id); var x = swfobject.embedSWF(src, id, width, height, version, false, false, params); }); }, // http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12536/configuration-options process_media: function() { // we're not currently using this (jwplayer is not being included) $("[data-mmtype='mp3']").each(function(index, element) { var jq = $(element); var id = jq.attr("data-figure-id"); var mmsrc = jq.attr("data-mmsrc"); // http://www.longtailvideo.com/jw/upload/bunny.mp3 // http://www.youtube.com/embed/CsGYh8AacgY var src = jq.attr("src"); var attr = jq.attr("data-attr"); if (attr == null) attr = ""; attr = attr.split(/\s*,\s*/); var params = new Object(); params.width = jq.width(); params.height = jq.height() + 24; // 24 is for the controler at the bottom params.file = mmsrc; params.image = src; params.controlbar = "bottom"; params.screencolor = "ffffff"; params["viral.allowmenu"] = "false"; params["viral.onpause"] = "false"; params["viral.oncomplete"] = "false"; // determine url of flashplayer based on whether we're published or not if (UI_Elements.in_preview_mode()) { params.flashplayer = "/js/preview/player.swf"; } else { params.flashplayer = "js/player.swf"; } safe_log(params.flashplayer); for (var i = 0; i < attr.length; ++i) { var a = attr[i].split(/\s*=\s*/); params[a[0]] = a[1]; } jwplayer(id).setup(params); }); //AF: this is less than ideal, but i had to make this a global variable so it can be accessed by the video players when they fire the templateloaded event. // we should look into changing it. videos.templateReady = function (figureObjectID) { var vidplayer = brightcove.api.getExperience(figureObjectID); var experienceModule = vidplayer.getModule(brightcove.api.modules.APIModules.EXPERIENCE); var playerModule = vidplayer.getModule(brightcove.api.modules.APIModules.VIDEO_PLAYER); }; videos.cuePointEvent = function (e) { //get the player - the name property of the cuePoint is set to the ID of the Brightcove experience //so we can find the player here. var vidplayer = brightcove.api.getExperience(e.cuePoint.name); globalPlayer = brightcove.api.getExperience(e.cuePoint.name); safe_log("got vid player"); var playerModule = vidplayer.getModule(brightcove.api.modules.APIModules.VIDEO_PLAYER); safe_log("got module"); playerModule.pause(true); safe_log("paused"); player.show_question_sequence(e.cuePoint.metadata, false); }; $("[data-mmtype='mov']").each(function(index, element) { var jq = $(element); var id = jq.attr("data-figure-id"); var mmsrc = jq.attr("data-mmsrc"); var src = jq.attr("src"); var attr = jq.attr("data-attr"); if (attr == null) attr = ""; attr = attr.split(/\s*,\s*/); var params = new Object(); for (var i = 0; i < attr.length; ++i) { var a = attr[i].split(/\s*=\s*/); params[a[0]] = a[1]; safe_log("added param " + a[0] + ": " + a[1]); } params.autoStart = jq.attr("data-autoplay"); var videoPlayerID = ""; var videoPlayerKey = ""; //if(params.showVideoControls == 'true'){ //AF: This is the video player with playback controls. We are only using this one for right now. videoPlayerID = "1513003547001"; if(jq.attr("data-playerid")){ videoPlayerID = jq.attr("data-playerid"); } videoPlayerKey = "AQ~~,AAABXVHBMdE~,bnY9CM55Z1MLPZuidy4KYEC_16wi-U8Q"; //}else{ // videoPlayerID = "1504927982001"; // videoPlayerKey = "AQ~~,AAABXVHBMdE~,bnY9CM55Z1PiqOYprq-NHmUPG2yKZ4U-"; //} videos[id] = mmsrc; var BCL = {}; BCL.markup = function (html, data) { var m; var i = 0; var match = html.match(data instanceof Array ? /{{\d+}}/g : /{{\w+}}/g) || []; while (m = match[i++]) { html = html.replace(m, data[m.substr(2, m.length-4)]); } return html; }; videos.templateLoad = function(e){ //AF: For now, we are not using captions. var vidplayer = brightcove.api.getExperience(e); var CuePointType = brightcove.api.modules.CuePointsModule.CuePointType; var modExp = vidplayer.getModule(brightcove.api.modules.APIModules.EXPERIENCE); modExp.addEventListener(brightcove.api.events.ExperienceEvent.TEMPLATE_READY, function (evt) { videos.templateReady(e); }); //captionsModule.loadDFXP(player.md.video_caption_url + videos[e] + ".xml", videos[e]); //if needed, we can use these events to trigger code upon the success or error of loading captions. //if there is an error, it fails silently and just doesn't show captions. //captionsModule.addEventListener(brightcove.api.events.CaptionsEvent.DFXP_LOAD_SUCCESS, onDFXPLoadSuccess); //captionsModule.addEventListener(brightcove.api.events.CaptionsEvent.DFXP_LOAD_ERROR, onDFXPLoadError); } BCL.playerData = { "playerID" : videoPlayerID, "playerKey" : videoPlayerKey, "width" : jq.width(), "height" : jq.height(), "videoID" : mmsrc, "autoStart" : "false"}; BCL.playerTemplate = "
"; var playerHTML = ""; playerHTML = BCL.markup(BCL.playerTemplate, BCL.playerData); //replaces placeholders with values jq.replaceWith(playerHTML); brightcove.createExperiences(); }); }, process_iframes: function(jq) { if (jq == null) { jq = $("body"); } jq.find("[data-mmtype='iframe']").each(function(index, element) { var jq = $(element); var id = jq.attr("data-figure-id"); var src = jq.attr("data-mmsrc"); var attr = jq.attr("data-attr"); if (attr == null) attr = ""; attr = attr.split(/\s*,\s*/); // get default width and height from the placeholder image var params = new Object(); params.width = jq.width(); params.height = jq.height(); params.frameborder = "no"; params.scrolling = "no"; params.style = "margin:0px; padding:0px"; params.src = src; for (var i = 0; i < attr.length; ++i) { var a = attr[i].split(/\s*=\s*/); params[a[0]] = a[1]; } var pstring = ""; for (var i in params) { pstring += ' ' + i + '="' + params[i] + '"'; } jq.replaceWith(''); }); }, // extend this function to do something when the media player is done playing media_player_done: function(id) { }, // show the figure -- which means shifting so that the figure is visible // we're not currently using this function, but I'm keeping it around in case we need it later show: function(ref) { // TODO: we assume here that the figure is part of the html page we currently have loaded. // this isn't a safe assumption; what we *should* do is have a table where we can look up // what html page the figure is in, and go to that page if necessary // find the figure we're referring to var jq = $(ref); var fig_id = jq.attr("data-refid"); // get that figure's jquery object var fig_jq = $("[data-figure-id=" + fig_id + "]"); // make sure we're in that figure's section var sec_jq = fig_jq.parents("[data-type=section]"); var sec_index = sec_jq.attr("data-section-index"); if (player.section_currently_showing != sec_index) { player.show_section(sec_index * 1); } // scroll to the figure $(window).scrollTo(fig_jq, 500); }, // expand the figure -- which means (at least for now) popping it up in a new window expand: function(ref) { // TODO: we assume here that the figure is part of the html page we currently have loaded. // this isn't a safe assumption; what we *should* do is have a table where we can look up // the figure id's across the entire book/project // also we should really show the figure's number/caption... var figure_jq; // if ref is a string, find the figure based on that reference if (typeof ref == "string") { figure_jq = $("[data-type=figure][data-figure-id=" + ref + "]"); // otherwise the figure should be an ancestor of ref } else { figure_jq = $(ref).parents('[data-type=figure]').first(); } // get the src of the image to expand var altsrc = figure_jq.attr('data-altsrc'); // not sure what to do with the title yet, if anything... // var title = figure_jq.find('[data-type=figure_text]').html().replace(/<.*?>/g, ''); window.open(altsrc, 'fig_win'); }, init: function() { this.process_swfs(); // flash this.process_media(); // mp3s and other things that get played via the MediaPlayer // only load all iframes at once if player.md.preload_all_iframes is set to true // otherwise we do it as we load each section. if (player.md.preload_all_iframes == "true") { this.process_iframes(); // iframes } // Figure references in the text should pop up the figure, unless the figure isn't expandable $("[data-type='ref'][data-ui='figure']").each(function(index, element) { // get the figure's jquery object to determine if it's expandable var fig_id = $(element).attr("data-refid"); var fig_jq = $("[data-figure-id=" + fig_id + "]"); // currently we can only expand images; this should change later var is_image = (fig_jq.find("[data-mmtype=image]").length > 0); if (fig_jq.attr("expandable") != "false" && is_image) { $(element).click(function() { return player.figures.expand($(this).attr("data-refid")) }).css("cursor", "pointer"); } }); // Now the figures themselves $("[data-type='figure']").each(function(index, element) { var jq = $(element); var ijq = $("[data-mmtype]", jq); // the figure's main image will have a mmtype tag // get the figure id var id = jq.attr("data-figure-id"); // if the figure is expandable, make the figure and its number clickable // currently we can only expand images; this should change later if (jq.attr("data-expandable") != "false" && ijq.attr("data-mmtype") == "image") { ijq.click(function() { return player.figures.expand(this) }).css("cursor", "pointer"); $("[data-type='number']", jq).click(function() { return player.figures.expand(this) }).css("cursor", "pointer"); // also, if altsrc isn't specified, set it to the image source if (jq.attr("data-altsrc") == undefined) { jq.attr("data-altsrc", ijq.attr("src")); } } // deal with attributes field on the image // note that multiple attributes must be separated by " | " -- at least one space // surrounding each attribute. This allows "||" to be a valid part of an attribute var attr = ijq.attr("data-attr"); if (attr != null) { attr = attr.split(/\s* \| \s*/); for (var i = 0; i < attr.length; ++i) { if (attr[i].search(/^(\w+)=(.*)/) > -1) { var key = RegExp.$1; var value = RegExp.$2; if (key == 'onclick') { ijq.click(new Function(value)); ijq.css("cursor", "pointer"); // default: just write them out as attributes of the image } else { ijq.attr(key, value); safe_log("Image attribute: set " + key + " to " + value); } } else if (attr[i] != "") { safe_log("Bad image attribute (" + i + "): '" + attr[i] + "'"); } } } }); } }); function updateweights(weight){ w=Number(weight); document.getElementById("mercury").innerHTML=Math.round(100*w*0.38)/100; document.getElementById("venus").innerHTML=Math.round(100*w*0.91)/100; document.getElementById("mars").innerHTML=Math.round(100*w*0.38)/100; document.getElementById("jupiter").innerHTML=Math.round(100*w*2.36)/100; document.getElementById("saturn").innerHTML=Math.round(100*w*1.1)/100; document.getElementById("uranus").innerHTML=Math.round(100*w*0.92)/100; document.getElementById("neptune").innerHTML=Math.round(100*w*1.1)/100; } var Activity_subtype = Activity_manuscript_type.extend({ submit_question: function (question_index) { this._super(question_index); // re-call mathjax conversion here MathJax.Hub.Queue(["Typeset", MathJax.Hub]); var st = player.get_current_section(); var section_jq = player.get_current_section_jq(); //if current section questions are answered if (st.all_questions_answered === true) { //show the summary block within the section $("[data-block_type=summary_block]", section_jq).show(); // scroll to the summary block $(window).scrollTo($("[data-block_type=summary_block]", section_jq), 0); } } }); var Player_subtype = Player_manuscript_type.extend({ show_popup: function(url){ window.open(url, "astro_popup", "width=400,height=500,left=500,top=300,location=0,menubar=0,scrollbars=1,status=0,toolbar=0,resizable=1"); }, initialize: function () { jQuery.getScript("https://prod-cdn-packages.macmillan.cloud/media/MathJax/MathJax.js?config=TeX-MML-AM_CHTML", function () { //optional code to execute after mathjax library has been loaded can go here }); // prepend word Question on Question numbers, to match old version of astrotutorials $("[data-type=question] h3").prepend('Question'); // insert "activity_report" block at the end of the last section // first clear any existing block out $("[data-block_type=activity_report]").remove(); $("[data-type=section]").last().append('Activity results are being submitted...
'); this._super(); $("[data-block_type=popup_link]").each(function (index, element) { var x = $(element).html(); var urlRegex = /{(.+)}/g; var textRegex = /\[(.+)\]/g var url = urlRegex.exec(x)[1]; var text = textRegex.exec(x)[1]; var html = "" + text + ""; $(element).html(html); }); // after we call this.super, re-initialize the activity to the custom // activity type for this subtype this.activity = new Activity_subtype(); }, initialize2: function () { this._super(); } }); player = new Player_subtype(); var FB_Query = FB_Query.extend({ evaluateAnswer: function() { this.user_answer = jQuery.trim($("#query_answer_" + this.query_index).val()); var is_correct = false; // if there's no one correct answer, any answer is correct! if (this.md.no_correct_answer == "true" || this.answers == null) { is_correct = true; // MT: 2013-08-22 fix as perPpepper's suggestion for DF-26 // NEXT ELSE IF IS NEW CODE // assume that an empty string is never correct } else if (this.user_answer === "") { is_correct = false; } else { for (var i = 0; i < this.answers.length; ++i) { var ca_comp = this.answers[i]; var sa_comp = this.user_answer; // if this is *not* case sensitive... if (this.md.case_sensitive != "true") { // convert to lower case ca_comp = ca_comp.toLowerCase(); sa_comp = sa_comp.toLowerCase(); // if ca_comp is a number and case_sensitive is false... // brb: Question 5 in ch06_the_basics_of_telescopes_and_ccds // is being treated as a number even though it is not // so we added the nan metadata value and set it to true // in the XML so that it does not get treated like a number // in the below if statement if (this.md.nan !== "true" && !isNaN(ca_comp * 1)) { // MOVE THIS TO ANOTHER FUNCTION SO WE CAN USE IT ELSEWHERE // see how many decimal places ca_comp has var dec = ca_comp.replace(/.*\.(.*)/, "$1"); var factor = Math.pow(10, dec.length); // convert ca_comp to a number ca_comp = ca_comp * 1; // convert sa_comp to a number and round to the given number of places sa_comp = Math.round(factor * sa_comp) / factor; } } // now evaluate against this answer if (sa_comp == ca_comp) { is_correct = true; break; } } } // set grade accordingly if (is_correct) { this.setGrade(100); } else { this.setGrade(0); } return true; } });