jessyInk.js revision a00a58fc3850b7b52549322b31e8b943ee16fed7
// Copyright 2008, 2009 Hannes Hochreiner
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
// Set onload event handler.
// Creating a namespace dictionary. The standard Inkscape namespaces are taken from inkex.py.
var NSS = new Object();
// Keycodes.
var SPACE_KEY = 32;
var ESCAPE_KEY = 27;
// Presentation modes.
var SLIDE_MODE = 1;
var INDEX_MODE = 2;
var DRAWING_MODE = 3;
// Mouse handler actions.
var MOUSE_UP = 1;
var MOUSE_DOWN = 2;
var MOUSE_MOVE = 3;
var MOUSE_WHEEL = 4;
// Parameters.
var HEIGHT = 0;
var WIDTH = 0;
var INDEX_COLUMNS_DEFAULT = 4;
var INDEX_OFFSET = 0;
var STATE_START = -1;
var STATE_END = -2;
var BACKGROUND_COLOR = null;
var slides = new Array();
// Initialisation.
var currentMode = SLIDE_MODE;
var masterSlide = null;
var activeSlide = 0;
var activeEffect = 0;
var lastFrameTime = null;
var processingEffect = false;
var transCounter = 0;
var effectArray = 0;
var defaultTransitionInDict = new Object();
var defaultTransitionOutDict = new Object();
var jessyInkInitialised = false;
// Initialise char and key code dictionaries.
// Initialise mouse handler dictionary.
var progress_bar_visible = false;
var timer_elapsed = 0;
var timer_start = timer_elapsed;
var history_counter = 0;
var history_original_elements = new Array();
var history_presentation_elements = new Array();
var mouse_original_path = null;
var mouse_presentation_path = null;
var mouse_last_x = -1;
var mouse_last_y = -1;
var path_colour = "red";
var path_width_default = 3;
var path_width = path_width_default;
var path_paint_width = path_width;
var number_of_added_slides = 0;
/** Initialisation function.
* The whole presentation is set-up in this function.
*/
function jessyInkInit()
{
// Make sure we only execute this code once. Double execution can occur if the onload event handler is set
// in the main svg tag as well (as was recommended in earlier versions). Executing this function twice does
// not lead to any problems, but it takes more time.
if (jessyInkInitialised)
return;
// Making the presentation scaleable.
if (VIEWBOX)
{
}
else
{
}
// Setting the background color.
{
{
{
}
}
}
// Defining clip-path.
{
if (!existingClipPath)
{
}
}
// Making a list of the slide and finding the master slide.
var tempSlides = new Array();
var existingJessyInkPresentationLayer = null;
{
if (nodes[counter].getAttributeNS(NSS["inkscape"], "groupmode") && (nodes[counter].getAttributeNS(NSS["inkscape"], "groupmode") == "layer"))
{
if (nodes[counter].getAttributeNS(NSS["inkscape"], "label") && nodes[counter].getAttributeNS(NSS["jessyink"], "masterSlide") == "masterSlide")
else if (nodes[counter].getAttributeNS(NSS["inkscape"], "label") && nodes[counter].getAttributeNS(NSS["jessyink"], "presentationLayer") == "presentationLayer")
else
}
{
}
}
// Hide master slide set default transitions.
if (masterSlide)
{
defaultTransitionInDict = propStrToDict(masterSlide.getAttributeNS(NSS["jessyink"], "transitionIn"));
defaultTransitionOutDict = propStrToDict(masterSlide.getAttributeNS(NSS["jessyink"], "transitionOut"));
}
if (existingJessyInkPresentationLayer != null)
{
}
// Set start slide.
if (activeSlide < 0)
activeSlide = 0;
JessyInkPresentationLayer.setAttributeNS(NSS["jessyink"], "presentationLayer", "presentationLayer");
// Gathering all the information about the transitions and effects of the slides, set the background
// from the master slide and substitute the auto-texts.
{
// Set build in transition.
var dict;
else
if (key != "name")
// Set build out transition.
else
if (key != "name")
// Copy master slide content.
if (masterSlide)
{
}
// Setting clip path.
// Substitute auto texts.
substituteAutoTexts(node, node.getAttributeNS(NSS["inkscape"], "label"), counter + 1, tempSlides.length);
// Set effects.
var tempEffects = new Array();
var groups = new Object();
{
var propName = "";
var dir = 0;
if (IOCounter == 0)
{
propName = "effectIn";
dir = 1;
}
else if (IOCounter == 1)
{
propName = "effectOut";
dir = -1;
}
{
// Put every element that has an effect associated with it, into its own group.
// Unless of course, we already put it into its own group.
{
}
var effectDict = new Object();
{
{
if (!effectDict["options"])
effectDict["options"] = new Object();
}
}
}
}
// Make invisible, but keep in rendering tree to ensure that bounding box can be calculated.
// Create a transform group.
// Add content to transform group.
while (node.firstChild)
// Transfer the transform attribute from the node to the transform group.
{
}
// Create a view group.
// Insert background.
if (BACKGROUND_COLOR != null)
{
}
// Set views.
var tempViews = new Array();
// Set initial view even if there are no other views.
{
{
matrixOld = pointMatrixToTransformation(rectToMatrix(element)).mult((new matrixSVG()).fromSVGMatrix(slides[counter].viewGroup.getScreenCTM()).inv().mult((new matrixSVG()).fromSVGMatrix(element.parentNode.getScreenCTM())).inv());
}
else
{
var effectDict = new Object();
{
{
if (!effectDict["options"])
effectDict["options"] = new Object();
}
}
effectDict["options"]["matrixNew"] = pointMatrixToTransformation(rectToMatrix(element)).mult((new matrixSVG()).fromSVGMatrix(slides[counter].viewGroup.getScreenCTM()).inv().mult((new matrixSVG()).fromSVGMatrix(element.parentNode.getScreenCTM())).inv());
}
// Remove element.
}
// Consolidate view array and append it to the effect array.
{
{
if (tempViews[viewCounter])
{
tempEffects[tempViews[viewCounter]["order"]][tempEffects[tempViews[viewCounter]["order"]].length] = tempViews[viewCounter];
}
}
}
// Set consolidated effect array.
{
{
if (tempEffects[effectCounter])
}
}
node.setAttribute("onmouseover", "if ((currentMode == INDEX_MODE) && ( activeSlide != " + counter + ")) { indexSetActiveSlide(" + counter + "); };");
// Set visibility for initial state.
if (counter == activeSlide)
{
}
else
{
}
}
// Set key handler.
{
{
}
}
// Set mouse handler.
{
{
{
if (!mouseHandlerDictionary[mode])
mouseHandlerDictionary[mode] = new Object();
}
}
}
// Check effect number.
{
activeEffect = 0;
}
{
}
jessyInkInitialised = true;
}
/** Function to subtitute the auto-texts.
*
* @param node the node
* @param slideName name of the slide the node is on
* @param slideNumber number of the slide the node is on
* @param numberOfSlides number of slides in the presentation
*/
{
{
}
}
/** Convenience function to get an element depending on whether it has a property with a particular name.
* This function emulates some dearly missed XPath functionality.
*
* @param node the node
* @param namespace namespace of the attribute
* @param name attribute name
*/
{
var elems = new Array();
{
}
return elems;
}
/** Function to dispatch the next effect, if there is none left, change the slide.
*
* @param dir direction of the change (1 = forwards, -1 = backwards)
*/
function dispatchEffects(dir)
{
if (slides[activeSlide]["effects"] && (((dir == 1) && (activeEffect < slides[activeSlide]["effects"].length)) || ((dir == -1) && (activeEffect > 0))))
{
processingEffect = true;
if (dir == 1)
{
activeEffect += dir;
}
else if (dir == -1)
{
activeEffect += dir;
}
transCounter = 0;
lastFrameTime = null;
}
else if (((dir == 1) && (activeSlide < (slides.length - 1))) || (((dir == -1) && (activeSlide > 0))))
{
}
}
/** Function to skip effects and directly either put the slide into start or end state or change slides.
*
* @param dir direction of the change (1 = forwards, -1 = backwards)
*/
function skipEffects(dir)
{
if (slides[activeSlide]["effects"] && (((dir == 1) && (activeEffect < slides[activeSlide]["effects"].length)) || ((dir == -1) && (activeEffect > 0))))
{
processingEffect = true;
else
activeEffect = 0;
if (dir == 1)
else
processingEffect = false;
}
else if (((dir == 1) && (activeSlide < (slides.length - 1))) || (((dir == -1) && (activeSlide > 0))))
{
}
}
/** Function to change between slides.
*
* @param dir direction (1 = forwards, -1 = backwards)
*/
function changeSlide(dir)
{
processingEffect = true;
effectArray = new Array();
effectArray[0] = new Object();
if (dir == 1)
{
}
else if (dir == -1)
{
}
activeSlide += dir;
effectArray[1] = new Object();
if (dir == 1)
{
}
else if (dir == -1)
{
}
else
activeEffect = 0;
if (dir == -1)
else
transCounter = 0;
lastFrameTime = null;
}
/** Function to toggle between index and slide mode.
*/
function toggleSlideIndex()
{
if (currentMode == SLIDE_MODE)
{
INDEX_OFFSET = -1;
}
else if (currentMode == INDEX_MODE)
{
{
if (counter == activeSlide)
{
activeEffect = 0;
}
else
{
}
}
if (progress_bar_visible)
{
}
}
}
/** Function to run an effect.
*
* @param dir direction in which to play the effect (1 = forwards, -1 = backwards)
*/
{
var done = true;
{
done &= fade(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]);
done &= appear(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]);
done &= pop(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]);
done &= view(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]);
}
if (!done)
{
var currentTime = (new Date()).getTime();
var timeDiff = 1;
if (lastFrameTime != null)
{
if (timeDiff <= 0)
timeDiff = 1;
}
}
else
{
processingEffect = false;
}
}
/** Function to display the index sheet.
*
* @param offsetNumber offset number
*/
function displayIndex(offsetNumber)
{
var offsetX = 0;
var offsetY = 0;
if (offsetNumber < 0)
offsetNumber = 0;
{
{
}
else
{
slides[counter]["element"].setAttribute("transform","scale("+1/INDEX_COLUMNS+") translate("+offsetX+","+offsetY+")");
}
}
//do we need to save the current offset?
if (INDEX_OFFSET != offsetNumber)
}
/** Function to set the active slide in the slide view.
*
* @param nbr index of the active slide
*/
function slideSetActiveSlide(nbr)
{
else if (nbr < 0)
nbr = 0;
activeEffect = 0;
}
/** Function to set the active slide in the index view.
*
* @param nbr index of the active slide
*/
function indexSetActiveSlide(nbr)
{
else if (nbr < 0)
nbr = 0;
}
/** Function to set the page and active slide in index view.
*
* @param nbr index of the active slide
*
* NOTE: To force a redraw,
* set INDEX_OFFSET to -1 before calling indexSetPageSlide().
*
* This is necessary for zooming (otherwise the index might not
* get redrawn) and when switching to index mode.
*
* INDEX_OFFSET = -1
* indexSetPageSlide(activeSlide);
*/
function indexSetPageSlide(nbr)
{
else if (nbr < 0)
nbr = 0;
//calculate the offset
if (offset < 0)
offset = 0;
//if different from kept offset, then record and change the page
if (offset != INDEX_OFFSET)
{
}
//set the active slide
}
/** Event handler for key press.
*
* @param e the event
*/
function keydown(e)
{
if (!e)
else
}
// Set event handler for key down.
/** Event handler for key press.
*
* @param e the event
*/
function keypress(e)
{
document.onkeypress = null;
if (!e)
}
/** Function to supply the default char code dictionary.
*
* @returns default char code dictionary
*/
function getDefaultCharCodeDictionary()
{
var charCodeDict = new Object();
charCodeDict[SLIDE_MODE] = new Object();
charCodeDict[INDEX_MODE] = new Object();
charCodeDict[DRAWING_MODE] = new Object();
return charCodeDict;
}
/** Function to supply the default key code dictionary.
*
* @returns default key code dictionary
*/
function getDefaultKeyCodeDictionary()
{
var keyCodeDict = new Object();
keyCodeDict[SLIDE_MODE] = new Object();
keyCodeDict[INDEX_MODE] = new Object();
keyCodeDict[DRAWING_MODE] = new Object();
keyCodeDict[INDEX_MODE][UP_KEY] = function() { return indexSetPageSlide(activeSlide - INDEX_COLUMNS); };
keyCodeDict[INDEX_MODE][DOWN_KEY] = function() { return indexSetPageSlide(activeSlide + INDEX_COLUMNS); };
keyCodeDict[INDEX_MODE][PAGE_UP_KEY] = function() { return indexSetPageSlide(activeSlide - INDEX_COLUMNS * INDEX_COLUMNS); };
keyCodeDict[INDEX_MODE][PAGE_DOWN_KEY] = function() { return indexSetPageSlide(activeSlide + INDEX_COLUMNS * INDEX_COLUMNS); };
return keyCodeDict;
}
/** Function to handle all mouse events.
*
* @param evnt event
* @param action type of event (e.g. mouse up, mouse wheel)
*/
{
if (!evnt)
var retVal = true;
if (!processingEffect && mouseHandlerDictionary[currentMode] && mouseHandlerDictionary[currentMode][action])
{
}
return retVal;
}
// Set mouse event handler.
// Moz
if (window.addEventListener)
{
window.addEventListener('DOMMouseScroll', function(e) { return mouseHandlerDispatch(e, MOUSE_WHEEL); }, false);
}
// Opera Safari OK - may not work in IE
/** Function to supply the default mouse handler dictionary.
*
* @returns default mouse handler dictionary
*/
function getDefaultMouseHandlerDictionary()
{
var mouseHandlerDict = new Object();
mouseHandlerDict[SLIDE_MODE] = new Object();
mouseHandlerDict[INDEX_MODE] = new Object();
mouseHandlerDict[DRAWING_MODE] = new Object();
return mouseHandlerDict;
}
/** Function to switch from slide mode to drawing mode.
*/
function slideSwitchToDrawingMode()
{
var tempDict;
else
tempDict = new Object();
}
/** Function to switch from drawing mode to slide mode.
*/
function drawingSwitchToSlideMode()
{
var tempDict;
else
tempDict = new Object();
}
/** Function to decrease the number of columns in index mode.
*/
function indexDecreaseNumberOfColumns()
{
if (INDEX_COLUMNS >= 3)
{
INDEX_COLUMNS -= 1;
INDEX_OFFSET = -1
}
}
/** Function to increase the number of columns in index mode.
*/
function indexIncreaseNumberOfColumns()
{
if (INDEX_COLUMNS < 7)
{
INDEX_COLUMNS += 1;
INDEX_OFFSET = -1
}
}
/** Function to reset the number of columns in index mode.
*/
function indexResetNumberOfColumns()
{
if (INDEX_COLUMNS != INDEX_COLUMNS_DEFAULT)
{
INDEX_OFFSET = -1
}
}
/** Function to reset path width in drawing mode.
*/
function drawingResetPathWidth()
{
}
/** Function to set path width in drawing mode.
*
* @param width new path width
*/
function drawingSetPathWidth(width)
{
path_width = width;
}
/** Function to set path colour in drawing mode.
*
* @param colour new path colour
*/
function drawingSetPathColour(colour)
{
}
/** Function to query the duration of the presentation from the user in slide mode.
*/
function slideQueryDuration()
{
{
}
updateTimer();
}
/** Function to add new slide in slide mode.
*
* @param afterSlide after which slide to insert the new one
*/
function slideAddSlide(afterSlide)
{
updateTimer();
}
/** Function to toggle the visibility of the progress bar in slide mode.
*/
function slideToggleProgressBarVisibility()
{
if (progress_bar_visible)
{
progress_bar_visible = false;
}
else
{
progress_bar_visible = true;
}
}
/** Function to reset the timer in slide mode.
*/
function slideResetTimer()
{
updateTimer();
}
/** Convenience function to pad a string with zero in front up to a certain length.
*/
{
{
}
return outStr;
}
/** Function to update the export layer.
*/
function slideUpdateExportLayer()
{
// Suspend redraw since we are going to mess with the slides.
var tmpActiveSlide = activeSlide;
var tmpActiveEffect = activeEffect;
var exportedLayers = new Array();
{
var exportNode;
var maxEffect = 0;
{
}
exportNode.setAttributeNS(NSS["inkscape"], "label", "slide_" + padString((counterSlides + 1).toString(), slides.length.toString().length) + "_effect_" + padString("0", maxEffect.toString().length));
{
{
for (var subCounter = 0; subCounter < slides[counterSlides]["effects"][counter].length; subCounter++)
{
}
var layerName = "slide_" + padString((counterSlides + 1).toString(), slides.length.toString().length) + "_effect_" + padString((counter + 1).toString(), maxEffect.toString().length);
}
}
}
// Copy image.
// Delete viewbox form new imag and set width and height.
// Delete all layers and script elements.
var nodesToBeRemoved = new Array();
{
{
{
}
}
}
{
// Before removing the node, check whether it contains any definitions.
{
{
}
}
// Remove node.
}
// Set current layer.
if (exportedLayers[0])
{
var namedView;
{
if ((newDoc.childNodes[nodeCounter].nodeType == 1) && (newDoc.childNodes[nodeCounter].getAttribute('id') == 'base'))
{
}
}
if (namedView)
{
namedView.setAttributeNS(NSS['inkscape'], 'current-layer', exportedLayers[0].getAttributeNS(NSS['inkscape'], 'label'));
}
}
// Add exported layers.
{
}
// Serialise the new document.
var serializer = new XMLSerializer();
var strm =
{
content : "",
close : function() {},
flush : function() {},
};
// Unsuspend redraw.
}
/** Function to undo last drawing operation.
*/
function drawingUndo()
{
mouse_presentation_path = null;
mouse_original_path = null;
{
var p = history_presentation_elements.pop();
p = history_original_elements.pop();
}
}
/** Event handler for mouse down in drawing mode.
*
* @param e the event
*/
function drawingMousedown(e)
{
var value = 0;
if (e.button)
else if (e.which)
if (value == 1)
{
var p = calcCoord(e);
mouse_last_x = e.clientX;
mouse_last_y = e.clientY;
else
return false;
}
return true;
}
/** Event handler for mouse up in drawing mode.
*
* @param e the event
*/
function drawingMouseup(e)
{
if(!e)
if (mouse_presentation_path != null)
{
var p = calcCoord(e);
d += " L" + p.x + "," + p.y;
mouse_presentation_path = null;
mouse_original_path = null;
return false;
}
return true;
}
/** Event handler for mouse move in drawing mode.
*
* @param e the event
*/
function drawingMousemove(e)
{
if(!e)
var dist = (mouse_last_x - e.clientX) * (mouse_last_x - e.clientX) + (mouse_last_y - e.clientY) * (mouse_last_y - e.clientY);
if (mouse_presentation_path == null)
{
return true;
}
if (dist >= mouse_min_dist_sqr)
{
var p = calcCoord(e);
d += " L" + p.x + "," + p.y;
mouse_last_x = e.clientX;
mouse_last_y = e.clientY;
}
return false;
}
/** Event handler for mouse wheel events in slide mode.
* based on http://adomas.org/javascript-mouse-wheel/
*
* @param e the event
*/
function slideMousewheel(e)
{
var delta = 0;
if (!e)
if (e.wheelDelta)
{ // IE Opera
}
else if (e.detail)
{ // MOZ
}
if (delta > 0)
skipEffects(-1);
else if (delta < 0)
skipEffects(1);
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
/** Event handler for mouse wheel events in index mode.
* based on http://adomas.org/javascript-mouse-wheel/
*
* @param e the event
*/
function indexMousewheel(e)
{
var delta = 0;
if (!e)
if (e.wheelDelta)
{ // IE Opera
}
else if (e.detail)
{ // MOZ
}
if (delta > 0)
else if (delta < 0)
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
/** Function to set the path paint width.
*/
function set_path_paint_width()
{
svgPoint1.x = 0.0;
svgPoint1.y = 0.0;
svgPoint2.x = 1.0;
svgPoint2.y = 0.0;
path_paint_width = path_width / Math.sqrt((svgPoint2.x - svgPoint1.x) * (svgPoint2.x - svgPoint1.x) + (svgPoint2.y - svgPoint1.y) * (svgPoint2.y - svgPoint1.y));
}
/** The view effect.
*
* @param dir direction the effect should be played (1 = forwards, -1 = backwards)
* @param element the element the effect should be applied to
* @param time the time that has elapsed since the beginning of the effect
* @param options a dictionary with additional options (e.g. length of the effect); for the view effect the options need to contain the old and the new matrix.
*/
{
var length = 250;
var fraction;
if (!options["matrixInitial"])
{
if (tempString)
else
}
fraction = 1;
else
{
}
if (dir == 1)
{
if (fraction <= 0)
{
}
else if (fraction >= 1)
{
options["matrixInitial"] = null;
return true;
}
else
{
element.setAttribute("transform", options["matrixInitial"].mix(options["matrixNew"], fraction).toAttribute());
}
}
else if (dir == -1)
{
if (fraction <= 0)
{
}
else if (fraction >= 1)
{
options["matrixInitial"] = null;
return true;
}
else
{
element.setAttribute("transform", options["matrixInitial"].mix(options["matrixOld"], fraction).toAttribute());
}
}
return false;
}
/** The fade effect.
*
* @param dir direction the effect should be played (1 = forwards, -1 = backwards)
* @param element the element the effect should be applied to
* @param time the time that has elapsed since the beginning of the effect
* @param options a dictionary with additional options (e.g. length of the effect)
*/
{
var length = 250;
var fraction;
fraction = 1;
else
{
}
if (dir == 1)
{
if (fraction <= 0)
{
}
else if (fraction >= 1)
{
return true;
}
else
{
}
}
else if (dir == -1)
{
if (fraction <= 0)
{
}
else if (fraction >= 1)
{
return true;
}
else
{
}
}
return false;
}
/** The appear effect.
*
* @param dir direction the effect should be played (1 = forwards, -1 = backwards)
* @param element the element the effect should be applied to
* @param time the time that has elapsed since the beginning of the effect
* @param options a dictionary with additional options (e.g. length of the effect)
*/
{
if (dir == 1)
{
}
else if (dir == -1)
{
}
return true;
}
/** The pop effect.
*
* @param dir direction the effect should be played (1 = forwards, -1 = backwards)
* @param element the element the effect should be applied to
* @param time the time that has elapsed since the beginning of the effect
* @param options a dictionary with additional options (e.g. length of the effect)
*/
{
var length = 500;
var fraction;
fraction = 1;
else
{
}
if (dir == 1)
{
if (fraction <= 0)
{
}
else if (fraction >= 1)
{
return true;
}
else
{
if (opacityFraction > 1)
opacityFraction = 1;
element.setAttribute("transform", "translate(" + offsetX + "," + offsetY + ") scale(" + fraction + ")");
}
}
else if (dir == -1)
{
if (fraction <= 0)
{
}
else if (fraction >= 1)
{
return true;
}
else
{
}
}
return false;
}
/** Function to set a slide either to the start or the end state.
*
* @param slide the slide to use
* @param state the state into which the slide should be set
*/
{
{
{
{
{
}
}
}
else if (state == STATE_START)
{
{
{
}
}
}
else
{
{
{
}
}
}
}
}
/** Convenience function to translate a attribute string into a dictionary.
*
* @param str the attribute string
* @return a dictionary
* @see dictToPropStr
*/
function propStrToDict(str)
{
var obj = new Object();
{
{
}
}
return obj;
}
/** Convenience function to translate a dictionary into a string that can be used as an attribute.
*
* @param dict the dictionary to convert
* @return a string that can be used as an attribute
* @see propStrToDict
*/
function dictToPropStr(dict)
{
var str = "";
{
}
return str;
}
/** Sub-function to add a suffix to the ids of the node and all its children.
*
* @param node the node to change
* @param suffix the suffix to add
* @param replace dictionary of replaced ids
* @see suffixNodeIds
*/
{
{
{
}
if ((node.nodeName == "use") && (node.getAttributeNS(NSS["xlink"], "href")) && (replace[node.getAttribute(NSS["xlink"], "href")]))
if (node.childNodes)
{
}
}
}
/** Function to add a suffix to the ids of the node and all its children.
*
* @param node the node to change
* @param suffix the suffix to add
* @return the changed node
* @see suffixNodeIds_sub
*/
{
var replace = new Object();
return node;
}
/** Function to build a progress bar.
*
* @param parent node to attach the progress bar to
*/
function createProgressBar(parent_node)
{
}
/** Function to hide the progress bar.
*
*/
function hideProgressBar()
{
if (!progress_bar)
{
return;
}
}
/** Function to show the progress bar.
*
*/
function showProgressBar()
{
if (!progress_bar)
{
return;
}
}
/** Set progress bar value.
*
* @param value the current slide number
*
*/
function setProgressBarValue(value)
{
if (!rect_progress_bar)
{
return;
}
if (value < 1)
{
// First slide, assumed to be the title of the presentation
var x = 0;
var w = 0.01 * HEIGHT;
}
{
// Last slide, assumed to be the end of the presentation
var w = 0.01 * HEIGHT;
}
else
{
value -= 1;
}
}
/** Set time indicator.
*
* @param value the percentage of time elapse so far between 0.0 and 1.0
*
*/
function setTimeIndicatorValue(value)
{
if (!circle_timer_indicator)
{
return;
}
if (value < 0.0)
{
value = 0.0;
}
if (value > 1.0)
{
value = 1.0;
}
}
/** Update timer.
*
*/
function updateTimer()
{
timer_elapsed += 1;
}
/** Convert screen coordinates to document coordinates.
*
* @param e event with screen coordinates
*
* @return coordinates in SVG file coordinate system
*/
function calcCoord(e)
{
return svgPoint;
}
/** Add slide.
*
* @param after_slide after which slide the new slide should be inserted into the presentation
*/
function addSlide(after_slide)
{
var new_slide = new Object();
new_slide["element"] = g;
// Set build in transition.
new_slide["transitionIn"] = new Object();
var dict = defaultTransitionInDict;
if (key != "name")
// Set build out transition.
new_slide["transitionOut"] = new Object();
if (key != "name")
// Copy master slide content.
if (masterSlide)
{
}
// Substitute auto texts.
substituteAutoTexts(g, "Whiteboard " + number_of_added_slides, "W" + number_of_added_slides, slides.length);
g.setAttribute("onmouseover", "if ((currentMode == INDEX_MODE) && ( activeSlide != " + (after_slide + 1) + ")) { indexSetActiveSlide(" + (after_slide + 1) + "); };");
// Create a transform group.
// Add content to transform group.
while (g.firstChild)
// Transfer the transform attribute from the node to the transform group.
if (g.getAttribute("transform"))
{
g.removeAttribute("transform");
}
// Create a view group.
// Insert background.
if (BACKGROUND_COLOR != null)
{
}
// Set initial view even if there are no other views.
// Insert slide
if (next_node)
{
}
else
{
}
new_slide["original_element"] = g;
if (next_node)
{
}
else
{
}
//resetting the counter attributes on the slides that follow the new slide...
{
slides[counter]["element"].setAttribute("onmouseover", "if ((currentMode == INDEX_MODE) && ( activeSlide != " + counter + ")) { indexSetActiveSlide(" + counter + "); };");
}
}
/** Convenience function to obtain a transformation matrix from a point matrix.
*
* @param mPoints Point matrix.
* @return A transformation matrix.
*/
function pointMatrixToTransformation(mPoints)
{
}
/** Convenience function to obtain a matrix with three corners of a rectangle.
*
* @param rect an svg rectangle
* @return a matrixSVG containing three corners of the rectangle
*/
function rectToMatrix(rect)
{
rectXcorr = 0;
rectYcorr = 0;
{
}
else
{
}
{
}
else
{
}
newVectors = (new matrixSVG()).fromElements(rectXcorr, rectXcorr + rectWidth, rectXcorr + rectWidth, rectYcorr, rectYcorr, rectYcorr + rectHeight, 0, 0, 0);
}
/** Function to handle JessyInk elements.
*
* @param node Element node.
*/
function handleElement(node)
{
{
var url;
var width;
var height;
var x;
var y;
var transform;
{
{
}
}
{
{
}
}
{
{
{
}
else
{
}
}
}
}
}
/** Class processing the location hash.
*
* @param str location hash
*/
function LocationHash(str)
{
this.slideNumber = 0;
this.effectNumber = 0;
// Try to extract slide number.
{
try
{
if (!isNaN(slideNumber))
{
}
}
catch (e)
{
}
}
// Try to extract effect number.
{
try
{
if (!isNaN(effectNumber))
{
this.effectNumber = effectNumber;
}
}
catch (e)
{
}
}
}
/** Class representing an svg matrix.
*/
function matrixSVG()
{
this.e31 = 0;
this.e32 = 0;
this.e33 = 0;
}
/** Constructor function.
*
* @param a element a (i.e. 1, 1) as described in the svg standard.
* @param b element b (i.e. 2, 1) as described in the svg standard.
* @param c element c (i.e. 1, 2) as described in the svg standard.
* @param d element d (i.e. 2, 2) as described in the svg standard.
* @param e element e (i.e. 1, 3) as described in the svg standard.
* @param f element f (i.e. 2, 3) as described in the svg standard.
*/
{
this.e11 = a;
this.e12 = c;
this.e13 = e;
this.e21 = b;
this.e22 = d;
this.e23 = f;
this.e31 = 0;
this.e32 = 0;
this.e33 = 1;
return this;
}
/** Constructor function.
*
* @param matrix an svg matrix as described in the svg standard.
*/
{
this.e11 = m.a;
this.e12 = m.c;
this.e13 = m.e;
this.e21 = m.b;
this.e22 = m.d;
this.e23 = m.f;
this.e31 = 0;
this.e32 = 0;
this.e33 = 1;
return this;
}
/** Constructor function.
*
* @param e11 element 1, 1 of the matrix.
* @param e12 element 1, 2 of the matrix.
* @param e13 element 1, 3 of the matrix.
* @param e21 element 2, 1 of the matrix.
* @param e22 element 2, 2 of the matrix.
* @param e23 element 2, 3 of the matrix.
* @param e31 element 3, 1 of the matrix.
* @param e32 element 3, 2 of the matrix.
* @param e33 element 3, 3 of the matrix.
*/
{
return this;
}
/** Constructor function.
*
* @param attrString string value of the "transform" attribute (currently only "matrix" is accepted)
*/
{
// Opera does not use commas to separate the values of the matrix, only spaces.
this.e31 = 0;
this.e32 = 0;
this.e33 = 1;
return this;
}
/** Output function
*
* @return a string that can be used as the "transform" attribute.
*/
{
return "matrix(" + this.e11 + ", " + this.e21 + ", " + this.e12 + ", " + this.e22 + ", " + this.e13 + ", " + this.e23 + ")";
}
/** Matrix nversion.
*
* @return the inverse of the matrix
*/
{
det = this.e11 * (this.e33 * this.e22 - this.e32 * this.e23) - this.e21 * (this.e33 * this.e12 - this.e32 * this.e13) + this.e31 * (this.e23 * this.e12 - this.e22 * this.e13);
return out;
}
/** Matrix multiplication.
*
* @param op another svg matrix
* @return this * op
*/
{
return out;
}
/** Matrix addition.
*
* @param op another svg matrix
* @return this + op
*/
{
return out;
}
/** Matrix mixing.
*
* @param op another svg matrix
* @parma contribOp contribution of the other matrix (0 <= contribOp <= 1)
* @return (1 - contribOp) * this + contribOp * op
*/
{
return out;
}
/** Trimming function for strings.
*/
{
return this.replace(/^\s+|\s+$/g, '');
}