and
to data-width
var fig_width = $.trim($figureDiv.attr('data-width'));
if (!xBookUtils.emptyValue(fig_width) && /^\d+$/.test(fig_width)) {
$figureDiv.attr('data-layout-width', '');
$image.attr('width', fig_width);
$figureDiv.css('width', fig_width + "px");
}
// Otherwise, if resizeDivWidth is requested then attach to each
// figure
else if (resize_div_width === "on") {
$figureDiv.imagesLoaded(function($images, $proper, $broken) {
$proper.each(function() {
var $image = $(this);
// Since we may have added additional elements between the
// image and the figure div (for credits) we need to use
// closest() instead of parent() to get figure div
var $parent = $image.closest('[data-type="figure"]');
if ($parent.length != 0) {
var img_width = $image.width();
if (img_width > 0) {
$parent.css("width", img_width + "px");
}
}
});
});
}
}); // end each()
} // end init()
}); // end Figures_manuscript_subtype
/*
Added 12/23/2015 by Bruce.
Adds ability to align table columns by character:
where CH can be a single character or string.
*/
var Tables_manuscript_subtype = Tables.extend({
init: function() {
this._super();
// fix any tables with data-align-char
this._set_data_align_char();
},
// call this function at the end of initialize2
align_columns: function() {
// align tables with align="char"
this._align_table_columns();
},
// set the 'char' attribute for any tables that have data-align-char assigned
_set_data_align_char: function() {
var that = this;
$("[data-type='table'][data-align-char]").each(function() {
var $this = $(this);
var align_char = $this.attr('data-align-char');
if (xBookUtils.emptyValue(align_char)) {
return;
}
xBookUtils.debug("setting align char to " + align_char + " for table #" + $this.attr('id'));
var $rows = $this.children('table').children("tbody").children('tr');
$rows.each(function() {
$.each(this.cells, function(col){
var $td = $(this);
if (!that._has_char_align($td)) {
return;
}
$td.attr("char", align_char);
});
});
});
},
_align_table_columns: function() {
var that = this;
$("#manuscript").find("table").each(function() {
var $table = $(this);
if ($table.parent().attr('data-char-align') === "false") {
xBookUtils.debug("table #" + $table.parent().attr('id') + " data-char-align='false'");
return;
}
var hasCharAlign = []; // stores alignment info for each column
var $rows = $table.children("tbody").children('tr');
// find the columns that have character alignment
$rows.each(function() {
$.each(this.cells, function(col){
var $td = $(this);
if (!that._has_char_align($td)) {
return;
}
// if we already have an align char set for the column we are done
if (hasCharAlign[col] !== undefined &&
hasCharAlign[col].ch !== undefined) {
return;
}
// find char we are aligning on
var align_char = $td.attr('char');
if (align_char === undefined) {
align_char = "."; // default
}
// set align char for this colum
hasCharAlign[col] = {};
hasCharAlign[col].ch = align_char;
xBookUtils.debug("table #" + $table.parent().attr('id') + " column " + col + " is aligned on char " + align_char);
});
});
// If we didn't find any columns with char align then we are done
if (hasCharAlign.length < 1) {
return;
}
// 1. add internal spans
// 2. get width of align char
// 3. for each column, get max width of left and right span
$rows.each(function() {
$.each(this.cells, function(col){
var $td = $(this);
if (!that._has_char_align($td)) {
return;
}
// Search for align char in |
var align_char = hasCharAlign[col].ch;
// escape special chars
align_char = align_char.replace(/([.*])/, "\\$1");
var regexp = new RegExp("(.*)(" + align_char + ")(.*)")
var html = $td.html();
var new_html;
var dmatch = html.match(regexp);
// if | has alignment character
if (dmatch !== null) {
new_html = "" + dmatch[1] + "" + dmatch[2] + "" + dmatch[3] + "";
$td.html(new_html);
if (hasCharAlign[col].hasalignchar !== true) {
hasCharAlign[col].hasalignchar = true;
var $ch_align_span = $td.find('.char-align-middle');
hasCharAlign[col].chwidth = $ch_align_span.width();
}
// get width of align char if needed
if (hasCharAlign[col].charwidth === undefined) {
hasCharAlign[col].charwidth = $td.find('.char-align-middle').width();
}
// get width of left span and set max left width if needed
var left_width = $td.find('.char-align-left').width();
if (hasCharAlign[col].maxleftwidth === undefined) {
hasCharAlign[col].maxleftwidth = left_width;
}
else if (left_width > hasCharAlign[col].maxleftwidth) {
hasCharAlign[col].maxleftwidth = left_width;
}
// get width of right span and set max right width if needed
var right_width = $td.find('.char-align-right').width();
if (hasCharAlign[col].maxrightwidth === undefined) {
hasCharAlign[col].maxrightwidth = right_width;
}
else if (right_width > hasCharAlign[col].maxrightwidth) {
hasCharAlign[col].maxrightwidth = right_width;
}
}
// if | does not have alignment char
else {
new_html = "" + html + "";
$td.html(new_html);
// get width of left span and set max left width if needed
var left_width = $td.find('.char-align-left').width();
if (hasCharAlign[col].maxleftwidth === undefined) {
hasCharAlign[col].maxleftwidth = left_width;
}
else if (left_width > hasCharAlign[col].maxleftwidth) {
hasCharAlign[col].maxleftwidth = left_width;
}
// right width will always be 0
if (hasCharAlign[col].maxrightwidth === undefined) {
hasCharAlign[col].maxrightwidth = 0;
}
}
});
});
// go through cells one more time adding padding where necessary
var font_size;
$rows.each(function() {
$.each(this.cells, function(col){
var $td = $(this);
if (!that._has_char_align($td)) {
return;
}
// find font size if needed
if (font_size === undefined) {
var style = window.getComputedStyle($td[0], null);
font_size = parseFloat(style.fontSize);
}
var $table_align = $td.children('.char-align-table');
var left_width = $table_align.children('.char-align-left').width();
// If left width is less than maxleftwidth then pad to maxleftwidth
if (left_width < hasCharAlign[col].maxleftwidth) {
$table_align.css('padding-left', ((hasCharAlign[col].maxleftwidth - left_width) / font_size) + "em");
}
var right_width = $table_align.children('.char-align-right').width();
var right_padding = 0;
if (right_width < hasCharAlign[col].maxrightwidth) {
right_padding = hasCharAlign[col].maxrightwidth - right_width;
}
var $align_ch = $table_align.children('.char-align-middle');
if (hasCharAlign[col].hasalignchar == true &&
$align_ch.text() != hasCharAlign[col].ch) {
right_padding += hasCharAlign[col].chwidth;
}
if (right_padding > 0) {
$table_align.css('padding-right', (right_padding / font_size) + "em");
}
});
});
}); // end for each table
}, // end align_table_columns
// argument should be a jQuery | object
_has_char_align: function($td) {
// getAttribute is a workaround for IE
var align_value = $td[0].getAttribute("align");
if (align_value !== "char") {
return false;
}
return true;
}
}); // end Tables_manuscript_subtype
/*
Added by Bruce 11/08/2013
Updates Glossary class as follows:
- accesses terms from a central hash table instead of embedded in the page
- hash table is defined in asset/terms.js and/or chapter-specific JS files
- places the pop-up window near the mouse click to avoid scrolling issues in PX
This class works in conjunction with the xBookUtils object (specifically, it uses
the xBookUtils.terms object as the hash table to store the term/definitions pairs).
By default, it will load them from asset/term.js. Using the terms.js file
for both glossary terms and footnotes can create quite a big file. As an alternative,
you can define chapter specific entries (such as footnotes) in the book's
chapter-specific JS files.
To add this functionality to your book, add the following to the player init method
in your book's custom JS file *AFTER* the call to _super:
this.glossary = new Glossary_manuscript_subtype();
Glossary terms should be defined in the xml as usual:
...
where key is the key(term) in the hash table
Footnotes should be defined in the xml as
...
The leading "fn_" on the key denotes it as a footnote
Entries defined in asset/terms.js and the chapter-specific JS files
should be added to the xBookUtils.terms object:
xBookUtils.terms['term'] = "definition";
If you aren't going to use asset/terms.js then you can add {terms: false}
to the context object in order to prevent the browser from trying to load it.
this.glossary = new Glossary_manuscript({terms: false});
*/
var Glossary_manuscript_subtype = Glossary.extend({
// turn this "on" to make glossary terms pop on hover instead of click
hoverTerms: "off",
// specify termrefs that should not be clickable
hoverTermsNoClick: "",
// turn on to use new sticky div
useStickyDiv: "off",
// div used to display gloss/footnotes using hover
hoverDiv: undefined,
// div used to display "sticky" (dragable) gloss/footnotes
stickyDiv: undefined,
// holds timer id for remove_hover
hoverTimer: undefined,
// Called by click handler
// This is the old default version of displaying click terms
show_definition: function(term, Xclick, Yclick, $element) {
var Xcoord = Xclick - 225;
var Ycoord = (Yclick - $(document).scrollTop()) + 25;
// Determine whether we have a glossary term or footnote
var type; // will be set to either "Glossary" or "Footnote"
if (/^fn_/.test(term)) {
type = "Footnote";
}
else {
type = "Glossary";
}
var entry = this.get_entry(term);
// If we didn't find an entry show standard error message
if (entry === undefined) {
Standard_Dialog.open("Can't find entry", {
"title": type,
"modal": false,
"draggable": true,
"buttons": "none",
"position": [Xcoord, Ycoord]
});
safe_log("Glossary.show_definition: Can't find " + type + " entry for '" + term + "'");
return;
}
Standard_Dialog.open(entry, {
"title": type,
"modal": false,
"draggable": true,
"buttons": "none",
"position": [Xcoord, Ycoord],
"element": $element
});
return;
}, // end show_definition
// This is the new way of displaying both click and hover terms
show_term_def: function(term, Xclick, Yclick_top, Yclick_bottom, type) {
// Save off local copy to increase speed
var h_div;
if (type === "hover") {
h_div = this.hoverDiv;
}
else {
h_div = this.stickyDiv;
}
var entry = this.get_entry(term);
if (entry === undefined) {
entry = "Can't find entry";
safe_log("Glossary.show_hover_definition: Can't find entry for '" + term + "'");
}
// add data-type here so styling is in place before we
// calculate height
h_div.attr("data-type", this.get_prefix(term));
h_div.css({"left": "-999px", "display": "block"});
h_div.children('.glossary-content').html(entry);
var Xcoord = 0;
var Ycoord = 0;
// Don't let left side of the div go past left side of page
var p_width = h_div.outerWidth();
if (Xclick - (p_width/2) > 9) {
Xcoord = Xclick - (p_width/2);
}
else {
Xcoord = 10;
}
// Display div above mouse by default
if (type === "keydown") {
h_div.addClass("keydown");
}
else {
h_div.removeClass("keydown");
}
// top of viewport
var win_top_px = $(document).scrollTop();
if (xBookUtils.inBrainhoneyPlayer()) {
win_top_px = $('#examcontainer').parent().scrollTop();
}
// height of hover div with content
var p_height = h_div.outerHeight();
// top of hover div with content
var p_top_px = Yclick_top - p_height - 10;
// Don't let top of the div go past top of viewport
if (p_top_px > win_top_px) {
Ycoord = p_top_px;
}
else {
Ycoord = Yclick_bottom + 10;
}
h_div.css({"top": Ycoord + "px", "left": Xcoord + "px"});
if (type === "keydown") {
document.getElementById('glossary-sticky-kb-leave').focus();
}
},
get_entry: function(key) {
key = key.replace(/{/g, "<");
key = key.replace(/}/g, ">");
var lc_key = key.toLowerCase();
var entry = xBookUtils.terms[key];
if (entry === undefined) {
entry = xBookUtils.terms[lc_key];
}
if (entry === undefined) {
entry = xBookUtils.terms[lc_key.singularize()];
}
if (entry === undefined) {
entry = xBookUtils.terms[lc_key.pluralize()];
}
if (entry === undefined) {
entry = xBookUtils.terms[key.singularize()];
}
if (entry === undefined) {
entry = xBookUtils.terms[key.pluralize()];
}
// If we found an entry return it
if (entry !== undefined) {
return xBookUtils.prepareMarkup(entry);
}
// We didn't find the entry in the terms array so check for
// the entry in the traditional
$('[data-type="glossaryentry"]').each(function() {
var $this = $(this);
var term = $this.children('[data-type="term"]').html();
if (key === term || lc_key === term) {
entry = $this.children('[data-type="definition"]').html();
return false;
}
}); // end inner each
return entry;
},
get_prefix: function (data_term) {
var term_prefix = "gl"; // default is glossary
// data_term may be undefined because no term attribute was set,
// in this case it is a glossary def
if (data_term === undefined) {
return term_prefix;
}
var pre_match = data_term.match(/^([a-z][a-z])_/);
if (pre_match !== null) {
term_prefix = pre_match[1];
}
return term_prefix;
},
handle_mouse_event: function(element, event) {
if (event === undefined || event === null) {
safe_log("Glossary.handle_mouse_event: empty event");
return;
}
var $element = $(element);
var mouse_type = $element.attr('data-mouse');
// set mouse type if not specified in html
if (mouse_type !== "click" &&
mouse_type !== "hover" &&
mouse_type !== "noclick") {
// mouse_type is 'click' by default
mouse_type = "click";
// local copy for speed
var hover = this.hoverTerms;
// If hover is turned on globally we need to check if this 'type'
// has click turned off
if (hover === "on" || hover === "all") {
var noclick_array = this.hoverTermsNoClick.split(",");
if ($.inArray(this.get_prefix($element.attr('data-term')), noclick_array) >= 0) {
mouse_type = "noclick";
}
else {
mouse_type = "hover";
}
}
else if (hover !== "off" && !xBookUtils.emptyValue(hover)) {
var hover_array = hover.split(",");
if ($.inArray(this.get_prefix($element.attr('data-term')), hover_array) >= 0) {
mouse_type = "hover";
}
}
}
var $termref = $element;
var term = $termref.attr("data-term");
var offset = $termref.offset();
// bitwise OR will truncate the decimal points
var term_top = offset.top|0;
if (xBookUtils.inBrainhoneyPlayer()) {
term_top += $('#examcontainer').parent().scrollTop();
}
var term_center = offset.left + (($termref.outerWidth())/2)|0;
//var term_bottom = (offset.top + $termref.outerHeight())|0;
var term_bottom = (term_top + $termref.outerHeight())|0;
// If there is no data-term attribute than use the html in the span
if (xBookUtils.emptyValue(term)) {
term = $termref.html();
if (xBookUtils.emptyValue(term)) {
safe_log("Glossary.handle_mouse_event: can't find term value");
return false;
}
}
if (event.type === "click") {
if (mouse_type !== "noclick") {
if (this.hoverTerms === "on") {
this.hoverDiv.css("display", "none");
}
if (this.useStickyDiv === "on") {
this.show_term_def(term, term_center, term_top, term_bottom, "click");
}
else {
this.show_definition(term, offset.left, offset.top, $element);
}
}
}
else if (event.type === "mouseenter") {
if (mouse_type !== "click") {
clearTimeout(this.hoverTimeout);
this.hoverDiv.attr('data-mouse-active', '1');
this.show_term_def(term, term_center, term_top, term_bottom, "hover");
}
}
else if (event.type === "mouseleave") {
if (mouse_type !== "click") {
this.hoverDiv.attr('data-mouse-active', '0');
this.hoverTimer = setTimeout(this.remove_hover, 1000);
}
}
else if (event.type === "keydown") {
// 13 = Enter key
if (event.keyCode == 13) {
$termref.attr('data-last-focus', '1');
if (this.useStickyDiv === "on") {
this.show_term_def(term, term_center, term_top, term_bottom, "keydown");
}
else {
this.show_definition(term, offset.left, offset.top);
}
}
}
},
remove_hover: function() {
// Since we are calling this from setTimeout we need to refer to
// the class variables through the player object
clearTimeout(player.glossary.hoverTimeout);
var mouse_active = player.glossary.hoverDiv.attr('data-mouse-active');
if (mouse_active != 1) {
player.glossary.hoverDiv.css("display", "none");
}
},
init: function(context) {
// By default load asset/terms.js but if you don't need it to
// load then you can pass {terms: false} in the context object
if (context !== undefined && context.terms !== undefined &&
context.terms === false) {
// do nothing if context.terms is false
}
else {
var termsFile = xBookUtils.getBaseUrl() + "asset/terms.js";
var body = document.getElementsByTagName("body")[0];
var script = document.createElement('script');
script.setAttribute('type','text/javascript');
script.setAttribute('src', termsFile);
body.appendChild(script);
}
this.hoverTerms = player.cfg_Glossary_hoverTerms || this.hoverTerms;
this.hoverTermsNoClick = player.cfg_Glossary_hoverTermsNoClick || this.hoverTermsNoClick;
this.useStickyDiv = player.cfg_Glossary_useStickyDiv || this.useStickyDiv;
// Remove the click handler to terms added by init() in the parent class
$("span[data-type='termref']").each(function() {
var $this = $(this);
$this.unbind('click');
$this.attr('tabindex', '0');
});
// Local copy for speed
var $man = $('#manuscript');
if ($man.length > 0) {
var that = this;
if (this.hoverTerms === "on") {
// Add div for terms
this.hoverDiv = $('');
$man.append(this.hoverDiv);
this.hoverDiv.mouseenter(function() {
clearTimeout(this.hoverTimer);
$(this).attr('data-mouse-active', '1');
});
this.hoverDiv.mouseleave(function() {
$(this).attr('data-mouse-active', '0');
that.hoverTimer = setTimeout(that.remove_hover, 1000);
});
} // end if hoverTerms
if (this.useStickyDiv === "on") {
this.stickyDiv = $('');
$man.append(this.stickyDiv);
this.stickyDiv.draggable({
cancel: ".glossary-close, .glossary-content",
handle: ".glossary-top-bar",
containment: "#manuscript"
});
this.stickyDiv.delegate('#glossary-sticky-close, #glossary-sticky-kb-close','keydown click', function(event) {
if (event.keyCode == 13 || event.type === "click") {
that.stickyDiv.css('display', 'none');
// return focus to last term clicked
var $last_focus = $('[data-last-focus="1"]');
if ($last_focus.length > 0) {
$last_focus.attr('data-last-focus', '0');
$last_focus.focus();
}
}
});
this.stickyDiv.delegate('#glossary-sticky-kb-leave','keydown click', function(event) {
if (event.keyCode == 13 || event.type === "click") {
// return focus to last term clicked
var $last_focus = $('[data-last-focus="1"]');
if ($last_focus.length > 0) {
$last_focus.attr('data-last-focus', '0');
$last_focus.focus();
}
}
});
} // end if useStickyDiv
if (this.hoverTerms === "on") {
$man.delegate('[data-type="termref"]', 'mouseenter mouseleave click', function(event) {
player.glossary.handle_mouse_event(this, event);
});
}
else {
$man.delegate('[data-type="termref"]', 'click', function(event) {
player.glossary.handle_mouse_event(this, event);
});
}
} // end if manuscript
} // end init
}); // end Glossary
/*
Added by Bruce 11/03/2013
Updates create_links to use the xBookUtils.create_links function,
which adds the following:
- honors the target attribute if set in the XML
- keeps any custom data types set in the XML
To use this updated create_links method add the following *AFTER*
the call to this._super in the initialize method for Player_subtype
in your book's custom js file:
this.xrefs = new XRefs_manuscript_subtype();
*/
var XRefs_manuscript_subtype = XRefs.extend({
create_links: function(jq) {
xBookUtils.create_links(jq);
}
});
var Activity_manuscript_type = Activity.extend({
// don't show any initialization alerts for ebook pages
ARGA_initialization_alert: function() {
// ... unless a md value says to override that
if (player.md.show_standard_arga_initialization == "true") {
this._super();
} else {
// we just have to call ARGA_initialization_final
player.activity.ARGA_initialization_final();
}
},
// also don't show grade saved message
show_grade_saved_message: function() {
// ... unless a md value says to override that
if (player.md.show_standard_arga_grade_saved_message == "true") {
this._super();
}
}
});
var Player_manuscript_type = Player.extend({
// Global config variables
// set to "on" to automatically remove wrapper s around rawhtml
removeRawHtmlDivs: "off",
// set to "on" to enable 'show answer' button
showAnswer: "off",
// set to "off" to turn off auto wrapping of answers embedded in xml
showAnswerWrapThis: "on",
// set to "on" to automatically move box title (h3) out of inner box
Box_moveTitle: "off",
// block_types (separated by commas)
Box_moveTitleExclude: "",
// Hack to fix duplicate title header in XB doc viewer
XBDocumentViewerHeaderFix: "off",
// Remove the notes button in the XB doc viewer (cfg_XBDocumentViewerHeaderFix
// must be turned on).
XBDocumentViewerRemoveNotes: "off",
// Add default page number functionality
pageNumbers: "on",
// Prefix string to be shown before page number in print_page_box
PPB_prefix: "Printed Page ",
// 'Continuation' string to be shown after page number if in print_page_box
PPB_continued: "(cont.)",
// Prefix string to be shown before page number in page_starts
pageStart_prefix: "Page ",
// Hide/Show page numbers menu item in print_page_box
PPM_pageNumberToggle: "on",
// 'Go to page' menu item in print_page_box
PPM_pageJump: "on",
// Check for supp_content and add menu toggle if found
PPM_supplementalContent: "on",
// There is currently a bug in PX where if we open up ebook pages with
// renderIn=supp the Home button (among others) still appear. This removes them.
removePXSuppButtons: "on",
// This variable is intended to be private and will be set accordingly when the
// player loads. Developers should not touch this variable.
PXWindowName: "", // This will hold the "name" of the outermost PX main window
show_section_animate: function(section_to_show, direction) {
// make sure modal window is closed
$("#toc_dialog").dialog("close");
// slide in using parent function
this._super(section_to_show, direction);
// update slide_number and title
$(".slide_title").html(this.get_current_section().title);
$(".slide_number").find("span").html((section_to_show+1) + " of " + this.sections.length + " ");
// if this is the first/last section, dim the previous/next button
if (this.section_currently_showing == 0) {
$(".previous_button").addClass("button_dimmed");
} else {
$(".previous_button").removeClass("button_dimmed");
}
if (this.section_currently_showing == (this.sections.length - 1)) {
$(".next_button").addClass("button_dimmed");
} else {
$(".next_button").removeClass("button_dimmed");
}
$(document).trigger('df-content-rendered'); //added as DF-57
},
show_navigation: function() {
// if there are no subsections, there's no navigation to show
if (this.sections.length == 1) {
return;
}
var table = " "
+ ""+ UI_Elements.get_button_html({
extra_class: "toolbar_button prev_next_buttons previous_button",
label: this.md.previous_page_button,
fn: 'player.show_section("previous")'
}) + " | "
+ ""+ UI_Elements.get_button_html({
extra_class: "toolbar_button slide_number",
label: "1 of " + this.sections.length,
fn: 'player.show_toc()'
}) + " | "
+ ""+ UI_Elements.get_button_html({
extra_class: "toolbar_button prev_next_buttons next_button",
label: this.md.next_page_button,
fn: 'player.show_section("next")'
}) + " | "
+ "
"
$("#manuscript").prepend(" " + table + " ");
$("#manuscript").append(" " + table + " ");
$("#toolbar").show();
// 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"
}
});
// activate all other buttons
UI_Elements.activate_buttons();
},
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) {
extra_style = "toc_section_not_available";
}
html += ""
;
}
if (this.md.sequenced_sections == "true") {
html = " Click on a slide to view it. Note: Grey slides are not accessible until preceding slides have been viewed or completed. " + html;
}
html = " " + html + " ";
$("body").append(html);
$("#toc_dialog").dialog({title:"Jump To...", width:450, modal:true, buttons: [ {text:"OK", click: function() {$("#toc_dialog").dialog("close");}}]});
},
extract_activity_metadata: function() {
this._super();
this.required_metadata_val("next_page_button", "Read on!", true);
this.required_metadata_val("previous_page_button", "Back up", true);
// by default we do not require students to go through slides in order,
// and we restore them to their last-viewed slide when they return.
this.required_metadata_val("sequenced_sections", "false");
this.required_metadata_val("restore_last_viewed_section", "true");
this.required_metadata_val("section_sequence_message", "You must read each page, and complete any questions on the page, in sequence.");
},
initialize_sections: function() {
// Added by Bruce 11/03/2013
// Save original ID on each section to data-sec-id before _super replaces it.
$('[data-type="section"]').each(function() {
var $this = $(this);
$this.attr('data-sec-id', $this.attr('id'));
});
this._super();
// Add class to body if we are viewing page in supp window
(function() {
try {
var $supp_iframe = $('#xBookSuppWinNavPageFrame', window.parent.document);
if ($supp_iframe.length != 0) {
$("body").addClass("xBookSuppWinNavPage");
}
}
catch(err) { }
})();
if (this.removeRawHtmlDivs === "on") {
$('[data-type="rawhtml"]').each(function() {
var $this = $(this);
var raw_content = $this.contents();
$this.replaceWith(raw_content);
});
}
var boxMoveTitle = this.Box_moveTitle;
if (boxMoveTitle === "all") {
var excludes_array = this.Box_moveTitleExclude.split(",");
$('[data-type="box"]').each(function() {
$this = $(this);
var block_type = $this.attr('data-block_type');
if (!xBookUtils.emptyValue(block_type)) {
if ($.inArray(block_type, excludes_array) >= 0) {
return;
}
}
$this.each(xBookUtils.moveBoxTitle);
});
}
else if (boxMoveTitle !== "off") {
var includes_array = this.Box_moveTitle.split(",");
$('[data-type="box"]').each(function() {
$this = $(this);
var block_type = $this.attr('data-block_type');
if (!xBookUtils.emptyValue(block_type)) {
if ($.inArray(block_type, includes_array) >= 0) {
$this.each(xBookUtils.moveBoxTitle);
}
}
});
}
if (this.showAnswer === "on") {
// Add click handler for show answer buttons
$('.show_answer_button').live("click", function() {
$this = $(this);
// Show Answer button must have a target (this should
// always be the case but we'll check anyway)
var target_id = $this.attr('data-target');
if (xBookUtils.emptyValue(target_id)) {
safe_log("showAnswer: no target set on button");
return;
}
// Make sure target(answer) container exists
var $container = $("#" + target_id);
if ($container.length < 1) {
safe_log("showAnswer: target #" + target_id + " does not exist");
return;
}
// Toggle the 'show_answer_button_on' class for both the
// button and the answer container
$this.toggleClass('show_answer_button_on');
$container.toggleClass('show_answer_button_on');
});
// Look for any elements with data-show-answer
var wrap_answer = this.showAnswerWrapThis;
$('[data-show-answer]').each(function() {
var $this = $(this);
// If we've already found an answer for this element we are done
if ($this.attr('data-found-show-answer') === "true") {
return;
}
var answer_id = $this.attr('id');
var type = $this.attr('data-show-answer');
if (type === "this") {
var this_wrap = $this.attr('data-show-answer-wrap');
$this.attr('data-found-show-answer', "true");
// Do we need to wrap this answer in a box?
if ((wrap_answer === "on" && this_wrap !== "false") ||
this_wrap === "true") {
$this.before(" ");
$this.wrap(function() {
return " ";
});
$this.before(" ");
}
else {
$this.before(" ");
$this.addClass('show_answer_container');
}
}
else if (type === "array") {
// Check if answer is stored in xBookUtils.showAnswers array
$this.each(xBookUtils.checkShowAnswer);
}
});
} // end showAnswer === "on"
}, // end initialize_sections
initialize: function(id) {
xBookUtils.debug("digfir_ebook.js version number: " + xBookUtils.DFVersionNumber);
this.removePXSuppButtons = this.cfg_removePXSuppButtons || this.removePXSuppButtons;
if (this.removePXSuppButtons === "on" && xBookUtils.inPXSuppWin()) {
xBookUtils.removePXSuppControls();
}
var $body = $('body');
var $html = $('html');
if (xBookUtils.inBrainhoneyPlayer()) {
$html.addClass('bh_player');
$body.addClass('bh_html_quiz_ebook');
}
// Set scrollWindow (if needed) - currently this is only used for
// the docviewer in PX
if (xBookUtils.inDocViewer()) {
try {
//xBookUtils.scrollWindow = window.parent.parent.parent;
xBookUtils.scrollWindow = top.window;
xBookUtils.debug("initialize: setting scroll window to top (" + xBookUtils.scrollWindow.name + ")");
}
catch(err) {
safe_log("initialize: Can't get scrollWindow in docviewer");
xBookUtils.scrollWindow = undefined;
}
}
// We need to do this before _super because the original XRefs.create_links
// will wipe out any custom data-attributes we have set on the link spans
// and it won't honor the target set in the XML.
//
// Really, we should change XRefs.create_links do everything that
// xBookUtils.create_links is doing and then it wouldn't be necessary
// to call this here or even extend XRefs in the first place.
xBookUtils.create_links($body);
this._super(id);
// Add height to around |