wrapper around the
. Since we don't want them both to have
// the same id we must use add "div" to the selector.
/*
$('div[data-figure-id]').each(function(index, element) {
var jq = $(element);
jq.attr('id', jq.data('figure-id'));
});
*/
// Hack: add ids to boxes
/*
$('.id_holder').each(function() {
var $id_div = $(this);
var $box_div = $id_div.next();
$box_div.attr('id', $id_div.attr('id'));
$id_div.remove();
});
*/
/* remove width/height attributes from
s as they are not supported */
/* These attributes aren't supported in HTML5 and should be removed from the
html, especially if we didn't include them in the first place */
/* Again, this isn't necessary, I just bothers me :-) */
$("table").removeAttr("width").removeAttr("height");
// process special tags in h3 headers
$("h3").each(function (index, element) {
var $h3 = $(element);
var h3_text = $h3.text();
h3_text = h3_text.replace(/#(.*?)#/g, "<$1>");
//safe_log("h3_text: " + h3_text);
$h3.html(h3_text);
});
$("[data-block_type='table_snap']").find("h3").each(function (index, element) {
var $h3 = $(element);
var h3_text = $h3.text();
match = h3_text.match(/Snapshot: (.*)/);
if (match !== null) {
var tmp_sub_text = match[1];
match = tmp_sub_text.match(/(fn:\d+_)(\d+)/);
if (match !== null) {
var replace_txt = "";
tmp_sub_text = tmp_sub_text.replace(/fn:\d+_\d+/, replace_txt);
}
$h3.html("Snapshot " + tmp_sub_text + "");
// add termref handler
// 2013-08-01: we don't need this because we are using delegate to
// catch these
//$h3.find("span[data-type='termref']").click(function() { player.glossary.show_definition(this); });
}
});
// we should probably combine this with the one above
/*
$("[data-block_type='portrait']").find("h3 .portrait_subtitle").each(function(index, element) {
var $h3 = $(element);
var h3_text = $h3.text();
var match = h3_text.match(/(fn:\d+_)(\d+)/);
if (match !== null) {
var replace_txt = "";
h3_text = h3_text.replace(/fn:\d+_\d+/, replace_txt);
$h3.html(h3_text);
$h3.find("span[data-type='termref']").click(function() { player.glossary.show_definition(this); });
}
});
*/
// create footnote in snapshot header
/*
$(".snap_subtitle").each(function(index, element) {
var jq = $(element);
safe_log("snapshot: " + jq.html());
});
*/
$("[data-block_type='portrait']").find("h3").each(function (index, element) {
var $h3 = $(element);
var h3_text = $h3.text();
match = h3_text.match(/Portrait: (.*)/);
if (match !== null) {
var subtitle = match[1];
match = subtitle.match(/(fn:\d+_)(\d+)/);
if (match !== null) {
var replace_txt = "";
subtitle = subtitle.replace(/fn:\d+_\d+/, replace_txt);
}
$h3.html("PORTRAIT " + subtitle + "");
// 2013-08-01: we don't need this because we are using delegate to
// catch these
/*
if (match !== null) {
$h3.find("span[data-type='termref']").click(function() { player.glossary.show_definition(this); });
}
*/
}
});
/* We should probably fix this where it is originally happening instead
of hacking it here but I don't have time right now to look into it */
// Allow figure width to be set in pixels
$("[data-type='figure']").each(function (index, element) {
var $this = $(element);
var width = $this.data('layout-width') + "x";
//safe_log("width: " + width);
match = width.match(/(\d+)/);
if (match !== null) {
//safe_log("changing width to " + match[1]);
$this.attr('style', "width:" + match[1] + "px");
var $img = $this.children("img");
$img.attr('style', "width:" + match[1] + "px; cursor: pointer");
}
});
/* this is a hack until we get the "start" attribute added to s */
/* NOT USED IN THIS BOOK */
/*
$('ol[data-block_type^="start"]').each(function() {
var start = $(this).attr("data-block_type");
var match = start.match(/start(\d+)/);
if (match != null && match[1].match(/\d+/)) {
$(this).attr("start", match[1]);
}
});
*/
},
/* we never want to 'slide' in a page */
/* This combines the show_section_animate() defined in both digfir_ebook.js
and player.js */
show_section_animate: function (section_to_show, direction) {
// make sure modal window is closed
$("#toc_dialog").dialog("close");
// hide currently showing section
if (this.section_currently_showing != null) {
this.get_current_section_jq().hide();
}
// get the jq for the section to show
var jq = $("[data-section-index=" + section_to_show + "]");
// if this is the first page, just show it -- no sliding
// brb: we always want no sliding
jq.show();
this.section_currently_showing = section_to_show;
$(document).trigger('df-content-rendered'); //added as DF-57
},
/* we don't want the navigation to show, ever */
show_navigation: function () {
return;
},
print: function(){
window.print();
},
show_print_button: function(){
var html = "Print
";
$("#manuscript").after(html);
},
initialize: function (id) {
/* We don't want to call super (Person.initialize) here:
- Player.initialize creates all the variables below, so if we are
extending a class (e.g. XRefs_subtype) then calling super creates the
original xrefs variable (in Player.initialize) and then we create it
again (below) which is just a waste of resources and...
- The bad thing about the above is that when the original xrefs is created
(Xrefs.init is called) it modifies the DOM so by the time we create our
extended xrefs variable we only have access to the modified DOM.
*/
//this._super();
//need to load a css file that doesnt have media=screen set in the markup
this.show_print_button();
this.manuscript_id = id;
// extract metadata (this might be already done by the activity-specific
// player, but that's OK; we'll just re-do it here, which is no problem.)
this.extract_activity_metadata();
// have to do variables first because that replaces the body html
this.variables = new Variables();
//this.figures = new Figures();
this.figures = new Figures_subtype();
//this.xrefs = new XRefs();
this.xrefs = new XRefs_subtype();
this.links = new Links();
//this.activity = new Activity();
this.activity = new Activity_subtype();
this.interactions = new Interactions();
this.tables = new Tables();
// moving this to initialize2 after we move the "box_seeking" boxes
//this.glossary = new Glossary();
//this.glossary = new Glossary_subtype();
// Prepare for activity functionality by getting ARGA data;
// that fn will call Initialize_ARGA_Session_Callback (see below)
var success = false;
if (window.Initialize_ARGA_Session != null) {
success = Initialize_ARGA_Session({
"fail_silently": (this.md.ARGA_fail_silently != "false"),
"retrieve_class_data": (this.md.ARGA_retrieve_class_data == 1 || this.md.ARGA_retrieve_class_data == "true" || this.md.ARGA_retrieve_class_data == true) ? 1 : 0,
"cancel_initialization_alert": true
});
}
if (!success) {
this.ARGA_running = false;
//safe_log("running in non-ARGA mode");
// We need to initialize the player after a timeout (mimicking what would happen
// if ARGA was initialized and initialize2 was called on a callback) so that
// inherited players will be called in the proper order.
setTimeout("player.initialize2()", 1);
} else {
this.ARGA_running = true;
}
},
initialize2: function () {
this._super();
// anything that you want to do after *everything* has been set up
// should be done here.
// handle glossary/footnote clicks here using delegate because we
// may have footnotes in question text
$("#manuscript").delegate('span[data-type="termref"]', 'click', function (event) {
player.glossary.show_definition(this, event);
});
/* If this is a sub-volume then we need to disable any links to the other
sub-volume */
var temp_course_id = xBookGetCourseID();
//safe_log("course id: " + temp_course_id);
if (temp_course_id == "strayer2evol1" || temp_course_id == "strayer2evol2") {
$("a").each(function () {
var $a = $(this);
var href = $a.attr("href");
safe_log("href: " + href);
var href_chap = get_href_chapter(href);
// if href_chap == 0 then get_href_chapter couldn't find chap in href
if (href_chap > 0) {
if (temp_course_id == "strayer2evol1" && href_chap > 12) {
$a.replaceWith($a.text());
safe_log("de-linking " + href);
}
else if (temp_course_id == "strayer2evol2" && href_chap < 12) {
$a.replaceWith($a.text());
safe_log("de-linking " + href);
}
}
});
}
// handle all clicks in #manuscript
// special targets that can be passed in:
// _pop: open link in supp window
// _disable: disable link
$("#manuscript").delegate('a', 'click', function (event) {
var $jqa = $(this);
var href = $jqa.attr('href');
var target = $jqa.attr('target');
var anchor = "";
//safe_log("delegate");
if (target === "_disable" || target === "_disabled") {
safe_log("link disabled");
return false;
}
// There are three types of URLs we take into consideration:
// 1. external/complete - begin with pattern ^[^:]+:/ (e.g. http://)
// 2. internal links to unique IDs - begin with a #
// 3. internal/relative links to files (all others not in 1 or 2)
// First we check if we have an external link. If so then we just let
// it bubble up.
if (href.search(/:/) != -1) {
return true;
}
// If we get here then we have an internal link.
// If the href starts with '#' then it is linking to a unique ID and
// we must lookup the actual filename that the ID is found on
var lmatch = href.match(/^#(.*)/);
if (lmatch !== null) {
var u_id = lmatch[1];
var file = xBookUtilGetFileFromId(u_id);
//safe_log("snagged file: " + file);
if (file === null || file === undefined) {
safe_log(" click handler: could not find filename for id: " + u_id);
return false;
}
anchor = href; // save off original href as anchor for URL
href = file; // href now holds the filename
}
// Check if link opens to supp window
if (target === "_pop") {
//safe_log("internal pop link clicked");
// we can just pass the href raw because xBookUtilOpenSuppWin
// knows how to handle it.
var file = href;
if (anchor.length > 0) {
file += anchor;
}
xBookUtilOpenSuppWin(file);
return false;
}
// prepare href for URL (this gives us the correct filename path that
// we can just tack on to the base URL)
//safe_log("href before xBookUtilPrepareFilenameForUrl: " + href);
href = xBookUtilPrepareFilenameForUrl(href);
//safe_log("href after xBookUtilPrepareFilenameForUrl: " + href);
// this is specific for strayer2e: for ch 1-23, if the href is pointing
// to the first page in the chapter (e.g. strayer2e_ch1_1) then we want
// it to go to the third page instead.
var href_match = href.match(/^(strayer2e_ch\d+)_1\.html/);
if (href_match != null) {
//safe_log("updated href from " + href + " to " + href_match[1] + "_3.html");
href = href_match[1] + "_3.html";
}
// get the 'base' URL for book
var base_url = xBookUtilGetBaseUrl();
// If we are in DF then just go to the page
if (top.PxPage == null) {
//safe_log("DF internal link: " + href + anchor);
$jqa.attr('href', href + anchor);
// let it bubble
return true;
}
// we are in PX
else {
// If this is a link to something other than a regular page then
// go to it. Generally, this should be a link to a non html resource
// that the user will download (e.g. Word doc).
if (/\//.test(href)) {
$jqa.attr('href', base_url + href + anchor);
return true;
}
event.stopImmediatePropagation();
xBookUtilOpenPxId(href);
return false;
}
});
// when the submit button is clicked the question text is refreshed and
// we need to convert the link spans to actual links again
$("#manuscript").delegate('.question_submit_button', 'click', function () {
// grab all the link spans in the query text
var $links = $(this).closest('[data-type="question"]').find('.query_text').find('[data-type="link"]');
// replace each link span with
$links.replaceWith(function () {
var $this = $(this);
return '' + $this.html() + '';
});
});
// these are spans that are used to target anchors on the same page since
// PX does not have a way to do it at the moment
$("#manuscript").delegate('span[data-block_type^="xref:"]', 'click', function (event) {
var xref = $(this).data('block_type');
var match = xref.match(/xref:(.*)/);
if (match !== null) {
var url = xBookUtilGetPageUrl();
// wrapper
if (/digfir-published/.test(url)) {
$('html,body').animate({ scrollTop: $("#" + match[1]).offset().top }, 1);
}
// PX
else {
var $window = $('#fne-content', window.parent.document);
if ($window !== null && $window !== undefined) {
$window.animate({ scrollTop: $("#" + match[1]).offset().top }, 1);
}
}
}
});
var self = this;
/* for ARGA */
//$("[data-block_type='mn1']").delegate("[data-block_type='answer']", 'click', function(event) {
$("[data-block_type='showanswer'] p").click(function (event) {
var $jq = $(this);
event.stopImmediatePropagation();
if ($jq.text().match(/Answer Question/)) {
var $p = $jq.parent();
var $p1 = $p.parent();
var $ta = $p1.find('textarea')
$ta.css('display', 'block');
$p1.find('.question_action_div').css('display', 'block');
$p1.find('.essay_question_evaulation_feedback').css('display', 'block');
$jq.text("[Hide Answer]");
$ta.before($p);
}
else if ($jq.text().match(/Hide Answer/)) {
var $hp_show = $jq.parent();
var $hp_ques = $hp_show.parent().parent();
var $hp_box = $hp_ques.parent();
$hp_ques.find('textarea').css('display', 'none');
$hp_ques.find('.question_action_div').css('display', 'none');
$hp_ques.find('.essay_question_evaulation_feedback').css('display', 'none');
$jq.text("[Answer Question]");
$hp_ques.after($hp_show);
}
});
// new show answer links
/* for Native PX */
/*
$("[data-block_type='showanswer'] p").click(function(event) {
var $jq = $(this);
var $jq_parent = $jq.parent();
event.stopImmediatePropagation();
//safe_log("mn1 show answer handler: " + this + ": " + $jq.text());
if ($jq.text().match(/Answer Question/)) {
//safe_log("mn1 currently answer question");
//$jq.parent().next().find('[data-type="query_display"]').show();
$jq_parent.prev().find(".cke_skin_bh").css('display', 'block');
$jq.text("[Hide Answer]");
$jq_parent.prev().find(".rich-text-editor").prepend($jq_parent);
}
else if ($jq.text().match(/Hide Answer/)) {
//safe_log("mn1 currently hide answer");
//$jq.parent().next().find('[data-type="query_display"]').hide();
$jq_parent.parent().find(".cke_skin_bh").css('display', 'none');
$jq.text("[Answer Question]");
$jq.parents("[data-type='question']").parent().append($jq_parent);
}
});
*/
// we don't have gre tables any more
/*
if ($("#gre_chart").length > 0) {
$("textarea.query_essay_ta").each(function(index, element) {
var $textarea = $(element);
$textarea.before("");
});
}
*/
// This was for ARGA which we aren't using any more(???)
$('.question_action_div').find('input').each(function () {
var $input = $(this);
$input.wrap('');
});
// load editor and gre helper functions if this page has a gre chart
/*
if ($("#gre_chart").length > 0) {
//$.getScript('asset/ckeditor/ckeditor.js');
//$.getScript('asset/gre/gre_arga.js');
$.ajax({
url: "asset/ckeditor/ckeditor.js",
dataType: "script",
async: false,
cache: false
});
$.ajax({
url: "asset/gre/gre_arga.js",
dataType: "script",
async: false,
cache: false
});
}
*/
// We aren't pushing down "Summing Up So Far" boxes any more
/*
if ($("body#gre").length == 0) {
$('[data-block_type="box_seeking"]').each(function(index, element) {
var $seek_box = $(element);
var $para = $seek_box.next();
// since we can't add classes to tags there might be a
// wrapped around the
tag we are trying to get
if ($para[0].nodeName != "P") {
$para = $para.children("p");
}
//safe_log($para.get(0));
var $push_div = $("
");
var line_height = getLineHeight($para.get(0));
//safe_log("line height: " + line_height);
$seek_box.before($push_div);
var seek_height = $seek_box.outerHeight();
var seek_num_lines = Math.ceil(seek_height / line_height);
var para_height = $para.outerHeight(true);
var para_num_lines = para_height / line_height;
var push_div_height = (para_num_lines - seek_num_lines) * line_height;
var para_bottom = $para.outerHeight(true) + $para.position().top;
var seek_bottom = seek_height + $seek_box.position().top;
if (seek_bottom < para_bottom) {
//$push_div.css('height', (push_div_height - line_height) + "px");
push_div_height -= line_height;
$push_div.css('height', push_div_height + "px");
}
$seek_box.css('marginTop', '1em');
// second pass
para_bottom = $para.outerHeight(true) + $para.position().top;
seek_bottom = seek_height + $seek_box.position().top;
});
}
*/
// Doing this here (instead of in initialize) because if we do it before
// we move the "box_seeking" (above) then we lose the event handler on the
// "termref" for some reason and I'm not sure what is causing that at
// this moment.
//this.glossary = new Glossary();
this.glossary = new Glossary_subtype();
/* update event handler on figures to use OpenSupp */
$("[data-type='figure']").each(function (index, element) {
var jq = $(element);
//safe_log("click handler for " + jq.data("figure-id"));
var ijq = $("img", jq);
if (jq.attr("data-expandable") != "false") {
var match = jq.data("altsrc").match(/(.*)\/(.*)/);
if (match != null) {
ijq.unbind('click');
ijq.click(function (event) {
xBookUtilOpenSupp(match[1], match[2]);
});
// regular images have a child 'head'
jq.find("[data-block_type='head']").click(function () { return xBookUtilOpenSupp(match[1], match[2]); }).css("cursor", "pointer");
jq.find("[data-block_type='vs_num']").click(function () { return xBookUtilOpenSupp(match[1], match[2]); }).css("cursor", "pointer");
// map and visual activities have 'head' and 'title' siblings
/*
jq.siblings("[data-block_type='head']").click(function() { return xBookOpenSupp(match[1],match[2]); }).css("cursor", "pointer");
jq.siblings("[data-block_type='title']").click(function() { return xBookOpenSupp(match[1],match[2]); }).css("cursor", "pointer");
*/
}
}
});
// These next group of three each loops will ultimately become
// obsolete because we are going to handle all special links in
// the global
.click handler
// add handler for numbered figure links (and maps)
$('[data-block_type^="fig:"]').each(function () {
var jq = $(this);
var start = jq.attr("data-block_type");
var match = start.match(/fig:(.*)\/(.*)/);
jq.click(function () { return xBookUtilOpenSupp(match[1], match[2]); });
});
// add handler for document links
$('[data-block_type^="doc:"]').each(function () {
var jq = $(this);
var start = jq.attr("data-block_type");
var match = start.match(/doc:(.*)/);
jq.click(function () { return xBookUtilOpenSupp('root', match[1]); });
});
// add handler for visual source links
$('[data-block_type^="vs:"]').each(function () {
var jq = $(this);
var start = jq.attr("data-block_type");
var match = start.match(/vs:(.*)/);
jq.click(function () { return xBookUtilOpenSupp('root', match[1]); });
});
// scrolling link boxes
$("[data-block_type='link_box']").jScrollElement();
// use the imagesLoaded plugin to adjust div wrapper width around images
// after they are loaded
$('#manuscript').imagesLoaded(adjustFigBorders);
// read in footnotes js file if needed
if ($(".footnote").length != 0) {
import_footnotes_file();
}
// if we are on websterfw then create the answer boxes
// Native PX
/*
if ($("[data-type='question']").length != 0) {
websterfw_create_answer_boxes();
}
*/
// This is being handled in the global .click handler now
// we need to disable any that have a target of _disable
/*
$('a[target="_disable"]').click(function(e) {
e.preventDefault();
});
*/
/*
// make sure we are at the anchor target if one was passed in with the URL
var anchor = window.location.hash.substring(1);
//safe_log("anchor: " + anchor);
if (anchor != "") {
//safe_log("scrolling to id: #" + anchor);
//$(document).scrollTop($("#" + anchor).offset().top);
window.location.hash = "#" + anchor;
}
*/
// make sure we are at the anchor target if one was passed in with the URL
var anchor = window.location.hash.substring(1);
if (anchor != undefined && anchor != "") {
//window.location.hash = "#" + anchor;
//window.location.href = "#my-new-hash";
if ($("#" + anchor).length != 0) {
$('html,body').animate({ scrollTop: $("#" + anchor).offset().top }, 1);
}
}
/*
var page_url = window.location.href;
if (page_url.match(/#/)) {
var temp;
var target = "#" + window.location.href.substring(window.location.href.indexOf('#')+1);
//safe_log("target: " + target);
if ($(target).length > 0) {
$(document).scrollTop( $(target).offset().top );
}
}
*/
// PX stuff to get iframe scroll bars functioning properly
/* activate this later if needed
$('#document-body-iframe', window.parent.document).attr('scrolling', 'yes');
$('#document-body-iframe', window.parent.document).css('height', '100%');
*/
}
});
//player = new Player_subtype(); /* called at the end of this file */
// This is specific to strayer
function get_href_chapter(href) {
var match = href.match(/#ch0?(\d+)/);
if (match != null) {
safe_log("get_href_chapter(1): returning " + match[1]);
return match[1];
}
// if we have a part, then return 1 for parts 1/2/3 and 13 for parts 4/5/6
match = href.match(/#pt0?(\d)/);
if (match != null) {
if (match[1] == "1" || match[1] == "2" || match[1] == "3") {
safe_log("get_href_chapter(4): part 1/2/3, returning 1");
return 1;
}
else {
safe_log("get_href_chapter(4): part 4/5/6, returning 13");
return 13;
}
}
// if we have a page
match = href.match(/#page-(\d+)/);
if (match != null) {
var page_num = parseInt(match[1]);
if (page_num < 558) {
safe_log("get_href_chapter(5): page num < 558, returning 11");
return 11;
}
else if (page_num > 609) {
safe_log("get_href_chapter(5): page num > 609, returning 13");
return 13;
}
else {
safe_log("get_href_chapter(5): page is from chapter 12 , returning 12");
return 12;
}
}
match = href.match(/0?(\d+)_\d+/);
if (match != null) {
safe_log("get_href_chapter(2): returning " + match[1]);
return match[1];
}
safe_log("get_href_chapter(3): can't find chapter for " + href);
return 0;
}
function import_footnotes_file() {
var body = document.getElementsByTagName("body")[0];
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
// get URL of current xbook page
//var curr_url = xBookUtilGetPageUrl();
var base_url = xBookUtilGetBaseUrl();
// remove filename from URL
//match = curr_url.match(/(.*\/).*/);
//var supp_url = match[1];
var fn_file = base_url + "asset/footnotes/" + xBookUtilGetChapter() + "_fn.js";
script.setAttribute('src', fn_file);
body.appendChild(script);
}
function getLineHeight(elem) {
var addendum = "
x";
var h0 = elem.offsetHeight;
elem.innerHTML += addendum;
var h1 = elem.offsetHeight;
elem.innerHTML = elem.innerHTML.slice(0, -addendum.length);
return h1 - h0;
}
function adjustFigBorders() {
$('[data-type="figure"], [data-block_type^="map"]').each(function (index, element) {
var jq = $(element);
var ijq = $("[data-mmtype]", jq); // the figure's main image will have a mmtype tag
var width = ijq.width();
// If we can't get the image width yet then just go with the defaults
if (width > 0) {
jq.css("width", width + "px");
}
else {
}
});
}
/* Book ID */
var xBookUtilBookId = "strayer2e";
/* This holds the ID-to-filename translations */
var xBookUtilIdObject = {};
/* This function takes a file name found in an internal link (e.g. maps/1_1.html or 9_2)
and formats it properly for use in a URL. */
function xBookUtilPrepareFilenameForUrl(file) {
// first, remove leading '/' if found
file = file.replace(/^\//, "");
//safe_log("xBookUtilPrepareFilenameForUrl: file = " + file);
// Fix up 'shortcut' links (those that end in \d+_\d+).
var match = file.match(/(.*?)(\d+_\d+)$/);
if (match !== null) {
//safe_log("xBookUtilPrepareFilenameForUrl (shorcut link): [" + match[1] + "], [" + match[2] + "]");
// if the filename is just \d+_\d+ then add 'bookID_ch'
if (match[1] === "" || match[1] === undefined || match[1] === null) {
file = xBookUtilBookId + "_ch" + match[2] + ".html";
}
else {
// if there is a '/' in the filename then just add .html to the end
if (match[1].search(/\//) != -1) {
file = file + ".html";
}
// otherwise add 'bookID_' and 'prefix'
else {
file = xBookUtilBookId + "_" + match[1] + match[2] + ".html";
}
}
}
// If there are no '/'s in the file name then this is a file in the main(root)
// ebook directory and we are done.
if (file.search(/\//) < 0) {
return file;
}
// Otherwise, this file is under the asset/ directory and we need to make sure
// it is formatted properly.
// If the filename already begins with 'asset/' then it is ready to go
if (file.search(/^asset\//) != -1) {
return file;
}
// Add 'asset/' to beginning of file name
return ("asset/" + file);
}
/*
This function takes the unique ID(id) passed in and converts it to the
filename it is found in.
The ID should be of the form: /^([^\-]+)\-(.*)/
If the first part of the ID is "page" then it is a "page ID" and the file name
will be pulled from the appropriate page ID json file.
Otherwise it is a regular unique ID and the file name will be pulled from json
file that corresponds to the first part of the id (e.g. ch01-p001 will pull from
ch01.json).
*/
function xBookUtilGetFileFromId(id) {
// first see if we already have id loaded in object
var file = xBookUtilIdObject[id];
if (file !== undefined && file !== null) {
return file;
}
// there are two types of IDs:
// - general internal links that start with ch\d+\- (e.g. ch01-p063).
// - page links of the form page\-.* (e.g page-100 or page-A-3).
// if it is not loaded, then load the appropriate IDs into xBookUtilIdObject
var match = id.match(/^([^\-]+)\-(.*)/);
if (match === null) {
safe_log("xBookUtilGetFileFromId: bad id: " + id);
return null;
}
var ch;
if (match[1] === "page") {
var page_num = parseInt(match[2], 10);
if (isNaN(page_num)) {
ch = "page0";
}
else {
ch = "page" + parseInt(page_num / 100);
}
}
else {
ch = match[1];
}
xBookUtilGetIds(ch);
// try one more time
file = xBookUtilIdObject[id];
if (file !== undefined && file !== null) {
//safe_log("xBookUtilGetFileFromId returns " + file);
return file;
}
safe_log("xBookUtilGetFileFromId: Can't find filename for id " + id);
return null;
}
/* This loads the unique ID/filenames from the specified json file(jfile)
into xBookUtilIdObject */
function xBookUtilGetIds(jfile) {
// get base URL
var base_url = xBookUtilGetBaseUrl();
var file = base_url + "asset/ids/" + jfile + ".json";
//safe_log("xBookUtilGetIds: reading " + file);
$.ajax({
url: file,
cache: true,
dataType: "text",
async: false, // we don't want to move on until we have the data.
success: function (data) {
// load json data from file in xBookUtilIdObject
xBookUtilIdObject = jQuery.parseJSON(data);
return true;
},
error: function (jqXHR, textStatus, errorThrown) {
safe_log("xBookUtilGetIds: Couldn't get ids from file " + file + ": " + textStatus + ":" + errorThrown);
return false;
}
});
}
/* This is a newer, more streamlined version for opening a supp window.
file: (REQUIRED) name of file that will open in supp window
- if file does not contain '/' then file will be in main(root) book directory
- if file begins with 'asset/' then file will be in asset/ directory
- otherwise, file will be in subdirectory of asset/ (e.g maps/1_1.html would mean
open file in asset/maps/1_1.html)
win_name: (OPTIONAL) specify name of supp window
NOTE: Currently this does not open external URLs (http://), so don't try it.
*/
function xBookUtilOpenSuppWin(file, win_name) {
//safe_log("xBookUtilOpenSuppWin: file = " + file);
var anchor = "";
var match = file.match(/([^#]+)(#.*)/);
if (match != null) {
file = match[1];
anchor = match[2];
}
var suppWinPos = 10; // make this configurable?
var new_win_name = "xBookSuppWin";
// get base URL of book
var base_url = xBookUtilGetBaseUrl();
// get proper filename for URL
//safe_log("before xBookUtilPrepareFilenameForUrl: " + file);
var pop_file = xBookUtilPrepareFilenameForUrl(file);
//safe_log("after xBookUtilPrepareFilenameForUrl: " + pop_file);
var re = new RegExp("^" + xBookUtilBookId + "_([a-z]+\\d+_\\d+)\\.html$");
var pop_match = pop_file.match(re);
if (pop_match != null) {
// remove # on target
anchor = anchor.replace(/^#/, '');
// fix first chapter page problem for strayer
var ebook_page = pop_match[1];
var href_match = ebook_page.match(/^(ch\d+)_1$/);
if (href_match != null) {
ebook_page = href_match[1] + "_3";
}
var pop_url = base_url + "asset/supp_win.html?bookid=" + xBookUtilBookId + "&manuscript=" + ebook_page + "&target=" + anchor + "&baseurl=" + base_url;
var sw = window.open(pop_url, "xBookSuppWinPage", "top=" + suppWinPos + ",left=" + suppWinPos + ",width=850,height=900,resizable,scrollbars", true);
sw.focus();
/*
match = supp_url.match(/digfir-published/);
if (match !== null) {
if (parent !== undefined && parent.iframe_wrapper !== undefined) {
parent.iframe_wrapper.registerWindow(sw);
}
}
*/
return;
}
// create URL
var supp_url = base_url + pop_file + anchor;
if (win_name !== undefined) {
new_win_name = win_name;
}
// TODO: make width/height variable?
var sw = window.open(supp_url, new_win_name, "top=" + suppWinPos + ",left=" + suppWinPos + ",width=780,height=600,resizable,scrollbars", true);
sw.focus();
// register pop up if we are in the wrapper iframe
// (this is not used in PX, so we will need to figure out how to automatically
// close the supp window if someone logs out of PX)
match = supp_url.match(/digfir-published/);
if (match !== null) {
if (parent !== undefined && parent.iframe_wrapper !== undefined) {
parent.iframe_wrapper.registerWindow(sw);
}
}
}
/* This pops open a supp window to display a file.
dir: (REQUIRED) directory where file is located under asset/
If file is in asset/ then pass '' or null or "asset".
If file is in parent of asset/ (the root book dir) then pass 'root'.
file: (REQUIRED) name of file
win_name: (OPTIONAL) specify name of supp window
*/
function xBookUtilOpenSupp(dir, file, win_name) {
var suppWinPos = 10; // make this configurable?
var new_win_name = "xBookSuppWin";
// get URL of current xbook page
var curr_url = xBookUtilGetPageUrl();
// remove filename from URL
var match = curr_url.match(/(.*\/).*/);
var supp_url = match[1];
// create URL for supp window
if (dir === "root") {
supp_url += file;
}
else if (dir === null || dir === "" || dir === "asset") {
supp_url += "asset/" + file;
}
else {
supp_url += "asset/" + dir + "/" + file;
}
if (win_name !== undefined) {
new_win_name = win_name;
}
// TODO: make width/height variable?
var sw = window.open(supp_url, new_win_name, "top=" + suppWinPos + ",left=" + suppWinPos + ",width=780,height=600,resizable,scrollbars", true);
sw.focus();
// register pop up if we are in the wrapper iframe
// (this is not used in PX, so we will need to figure out how to automatically
// close the supp window if someone logs out of PX)
match = supp_url.match(/websterfw/);
if (match !== null) {
if (parent !== undefined && parent.iframe_wrapper !== undefined) {
parent.iframe_wrapper.registerWindow(sw);
}
}
}
/* This is specific to LP */
function xBookGetCourseID() {
var elements = document.location.search.split('&');
// Currently, it appears we can find the actual course ID in the the xdm_e variable
// of the document "search" string (hopefully this doesn't change)
var queryParts = $(elements).filter(function (index) { return this.toLowerCase().indexOf('xdm_e=') >= 0 });
if (queryParts.length > 0) {
var url = queryParts[0].split('=')[1];
url = decodeURIComponent(url);
var url_match = url.match(/launchpad\/([^\/]+)\//);
if (url_match != null) {
//safe_log("xBookGetCourseID: returning " + url_match[1]);
return url_match[1];
}
}
safe_log("xBookGetCourseID: returning null");
return null;
}
/* If we are viewing an xbook page on PX then this will return the PX-specific
URL of the page. Otherwise it returns window.location.href */
function xBookUtilGetPageUrl() {
//safe_log(document.location.search);
var elements = document.location.search.split('&');
// PX URL will have ContentUrl variable
var queryParts = $(elements).filter(function (index) { return this.toLowerCase().indexOf('contenturl=') > 0 });
// Turns out that PX will not always have ContentUrl, it may just have "Url"
if (queryParts.length == 0) {
queryParts = $(elements).filter(function (index) { return this.toLowerCase().indexOf('url=') > 0 });
}
// If we did not find ContentUrl (or Url) then return window href
if (queryParts.length == 0) {
var href_url = window.location.href;
href_url = href_url.replace(/\?.*/, "");
//safe_log("xBookUtilGetPageUrl: returning window href: " + href_url);
return href_url;
}
// get value of ContentUrl (or Url)
var url = queryParts[0].split('=')[1];
// decode the url
url = decodeURIComponent(url);
// apparently the url may now have args tacked onto the end of it
url = url.replace(/\?.*/, "");
return url;
}
/* This function gets the 'base' URL for the book (the url for the main(root)
directory of the book). You can then tack on filename paths to create a URL
to a specific page.
It always returns a URL with a trailing '/'.
*/
function xBookUtilGetBaseUrl() {
var curr_page_url = xBookUtilGetPageUrl();
// remove trailing filename (everything after the last '/')
var match = curr_page_url.match(/(.*\/).*/);
var base_url = match[1];
// remove asset/ (and all trailing directories) if found
base_url = base_url.replace(/\/asset\/.*/, "/");
//safe_log("xBookUtilGetBaseUrl: " + base_url);
return base_url;
}
/*
Returns the alpha_numeric chapter/part/fm number of the file name.
For example:
chapter 1 returns "ch1"
part 3 returns "part3"
front matter 2 returns "fm2"
*/
function xBookUtilGetChapter() {
var url = xBookUtilGetPageUrl();
//safe_log("xBookUtilGetChapter: " + url);
var match = url.match(/_([a-z]+\d+)_\d+\.html/);
if (match !== null) {
return match[1];
}
/*
match = url.match(/_part0?(\d+)_\d+\.html/);
if (match !== null) {
return "part" + match[1];
}
match = url.match(/_fm0?(\d+)_\d+\.html/);
if (match !== null) {
return "fm" + match[1];
}
*/
return -1;
}
/* Opens PX ebook page. Argument is html file name (e.g. strayer2e_ch1_1.html) */
function xBookUtilOpenPxId(file) {
var re = new RegExp(xBookUtilBookId + "_([a-z]+\\d+)_");
var match = file.match(re);
if (match == null) {
safe_log("xBookUtilOpenPxId: bad file " + file);
return false;
}
var jfile = match[1];
// get base URL
var base_url = xBookUtilGetBaseUrl();
var px_file = base_url + "asset/ids/px_" + jfile + ".json";
var PX_IDs = {};
$.ajax({
url: px_file,
cache: true,
dataType: "text",
async: false, // we don't want to move on until we have the data.
success: function (data) {
// load json data from file in xBookUtilIdObject
PX_IDs = jQuery.parseJSON(data);
if (PX_IDs[file] != undefined) {
safe_log("xBookUtilOpenPxId: opening " + PX_IDs[file]);
top.PxPage.openContent({ id: PX_IDs[file] });
return false;
}
safe_log("xBookUtilOpenPxId: can't find PX ID for " + file);
return false;
},
error: function (jqXHR, textStatus, errorThrown) {
safe_log("xBookUtilOpenPxId: Couldn't get ids from file " + file + ": " + textStatus + ":" + errorThrown);
return false;
}
});
}
function LoadSection(file, target) {
var temp;
var curr_url = window.location.href;
//safe_log(curr_url);
var match = curr_url.match(/(.*\/).*/);
curr_url = match[1];
//safe_log(curr_url);
var new_url = curr_url + file + "#" + target;
//safe_log(new_url);
window.location.href = new_url;
}
player = new Player_subtype();