From 66f05b5d5acc43e4615bc19045d3600ed93e328b Mon Sep 17 00:00:00 2001 From: Marco Date: Sun, 4 Sep 2011 12:32:46 +0200 Subject: Bin generated svgscript.hxx, add original file. Removes the old auto-generated svgscript, and instead generate it from the true source. --- filter/source/svg/js2hxx.py | 163 + filter/source/svg/makefile.mk | 4 + filter/source/svg/presentation_engine.js | 8320 ++++++++++++++++++++++++++++++ filter/source/svg/svgscript.hxx | 7465 --------------------------- 4 files changed, 8487 insertions(+), 7465 deletions(-) create mode 100755 filter/source/svg/js2hxx.py create mode 100644 filter/source/svg/presentation_engine.js delete mode 100644 filter/source/svg/svgscript.hxx (limited to 'filter') diff --git a/filter/source/svg/js2hxx.py b/filter/source/svg/js2hxx.py new file mode 100755 index 000000000000..0967dd60228f --- /dev/null +++ b/filter/source/svg/js2hxx.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python +# +# Version: MPL 1.1 / GPLv3+ / LGPLv3+ +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License or as specified alternatively below. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# Major Contributor(s): +# Copyright (C) 2011 Marco Cecchetti +# +# All Rights Reserved. +# +# For minor contributions see the git repository. +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 3 or later (the "GPLv3+"), or +# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), +# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable +# instead of those above. +# + +import os, sys + +MAX_LINES = 200 +VARIABLE_NAME = 'aSVGScript' + +def get_var_decl(n): + return 'static const char %s%d[] =' % ( VARIABLE_NAME, n ) + +script_name = os.path.basename( sys.argv[0] ) +infile_name = sys.argv[1] +outfile_name = sys.argv[2] + + +# collect input JavaScript file lines +if( not os.path.isfile( infile_name ) ): + print '%s: error: file "%s" not found' % ( script_name, infile_name ) + sys.exit( -1 ) + +infile = open( infile_name, 'r' ) +in_lines = [line.rstrip() for line in infile.readlines()] +infile.close() + + +valid_lines=[] +is_multiline_comment = False +lineNumber = 0 +emptyLineCount = 0 +for line in in_lines: + lineNumber += 1 + index = line.find('"') + if( index != -1 ): + print '%s: warning: processed file contains \'"\' at %d:%d' % ( script_name, lineNumber, index ) + + sline = line.strip() + + # strip comment lines except multilines comments that begins with one '/' and exactly 5 '*' + if( is_multiline_comment and sline.endswith( '*/' ) ): + is_multiline_comment = False + continue + + if( is_multiline_comment ): + continue + + if( sline.startswith( '//' ) ): + continue + + if( sline.startswith( '/*' ) and sline.endswith( '*/' ) ): + continue + + if( ( sline.startswith( '/*' ) and not sline.startswith( '/*****' ) ) + or sline.startswith( '/******' ) ): + is_multiline_comment = True + continue + + # append a 4 spaces indentation to each line + escaped_line = ' %s' % line + escaped_line = escaped_line.rstrip() + + # no more than 2 consecutive empty lines + if( escaped_line == '' ): + emptyLineCount += 1 + else: + emptyLineCount = 0 + + if( emptyLineCount > 2 ): + continue + + # append to some escape sequence another '\' + escaped_line = escaped_line.replace( '\\', '\\\\' ) + escaped_line = escaped_line.replace( '\n', '\\n') + escaped_line = escaped_line.replace( '\t', '\\t' ) + + valid_lines.append( escaped_line ) + + +# compute the number of needed fragments that is of C constant strings +total_valid_lines = len (valid_lines) + 2 +total_fragments = total_valid_lines / MAX_LINES +if( ( total_valid_lines % MAX_LINES ) != 0 ): + total_fragments += 1 + + + +out_lines = [] +out_lines.append( '' ) +out_lines.append( '#define N_SVGSCRIPT_FRAGMENTS %d' % total_fragments ) +out_lines.append( '' ) +out_lines.append( get_var_decl( 0 ) ) +out_lines.append( '"";' ) +out_lines.append( '' ) + + +outfile = open( outfile_name, 'w' ) +if( not os.path.isfile( outfile_name ) ): + print '%s: error: I cannot create file "%s"' % ( script_name, outfile_name ) + sys.exit( -1 ) + + +# C++ header +header_info = """ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* !! This file is auto-generated, do not edit !! */ +""" + +vim_setup = '/* vim:set shiftwidth=4 softtabstop=4 expandtab: */' + +outfile.write( header_info +'\n' ) +outfile.write( '\n' ) + +for line in out_lines: + outfile.write( line + '\n' ) + +outfile.write( '\n' ) +outfile.write( '\n' ) +outfile.write( vim_setup + '\n' ) + +outfile.close() + + + diff --git a/filter/source/svg/makefile.mk b/filter/source/svg/makefile.mk index 425eae9489a2..b76db4d90e99 100644 --- a/filter/source/svg/makefile.mk +++ b/filter/source/svg/makefile.mk @@ -108,6 +108,10 @@ $(INCCOM)$/tokens.cxx : $(MISC)$/tokens.gperf makefile.mk ALLTAR : $(MISC)/svgfilter.component +$(INCCOM)$/svgscript.hxx : presentation_engine.js js2hxx.py + js2hxx.py presentation_engine.js $@ +$(SLO)$/svgexport.obj : svgexport.cxx $(INCCOM)$/svgscript.hxx + $(MISC)/svgfilter.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ svgfilter.component $(XSLTPROC) --nonet --stringparam uri \ diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js new file mode 100644 index 000000000000..aa2835a4a87a --- /dev/null +++ b/filter/source/svg/presentation_engine.js @@ -0,0 +1,8320 @@ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * - Presentation Engine - * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / + +/** + * WARNING: any comment that should not be striped out by the script + * generating the C++ header file must starts with a '/' and exactly 5 '*' + * not striped examples: '/*****', '/***** *' + * striped examples: '/** ***' (not contiguous), '/******' (more than 5) + */ + + + +/***** + * @licstart + * + * The following is the license notice for the part of JavaScript code of this + * page included between the '@jessyinkstart' and the '@jessyinkend' notes. + */ + +/***** ****************************************************************** + * + * Copyright 2008, 2009 Hannes Hochreiner + * + * The JavaScript code included between the start note '@jessyinkstart' + * and the end note '@jessyinkend' is free software: you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License (GNU GPL) as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) + * any later version. The code is distributed WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. + * + * As additional permission under GNU GPL version 3 section 7, you + * may distribute non-source (e.g., minimized or compacted) forms of + * that code without the copy of the GNU GPL normally required by + * section 4, provided you include this license notice and a URL + * through which recipients can access the Corresponding Source. + * + *************************************************************************/ + +/***** + * You can find the complete source code of the JessyInk project at: + * @source http://code.google.com/p/jessyink/ + */ + +/***** + * @licend + * + * The above is the license notice for the part of JavaScript code of this + * page included between the '@jessyinkstart' and the '@jessyinkend' notes. + */ + + + +/***** + * @jessyinkstart + * + * The following code is a derivative work of some parts of the JessyInk + * project. + * @source http://code.google.com/p/jessyink/ + */ + + +/** Convenience function to get an element depending on whether it has a + * property with a particular name. + * + * @param node: element of the document + * @param name: attribute name + * + * @returns an array containing all the elements of the tree with root + * 'node' that own the property 'name' + */ +function getElementsByProperty( node, name ) +{ + var elems = new Array(); + + if( node.getAttribute( name ) ) + elems.push( node ); + + for( var counter = 0; counter < node.childNodes.length; ++counter ) + { + if( node.childNodes[counter].nodeType == 1 ) + { + var subElems = getElementsByProperty( node.childNodes[counter], name ); + elems = elems.concat( subElems ); + } + } + return elems; +} + +/** Event handler for key press. + * + * @param aEvt the event + */ +function onKeyDown( aEvt ) +{ + if ( !aEvt ) + aEvt = window.event; + + code = aEvt.keyCode || aEvt.charCode; + + if ( !processingEffect && keyCodeDictionary[currentMode] && keyCodeDictionary[currentMode][code] ) + return keyCodeDictionary[currentMode][code](); + else + document.onkeypress = onKeyPress; +} +//Set event handler for key down. +document.onkeydown = onKeyDown; + +/** Event handler for key press. + * + * @param aEvt the event + */ +function onKeyPress( aEvt ) +{ + document.onkeypress = null; + + if ( !aEvt ) + aEvt = window.event; + + str = String.fromCharCode( aEvt.keyCode || aEvt.charCode ); + + if ( !processingEffect && charCodeDictionary[currentMode] && charCodeDictionary[currentMode][str] ) + return charCodeDictionary[currentMode][str](); +} + +/** 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(); + + // slide mode + keyCodeDict[SLIDE_MODE][LEFT_KEY] + = function() { return dispatchEffects(-1); }; + keyCodeDict[SLIDE_MODE][RIGHT_KEY] + = function() { return dispatchEffects(1); }; + keyCodeDict[SLIDE_MODE][UP_KEY] + = function() { return skipEffects(-1); }; + keyCodeDict[SLIDE_MODE][DOWN_KEY] + = function() { return skipEffects(1); }; + keyCodeDict[SLIDE_MODE][PAGE_UP_KEY] + = function() { return switchSlide( -1, true ); }; + keyCodeDict[SLIDE_MODE][PAGE_DOWN_KEY] + = function() { return switchSlide( 1, true ); }; + keyCodeDict[SLIDE_MODE][HOME_KEY] + = function() { return aSlideShow.displaySlide( 0, true ); }; + keyCodeDict[SLIDE_MODE][END_KEY] + = function() { return aSlideShow.displaySlide( theMetaDoc.nNumberOfSlides - 1, true ); }; + keyCodeDict[SLIDE_MODE][SPACE_KEY] + = function() { return dispatchEffects(1); }; + + // index mode + keyCodeDict[INDEX_MODE][LEFT_KEY] + = function() { return indexSetPageSlide( theSlideIndexPage.selectedSlideIndex - 1 ); }; + keyCodeDict[INDEX_MODE][RIGHT_KEY] + = function() { return indexSetPageSlide( theSlideIndexPage.selectedSlideIndex + 1 ); }; + keyCodeDict[INDEX_MODE][UP_KEY] + = function() { return indexSetPageSlide( theSlideIndexPage.selectedSlideIndex - theSlideIndexPage.indexColumns ); }; + keyCodeDict[INDEX_MODE][DOWN_KEY] + = function() { return indexSetPageSlide( theSlideIndexPage.selectedSlideIndex + theSlideIndexPage.indexColumns ); }; + keyCodeDict[INDEX_MODE][PAGE_UP_KEY] + = function() { return indexSetPageSlide( theSlideIndexPage.selectedSlideIndex - theSlideIndexPage.getTotalThumbnails() ); }; + keyCodeDict[INDEX_MODE][PAGE_DOWN_KEY] + = function() { return indexSetPageSlide( theSlideIndexPage.selectedSlideIndex + theSlideIndexPage.getTotalThumbnails() ); }; + keyCodeDict[INDEX_MODE][HOME_KEY] + = function() { return indexSetPageSlide( 0 ); }; + keyCodeDict[INDEX_MODE][END_KEY] + = function() { return indexSetPageSlide( theMetaDoc.nNumberOfSlides - 1 ); }; + keyCodeDict[INDEX_MODE][ENTER_KEY] + = function() { return toggleSlideIndex(); }; + keyCodeDict[INDEX_MODE][SPACE_KEY] + = function() { return toggleSlideIndex(); }; + keyCodeDict[INDEX_MODE][ESCAPE_KEY] + = function() { return abandonIndexMode(); }; + + return keyCodeDict; +} + +/** 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(); + + // slide mode + charCodeDict[SLIDE_MODE]['i'] + = function () { return toggleSlideIndex(); }; + + // index mode + charCodeDict[INDEX_MODE]['i'] + = function () { return toggleSlideIndex(); }; + charCodeDict[INDEX_MODE]['-'] + = function () { return theSlideIndexPage.decreaseNumberOfColumns(); }; + charCodeDict[INDEX_MODE]['='] + = function () { return theSlideIndexPage.increaseNumberOfColumns(); }; + charCodeDict[INDEX_MODE]['+'] + = function () { return theSlideIndexPage.increaseNumberOfColumns(); }; + charCodeDict[INDEX_MODE]['0'] + = function () { return theSlideIndexPage.resetNumberOfColumns(); }; + + return charCodeDict; +} + + +function slideOnMouseDown( aEvt ) +{ + if (!aEvt) + aEvt = window.event; + + var nOffset = 0; + + if( aEvt.button == 0 ) + nOffset = 1; + else if( aEvt.button == 2 ) + nOffset = -1; + + if( 0 != nOffset ) + dispatchEffects( nOffset ); +} + +/** Event handler for mouse wheel events in slide mode. + * based on http://adomas.org/javascript-mouse-wheel/ + * + * @param aEvt the event + */ +function slideOnMouseWheel(aEvt) +{ + var delta = 0; + + if (!aEvt) + aEvt = window.event; + + if (aEvt.wheelDelta) + { // IE Opera + delta = aEvt.wheelDelta/120; + } + else if (aEvt.detail) + { // MOZ + delta = -aEvt.detail/3; + } + + if (delta > 0) + skipEffects(-1); + else if (delta < 0) + skipEffects(1); + + if (aEvt.preventDefault) + aEvt.preventDefault(); + + aEvt.returnValue = false; +} + +//Mozilla +if( window.addEventListener ) +{ + window.addEventListener( 'DOMMouseScroll', function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_WHEEL ); }, false ); +} + +//Opera Safari OK - may not work in IE +window.onmousewheel + = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_WHEEL ); }; + +/** Function to handle all mouse events. + * + * @param aEvt event + * @param anAction type of event (e.g. mouse up, mouse wheel) + */ +function mouseHandlerDispatch( aEvt, anAction ) +{ + if( !aEvt ) + aEvt = window.event; + + var retVal = true; + + if ( mouseHandlerDictionary[currentMode] && mouseHandlerDictionary[currentMode][anAction] ) + { + var subRetVal = mouseHandlerDictionary[currentMode][anAction]( aEvt ); + + if( subRetVal != null && subRetVal != undefined ) + retVal = subRetVal; + } + + if( aEvt.preventDefault && !retVal ) + aEvt.preventDefault(); + + aEvt.returnValue = retVal; + + return retVal; +} + +//Set mouse event handler. +document.onmousedown = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_DOWN ); }; +//document.onmousemove = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_MOVE ); }; + +/** 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(); + + // slide mode + mouseHandlerDict[SLIDE_MODE][MOUSE_DOWN] + = function( aEvt ) { return slideOnMouseDown( aEvt ); }; + mouseHandlerDict[SLIDE_MODE][MOUSE_WHEEL] + = function( aEvt ) { return slideOnMouseWheel( aEvt ); }; + + // index mode + mouseHandlerDict[INDEX_MODE][MOUSE_DOWN] + = function( aEvt ) { return toggleSlideIndex(); }; + + return mouseHandlerDict; +} + +/** Function to set the page and active slide in index view. +* +* @param nIndex 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( nIndex ) +{ + var aMetaSlideSet = theMetaDoc.aMetaSlideSet; + nIndex = getSafeIndex( nIndex, 0, aMetaSlideSet.length - 1 ); + + //calculate the offset + var nSelectedThumbnailIndex = nIndex % theSlideIndexPage.getTotalThumbnails(); + var offset = nIndex - nSelectedThumbnailIndex; + + if( offset < 0 ) + offset = 0; + + //if different from kept offset, then record and change the page + if( offset != INDEX_OFFSET ) + { + INDEX_OFFSET = offset; + displayIndex( INDEX_OFFSET ); + } + + //set the selected thumbnail and the current slide + theSlideIndexPage.setSelection( nSelectedThumbnailIndex ); +} + + +/***** + * @jessyinkend + * + * The above code is a derivative work of some parts of the JessyInk project. + * @source http://code.google.com/p/jessyink/ + */ + + + + + +/***** + * @licstart + * + * The following is the license notice for the part of JavaScript code of this + * page included between the '@stdlibstart' and the '@stdlibend' notes. + */ + +/***** ****************************************************************** + * + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + * Free Software Foundation, Inc. + * + * The code included between the start note '@stdlibstart' and the end + * note '@stdlibend' is a derivative work of the GNU ISO C++ Library. + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * This library 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. + * + * Under Section 7 of GPL version 3, you are granted additional + * permissions described in the GCC Runtime Library Exception, version + * 3.1, as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License and + * a copy of the GCC Runtime Library Exception along with this program; + * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + * . + * + *************************************************************************/ + +/***** + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided 'as is' without express or implied warranty. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided 'as is' without express or implied warranty. + * + ************************************************************************/ + +/***** + * @licend + * + * The above is the license notice for the part of JavaScript code of this + * page included between the '@stdlibstart' and the '@stdlibend' notes. + */ + + + +/***** + * @stdlibstart + * + * The following code is a porting, performed on August 2011, of a part of + * the C++ code included into the source file stl_queue.h that is part of + * the GNU ISO C++ Library. + */ + + +function PriorityQueue( aCompareFunc ) +{ + this.aSequence = new Array(); + this.aCompareFunc = aCompareFunc; +} + +PriorityQueue.prototype.top = function() +{ + return this.aSequence[0]; +}; + +PriorityQueue.prototype.isEmpty = function() +{ + return ( this.size() === 0 ); +}; + +PriorityQueue.prototype.size = function() +{ + return this.aSequence.length; +}; + +PriorityQueue.prototype.push = function( aValue ) +{ + this.implPushHeap( 0, this.aSequence.length, 0, aValue ); +}; + +PriorityQueue.prototype.clear = function() +{ + return this.aSequence = new Array(); +}; + + +PriorityQueue.prototype.pop = function() +{ + if( this.isEmpty() ) + return; + + var nLast = this.aSequence.length - 1; + var aValue = this.aSequence[ nLast ]; + this.aSequence[ nLast ] = this.aSequence[ 0 ]; + this.implAdjustHeap( 0, 0, nLast, aValue ); + this.aSequence.pop(); +}; + +PriorityQueue.prototype.implAdjustHeap = function( nFirst, nHoleIndex, nLength, aValue ) +{ + var nTopIndex = nHoleIndex; + var nSecondChild = nHoleIndex; + + while( nSecondChild < Math.floor( ( nLength - 1 ) / 2 ) ) + { + nSecondChild = 2 * ( nSecondChild + 1 ); + if( this.aCompareFunc( this.aSequence[ nFirst + nSecondChild ], + this.aSequence[ nFirst + nSecondChild - 1] ) ) + { + --nSecondChild; + } + this.aSequence[ nFirst + nHoleIndex ] = this.aSequence[ nFirst + nSecondChild ]; + nHoleIndex = nSecondChild; + } + + if( ( ( nLength & 1 ) === 0 ) && ( nSecondChild === Math.floor( ( nLength - 2 ) / 2 ) ) ) + { + nSecondChild = 2 * ( nSecondChild + 1 ); + this.aSequence[ nFirst + nHoleIndex ] = this.aSequence[ nFirst + nSecondChild - 1]; + nHoleIndex = nSecondChild - 1; + } + + this.implPushHeap( nFirst, nHoleIndex, nTopIndex, aValue ); +}; + +PriorityQueue.prototype.implPushHeap = function( nFirst, nHoleIndex, nTopIndex, aValue ) +{ + var nParent = Math.floor( ( nHoleIndex - 1 ) / 2 ); + + while( ( nHoleIndex > nTopIndex ) && + this.aCompareFunc( this.aSequence[ nFirst + nParent ], aValue ) ) + { + this.aSequence[ nFirst + nHoleIndex ] = this.aSequence[ nFirst + nParent ]; + nHoleIndex = nParent; + nParent = Math.floor( ( nHoleIndex - 1 ) / 2 ); + } + this.aSequence[ nFirst + nHoleIndex ] = aValue; +}; + + +/***** + * @stdlibend + * + * The above code is a porting, performed on August 2011, of a part of + * the C++ code included into the source file stl_queue.h that is part of + * the GNU ISO C++ Library. + */ + + + + + +/***** + * @licstart + * + * The following is the license notice for the part of JavaScript code of + * this page included between the '@libreofficestart' and the '@libreofficeend' + * notes. + */ + +/***** ****************************************************************** + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +/***** + * @licend + * + * The above is the license notice for the part of JavaScript code of + * this page included between the '@libreofficestart' and the '@libreofficeend' + * notes. + */ + + + +/***** + * @libreofficestart + * + * Several parts of the following code are the result of the porting, + * started on August 2011, of the C++ code included in the source files + * placed under the folder '/slideshow/source' and subfolders. + * @source http://cgit.freedesktop.org/libreoffice/core/tree/slideshow/source + * + */ + + +window.onload = init; + + +// ooo elements +var aOOOElemMetaSlides = 'ooo:meta_slides'; +var aOOOElemMetaSlide = 'ooo:meta_slide'; +var aOOOElemTextField = 'ooo:text_field'; + +// ooo attributes +var aOOOAttrNumberOfSlides = 'number-of-slides'; +var aOOOAttrNumberingType = 'page-numbering-type'; + +var aOOOAttrSlide = 'slide'; +var aOOOAttrMaster = 'master'; +var aOOOAttrBackgroundVisibility = 'background-visibility'; +var aOOOAttrMasterObjectsVisibility = 'master-objects-visibility'; +var aOOOAttrPageNumberVisibility = 'page-number-visibility'; +var aOOOAttrDateTimeVisibility = 'date-time-visibility'; +var aOOOAttrFooterVisibility = 'footer-visibility'; +var aOOOAttrHeaderVisibility = 'header-visibility'; +var aOOOAttrDateTimeField = 'date-time-field'; +var aOOOAttrFooterField = 'footer-field'; +var aOOOAttrHeaderField = 'header-field'; + +var aOOOAttrDateTimeFormat = 'date-time-format'; + +var aOOOAttrTextAdjust = 'text-adjust'; + +// Placeholder class names +var aSlideNumberClassName = 'Slide_Number'; +var aDateTimeClassName = 'Date/Time'; +var aFooterClassName = 'Footer'; +var aHeaderClassName = 'Header'; + +// Creating a namespace dictionary. +var NSS = new Object(); +NSS['svg']='http://www.w3.org/2000/svg'; +NSS['rdf']='http://www.w3.org/1999/02/22-rdf-syntax-ns#'; +NSS['xlink']='http://www.w3.org/1999/xlink'; +NSS['xml']='http://www.w3.org/XML/1998/namespace'; +NSS['ooo'] = 'http://xml.openoffice.org/svg/export'; + +// Presentation modes. +var SLIDE_MODE = 1; +var INDEX_MODE = 2; + +// Mouse handler actions. +var MOUSE_UP = 1; +var MOUSE_DOWN = 2; +var MOUSE_MOVE = 3; +var MOUSE_WHEEL = 4; + +// Keycodes. +var LEFT_KEY = 37; // cursor left keycode +var UP_KEY = 38; // cursor up keycode +var RIGHT_KEY = 39; // cursor right keycode +var DOWN_KEY = 40; // cursor down keycode +var PAGE_UP_KEY = 33; // page up keycode +var PAGE_DOWN_KEY = 34; // page down keycode +var HOME_KEY = 36; // home keycode +var END_KEY = 35; // end keycode +var ENTER_KEY = 13; +var SPACE_KEY = 32; +var ESCAPE_KEY = 27; + +// Visibility Values +var HIDDEN = 0; +var VISIBLE = 1; +var INHERIT = 2; +var aVisibilityAttributeValue = [ 'hidden', 'visible', 'inherit' ]; +var aVisibilityValue = { 'hidden' : HIDDEN, 'visible' : VISIBLE, 'inherit' : INHERIT }; + +// Parameters +var ROOT_NODE = document.getElementsByTagNameNS( NSS['svg'], 'svg' )[0]; +var WIDTH = 0; +var HEIGHT = 0; +var INDEX_COLUMNS_DEFAULT = 3; +var INDEX_OFFSET = 0; + +// Initialization. +var theMetaDoc; +var theSlideIndexPage; +var currentMode = SLIDE_MODE; +var processingEffect = false; +var nCurSlide = undefined; + +// Initialize char and key code dictionaries. +var charCodeDictionary = getDefaultCharCodeDictionary(); +var keyCodeDictionary = getDefaultKeyCodeDictionary(); + +// Initialize mouse handler dictionary. +var mouseHandlerDictionary = getDefaultMouseHandlerDictionary(); + +/*************************** + ** OOP support functions ** + ***************************/ + +function object( aObject ) +{ + var F = function() {}; + F.prototype = aObject; + return new F(); +} + + +function extend( aSubType, aSuperType ) +{ + if (!aSuperType || !aSubType) + { + alert('extend failed, verify dependencies'); + } + var OP = Object.prototype; + var sp = aSuperType.prototype; + var rp = object( sp ); + aSubType.prototype = rp; + + rp.constructor = aSubType; + aSubType.superclass = sp; + + // assign constructor property + if (aSuperType != Object && sp.constructor == OP.constructor) + { + sp.constructor = aSuperType; + } + + return aSubType; +} + + +function instantiate( TemplateClass, BaseType ) +{ + if( !TemplateClass.instanceSet ) + TemplateClass.instanceSet = new Array(); + + var nSize = TemplateClass.instanceSet.length; + + for( var i = 0; i < nSize; ++i ) + { + if( TemplateClass.instanceSet[i].base === BaseType ) + return TemplateClass.instanceSet[i].instance; + } + + TemplateClass.instanceSet[ nSize ] = new Object(); + TemplateClass.instanceSet[ nSize ].base = BaseType; + TemplateClass.instanceSet[ nSize ].instance = TemplateClass( BaseType ); + + return TemplateClass.instanceSet[ nSize ].instance; +}; + +// ------------------------------------------------------------------------------------------ // +/********************************** + ** Helper functions and classes ** + **********************************/ + +function Rectangle( aSVGRectElem ) +{ + var x = parseInt( aSVGRectElem.getAttribute( 'x' ) ); + var y = parseInt( aSVGRectElem.getAttribute( 'y' ) ); + var width = parseInt( aSVGRectElem.getAttribute( 'width' ) ); + var height = parseInt( aSVGRectElem.getAttribute( 'height' ) ); + + this.left = x; + this.right = x + width; + this.top = y; + this.bottom = y + height; +} + +function log( message ) +{ + if( typeof console == 'object' ) + { + console.log( message ); + } + else if( typeof opera == 'object' ) + { + opera.postError( message ); + } + else if( typeof java == 'object' && typeof java.lang == 'object' ) + { + java.lang.System.out.println( message ); + } +} + +function getNSAttribute( sNSPrefix, aElem, sAttrName ) +{ + if( !aElem ) return null; + if( aElem.hasAttributeNS( NSS[sNSPrefix], sAttrName ) ) + { + return aElem.getAttributeNS( NSS[sNSPrefix], sAttrName ); + } + return null; +} + +function getOOOAttribute( aElem, sAttrName ) +{ + return getNSAttribute( 'ooo', aElem, sAttrName ); +} + +function setNSAttribute( sNSPrefix, aElem, sAttrName, aValue ) +{ + if( !aElem ) return false; + if( 'setAttributeNS' in aElem ) + { + aElem.setAttributeNS( NSS[sNSPrefix], sAttrName, aValue ); + return true; + } + else + { + aElem.setAttribute(sNSPrefix + ':' + sAttrName, aValue ); + return true; + } +} + +function setOOOAttribute( aElem, sAttrName, aValue ) +{ + return setNSAttribute( 'ooo', aElem, sAttrName, aValue ); +} + +function checkElemAndSetAttribute( aElem, sAttrName, aValue ) +{ + if( aElem ) + aElem.setAttribute( sAttrName, aValue ); +} + +function getElementsByClassName( aElem, sClassName ) +{ + + var aElementSet = new Array(); + // not all browsers support the 'getElementsByClassName' method + if( 'getElementsByClassName' in aElem ) + { + aElementSet = aElem.getElementsByClassName( sClassName ); + } + else + { + var aElementSetByClassProperty = getElementsByProperty( aElem, 'class' ); + for( var i = 0; i < aElementSetByClassProperty.length; ++i ) + { + var sAttrClassName = aElementSetByClassProperty[i].getAttribute( 'class' ); + if( sAttrClassName == sClassName ) + { + aElementSet.push( aElementSetByClassProperty[i] ); + } + } + } + return aElementSet; +} + +function getElementByClassName( aElem, sClassName /*, sTagName */) +{ + var aElementSet = getElementsByClassName( aElem, sClassName ); + if ( aElementSet.length == 1 ) + return aElementSet[0]; + else + return null; +} + +function getClassAttribute( aElem ) +{ + if( aElem ) + return aElem.getAttribute( 'class' ); + return ''; +} + +function initVisibilityProperty( aElement ) +{ + var nVisibility = VISIBLE; + var sVisibility = aElement.getAttribute( 'visibility' ); + if( sVisibility ) nVisibility = aVisibilityValue[ sVisibility ]; + return nVisibility; +} + +function setElementVisibility( aElement, nCurrentVisibility, nNewVisibility ) +{ + if( nCurrentVisibility != nNewVisibility ) + { + checkElemAndSetAttribute( aElement, 'visibility', aVisibilityAttributeValue[nNewVisibility] ); + return nNewVisibility; + } + return nCurrentVisibility; +} + +function getSafeIndex( nIndex, nMin, nMax ) +{ + if( nIndex < nMin ) + return nMin; + else if( nIndex > nMax ) + return nMax; + else + return nIndex; +} + + + +// ------------------------------------------------------------------------------------------ // +/********************* + ** Debug Utilities ** + *********************/ + +function DebugPrinter() +{ + this.bEnabled = false; +} + + +DebugPrinter.prototype.on = function() +{ + this.bEnabled = true; +}; + +DebugPrinter.prototype.off = function() +{ + this.bEnabled = false; +}; + +DebugPrinter.prototype.isEnabled = function() +{ + return this.bEnabled; +}; + +DebugPrinter.prototype.print = function( sMessage, nTime ) +{ + if( this.isEnabled() ) + { + sInfo = 'DBG: ' + sMessage; + if( nTime ) + sInfo += ' (at: ' + String( nTime / 1000 ) + 's)'; + log( sInfo ); + } + }; + + +// - Debug Printers - +var NAVDBG = new DebugPrinter(); +NAVDBG.off(); + +var ANIMDBG = new DebugPrinter(); +ANIMDBG.off(); + +var aRegisterEventDebugPrinter = new DebugPrinter(); +aRegisterEventDebugPrinter.off(); + +var aTimerEventQueueDebugPrinter = new DebugPrinter(); +aTimerEventQueueDebugPrinter.off(); + +var aEventMultiplexerDebugPrinter = new DebugPrinter(); +aEventMultiplexerDebugPrinter.off(); + +var aNextEffectEventArrayDebugPrinter = new DebugPrinter(); +aNextEffectEventArrayDebugPrinter.off(); + +var aActivityQueueDebugPrinter = new DebugPrinter(); +aActivityQueueDebugPrinter.off(); + +var aAnimatedElementDebugPrinter = new DebugPrinter(); +aAnimatedElementDebugPrinter.off(); + + + +// ------------------------------------------------------------------------------------------ // +/****************** + ** Core Classes ** + ******************/ + +/** Class MetaDocument ** + * This class provides a pool of properties related to the whole presentation and + * it is responsible for initializing the set of MetaSlide objects that handle + * the meta information for each slide. + */ +function MetaDocument( aMetaDocElem ) +{ + this.nNumberOfSlides = parseInt( aMetaDocElem.getAttributeNS( NSS['ooo'], aOOOAttrNumberOfSlides ) ); + assert( typeof this.nNumberOfSlides == 'number' && this.nNumberOfSlides > 0, + 'MetaDocument: number of slides is zero or undefined.' ); + this.startSlideNumber = 0; + this.sPageNumberingType = aMetaDocElem.getAttributeNS( NSS['ooo'], aOOOAttrNumberingType ) || 'arabic'; + this.aMetaSlideSet = new Array(); + this.aMasterPageSet = new Object(); + this.aTextFieldSet = new Array(); + this.slideNumberField = new SlideNumberField( this.startSlideNumber + 1, this.sPageNumberingType ); + + this.aSlideAnimationsMap = new Object(); + this.initSlideAnimationsMap(); + + + for( var i = 0; i < this.nNumberOfSlides; ++i ) + { + var sMetaSlideId = aOOOElemMetaSlide + '_' + i; + this.aMetaSlideSet.push( new MetaSlide( sMetaSlideId, this ) ); + } + assert( this.aMetaSlideSet.length == this.nNumberOfSlides, + 'MetaDocument: aMetaSlideSet.length != nNumberOfSlides.' ); + //this.aMetaSlideSet[ this.startSlideNumber ].show(); +} + +MetaDocument.prototype.initPlaceholderShapes = function() +{ + this.aMetaSlideSet[0].initPlaceholderShapes(); +}; + +MetaDocument.prototype.initSlideAnimationsMap = function() +{ + var aAnimationsSection = document.getElementById( 'presentation-animations' ); + if( aAnimationsSection ) + { + var aAnimationsDefSet = aAnimationsSection.getElementsByTagName( 'defs' ); + + for( var i = 0; i < aAnimationsDefSet.length; ++i ) + { + var sSlideId = aAnimationsDefSet[i].getAttributeNS( NSS['ooo'], aOOOAttrSlide ); + var aChildSet = getElementChildren( aAnimationsDefSet[i] ); + if( sSlideId && ( aChildSet.length === 1 ) ) + { + this.aSlideAnimationsMap[ sSlideId ] = aChildSet[0]; + } + } + } +}; + + + +/** Class MetaSlide ** + * This class is responsible for managing the visibility of all master page shapes + * and background related to a given slide element; it performs the creation and + * the initialization of each Text Field object. + */ +function MetaSlide( sMetaSlideId, aMetaDoc ) +{ + this.theDocument = document; + this.id = sMetaSlideId; + this.theMetaDoc = aMetaDoc; + this.element = this.theDocument.getElementById( this.id ); + assert( this.element, 'MetaSlide: meta_slide element <' + this.id + '> not found.' ); + // - Initialize the Slide Element - + this.slideId = this.element.getAttributeNS( NSS['ooo'], aOOOAttrSlide ); + this.slideElement = this.theDocument.getElementById( this.slideId ); + assert( this.slideElement, 'MetaSlide: slide element <' + this.slideId + '> not found.' ); + // - Initialize the Target Master Page Element - + this.masterPage = this.initMasterPage(); + // - Initialize Background - + //this.aBackground = getElementByClassName( this.aSlide, 'Background' ); + // - Initialize Visibility Properties - + this.nAreMasterObjectsVisible = this.initVisibilityProperty( aOOOAttrMasterObjectsVisibility, VISIBLE ); + this.nIsBackgroundVisible = this.initVisibilityProperty( aOOOAttrBackgroundVisibility, VISIBLE ); + this.nIsPageNumberVisible = this.initVisibilityProperty( aOOOAttrPageNumberVisibility, HIDDEN ); + this.nIsDateTimeVisible = this.initVisibilityProperty( aOOOAttrDateTimeVisibility, VISIBLE ); + this.nIsFooterVisible = this.initVisibilityProperty( aOOOAttrFooterVisibility, VISIBLE ); + this.nIsHeaderVisible = this.initVisibilityProperty( aOOOAttrHeaderVisibility, VISIBLE ); + // - Initialize Master Page Text Fields (Placeholders)- + this.aMPTextFieldSet = new Object(); + this.aMPTextFieldSet[aSlideNumberClassName] = this.initSlideNumberField(); + this.aMPTextFieldSet[aDateTimeClassName] = this.initDateTimeField( aOOOAttrDateTimeField ); + this.aMPTextFieldSet[aFooterClassName] = this.initFixedTextField( aOOOAttrFooterField ); + this.aMPTextFieldSet[aHeaderClassName] = this.initFixedTextField( aOOOAttrHeaderField ); + + // - Initialize Slide Animations Handler + this.aSlideAnimationsHandler = new SlideAnimations( aSlideShow.getContext() ); + this.aSlideAnimationsHandler.importAnimations( this.getSlideAnimationsRoot() ); + this.aSlideAnimationsHandler.parseElements(); + if( false && this.aSlideAnimationsHandler.aRootNode ) + log( this.aSlideAnimationsHandler.aRootNode.info( true ) ); +} + +/*** MetaSlide methods ***/ +MetaSlide.prototype = +{ + /*** public methods ***/ + hide : function() + { + checkElemAndSetAttribute( this.slideElement, 'visibility', 'hidden' ); + + this.masterPage.hide(); + this.masterPage.hideBackground(); + + var aFieldSet = this.aMPTextFieldSet; + var aShapeSet = this.masterPage.aPlaceholderShapeSet; + if( aFieldSet[aSlideNumberClassName] ) aFieldSet[aSlideNumberClassName].hide( aShapeSet[aSlideNumberClassName] ); + if( aFieldSet[aDateTimeClassName] ) aFieldSet[aDateTimeClassName].hide( aShapeSet[aDateTimeClassName] ); + if( aFieldSet[aFooterClassName] ) aFieldSet[aFooterClassName].hide( aShapeSet[aFooterClassName] ); + if( aFieldSet[aHeaderClassName] ) aFieldSet[aHeaderClassName].hide( aShapeSet[aHeaderClassName] ); + }, + + hideExceptMaster : function() + { + checkElemAndSetAttribute( this.slideElement, 'visibility', 'hidden' ); + }, + + show : function() + { + checkElemAndSetAttribute( this.slideElement, 'visibility', 'visible' ); + + this.masterPage.setVisibility( this.nAreMasterObjectsVisible ); + this.masterPage.setVisibilityBackground( this.nIsBackgroundVisible ); + + + this.setTextFieldVisibility( aSlideNumberClassName, this.nIsPageNumberVisible ); + this.setTextFieldVisibility( aDateTimeClassName, this.nIsDateTimeVisible ); + this.setTextFieldVisibility( aFooterClassName, this.nIsFooterVisible ); + this.setTextFieldVisibility( aHeaderClassName, this.nIsHeaderVisible ); + }, + + getMasterPageId : function() + { + return this.masterPage.id; + }, + + getMasterPageElement : function() + { + return this.masterPage.element; + }, + + getBackground : function() + { + return getElementByClassName( this.slideElement, 'Background' ); + }, + + getMasterPageBackground : function() + { + return this.masterPage.background; + }, + + /*** private methods ***/ + initMasterPage : function() + { + var sMasterPageId = this.element.getAttributeNS( NSS['ooo'], aOOOAttrMaster ); + if( !this.theMetaDoc.aMasterPageSet.hasOwnProperty( sMasterPageId ) ) + this.theMetaDoc.aMasterPageSet[ sMasterPageId ] = new MasterPage( sMasterPageId ); + return this.theMetaDoc.aMasterPageSet[ sMasterPageId ]; + }, + + initVisibilityProperty : function( aVisibilityAttribute, nDefaultValue ) + { + var nVisibility = nDefaultValue; + var sVisibility = getOOOAttribute( this.element, aVisibilityAttribute ); + if( sVisibility ) + nVisibility = aVisibilityValue[ sVisibility ]; + return nVisibility; + }, + + initSlideNumberField : function() + { + return this.theMetaDoc.slideNumberField; + }, + + initDateTimeField : function( aOOOAttrDateTimeField ) + { + var sTextFieldId = getOOOAttribute( this.element, aOOOAttrDateTimeField ); + if( !sTextFieldId ) return null; + + var nLength = aOOOElemTextField.length + 1; + var nIndex = parseInt(sTextFieldId.substring( nLength ) ); + if( typeof nIndex != 'number') return null; + + if( !this.theMetaDoc.aTextFieldSet[ nIndex ] ) + { + var aTextField; + var aTextFieldElem = document.getElementById( sTextFieldId ); + var sClassName = getClassAttribute( aTextFieldElem ); + if( sClassName == 'FixedDateTimeField' ) + { + aTextField = new FixedTextField( aTextFieldElem ); + } + else if( sClassName == 'VariableDateTimeField' ) + { + aTextField = new VariableDateTimeField( aTextFieldElem ); + } + else + { + aTextField = null; + } + this.theMetaDoc.aTextFieldSet[ nIndex ] = aTextField; + } + return this.theMetaDoc.aTextFieldSet[ nIndex ]; + }, + + initFixedTextField : function( aOOOAttribute ) + { + var sTextFieldId = getOOOAttribute( this.element, aOOOAttribute ); + if( !sTextFieldId ) return null; + + var nLength = aOOOElemTextField.length + 1; + var nIndex = parseInt( sTextFieldId.substring( nLength ) ); + if( typeof nIndex != 'number') return null; + + if( !this.theMetaDoc.aTextFieldSet[ nIndex ] ) + { + var aTextFieldElem = document.getElementById( sTextFieldId ); + this.theMetaDoc.aTextFieldSet[ nIndex ] + = new FixedTextField( aTextFieldElem ); + } + return this.theMetaDoc.aTextFieldSet[ nIndex ]; + }, + + setTextFieldVisibility : function( sClassName, nVisible ) + { + var aTextField = this.aMPTextFieldSet[ sClassName ]; + var aPlaceholderShape = this.masterPage.aPlaceholderShapeSet[ sClassName ]; + if( !aTextField ) return; + aTextField.setVisibility( this.nAreMasterObjectsVisible & nVisible, aPlaceholderShape ); + }, + + getSlideAnimationsRoot : function() + { + return this.theMetaDoc.aSlideAnimationsMap[ this.slideId ]; + } + +}; + +/** Class MasterPage ** + * This class gives access to a master page element, its background and + * each placeholder shape present in the master page element. + */ +function MasterPage( sMasterPageId ) +{ + this.id = sMasterPageId; + this.element = document.getElementById( this.id ); + assert( this.element, 'MasterPage: master page element <' + this.id + '> not found.' ); + this.background = getElementByClassName( this.element, 'Background' ); + this.backgroundId = this.background.getAttribute( 'id' ); + this.backgroundVisibility = initVisibilityProperty( this.background ); + this.backgroundObjects = getElementByClassName( this.element, 'BackgroundObjects' ); + this.backgroundObjectsId = this.backgroundObjects.getAttribute( 'id' ); + this.backgroundObjectsVisibility = initVisibilityProperty( this.backgroundObjects ); + this.aPlaceholderShapeSet = new Object(); + this.initPlaceholderShapes(); +} + +/*** MasterPage methods ***/ +MasterPage.prototype = +{ + /*** public method ***/ + setVisibility : function( nVisibility ) + { + this.backgroundObjectsVisibility = setElementVisibility( this.backgroundObjects, this.backgroundObjectsVisibility, nVisibility ); + }, + + setVisibilityBackground : function( nVisibility ) + { + this.backgroundVisibility = setElementVisibility( this.background, this.backgroundVisibility, nVisibility ); + }, + + hide : function() + { + this.setVisibility( HIDDEN ); + }, + + show : function() + { + this.setVisibility( VISIBLE ); + }, + + hideBackground : function() + { + this.setVisibilityBackground( HIDDEN ); + }, + + showBackground : function() + { + this.setVisibilityBackground( VISIBLE ); + }, + + /*** private method ***/ + initPlaceholderShapes : function() + { + this.aPlaceholderShapeSet[ aSlideNumberClassName ] = new PlaceholderShape( this, aSlideNumberClassName ); + this.aPlaceholderShapeSet[ aDateTimeClassName ] = new PlaceholderShape( this, aDateTimeClassName ); + this.aPlaceholderShapeSet[ aFooterClassName ] = new PlaceholderShape( this, aFooterClassName ); + this.aPlaceholderShapeSet[ aHeaderClassName ] = new PlaceholderShape( this, aHeaderClassName ); + } +}; + +/** Class PlaceholderShape ** + * This class manages the visibility and the text content of a placeholder shape. + */ +function PlaceholderShape( aMasterPage, sClassName ) +{ + this.masterPage = aMasterPage; + this.className = sClassName; + this.element = null; + this.textElement = null; + + this.init(); +} + +/* public methods */ +PlaceholderShape.prototype.setTextContent = function( sText ) +{ + if( !this.textElement ) + { + log( 'error: PlaceholderShape.setTextContent: text element is not valid in placeholder of type ' + + this.className + ' that belongs to master slide ' + this.masterPage.id ); + return; + } + this.textElement.textContent = sText; +}; + +PlaceholderShape.prototype.setVisibility = function( nVisibility ) +{ + this.element.setAttribute( 'visibility', aVisibilityAttributeValue[nVisibility] ); +}; + +PlaceholderShape.prototype.show = function() +{ + this.element.setAttribute( 'visibility', 'visible' ); +}; + +PlaceholderShape.prototype.hide = function() +{ + this.element.setAttribute( 'visibility', 'hidden' ); +}; + +/* private methods */ +PlaceholderShape.prototype.init = function() +{ + var aShapeElem = getElementByClassName( this.masterPage.backgroundObjects, this.className ); + if( !aShapeElem ) return; + + this.element = aShapeElem; + this.element.setAttribute( 'visibility', 'hidden' ); + + this.textElement = getElementByClassName( this.element , 'PlaceholderText' ); + if( !this.textElement ) return; + + + var aSVGRectElemSet = this.element.getElementsByTagName( 'rect' ); + if( aSVGRectElemSet.length != 1) return; + + var aRect = new Rectangle( aSVGRectElemSet[0] ); + + var sTextAdjust = getOOOAttribute( this.element, aOOOAttrTextAdjust ) || 'left'; + var sTextAnchor, sX; + if( sTextAdjust == 'left' ) + { + sTextAnchor = 'start'; + sX = String( aRect.left ); + } + else if( sTextAdjust == 'right' ) + { + sTextAnchor = 'end'; + sX = String( aRect.right ); + } + else if( sTextAdjust == 'center' ) + { + sTextAnchor = 'middle'; + var nMiddle = ( aRect.left + aRect.right ) / 2; + sX = String( parseInt( String( nMiddle ) ) ); + } + + + this.textElement.setAttribute( 'text-anchor', sTextAnchor ); + this.textElement.setAttribute( 'x', sX ); +}; + + +// ------------------------------------------------------------------------------------------ // +/******************************** + ** Text Field Class Hierarchy ** + ********************************/ + +/** Class TextField ** + * This class is the root abstract class of the hierarchy. + * The 'shapeElement' property is the shape element to which + * this TextField object provides the text content. + */ +function TextField( aTextFieldElem ) +{ + this.bIsUpdated = false; +} + +/*** TextField public methods ***/ +TextField.prototype.getShapeElement = function() +{ + return this.shapeElement; +}; + +TextField.prototype.setVisibility = function( nVisibility, aPlaceholderShape ) +{ + if( !this.bIsUpdated ) + { + if( nVisibility ) + { + this.update( aPlaceholderShape ); + this.bIsUpdated = true; + } + aPlaceholderShape.setVisibility( nVisibility ); + } + else if( !nVisibility ) + { + aPlaceholderShape.hide(); + this.bIsUpdated = false; + } +}; + +TextField.prototype.show = function( aPlaceholderShape ) +{ + this.setVisibility( VISIBLE, aPlaceholderShape ); +}; + +TextField.prototype.hide = function( aPlaceholderShape ) +{ + this.setVisibility( HIDDEN, aPlaceholderShape ); +}; + + +/** Class FixedTextField ** + * This class handles text field with a fixed text. + * The text content is provided by the 'text' property. + */ +function FixedTextField( aTextFieldElem ) +{ + TextField.call( this, aTextFieldElem ); + this.text = aTextFieldElem.textContent; +} +extend( FixedTextField, TextField ); + +FixedTextField.prototype.update = function( aPlaceholderShape ) +{ + aPlaceholderShape.setTextContent( this.text ); +}; + + +/** Class VariableDateTimeField ** + * Provide the text content for the related shape by generating the current + * date/time in the format specified by the 'dateTimeFormat' property. + */ +function VariableDateTimeField( aTextFieldElem ) +{ + VariableDateTimeField.superclass.constructor.call( this, aTextFieldElem ); + this.dateTimeFormat = getOOOAttribute( aTextFieldElem, aOOOAttrDateTimeFormat ); +} +extend( VariableDateTimeField, TextField ); + +/*** public methods ***/ +VariableDateTimeField.prototype.update = function( aPlaceholderShape ) +{ + var sText = this.createDateTimeText( this.dateTimeFormat ); + aPlaceholderShape.setTextContent( sText ); +}; + +VariableDateTimeField.prototype.createDateTimeText = function( sDateTimeFormat ) +{ + // TODO handle date/time format + var aDate = Date(); + var sDate = aDate.toLocaleString(); + return sDate; +}; + +/** Class SlideNumberField ** + * Provides the text content to the related shape by generating + * the current page number in the given page numbering type. + */ +function SlideNumberField( nInitialSlideNumber, sPageNumberingType ) +{ + SlideNumberField.superclass.constructor.call( this, null ); + this.nInitialSlideNumber = nInitialSlideNumber; + this.pageNumberingType = sPageNumberingType; + +} +extend( SlideNumberField, TextField ); + +/*** public methods ***/ +SlideNumberField.prototype.getNumberingType = function() +{ + return this.pageNumberingType; +}; + +SlideNumberField.prototype.update = function( aPlaceholderShape ) +{ + var nSlideNumber; + if( nCurSlide === undefined ) + nSlideNumber = this.nInitialSlideNumber; + else + nSlideNumber = nCurSlide + 1; + var sText = this.createSlideNumberText( nSlideNumber, this.getNumberingType() ); + aPlaceholderShape.setTextContent( sText ); +}; + +SlideNumberField.prototype.createSlideNumberText = function( nSlideNumber, sNumberingType ) +{ + // TODO handle page numbering type + return String( nSlideNumber ); +}; + + + +//------------------------------------------------------------------------------------------- // +/******************************** + ** Slide Index Classes ** + ********************************/ + +/** Class SlideIndePagex ** + * This class is responsible for handling the slide index page + */ +function SlideIndexPage() +{ + this.pageElementId = 'slide_index'; + this.pageBgColor = 'rgb(252,252,252)'; + this.pageElement = this.createPageElement(); + assert( this.pageElement, 'SlideIndexPage: pageElement is not valid' ); + this.indexColumns = INDEX_COLUMNS_DEFAULT; + this.totalThumbnails = this.indexColumns * this.indexColumns; + this.selectedSlideIndex = undefined; + + // set up layout paramers + this.xSpacingFactor = 600/28000; + this.ySpacingFactor = 450/21000; + this.xSpacing = WIDTH * this.xSpacingFactor; + this.ySpacing = HEIGHT * this.ySpacingFactor; + this.halfBorderWidthFactor = ( 300/28000 ) * ( this.indexColumns / 3 ); + this.halfBorderWidth = WIDTH * this.halfBorderWidthFactor; + this.borderWidth = 2 * this.halfBorderWidth; + // the following formula is used to compute the slide shrinking factor: + // scaleFactor = ( WIDTH - ( columns + 1 ) * xSpacing ) / ( columns * ( WIDTH + borderWidth ) ) + // indeed we can divide everything by WIDTH: + this.scaleFactor = ( 1 - ( this.indexColumns + 1 ) * this.xSpacingFactor ) / + ( this.indexColumns * ( 1 + 2 * this.halfBorderWidthFactor ) ); + + // We create a Thumbnail Border and Thumbnail MouseArea rectangle template that will be + // used by every Thumbnail. The Mouse Area rectangle is used in order to trigger the + // mouseover event properly even when the slide background is hidden. + this.thumbnailMouseAreaTemplateId = 'thumbnail_mouse_area'; + this.thumbnailMouseAreaTemplateElement = null; + this.thumbnailBorderTemplateId = 'thumbnail_border'; + this.thumbnailBorderTemplateElement = null; + this.createTemplateElements(); + + // Now we create the grid of thumbnails + this.aThumbnailSet = new Array( this.totalThumbnails ); + for( var i = 0; i < this.totalThumbnails; ++i ) + { + this.aThumbnailSet[i] = new Thumbnail( this, i ); + this.aThumbnailSet[i].updateView(); + } + +// this.curThumbnailIndex = this.selectedSlideIndex % this.totalThumbnails; + this.curThumbnailIndex = 0; +// this.aThumbnailSet[ this.curThumbnailIndex ].select(); +} + + +/* public methods */ +SlideIndexPage.prototype.getTotalThumbnails = function() +{ + return this.totalThumbnails; +}; + +SlideIndexPage.prototype.show = function() +{ + this.pageElement.setAttribute( 'display', 'inherit' ); +}; + +SlideIndexPage.prototype.hide = function() +{ + this.pageElement.setAttribute( 'display', 'none' ); +}; + +/** setSelection + * + * Change the selected thumbnail from the current one to the thumbnail with index nIndex. + * + * @param nIndex - the thumbnail index + */ +SlideIndexPage.prototype.setSelection = function( nIndex ) +{ + nIndex = getSafeIndex( nIndex, 0, this.getTotalThumbnails() - 1 ); + if( this.curThumbnailIndex != nIndex ) + { + this.aThumbnailSet[ this.curThumbnailIndex ].unselect(); + this.aThumbnailSet[ nIndex ].select(); + this.curThumbnailIndex = nIndex; + } + this.selectedSlideIndex = this.aThumbnailSet[ nIndex ].slideIndex; +}; + +SlideIndexPage.prototype.createPageElement = function() +{ + var aPageElement = document.createElementNS( NSS['svg'], 'g' ); + aPageElement.setAttribute( 'id', this.pageElementId ); + aPageElement.setAttribute( 'display', 'none' ); + + // the slide index page background + var sPageBgColor = this.pageBgColor + ';'; + var aRectElement = document.createElementNS( NSS['svg'], 'rect' ); + aRectElement.setAttribute( 'x', 0 ); + aRectElement.setAttribute( 'y', 0 ); + aRectElement.setAttribute( 'width', WIDTH ); + aRectElement.setAttribute( 'height', HEIGHT ); + aRectElement.setAttribute( 'style', 'stroke:none;fill:' + sPageBgColor ); + + aPageElement.appendChild( aRectElement ); + // The index page is appended after all slide elements + // so when it is displayed it covers them all + ROOT_NODE.appendChild( aPageElement ); + return( document.getElementById( this.pageElementId ) ); +}; + +SlideIndexPage.prototype.createTemplateElements = function() +{ + // We define a Rect element as a template of thumbnail border for all slide-thumbnails. + // The stroke color is defined individually by each thumbnail according to + // its selection status. + var aDefsElement = document.createElementNS( NSS['svg'], 'defs' ); + var aRectElement = document.createElementNS( NSS['svg'], 'rect' ); + aRectElement.setAttribute( 'id', this.thumbnailBorderTemplateId ); + aRectElement.setAttribute( 'x', -this.halfBorderWidth ); + aRectElement.setAttribute( 'y', -this.halfBorderWidth ); + aRectElement.setAttribute( 'rx', this.halfBorderWidth ); + aRectElement.setAttribute( 'ry', this.halfBorderWidth ); + aRectElement.setAttribute( 'width', WIDTH + this.halfBorderWidth ); + aRectElement.setAttribute( 'height', HEIGHT + this.halfBorderWidth ); + aRectElement.setAttribute( 'stroke-width', this.borderWidth ); + aRectElement.setAttribute( 'fill', 'none' ); + aDefsElement.appendChild( aRectElement ); + + // We define a Rect element as a template of mouse area for triggering the mouseover event. + // A copy is used by each thumbnail element. + aRectElement = document.createElementNS( NSS['svg'], 'rect' ); + aRectElement.setAttribute( 'id', this.thumbnailMouseAreaTemplateId ); + aRectElement.setAttribute( 'x', 0 ); + aRectElement.setAttribute( 'y', 0 ); + aRectElement.setAttribute( 'width', WIDTH ); + aRectElement.setAttribute( 'height', HEIGHT ); + aRectElement.setAttribute( 'fill', this.pageBgColor ); + aDefsElement.appendChild( aRectElement ); + + this.pageElement.appendChild( aDefsElement ); + + this.thumbnailMouseAreaTemplateElement = document.getElementById( this.thumbnailMouseAreaTemplateId ); + this.thumbnailBorderTemplateElement = document.getElementById( this.thumbnailBorderTemplateId ); +}; + +SlideIndexPage.prototype.decreaseNumberOfColumns = function() +{ + this.setNumberOfColumns( this.indexColumns - 1 ); +}; + +SlideIndexPage.prototype.increaseNumberOfColumns = function() +{ + this.setNumberOfColumns( this.indexColumns + 1 ); +}; + +SlideIndexPage.prototype.resetNumberOfColumns = function() +{ + this.setNumberOfColumns( INDEX_COLUMNS_DEFAULT ); +}; + +/** setNumberOfColumns + * + * Change the size of the thumbnail grid. + * + * @param nNumberOfColumns - the new number of columns/rows of the thumbnail grid + */ +SlideIndexPage.prototype.setNumberOfColumns = function( nNumberOfColumns ) +{ + if( this.indexColumns == nNumberOfColumns ) return; + if( nNumberOfColumns < 2 || nNumberOfColumns > 6 ) return; + + var suspendHandle = ROOT_NODE.suspendRedraw(500); + + var nOldTotalThumbnails = this.totalThumbnails; + this.indexColumns = nNumberOfColumns; + this.totalThumbnails = nNumberOfColumns * nNumberOfColumns;; + + this.aThumbnailSet[this.curThumbnailIndex].unselect(); + + // if we decreased the number of used columns we remove the exceding thumbnail elements + for( var i = this.totalThumbnails; i < nOldTotalThumbnails; ++i ) + { + this.aThumbnailSet[i].removeElement(); + }; + + // if we increased the number of used columns we create the needed thumbnail objects + for( var i = nOldTotalThumbnails; i < this.totalThumbnails; ++i ) + { + this.aThumbnailSet[i] = new Thumbnail( this, i ); + }; + + // we set up layout parameters that depend on the number of columns + this.halfBorderWidthFactor = ( 300/28000 ) * ( this.indexColumns / 3 ); + this.halfBorderWidth = WIDTH * this.halfBorderWidthFactor; + this.borderWidth = 2 * this.halfBorderWidth; + // scaleFactor = ( WIDTH - ( columns + 1 ) * xSpacing ) / ( columns * ( WIDTH + borderWidth ) ) + this.scaleFactor = ( 1 - ( this.indexColumns + 1 ) * this.xSpacingFactor ) / + ( this.indexColumns * ( 1 + 2 * this.halfBorderWidthFactor ) ); + + // update the thumbnail border size + var aRectElement = this.thumbnailBorderTemplateElement; + aRectElement.setAttribute( 'x', -this.halfBorderWidth ); + aRectElement.setAttribute( 'y', -this.halfBorderWidth ); + aRectElement.setAttribute( 'rx', this.halfBorderWidth ); + aRectElement.setAttribute( 'ry', this.halfBorderWidth ); + aRectElement.setAttribute( 'width', WIDTH + this.halfBorderWidth ); + aRectElement.setAttribute( 'height', HEIGHT + this.halfBorderWidth ); + aRectElement.setAttribute( 'stroke-width', this.borderWidth ); + + // now we update the displacement on the index page of each thumbnail (old and new) + for( var i = 0; i < this.totalThumbnails; ++i ) + { + this.aThumbnailSet[i].updateView(); + } + + this.curThumbnailIndex = this.selectedSlideIndex % this.totalThumbnails; + this.aThumbnailSet[this.curThumbnailIndex].select(); + + // needed for forcing the indexSetPageSlide routine to update the INDEX_OFFSET + INDEX_OFFSET = -1; + indexSetPageSlide( this.selectedSlideIndex ); + + ROOT_NODE.unsuspendRedraw( suspendHandle ); + ROOT_NODE.forceRedraw(); +}; + + +/** Class Thumbnail ** + * This class handles a slide thumbnail. + */ +function Thumbnail( aSlideIndexPage, nIndex ) +{ + this.container = aSlideIndexPage; + this.index = nIndex;//= getSafeIndex( nIndex, 0, this.container.getTotalThumbnails() ); + this.pageElement = this.container.pageElement; + this.thumbnailId = 'thumbnail' + this.index; + this.thumbnailElement = this.createThumbnailElement(); + this.slideElement = getElementByClassName( this.thumbnailElement, 'Slide' ); + this.backgroundElement = getElementByClassName( this.thumbnailElement, 'Background' ); + this.backgroundObjectsElement = getElementByClassName( this.thumbnailElement, 'BackgroundObjects' ); + this.borderElement = getElementByClassName( this.thumbnailElement, 'Border' ); + this.aTransformSet = new Array( 3 ); + this.visibility = VISIBLE; + this.isSelected = false; +}; + +/* static const class member */ +Thumbnail.prototype.sNormalBorderColor = 'rgb(216,216,216)'; +Thumbnail.prototype.sSelectionBorderColor = 'rgb(92,92,255)'; + +/* public methods */ +Thumbnail.prototype.removeElement = function() +{ + if( this.thumbnailElement ) + this.container.pageElement.removeChild( this.thumbnailElement ); +}; + +Thumbnail.prototype.show = function() +{ + if( this.visibility == HIDDEN ) + { + this.thumbnailElement.setAttribute( 'display', 'inherit' ); + this.visibility = VISIBLE; + } +}; + +Thumbnail.prototype.hide = function() +{ + if( this.visibility == VISIBLE ) + { + this.thumbnailElement.setAttribute( 'display', 'none' ); + this.visibility = HIDDEN; + } + }; + + Thumbnail.prototype.select = function() + { + if( !this.isSelected ) + { + this.borderElement.setAttribute( 'stroke', this.sSelectionBorderColor ); + this.isSelected = true; + } +}; + +Thumbnail.prototype.unselect = function() +{ + if( this.isSelected ) + { + this.borderElement.setAttribute( 'stroke', this.sNormalBorderColor ); + this.isSelected = false; + } +}; + +/** updateView + * + * This method updates the displacement of the thumbnail on the slide index page, + * the value of the row, column coordinates of the thumbnail in the grid, and + * the onmouseover property of the thumbnail element. + * + */ +Thumbnail.prototype.updateView = function() +{ + this.column = this.index % this.container.indexColumns; + this.row = ( this.index - this.column ) / this.container.indexColumns; + this.halfBorderWidth = this.container.halfBorderWidth; + this.borderWidth = this.container.borderWidth; + this.width = ( WIDTH + this.borderWidth ) * this.container.scaleFactor; + this.height = ( HEIGHT + this.borderWidth ) * this.container.scaleFactor; + this.aTransformSet[2] = 'translate(' + this.halfBorderWidth + ' ' + this.halfBorderWidth + ')'; + this.aTransformSet[1] = 'scale(' + this.container.scaleFactor + ')'; + var sTransformAttrValue = this.computeTransform(); + this.thumbnailElement.setAttribute( 'transform', sTransformAttrValue ); + this.thumbnailElement.setAttribute( 'onmouseover', 'theSlideIndexPage.aThumbnailSet[' + this.index + '].onMouseOver()' ); +}; + +/** update + * + * This method update the content of the thumbnail view + * + * @param nIndex - the index of the slide to be shown in the thumbnail + */ +Thumbnail.prototype.update = function( nIndex ) +{ + if( this.slideIndex == nIndex ) return; + + var aMetaSlide = theMetaDoc.aMetaSlideSet[nIndex]; + setNSAttribute( 'xlink', this.slideElement, 'href', '#' + aMetaSlide.slideId ); + if( aMetaSlide.nIsBackgroundVisible ) + { + setNSAttribute( 'xlink', this.backgroundElement, 'href', '#' + aMetaSlide.masterPage.backgroundId ); + this.backgroundElement.setAttribute( 'visibility', 'inherit' ); + } + else + { + this.backgroundElement.setAttribute( 'visibility', 'hidden' ); + } + if( aMetaSlide.nAreMasterObjectsVisible ) + { + setNSAttribute( 'xlink', this.backgroundObjectsElement, 'href', '#' + aMetaSlide.masterPage.backgroundObjectsId ); + this.backgroundObjectsElement.setAttribute( 'visibility', 'inherit' ); + } + else + { + this.backgroundObjectsElement.setAttribute( 'visibility', 'hidden' ); + } + this.slideIndex = nIndex; +}; + +Thumbnail.prototype.clear = function( nIndex ) +{ + setNSAttribute( 'xlink', this.slideElement, 'href', '' ); + setNSAttribute( 'xlink', this.backgroundElement, 'href', '' ); + setNSAttribute( 'xlink', this.backgroundObjectsElement, 'href', '' ); +}; + +/* private methods */ +Thumbnail.prototype.createThumbnailElement = function() +{ + var aThumbnailElement = document.createElementNS( NSS['svg'], 'g' ); + aThumbnailElement.setAttribute( 'id', this.thumbnailId ); + aThumbnailElement.setAttribute( 'display', 'inherit' ); + + var aMouseAreaElement = document.createElementNS( NSS['svg'], 'use' ); + setNSAttribute( 'xlink', aMouseAreaElement, 'href', '#' + this.container.thumbnailMouseAreaTemplateId ); + aMouseAreaElement.setAttribute( 'class', 'MouseArea' ); + aThumbnailElement.appendChild( aMouseAreaElement ); + + var aBackgroundElement = document.createElementNS( NSS['svg'], 'use' ); + setNSAttribute( 'xlink', aBackgroundElement, 'href', '' ); + aBackgroundElement.setAttribute( 'visibility', 'inherit'); + aBackgroundElement.setAttribute( 'class', 'Background' ); + aThumbnailElement.appendChild( aBackgroundElement ); + + var aBackgroundObjectsElement = document.createElementNS( NSS['svg'], 'use' ); + setNSAttribute( 'xlink', aBackgroundObjectsElement, 'href', '' ); + aBackgroundObjectsElement.setAttribute( 'visibility', 'inherit'); + aBackgroundObjectsElement.setAttribute( 'class', 'BackgroundObjects' ); + aThumbnailElement.appendChild( aBackgroundObjectsElement ); + + var aSlideElement = document.createElementNS( NSS['svg'], 'use' ); + setNSAttribute( 'xlink', aSlideElement, 'href', '' ); + aSlideElement.setAttribute( 'class', 'Slide' ); + aThumbnailElement.appendChild( aSlideElement ); + + var aBorderElement = document.createElementNS( NSS['svg'], 'use' ); + setNSAttribute( 'xlink', aBorderElement, 'href', '#' + this.container.thumbnailBorderTemplateId ); + aBorderElement.setAttribute( 'stroke', this.sNormalBorderColor ); + aBorderElement.setAttribute( 'class', 'Border' ); + aThumbnailElement.appendChild( aBorderElement ); + + this.container.pageElement.appendChild( aThumbnailElement ); + return( document.getElementById( this.thumbnailId ) ); +}; + +Thumbnail.prototype.computeTransform = function() +{ + var nXSpacing = this.container.xSpacing; + var nYSpacing = this.container.ySpacing; + + var nXOffset = nXSpacing + ( this.width + nXSpacing ) * this.column; + var nYOffset = nYSpacing + ( this.height + nYSpacing ) * this.row; + + this.aTransformSet[0] = 'translate(' + nXOffset + ' ' + nYOffset + ')'; + + sTransform = this.aTransformSet.join( ' ' ); + + return sTransform; +}; + +Thumbnail.prototype.onMouseOver = function() +{ + if( ( currentMode == INDEX_MODE ) && ( this.container.curThumbnailIndex != this.index ) ) + { + this.container.setSelection( this.index ); + } +}; + + + + +// ------------------------------------------------------------------------------------------ // +/** Initialization function. + * The whole presentation is set-up in this function. + */ +function init() +{ + var VIEWBOX = ROOT_NODE.getAttribute('viewBox'); + + if( VIEWBOX ) + { + WIDTH = ROOT_NODE.viewBox.animVal.width; + HEIGHT = ROOT_NODE.viewBox.animVal.height; + } + + var aMetaDocElem = document.getElementById( aOOOElemMetaSlides ); + assert( aMetaDocElem, 'init: meta document element not found' ); + aSlideShow = new SlideShow(); + theMetaDoc = new MetaDocument( aMetaDocElem ); + theSlideIndexPage = new SlideIndexPage(); + aSlideShow.displaySlide( theMetaDoc.startSlideNumber ); + + //=====================================// + // ===== timing test ===== // + //=====================================// +// var aTimingAttributeList = [ '0.001s', '-12:16.123', 'next', 'id23.click', 'id3.end + 5s', 'id4.begin - 12:45' ]; +// +// for( var i = 0; i < aTimingAttributeList.length; ++i) +// { +// var aTiming = new Timing( aTimingAttributeList[i] ); +// aTiming.parse(); +// aTiming.info(); +// } + + + //=====================================// + // == animations parsing test == // + //=====================================// + +// var aSlideShowContext = aSlideShow.getContext(); +// var aSlideAnimations = new SlideAnimations( aSlideShowContext ); +// aSlideAnimations.importAnimations( getSlideAnimationsRoot( 'id7' ) ); +// aSlideAnimations.parseElements(); +// log( aSlideAnimations.aRootNode.info( true ) ); + +} + +function presentationEngineStop() +{ + alert( 'We are sorry! An unexpected error occurred.\nThe presentation engine will be stopped' ); + document.onkeydown = null; + document.onkeypress = null; + document.onclick = null; + window.onmousewheel = null; +} + +function assert( condition, message ) +{ + if (!condition) + { + presentationEngineStop(); + if (typeof console == 'object') + console.trace(); + throw new Error( message ); + } +} + +function dispatchEffects(dir) +{ + // TODO to be implemented + + if( dir == 1 ) + { + var bRet = aSlideShow.nextEffect(); + + if( !bRet ) + { + switchSlide( 1 ); + } + } + else + { + switchSlide( dir ); + } +} + +function skipEffects(dir) +{ + // TODO to be implemented + switchSlide(dir); +} + +function switchSlide( nOffset, bSkipTransition ) +{ + var nNextSlide = nCurSlide + nOffset; + aSlideShow.displaySlide( nNextSlide, bSkipTransition ); +} + +/** Function to display the index sheet. +* +* @param offsetNumber offset number +*/ + function displayIndex( offsetNumber ) + { + var aMetaSlideSet = theMetaDoc.aMetaSlideSet; + offsetNumber = getSafeIndex( offsetNumber, 0, aMetaSlideSet.length - 1 ); + + var nTotalThumbnails = theSlideIndexPage.getTotalThumbnails(); + var nEnd = Math.min( offsetNumber + nTotalThumbnails, aMetaSlideSet.length); + + var aThumbnailSet = theSlideIndexPage.aThumbnailSet; + var j = 0; + for( var i = offsetNumber; i < nEnd; ++i, ++j ) + { + aThumbnailSet[j].update( i ); + aThumbnailSet[j].show(); + } + for( ; j < nTotalThumbnails; ++j ) + { + aThumbnailSet[j].hide(); + } + + //do we need to save the current offset? + if (INDEX_OFFSET != offsetNumber) + INDEX_OFFSET = offsetNumber; + } + +/** Function to toggle between index and slide mode. + */ +function toggleSlideIndex() +{ + var suspendHandle = ROOT_NODE.suspendRedraw(500); + var aMetaSlideSet = theMetaDoc.aMetaSlideSet; + + if( currentMode == SLIDE_MODE ) + { + aMetaSlideSet[nCurSlide].hide(); + for( var counter = 0; counter < aMetaSlideSet.length; ++counter ) + { + checkElemAndSetAttribute( aMetaSlideSet[counter].slideElement, 'visibility', 'inherit' ); + aMetaSlideSet[counter].masterPage.setVisibilityBackground( INHERIT ); + aMetaSlideSet[counter].masterPage.setVisibility( INHERIT ); + } + INDEX_OFFSET = -1; + indexSetPageSlide( nCurSlide ); + theSlideIndexPage.show(); + currentMode = INDEX_MODE; + } + else if( currentMode == INDEX_MODE ) + { + theSlideIndexPage.hide(); + var nNewSlide = theSlideIndexPage.selectedSlideIndex; + + for( var counter = 0; counter < aMetaSlideSet.length; ++counter ) + { + var aMetaSlide = aMetaSlideSet[counter]; + aMetaSlide.slideElement.setAttribute( 'visibility', 'hidden' ); + aMetaSlide.masterPage.setVisibilityBackground( HIDDEN ); + aMetaSlide.masterPage.setVisibility( HIDDEN ); + } + + aSlideShow.displaySlide( nNewSlide, true ); + currentMode = SLIDE_MODE; + } + + ROOT_NODE.unsuspendRedraw(suspendHandle); + ROOT_NODE.forceRedraw(); +} + +/** Function that exit from the index mode without changing the shown slide + * + */ +function abandonIndexMode() +{ + theSlideIndexPage.selectedSlideIndex = nCurSlide; + toggleSlideIndex(); +} + + + + + +/********************************************************************************************* + ********************************************************************************************* + ********************************************************************************************* + + ***** ANIMATION ENGINE ***** + + ********************************************************************************************* + ********************************************************************************************* + *********************************************************************************************/ + + + + + +// ------------------------------------------------------------------------------------------ // +// helper functions + + +var CURR_UNIQUE_ID = 0; + +function getUniqueId() +{ + ++CURR_UNIQUE_ID; + return CURR_UNIQUE_ID; +} + +function mem_fn( sMethodName ) +{ + return function( aObject ) + { + var aMethod = aObject[ sMethodName ]; + if( aMethod ) + aMethod.call( aObject ); + else + log( 'method sMethodName not found' ); + }; +} + +function bind( aObject, aMethod ) +{ + return function() + { + return aMethod.call( aObject, arguments[0] ); + }; +} + +function getCurrentSystemTime() +{ + return ( new Date() ).getTime(); + //return ROOT_NODE.getCurrentTime(); +} + +function getSlideAnimationsRoot( sSlideId ) +{ + return theMetaDoc.aSlideAnimationsMap[ sSlideId ]; +} + +/** This function return an array populated with all children nodes of the + * passed element that are elements + * + * @param aElement: any XML element + * + * @returns an array that contains all children elements + */ +function getElementChildren( aElement ) +{ + var aChildrenArray = new Array(); + + var nSize = aElement.childNodes.length; + + for( var i = 0; i < nSize; ++i ) + { + if( aElement.childNodes[i].nodeType == 1 ) + aChildrenArray.push( aElement.childNodes[i] ); + } + + return aChildrenArray; +} + +function removeWhiteSpaces( str ) +{ + if( !str ) + return ''; + + var re = / */; + var aSplittedString = str.split( re ); + return aSplittedString.join(''); +} + +function clamp( nValue, nMinimum, nMaximum ) +{ + if( nValue < nMinimum ) + { + return nMinimum; + } + else if( nValue > nMaximum ) + { + return nMaximum; + } + else + { + return nValue; + } +} + +function makeMatrixString( a, b, c, d, e, f ) +{ + var s = 'matrix('; + s += a + ', '; + s += b + ', '; + s += c + ', '; + s += d + ', '; + s += e + ', '; + s += f + ')'; + + return s; +} + +function matrixToString( aSVGMatrix ) +{ + return makeMatrixString( aSVGMatrix.a, aSVGMatrix.b, aSVGMatrix.c, + aSVGMatrix.d, aSVGMatrix.e, aSVGMatrix.f ); +} + + + +// ------------------------------------------------------------------------------------------ // +// Attribute Parsers + +function numberParser( sValue ) +{ + if( sValue === '.' ) + return undefined; + var reFloatNumber = /^[+-]?[0-9]*[.]?[0-9]*$/; + + if( reFloatNumber.test( sValue ) ) + return parseFloat( sValue ); + else + return undefined; +} + +function booleanParser( sValue ) +{ + sValue = sValue.toLowerCase(); + if( sValue === 'true' ) + return true; + else if( sValue === 'false' ) + return false; + else + return undefined; +} + +function colorParser( sValue ) +{ + + function hsl( nHue, nSaturation, nLuminance ) + { + return new HSLColor( nHue, nSaturation / 100, nLuminance / 100 ); + } + + function rgb( nRed, nGreen, nBlue ) + { + return new RGBColor( nRed / 255, nGreen / 255, nBlue / 255 ); + } + + function prgb( nRed, nGreen, nBlue ) + { + return new RGBColor( nRed / 100, nGreen / 100, nBlue / 100 ); + } + + var sCommaPattern = ' *[,] *'; + var sIntegerPattern = '[+-]?[0-9]+'; + var sHexDigitPattern = '[0-9A-Fa-f]'; + + var sHexColorPattern = '#(' + sHexDigitPattern + '{2})(' + + sHexDigitPattern + '{2})(' + + sHexDigitPattern + '{2})'; + + var sRGBIntegerPattern = 'rgb[(] *' + sIntegerPattern + sCommaPattern + + sIntegerPattern + sCommaPattern + + sIntegerPattern + ' *[)]'; + + var sRGBPercentPattern = 'rgb[(] *' + sIntegerPattern + '%' + sCommaPattern + + sIntegerPattern + '%' + sCommaPattern + + sIntegerPattern + '%' + ' *[)]'; + + var sHSLPercentPattern = 'hsl[(] *' + sIntegerPattern + sCommaPattern + + sIntegerPattern + '%' + sCommaPattern + + sIntegerPattern + '%' + ' *[)]'; + + var reHexColor = RegExp( sHexColorPattern ); + var reRGBInteger = RegExp( sRGBIntegerPattern ); + var reRGBPercent = RegExp( sRGBPercentPattern ); + var reHSLPercent = RegExp( sHSLPercentPattern ); + + if( reHexColor.test( sValue ) ) + { + var aRGBTriple = reHexColor.exec( sValue ); + + var nRed = parseInt( aRGBTriple[1], 16 ) / 255; + var nGreen = parseInt( aRGBTriple[2], 16 ) / 255; + var nBlue = parseInt( aRGBTriple[3], 16 ) / 255; + + return new RGBColor( nRed, nGreen, nBlue ); + } + else if( reHSLPercent.test( sValue ) ) + { + sValue = sValue.replace( '%', '' ).replace( '%', '' ); + return eval( sValue ); + } + else if( reRGBInteger.test( sValue ) ) + { + return eval( sValue ); + } + else if( reRGBPercent.test( sValue ) ) + { + sValue = 'p' + sValue.replace( '%', '' ).replace( '%', '' ).replace( '%', '' ); + return eval( sValue ); + } + else + { + return null; + } +} + + + +/********************************************************************************************** + * RGB and HSL color classes + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // +function RGBColor( nRed, nGreen, nBlue ) +{ + this.eColorSpace = COLOR_SPACE_RGB; + // values in the [0,1] range + this.nRed = nRed; + this.nGreen = nGreen; + this.nBlue = nBlue; +} + + +RGBColor.prototype.clone = function() +{ + return new RGBColor( this.nRed, this.nGreen, this.nBlue ); +}; + +RGBColor.prototype.add = function( aRGBColor ) +{ + this.nRed += aRGBColor.nRed; + this.nGreen += aRGBColor.nGreen; + this.nBlue += aRGBColor.nBlue; + return this; +}; + +RGBColor.prototype.scale = function( aT ) +{ + this.nRed *= aT; + this.nGreen *= aT; + this.nBlue *= aT; + return this; +}; + +RGBColor.clamp = function( aRGBColor ) +{ + var aClampedRGBColor = new RGBColor( 0, 0, 0 ); + + aClampedRGBColor.nRed = clamp( aRGBColor.nRed, 0.0, 1.0 ); + aClampedRGBColor.nGreen = clamp( aRGBColor.nGreen, 0.0, 1.0 ); + aClampedRGBColor.nBlue = clamp( aRGBColor.nBlue, 0.0, 1.0 ); + + return aClampedRGBColor; +}; + +RGBColor.prototype.convertToHSL = function() +{ + var nRed = clamp( this.nRed, 0.0, 1.0 ); + var nGreen = clamp( this.nGreen, 0.0, 1.0 ); + var nBlue = clamp( this.nBlue, 0.0, 1.0 ); + + var nMax = Math.max( nRed, nGreen, nBlue ); + var nMin = Math.min( nRed, nGreen, nBlue ); + var nDelta = nMax - nMin; + + var nLuminance = ( nMax + nMin ) / 2.0; + var nSaturation = 0.0; + var nHue = 0.0; + if( nDelta !== 0 ) + { + nSaturation = ( nLuminance > 0.5 ) ? + ( nDelta / ( 2.0 - nMax - nMin) ) : + ( nDelta / ( nMax + nMin ) ); + + if( nRed == nMax ) + nHue = ( nGreen - nBlue ) / nDelta; + else if( nGreen == nMax ) + nHue = 2.0 + ( nBlue - nRed ) / nDelta; + else if( nBlue == nMax ) + nHue = 4.0 + ( nRed - nGreen ) / nDelta; + + nHue *= 60.0; + + if( nHue < 0.0 ) + nHue += 360.0; + } + + return new HSLColor( nHue, nSaturation, nLuminance ); + +}; + +RGBColor.prototype.toString = function( bClamped ) +{ + var aRGBColor; + if( bClamped ) + { + aRGBColor = RGBColor.clamp( this ); + } + else + { + aRGBColor = this; + } + + var nRed = Math.round( aRGBColor.nRed * 255 ); + var nGreen = Math.round( aRGBColor.nGreen * 255 ); + var nBlue = Math.round( aRGBColor.nBlue * 255 ); + + return ( 'rgb(' + nRed + ',' + nGreen + ',' + nBlue + ')' ); +}; + +RGBColor.interpolate = function( aStartRGB , aEndRGB, nT ) +{ + var aResult = aStartRGB.clone(); + var aTEndRGB = aEndRGB.clone(); + aResult.scale( 1.0 - nT ); + aTEndRGB.scale( nT ); + aResult.add( aTEndRGB ); + + return aResult; +}; + + + +// ------------------------------------------------------------------------------------------ // +function HSLColor( nHue, nSaturation, nLuminance ) +{ + this.eColorSpace = COLOR_SPACE_HSL; + // Hue is in the [0,360[ range, Saturation and Luminance are in the [0,1] range + this.nHue = nHue; + this.nSaturation = nSaturation; + this.nLuminance = nLuminance; + + this.normalizeHue(); +} + + +HSLColor.prototype.clone = function() +{ + return new HSLColor( this.nHue, this.nSaturation, this.nLuminance ); +}; + +HSLColor.prototype.add = function( aHSLColor ) +{ + this.nHue += aHSLColor.nHue; + this.nSaturation += aHSLColor.nSaturation; + this.nLuminance += aHSLColor.nLuminance; + this.normalizeHue(); + return this; +}; + +HSLColor.prototype.scale = function( aT ) +{ + this.nHue *= aT; + this.nSaturation *= aT; + this.nLuminance *= aT; + this.normalizeHue(); + return this; +}; + +HSLColor.clamp = function( aHSLColor ) +{ + var aClampedHSLColor = new HSLColor( 0, 0, 0 ); + + aClampedHSLColor.nHue = aHSLColor.nHue % 360; + if( aClampedHSLColor.nHue < 0 ) + aClampedHSLColor.nHue += 360; + aClampedHSLColor.nSaturation = clamp( aHSLColor.nSaturation, 0.0, 1.0 ); + aClampedHSLColor.nLuminance = clamp( aHSLColor.nLuminance, 0.0, 1.0 ); +}; + +HSLColor.prototype.normalizeHue = function() +{ + this.nHue = this.nHue % 360; + if( this.nHue < 0 ) this.nHue += 360; +}; + +HSLColor.prototype.toString = function() +{ + return 'hsl(' + this.nHue.toFixed( 3 ) + ',' + + this.nSaturation.toFixed( 3 ) + ',' + + this.nLuminance.toFixed( 3 ) + ')'; +}; + +HSLColor.prototype.convertToRGB = function() +{ + + var nHue = this.nHue % 360; + if( nHue < 0 ) nHue += 360; + var nSaturation = clamp( this.nSaturation, 0.0, 1.0 ); + var nLuminance = clamp( this.nLuminance, 0.0, 1.0 ); + + + if( nSaturation === 0 ) + { + return new RGBColor( nLuminance, nLuminance, nLuminance ); + } + + var nVal1 = ( nLuminance <= 0.5 ) ? + ( nLuminance * (1.0 + nSaturation) ) : + ( nLuminance + nSaturation - nLuminance * nSaturation ); + + var nVal2 = 2.0 * nLuminance - nVal1; + + var nRed = HSLColor.hsl2rgbHelper( nVal2, nVal1, nHue + 120 ); + var nGreen = HSLColor.hsl2rgbHelper( nVal2, nVal1, nHue ); + var nBlue = HSLColor.hsl2rgbHelper( nVal2, nVal1, nHue - 120 ); + + return new RGBColor( nRed, nGreen, nBlue ); +}; + +HSLColor.hsl2rgbHelper = function( nValue1, nValue2, nHue ) +{ + nHue = nHue % 360; + if( nHue < 0 ) + nHue += 360; + + if( nHue < 60.0 ) + return nValue1 + ( nValue2 - nValue1 ) * nHue / 60.0; + else if( nHue < 180.0 ) + return nValue2; + else if( nHue < 240.0 ) + return ( nValue1 + ( nValue2 - nValue1 ) * ( 240.0 - nHue ) / 60.0 ); + else + return nValue1; +}; + +HSLColor.interpolate = function( aFrom, aTo, nT, bCCW ) +{ + var nS = 1.0 - nT; + + var nHue = 0.0; + if( aFrom.nHue <= aTo.nHue && !bCCW ) + { + // interpolate hue clockwise. That is, hue starts at + // high values and ends at low ones. Therefore, we + // must 'cross' the 360 degrees and start at low + // values again (imagine the hues to lie on the + // circle, where values above 360 degrees are mapped + // back to [0,360)). + nHue = nS * (aFrom.nHue + 360.0) + nT * aTo.nHue; + } + else if( aFrom.nHue > aTo.nHue && bCCW ) + { + // interpolate hue counter-clockwise. That is, hue + // starts at high values and ends at low + // ones. Therefore, we must 'cross' the 360 degrees + // and start at low values again (imagine the hues to + // lie on the circle, where values above 360 degrees + // are mapped back to [0,360)). + nHue = nS * aFrom.nHue + nT * (aTo.nHue + 360.0); + } + else + { + // interpolate hue counter-clockwise. That is, hue + // starts at low values and ends at high ones (imagine + // the hue value as degrees on a circle, with + // increasing values going counter-clockwise) + nHue = nS * aFrom.nHue + nT * aTo.nHue; + } + + var nSaturation = nS * aFrom.nSaturation + nT * aTo.nSaturation; + var nLuminance = nS * aFrom.nLuminance + nT * aTo.nLuminance; + + return new HSLColor( nHue, nSaturation, nLuminance ); + }; + + + + +/********************************************************************************************** + * AnimationNode Class Hierarchy + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // + +// Node Types +var ANIMATION_NODE_CUSTOM = 0; +var ANIMATION_NODE_PAR = 1; +var ANIMATION_NODE_SEQ = 2; +var ANIMATION_NODE_ITERATE = 3; +var ANIMATION_NODE_ANIMATE = 4; +var ANIMATION_NODE_SET = 5; +var ANIMATION_NODE_ANIMATEMOTION = 6; +var ANIMATION_NODE_ANIMATECOLOR = 7; +var ANIMATION_NODE_ANIMATETRANSFORM = 8; +var ANIMATION_NODE_TRANSITIONFILTER = 9; +var ANIMATION_NODE_AUDIO = 10; +var ANIMATION_NODE_COMMAND = 11; + +aAnimationNodeTypeInMap = { + 'par' : ANIMATION_NODE_PAR, + 'seq' : ANIMATION_NODE_SEQ, + 'iterate' : ANIMATION_NODE_ITERATE, + 'animate' : ANIMATION_NODE_ANIMATE, + 'set' : ANIMATION_NODE_SET, + 'animatemotion' : ANIMATION_NODE_ANIMATEMOTION, + 'animatecolor' : ANIMATION_NODE_ANIMATECOLOR, + 'animatetransform' : ANIMATION_NODE_ANIMATETRANSFORM, + 'transitionfilter' : ANIMATION_NODE_TRANSITIONFILTER +}; + + + +// ------------------------------------------------------------------------------------------ // +function getAnimationElementType( aElement ) +{ + var sName = aElement.localName.toLowerCase(); + //log( 'getAnimationElementType: ' + sName ); + + if( sName && aAnimationNodeTypeInMap[ sName ] ) + return aAnimationNodeTypeInMap[ sName ]; + else + return ANIMATION_NODE_CUSTOM; +} + + + +// ------------------------------------------------------------------------------------------ // + +// Node States +var INVALID_NODE = 0; +var UNRESOLVED_NODE = 1; +var RESOLVED_NODE = 2; +var ACTIVE_NODE = 4; +var FROZEN_NODE = 8; +var ENDED_NODE = 16; + +function getNodeStateName( eNodeState ) +{ + switch( eNodeState ) + { + case INVALID_NODE: + return 'INVALID'; + case UNRESOLVED_NODE: + return 'UNRESOLVED'; + case RESOLVED_NODE: + return 'RESOLVED'; + case ACTIVE_NODE: + return 'ACTIVE'; + case FROZEN_NODE: + return 'FROZEN'; + case ENDED_NODE: + return 'ENDED'; + default: + return 'UNKNOWN'; + } +} + + +// Impress Node Types +IMPRESS_DEFAULT_NODE = 0; +IMPRESS_ON_CLICK_NODE = 1; +IMPRESS_WITH_PREVIOUS_NODE = 2; +IMPRESS_AFTER_PREVIOUS_NODE = 3; +IMPRESS_MAIN_SEQUENCE_NODE = 4; +IMPRESS_TIMING_ROOT_NODE = 5; +IMPRESS_INTERACTIVE_SEQUENCE_NODE = 6; + +aImpressNodeTypeInMap = { + 'on-click' : IMPRESS_ON_CLICK_NODE, + 'with-previous' : IMPRESS_WITH_PREVIOUS_NODE, + 'after-previous' : IMPRESS_AFTER_PREVIOUS_NODE, + 'main-sequence' : IMPRESS_MAIN_SEQUENCE_NODE, + 'timing-root' : IMPRESS_TIMING_ROOT_NODE, + 'interactive-sequence' : IMPRESS_INTERACTIVE_SEQUENCE_NODE +}; + +aImpressNodeTypeOutMap = [ 'default', 'on-click', 'with-previous', 'after-previous', + 'main-sequence', 'timing-root', 'interactive-sequence' ]; + + +// Preset Classes +aPresetClassInMap = {}; + + +// Preset Ids +aPresetIdInMap = {}; + + +// Restart Modes +RESTART_MODE_DEFAULT = 0; +RESTART_MODE_INHERIT = 0; +RESTART_MODE_ALWAYS = 1; +RESTART_MODE_WHEN_NOT_ACTIVE = 2; +RESTART_MODE_NEVER = 3; + +aRestartModeInMap = { + 'inherit' : RESTART_MODE_DEFAULT, + 'always' : RESTART_MODE_ALWAYS, + 'whenNotActive' : RESTART_MODE_WHEN_NOT_ACTIVE, + 'never' : RESTART_MODE_NEVER +}; + +aRestartModeOutMap = [ 'inherit','always', 'whenNotActive', 'never' ]; + + +// Fill Modes +var FILL_MODE_DEFAULT = 0; +var FILL_MODE_INHERIT = 0; +var FILL_MODE_REMOVE = 1; +var FILL_MODE_FREEZE = 2; +var FILL_MODE_HOLD = 3; +var FILL_MODE_TRANSITION = 4; +var FILL_MODE_AUTO = 5; + +aFillModeInMap = { + 'inherit' : FILL_MODE_DEFAULT, + 'remove' : FILL_MODE_REMOVE, + 'freeze' : FILL_MODE_FREEZE, + 'hold' : FILL_MODE_HOLD, + 'transition' : FILL_MODE_TRANSITION, + 'auto' : FILL_MODE_AUTO +}; + +aFillModeOutMap = [ 'inherit', 'remove', 'freeze', 'hold', 'transition', 'auto' ]; + + +// Additive Modes +var ADDITIVE_MODE_BASE = 0; +var ADDITIVE_MODE_SUM = 1; +var ADDITIVE_MODE_REPLACE = 2; +var ADDITIVE_MODE_MULTIPLY = 3; +var ADDITIVE_MODE_NONE = 4; + +aAddittiveModeInMap = { + 'base' : ADDITIVE_MODE_BASE, + 'sum' : ADDITIVE_MODE_SUM, + 'replace' : ADDITIVE_MODE_REPLACE, + 'multiply' : ADDITIVE_MODE_MULTIPLY, + 'none' : ADDITIVE_MODE_NONE +}; + +aAddittiveModeOutMap = [ 'base', 'sum', 'replace', 'multiply', 'none' ]; + + +// Accumulate Modes +var ACCUMULATE_MODE_NONE = 0; +var ACCUMULATE_MODE_SUM = 1; + +aAccumulateModeOutMap = [ 'none', 'sum' ]; + +// Calculation Modes +var CALC_MODE_DISCRETE = 0; +var CALC_MODE_LINEAR = 1; +var CALC_MODE_PACED = 2; +var CALC_MODE_SPLINE = 3; + +aCalcModeInMap = { + 'discrete' : CALC_MODE_DISCRETE, + 'linear' : CALC_MODE_LINEAR, + 'paced' : CALC_MODE_PACED, + 'spline' : CALC_MODE_SPLINE +}; + +aCalcModeOutMap = [ 'discrete', 'linear', 'paced', 'spline' ]; + + +// Color Spaces +var COLOR_SPACE_RGB = 0; +var COLOR_SPACE_HSL = 1; + +aColorSpaceInMap = { 'rgb': COLOR_SPACE_RGB, 'hsl': COLOR_SPACE_HSL }; + +aColorSpaceOutMap = [ 'rgb', 'hsl' ]; + + +// Clock Directions +var CLOCKWISE = 0; +var COUNTERCLOCKWISE = 1; + +aClockDirectionInMap = { 'clockwise': CLOCKWISE, 'counterclockwise': COUNTERCLOCKWISE }; + +aClockDirectionOutMap = [ 'clockwise', 'counterclockwise' ]; + + +// Attribute Value Types +UNKNOWN_PROPERTY = 0; +NUMBER_PROPERTY = 1; +ENUM_PROPERTY = 2; +COLOR_PROPERTY = 3; +STRING_PROPERTY = 4; +BOOL_PROPERTY = 5; + +aValueTypeOutMap = [ 'unknown', 'number', 'enum', 'color', 'string', 'boolean' ]; + + +// Attribute Map +var aAttributeMap = +{ + 'height': { 'type': NUMBER_PROPERTY, + 'get': 'getHeight', + 'set': 'setHeight', + 'getmod': 'makeScaler( 1/nHeight )', + 'setmod': 'makeScaler( nHeight)' }, + + 'opacity': { 'type': NUMBER_PROPERTY, + 'get': 'getOpacity', + 'set': 'setOpacity' }, + + 'width': { 'type': NUMBER_PROPERTY, + 'get': 'getWidth', + 'set': 'setWidth', + 'getmod': 'makeScaler( 1/nWidth )', + 'setmod': 'makeScaler( nWidth)' }, + + 'x': { 'type': NUMBER_PROPERTY, + 'get': 'getX', + 'set': 'setX', + 'getmod': 'makeScaler( 1/nWidth )', + 'setmod': 'makeScaler( nWidth)' }, + + 'y': { 'type': NUMBER_PROPERTY, + 'get': 'getY', + 'set': 'setY', + 'getmod': 'makeScaler( 1/nHeight )', + 'setmod': 'makeScaler( nHeight)' }, + + 'fill': { 'type': ENUM_PROPERTY, + 'get': 'getFillStyle', + 'set': 'setFillStyle' }, + + 'stroke': { 'type': ENUM_PROPERTY, + 'get': 'getStrokeStyle', + 'set': 'setStrokeStyle' }, + + 'visibility': { 'type': ENUM_PROPERTY, + 'get': 'getVisibility', + 'set': 'setVisibility' }, + + 'fill-color': { 'type': COLOR_PROPERTY, + 'get': 'getFillColor', + 'set': 'setFillColor' }, + + 'stroke-color': { 'type': COLOR_PROPERTY, + 'get': 'getStrokeColor', + 'set': 'setStrokeColor' }, + + 'color': { 'type': COLOR_PROPERTY, + 'get': 'getFontColor', + 'set': 'setFontColor' }, + +}; + + +// Transition Types +BARWIPE_TRANSITION = 1; +FADE_TRANSITION = 2; // 37 + +aTransitionTypeInMap = { + 'barWipe' : BARWIPE_TRANSITION, + 'fade' : FADE_TRANSITION +}; + +aTransitionTypeOutMap = [ '', 'barWipe', 'fade' ]; + + +// Transition Subtypes +DEFAULT_TRANS_SUBTYPE = 0; +LEFTTORIGHT_TRANS_SUBTYPE = 1; +TOPTOBOTTOM_TRANS_SUBTYPE = 2; +CROSSFADE_TRANS_SUBTYPE = 3; // 101 + +aTransitionSubtypeInMap = { + 'leftToRight' : LEFTTORIGHT_TRANS_SUBTYPE, + 'topToBottom' : TOPTOBOTTOM_TRANS_SUBTYPE, + 'crossfade' : CROSSFADE_TRANS_SUBTYPE +}; + +aTransitionSubtypeOutMap = [ 'default', 'leftToRight', 'topToBottom', 'crossfade' ]; + + +// Transition Modes +TRANSITION_MODE_IN = 1; +TRANSITION_MODE_OUT = 0; + +aTransitionModeInMap = { 'out': TRANSITION_MODE_OUT, 'in': TRANSITION_MODE_IN }; +aTransitionModeOutMap = [ 'out', 'in' ]; + + +// ------------------------------------------------------------------------------------------ // +// Transition tables + +// transition table for restart=NEVER, fill=FREEZE +var aStateTransitionTable_Never_Freeze = +[ + INVALID_NODE, + RESOLVED_NODE | ENDED_NODE, // active successors for UNRESOLVED + ACTIVE_NODE | ENDED_NODE, // active successors for RESOLVED + INVALID_NODE, + FROZEN_NODE | ENDED_NODE, // active successors for ACTIVE: freeze object + INVALID_NODE, + INVALID_NODE, + INVALID_NODE, + ENDED_NODE, // active successors for FROZEN: end + INVALID_NODE, + INVALID_NODE, + INVALID_NODE, + INVALID_NODE, + INVALID_NODE, + INVALID_NODE, + INVALID_NODE, + ENDED_NODE // active successors for ENDED: + // this state is a sink here (cannot restart) +]; + + +// Table guide +var aTableGuide = +[ + null, + null, + null, + aStateTransitionTable_Never_Freeze, + null, + null +]; + + + +// ------------------------------------------------------------------------------------------ // +function getTransitionTable( eRestartMode, eFillMode ) +{ + var nRestartValue = 0; // never + + var nFillValue = 1; // frozen + + return aTableGuide[ 3*nFillValue + nRestartValue ]; +} + + + +// ------------------------------------------------------------------------------------------ // + +// Event Triggers +var EVENT_TRIGGER_UNKNOWN = 0; +var EVENT_TRIGGER_ON_SLIDE_BEGIN = 1; +var EVENT_TRIGGER_ON_SLIDE_END = 2; +var EVENT_TRIGGER_BEGIN_EVENT = 3; +var EVENT_TRIGGER_END_EVENT = 4; +var EVENT_TRIGGER_ON_CLICK = 5; +var EVENT_TRIGGER_ON_DBL_CLICK = 6; +var EVENT_TRIGGER_ON_MOUSE_ENTER = 7; +var EVENT_TRIGGER_ON_MOUSE_LEAVE = 8; +var EVENT_TRIGGER_ON_NEXT_EFFECT = 9; +var EVENT_TRIGGER_ON_PREV_EFFECT = 10; +var EVENT_TRIGGER_REPEAT = 11; + +aEventTriggerOutMap = [ 'unknown', 'slideBegin', 'slideEnd', 'begin', 'end', 'click', + 'doubleClick', 'mouseEnter', 'mouseLeave', 'next', 'previous', 'repeat' ]; + + +function getEventTriggerType( sEventTrigger ) +{ + if( sEventTrigger == 'begin' ) + return EVENT_TRIGGER_BEGIN_EVENT; + else if( sEventTrigger == 'end' ) + return EVENT_TRIGGER_END_EVENT; + else if( sEventTrigger == 'next' ) + return EVENT_TRIGGER_ON_NEXT_EFFECT; + else if( sEventTrigger == 'prev' ) + return EVENT_TRIGGER_ON_PREV_EFFECT; + else if( sEventTrigger == 'click' ) + return EVENT_TRIGGER_ON_CLICK; + else + return EVENT_TRIGGER_UNKNOWN; +} + + + +// ------------------------------------------------------------------------------------------ // + +// Timing Types +var UNKNOWN_TIMING = 0; +var OFFSET_TIMING = 1; +var WALLCLOCK_TIMING = 2; +var INDEFINITE_TIMING = 3; +var EVENT_TIMING = 4; +var SYNCBASE_TIMING = 5; +var MEDIA_TIMING = 6; + +aTimingTypeOutMap = [ 'unknown', 'offset', 'wallclock', 'indefinite', 'event', 'syncbase', 'media' ]; + + +// Char Codes +var CHARCODE_PLUS = '+'.charCodeAt(0); +var CHARCODE_MINUS = '-'.charCodeAt(0); +var CHARCODE_0 = '0'.charCodeAt(0); +var CHARCODE_9 = '9'.charCodeAt(0); + + + +function Timing( aAnimationNode, sTimingAttribute ) +{ + this.aAnimationNode = aAnimationNode; // the node, the timing attribute belongs to + this.sTimingDescription = removeWhiteSpaces( sTimingAttribute ); + this.eTimingType = UNKNOWN_TIMING; + this.nOffset = 0.0; // in seconds + this.sEventBaseElementId = ''; // the element id for event based timing + this.eEventType = EVENT_TRIGGER_UNKNOWN; // the event type +} + +Timing.prototype.getAnimationNode = function() +{ + return this.aAnimationNode; +}; + +Timing.prototype.getType = function() +{ + return this.eTimingType; +}; + +Timing.prototype.getOffset = function() +{ + return this.nOffset; +}; + +Timing.prototype.getEventBaseElementId = function() +{ + return this.sEventBaseElementId; +}; + +Timing.prototype.getEventType = function() +{ + return this.eEventType; +}; + +Timing.prototype.parse = function() +{ + if( !this.sTimingDescription ) + { + this.eTimingType = OFFSET_TIMING; + return; + } + + if( this.sTimingDescription == 'indefinite' ) + this.eTimingType = INDEFINITE_TIMING; + else + { + var nFisrtCharCode = this.sTimingDescription.charCodeAt(0); + var bPositiveOffset = !( nFisrtCharCode == CHARCODE_MINUS ); + if ( ( nFisrtCharCode == CHARCODE_PLUS ) || + ( nFisrtCharCode == CHARCODE_MINUS ) || + ( ( nFisrtCharCode >= CHARCODE_0 ) && ( nFisrtCharCode <= CHARCODE_9 ) ) ) + { + var sClockValue + = ( ( nFisrtCharCode == CHARCODE_PLUS ) || ( nFisrtCharCode == CHARCODE_MINUS ) ) + ? this.sTimingDescription.substr( 1 ) + : this.sTimingDescription; + + var TimeInSec = Timing.parseClockValue( sClockValue ); + if( TimeInSec != undefined ) + { + this.eTimingType = OFFSET_TIMING; + this.nOffset = bPositiveOffset ? TimeInSec : -TimeInSec; + } + } + else + { + var aTimingSplit = new Array(); + bPositiveOffset = true; + if( this.sTimingDescription.indexOf( '+' ) != -1 ) + { + aTimingSplit = this.sTimingDescription.split( '+' ); + } + else if( this.sTimingDescription.indexOf( '-' ) != -1 ) + { + aTimingSplit = this.sTimingDescription.split( '-' ); + bPositiveOffset = false; + } + else + { + aTimingSplit[0] = this.sTimingDescription; + aTimingSplit[1] = ''; + } + + if( aTimingSplit[0].indexOf( '.' ) != -1 ) + { + var aEventSplit = aTimingSplit[0].split( '.' ); + this.sEventBaseElementId = aEventSplit[0]; + this.eEventType = getEventTriggerType( aEventSplit[1] ); + } + else + { + this.eEventType = getEventTriggerType( aTimingSplit[0] ); + } + + if( this.eEventType == EVENT_TRIGGER_UNKNOWN ) + return; + + if( ( this.eEventType == EVENT_TRIGGER_BEGIN_EVENT ) || + ( this.eEventType == EVENT_TRIGGER_END_EVENT ) ) + { + this.eTimingType = SYNCBASE_TIMING; + } + else + { + this.eTimingType = EVENT_TIMING; + } + + if( aTimingSplit[1] ) + { + var sClockValue = aTimingSplit[1]; + var TimeInSec = Timing.parseClockValue( sClockValue ); + if( TimeInSec != undefined ) + { + this.nOffset = ( bPositiveOffset ) ? TimeInSec : -TimeInSec; + } + else + { + this.eTimingType = UNKNOWN_TIMING; + } + + } + } + } + +}; + +Timing.parseClockValue = function( sClockValue ) +{ + if( !sClockValue ) + return 0.0; + + var nTimeInSec = undefined; + + var reFullClockValue = /^([0-9]+):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?$/; + var rePartialClockValue = /^([0-5][0-9]):([0-5][0-9])(.[0-9]+)?$/; + var reTimecountValue = /^([0-9]+)(.[0-9]+)?(h|min|s|ms)?$/; + + if( reFullClockValue.test( sClockValue ) ) + { + var aClockTimeParts = reFullClockValue.exec( sClockValue ); + + var nHours = parseInt( aClockTimeParts[1] ); + var nMinutes = parseInt( aClockTimeParts[2] ); + var nSeconds = parseInt( aClockTimeParts[3] ); + if( aClockTimeParts[4] ) + nSeconds += parseFloat( aClockTimeParts[4] ); + + nTimeInSec = ( ( nHours * 60 ) + nMinutes ) * 60 + nSeconds; + + } + else if( rePartialClockValue.test( sClockValue ) ) + { + var aClockTimeParts = rePartialClockValue.exec( sClockValue ); + + var nMinutes = parseInt( aClockTimeParts[1] ); + var nSeconds = parseInt( aClockTimeParts[2] ); + if( aClockTimeParts[3] ) + nSeconds += parseFloat( aClockTimeParts[3] ); + + nTimeInSec = nMinutes * 60 + nSeconds; + } + else if( reTimecountValue.test( sClockValue ) ) + { + var aClockTimeParts = reTimecountValue.exec( sClockValue ); + + var nTimecount = parseInt( aClockTimeParts[1] ); + if( aClockTimeParts[2] ) + nTimecount += parseFloat( aClockTimeParts[2] ); + + if( aClockTimeParts[3] ) + { + if( aClockTimeParts[3] == 'h' ) + { + nTimeInSec = nTimecount * 3600; + } + else if( aClockTimeParts[3] == 'min' ) + { + nTimeInSec = nTimecount * 60; + } + else if( aClockTimeParts[3] == 's' ) + { + nTimeInSec = nTimecount; + } + else if( aClockTimeParts[3] == 'ms' ) + { + nTimeInSec = nTimecount / 1000; + } + } + else + { + nTimeInSec = nTimecount; + } + + } + + if( nTimeInSec ) + nTimeInSec = parseFloat( nTimeInSec.toFixed( 3 ) ); + return nTimeInSec; +}; + +Timing.prototype.info = function( bVerbose ) +{ + + var sInfo = ''; + + if( bVerbose ) + { + sInfo = 'description: ' + this.sTimingDescription + ', '; + + sInfo += ', type: ' + aTimingTypeOutMap[ this.getType() ]; + sInfo += ', offset: ' + this.getOffset(); + sInfo += ', event base element id: ' + this.getEventBaseElementId(); + sInfo += ', timing event type: ' + aEventTriggerOutMap[ this.getEventType() ]; + } + else + { + switch( this.getType() ) + { + case INDEFINITE_TIMING: + sInfo += 'indefinite'; + break; + case OFFSET_TIMING: + sInfo += this.getOffset(); + break; + case EVENT_TIMING: + case SYNCBASE_TIMING: + if( this.getEventBaseElementId() ) + sInfo += this.getEventBaseElementId() + '.'; + sInfo += aEventTriggerOutMap[ this.getEventType() ]; + if( this.getOffset() ) + { + if( this.getOffset() > 0 ) + sInfo += '+'; + sInfo += this.getOffset(); + } + } + } + + return sInfo; +}; + + + +// ------------------------------------------------------------------------------------------ // +function Duration( sDurationAttribute ) +{ + this.bIndefinite = false; + this.bMedia = false; + this.nValue = undefined; + this.bDefined = false; + + if( !sDurationAttribute ) + return; + + if( sDurationAttribute == 'indefinite' ) + this.bIndefinite = true; + else if( sDurationAttribute == 'media' ) + this.bMedia = true; + else + { + this.nValue = Timing.parseClockValue( sDurationAttribute ); + if( this.nValue <= 0.0 ) + this.nValue = 0.001; // duration must be always greater than 0 + } + this.bDefined = true; +} + + +Duration.prototype.isSet = function() +{ + return this.bDefined; +}; + +Duration.prototype.isIndefinite = function() +{ + return this.bIndefinite; +}; + +Duration.prototype.isMedia = function() +{ + return this.bMedia; +}; + +Duration.prototype.isValue = function() +{ + return this.nValue != undefined; +}; + +Duration.prototype.getValue= function() +{ + return this.nValue; +}; + +Duration.prototype.info= function() +{ + var sInfo; + + if( this.isIndefinite() ) + sInfo = 'indefinite'; + else if( this.isMedia() ) + sInfo = 'media'; + else if( this.getValue() ) + sInfo = this.getValue(); + + return sInfo; +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimationNode() +{ +} + +AnimationNode.prototype.init = function() {}; +AnimationNode.prototype.resolve = function() {}; +AnimationNode.prototype.activate = function() {}; +AnimationNode.prototype.deactivate = function() {}; +AnimationNode.prototype.end = function() {}; +AnimationNode.prototype.getState = function() {}; +AnimationNode.prototype.registerDeactivatingListener = function() {}; +AnimationNode.prototype.notifyDeactivating = function() {}; + + + +// ------------------------------------------------------------------------------------------ // +function NodeContext( aSlideShowContext ) +{ + this.aContext = aSlideShowContext; + this.aAnimationNodeMap = null; + this.aAnimatedElementMap = null; + this.aSourceEventElementMap = null; + this.nStartDelay = 0.0; + this.bFirstRun = undefined; + this.aSlideHeight = HEIGHT; + this.aSlideWidth = WIDTH; +} + + +NodeContext.prototype.makeSourceEventElement = function( sId, aEventBaseElem ) +{ + if( !aEventBaseElem ) + { + log( 'NodeContext.makeSourceEventElement: event base element is not valid' ); + return null; + } + + if( !this.aContext.aEventMultiplexer ) + { + log( 'NodeContext.makeSourceEventElement: event multiplexer not initialized' ); + return null; + } + + if( !this.aAnimationNodeMap[ sId ] ) + { + this.aAnimationNodeMap[ sId ] = new SourceEventElement( aEventBaseElem, this.aContext.aEventMultiplexer ); + } + return this.aAnimationNodeMap[ sId ]; +}; + + + +// ------------------------------------------------------------------------------------------ // +function StateTransition( aBaseNode ) +{ + this.aNode = aBaseNode; + this.eToState = INVALID_NODE; +} + +StateTransition.prototype.enter = function( eNodeState, bForce ) +{ + if( !bForce ) bForce = false; + + if( this.eToState != INVALID_NODE ) + { + log( 'StateTransition.enter: commit() before enter()ing again!' ); + return false; + } + if( !bForce && !this.aNode.isTransition( this.aNode.getState(), eNodeState ) ) + return false; + + // recursion detection: + if( ( this.aNode.nCurrentStateTransition & eNodeState ) != 0 ) + return false; // already in wanted transition + + // mark transition: + this.aNode.nCurrentStateTransition |= eNodeState; + this.eToState = eNodeState; + return true; +}; + +StateTransition.prototype.commit = function() +{ + if( this.eToState != INVALID_NODE ) + { + this.aNode.eCurrentState = this.eToState; + this.clear(); + } +}; + +StateTransition.prototype.clear = function() +{ + if( this.eToState != INVALID_NODE ) + { + this.aNode.nCurrentStateTransition &= ~this.eToState; + this.eToState = INVALID_NODE; + } +}; + + + +// ------------------------------------------------------------------------------------------ // +function BaseNode( aAnimElem, aParentNode, aNodeContext ) +{ + this.nId = getUniqueId(); + this.sClassName = 'BaseNode'; + + if( !aAnimElem ) + log( 'BaseNode(id:' + this.nId + ') constructor: aAnimElem is not valid' ); + + if( !aNodeContext ) + log( 'BaseNode(id:' + this.nId + ') constructor: aNodeContext is not valid' ); + + if( !aNodeContext.aContext ) + log( 'BaseNode(id:' + this.nId + ') constructor: aNodeContext.aContext is not valid' ); + + + this.bIsContainer; + this.aElement = aAnimElem; + this.aParentNode = aParentNode; + this.aNodeContext = aNodeContext; + this.aContext = aNodeContext.aContext; + this.nStartDelay = aNodeContext.nStartDelay; + this.eCurrentState = UNRESOLVED_NODE; + this.nCurrentStateTransition = 0; + this.aDeactivatingListenerArray = new Array(); + this.aActivationEvent = null; + this.aDeactivationEvent = null; + + this.aBegin = null; + this.aDuration = null; + this.aEnd = null; + this.bMainSequenceRootNode = false; + this.eFillMode = FILL_MODE_FREEZE; + this.eRestartMode = RESTART_MODE_NEVER; + this.nReapeatCount = undefined; + this.nAccelerate = 0.0; + this.nDecelerate = 0.0; + this.bAutoReverse = false; + +} +extend( BaseNode, AnimationNode ); + + +BaseNode.prototype.getId = function() +{ + return this.nId; +}; + +BaseNode.prototype.parseElement = function() +{ + var aAnimElem = this.aElement; + + // id attribute + var sIdAttr = aAnimElem.getAttributeNS( NSS['xml'], 'id' ); + // we append the animation node to the Animation Node Map so that it can be retrieved + // by the registerEvent routine for resolving begin values of type 'id.begin', 'id.end' + if( sIdAttr ) + this.aNodeContext.aAnimationNodeMap[ sIdAttr ] = this; + + // begin attribute + this.aBegin = null; + var sBeginAttr = aAnimElem.getAttribute( 'begin' ); + this.aBegin = new Timing( this, sBeginAttr ); + this.aBegin.parse(); + + // end attribute + this.aEnd = null; + var sEndAttr = aAnimElem.getAttribute( 'end' ); + if( sEndAttr ) + { + this.aEnd = new Timing( this, sEndAttr ); + this.aEnd.parse(); + } + + // dur attribute + this.aDuration = null; + var sDurAttr = aAnimElem.getAttribute( 'dur' ); + this.aDuration = new Duration( sDurAttr ); + if( !this.aDuration.isSet() ) + { + if( this.isContainer() ) + this.aDuration = null; + else + this.aDuration = new Duration( 'indefinite' ); + } + + // fill attribute + var sFillAttr = aAnimElem.getAttribute( 'fill' ); + if( sFillAttr && aFillModeInMap[ sFillAttr ]) + this.eFillMode = aFillModeInMap[ sFillAttr ]; + else + this.eFillMode = FILL_MODE_DEFAULT; + + // restart attribute + var sRestartAttr = aAnimElem.getAttribute( 'restart' ); + if( sRestartAttr && aRestartModeInMap[ sRestartAttr ] ) + this.eRestartMode = aRestartModeInMap[ sRestartAttr ]; + else + this.eRestartMode = RESTART_MODE_DEFAULT; + + // repeatCount attribute + var sRepeatCount = aAnimElem.getAttribute( 'repeatCount' ); + if( !sRepeatCount ) + this.nReapeatCount = 1; + else + this.nReapeatCount = parseFloat( sRepeatCount ); + if( ( this.nReapeatCount == NaN ) && ( sRepeatCount != 'indefinite' ) ) + this.nReapeatCount = 1; + + // accelerate attribute + this.nAccelerate = 0.0; + var sAccelerateAttr = aAnimElem.getAttribute( 'accelerate' ); + if( sAccelerateAttr ) + this.nAccelerate = parseFloat( sAccelerateAttr ); + if( this.nAccelerate == NaN ) + this.nAccelerate = 0.0; + + // decelerate attribute + this.nDecelerate = 0.0; + var sDecelerateAttr = aAnimElem.getAttribute( 'decelerate' ); + if( sDecelerateAttr ) + this.nDecelerate = parseFloat( sDecelerateAttr ); + if( this.nDecelerate == NaN ) + this.nDecelerate = 0.0; + + // autoReverse attribute + this.bAutoreverse = false; + var sAutoReverseAttr = aAnimElem.getAttribute( 'autoReverse' ); + if( sAutoReverseAttr == 'true' ) + this.bAutoreverse = true; + + + // resolve fill value + if( this.eFillMode == FILL_MODE_DEFAULT ) + if( this.getParentNode() ) + this.eFillMode = this.getParentNode().getFillMode(); + else + this.eFillMode = FILL_MODE_AUTO; + + if( this.eFillMode == FILL_MODE_AUTO ) // see SMIL recommendation document + { + this.eFillMode = ( this.aEnd || + ( this.nReapeatCount != 1) || + this.aDuration ) + ? FILL_MODE_REMOVE + : FILL_MODE_FREEZE; + } + + // resolve restart value + if( this.eRestartMode == RESTART_MODE_DEFAULT ) + if( this.getParentNode() ) + this.eRestartMode = this.getParentNode().getRestartMode(); + else + // SMIL recommendation document says to set it to 'always' + // but we follow the slideshow engine C++ implementation + this.eRestartMode = RESTART_MODE_NEVER; + + // resolve accelerate and decelerate attributes + // from the SMIL recommendation document: if the individual values of the accelerate + // and decelerate attributes are between 0 and 1 and the sum is greater than 1, + // then both the accelerate and decelerate attributes will be ignored and the timed + // element will behave as if neither attribute was specified. + if( ( this.nAccelerate + this.nDecelerate ) > 1.0 ) + { + this.nAccelerate = 0.0; + this.nDecelerate = 0.0; + } + + // TODO: at present we are able to manage only this case + this.eFillMode = FILL_MODE_FREEZE; + this.eRestartMode = RESTART_MODE_NEVER; + this.aStateTransTable = getTransitionTable( this.getRestartMode(), this.getFillMode() ); + + return true; +}; + +BaseNode.prototype.getParentNode = function() +{ + return this.aParentNode; +}; + +BaseNode.prototype.init = function() +{ + if( ! this.checkValidNode() ) + return false; + if( this.aActivationEvent ) + this.aActivationEvent.dispose(); + if( this.aDeactivationEvent ) + this.aDeactivationEvent.dispose(); + + this.eCurrentState = UNRESOLVED_NODE; + + return this.init_st(); +}; + +BaseNode.prototype.resolve = function() +{ + if( ! this.checkValidNode() ) + return false; + + this.DBG( this.callInfo( 'resolve' ) ); + + if( this.eCurrentState == RESOLVED_NODE ) + log( 'BaseNode.resolve: already in RESOLVED state' ); + + var aStateTrans = new StateTransition( this ); + + if( aStateTrans.enter( RESOLVED_NODE ) && + this.isTransition( RESOLVED_NODE, ACTIVE_NODE ) && + this.resolve_st() ) + { + aStateTrans.commit(); + + if( this.aActivationEvent ) + { + this.aActivationEvent.charge(); + } + else + { + this.aActivationEvent = makeDelay( bind( this, this.activate ), this.getBegin().getOffset() + this.nStartDelay ); + } + registerEvent( this.getBegin(), this.aActivationEvent, this.aNodeContext ); + + return true; + } + + return false; +}; + +BaseNode.prototype.activate = function() +{ + if( ! this.checkValidNode() ) + return false; + + if( this.eCurrentState == ACTIVE_NODE ) + log( 'BaseNode.activate: already in ACTIVE state' ); + + this.DBG( this.callInfo( 'activate' ), getCurrentSystemTime() ); + + var aStateTrans = new StateTransition( this ); + + if( aStateTrans.enter( ACTIVE_NODE ) ) + { + this.activate_st(); + aStateTrans.commit(); + if( !this.aContext.aEventMultiplexer ) + log( 'BaseNode.activate: this.aContext.aEventMultiplexer is not valid' ); + this.aContext.aEventMultiplexer.notifyEvent( EVENT_TRIGGER_BEGIN_EVENT, this.getId() ); + return true; + } + return false; +}; + +BaseNode.prototype.deactivate = function() +{ + if( this.inStateOrTransition( ENDED_NODE | FROZEN_NODE ) || !this.checkValidNode() ) + return; + + if( this.isTransition( this.eCurrentState, FROZEN_NODE ) ) + { + this.DBG( this.callInfo( 'deactivate' ), getCurrentSystemTime() ); + + var aStateTrans = new StateTransition( this ); + if( aStateTrans.enter( FROZEN_NODE, true /* FORCE */ ) ) + { + this.deactivate_st(); + aStateTrans.commit(); + + this.notifyEndListeners(); + + if( this.aActivationEvent ) + this.aActivationEvent.dispose(); + if( this.aDeactivationEvent ) + this.aDeactivationEvent.dispose(); + } + } + else + { + this.end(); + } + // state has changed either to FROZEN or ENDED +}; + +BaseNode.prototype.end = function() +{ + var bIsFrozenOrInTransitionToFrozen = this.inStateOrTransition( FROZEN_NODE ); + if( this.inStateOrTransition( ENDED_NODE ) || !this.checkValidNode() ) + return; + + if( !(this.isTransition( this.eCurrentState, ENDED_NODE ) ) ) + log( 'BaseNode.end: end state not reachable in transition table' ); + + this.DBG( this.callInfo( 'end' ), getCurrentSystemTime() ); + + var aStateTrans = new StateTransition( this ); + if( aStateTrans.enter( ENDED_NODE, true /* FORCE */ ) ) + { + this.deactivate_st( ENDED_NODE ); + aStateTrans.commit(); + + // if is FROZEN or is to be FROZEN, then + // will/already notified deactivating listeners + if( !bIsFrozenOrInTransitionToFrozen ) + this.notifyEndListeners(); + + if( this.aActivationEvent ) + this.aActivationEvent.dispose(); + if( this.aDeactivationEvent ) + this.aDeactivationEvent.dispose(); + } +}; + +BaseNode.prototype.dispose = function() +{ + if( this.aActivationEvent ) + this.aActivationEvent.dispose(); + if( this.aDeactivationEvent ) + this.aDeactivationEvent.dispose(); + this.aDeactivatingListenerArray = new Array(); +}; + +BaseNode.prototype.getState = function() +{ + return this.eCurrentState; +}; + +BaseNode.prototype.registerDeactivatingListener = function( aNotifiee ) +{ + if (! this.checkValidNode()) + return false; + + if( !aNotifiee ) + { + log( 'BaseNode.registerDeactivatingListener(): invalid notifee' ); + return false; + } + this.aDeactivatingListenerArray.push( aNotifiee ); + + return true; +}; + +BaseNode.prototype.notifyDeactivating = function( aNotifier ) +{ + assert( ( aNotifier.getState() == FROZEN_NODE ) || ( aNotifier.getState() == ENDED_NODE ), + 'BaseNode.notifyDeactivating: Notifier node is neither in FROZEN nor in ENDED state' ); +}; + +BaseNode.prototype.isMainSequenceRootNode = function() +{ + return this.bMainSequenceRootNode; +}; + +BaseNode.prototype.makeDeactivationEvent = function( nDelay ) +{ + if( this.aDeactivationEvent ) + { + this.aDeactivationEvent.charge(); + } + else + { + if( typeof( nDelay ) == typeof(0) ) + this.aDeactivationEvent = makeDelay( bind( this, this.deactivate ), nDelay ); + else + this.aDeactivationEvent = null; + } + return this.aDeactivationEvent; +}; + +BaseNode.prototype.scheduleDeactivationEvent = function( aEvent ) +{ + this.DBG( this.callInfo( 'scheduleDeactivationEvent' ) ); + + if( !aEvent ) + { + if( this.getDuration() && this.getDuration().isValue() ) + aEvent = this.makeDeactivationEvent( this.getDuration().getValue() ); + } + if( aEvent ) + { + this.aContext.aTimerEventQueue.addEvent( aEvent ); + } +}; + +BaseNode.prototype.checkValidNode = function() +{ + return ( this.eCurrentState != INVALID_NODE ); +}; + +BaseNode.prototype.init_st = function() +{ + return true; +}; + +BaseNode.prototype.resolve_st = function() +{ + return true; +}; + +BaseNode.prototype.activate_st = function() +{ + this.scheduleDeactivationEvent(); +}; + +BaseNode.prototype.deactivate_st = function( aNodeState ) +{ + // empty body +}; + +BaseNode.prototype.notifyEndListeners = function() +{ + var nDeactivatingListenerCount = this.aDeactivatingListenerArray.length; + + for( var i = 0; i < nDeactivatingListenerCount; ++i ) + { + this.aDeactivatingListenerArray[i].notifyDeactivating( this ); + } + + this.aContext.aEventMultiplexer.notifyEvent( EVENT_TRIGGER_END_EVENT, this.getId() ); +}; + +BaseNode.prototype.getContext = function() +{ + return this.aContext; +}; + +BaseNode.prototype.isTransition = function( eFromState, eToState ) +{ + return ( ( this.aStateTransTable[ eFromState ] & eToState ) != 0 ); +}; + +BaseNode.prototype.inStateOrTransition = function( nMask ) +{ + return ( ( ( this.eCurrentState & nMask ) != 0 ) || ( ( this.nCurrentStateTransition & nMask ) != 0 ) ); +}; + +BaseNode.prototype.isContainer = function() +{ + return this.bIsContainer; +}; + +BaseNode.prototype.getBegin = function() +{ + return this.aBegin; +}; + +BaseNode.prototype.getDuration = function() +{ + return this.aDuration; +}; + +BaseNode.prototype.getEnd = function() +{ + return this.aEnd; +}; + +BaseNode.prototype.getFillMode = function() +{ + return this.eFillMode; +}; + +BaseNode.prototype.getRestartMode = function() +{ + return this.eRestartMode; +}; + +BaseNode.prototype.getRepeatCount = function() +{ + return this.nReapeatCount; +}; + +BaseNode.prototype.getAccelerateValue = function() +{ + return this.nAccelerate; +}; + +BaseNode.prototype.getDecelerateValue = function() +{ + return this.nDecelerate; +}; + +BaseNode.prototype.isAutoReverseEnabled = function() +{ + return this.bAutoreverse; +}; + +BaseNode.prototype.info = function( bVerbose ) +{ + var sInfo = 'class name: ' + this.sClassName; + sInfo += '; element name: ' + this.aElement.localName; + sInfo += '; id: ' + this.getId(); + sInfo += '; state: ' + getNodeStateName( this.getState() ); + + if( bVerbose ) + { + // is container + sInfo += '; is container: ' + this.isContainer(); + + // begin + if( this.getBegin() ) + sInfo += '; begin: ' + this.getBegin().info(); + + // duration + if( this.getDuration() ) + sInfo += '; dur: ' + this.getDuration().info(); + + // end + if( this.getEnd() ) + sInfo += '; end: ' + this.getEnd().info(); + + // fill mode + if( this.getFillMode() ) + sInfo += '; fill: ' + aFillModeOutMap[ this.getFillMode() ]; + + // restart mode + if( this.getRestartMode() ) + sInfo += '; restart: ' + aRestartModeOutMap[ this.getRestartMode() ]; + + // repeatCount + if( this.getRepeatCount() && ( this.getRepeatCount() != 1.0 ) ) + sInfo += '; repeatCount: ' + this.getRepeatCount(); + + // accelerate + if( this.getAccelerateValue() ) + sInfo += '; accelerate: ' + this.getAccelerateValue(); + + // decelerate + if( this.getDecelerateValue() ) + sInfo += '; decelerate: ' + this.getDecelerateValue(); + + // auto reverse + if( this.isAutoReverseEnabled() ) + sInfo += '; autoReverse: true'; + + } + + return sInfo; +}; + +BaseNode.prototype.callInfo = function( sMethodName ) +{ + var sInfo = this.sClassName + + '( ' + this.getId() + + ', ' + getNodeStateName( this.getState() ) + + ' ).' + sMethodName; + return sInfo; +}; + +BaseNode.prototype.DBG = function( sMessage, nTime ) +{ + ANIMDBG.print( sMessage, nTime ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimationBaseNode( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationBaseNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'AnimationBaseNode'; + this.bIsContainer = false; + this.aTargetElement = null; + this.aAnimatedElement = null; + this.aActivity = null; + + this.nMinFrameCount; + this.eAdditiveMode; + +} +extend( AnimationBaseNode, BaseNode ); + + +AnimationBaseNode.prototype.parseElement = function() +{ + var bRet = AnimationBaseNode.superclass.parseElement.call( this ); + + var aAnimElem = this.aElement; + + // targetElement attribute + this.aTargetElement = null; + var sTargetElementAttr = aAnimElem.getAttribute( 'targetElement' ); + if( sTargetElementAttr ) + this.aTargetElement = document.getElementById( sTargetElementAttr ); + + if( !this.aTargetElement ) + { + this.eCurrentState = INVALID_NODE; + log( 'AnimationBaseNode.parseElement: target element not found: ' + sTargetElementAttr ); + } + + // additive attribute + var sAdditiveAttr = aAnimElem.getAttribute( 'additive' ); + if( sAdditiveAttr && aAddittiveModeInMap[sAdditiveAttr] ) + this.eAdditiveMode = aAddittiveModeInMap[sAdditiveAttr]; + else + this.eAdditiveMode = ADDITIVE_MODE_REPLACE; + + // set up min frame count value; + this.nMinFrameCount = ( this.getDuration().isValue() ) + ? ( this.getDuration().getValue() * MINIMUM_FRAMES_PER_SECONDS ) + : MINIMUM_FRAMES_PER_SECONDS; + if( this.nMinFrameCount < 1.0 ) + this.nMinFrameCount = 1; + else if( this.nMinFrameCount > MINIMUM_FRAMES_PER_SECONDS ) + this.nMinFrameCount = MINIMUM_FRAMES_PER_SECONDS; + + + if( this.aTargetElement ) + { + // set up target element initial visibility + if( true && aAnimElem.getAttribute( 'attributeName' ) === 'visibility' ) + { + if( aAnimElem.getAttribute( 'to' ) === 'visible' ) + this.aTargetElement.setAttribute( 'visibility', 'hidden' ); + } + + // create animated element + if( !this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] ) + { + this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] + = new AnimatedElement( this.aTargetElement ); + } + this.aAnimatedElement = this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ]; + + // set additive mode + this.aAnimatedElement.setAdditiveMode( this.eAdditiveMode ); + } + + + return bRet; +}; + +AnimationBaseNode.prototype.init_st = function() +{ + if( this.aActivity ) + this.aActivity.activate( makeEvent( bind( this, this.deactivate ) ) ); + else + this.aActivity = this.createActivity(); + return true; +}; + +AnimationBaseNode.prototype.resolve_st = function() +{ + return true; +}; + +AnimationBaseNode.prototype.activate_st = function() +{ + if( this.aActivity ) + { + this.aActivity.setTargets( this.getAnimatedElement() ); + this.getContext().aActivityQueue.addActivity( this.aActivity ); + } + else + { + AnimationBaseNode.superclass.scheduleDeactivationEvent.call( this ); + } + + // TODO: only for testing! to be removed! + //AnimationBaseNode.superclass.scheduleDeactivationEvent.call( this ); +}; + +AnimationBaseNode.prototype.deactivate_st = function( eDestState ) +{ + if( eDestState == FROZEN_NODE ) + { + if( this.aActivity ) + this.aActivity.end(); + } + if( eDestState == ENDED_NODE ) + { + if( this.aActivity ) + this.aActivity.dispose(); + } +}; + +AnimationBaseNode.prototype.createActivity = function() +{ + log( 'AnimationBaseNode.createActivity: abstract method called' ); +}; + +AnimationBaseNode.prototype.fillActivityParams = function() +{ + + // compute duration + var nDuration = 0.001; + if( this.getDuration().isValue() ) + { + nDuration = this.getDuration().getValue(); + } + else + { + log( 'AnimationBaseNode.fillActivityParams: duration is not a number' ); + } + + // create and set up activity params + var aActivityParamSet = new ActivityParamSet(); + + aActivityParamSet.aEndEvent = makeEvent( bind( this, this.deactivate ) ); + aActivityParamSet.aTimerEventQueue = this.aContext.aTimerEventQueue; + aActivityParamSet.aActivityQueue = this.aContext.aActivityQueue; + aActivityParamSet.nMinDuration = nDuration; + aActivityParamSet.nMinNumberOfFrames = this.getMinFrameCount(); + aActivityParamSet.bAutoReverse = this.isAutoReverseEnabled(); + aActivityParamSet.nRepeatCount = this.getRepeatCount(); + aActivityParamSet.nAccelerationFraction = this.getAccelerateValue(); + aActivityParamSet.nDecelerationFraction = this.getDecelerateValue(); + aActivityParamSet.nSlideWidth = this.aNodeContext.aSlideWidth; + aActivityParamSet.nSlideHeight = this.aNodeContext.aSlideHeight; + + return aActivityParamSet; + }; + + AnimationBaseNode.prototype.hasPendingAnimation = function() + { + return true; + }; + + AnimationBaseNode.prototype.getTargetElement = function() + { + return this.aTargetElement; + }; + + AnimationBaseNode.prototype.getAnimatedElement = function() + { + return this.aAnimatedElement; + }; + + AnimationBaseNode.prototype.dispose= function() + { + if( this.aActivity ) + this.aActivity.dispose(); + + AnimationBaseNode.superclass.dispose.call( this ); + }; + + AnimationBaseNode.prototype.getMinFrameCount = function() + { + return this.nMinFrameCount; + }; + + AnimationBaseNode.prototype.getAdditiveMode = function() + { + return this.eAdditiveMode; + }; + + AnimationBaseNode.prototype.info = function( bVerbose ) + { + var sInfo = AnimationBaseNode.superclass.info.call( this, bVerbose ); + + if( bVerbose ) + { + // min frame count + if( this.getMinFrameCount() ) + sInfo += '; min frame count: ' + this.getMinFrameCount(); + + // additive mode + sInfo += '; additive: ' + aAddittiveModeOutMap[ this.getAdditiveMode() ]; + + // target element + if( this.getShape() ) + { + sElemId = this.getShape().getAttribute( 'id' ); + sInfo += '; targetElement: ' + sElemId; + } + } + + return sInfo; +}; + + +// ------------------------------------------------------------------------------------------ // +function AnimationBaseNode2( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationBaseNode2.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sAttributeName; + this.aToValue; + +} +extend( AnimationBaseNode2, AnimationBaseNode ); + + +AnimationBaseNode2.prototype.parseElement = function() +{ + var bRet = AnimationBaseNode2.superclass.parseElement.call( this ); + + var aAnimElem = this.aElement; + + // attributeName attribute + this.sAttributeName = aAnimElem.getAttribute( 'attributeName' ); + if( !this.sAttributeName ) + { + this.eCurrentState = INVALID_NODE; + log( 'AnimationBaseNode2.parseElement: target attribute name not found: ' + this.sAttributeName ); + } + + // to attribute + this.aToValue = aAnimElem.getAttribute( 'to' ); + + return bRet; +}; + +AnimationBaseNode2.prototype.getAttributeName = function() +{ + return this.sAttributeName; +}; + +AnimationBaseNode2.prototype.getToValue = function() +{ + return this.aToValue; +}; + +AnimationBaseNode2.prototype.info = function( bVerbose ) +{ + var sInfo = AnimationBaseNode2.superclass.info.call( this, bVerbose ); + + if( bVerbose ) + { + // attribute name + if( this.getAttributeName() ) + sInfo += '; attributeName: ' + this.getAttributeName(); + + // To + if( this.getToValue() ) + sInfo += '; to: ' + this.getToValue(); + } + + return sInfo; +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimationBaseNode3( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationBaseNode3.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.eAccumulate; + this.eCalcMode; + this.aFromValue; + this.aByValue; + this.aKeyTimes; + this.aValues; + +} +extend( AnimationBaseNode3, AnimationBaseNode2 ); + + +AnimationBaseNode3.prototype.parseElement = function() +{ + var bRet = AnimationBaseNode3.superclass.parseElement.call( this ); + + var aAnimElem = this.aElement; + + // accumulate attribute + this.eAccumulate = ACCUMULATE_MODE_NONE; + var sAccumulateAttr = aAnimElem.getAttribute( 'accumulate' ); + if( sAccumulateAttr == 'sum' ) + this.eAccumulate = ACCUMULATE_MODE_SUM; + + // calcMode attribute + this.eCalcMode = CALC_MODE_LINEAR; + var sCalcModeAttr = aAnimElem.getAttribute( 'calcMode' ); + if( sCalcModeAttr && aCalcModeInMap[ sCalcModeAttr ] ) + this.eCalcMode = aCalcModeInMap[ sCalcModeAttr ]; + + // from attribute + this.aFromValue = aAnimElem.getAttribute( 'from' ); + + // by attribute + this.aByValue = aAnimElem.getAttribute( 'by' ); + + // keyTimes attribute + this.aKeyTimes = new Array(); + var sKeyTimesAttr = aAnimElem.getAttribute( 'keyTimes' ); + sKeyTimesAttr = removeWhiteSpaces( sKeyTimesAttr ); + if( sKeyTimesAttr ) + { + var aKeyTimes = sKeyTimesAttr.split( ';' ); + for( var i = 0; i < aKeyTimes.length; ++i ) + this.aKeyTimes.push( parseFloat( aKeyTimes[i] ) ); + } + + // values attribute + var sValuesAttr = aAnimElem.getAttribute( 'values' ); + if( sValuesAttr ) + { + this.aValues = sValuesAttr.split( ';' ); + } + else + { + this.aValues = new Array(); + } + + return bRet; +}; + +AnimationBaseNode3.prototype.getAccumulate = function() +{ + return this.eAccumulate; +}; + +AnimationBaseNode3.prototype.getCalcMode = function() +{ + return this.eCalcMode; +}; + +AnimationBaseNode3.prototype.getFromValue = function() +{ + return this.aFromValue; +}; + +AnimationBaseNode3.prototype.getByValue = function() +{ + return this.aByValue; +}; + +AnimationBaseNode3.prototype.getKeyTimes = function() +{ + return this.aKeyTimes; +}; + +AnimationBaseNode3.prototype.getValues = function() +{ + return this.aValues; +}; + +AnimationBaseNode3.prototype.info = function( bVerbose ) +{ + var sInfo = AnimationBaseNode3.superclass.info.call( this, bVerbose ); + + if( bVerbose ) + { + // accumulate mode + if( this.getAccumulate() ) + sInfo += '; accumulate: ' + aAccumulateModeOutMap[ this.getAccumulate() ]; + + // calcMode + sInfo += '; calcMode: ' + aCalcModeOutMap[ this.getCalcMode() ]; + + // from + if( this.getFromValue() ) + sInfo += '; from: ' + this.getFromValue(); + + // by + if( this.getByValue() ) + sInfo += '; by: ' + this.getByValue(); + + // keyTimes + if( this.getKeyTimes().length ) + sInfo += '; keyTimes: ' + this.getKeyTimes().join( ',' ); + + // values + if( this.getKeyTimes().length ) + sInfo += '; values: ' + this.getValues().join( ',' ); + } + + return sInfo; +}; + + + +// ------------------------------------------------------------------------------------------ // +function BaseContainerNode( aAnimElem, aParentNode, aNodeContext ) +{ + BaseContainerNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'BaseContainerNode'; + this.bIsContainer = true; + this.aChildrenArray = new Array(); + this.nFinishedChildren = 0; + this.bDurationIndefinite = false; + + this.eImpressNodeType = undefined; + this.ePresetClass = undefined; + this.ePresetId = undefined; +} +extend( BaseContainerNode, BaseNode ); + + +BaseContainerNode.prototype.parseElement= function() +{ + var bRet = BaseContainerNode.superclass.parseElement.call( this ); + + var aAnimElem = this.aElement; + + // node-type attribute + this.eImpressNodeType = IMPRESS_DEFAULT_NODE; + var sNodeTypeAttr = aAnimElem.getAttribute( 'node-type' ); + if( sNodeTypeAttr && aImpressNodeTypeInMap[ sNodeTypeAttr ] ) + this.eImpressNodeType = aImpressNodeTypeInMap[ sNodeTypeAttr ]; + this.bMainSequenceRootNode = ( this.eImpressNodeType == IMPRESS_MAIN_SEQUENCE_NODE ); + + // preset-class attribute + this.ePresetClass = undefined; + var sPresetClassAttr = aAnimElem.getAttribute( 'preset-class' ); + if( sPresetClassAttr && aPresetClassInMap[ sPresetClassAttr ] ) + this.ePresetClass = aPresetClassInMap[ sPresetClassAttr ]; + + // preset-id attribute + this.ePresetId = undefined; + var sPresetIdAttr = aAnimElem.getAttribute( 'preset-id' ); + if( sPresetIdAttr && aPresetIdInMap[ sPresetIdAttr ] ) + this.ePresetId = aPresetIdInMap[ sPresetIdAttr ]; + + + // parse children elements + var nChildrenCount = this.aChildrenArray.length; + for( var i = 0; i < nChildrenCount; ++i ) + { + this.aChildrenArray[i].parseElement(); + } + + + // resolve duration + this.bDurationIndefinite + = ( !this.getDuration() || this.getDuration().isIndefinite() ) && + ( !this.getEnd() || ( this.getEnd().getType() != OFFSET_TIMING ) ); + + return bRet; +}; + +BaseContainerNode.prototype.appendChildNode = function( aAnimationNode ) +{ + if( ! this.checkValidNode() ) + return ; + + if( aAnimationNode.registerDeactivatingListener( this ) ) + this.aChildrenArray.push( aAnimationNode ); +}; + +BaseContainerNode.prototype.init_st = function() +{ + this.nFinishedChildren = 0; + var nChildrenCount = this.aChildrenArray.length; + var nInitChildren = 0; + for( var i = 0; i < nChildrenCount; ++i ) + { + if( this.aChildrenArray[i].init() ) + { + ++nInitChildren; + } + } + return ( nChildrenCount == nInitChildren ); +}; + +BaseContainerNode.prototype.deactivate_st = function( eDestState ) +{ + if( eDestState == FROZEN_NODE ) + { + // deactivate all children that are not FROZEN or ENDED: + this.forEachChildNode( mem_fn( 'deactivate' ), ~( FROZEN_NODE | ENDED_NODE ) ); + } + else + { + // end all children that are not ENDED: + this.forEachChildNode( mem_fn( 'end' ), ~ENDED_NODE ); + } +}; + +BaseContainerNode.prototype.hasPendingAnimation = function() +{ + var nChildrenCount = this.aChildrenArray.length; + for( var i = 0; i < nChildrenCount; ++i ) + { + if( this.aChildrenArray[i].hasPendingAnimation() ) + return true; + } + return false; +}; + +BaseContainerNode.prototype.activate_st = function() +{ + log( 'BaseContainerNode.activate_st: abstract method called' ); +}; + +BaseContainerNode.prototype.notifyDeactivating = function( aAnimationNode ) +{ + log( 'BaseContainerNode.notifyDeactivating: abstract method called' ); +}; + +BaseContainerNode.prototype.isDurationIndefinite = function() +{ + return this.bDurationIndefinite; +}; + +BaseContainerNode.prototype.isChildNode = function( aAnimationNode ) +{ + var nChildrenCount = this.aChildrenArray.length; + for( var i = 0; i < nChildrenCount; ++i ) + { + if( this.aChildrenArray[i].getId() == aAnimationNode.getId() ) + return true; + } + return false; +}; + +BaseContainerNode.prototype.notifyDeactivatedChild = function( aChildNode ) +{ + assert( ( aChildNode.getState() == FROZEN_NODE ) || ( aChildNode.getState() == ENDED_NODE ), + 'BaseContainerNode.notifyDeactivatedChild: passed child node is neither in FROZEN nor in ENDED state' ); + + assert( this.getState() != INVALID_NODE, + 'BaseContainerNode.notifyDeactivatedChild: this node is invalid' ); + + if( !this.isChildNode( aChildNode ) ) + { + log( 'BaseContainerNode.notifyDeactivatedChild: unknown child notifier!' ); + return false; + } + + var nChildrenCount = this.aChildrenArray.length; + + assert( ( this.nFinishedChildren < nChildrenCount ), + 'BaseContainerNode.notifyDeactivatedChild: assert(this.nFinishedChildren < nChildrenCount) failed' ); + + ++this.nFinishedChildren; + var bFinished = ( this.nFinishedChildren >= nChildrenCount ); + + if( bFinished && this.isDurationIndefinite() ) + { + this.deactivate(); + } + + return bFinished; +}; + +BaseContainerNode.prototype.forEachChildNode = function( aFunction, eNodeStateMask ) +{ + if( !eNodeStateMask ) + eNodeStateMask = -1; + + var nChildrenCount = this.aChildrenArray.length; + for( var i = 0; i < nChildrenCount; ++i ) + { + if( ( eNodeStateMask != -1 ) && ( ( this.aChildrenArray[i].getState() & eNodeStateMask ) == 0 ) ) + continue; + aFunction( this.aChildrenArray[i] ); + } +}; + +BaseContainerNode.prototype.dispose = function() +{ + var nChildrenCount = this.aChildrenArray.length; + for( var i = 0; i < nChildrenCount; ++i ) + { + this.aChildrenArray[i].dispose(); + } + + BaseContainerNode.superclass.dispose.call( this ); +}; + +BaseContainerNode.prototype.getImpressNodeType = function() +{ + return this.eImpressNodeType; +}; + +BaseContainerNode.prototype.info = function( bVerbose ) +{ + var sInfo = BaseContainerNode.superclass.info.call( this, bVerbose ); + + if( bVerbose ) + { + // impress node type + if( this.getImpressNodeType() ) + sInfo += '; node-type: ' + aImpressNodeTypeOutMap[ this.getImpressNodeType() ]; + } + + var nChildrenCount = this.aChildrenArray.length; + for( var i = 0; i < nChildrenCount; ++i ) + { + sInfo += '\n'; + sInfo += this.aChildrenArray[i].info( bVerbose ); + } + + return sInfo; +}; + +// ------------------------------------------------------------------------------------------ // +function ParallelTimeContainer( aAnimElem, aParentNode, aNodeContext ) +{ + ParallelTimeContainer.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'ParallelTimeContainer'; +} +extend( ParallelTimeContainer, BaseContainerNode ); + + +ParallelTimeContainer.prototype.activate_st = function() +{ + var nChildrenCount = this.aChildrenArray.length; + var nResolvedChildren = 0; + for( var i = 0; i < nChildrenCount; ++i ) + { + if( this.aChildrenArray[i].resolve() ) + { + ++nResolvedChildren; + } + } + + if( nChildrenCount != nResolvedChildren ) + { + log( 'ParallelTimeContainer.activate_st: resolving all children failed' ); + return; + } + + + if( this.isDurationIndefinite() && ( nChildrenCount == 0 ) ) + { + this.scheduleDeactivationEvent( this.makeDeactivationEvent( 0.0 ) ); + } + else + { + this.scheduleDeactivationEvent(); + } +}; + +ParallelTimeContainer.prototype.notifyDeactivating = function( aAnimationNode ) +{ + this.notifyDeactivatedChild( aAnimationNode ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function SequentialTimeContainer( aAnimElem, aParentNode, aNodeContext ) +{ + SequentialTimeContainer.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'SequentialTimeContainer'; +} +extend( SequentialTimeContainer, BaseContainerNode ); + + +SequentialTimeContainer.prototype.activate_st = function() +{ + var nChildrenCount = this.aChildrenArray.length; + for( ; this.nFinishedChildren < nChildrenCount; ++this.nFinishedChildren ) + { + if( this.resolveChild( this.aChildrenArray[ this.nFinishedChildren ] ) ) + break; + else + log( 'SequentialTimeContainer.activate_st: resolving child failed!' ); + } + + if( this.isDurationIndefinite() && ( ( nChildrenCount == 0 ) || ( this.nFinishedChildren >= nChildrenCount ) ) ) + { + // deactivate ASAP: + this.scheduleDeactivationEvent( this.makeDeactivationEvent( 0.0 ) ); + } + else + { + this.scheduleDeactivationEvent(); + } +}; + +SequentialTimeContainer.prototype.notifyDeactivating = function( aNotifier ) +{ + if( this.notifyDeactivatedChild( aNotifier ) ) + return; + + assert( this.nFinishedChildren < this.aChildrenArray.length, + 'SequentialTimeContainer.notifyDeactivating: assertion (this.nFinishedChildren < this.aChildrenArray.length) failed' ); + + var aNextChild = this.aChildrenArray[ this.nFinishedChildren ]; + + assert( aNextChild.getState() == UNRESOLVED_NODE, + 'SequentialTimeContainer.notifyDeactivating: assertion (aNextChild.getState == UNRESOLVED_NODE) failed' ); + + if( !this.resolveChild( aNextChild ) ) + { + // could not resolve child - since we risk to + // stall the chain of events here, play it safe + // and deactivate this node (only if we have + // indefinite duration - otherwise, we'll get a + // deactivation event, anyways). + this.deactivate(); + } +}; + +SequentialTimeContainer.prototype.skipEffect = function( aChildNode ) +{ + // not implemented +}; + +SequentialTimeContainer.prototype.rewindEffect = function( aChildNode ) +{ + // not implemented +}; + +SequentialTimeContainer.prototype.resolveChild = function( aChildNode ) +{ + var bResolved = aChildNode.resolve(); + + if( bResolved && this.isMainSequenceRootNode() ) + { + // skip/rewind events handling + } + return bResolved; +}; + + + +// ------------------------------------------------------------------------------------------ // +function PropertyAnimationNode( aAnimElem, aParentNode, aNodeContext ) +{ + PropertyAnimationNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'PropertyAnimationNode'; +} +extend( PropertyAnimationNode, AnimationBaseNode3 ); + + +PropertyAnimationNode.prototype.createActivity = function() +{ + + /* + var aActivityParamSet = this.fillActivityParams(); + var aAnimation = createPropertyAnimation( 'opacity', + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + return new SimpleActivity( aActivityParamSet, aAnimation, FORWARD ); + */ + + + /* + if( true && this.getAttributeName() === 'x' ) + { + var sAttributeName = 'x'; + + this.aDuration = new Duration( '2s' ); + this.sAttributeName = sAttributeName; + this.aKeyTimes = [ 0.0, 0.25, 0.50, 0.75, 1.0 ]; + //this.aKeyTimes = [ 0.0, 1.0 ]; + var aM = 5000 / this.aNodeContext.aSlideWidth; + this.aValues = [ 'x', 'x - ' + aM, 'x', 'x + ' + aM, 'x' ]; + //this.aValues = [ '0', 'width' ]; + + //this.aFromValue = ''; + //this.aToValue = '0 + ' + aTranslationValue; + //this.aByValue = aTranslationValue; + //this.nRepeatCount = 3; + + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( this.getAttributeName(), + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + var aInterpolator = null; + return createActivity( aActivityParamSet, this, aAnimation, aInterpolator ); + } + + if( true && this.getAttributeName() === 'y' ) + { + var sAttributeName = 'height'; + this.aDuration = new Duration( '2s' ); + this.sAttributeName = sAttributeName; + this.aKeyTimes = [ 0.0, 0.25, 0.50, 0.75, 1.0 ]; + //this.aKeyTimes = [ 0.0, 1.0 ]; + var aM = 5000 / this.aNodeContext.aSlideHeight; + this.aValues = new Array(); + //this.aValues = [ 'y', 'y', 'y - ' + aM, 'y - ' + aM, 'y' ]; + this.aValues = [ 'height', '0', 'height', '2*height', 'height' ]; + //this.aValues = [ '0', 'height' ]; + + //this.aFromValue = '2 * height'; + //this.aToValue = 'width'; + //this.aByValue = 'width';//aTranslationValue; + + + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( this.getAttributeName(), + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + var aInterpolator = null; + return createActivity( aActivityParamSet, this, aAnimation, aInterpolator ); + } + */ + + + + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( this.getAttributeName(), + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + var aInterpolator = null; // createActivity will compute it; + return createActivity( aActivityParamSet, this, aAnimation, aInterpolator ); + +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimationSetNode( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationSetNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'AnimationSetNode'; +} +extend( AnimationSetNode, AnimationBaseNode2 ); + + +AnimationSetNode.prototype.createActivity = function() +{ + var aAnimation = createPropertyAnimation( this.getAttributeName(), + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + var aActivityParamSet = this.fillActivityParams(); + + return new SetActivity( aActivityParamSet, aAnimation, this.getToValue() ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimationColorNode( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationColorNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'AnimationColorNode'; + + this.eColorInterpolation; + this.eColorInterpolationDirection; +} +extend( AnimationColorNode, AnimationBaseNode3 ); + + +AnimationColorNode.prototype.parseElement = function() +{ + var bRet = AnimationColorNode.superclass.parseElement.call( this ); + + var aAnimElem = this.aElement; + + // color-interpolation attribute + this.eColorInterpolation = COLOR_SPACE_RGB; + var sColorInterpolationAttr = aAnimElem.getAttribute( 'color-interpolation' ); + if( sColorInterpolationAttr && aColorSpaceInMap[ sColorInterpolationAttr ] ) + this.eColorInterpolation = aColorSpaceInMap[ sColorInterpolationAttr ]; + + // color-interpolation-direction attribute + this.eColorInterpolationDirection = CLOCKWISE; + var sColorInterpolationDirectionAttr = aAnimElem.getAttribute( 'color-interpolation-direction' ); + if( sColorInterpolationDirectionAttr && aClockDirectionInMap[ sColorInterpolationDirectionAttr ] ) + this.eColorInterpolationDirection = aClockDirectionInMap[ sColorInterpolationDirectionAttr ]; + + return bRet; +}; + +AnimationColorNode.prototype.createActivity = function() +{ + /* + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( 'opacity', + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + return new SimpleActivity( aActivityParamSet, aAnimation, FORWARD ); + */ + + /* + if( false && this.getAttributeName() === 'fill-color' ) + { + var sAttributeName = 'stroke-color'; + + this.aDuration = new Duration( '2s' ); + this.nAccelerate = 0.0; + this.nDecelerate = 0.0; + this.eColorInterpolation = COLOR_SPACE_RGB; + this.eColorInterpolationDirection = COUNTERCLOCKWISE; + + this.sAttributeName = sAttributeName; + + this.aFromValue = 'rgb( 0%, 0%, 0% )'; + this.aToValue = 'rgb( 0%, 0%, 100% )'; + //this.aByValue = 'hsl( 0, -12%, -25% )'; + + + + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( this.getAttributeName(), + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + var aColorAnimation; + var aInterpolator; + if( this.getColorInterpolation() === COLOR_SPACE_HSL ) + { + ANIMDBG.print( 'AnimationColorNode.createActivity: color space hsl' ); + aColorAnimation = new HSLAnimationWrapper( aAnimation ); + var aInterpolatorMaker = aInterpolatorHandler.getInterpolator( this.getCalcMode(), + COLOR_PROPERTY, + COLOR_SPACE_HSL ); + aInterpolator = aInterpolatorMaker( this.getColorInterpolationDirection() ); + } + else + { + ANIMDBG.print( 'AnimationColorNode.createActivity: color space rgb' ); + aColorAnimation = aAnimation; + aInterpolator = aInterpolatorHandler.getInterpolator( this.getCalcMode(), + COLOR_PROPERTY, + COLOR_SPACE_RGB ); + } + + return createActivity( aActivityParamSet, this, aColorAnimation, aInterpolator ); + } + */ + + + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( this.getAttributeName(), + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + var aColorAnimation; + var aInterpolator; + if( this.getColorInterpolation() === COLOR_SPACE_HSL ) + { + ANIMDBG.print( 'AnimationColorNode.createActivity: color space hsl' ); + aColorAnimation = new HSLAnimationWrapper( aAnimation ); + var aInterpolatorMaker = aInterpolatorHandler.getInterpolator( this.getCalcMode(), + COLOR_PROPERTY, + COLOR_SPACE_HSL ); + aInterpolator = aInterpolatorMaker( this.getColorInterpolationDirection() ); + } + else + { + ANIMDBG.print( 'AnimationColorNode.createActivity: color space rgb' ); + aColorAnimation = aAnimation; + aInterpolator = aInterpolatorHandler.getInterpolator( this.getCalcMode(), + COLOR_PROPERTY, + COLOR_SPACE_RGB ); + } + + return createActivity( aActivityParamSet, this, aColorAnimation, aInterpolator ); + + +}; + +AnimationColorNode.prototype.getColorInterpolation = function() +{ + return this.eColorInterpolation; +}; + +AnimationColorNode.prototype.getColorInterpolationDirection = function() +{ + return this.eColorInterpolationDirection; +}; + +AnimationColorNode.prototype.info = function( bVerbose ) +{ + var sInfo = AnimationColorNode.superclass.info.call( this, bVerbose ); + + if( bVerbose ) + { + // color interpolation + sInfo += '; color-interpolation: ' + aColorSpaceOutMap[ this.getColorInterpolation() ]; + + // color interpolation direction + sInfo += '; color-interpolation-direction: ' + aClockDirectionOutMap[ this.getColorInterpolationDirection() ]; + } + return sInfo; +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimationTransitionFilterNode( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationTransitionFilterNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'AnimationTransitionFilterNode'; + + this.eTransitionType; + this.eTransitionSubType; + this.bReverseDirection; + this.eTransitionMode; +} +extend( AnimationTransitionFilterNode, AnimationBaseNode ); + + +AnimationTransitionFilterNode.prototype.createActivity = function() +{ + var aActivityParamSet = this.fillActivityParams(); + + var aAnimation = createPropertyAnimation( 'opacity', + this.getAnimatedElement(), + this.aNodeContext.aSlideWidth, + this.aNodeContext.aSlideHeight ); + + var eDirection = this.getTransitionMode() ? FORWARD : BACKWARD; + + return new SimpleActivity( aActivityParamSet, aAnimation, eDirection ); + +}; + +AnimationTransitionFilterNode.prototype.parseElement = function() +{ + var bRet = AnimationTransitionFilterNode.superclass.parseElement.call( this ); + + var aAnimElem = this.aElement; + + // type attribute + this.eTransitionType = undefined; + var sTypeAttr = aAnimElem.getAttribute( 'type' ); + if( sTypeAttr && aTransitionTypeInMap[ sTypeAttr ] ) + { + this.eTransitionType = aTransitionTypeInMap[ sTypeAttr ]; + } + else + { + this.eCurrentState = INVALID_NODE; + log( 'AnimationTransitionFilterNode.parseElement: transition type not valid: ' + sTypeAttr ); + } + + // subtype attribute + this.eTransitionSubType = undefined; + var sSubTypeAttr = aAnimElem.getAttribute( 'subtype' ); + if( sSubTypeAttr && aTransitionSubtypeInMap[ sSubTypeAttr ] ) + { + this.eTransitionSubType = aTransitionSubtypeInMap[ sSubTypeAttr ]; + } + else + { + this.eCurrentState = INVALID_NODE; + log( 'AnimationTransitionFilterNode.parseElement: transition subtype not valid: ' + sSubTypeAttr ); + } + + // direction attribute + this.bReverseDirection = false; + var sDirectionAttr = aAnimElem.getAttribute( 'direction' ); + if( sDirectionAttr == 'reverse' ) + this.bReverseDirection = true; + + // mode attribute: + this.eTransitionMode = TRANSITION_MODE_IN; + var sModeAttr = aAnimElem.getAttribute( 'mode' ); + if( sModeAttr === 'out' ) + this.eTransitionMode = TRANSITION_MODE_OUT; + + return bRet; +}; + +AnimationTransitionFilterNode.prototype.getTransitionType = function() +{ + return this.eTransitionType; +}; + +AnimationTransitionFilterNode.prototype.getTransitionSubType = function() +{ + return this.eTransitionSubType; +}; + +AnimationTransitionFilterNode.prototype.getTransitionMode = function() +{ + return this.eTransitionMode; +}; + +AnimationTransitionFilterNode.prototype.getReverseDirection = function() +{ + return this.bReverseDirection; +}; + +AnimationTransitionFilterNode.prototype.info = function( bVerbose ) +{ + var sInfo = AnimationTransitionFilterNode.superclass.info.call( this, bVerbose ); + + if( bVerbose ) + { + // transition type + sInfo += '; type: ' + aTransitionTypeOutMap[ String( this.getTransitionType() ) ]; + + // transition subtype + sInfo += '; subtype: ' + aTransitionSubtypeOutMap[ this.getTransitionSubType() ]; + + // transition direction + if( this.getReverseDirection() ) + sInfo += '; direction: reverse'; + } + + return sInfo; +}; + + + +/********************************************************************************************** + * Animation Node Factory + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // +function createAnimationTree( aRootElement, aNodeContext ) +{ + return createAnimationNode( aRootElement, null, aNodeContext ); +} + + + +// ------------------------------------------------------------------------------------------ // +function createAnimationNode( aElement, aParentNode, aNodeContext ) +{ + assert( aElement, 'createAnimationNode: invalid animation element' ); + + var eAnimationNodeType = getAnimationElementType( aElement ); + + var aCreatedNode = null; + var aCreatedContainer = null; + + switch( eAnimationNodeType ) + { + case ANIMATION_NODE_PAR: + aCreatedNode = aCreatedContainer = + new ParallelTimeContainer( aElement, aParentNode, aNodeContext ); + break; + case ANIMATION_NODE_ITERATE: + // map iterate container to ParallelTimeContainer. + // the iterating functionality is to be found + // below, (see method implCreateIteratedNodes) + aCreatedNode = aCreatedContainer = + new ParallelTimeContainer( aElement, aParentNode, aNodeContext ); + break; + case ANIMATION_NODE_SEQ: + aCreatedNode = aCreatedContainer = + new SequentialTimeContainer( aElement, aParentNode, aNodeContext ); + break; + case ANIMATION_NODE_ANIMATE: + aCreatedNode = new PropertyAnimationNode( aElement, aParentNode, aNodeContext ); + break; + case ANIMATION_NODE_SET: + aCreatedNode = new AnimationSetNode( aElement, aParentNode, aNodeContext ); + break; + case ANIMATION_NODE_ANIMATEMOTION: + //aCreatedNode = new AnimationPathMotionNode( aElement, aParentNode, aNodeContext ); + //break; + log( 'createAnimationNode: ANIMATEMOTION not implemented' ); + return null; + case ANIMATION_NODE_ANIMATECOLOR: + aCreatedNode = new AnimationColorNode( aElement, aParentNode, aNodeContext ); + break; + case ANIMATION_NODE_ANIMATETRANSFORM: + //aCreatedNode = new AnimationTransformNode( aElement, aParentNode, aNodeContext ); + //break; + log( 'createAnimationNode: ANIMATETRANSFORM not implemented' ); + return null; + case ANIMATION_NODE_TRANSITIONFILTER: + aCreatedNode = new AnimationTransitionFilterNode( aElement, aParentNode, aNodeContext ); + break; + default: + log( 'createAnimationNode: invalid Animation Node Type: ' + eAnimationNodeType ); + return null; + } + + if( aCreatedContainer ) + { + if( eAnimationNodeType == ANIMATION_NODE_ITERATE ) + { + createIteratedNodes( aElement, aCreatedContainer, aNodeContext ); + } + else + { + var aChildrenArray = getElementChildren( aElement ); + for( var i = 0; i < aChildrenArray.length; ++i ) + { + if( !createChildNode( aChildrenArray[i], aCreatedContainer, aNodeContext ) ) + { + return null; + } + } + } + } + + return aCreatedNode; +} + + + +// ------------------------------------------------------------------------------------------ // +function createChildNode( aElement, aParentNode, aNodeContext ) +{ + var aChildNode = createAnimationNode( aElement, aParentNode, aNodeContext ); + + if( !aChildNode ) + { + log( 'createChildNode: child node creation failed' ); + return false; + } + else + { + aParentNode.appendChildNode( aChildNode ); + return true; + } +} + + + +// ------------------------------------------------------------------------------------------ // +function createIteratedNodes( aElement, aContainerNode, aNodeContext ) +{ + // not implemented +} + + + +/********************************************************************************************** + * Animation Factory + **********************************************************************************************/ + + +// ------------------------------------------------------------------------------------------ // +function makeScaler( nScale ) +{ + if( ( typeof( nScale ) !== typeof( 0 ) ) || !isFinite( nScale ) ) + { + log( 'makeScaler: not valid param passed: ' + nScale ); + return null; + } + + return function( nValue ) + { + return ( nScale * nValue ); + }; +} + + + +// ------------------------------------------------------------------------------------------ // +function createPropertyAnimation( sAttrName, aAnimatedElement, nWidth, nHeight ) +{ + if( !aAttributeMap[ sAttrName ] ) + { + log( 'createPropertyAnimation: attribute is unknown' ); + return; + } + + + var aFunctorSet = aAttributeMap[ sAttrName ]; + + var sGetValueMethod = aFunctorSet.get; + var sSetValueMethod = aFunctorSet.set; + + if( !sGetValueMethod || !sSetValueMethod ) + { + log( 'createPropertyAnimation: attribute is not handled' ); + return; + } + + var aGetModifier = eval( aFunctorSet.getmod ); + var aSetModifier = eval( aFunctorSet.setmod ); + + + return new GenericAnimation( bind( aAnimatedElement, aAnimatedElement[ sGetValueMethod ] ), + bind( aAnimatedElement, aAnimatedElement[ sSetValueMethod ] ), + aGetModifier, + aSetModifier); +} + + + +// ------------------------------------------------------------------------------------------ // +function GenericAnimation( aGetValueFunc, aSetValueFunc, aGetModifier, aSetModifier ) +{ + assert( aGetValueFunc && aSetValueFunc, + 'GenericAnimation constructor: get value functor and/or set value functor are not valid' ); + + this.aGetValueFunc = aGetValueFunc; + this.aSetValueFunc = aSetValueFunc; + this.aGetModifier = aGetModifier; + this.aSetModifier = aSetModifier; + this.aAnimatableElement = null; + this.bAnimationStarted = false; +} + + +GenericAnimation.prototype.start = function( aAnimatableElement ) +{ + assert( aAnimatableElement, 'GenericAnimation.start: animatable element is not valid' ); + + this.aAnimatableElement = aAnimatableElement; + this.aAnimatableElement.notifyAnimationStart(); + + if( !this.bAnimationStarted ) + this.bAnimationStarted = true; +}; + +GenericAnimation.prototype.end = function() +{ + if( this.bAnimationStarted ) + this.bAnimationStarted = false; +}; + +GenericAnimation.prototype.perform = function( aValue ) +{ + if( this.aSetModifier ) + aValue = this.aSetModifier( aValue ); + + this.aSetValueFunc( aValue ); +}; + +GenericAnimation.prototype.getUnderlyingValue = function() +{ + var aValue = this.aGetValueFunc(); + if( this.aGetModifier ) + aValue = this.aGetModifier( aValue ); + return aValue; +}; + + + +// ------------------------------------------------------------------------------------------ // +function HSLAnimationWrapper( aColorAnimation ) +{ + assert( aColorAnimation, + 'HSLAnimationWrapper constructor: invalid color animation delegate' ); + + this.aAnimation = aColorAnimation; +} + + +HSLAnimationWrapper.prototype.start = function( aAnimatableElement ) +{ + this.aAnimation.start( aAnimatableElement ); +}; + +HSLAnimationWrapper.prototype.end = function() +{ + this.aAnimation.end(); +}; +HSLAnimationWrapper.prototype.perform = function( aHSLValue ) +{ + this.aAnimation.perform( aHSLValue.convertToRGB() ); +}; + +HSLAnimationWrapper.prototype.getUnderlyingValue = function() +{ + return this.aAnimation.getUnderlyingValue().convertToHSL(); +}; + + + +// ------------------------------------------------------------------------------------------ // +function AnimatedElement( aElement ) +{ + if( !aElement ) + { + log( 'AnimatedElement constructor: element is not valid' ); + } + + this.aActiveElement = aElement; + this.initElement(); + + this.aBaseBBox = this.aActiveElement.getBBox(); + this.nBaseCenterX = this.aBaseBBox.x + this.aBaseBBox.width / 2; + this.nBaseCenterY = this.aBaseBBox.y + this.aBaseBBox.height / 2; + this.nCenterX = this.nBaseCenterX; + this.nCenterY = this.nBaseCenterY; + this.nScaleFactorX = 1.0; + this.nScaleFactorY = 1.0; + + this.aPreviousElement = null; + this.aElementArray = new Array(); + this.nCurrentState = 0; + this.eAdditiveMode = ADDITIVE_MODE_REPLACE; + this.bIsUpdated = true; + + this.aTMatrix = document.documentElement.createSVGMatrix(); + this.aCTM = document.documentElement.createSVGMatrix(); + this.aICTM = document.documentElement.createSVGMatrix(); + this.setCTM(); + + this.aElementArray[0] = this.aActiveElement.cloneNode( true ); +} + +AnimatedElement.prototype.initElement = function() +{ + // add a transform attribute of type matrix + this.aActiveElement.setAttribute( 'transform', makeMatrixString( 1, 0, 0, 1, 0, 0 ) ); +}; + +AnimatedElement.prototype.getId = function() +{ + return this.aActiveElement.getAttribute( 'id' ); +}; + +AnimatedElement.prototype.isUpdated = function() +{ + return this.bIsUpdated; +}; + +AnimatedElement.prototype.getAdditiveMode = function() +{ + return this.eAdditiveMode; +}; + +AnimatedElement.prototype.setAdditiveMode = function( eAdditiveMode ) +{ + this.eAdditiveMode = eAdditiveMode; +}; + +AnimatedElement.prototype.setToElement = function( aElement ) +{ + if( !aElement ) + { + log( 'AnimatedElement(' + this.getId() + ').setToElement: element is not valid' ); + return false; + } + + var aClone = aElement.cloneNode( true ); + this.aPreviousElement = this.aActiveElement.parentNode.replaceChild( aClone, this.aActiveElement ); + this.aActiveElement = aClone; + + return true; +}; + +AnimatedElement.prototype.notifySlideStart = function() +{ + this.setToFirst(); + this.DBG( '.notifySlideStart invoked' ); +}; + +AnimatedElement.prototype.notifyAnimationStart = function() +{ + + this.DBG( '.notifyAnimationStart invoked' ); + this.bIsUpdated = false; +}; + +AnimatedElement.prototype.notifyAnimationEnd = function() +{ + // empty body +}; + +AnimatedElement.prototype.notifyNextEffectStart = function( nEffectIndex ) +{ + assert( this.nCurrentState === nEffectIndex, + 'AnimatedElement(' + this.getId() + ').notifyNextEffectStart: assertion (current state == effect index) failed' ); + + if( this.isUpdated() ) + { + if( !this.aElementArray[ nEffectIndex ] ) + { + this.aElementArray[ nEffectIndex ] = this.aElementArray[ this.nCurrentState ]; + this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): new state set to previous one ' ); + } + } + else + { + if( !this.aElementArray[ nEffectIndex ] ) + { + this.aElementArray[ nEffectIndex ] = this.aActiveElement.cloneNode( true ); + this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): cloned active state ' ); + } + } + ++this.nCurrentState; + }; + + AnimatedElement.prototype.setToFirst = function() + { + this.setTo( 0 ); + }; + + AnimatedElement.prototype.setToLast = function() + { + this.setTo( this.aElementArray.length - 1 ); + }; + + AnimatedElement.prototype.setTo = function( nEffectIndex ) + { + var bRet = this.setToElement( this.aElementArray[ nEffectIndex ] ); + if( bRet ) + { + this.nCurrentState = nEffectIndex; + + var aBBox = this.getBBox(); + var aBaseBBox = this.getBaseBBox(); + this.nCenterX = aBBox.x + aBBox.width / 2; + this.nCenterY = aBBox.y + aBBox.height / 2; + this.nScaleFactorX = aBBox.width / aBaseBBox.width; + this.nScaleFactorY = aBBox.height / aBaseBBox.height; + } + }; + + AnimatedElement.prototype.getBaseBBox = function() + { + return this.aBaseBBox; + }; + + AnimatedElement.prototype.getBaseCenterX = function() + { + return this.nBaseCenterX; + }; + + AnimatedElement.prototype.getBaseCenterY = function() + { + return this.nBaseCenterY; + }; + + AnimatedElement.prototype.getBBox = function() + { + return this.aActiveElement.parentNode.getBBox(); + }; + + AnimatedElement.prototype.getX = function() + { + return this.nCenterX; + }; + + AnimatedElement.prototype.getY = function() + { + return this.nCenterY; + }; + + AnimatedElement.prototype.getWidth = function() + { + return this.nScaleFactorX * this.getBaseBBox().width; + }; + + AnimatedElement.prototype.getHeight = function() + { + return this.nScaleFactorY * this.getBaseBBox().height; + }; + + AnimatedElement.prototype.setCTM = function() + { + + this.aICTM.e = this.getBaseCenterX(); + this.aICTM.f = this.getBaseCenterY(); + + this.aCTM.e = -this.aICTM.e; + this.aCTM.f = -this.aICTM.f; + }; + + AnimatedElement.prototype.updateTransformAttribute = function() + { + this.aTransformAttrList = this.aActiveElement.transform.baseVal; + this.aTransformAttr = this.aTransformAttrList.getItem( 0 ); + this.aTransformAttr.setMatrix( this.aTMatrix ); + }; + + AnimatedElement.prototype.setX = function( nXNewPos ) + { + this.aTransformAttrList = this.aActiveElement.transform.baseVal; + this.aTransformAttr = this.aTransformAttrList.getItem( 0 ); + this.aTransformAttr.matrix.e += ( nXNewPos - this.getX() ); + this.nCenterX = nXNewPos; + }; + + AnimatedElement.prototype.setY = function( nYNewPos ) + { + this.aTransformAttrList = this.aActiveElement.transform.baseVal; + this.aTransformAttr = this.aTransformAttrList.getItem( 0 ); + this.aTransformAttr.matrix.f += ( nYNewPos - this.getY() ); + this.nCenterY = nYNewPos; + }; + + AnimatedElement.prototype.setWidth = function( nNewWidth ) + { + var nBaseWidth = this.getBaseBBox().width; + if( nBaseWidth <= 0 ) + return; + + this.nScaleFactorX = nNewWidth / nBaseWidth; + this.implScale(); + }; + + AnimatedElement.prototype.setHeight = function( nNewHeight ) + { + var nBaseHeight = this.getBaseBBox().height; + if( nBaseHeight <= 0 ) + return; + + this.nScaleFactorY = nNewHeight / nBaseHeight; + this.implScale(); + }; + + AnimatedElement.prototype.implScale = function( ) + { + this.aTMatrix = document.documentElement.createSVGMatrix(); + this.aTMatrix.a = this.nScaleFactorX; + this.aTMatrix.d = this.nScaleFactorY; + this.aTMatrix = this.aICTM.multiply( this.aTMatrix.multiply( this.aCTM ) ); + + var nDeltaX = this.getX() - this.getBaseCenterX(); + var nDeltaY = this.getY() - this.getBaseCenterY(); + this.aTMatrix = this.aTMatrix.translate( nDeltaX, nDeltaY ); + this.updateTransformAttribute(); + }; + + AnimatedElement.prototype.setWidth2 = function( nNewWidth ) + { + if( nNewWidth < 0 ) + log( 'AnimatedElement(' + this.getId() + ').setWidth: negative width!' ); + if( nNewWidth < 0.001 ) + nNewWidth = 0.001; + + this.setCTM(); + + var nCurWidth = this.getWidth(); + if( nCurWidth <= 0 ) + nCurWidth = 0.001; + + var nScaleFactor = nNewWidth / nCurWidth; + if( nScaleFactor < 1e-5 ) + nScaleFactor = 1e-5; + this.aTMatrix = document.documentElement.createSVGMatrix(); + this.aTMatrix.a = nScaleFactor; + this.aTMatrix = this.aICTM.multiply( this.aTMatrix.multiply( this.aCTM ) ); + this.updateTransformAttribute(); +}; + +AnimatedElement.prototype.setHeight2 = function( nNewHeight ) +{ + ANIMDBG.print( 'AnimatedElement.setHeight: nNewHeight = ' + nNewHeight ); + if( nNewHeight < 0 ) + log( 'AnimatedElement(' + this.getId() + ').setWidth: negative height!' ); + if( nNewHeight < 0.001 ) + nNewHeight = 0.001; + + this.setCTM(); + + var nCurHeight = this.getHeight(); + ANIMDBG.print( 'AnimatedElement.setHeight: nCurHeight = ' + nCurHeight ); + if( nCurHeight <= 0 ) + nCurHeight = 0.001; + + var nScaleFactor = nNewHeight / nCurHeight; + ANIMDBG.print( 'AnimatedElement.setHeight: nScaleFactor = ' + nScaleFactor ); + if( nScaleFactor < 1e-5 ) + nScaleFactor = 1e-5; + this.aTMatrix = document.documentElement.createSVGMatrix(); + this.aTMatrix.d = nScaleFactor; + this.aTMatrix = this.aICTM.multiply( this.aTMatrix.multiply( this.aCTM ) ); + this.updateTransformAttribute(); +}; + +AnimatedElement.prototype.getOpacity = function() +{ + return this.aActiveElement.getAttribute( 'opacity' ); +}; + +AnimatedElement.prototype.setOpacity = function( nValue ) +{ + this.aActiveElement.setAttribute( 'opacity', nValue ); +}; + +AnimatedElement.prototype.getVisibility = function() +{ + + var sVisibilityValue = this.aActiveElement.getAttribute( 'visibility' ); + if( !sVisibilityValue || ( sVisibilityValue === 'inherit' ) ) + return 'visible'; // TODO: look for parent visibility! + else + return sVisibilityValue; +}; + +AnimatedElement.prototype.setVisibility = function( sValue ) +{ + if( sValue == 'visible' ) + sValue = 'inherit'; + this.aActiveElement.setAttribute( 'visibility', sValue ); +}; + +AnimatedElement.prototype.getStrokeStyle = function() +{ + // TODO: getStrokeStyle: implement it + return 'solid'; +}; + +AnimatedElement.prototype.setStrokeStyle = function( sValue ) +{ + ANIMDBG.print( 'AnimatedElement.setStrokeStyle(' + sValue + ')' ); +}; + +AnimatedElement.prototype.getFillStyle = function() +{ + // TODO: getFillStyle: implement it + return 'solid'; +}; + +AnimatedElement.prototype.setFillStyle = function( sValue ) +{ + ANIMDBG.print( 'AnimatedElement.setFillStyle(' + sValue + ')' ); +}; + +AnimatedElement.prototype.getFillColor = function() +{ + var aChildSet = getElementChildren( this.aActiveElement ); + var sFillColorValue = ''; + for( var i = 0; i < aChildSet.length; ++i ) + { + sFillColorValue = aChildSet[i].getAttribute( 'fill' ); + if( sFillColorValue && ( sFillColorValue !== 'none' ) ) + break; + } + + return colorParser( sFillColorValue ); +}; + +AnimatedElement.prototype.setFillColor = function( aRGBValue ) +{ + assert( aRGBValue instanceof RGBColor, + 'AnimatedElement.setFillColor: value argument is not an instance of RGBColor' ); + + var sValue = aRGBValue.toString( true /* clamped values */ ); + var aChildSet = getElementChildren( this.aActiveElement ); + + var sFillColorValue = ''; + for( var i = 0; i < aChildSet.length; ++i ) + { + sFillColorValue = aChildSet[i].getAttribute( 'fill' ); + if( sFillColorValue && ( sFillColorValue !== 'none' ) ) + { + aChildSet[i].setAttribute( 'fill', sValue ); + } + } +}; + +AnimatedElement.prototype.getStrokeColor = function() +{ + var aChildSet = getElementChildren( this.aActiveElement ); + var sStrokeColorValue = ''; + for( var i = 0; i < aChildSet.length; ++i ) + { + sStrokeColorValue = aChildSet[i].getAttribute( 'stroke' ); + if( sStrokeColorValue && ( sStrokeColorValue !== 'none' ) ) + break; + } + + return colorParser( sStrokeColorValue ); +}; + +AnimatedElement.prototype.setStrokeColor = function( aRGBValue ) +{ + assert( aRGBValue instanceof RGBColor, + 'AnimatedElement.setFillColor: value argument is not an instance of RGBColor' ); + + var sValue = aRGBValue.toString( true /* clamped values */ ); + var aChildSet = getElementChildren( this.aActiveElement ); + + var sStrokeColorValue = ''; + for( var i = 0; i < aChildSet.length; ++i ) + { + sStrokeColorValue = aChildSet[i].getAttribute( 'stroke' ); + if( sStrokeColorValue && ( sStrokeColorValue !== 'none' ) ) + { + aChildSet[i].setAttribute( 'stroke', sValue ); + } + } +}; + +AnimatedElement.prototype.getFontColor = function() +{ + // TODO: getFontColor implement it + return new RGBColor( 0, 0, 0 ); +}; + +AnimatedElement.prototype.setFontColor = function( sValue ) +{ + ANIMDBG.print( 'AnimatedElement.setFontColor(' + sValue + ')' ); +}; + +AnimatedElement.prototype.DBG = function( sMessage, nTime ) +{ + aAnimatedElementDebugPrinter.print( 'AnimatedElement(' + this.getId() + ')' + sMessage, nTime ); +}; + + + +// ------------------------------------------------------------------------------------------ // +// SlideAnimations + +function SlideAnimations( aSlideShowContext ) +{ + this.aContext = new NodeContext( aSlideShowContext ); + this.aAnimationNodeMap = new Object(); + this.aAnimatedElementMap = new Object(); + this.aSourceEventElementMap = new Object(); + this.aNextEffectEventArray = new NextEffectEventArray(); + this.aEventMultiplexer = new EventMultiplexer( aSlideShowContext.aTimerEventQueue ); + this.aRootNode = null; + this.bElementsParsed = false; + + this.aContext.aAnimationNodeMap = this.aAnimationNodeMap; + this.aContext.aAnimatedElementMap = this.aAnimatedElementMap; + this.aContext.aSourceEventElementMap = this.aSourceEventElementMap; +} + + +SlideAnimations.prototype.importAnimations = function( aAnimationRootElement ) +{ + if( !aAnimationRootElement ) + return false; + + this.aRootNode = createAnimationTree( aAnimationRootElement, this.aContext ); + + return ( this.aRootNode ? true : false ); +}; + +SlideAnimations.prototype.parseElements = function() +{ + if( !this.aRootNode ) + return false; + + // parse all nodes + if( !this.aRootNode.parseElement() ) + return false; + else + this.bElementsParsed = true; +}; + +SlideAnimations.prototype.elementsParsed = function() +{ + return this.bElementsParsed; +}; + +SlideAnimations.prototype.isFirstRun = function() +{ + return this.aContext.bFirstRun; +}; + +SlideAnimations.prototype.isAnimated = function() +{ + if( !this.bElementsParsed ) + return false; + + return this.aRootNode.hasPendingAnimation(); +}; + +SlideAnimations.prototype.start = function() +{ + if( !this.bElementsParsed ) + return false; + + aSlideShow.setSlideEvents( this.aNextEffectEventArray, this.aEventMultiplexer ); + + if( this.aContext.bFirstRun == undefined ) + this.aContext.bFirstRun = true; + else if( this.aContext.bFirstRun ) + this.aContext.bFirstRun = false; + + // init all nodes + if( !this.aRootNode.init() ) + return false; + + // resolve root node + if( !this.aRootNode.resolve() ) + return false; + + return true; +}; + +SlideAnimations.prototype.end = function( bLeftEffectsSkipped ) +{ + if( !this.bElementsParsed ) + return; // no animations there + + // end root node + this.aRootNode.deactivate(); + this.aRootNode.end(); + + if( bLeftEffectsSkipped && this.isFirstRun() ) + { + // in case this is the first run and left events have been skipped + // some next effect events for the slide could not be collected + // so the next time we should behave as it was the first run again + this.aContext.bFirstRun = undefined; + } + else if( this.isFirstRun() ) + { + this.aContext.bFirstRun = false; + } + +}; + +SlideAnimations.prototype.dispose = function() +{ + if( this.aRootNode ) + { + this.aRootNode.dispose(); + } +}; + +SlideAnimations.prototype.clearNextEffectEvents = function() +{ + ANIMDBG.print( 'SlideAnimations.clearNextEffectEvents: current slide: ' + nCurSlide ); + this.aNextEffectEventArray.clear(); + this.aContext.bFirstRun = undefined; +}; + + + +/********************************************************************************************** + * Event classes and helper functions + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // +function Event() +{ + this.nId = Event.getUniqueId(); +} + + +Event.CURR_UNIQUE_ID = 0; + +Event.getUniqueId = function() +{ + ++Event.CURR_UNIQUE_ID; + return Event.CURR_UNIQUE_ID; +}; + +Event.prototype.getId = function() +{ + return this.nId; +}; + + +// ------------------------------------------------------------------------------------------ // +function DelayEvent( aFunctor, nTimeout ) +{ + DelayEvent.superclass.constructor.call( this ); + + this.aFunctor = aFunctor; + this.nTimeout = nTimeout; + this.bWasFired = false; +} +extend( DelayEvent, Event ); + + +DelayEvent.prototype.fire = function() +{ + assert( this.isCharged(), 'DelayEvent.fire: assertion isCharged failed' ); + + this.bWasFired = true; + this.aFunctor(); + return true; +}; + +DelayEvent.prototype.isCharged = function() +{ + return !this.bWasFired; +}; + +DelayEvent.prototype.getActivationTime = function( nCurrentTime ) +{ + return ( this.nTimeout + nCurrentTime ); +}; + +DelayEvent.prototype.dispose = function() +{ + // don't clear unconditionally, because it may currently be executed: + if( this.isCharged() ) + this.bWasFired = true; +}; + +DelayEvent.prototype.charge = function() +{ + if( !this.isCharged() ) + this.bWasFired = false; +}; + + +// ------------------------------------------------------------------------------------------ // +function makeEvent( aFunctor ) +{ + return new DelayEvent( aFunctor, 0.0 ); +} + + + +// ------------------------------------------------------------------------------------------ // +function makeDelay( aFunctor, nTimeout ) +{ + return new DelayEvent( aFunctor, nTimeout ); +} + + + +// ------------------------------------------------------------------------------------------ // +function registerEvent( aTiming, aEvent, aNodeContext ) +{ + var aSlideShowContext = aNodeContext.aContext; + var eTimingType = aTiming.getType(); + + registerEvent.DBG( aTiming ); + + if( eTimingType == OFFSET_TIMING ) + { + aSlideShowContext.aTimerEventQueue.addEvent( aEvent ); + } + else if ( aNodeContext.bFirstRun ) + { + var aEventMultiplexer = aSlideShowContext.aEventMultiplexer; + if( !aEventMultiplexer ) + { + log( 'registerEvent: event multiplexer not initialized' ); + return; + } + var aNextEffectEventArray = aSlideShowContext.aNextEffectEventArray; + if( !aNextEffectEventArray ) + { + log( 'registerEvent: next effect event array not initialized' ); + return; + } + switch( eTimingType ) + { + case EVENT_TIMING: + var eEventType = aTiming.getEventType(); + var sEventBaseElemId = aTiming.getEventBaseElementId(); + if( sEventBaseElemId ) + { + var aEventBaseElem = document.getElementById( sEventBaseElemId ); + if( !aEventBaseElem ) + { + log( 'generateEvent: EVENT_TIMING: event base element not found: ' + sEventBaseElemId ); + return; + } + var aSourceEventElement = aNodeContext.makeSourceEventElement( sEventBaseElemId, aEventBaseElem ); + + var bEventRegistered = false; + switch( eEventType ) + { + case EVENT_TRIGGER_ON_CLICK: + aEventMultiplexer.registerEvent( eEventType, aSourceEventElement.getId(), aEvent ); + bEventRegistered = true; + break; + default: + log( 'generateEvent: not handled event type: ' + eEventType ); + } + if( bEventRegistered ) + aSourceEventElement.addEventListener( eEventType ); + } + else // no base event element present + { + switch( eEventType ) + { + case EVENT_TRIGGER_ON_NEXT_EFFECT: + aNextEffectEventArray.appendEvent( aEvent ); + break; + default: + log( 'generateEvent: not handled event type: ' + eEventType ); + } + } + break; + case SYNCBASE_TIMING: + var eEventType = aTiming.getEventType(); + var sEventBaseElemId = aTiming.getEventBaseElementId(); + if( sEventBaseElemId ) + { + var aAnimationNode = aNodeContext.aAnimationNodeMap[ sEventBaseElemId ]; + if( !aAnimationNode ) + { + log( 'generateEvent: SYNCBASE_TIMING: event base element not found: ' + sEventBaseElemId ); + return; + } + aEventMultiplexer.registerEvent( eEventType, aAnimationNode.getId(), aEvent ); + } + else + { + log( 'generateEvent: SYNCBASE_TIMING: event base element not specified' ); + } + break; + default: + log( 'generateEvent: not handled timing type: ' + eTimingType ); + } + } +} + +registerEvent.DEBUG = aRegisterEventDebugPrinter.isEnabled(); + +registerEvent.DBG = function( aTiming, nTime ) +{ + if( registerEvent.DEBUG ) + { + aRegisterEventDebugPrinter.print( 'registerEvent( timing: ' + aTiming.info() + ' )', nTime ); + } +}; + + + +// ------------------------------------------------------------------------------------------ // +function SourceEventElement( aElement, aEventMulyiplexer ) +{ + this.nId = getUniqueId(); + this.aElement = aElement; + this.aEventMultiplexer = aEventMulyiplexer; + this.aEventListenerStateArray = new Array(); +} + + +SourceEventElement.prototype.getId = function() +{ + return this.nId; +}; + +SourceEventElement.prototype.isEqualTo = function( aSourceEventElement ) +{ + return ( this.getId() == aSourceEventElement.getId() ); +}; + +SourceEventElement.prototype.onClick = function() +{ + aEventMulyiplexer.notifyClickEvent( this ); +}; + +SourceEventElement.prototype.isEventListenerRegistered = function( eEventType ) +{ + return this.aEventListenerStateArray[ eEventType ]; +}; + +SourceEventElement.prototype.addEventListener = function( eEventType ) +{ + if( !this.aElement ) + return false; + + this.aEventListenerStateArray[ eEventType ] = true; + switch( eEventType ) + { + case EVENT_TRIGGER_ON_CLICK: + this.aElement.addEventListener( 'click', this.onClick, false ); + break; + default: + log( 'SourceEventElement.addEventListener: not handled event type: ' + eEventType ); + return false; + } + return true; +}; + +SourceEventElement.prototype.removeEventListener = function( eEventType ) +{ + if( !this.aElement ) + return false; + + this.aEventListenerStateArray[ eEventType ] = false; + switch( eEventType ) + { + case EVENT_TRIGGER_ON_CLICK: + this.aElement.removeEventListener( 'click', this.onClick, false ); + break; + default: + log( 'SourceEventElement.removeEventListener: not handled event type: ' + eEventType ); + return false; + } + return true; +}; + + +// ------------------------------------------------------------------------------------------ // +function EventMultiplexer( aTimerEventQueue ) +{ + this.aTimerEventQueue = aTimerEventQueue; + this.aEventMap = new Object(); + +} + + +EventMultiplexer.prototype.registerEvent = function( eEventType, aNotifierId, aEvent ) +{ + this.DBG( 'registerEvent', eEventType, aNotifierId ); + if( !this.aEventMap[ eEventType ] ) + { + this.aEventMap[ eEventType ] = new Object(); + } + if( !this.aEventMap[ eEventType ][ aNotifierId ] ) + { + this.aEventMap[ eEventType ][ aNotifierId ] = new Array(); + } + this.aEventMap[ eEventType ][ aNotifierId ].push( aEvent ); +}; + + +EventMultiplexer.prototype.notifyEvent = function( eEventType, aNotifierId ) +{ + this.DBG( 'notifyEvent', eEventType, aNotifierId ); + if( this.aEventMap[ eEventType ] ) + { + if( this.aEventMap[ eEventType ][ aNotifierId ] ) + { + var aEventArray = this.aEventMap[ eEventType ][ aNotifierId ]; + var nSize = aEventArray.length; + for( var i = 0; i < nSize; ++i ) + { + this.aTimerEventQueue.addEvent( aEventArray[i] ); + } + } + } +}; + +EventMultiplexer.DEBUG = aEventMultiplexerDebugPrinter.isEnabled(); + +EventMultiplexer.prototype.DBG = function( sMethodName, eEventType, aNotifierId, nTime ) +{ + if( EventMultiplexer.DEBUG ) + { + var sInfo = 'EventMultiplexer.' + sMethodName; + sInfo += '( type: ' + aEventTriggerOutMap[ eEventType ]; + sInfo += ', notifier: ' + aNotifierId + ' )'; + aEventMultiplexerDebugPrinter.print( sInfo, nTime ); + } +}; + + + +/********************************************************************************************** + * Interpolator Handler and KeyStopLerp + **********************************************************************************************/ + +var aInterpolatorHandler = new Object(); + +aInterpolatorHandler.getInterpolator = function( eCalcMode, eValueType, eValueSubtype ) +{ + var bHasSubtype = ( typeof( eValueSubtype ) === typeof( 0 ) ); + + if( !bHasSubtype && aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ] ) + { + return aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ]; + } + else if( bHasSubtype && aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ][ eValueSubtype ] ) + { + return aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ][ eValueSubtype ]; + } + else + { + log( 'aInterpolatorHandler.getInterpolator: not found any valid interpolator for clalc mode ' + + aCalcModeOutMap[eCalcMode] + 'and value type ' + aValueTypeOutMap[eValueType] ); + return null; + } +}; + +aInterpolatorHandler.aLerpFunctorMap = new Array(); +aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_DISCRETE ] = new Array(); +aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ] = new Array(); + + +// interpolators for linear calculation + +aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ NUMBER_PROPERTY ] = + function ( nFrom, nTo, nT ) + { + return ( ( 1.0 - nT )* nFrom + nT * nTo ); + }; + +aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ COLOR_PROPERTY ] = new Array(); + +aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ COLOR_PROPERTY ][ COLOR_SPACE_RGB ] = + function ( nFrom, nTo, nT ) + { + return RGBColor.interpolate( nFrom, nTo, nT ); + }; + +// For HSLColor we do not return the interpolator but a function +// that generate the interpolator. The AnimationColorNode is 'aware' of that. +aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ COLOR_PROPERTY ][ COLOR_SPACE_HSL ] = + function ( bCCW ) + { + return function ( nFrom, nTo, nT ) + { + return HSLColor.interpolate( nFrom, nTo, nT, bCCW ); + }; + }; + + + +// ------------------------------------------------------------------------------------------ // +function KeyStopLerp( aValueList ) +{ + KeyStopLerp.validateInput( aValueList ); + + this.aKeyStopList = new Array(); + this.nLastIndex = 0; + this.nKeyStopDistance = aValueList[1] - aValueList[0]; + if( this.nKeyStopDistance <= 0 ) + this.nKeyStopDistance = 0.001; + + for( var i = 0; i < aValueList.length; ++i ) + this.aKeyStopList.push( aValueList[i] ); + + this.nUpperBoundIndex = this.aKeyStopList.length - 2; +} + + +KeyStopLerp.validateInput = function( aValueList ) +{ + var nSize = aValueList.length; + assert( nSize > 1, 'KeyStopLerp.validateInput: key stop vector must have two entries or more' ); + + for( var i = 1; i < nSize; ++i ) + { + if( aValueList[i-1] > aValueList[i] ) + log( 'KeyStopLerp.validateInput: time vector is not sorted in ascending order!' ); + } +}; + +KeyStopLerp.prototype.reset = function() +{ + KeyStopLerp.validateInput( this.aKeyStopList ); + this.nLastIndex = 0; + this.nKeyStopDistance = this.aKeyStopList[1] - this.aKeyStopList[0]; + if( this.nKeyStopDistance <= 0 ) + this.nKeyStopDistance = 0.001; + +}; + +KeyStopLerp.prototype.lerp = function( nAlpha ) +{ + if( nAlpha > this.aKeyStopList[ this.nLastIndex + 1 ] ) + { + do + { + var nIndex = this.nLastIndex + 1; + this.nLastIndex = clamp( nIndex, 0, this.nUpperBoundIndex ); + this.nKeyStopDistance = this.aKeyStopList[ this.nLastIndex + 1 ] - this.aKeyStopList[ this.nLastIndex ]; + } + while( ( this.nKeyStopDistance <= 0 ) && ( this.nLastIndex < this.nUpperBoundIndex ) ); + } + + var nRawLerp = ( nAlpha - this.aKeyStopList[ this.nLastIndex ] ) / this.nKeyStopDistance; + + nRawLerp = clamp( nRawLerp, 0.0, 1.0 ); + + var aResult = new Object(); + aResult.nIndex = this.nLastIndex; + aResult.nLerp = nRawLerp; + + return aResult; +}; + +KeyStopLerp.prototype.lerp_ported = function( nAlpha ) +{ + if( ( this.aKeyStopList[ this.nLastIndex ] < nAlpha ) || + ( this.aKeyStopList[ this.nLastIndex + 1 ] >= nAlpha ) ) + { + var i = 0; + for( ; i < this.aKeyStopList.length; ++i ) + { + if( this.aKeyStopList[i] >= nAlpha ) + break; + } + if( this.aKeyStopList[i] > nAlpha ) + --i; + var nIndex = i - 1; + this.nLastIndex = clamp( nIndex, 0, this.aKeyStopList.length - 2 ); + } + + var nRawLerp = ( nAlpha - this.aKeyStopList[ this.nLastIndex ] ) / + ( this.aKeyStopList[ this.nLastIndex+1 ] - this.aKeyStopList[ this.nLastIndex ] ); + + nRawLerp = clamp( nRawLerp, 0.0, 1.0 ); + + var aResult = new Object(); + aResult.nIndex = this.nLastIndex; + aResult.nLerp = nRawLerp; + + return aResult; +}; + + + +/********************************************************************************************** + * Operators + **********************************************************************************************/ + +var aOperatorSetMap = new Array(); + +// number operators +aOperatorSetMap[ NUMBER_PROPERTY ] = new Object(); + +aOperatorSetMap[ NUMBER_PROPERTY ].add = function( a, b ) +{ + return ( a + b ); +}; + +aOperatorSetMap[ NUMBER_PROPERTY ].scale = function( k, v ) +{ + return ( k * v ); +}; + +// color operators +aOperatorSetMap[ COLOR_PROPERTY ] = new Object(); + +aOperatorSetMap[ COLOR_PROPERTY ].add = function( a, b ) +{ + var c = a.clone(); + c.add( b ); + return c; +}; + +aOperatorSetMap[ COLOR_PROPERTY ].scale = function( k, v ) +{ + var r = v.clone(); + r.scale( k ); + return r; +}; + + + +/********************************************************************************************** + * Activity Class Hierarchy + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // +function ActivityParamSet() +{ + this.aEndEvent = null; + this.aTimerEventQueue = null; + this.aActivityQueue = null; + this.nRepeatCount = 1.0; + this.nAccelerationFraction = 0.0; + this.nDecelerationFraction = 0.0; + this.bAutoReverse = false; + this.nMinDuration = undefined; + this.nMinNumberOfFrames = MINIMUM_FRAMES_PER_SECONDS; + this.aDiscreteTimes = new Array(); +} + +// ------------------------------------------------------------------------------------------ // +function AnimationActivity() +{ + this.nId = AnimationActivity.getUniqueId(); +} + + +AnimationActivity.CURR_UNIQUE_ID = 0; + +AnimationActivity.getUniqueId = function() +{ + ++AnimationActivity.CURR_UNIQUE_ID; + return AnimationActivity.CURR_UNIQUE_ID; +}; + +AnimationActivity.prototype.getId = function() +{ + return this.nId; +}; + + + +// ------------------------------------------------------------------------------------------ // +function SetActivity( aCommonParamSet, aAnimation, aToAttr ) +{ + SetActivity.superclass.constructor.call( this ); + + this.aAnimation = aAnimation; + this.aTargetElement = null; + this.aEndEvent = aCommonParamSet.aEndEvent; + this.aTimerEventQueue = aCommonParamSet.aTimerEventQueue; + this.aToAttr = aToAttr; + this.bIsActive = true; +} +extend( SetActivity, AnimationActivity ); + + +SetActivity.prototype.activate = function( aEndEvent ) +{ + this.aEndEvent = aEndEvent; + this.bIsActive = true; +}; + +SetActivity.prototype.dispose = function() +{ + this.bIsActive = false; + if( this.aEndEvent && this.aEndEvent.isCharged() ) + this.aEndEvent.dispose(); +}; + +SetActivity.prototype.calcTimeLag = function() +{ + return 0.0; +}; + +SetActivity.prototype.perform = function() +{ + if( !this.isActive() ) + return false; + + // we're going inactive immediately: + this.bIsActive = false; + + if( this.aAnimation && this.aTargetElement ) + { + this.aAnimation.start( this.aTargetElement ); + this.aAnimation.perform( this.aToAttr ); + this.aAnimation.end(); + } + + if( this.aEndEvent ) + this.aTimerEventQueue.addEvent( this.aEndEvent ); + + }; + + SetActivity.prototype.isActive = function() + { + return this.bIsActive; + }; + + SetActivity.prototype.dequeued = function() + { + // empty body +}; + +SetActivity.prototype.end = function() +{ + this.perform(); +}; + +SetActivity.prototype.setTargets = function( aTargetElement ) +{ + assert( aTargetElement, 'SetActivity.setTargets: target element is not valid' ); + this.aTargetElement = aTargetElement; +}; + + + +// ------------------------------------------------------------------------------------------ // + function ActivityBase( aCommonParamSet ) + { + ActivityBase.superclass.constructor.call( this ); + + this.aTargetElement = null; + this.aEndEvent = aCommonParamSet.aEndEvent; + this.aTimerEventQueue = aCommonParamSet.aTimerEventQueue; + this.nRepeats = aCommonParamSet.nRepeatCount; + this.nAccelerationFraction = aCommonParamSet.nAccelerationFraction; + this.nDecelerationFraction = aCommonParamSet.nDecelerationFraction; + this.bAutoReverse = aCommonParamSet.bAutoReverse; + + this.bFirstPerformCall = true; + this.bIsActive = true; + + } + extend( ActivityBase, AnimationActivity ); + + + ActivityBase.prototype.activate = function( aEndEvent ) + { + this.aEndEvent = aEndEvent; + this.bFirstPerformCall = true; + this.bIsActive = true; + }; + + ActivityBase.prototype.dispose = function() + { + // deactivate + this.bIsActive = false; + + // dispose event + if( this.aEndEvent ) + this.aEndEvent.dispose(); + + this.aEndEvent = null; +}; + +ActivityBase.prototype.perform = function() +{ + // still active? + if( !this.isActive() ) + return false; // no, early exit. + + assert( !this.FirstPerformCall, 'ActivityBase.perform: assertion (!this.FirstPerformCall) failed' ); + + return true; +}; + +ActivityBase.prototype.calcTimeLag = function() +{ + // TODO(Q1): implement different init process! + if( this.isActive() && this.bFirstPerformCall ) + { + this.bFirstPerformCall = false; + + // notify derived classes that we're + // starting now + this.startAnimation(); + } + return 0.0; +}; + +ActivityBase.prototype.isActive = function() +{ + return this.bIsActive; +}; + +ActivityBase.prototype.isDisposed = function() +{ + return ( !this.bIsActive && !this.aEndEvent ); +}; + +ActivityBase.prototype.dequeued = function() +{ + if( !this.isActive() ) + this.endAnimation(); +}; + +ActivityBase.prototype.setTargets = function( aTargetElement ) +{ + assert( aTargetElement, 'ActivityBase.setTargets: target element is not valid' ); + + this.aTargetElement = aTargetElement; +}; + +ActivityBase.prototype.startAnimation = function() +{ + throw ( 'ActivityBase.startAnimation: abstract method invoked' ); +}; + +ActivityBase.prototype.endAnimation = function() +{ + throw ( 'ActivityBase.endAnimation: abstract method invoked' ); +}; + +ActivityBase.prototype.endActivity = function() +{ + // this is a regular activity end + this.bIsActive = false; + + // Activity is ending, queue event, then + if( this.aEndEvent ) + this.aTimerEventQueue.addEvent( this.aEndEvent ); + + this.aEndEvent = null; + +}; + +ActivityBase.prototype.calcAcceleratedTime = function( nT ) +{ + // Handle acceleration/deceleration + + + // clamp nT to permissible [0,1] range + nT = clamp( nT, 0.0, 1.0 ); + + // take acceleration/deceleration into account. if the sum + // of nAccelerationFraction and nDecelerationFraction + // exceeds 1.0, ignore both (that's according to SMIL spec) + if( ( this.nAccelerationFraction > 0.0 || this.nDecelerationFraction > 0.0 ) && + ( this.nAccelerationFraction + this.nDecelerationFraction <= 1.0 ) ) + { + var nC = 1.0 - 0.5*this.nAccelerationFraction - 0.5*this.nDecelerationFraction; + + // this variable accumulates the new time value + var nTPrime = 0.0; + + if( nT < this.nAccelerationFraction ) + { + nTPrime += 0.5 * nT * nT / this.nAccelerationFraction; // partial first interval + } + else + { + nTPrime += 0.5 * this.nAccelerationFraction; // full first interval + + if( nT <= ( 1.0 - this.nDecelerationFraction ) ) + { + nTPrime += nT - this.nAccelerationFraction; // partial second interval + } + else + { + nTPrime += 1.0 - this.nAccelerationFraction - this.nDecelerationFraction; // full second interval + + var nTRelative = nT - 1.0 + this.nDecelerationFraction; + + nTPrime += nTRelative - 0.5*nTRelative*nTRelative / this.nDecelerationFraction; + } + } + + // normalize, and assign to work variable + nT = nTPrime / nC; + + } + return nT; +}; + +ActivityBase.prototype.getEventQueue = function() +{ + return this.aTimerEventQueue; +}; + +ActivityBase.prototype.getTargetElement = function() +{ + return this.aTargetElement; +}; + +ActivityBase.prototype.isRepeatCountValid = function() +{ + if( this.nRepeats ) + return true; + else + return false; +}; + +ActivityBase.prototype.getRepeatCount = function() +{ + return this.nRepeats; +}; + +ActivityBase.prototype.isAutoReverse = function() +{ + return this.bAutoReverse; +}; + +ActivityBase.prototype.end = function() +{ + if( !this.isActive() || this.isDisposed() ) + return; + + // assure animation is started: + if( this.bFirstPerformCall ) + { + this.bFirstPerformCall = false; + // notify derived classes that we're starting now + this.startAnimation(); + } + + this.performEnd(); + this.endAnimation(); + this.endActivity(); +}; + +ActivityBase.prototype.performEnd = function() +{ + throw ( 'ActivityBase.performEnd: abstract method invoked' ); + }; + + + + // ------------------------------------------------------------------------------------------ // +function SimpleContinuousActivityBase( aCommonParamSet ) +{ + SimpleContinuousActivityBase.superclass.constructor.call( this, aCommonParamSet ); + + // Time elapsed since activity started + this.aTimer = new ElapsedTime( aCommonParamSet.aActivityQueue.getTimer() ); + // Simple duration of activity + this.nMinSimpleDuration = aCommonParamSet.nMinDuration; + // Minimal number of frames to show + this.nMinNumberOfFrames = aCommonParamSet.nMinNumberOfFrames; + // Actual number of frames shown until now. + this.nCurrPerformCalls = 0; + +} +extend( SimpleContinuousActivityBase, ActivityBase ); + + +SimpleContinuousActivityBase.prototype.startAnimation = function() +{ + // init timer. We measure animation time only when we're + // actually started. + this.aTimer.reset(); + +}; + +SimpleContinuousActivityBase.prototype.calcTimeLag = function() +{ + SimpleContinuousActivityBase.superclass.calcTimeLag.call( this ); + + if( !this.isActive() ) + return 0.0; + + // retrieve locally elapsed time + var nCurrElapsedTime = this.aTimer.getElapsedTime(); + + // go to great length to ensure a proper animation + // run. Since we don't know how often we will be called + // here, try to spread the animator calls uniquely over + // the [0,1] parameter range. Be aware of the fact that + // perform will be called at least mnMinNumberOfTurns + // times. + + // fraction of time elapsed + var nFractionElapsedTime = nCurrElapsedTime / this.nMinSimpleDuration; + + // fraction of minimum calls performed + var nFractionRequiredCalls = this.nCurrPerformCalls / this.nMinNumberOfFrames; + + // okay, so now, the decision is easy: + // + // If the fraction of time elapsed is smaller than the + // number of calls required to be performed, then we calc + // the position on the animation range according to + // elapsed time. That is, we're so to say ahead of time. + // + // In contrary, if the fraction of time elapsed is larger, + // then we're lagging, and we thus calc the position on + // the animation time line according to the fraction of + // calls performed. Thus, the animation is forced to slow + // down, and take the required minimal number of steps, + // sufficiently equally distributed across the animation + // time line. + + if( nFractionElapsedTime < nFractionRequiredCalls ) + { + return 0.0; + } + else + { + // lag global time, so all other animations lag, too: + return ( ( nFractionElapsedTime - nFractionRequiredCalls ) * this.nMinSimpleDuration ); + } +}; + +SimpleContinuousActivityBase.prototype.perform = function() +{ + // call base class, for start() calls and end handling + if( !SimpleContinuousActivityBase.superclass.perform.call( this ) ) + return false; // done, we're ended + + // get relative animation position + var nCurrElapsedTime = this.aTimer.getElapsedTime(); + var nT = nCurrElapsedTime / this.nMinSimpleDuration; + + + // one of the stop criteria reached? + + // will be set to true below, if one of the termination criteria matched. + var bActivityEnding = false; + + if( this.isRepeatCountValid() ) + { + // Finite duration case + + // When we've autoreverse on, the repeat count doubles + var nRepeatCount = this.getRepeatCount(); + var nEffectiveRepeat = this.isAutoReverse() ? 2.0 * nRepeatCount : nRepeatCount; + + // time (or frame count) elapsed? + if( nEffectiveRepeat <= nT ) + { + // Ok done for now. Will not exit right here, + // to give animation the chance to render the last + // frame below + bActivityEnding = true; + + // clamp animation to max permissible value + nT = nEffectiveRepeat; + } + } + + + // need to do auto-reverse? + + var nRepeats; + var nRelativeSimpleTime; + // TODO(Q3): Refactor this mess + if( this.isAutoReverse() ) + { + // divert active duration into repeat and + // fractional part. + nRepeats = Math.floor( nT ); + var nFractionalActiveDuration = nT - nRepeats; + + // for auto-reverse, map ranges [1,2), [3,4), ... + // to ranges [0,1), [1,2), etc. + if( nRepeats % 2 ) + { + // we're in an odd range, reverse sweep + nRelativeSimpleTime = 1.0 - nFractionalActiveDuration; + } + else + { + // we're in an even range, pass on as is + nRelativeSimpleTime = nFractionalActiveDuration; + } + + // effective repeat count for autoreverse is half of + // the input time's value (each run of an autoreverse + // cycle is half of a repeat) + nRepeats /= 2; + } + else + { + // determine repeat + + // calc simple time and number of repeats from nT + // Now, that's easy, since the fractional part of + // nT gives the relative simple time, and the + // integer part the number of full repeats: + nRepeats = Math.floor( nT ); + nRelativeSimpleTime = nT - nRepeats; + + // clamp repeats to max permissible value (maRepeats.getValue() - 1.0) + if( this.isRepeatCountValid() && ( nRepeats >= this.getRepeatCount() ) ) + { + // Note that this code here only gets + // triggered if this.nRepeats is an + // _integer_. Otherwise, nRepeats will never + // reach nor exceed + // maRepeats.getValue(). Thus, the code below + // does not need to handle cases of fractional + // repeats, and can always assume that a full + // animation run has ended (with + // nRelativeSimpleTime = 1.0 for + // non-autoreversed activities). + + // with modf, nRelativeSimpleTime will never + // become 1.0, since nRepeats is incremented and + // nRelativeSimpleTime set to 0.0 then. + // + // For the animation to reach its final value, + // nRepeats must although become this.nRepeats - 1.0, + // and nRelativeSimpleTime = 1.0. + nRelativeSimpleTime = 1.0; + nRepeats -= 1.0; + } + } + + + // actually perform something + + this.simplePerform( nRelativeSimpleTime, nRepeats ); + + // delayed endActivity() call from end condition check + // below. Issued after the simplePerform() call above, to + // give animations the chance to correctly reach the + // animation end value, without spurious bail-outs because + // of isActive() returning false. + if( bActivityEnding ) + this.endActivity(); + + // one more frame successfully performed + ++this.nCurrPerformCalls; + + return this.isActive(); +}; + +SimpleContinuousActivityBase.prototype.simplePerform = function( nSimpleTime, nRepeatCount ) +{ + throw ( 'SimpleContinuousActivityBase.simplePerform: abstract method invoked' ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function ContinuousKeyTimeActivityBase( aCommonParamSet ) +{ + var nSize = aCommonParamSet.aDiscreteTimes.length; + assert( nSize > 1, + 'ContinuousKeyTimeActivityBase constructor: assertion (aDiscreteTimes.length > 1) failed' ); + + assert( aCommonParamSet.aDiscreteTimes[0] == 0.0, + 'ContinuousKeyTimeActivityBase constructor: assertion (aDiscreteTimes.front() == 0.0) failed' ); + + assert( aCommonParamSet.aDiscreteTimes[ nSize - 1 ] <= 1.0, + 'ContinuousKeyTimeActivityBase constructor: assertion (aDiscreteTimes.back() <= 1.0) failed' ); + + ContinuousKeyTimeActivityBase.superclass.constructor.call( this, aCommonParamSet ); + + this.aLerper = new KeyStopLerp( aCommonParamSet.aDiscreteTimes ); +} +extend( ContinuousKeyTimeActivityBase, SimpleContinuousActivityBase ); + + +ContinuousKeyTimeActivityBase.prototype.activate = function( aEndElement ) +{ + ContinuousKeyTimeActivityBase.superclass.activate.call( this, aEndElement ); + + this.aLerper.reset(); +}; + +ContinuousKeyTimeActivityBase.prototype.performHook = function( nIndex, nFractionalIndex, nRepeatCount ) +{ + throw ( 'ContinuousKeyTimeActivityBase.performHook: abstract method invoked' ); +}; + +ContinuousKeyTimeActivityBase.prototype.simplePerform = function( nSimpleTime, nRepeatCount ) +{ + var nAlpha = this.calcAcceleratedTime( nSimpleTime ); + + var aLerpResult = this.aLerper.lerp( nAlpha ); + + this.performHook( aLerpResult.nIndex, aLerpResult.nLerp, nRepeatCount ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function ContinuousActivityBase( aCommonParamSet ) +{ + ContinuousActivityBase.superclass.constructor.call( this, aCommonParamSet ); + +} +extend( ContinuousActivityBase, SimpleContinuousActivityBase ); + + +ContinuousActivityBase.prototype.performHook = function( nModifiedTime, nRepeatCount ) +{ + throw ( 'ContinuousActivityBase.performHook: abstract method invoked' ); +}; + +ContinuousActivityBase.prototype.simplePerform = function( nSimpleTime, nRepeatCount ) +{ + this.performHook( this.calcAcceleratedTime( nSimpleTime ), nRepeatCount ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function SimpleActivity( aCommonParamSet, aNumberAnimation, eDirection ) +{ + assert( ( eDirection == BACKWARD ) || ( eDirection == FORWARD ), + 'SimpleActivity constructor: animation direction is not valid' ); + + assert( aNumberAnimation, 'SimpleActivity constructor: animation object is not valid' ); + + SimpleActivity.superclass.constructor.call( this, aCommonParamSet ); + + this.aAnimation = aNumberAnimation; + this.nDirection = ( eDirection == FORWARD ) ? 1.0 : 0.0; +} +extend( SimpleActivity, ContinuousActivityBase ); + + +SimpleActivity.prototype.startAnimation = function() +{ + if( this.isDisposed() || !this.aAnimation ) + return; + + ANIMDBG.print( 'SimpleActivity.startAnimation invoked' ); + SimpleActivity.superclass.startAnimation.call( this ); + + // start animation + this.aAnimation.start( this.getTargetElement() ); + }; + + SimpleActivity.prototype.endAnimation = function() + { + if( this.aAnimation ) + this.aAnimation.end(); + + }; + + SimpleActivity.prototype.performHook = function( nModifiedTime, nRepeatCount ) + { + // nRepeatCount is not used + + if( this.isDisposed() || !this.aAnimation ) + return; + + var nT = 1.0 - this.nDirection + nModifiedTime * ( 2.0*this.nDirection - 1.0 ); + //ANIMDBG.print( 'SimpleActivity.performHook: nT = ' + nT ); + this.aAnimation.perform( nT ); +}; + +SimpleActivity.prototype.performEnd = function() +{ + if( this.aAnimation ) + this.aAnimation.perform( this.nDirection ); +}; + + + +// ------------------------------------------------------------------------------------------ // +// FromToByActivity< BaseType > template class + + +function FromToByActivityTemplate( BaseType ) // template parameter +{ + + function FromToByActivity( aFromValue, aToValue, aByValue, + aActivityParamSet, aAnimation, + aInterpolator, aOperatorSet, bAccumulate ) + { + assert( aAnimation, 'FromToByActivity constructor: invalid animation object' ); + assert( ( aToValue != undefined ) || ( aByValue != undefined ), + 'FromToByActivity constructor: one of aToValue or aByValue must be valid' ); + + FromToByActivity.superclass.constructor.call( this, aActivityParamSet ); + + this.aFrom = aFromValue; + this.aTo = aToValue; + this.aBy = aByValue; + this.aStartValue; + this.aEndValue; + this.aAnimation = aAnimation; + this.aInterpolator = aInterpolator; + this.add = aOperatorSet.add; + this.scale = aOperatorSet.scale; + this.bDynamicStartValue = false; + this.bCumulative = bAccumulate; + + this.initAnimatedElement(); + + } + extend( FromToByActivity, BaseType ); + + FromToByActivity.prototype.initAnimatedElement = function() + { + if( this.aAnimation && this.aFrom ) + this.aAnimation.perform( this.aFrom ); + }; + + FromToByActivity.prototype.startAnimation = function() + { + if( this.isDisposed() || !this.aAnimation ) + { + log( 'FromToByActivity.startAnimation: activity disposed or not valid animation' ); + return; + } + + FromToByActivity.superclass.startAnimation.call( this ); + + this.aAnimation.start( this.getTargetElement() ); + + + var aAnimationStartValue = this.aAnimation.getUnderlyingValue(); + + // first of all, determine general type of + // animation, by inspecting which of the FromToBy values + // are actually valid. + // See http://www.w3.org/TR/smil20/animation.html#AnimationNS-FromToBy + // for a definition + if( this.aFrom ) + { + // From-to or From-by animation. According to + // SMIL spec, the To value takes precedence + // over the By value, if both are specified + if( this.aTo ) + { + // From-To animation + this.aStartValue = this.aFrom; + this.aEndValue = this.aTo; + } + else if( this.aBy ) + { + // From-By animation + this.aStartValue = this.aFrom; + + // this.aEndValue = this.aStartValue + this.aBy; + this.aEndValue = this.add( this.aStartValue, this.aBy ); + } + } + else + { + // By or To animation. According to SMIL spec, + // the To value takes precedence over the By + // value, if both are specified + if( this.aTo ) + { + // To animation + + // According to the SMIL spec + // (http://www.w3.org/TR/smil20/animation.html#animationNS-ToAnimation), + // the to animation interpolates between + // the _running_ underlying value and the to value (as the end value) + this.bDynamicStartValue = true; + this.aEndValue = this.aTo; + } + else if( this.aBy ) + { + // By animation + this.aStartValue = aAnimationStartValue; + + // this.aEndValue = this.aStartValue + this.aBy; + this.aEndValue = this.add( this.aStartValue, this.aBy ); + } + } + + ANIMDBG.print( 'FromToByActivity.startAnimation: aStartValue = ' + this.aStartValue + ', aEndValue = ' + this.aEndValue ); + }; + + FromToByActivity.prototype.endAnimation = function() + { + if( this.aAnimation ) + this.aAnimation.end(); + }; + + // performHook override for ContinuousActivityBase + FromToByActivity.prototype.performHook = function( nModifiedTime, nRepeatCount ) + { + if( this.isDisposed() || !this.aAnimation ) + { + log( 'FromToByActivity.performHook: activity disposed or not valid animation' ); + return; + } + + var aValue = this.bDynamicStartValue ? this.aAnimation.getUnderlyingValue() + : this.aStartValue; + + aValue = this.aInterpolator( aValue, this.aEndValue, nModifiedTime ); + + if( this.bCumulative ) + { + // aValue = this.aEndValue * nRepeatCount + aValue; + aValue = this.add( this.scale( nRepeatCount, this.aEndValue ), aValue ); + } + + this.aAnimation.perform( aValue ); + }; + + FromToByActivity.prototype.performEnd = function() + { + if( this.aAnimation ) + { + if( this.isAutoreverse() ) + this.aAnimation.perform( this.aStartValue ); + else + this.aAnimation.perform( this.aEndValue ); + } + }; + + FromToByActivity.prototype.dispose = function() + { + FromToByActivity.superclass.dispose.call( this ); + }; + + + return FromToByActivity; +} + + +// FromToByActivity< ContinuousActivityBase > instantiation +var LinearFromToByActivity = instantiate( FromToByActivityTemplate, ContinuousActivityBase ); + + + +// ------------------------------------------------------------------------------------------ // +// ValueListActivity< BaseType > template class + + +function ValueListActivityTemplate( BaseType ) // template parameter +{ + + function ValueListActivity( aValueList, aActivityParamSet, + aAnimation, aInterpolator, + aOperatorSet, bAccumulate ) + { + assert( aAnimation, 'ValueListActivity constructor: invalid animation object' ); + assert( aValueList.length != 0, 'ValueListActivity: value list is empty' ); + + ValueListActivity.superclass.constructor.call( this, aActivityParamSet ); + + this.aValueList = aValueList; + this.aAnimation = aAnimation; + this.aInterpolator = aInterpolator; + this.add = aOperatorSet.add; + this.scale = aOperatorSet.scale; + this.bCumulative = bAccumulate; + this.aLastValue = this.aValueList[ this.aValueList.length - 1 ]; + + this.initAnimatedElement(); + } + extend( ValueListActivity, BaseType ); + + ValueListActivity.prototype.activate = function( aEndEvent ) + { + ValueListActivity.superclass.activate.call( this, aEndEvent ); + for( var i = 0; i < this.aValueList.length; ++i ) + { + ANIMDBG.print( 'createValueListActivity: value[' + i + '] = ' + this.aValueList[i] ); + } + + this.initAnimatedElement(); + }; + + ValueListActivity.prototype.initAnimatedElement = function() + { + if( this.aAnimation ) + this.aAnimation.perform( this.aValueList[0] ); + }; + + ValueListActivity.prototype.startAnimation = function() + { + if( this.isDisposed() || !this.aAnimation ) + { + log( 'ValueListActivity.startAnimation: activity disposed or not valid animation' ); + return; + } + + ValueListActivity.superclass.startAnimation.call( this ); + + this.aAnimation.start( this.getTargetElement() ); + }; + + ValueListActivity.prototype.endAnimation = function() + { + if( this.aAnimation ) + this.aAnimation.end(); + }; + + // performHook override for ContinuousKeyTimeActivityBase base + ValueListActivity.prototype.performHook = function( nIndex, nFractionalIndex, nRepeatCount ) + { + if( this.isDisposed() || !this.aAnimation ) + { + log( 'ValueListActivity.performHook: activity disposed or not valid animation' ); + return; + } + + assert( ( nIndex + 1 ) < this.aValueList.length, + 'ValueListActivity.performHook: assertion (nIndex + 1 < this.aValueList.length) failed' ); + + // interpolate between nIndex and nIndex+1 values + + var aValue = this.aInterpolator( this.aValueList[ nIndex ], + this.aValueList[ nIndex+1 ], + nFractionalIndex ); + + if( this.bCumulative ) + { + aValue = this.add( aValue, this.scale( nRepeatCount, this.aLastValue ) ); + //aValue = aValue + nRepeatCount * this.aLastValue; + } + this.aAnimation.perform( aValue ); + }; + + ValueListActivity.prototype.performEnd = function() + { + if( this.aAnimation ) + { + this.aAnimation.perform( this.aLastValue ); + } + }; + + ValueListActivity.prototype.dispose = function() + { + ValueListActivity.superclass.dispose.call( this ); + }; + + + return ValueListActivity; +} + + +// ValueListActivity< ContinuousKeyTimeActivityBase > instantiation +var LinearValueListActivity = instantiate( ValueListActivityTemplate, ContinuousKeyTimeActivityBase ); + + + +/********************************************************************************************** + * Activity Factory + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // +function createActivity( aActivityParamSet, aAnimationNode, aAnimation, aInterpolator ) +{ + var eCalcMode = aAnimationNode.getCalcMode(); + + var sAttributeName = aAnimationNode.getAttributeName(); + var aAttributeProp = aAttributeMap[ sAttributeName ]; + + var eValueType = aAttributeProp[ 'type' ]; + var eValueSubtype = aAttributeProp[ 'subtype' ]; + + // do we need to get an interpolator ? + if( ! aInterpolator ) + { + aInterpolator = aInterpolatorHandler.getInterpolator( eCalcMode, + eValueType, + eValueSubtype ); + } + + // is it cumulative ? + var bAccumulate = ( aAnimationNode.getAccumulate() === ACCUMULATE_MODE_SUM ) + && !( eValueType === BOOL_PROPERTY || + eValueType === STRING_PROPERTY || + eValueType === ENUM_PROPERTY ); + + + + aActivityParamSet.aDiscreteTimes = aAnimationNode.getKeyTimes(); + + // do we have a value list ? + var aValueSet = aAnimationNode.getValues(); + var nValueSetSize = aValueSet.length; + + if( nValueSetSize != 0 ) + { + // Value list activity + + if( aActivityParamSet.aDiscreteTimes.length == 0 ) + { + for( var i = 0; i < nValueSetSize; ++i ) + aActivityParamSet.aDiscreteTimes[i].push( i / nValueSetSize ); + } + + switch( eCalcMode ) + { + case CALC_MODE_DISCRETE: + log( 'createActivity: discrete calculation case not yet implemented' ); + break; + + default: + log( 'createActivity: unexpected calculation mode: ' + eCalcMode ); + // FALLTHROUGH intended + case CALC_MODE_PACED : + // FALLTHROUGH intended + case CALC_MODE_SPLINE : + // FALLTHROUGH intended + case CALC_MODE_LINEAR: + return createValueListActivity( aActivityParamSet, + aAnimationNode, + aAnimation, + aInterpolator, + LinearValueListActivity, + bAccumulate, + eValueType ); + } + } + else + { + // FromToBy activity + + switch( eCalcMode ) + { + case CALC_MODE_DISCRETE: + log( 'createActivity: discrete calculation case not yet implemented' ); + break; + + default: + log( 'createActivity: unexpected calculation mode: ' + eCalcMode ); + // FALLTHROUGH intended + case CALC_MODE_PACED : + // FALLTHROUGH intended + case CALC_MODE_SPLINE : + // FALLTHROUGH intended + case CALC_MODE_LINEAR: + return createFromToByActivity( aActivityParamSet, + aAnimationNode, + aAnimation, + aInterpolator, + LinearFromToByActivity, + bAccumulate, + eValueType ); + } + } +} + + + +// ------------------------------------------------------------------------------------------ // +function createValueListActivity( aActivityParamSet, aAnimationNode, aAnimation, + aInterpolator, ClassTemplateInstance, bAccumulate, eValueType ) +{ + var aAnimatedElement = aAnimationNode.getAnimatedElement(); + var aOperatorSet = aOperatorSetMap[ eValueType ]; + assert( aOperatorSet, 'createFromToByActivity: no operator set found' ); + + var aValueSet = aAnimationNode.getValues(); + + var aValueList = new Array(); + + extractAttributeValues( eValueType, + aValueList, + aValueSet, + aAnimatedElement.getBaseBBox(), + aActivityParamSet.nSlideWidth, + aActivityParamSet.nSlideHeight ); + + for( var i = 0; i < aValueList.length; ++i ) + { + ANIMDBG.print( 'createValueListActivity: value[' + i + '] = ' + aValueList[i] ); + } + + return new ClassTemplateInstance( aValueList, aActivityParamSet, aAnimation, + aInterpolator, aOperatorSet, bAccumulate ); +} + + + +// ------------------------------------------------------------------------------------------ // +function createFromToByActivity( aActivityParamSet, aAnimationNode, aAnimation, + aInterpolator, ClassTemplateInstance, bAccumulate, eValueType ) +{ + + var aAnimatedElement = aAnimationNode.getAnimatedElement(); + var aOperatorSet = aOperatorSetMap[ eValueType ]; + assert( aOperatorSet, 'createFromToByActivity: no operator set found' ); + + var aValueSet = new Array(); + aValueSet[0] = aAnimationNode.getFromValue(); + aValueSet[1] = aAnimationNode.getToValue(); + aValueSet[2] = aAnimationNode.getByValue(); + + ANIMDBG.print( 'createFromToByActivity: value type: ' + aValueTypeOutMap[eValueType] + + ', aFrom = ' + aValueSet[0] + + ', aTo = ' + aValueSet[1] + + ', aBy = ' + aValueSet[2] ); + + var aValueList = new Array(); + + extractAttributeValues( eValueType, + aValueList, + aValueSet, + aAnimatedElement.getBaseBBox(), + aActivityParamSet.nSlideWidth, + aActivityParamSet.nSlideHeight ); + + ANIMDBG.print( 'createFromToByActivity: ' + + ', aFrom = ' + aValueList[0] + + ', aTo = ' + aValueList[1] + + ', aBy = ' + aValueList[2] ); + + return new ClassTemplateInstance( aValueList[0], aValueList[1], aValueList[2], + aActivityParamSet, aAnimation, + aInterpolator, aOperatorSet, bAccumulate ); +} + + +// ------------------------------------------------------------------------------------------ // +function extractAttributeValues( eValueType, aValueList, aValueSet, aBBox, nSlideWidth, nSlideHeight ) +{ + switch( eValueType ) + { + case NUMBER_PROPERTY : + evalValuesAttribute( aValueList, aValueSet, aBBox, nSlideWidth, nSlideHeight ); + break; + case BOOL_PROPERTY : + for( var i = 0; i < aValueSet.length; ++i ) + { + var aValue = booleanParser( aValueSet[i] ); + aValueList.push( aValue ); + } + break; + case STRING_PROPERTY : + for( var i = 0; i < aValueSet.length; ++i ) + { + aValueList.push( aValueSet[i] ); + } + break; + case ENUM_PROPERTY : + for( var i = 0; i < aValueSet.length; ++i ) + { + aValueList.push( aValueSet[i] ); + } + break; + case COLOR_PROPERTY : + for( var i = 0; i < aValueSet.length; ++i ) + { + var aValue = colorParser( aValueSet[i] ); + aValueList.push( aValue ); + } + break; + default: + log( 'createValueListActivity: unexpeded value type: ' + eValueType ); + } + +} + +// ------------------------------------------------------------------------------------------ // +function evalValuesAttribute( aValueList, aValueSet, aBBox, nSlideWidth, nSlideHeight ) +{ + var width = aBBox.width / nSlideWidth; + var height = aBBox.height / nSlideHeight; + var x = ( aBBox.x + aBBox.width / 2 ) / nSlideWidth; + var y = ( aBBox.y + aBBox.height / 2 ) / nSlideHeight; + + for( var i = 0; i < aValueSet.length; ++i ) + { + var aValue = eval( aValueSet[i] ); + aValueList.push( aValue ); + } +} + + + +/********************************************************************************************** + * SlideShow, SlideShowContext and FrameSynchronization + **********************************************************************************************/ + +// ------------------------------------------------------------------------------------------ // + +// direction of animation, important: not change the values! +var BACKWARD = 0; +var FORWARD = 1; + +var MAXIMUM_FRAME_COUNT = 60; +var MINIMUM_TIMEOUT = 1.0 / MAXIMUM_FRAME_COUNT; +var MAXIMUM_TIMEOUT = 4.0; +var MINIMUM_FRAMES_PER_SECONDS = 10; +var PREFERRED_FRAMES_PER_SECONDS = 50; +var PREFERRED_FRAME_RATE = 1.0 / PREFERRED_FRAMES_PER_SECONDS; + + + +function SlideShow() +{ + this.aTimer = new ElapsedTime(); + this.aFrameSynchronization = new FrameSynchronization( PREFERRED_FRAME_RATE ); + this.aTimerEventQueue = new TimerEventQueue( this.aTimer ); + this.aActivityQueue = new ActivityQueue( this.aTimer ); + this.aNextEffectEventArray = null; + this.aEventMultiplexer = null; + + this.aContext = new SlideShowContext( this.aTimerEventQueue, this.aEventMultiplexer, + this.aNextEffectEventArray, this.aActivityQueue ); + this.nCurrentEffect = 0; + this.eDirection = FORWARD; + this.bIsIdle = true; + this.bIsEnabled = true; +} + + +SlideShow.prototype.setSlideEvents = function( aNextEffectEventArray, aEventMultiplexer ) +{ + if( !aNextEffectEventArray ) + log( 'SlideShow.setSlideEvents: aNextEffectEventArray is not valid' ); + + if( !aEventMultiplexer ) + log( 'SlideShow.setSlideEvents: aEventMultiplexer is not valid' ); + + this.aContext.aNextEffectEventArray = aNextEffectEventArray; + this.aNextEffectEventArray = aNextEffectEventArray; + this.aContext.aEventMultiplexer = aEventMultiplexer; + this.aEventMultiplexer = aEventMultiplexer; + this.nCurrentEffect = 0; +}; + +SlideShow.prototype.isRunning = function() +{ + return !this.bIsIdle; +}; + +SlideShow.prototype.isEnabled = function() +{ + return this.bIsEnabled; +}; + +SlideShow.prototype.notifyNextEffectStart = function() +{ + var aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nCurSlide].aSlideAnimationsHandler.aAnimatedElementMap; + for( sId in aAnimatedElementMap ) + aAnimatedElementMap[ sId ].notifyNextEffectStart( this.nCurrentEffect ); +}; + +SlideShow.prototype.notifySlideStart = function( nSlideIndex ) +{ + var aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nSlideIndex].aSlideAnimationsHandler.aAnimatedElementMap; + for( sId in aAnimatedElementMap ) + aAnimatedElementMap[ sId ].notifySlideStart(); +}; + +SlideShow.prototype.nextEffect = function() +{ + if( !this.isEnabled() ) + return false; + + if( this.isRunning() ) + return true; + + if( !this.aNextEffectEventArray ) + return false; + + this.notifyNextEffectStart(); + + if( this.nCurrentEffect >= this.aNextEffectEventArray.size() ) + return false; + + this.eDirection = FORWARD; + this.aNextEffectEventArray.at( this.nCurrentEffect ).fire(); + ++this.nCurrentEffect; + this.update(); + return true; +}; + +SlideShow.prototype.previousEffect = function() +{ + if( this.nCurrentEffect <= 0 ) + return false; + this.eDirection = BACKWARD; + this.aNextEffectEventArray.at( this.nCurrentEffect ).fire(); + --this.nCurrentEffect; + return true; +}; + +SlideShow.prototype.displaySlide = function( nNewSlide, bSkipSlideTransition ) +{ + var aMetaDoc = theMetaDoc; + var nSlides = aMetaDoc.nNumberOfSlides; + if( nNewSlide < 0 && nSlides > 0 ) + nNewSlide = nSlides - 1; + else if( nNewSlide >= nSlides ) + nNewSlide = 0; + + if( ( currentMode === INDEX_MODE ) && ( nNewSlide === nCurSlide ) ) + { + var newMetaSlide = aMetaDoc.aMetaSlideSet[nNewSlide]; + newMetaSlide.show(); + return; + } + + // handle current slide + var nOldSlide = nCurSlide; + if( nOldSlide !== undefined ) + { + var oldMetaSlide = aMetaDoc.aMetaSlideSet[nOldSlide]; + if( this.isEnabled() ) + { + // hide current slide + oldMetaSlide.hide(); + if( oldMetaSlide.aSlideAnimationsHandler.isAnimated() ) + { + // force end animations + oldMetaSlide.aSlideAnimationsHandler.end( bSkipSlideTransition ); + + // clear all queues + this.dispose(); + } + } + else + { + oldMetaSlide.hide(); + } + } + + // handle new slide + nCurSlide = nNewSlide; + var newMetaSlide = aMetaDoc.aMetaSlideSet[nNewSlide]; + if( this.isEnabled() ) + { + // prepare to show a new slide + this.notifySlideStart( nNewSlide ); + + if( !bSkipSlideTransition ) + { + // create slide transition and add to activity queue + // to be implemented + } + + // show next slide and start animations + newMetaSlide.show(); + newMetaSlide.aSlideAnimationsHandler.start(); + this.update(); + } + else + { + newMetaSlide.show(); + } + + + + /* + var nOldSlide = nCurSlide; + nCurSlide = nNewSlide; + + var oldMetaSlide = aMetaDoc.aMetaSlideSet[nOldSlide]; + var newMetaSlide = aMetaDoc.aMetaSlideSet[nNewSlide]; + + if( !this.isEnabled() ) + { + oldMetaSlide.hide(); + newMetaSlide.show(); + return; + } + + // force end animations and hide current slide + oldMetaSlide.hide(); + oldMetaSlide.aSlideAnimationsHandler.end( bSkipSlideTransition ); + + // clear all queues + this.dispose(); + + // prepare to show a new slide + this.notifySlideStart(); + + if( !bSkipSlideTransition ) + { + // create slide transition and add to activity queue + // to be implemented + } + + // show next slide and start animations + newMetaSlide.show(); + newMetaSlide.aSlideAnimationsHandler.start(); + this.update(); + */ +}; + +SlideShow.prototype.update = function() +{ + this.aTimer.holdTimer(); + var suspendHandle = ROOT_NODE.suspendRedraw( PREFERRED_FRAME_RATE * 1000 ); + + // process queues + this.aTimerEventQueue.process(); + this.aActivityQueue.process(); + + this.aFrameSynchronization.synchronize(); + + ROOT_NODE.unsuspendRedraw(suspendHandle); + ROOT_NODE.forceRedraw(); + this.aTimer.releaseTimer(); + + var bActivitiesLeft = ( ! this.aActivityQueue.isEmpty() ); + var bTimerEventsLeft = ( ! this.aTimerEventQueue.isEmpty() ); + var bEventsLeft = ( bActivitiesLeft || bTimerEventsLeft ); + + + if( bEventsLeft ) + { + var nNextTimeout; + if( bActivitiesLeft ) + { + nNextTimeout = MINIMUM_TIMEOUT; + this.aFrameSynchronization.activate(); + } + else + { + nNextTimeout = this.aTimerEventQueue.nextTimeout(); + if( nNextTimeout < MINIMUM_TIMEOUT ) + nNextTimeout = MINIMUM_TIMEOUT; + else if( nNextTimeout > MAXIMUM_TIMEOUT ) + nNextTimeout = MAXIMUM_TIMEOUT; + this.aFrameSynchronization.deactivate(); + } + + this.bIsIdle = false; + window.setTimeout( 'aSlideShow.update()', nNextTimeout * 1000 ); + } + else + { + this.bIsIdle = true; + } +}; + +SlideShow.prototype.dispose = function() +{ + // clear all queues + this.aTimerEventQueue.clear(); + this.aActivityQueue.clear(); + this.aNextEffectEventArray = null; + this.aEventMultiplexer = null; +}; + +SlideShow.prototype.getContext = function() +{ + return this.aContext; +}; + +// the SlideShow global instance +var aSlideShow = null; + + + +// ------------------------------------------------------------------------------------------ // +function SlideShowContext( aTimerEventQueue, aEventMultiplexer, aNextEffectEventArray, aActivityQueue) +{ + this.aTimerEventQueue = aTimerEventQueue; + this.aEventMultiplexer = aEventMultiplexer; + this.aNextEffectEventArray = aNextEffectEventArray; + this.aActivityQueue = aActivityQueue; +} + + + +// ------------------------------------------------------------------------------------------ // +function FrameSynchronization( nFrameDuration ) +{ + this.nFrameDuration = nFrameDuration; + this.aTimer = new ElapsedTime(); + this.nNextFrameTargetTime = 0.0; + this.bIsActive = false; + + this.markCurrentFrame(); +} + + +FrameSynchronization.prototype.markCurrentFrame = function() +{ + this.nNextFrameTargetTime = this.aTimer.getElapsedTime() + this.nFrameDuration; +}; + +FrameSynchronization.prototype.synchronize = function() +{ + if( this.bIsActive ) + { + // Do busy waiting for now. + while( this.aTimer.getElapsedTime() < this.nNextFrameTargetTime ) + ; + } + + this.markCurrentFrame(); + +}; + +FrameSynchronization.prototype.activate = function() +{ + this.bIsActive = true; +}; + +FrameSynchronization.prototype.deactivate = function() +{ + this.bIsActive = false; +}; + + + +/********************************************************************************************** + * TimerEventQueue, ActivityQueue and ElapsedTime + **********************************************************************************************/ + +//------------------------------------------------------------------------------------------- // +function NextEffectEventArray() +{ + this.aEventArray = new Array(); +} + + +NextEffectEventArray.prototype.size = function() +{ + return this.aEventArray.length; +}; + +NextEffectEventArray.prototype.at = function( nIndex ) +{ + return this.aEventArray[ nIndex ]; +}; + +NextEffectEventArray.prototype.appendEvent = function( aEvent ) +{ + var nSize = this.size(); + for( var i = 0; i < nSize; ++i ) + { + if( this.aEventArray[i].getId() == aEvent.getId() ) + { + aNextEffectEventArrayDebugPrinter.print( 'NextEffectEventArray.appendEvent: event already present' ); + return false; + } + } + this.aEventArray.push( aEvent ); + aNextEffectEventArrayDebugPrinter.print( 'NextEffectEventArray.appendEvent: event appended' ); + return true; + }; + + NextEffectEventArray.prototype.clear = function( ) + { + this.aEventArray = new Array(); + }; + + + + //------------------------------------------------------------------------------------------- // +function TimerEventQueue( aTimer ) +{ + this.aTimer = aTimer; + this.aEventSet = new PriorityQueue( EventEntry.compare ); +} + + +TimerEventQueue.prototype.addEvent = function( aEvent ) +{ + this.DBG( 'TimerEventQueue.addEvent invoked' ); + if( !aEvent ) + { + log( 'error: TimerEventQueue.addEvent: null event' ); + return false; + } + + var nTime = aEvent.getActivationTime( this.aTimer.getElapsedTime() ); + var aEventEntry = new EventEntry( aEvent, nTime ); + this.aEventSet.push( aEventEntry ); + + return true; +}; + +TimerEventQueue.prototype.process = function() +{ + var nCurrentTime = this.aTimer.getElapsedTime(); + + while( !this.isEmpty() && ( this.aEventSet.top().nActivationTime <= nCurrentTime ) ) + { + var aEventEntry = this.aEventSet.top(); + this.aEventSet.pop(); + + var aEvent = aEventEntry.aEvent; + if( aEvent.isCharged() ) + aEvent.fire(); + } +}; + +TimerEventQueue.prototype.isEmpty = function() +{ + return this.aEventSet.isEmpty(); +}; + +TimerEventQueue.prototype.nextTimeout = function() +{ + var nTimeout = Number.MAX_VALUE; + var nCurrentTime = this.aTimer.getElapsedTime(); + if( !this.isEmpty() ) + nTimeout = this.aEventSet.top().nActivationTime - nCurrentTime; + return nTimeout; +}; + +TimerEventQueue.prototype.clear = function() +{ + this.DBG( 'TimerEventQueue.clear invoked' ); + this.aEventSet.clear(); +}; + +TimerEventQueue.prototype.getTimer = function() +{ + return this.aTimer; +}; + +TimerEventQueue.prototype.DBG = function( sMessage, nTime ) +{ + aTimerEventQueueDebugPrinter.print( sMessage, nTime ); +}; + + +TimerEventQueue.prototype.insert = function( aEventEntry ) +{ + var nHoleIndex = this.aEventSet.length; + var nParent = Math.floor( ( nHoleIndex - 1 ) / 2 ); + + while( ( nHoleIndex > 0 ) && this.aEventSet[ nParent ].compare( aEventEntry ) ) + { + this.aEventSet[ nHoleIndex ] = this.aEventSet[ nParent ]; + nHoleIndex = nParent; + nParent = Math.floor( ( nHoleIndex - 1 ) / 2 ); + } + this.aEventSet[ nHoleIndex ] = aEventEntry; +}; + + + +// ------------------------------------------------------------------------------------------ // +function EventEntry( aEvent, nTime ) +{ + this.aEvent = aEvent; + this.nActivationTime = nTime; +} + + +EventEntry.compare = function( aLhsEventEntry, aRhsEventEntry ) +{ + return ( aLhsEventEntry.nActivationTime > aRhsEventEntry.nActivationTime ); +}; + + + +// ------------------------------------------------------------------------------------------ // +function ActivityQueue( aTimer ) +{ + this.aTimer = aTimer; + this.aCurrentActivityWaitingSet = new Array(); + this.aCurrentActivityReinsertSet = new Array(); + this.aDequeuedActivitySet = new Array(); +} + + +ActivityQueue.prototype.dispose = function() +{ + var nSize = this.aCurrentActivityWaitingSet.length; + for( var i = 0; i < nSize; ++i ) + this.aCurrentActivityWaitingSet[i].dispose(); + + nSize = this.aCurrentActivityReinsertSet.length; + for( var i = 0; i < nSize; ++i ) + this.aCurrentActivityReinsertSet[i].dispose(); +}; + +ActivityQueue.prototype.addActivity = function( aActivity ) +{ + if( !aActivity ) + { + log( 'ActivityQueue.addActivity: activity is not valid' ); + return false; + } + + this.aCurrentActivityWaitingSet.push( aActivity ); + aActivityQueueDebugPrinter.print( 'ActivityQueue.addActivity: activity appended' ); + return true; +}; + +ActivityQueue.prototype.process = function() +{ + var nSize = this.aCurrentActivityWaitingSet.length; + var nLag = 0.0; + for( var i = 0; i < nSize; ++i ) + { + nLag = Math.max( nLag,this.aCurrentActivityWaitingSet[i].calcTimeLag() ); + } + + if( nLag > 0.0 ) + this.aTimer.adjustTimer( -nLag, true ); + + + while( this.aCurrentActivityWaitingSet.length != 0 ) + { + var aActivity = this.aCurrentActivityWaitingSet.shift(); + var bReinsert = false; + + bReinsert = aActivity.perform(); + + if( bReinsert ) + { + this.aCurrentActivityReinsertSet.push( aActivity ); + } + else + { + this.aDequeuedActivitySet.push( aActivity ); + } + } + + if( this.aCurrentActivityReinsertSet.length != 0 ) + { + // TODO: optimization, try to swap reference here + this.aCurrentActivityWaitingSet = this.aCurrentActivityReinsertSet; + this.aCurrentActivityReinsertSet = new Array(); + } +}; + +ActivityQueue.prototype.processDequeued = function() +{ + // notify all dequeued activities from last round + var nSize = this.aDequeuedActivitySet.length; + for( var i = 0; i < nSize; ++i ) + this.aDequeuedActivitySet[i].dequeued(); + + this.aDequeuedActivitySet = new Array(); +}; + +ActivityQueue.prototype.isEmpty = function() +{ + return ( ( this.aCurrentActivityWaitingSet.length == 0 ) && + ( this.aCurrentActivityReinsertSet.length == 0 ) ); +}; + +ActivityQueue.prototype.clear = function() +{ + aActivityQueueDebugPrinter.print( 'ActivityQueue.clear invoked' ); + var nSize = this.aCurrentActivityWaitingSet.length; + for( var i = 0; i < nSize; ++i ) + this.aCurrentActivityWaitingSet[i].dequeued(); + this.aCurrentActivityWaitingSet = new Array(); + + nSize = this.aCurrentActivityReinsertSet.length; + for( var i = 0; i < nSize; ++i ) + this.aCurrentActivityReinsertSet[i].dequeued(); + this.aCurrentActivityReinsertSet = new Array(); +}; + +ActivityQueue.prototype.getTimer = function() +{ + return this.aTimer; +}; + +ActivityQueue.prototype.size = function() +{ + return ( this.aCurrentActivityWaitingSet.length + + this.aCurrentActivityReinsertSet.length + + this.aDequeuedActivitySet.length ); +}; + + + +// ------------------------------------------------------------------------------------------ // + function ElapsedTime( aTimeBase ) + { + this.aTimeBase = aTimeBase; + this.nLastQueriedTime = 0.0; + this.nStartTime = this.getCurrentTime(); + this.nFrozenTime = 0.0; + this.bInPauseMode = false; + this.bInHoldMode = false; + } + + + ElapsedTime.prototype.getTimeBase = function() + { + return aTimeBase; + }; + + ElapsedTime.prototype.reset = function() + { + this.nLastQueriedTime = 0.0; + this.nStartTime = this.getCurrentTime(); + this.nFrozenTime = 0.0; + this.bInPauseMode = false; + this.bInHoldMode = false; + }; + + ElapsedTime.prototype.getElapsedTime = function() + { + this.nLastQueriedTime = this.getElapsedTimeImpl(); + return this.nLastQueriedTime; + }; + + ElapsedTime.prototype.pauseTimer = function() + { + this.nFrozenTime = this.getElapsedTimeImpl(); + this.bInPauseMode = true; + }; + + ElapsedTime.prototype.continueTimer = function() + { + this.bInPauseMode = false; + + // stop pausing, time runs again. Note that + // getElapsedTimeImpl() honors hold mode, i.e. a + // continueTimer() in hold mode will preserve the latter + var nPauseDuration = this.getElapsedTimeImpl() - this.nFrozenTime; + + // adjust start time, such that subsequent getElapsedTime() calls + // will virtually start from m_fFrozenTime. + this.nStartTime += nPauseDuration; +}; + +ElapsedTime.prototype.adjustTimer = function( nOffset, bLimitToLastQueriedTime ) +{ + if( bLimitToLastQueriedTime == undefined ) + bLimitToLastQueriedTime = true; + + // to make getElapsedTime() become _larger_, have to reduce nStartTime. + this.nStartTime -= nOffset; + + // also adjust frozen time, this method must _always_ affect the + // value returned by getElapsedTime()! + if( this.bInHoldMode || this.bInPauseMode ) + this.nFrozenTime += nOffset; +}; + +ElapsedTime.prototype.holdTimer = function() +{ + // when called during hold mode (e.g. more than once per time + // object), the original hold time will be maintained. + this.nFrozenTime = this.getElapsedTimeImpl(); + this.bInHoldMode = true; +}; + +ElapsedTime.prototype.releaseTimer = function() +{ + this.bInHoldMode = false; +}; + +ElapsedTime.prototype.getSystemTime = function() +{ + return ( getCurrentSystemTime() / 1000.0 ); +}; + +ElapsedTime.prototype.getCurrentTime = function() +{ + var nCurrentTime; + if ( !this.aTimeBase ) + { + nCurrentTime = this.getSystemTime(); +// if( !isFinite(nCurrentTime) ) +// { +// log( 'ElapsedTime.getCurrentTime: this.getSystemTime() == ' + nCurrentTime ); +// } + } + else + { + nCurrentTime = this.aTimeBase.getElapsedTimeImpl(); +// if( !isFinite(nCurrentTime) ) +// { +// log( 'ElapsedTime.getCurrentTime: this.aTimeBase.getElapsedTimeImpl() == ' + nCurrentTime ); +// } + } + + assert( ( typeof( nCurrentTime ) === typeof( 0 ) ) && isFinite( nCurrentTime ), + 'ElapsedTime.getCurrentTime: assertion failed: nCurrentTime == ' + nCurrentTime ); + + + return nCurrentTime; +}; + +ElapsedTime.prototype.getElapsedTimeImpl = function() +{ + if( this.bInHoldMode || this.bInPauseMode ) + { +// if( !isFinite(this.nFrozenTime) ) +// { +// log( 'ElapsedTime.getElapsedTimeImpl: nFrozenTime == ' + this.nFrozenTime ); +// } + + return this.nFrozenTime; + } + + var nCurTime = this.getCurrentTime(); + return ( nCurTime - this.nStartTime ); +}; + + +/***** + * @libreofficeend + * + * Several parts of the above code are the result of the porting, + * started on August 2011, of the C++ code included in the source files + * placed under the folder '/slideshow/source' and subfolders. + * @source http://cgit.freedesktop.org/libreoffice/core/tree/slideshow/source + * + */ + + diff --git a/filter/source/svg/svgscript.hxx b/filter/source/svg/svgscript.hxx deleted file mode 100644 index 6164489162a6..000000000000 --- a/filter/source/svg/svgscript.hxx +++ /dev/null @@ -1,7465 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org 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 Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - - - -#define N_SVGSCRIPT_FRAGMENTS 37 - -static const char aSVGScript0[] = -" 0)\n\ - skipEffects(-1);\n\ - else if (delta < 0)\n\ - skipEffects(1);\n\ -\n\ - if (aEvt.preventDefault)\n\ - aEvt.preventDefault();\n\ -\n\ - aEvt.returnValue = false;\n\ - }\n\ -\n\ - if( window.addEventListener )\n\ - {\n\ - window.addEventListener( 'DOMMouseScroll', function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_WHEEL ); }, false );\n\ - }\n\ -\n\ - window.onmousewheel\n\ - = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_WHEEL ); };\n\ -\n\ - function mouseHandlerDispatch( aEvt, anAction )\n\ - {\n\ - if( !aEvt )\n\ - aEvt = window.event;\n\ -\n\ - var retVal = true;\n\ -\n\ - if ( mouseHandlerDictionary[currentMode] && mouseHandlerDictionary[currentMode][anAction] )\n\ - {\n\ - var subRetVal = mouseHandlerDictionary[currentMode][anAction]( aEvt );\n\ -\n\ - if( subRetVal != null && subRetVal != undefined )\n\ - retVal = subRetVal;\n\ - }\n\ -\n\ - if( aEvt.preventDefault && !retVal )\n\ - aEvt.preventDefault();\n\ -\n\ - aEvt.returnValue = retVal;\n\ -\n\ - return retVal;\n\ - }\n\ -\n\ - document.onmousedown = function( aEvt ) { return mouseHandlerDispatch( aEvt, MOUSE_DOWN ); };\n\ -\n\ - function getDefaultMouseHandlerDictionary()\n\ - {\n\ - var mouseHandlerDict = new Object();\n\ -\n\ - mouseHandlerDict[SLIDE_MODE] = new Object();\n\ - mouseHandlerDict[INDEX_MODE] = new Object();\n\ -\n\ - mouseHandlerDict[SLIDE_MODE][MOUSE_DOWN]\n\ - = function( aEvt ) { return slideOnMouseDown( aEvt ); };\n\ - mouseHandlerDict[SLIDE_MODE][MOUSE_WHEEL]\n\ - = function( aEvt ) { return slideOnMouseWheel( aEvt ); };\n\ -\n\ - mouseHandlerDict[INDEX_MODE][MOUSE_DOWN]\n\ - = function( aEvt ) { return toggleSlideIndex(); };\n\ -\n\ - return mouseHandlerDict;\n\ - }\n\ -\n\ - function indexSetPageSlide( nIndex )\n\ - {\n\ - var aMetaSlideSet = theMetaDoc.aMetaSlideSet;\n\ - nIndex = getSafeIndex( nIndex, 0, aMetaSlideSet.length - 1 );\n\ -\n\ - var nSelectedThumbnailIndex = nIndex % theSlideIndexPage.getTotalThumbnails();\n\ - var offset = nIndex - nSelectedThumbnailIndex;\n\ -\n\ - if( offset < 0 )\n\ - offset = 0;\n\ -\n\ - if( offset != INDEX_OFFSET )\n\ - {\n\ - INDEX_OFFSET = offset;\n\ - displayIndex( INDEX_OFFSET );\n\ - }\n\ -\n\ - theSlideIndexPage.setSelection( nSelectedThumbnailIndex );\n\ - }\n\ -\n\ -\n\ - /*****\n\ - * @jessyinkend\n\ - *\n\ - * The above code is a derivative work of some parts of the JessyInk project.\n\ - * @source http://code.google.com/p/jessyink/\n\ - */\n\ -\n\ -\n\ - /*****\n\ - * @licstart\n\ - *\n\ - * The following is the license notice for the part of JavaScript code of this\n\ - * page included between the '@stdlibstart' and the '@stdlibend' notes.\n\ - */\n\ -\n\ - /***** ******************************************************************\n\ - *\n\ - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009\n\ - * Free Software Foundation, Inc.\n\ - *\n\ - * The code included between the start note '@stdlibstart' and the end\n\ - * note '@stdlibend' is a derivative work of the GNU ISO C++ Library.\n\ - * This library is free software; you can redistribute it and/or modify\n\ - * it under the terms of the GNU General Public License as published by\n\ - * the Free Software Foundation; either version 3, or (at your option)\n\ - * any later version.\n\ - *\n\ - * This library is distributed in the hope that it will be useful,\n\ - * but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ - * GNU General Public License for more details.\n\ - *\n\ - * Under Section 7 of GPL version 3, you are granted additional\n\ - * permissions described in the GCC Runtime Library Exception, version\n\ - * 3.1, as published by the Free Software Foundation.\n\ - *\n\ - * You should have received a copy of the GNU General Public License and\n\ - * a copy of the GCC Runtime Library Exception along with this program;\n\ - * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see\n\ - * .\n\ - *\n\ - *************************************************************************/\n\ -\n\ - /*****\n\ - *\n\ - * Copyright (c) 1994\n\ - * Hewlett-Packard Company\n\ - *\n\ - * Permission to use, copy, modify, distribute and sell this software\n\ - * and its documentation for any purpose is hereby granted without fee,\n\ - * provided that the above copyright notice appear in all copies and\n\ - * that both that copyright notice and this permission notice appear\n\ - * in supporting documentation. Hewlett-Packard Company makes no\n\ - * representations about the suitability of this software for any\n\ - * purpose. It is provided 'as is' without express or implied warranty.\n\ - *\n\ - *\n\ - * Copyright (c) 1996,1997\n\ - * Silicon Graphics Computer Systems, Inc.\n\ - *\n\ - * Permission to use, copy, modify, distribute and sell this software\n\ - * and its documentation for any purpose is hereby granted without fee,\n\ - * provided that the above copyright notice appear in all copies and\n\ - * that both that copyright notice and this permission notice appear\n\ - * in supporting documentation. Silicon Graphics makes no\n\ - * representations about the suitability of this software for any\n\ - * purpose. It is provided 'as is' without express or implied warranty.\n\ - *\n\ - ************************************************************************/\n\ -\n\ - /*****\n\ - * @licend\n\ - *\n\ - * The above is the license notice for the part of JavaScript code of this\n\ - * page included between the '@stdlibstart' and the '@stdlibend' notes.\n\ - */\n\ -\n\ -\n\ - /*****\n\ - * @stdlibstart\n\ - *\n\ - * The following code is a porting, performed on August 2011, of a part of\n\ - * the C++ code included into the source file stl_queue.h that is part of\n\ - * the GNU ISO C++ Library.\n\ - */\n\ -\n\ -\n\ - function PriorityQueue( aCompareFunc )\n\ - {\n\ - this.aSequence = new Array();\n\ - this.aCompareFunc = aCompareFunc;\n\ - }\n\ -\n\ - PriorityQueue.prototype.top = function()\n\ - {\n\ - return this.aSequence[0];\n\ - };\n\ -\n\ - PriorityQueue.prototype.isEmpty = function()\n\ - {\n\ - return ( this.size() === 0 );\n\ - };\n\ -\n\ - PriorityQueue.prototype.size = function()\n\ -"; - -static const char aSVGScript2[] = -"\ - {\n\ - return this.aSequence.length;\n\ - };\n\ -\n\ - PriorityQueue.prototype.push = function( aValue )\n\ - {\n\ - this.implPushHeap( 0, this.aSequence.length, 0, aValue );\n\ - };\n\ -\n\ - PriorityQueue.prototype.clear = function()\n\ - {\n\ - return this.aSequence = new Array();\n\ - };\n\ -\n\ -\n\ - PriorityQueue.prototype.pop = function()\n\ - {\n\ - if( this.isEmpty() )\n\ - return;\n\ -\n\ - var nLast = this.aSequence.length - 1;\n\ - var aValue = this.aSequence[ nLast ];\n\ - this.aSequence[ nLast ] = this.aSequence[ 0 ];\n\ - this.implAdjustHeap( 0, 0, nLast, aValue );\n\ - this.aSequence.pop();\n\ - };\n\ -\n\ - PriorityQueue.prototype.implAdjustHeap = function( nFirst, nHoleIndex, nLength, aValue )\n\ - {\n\ - var nTopIndex = nHoleIndex;\n\ - var nSecondChild = nHoleIndex;\n\ -\n\ - while( nSecondChild < Math.floor( ( nLength - 1 ) / 2 ) )\n\ - {\n\ - nSecondChild = 2 * ( nSecondChild + 1 );\n\ - if( this.aCompareFunc( this.aSequence[ nFirst + nSecondChild ],\n\ - this.aSequence[ nFirst + nSecondChild - 1] ) )\n\ - {\n\ - --nSecondChild;\n\ - }\n\ - this.aSequence[ nFirst + nHoleIndex ] = this.aSequence[ nFirst + nSecondChild ];\n\ - nHoleIndex = nSecondChild;\n\ - }\n\ -\n\ - if( ( ( nLength & 1 ) === 0 ) && ( nSecondChild === Math.floor( ( nLength - 2 ) / 2 ) ) )\n\ - {\n\ - nSecondChild = 2 * ( nSecondChild + 1 );\n\ - this.aSequence[ nFirst + nHoleIndex ] = this.aSequence[ nFirst + nSecondChild - 1];\n\ - nHoleIndex = nSecondChild - 1;\n\ - }\n\ -\n\ - this.implPushHeap( nFirst, nHoleIndex, nTopIndex, aValue );\n\ - };\n\ -\n\ - PriorityQueue.prototype.implPushHeap = function( nFirst, nHoleIndex, nTopIndex, aValue )\n\ - {\n\ - var nParent = Math.floor( ( nHoleIndex - 1 ) / 2 );\n\ -\n\ - while( ( nHoleIndex > nTopIndex ) &&\n\ - this.aCompareFunc( this.aSequence[ nFirst + nParent ], aValue ) )\n\ - {\n\ - this.aSequence[ nFirst + nHoleIndex ] = this.aSequence[ nFirst + nParent ];\n\ - nHoleIndex = nParent;\n\ - nParent = Math.floor( ( nHoleIndex - 1 ) / 2 );\n\ - }\n\ - this.aSequence[ nFirst + nHoleIndex ] = aValue;\n\ - };\n\ -\n\ -\n\ - /*****\n\ - * @stdlibend\n\ - *\n\ - * The above code is a porting, performed on August 2011, of a part of\n\ - * the C++ code included into the source file stl_queue.h that is part of\n\ - * the GNU ISO C++ Library.\n\ - */\n\ -\n\ -\n\ - /*****\n\ - * @licstart\n\ - *\n\ - * The following is the license notice for the part of JavaScript code of\n\ - * this page included between the '@libreofficestart' and the '@libreofficeend'\n\ - * notes.\n\ - */\n\ -\n\ - /***** ******************************************************************\n\ - *\n\ - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n\ - *\n\ - * Copyright 2000, 2010 Oracle and/or its affiliates.\n\ - *\n\ - * OpenOffice.org - a multi-platform office productivity suite\n\ - *\n\ - * This file is part of OpenOffice.org.\n\ - *\n\ - * OpenOffice.org is free software: you can redistribute it and/or modify\n\ - * it under the terms of the GNU Lesser General Public License version 3\n\ - * only, as published by the Free Software Foundation.\n\ - *\n\ - * OpenOffice.org is distributed in the hope that it will be useful,\n\ - * but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ - * GNU Lesser General Public License version 3 for more details\n\ - * (a copy is included in the LICENSE file that accompanied this code).\n\ - *\n\ - * You should have received a copy of the GNU Lesser General Public License\n\ - * version 3 along with OpenOffice.org. If not, see\n\ - * \n\ - * for a copy of the LGPLv3 License.\n\ - *\n\ - ************************************************************************/\n\ -\n\ - /*****\n\ - * @licend\n\ - *\n\ - * The above is the license notice for the part of JavaScript code of\n\ - * this page included between the '@libreofficestart' and the '@libreofficeend'\n\ - * notes.\n\ - */\n\ -\n\ -\n\ - /*****\n\ - * @libreofficestart\n\ - *\n\ - * Several parts of the following code are the result of the porting,\n\ - * started on August 2011, of the C++ code included in the source files\n\ - * placed under the folder '/slideshow/source' and subfolders.\n\ - * @source http://cgit.freedesktop.org/libreoffice/core/tree/slideshow/source\n\ - *\n\ - */\n\ -\n\ -\n\ - window.onload = init;\n\ -\n\ -\n\ - var aOOOElemMetaSlides = 'ooo:meta_slides';\n\ - var aOOOElemMetaSlide = 'ooo:meta_slide';\n\ - var aOOOElemTextField = 'ooo:text_field';\n\ -\n\ - var aOOOAttrNumberOfSlides = 'number-of-slides';\n\ - var aOOOAttrNumberingType = 'page-numbering-type';\n\ -\n\ - var aOOOAttrSlide = 'slide';\n\ - var aOOOAttrMaster = 'master';\n\ - var aOOOAttrBackgroundVisibility = 'background-visibility';\n\ - var aOOOAttrMasterObjectsVisibility = 'master-objects-visibility';\n\ - var aOOOAttrPageNumberVisibility = 'page-number-visibility';\n\ - var aOOOAttrDateTimeVisibility = 'date-time-visibility';\n\ - var aOOOAttrFooterVisibility = 'footer-visibility';\n\ - var aOOOAttrHeaderVisibility = 'header-visibility';\n\ - var aOOOAttrDateTimeField = 'date-time-field';\n\ - var aOOOAttrFooterField = 'footer-field';\n\ - var aOOOAttrHeaderField = 'header-field';\n\ -\n\ - var aOOOAttrDateTimeFormat = 'date-time-format';\n\ -\n\ - var aOOOAttrTextAdjust = 'text-adjust';\n\ -\n\ - var aSlideNumberClassName = 'Slide_Number';\n\ - var aDateTimeClassName = 'Date/Time';\n\ - var aFooterClassName = 'Footer';\n\ - var aHeaderClassName = 'Header';\n\ -\n\ - var NSS = new Object();\n\ - NSS['svg']='http://www.w3.org/2000/svg';\n\ - NSS['rdf']='http://www.w3.org/1999/02/22-rdf-syntax-ns#';\n\ - NSS['xlink']='http://www.w3.org/1999/xlink';\n\ - NSS['xml']='http://www.w3.org/XML/1998/namespace';\n\ - NSS['ooo'] = 'http://xml.openoffice.org/svg/export';\n\ -\n\ - var SLIDE_MODE = 1;\n\ - var INDEX_MODE = 2;\n\ -\n\ - var MOUSE_UP = 1;\n\ - var MOUSE_DOWN = 2;\n\ - var MOUSE_MOVE = 3;\n\ - var MOUSE_WHEEL = 4;\n\ -\n\ - var LEFT_KEY = 37; // cursor left keycode\n\ - var UP_KEY = 38; // cursor up keycode\n\ - var RIGHT_KEY = 39; // cursor right keycode\n\ - var DOWN_KEY = 40; // cursor down keycode\n\ - var PAGE_UP_KEY = 33; // page up keycode\n\ - var PAGE_DOWN_KEY = 34; // page down keycode\n\ - var HOME_KEY = 36; // home keycode\n\ - var END_KEY = 35; // end keycode\n\ - var ENTER_KEY = 13;\n\ - var SPACE_KEY = 32;\n\ - var ESCAPE_KEY = 27;\n\ -\n\ - var HIDDEN = 0;\n\ - var VISIBLE = 1;\n\ - var INHERIT = 2;\n\ - var aVisibilityAttributeValue = [ 'hidden', 'visible', 'inherit' ];\n\ - var aVisibilityValue = { 'hidden' : HIDDEN, 'visible' : VISIBLE, 'inherit' : INHERIT };\n\ -\n\ - var ROOT_NODE = document.getElementsByTagNameNS( NSS['svg'], 'svg' )[0];\n\ - var WIDTH = 0;\n\ - var HEIGHT = 0;\n\ -"; - -static const char aSVGScript3[] = -"\ - var INDEX_COLUMNS_DEFAULT = 3;\n\ - var INDEX_OFFSET = 0;\n\ -\n\ - var theMetaDoc;\n\ - var theSlideIndexPage;\n\ - var currentMode = SLIDE_MODE;\n\ - var processingEffect = false;\n\ - var nCurSlide = 0;\n\ -\n\ - var charCodeDictionary = getDefaultCharCodeDictionary();\n\ - var keyCodeDictionary = getDefaultKeyCodeDictionary();\n\ -\n\ - var mouseHandlerDictionary = getDefaultMouseHandlerDictionary();\n\ -\n\ -\n\ - function object( aObject )\n\ - {\n\ - var F = function() {};\n\ - F.prototype = aObject;\n\ - return new F();\n\ - }\n\ -\n\ -\n\ - function extend( aSubType, aSuperType )\n\ - {\n\ - if (!aSuperType || !aSubType)\n\ - {\n\ - alert('extend failed, verify dependencies');\n\ - }\n\ - var OP = Object.prototype;\n\ - var sp = aSuperType.prototype;\n\ - var rp = object( sp );\n\ - aSubType.prototype = rp;\n\ -\n\ - rp.constructor = aSubType;\n\ - aSubType.superclass = sp;\n\ -\n\ - if (aSuperType != Object && sp.constructor == OP.constructor)\n\ - {\n\ - sp.constructor = aSuperType;\n\ - }\n\ -\n\ - return aSubType;\n\ - }\n\ -\n\ -\n\ - function instantiate( TemplateClass, BaseType )\n\ - {\n\ - if( !TemplateClass.instanceSet )\n\ - TemplateClass.instanceSet = new Array();\n\ -\n\ - var nSize = TemplateClass.instanceSet.length;\n\ -\n\ - for( var i = 0; i < nSize; ++i )\n\ - {\n\ - if( TemplateClass.instanceSet[i].base === BaseType )\n\ - return TemplateClass.instanceSet[i].instance;\n\ - }\n\ -\n\ - TemplateClass.instanceSet[ nSize ] = new Object();\n\ - TemplateClass.instanceSet[ nSize ].base = BaseType;\n\ - TemplateClass.instanceSet[ nSize ].instance = TemplateClass( BaseType );\n\ -\n\ - return TemplateClass.instanceSet[ nSize ].instance;\n\ - };\n\ -\n\ -\n\ - function Rectangle( aSVGRectElem )\n\ - {\n\ - var x = parseInt( aSVGRectElem.getAttribute( 'x' ) );\n\ - var y = parseInt( aSVGRectElem.getAttribute( 'y' ) );\n\ - var width = parseInt( aSVGRectElem.getAttribute( 'width' ) );\n\ - var height = parseInt( aSVGRectElem.getAttribute( 'height' ) );\n\ -\n\ - this.left = x;\n\ - this.right = x + width;\n\ - this.top = y;\n\ - this.bottom = y + height;\n\ - }\n\ -\n\ - function log( message )\n\ - {\n\ - if( typeof console == 'object' )\n\ - {\n\ - console.log( message );\n\ - }\n\ - else if( typeof opera == 'object' )\n\ - {\n\ - opera.postError( message );\n\ - }\n\ - else if( typeof java == 'object' && typeof java.lang == 'object' )\n\ - {\n\ - java.lang.System.out.println( message );\n\ - }\n\ - }\n\ -\n\ - function getNSAttribute( sNSPrefix, aElem, sAttrName )\n\ - {\n\ - if( !aElem ) return null;\n\ - if( aElem.hasAttributeNS( NSS[sNSPrefix], sAttrName ) )\n\ - {\n\ - return aElem.getAttributeNS( NSS[sNSPrefix], sAttrName );\n\ - }\n\ - return null;\n\ - }\n\ -\n\ - function getOOOAttribute( aElem, sAttrName )\n\ - {\n\ - return getNSAttribute( 'ooo', aElem, sAttrName );\n\ - }\n\ -\n\ - function setNSAttribute( sNSPrefix, aElem, sAttrName, aValue )\n\ - {\n\ - if( !aElem ) return false;\n\ - if( 'setAttributeNS' in aElem )\n\ - {\n\ - aElem.setAttributeNS( NSS[sNSPrefix], sAttrName, aValue );\n\ - return true;\n\ - }\n\ - else\n\ - {\n\ - aElem.setAttribute(sNSPrefix + ':' + sAttrName, aValue );\n\ - return true;\n\ - }\n\ - }\n\ -\n\ - function setOOOAttribute( aElem, sAttrName, aValue )\n\ - {\n\ - return setNSAttribute( 'ooo', aElem, sAttrName, aValue );\n\ - }\n\ -\n\ - function checkElemAndSetAttribute( aElem, sAttrName, aValue )\n\ - {\n\ - if( aElem )\n\ - aElem.setAttribute( sAttrName, aValue );\n\ - }\n\ -\n\ - function getElementsByClassName( aElem, sClassName )\n\ - {\n\ -\n\ - var aElementSet = new Array();\n\ - if( 'getElementsByClassName' in aElem )\n\ - {\n\ - aElementSet = aElem.getElementsByClassName( sClassName );\n\ - }\n\ - else\n\ - {\n\ - var aElementSetByClassProperty = getElementsByProperty( aElem, 'class' );\n\ - for( var i = 0; i < aElementSetByClassProperty.length; ++i )\n\ - {\n\ - var sAttrClassName = aElementSetByClassProperty[i].getAttribute( 'class' );\n\ - if( sAttrClassName == sClassName )\n\ - {\n\ - aElementSet.push( aElementSetByClassProperty[i] );\n\ - }\n\ - }\n\ - }\n\ - return aElementSet;\n\ - }\n\ -\n\ - function getElementByClassName( aElem, sClassName /*, sTagName */)\n\ - {\n\ - var aElementSet = getElementsByClassName( aElem, sClassName );\n\ - if ( aElementSet.length == 1 )\n\ - return aElementSet[0];\n\ - else\n\ - return null;\n\ - }\n\ -\n\ - function getClassAttribute( aElem )\n\ - {\n\ - if( aElem )\n\ - return aElem.getAttribute( 'class' );\n\ - return '';\n\ - }\n\ -\n\ - function initVisibilityProperty( aElement )\n\ - {\n\ - var nVisibility = VISIBLE;\n\ - var sVisibility = aElement.getAttribute( 'visibility' );\n\ - if( sVisibility ) nVisibility = aVisibilityValue[ sVisibility ];\n\ - return nVisibility;\n\ - }\n\ -\n\ - function setElementVisibility( aElement, nCurrentVisibility, nNewVisibility )\n\ - {\n\ - if( nCurrentVisibility != nNewVisibility )\n\ - {\n\ - checkElemAndSetAttribute( aElement, 'visibility', aVisibilityAttributeValue[nNewVisibility] );\n\ - return nNewVisibility;\n\ - }\n\ - return nCurrentVisibility;\n\ - }\n\ -\n\ - function getSafeIndex( nIndex, nMin, nMax )\n\ - {\n\ - if( nIndex < nMin )\n\ - return nMin;\n\ - else if( nIndex > nMax )\n\ - return nMax;\n\ -"; - -static const char aSVGScript4[] = -"\ - else\n\ - return nIndex;\n\ - }\n\ -\n\ -\n\ - function DebugPrinter()\n\ - {\n\ - this.bEnabled = false;\n\ - }\n\ -\n\ -\n\ - DebugPrinter.prototype.on = function()\n\ - {\n\ - this.bEnabled = true;\n\ - };\n\ -\n\ - DebugPrinter.prototype.off = function()\n\ - {\n\ - this.bEnabled = false;\n\ - };\n\ -\n\ - DebugPrinter.prototype.isEnabled = function()\n\ - {\n\ - return this.bEnabled;\n\ - };\n\ -\n\ - DebugPrinter.prototype.print = function( sMessage, nTime )\n\ - {\n\ - if( this.isEnabled() )\n\ - {\n\ - sInfo = 'DBG: ' + sMessage;\n\ - if( nTime )\n\ - sInfo += ' (at: ' + String( nTime / 1000 ) + 's)';\n\ - log( sInfo );\n\ - }\n\ - };\n\ -\n\ -\n\ - var NAVDBG = new DebugPrinter();\n\ - NAVDBG.off();\n\ -\n\ - var ANIMDBG = new DebugPrinter();\n\ - ANIMDBG.off();\n\ -\n\ - var aRegisterEventDebugPrinter = new DebugPrinter();\n\ - aRegisterEventDebugPrinter.off();\n\ -\n\ - var aTimerEventQueueDebugPrinter = new DebugPrinter();\n\ - aTimerEventQueueDebugPrinter.off();\n\ -\n\ - var aEventMultiplexerDebugPrinter = new DebugPrinter();\n\ - aEventMultiplexerDebugPrinter.off();\n\ -\n\ - var aNextEffectEventArrayDebugPrinter = new DebugPrinter();\n\ - aNextEffectEventArrayDebugPrinter.off();\n\ -\n\ - var aActivityQueueDebugPrinter = new DebugPrinter();\n\ - aActivityQueueDebugPrinter.off();\n\ -\n\ - var aAnimatedElementDebugPrinter = new DebugPrinter();\n\ - aAnimatedElementDebugPrinter.off();\n\ -\n\ -\n\ - function MetaDocument( aMetaDocElem )\n\ - {\n\ - this.nNumberOfSlides = parseInt( aMetaDocElem.getAttributeNS( NSS['ooo'], aOOOAttrNumberOfSlides ) );\n\ - assert( typeof this.nNumberOfSlides == 'number' && this.nNumberOfSlides > 0,\n\ - 'MetaDocument: number of slides is zero or undefined.' );\n\ - this.startSlideNumber = 0;\n\ - this.sPageNumberingType = aMetaDocElem.getAttributeNS( NSS['ooo'], aOOOAttrNumberingType ) || 'arabic';\n\ - this.aMetaSlideSet = new Array();\n\ - this.aMasterPageSet = new Object();\n\ - this.aTextFieldSet = new Array();\n\ - this.slideNumberField = new SlideNumberField( this.sPageNumberingType );\n\ -\n\ - this.aSlideAnimationsMap = new Object();\n\ - this.initSlideAnimationsMap();\n\ -\n\ -\n\ - for( var i = 0; i < this.nNumberOfSlides; ++i )\n\ - {\n\ - var sMetaSlideId = aOOOElemMetaSlide + '_' + i;\n\ - this.aMetaSlideSet.push( new MetaSlide( sMetaSlideId, this ) );\n\ - }\n\ - assert( this.aMetaSlideSet.length == this.nNumberOfSlides,\n\ - 'MetaDocument: aMetaSlideSet.length != nNumberOfSlides.' );\n\ - this.aMetaSlideSet[ this.startSlideNumber ].show();\n\ -\n\ - }\n\ -\n\ - MetaDocument.prototype.initPlaceholderShapes = function()\n\ - {\n\ - this.aMetaSlideSet[0].initPlaceholderShapes();\n\ - };\n\ -\n\ - MetaDocument.prototype.initSlideAnimationsMap = function()\n\ - {\n\ - var aAnimationsSection = document.getElementById( 'presentation-animations' );\n\ - if( aAnimationsSection )\n\ - {\n\ - var aAnimationsDefSet = aAnimationsSection.getElementsByTagName( 'defs' );\n\ -\n\ - for( var i = 0; i < aAnimationsDefSet.length; ++i )\n\ - {\n\ - var sSlideId = aAnimationsDefSet[i].getAttributeNS( NSS['ooo'], aOOOAttrSlide );\n\ - var aChildSet = getElementChildren( aAnimationsDefSet[i] );\n\ - if( sSlideId && ( aChildSet.length == 1 ) )\n\ - {\n\ - this.aSlideAnimationsMap[ sSlideId ] = aChildSet[0];\n\ - }\n\ - }\n\ - }\n\ - };\n\ -\n\ -\n\ - function MetaSlide( sMetaSlideId, aMetaDoc )\n\ - {\n\ - this.theDocument = document;\n\ - this.id = sMetaSlideId;\n\ - this.theMetaDoc = aMetaDoc;\n\ - this.element = this.theDocument.getElementById( this.id );\n\ - assert( this.element, 'MetaSlide: meta_slide element <' + this.id + '> not found.' );\n\ - this.slideId = this.element.getAttributeNS( NSS['ooo'], aOOOAttrSlide );\n\ - this.slideElement = this.theDocument.getElementById( this.slideId );\n\ - assert( this.slideElement, 'MetaSlide: slide element <' + this.slideId + '> not found.' );\n\ - this.masterPage = this.initMasterPage();\n\ - this.nAreMasterObjectsVisible = this.initVisibilityProperty( aOOOAttrMasterObjectsVisibility, VISIBLE );\n\ - this.nIsBackgroundVisible = this.initVisibilityProperty( aOOOAttrBackgroundVisibility, VISIBLE );\n\ - this.nIsPageNumberVisible = this.initVisibilityProperty( aOOOAttrPageNumberVisibility, HIDDEN );\n\ - this.nIsDateTimeVisible = this.initVisibilityProperty( aOOOAttrDateTimeVisibility, VISIBLE );\n\ - this.nIsFooterVisible = this.initVisibilityProperty( aOOOAttrFooterVisibility, VISIBLE );\n\ - this.nIsHeaderVisible = this.initVisibilityProperty( aOOOAttrHeaderVisibility, VISIBLE );\n\ - this.aMPTextFieldSet = new Object();\n\ - this.aMPTextFieldSet[aSlideNumberClassName] = this.initSlideNumberField();\n\ - this.aMPTextFieldSet[aDateTimeClassName] = this.initDateTimeField( aOOOAttrDateTimeField );\n\ - this.aMPTextFieldSet[aFooterClassName] = this.initFixedTextField( aOOOAttrFooterField );\n\ - this.aMPTextFieldSet[aHeaderClassName] = this.initFixedTextField( aOOOAttrHeaderField );\n\ -\n\ - this.aSlideAnimationsHandler = new SlideAnimations( aSlideShow.getContext() );\n\ - this.aSlideAnimationsHandler.importAnimations( this.getSlideAnimationsRoot() );\n\ - this.aSlideAnimationsHandler.parseElements();\n\ - if( false && this.aSlideAnimationsHandler.aRootNode )\n\ - log( this.aSlideAnimationsHandler.aRootNode.info( true ) );\n\ - }\n\ -\n\ - MetaSlide.prototype =\n\ - {\n\ - hide : function()\n\ - {\n\ - checkElemAndSetAttribute( this.slideElement, 'visibility', 'hidden' );\n\ -\n\ - this.masterPage.hide();\n\ - this.masterPage.hideBackground();\n\ -\n\ - var aFieldSet = this.aMPTextFieldSet;\n\ - var aShapeSet = this.masterPage.aPlaceholderShapeSet;\n\ - if( aFieldSet[aSlideNumberClassName] ) aFieldSet[aSlideNumberClassName].hide( aShapeSet[aSlideNumberClassName] );\n\ - if( aFieldSet[aDateTimeClassName] ) aFieldSet[aDateTimeClassName].hide( aShapeSet[aDateTimeClassName] );\n\ - if( aFieldSet[aFooterClassName] ) aFieldSet[aFooterClassName].hide( aShapeSet[aFooterClassName] );\n\ - if( aFieldSet[aHeaderClassName] ) aFieldSet[aHeaderClassName].hide( aShapeSet[aHeaderClassName] );\n\ - },\n\ -\n\ - hideExceptMaster : function()\n\ - {\n\ - checkElemAndSetAttribute( this.slideElement, 'visibility', 'hidden' );\n\ - },\n\ -\n\ - show : function()\n\ - {\n\ - checkElemAndSetAttribute( this.slideElement, 'visibility', 'visible' );\n\ -\n\ - this.masterPage.setVisibility( this.nAreMasterObjectsVisible );\n\ - this.masterPage.setVisibilityBackground( this.nIsBackgroundVisible );\n\ -\n\ -\n\ - this.setTextFieldVisibility( aSlideNumberClassName, this.nIsPageNumberVisible );\n\ - this.setTextFieldVisibility( aDateTimeClassName, this.nIsDateTimeVisible );\n\ - this.setTextFieldVisibility( aFooterClassName, this.nIsFooterVisible );\n\ - this.setTextFieldVisibility( aHeaderClassName, this.nIsHeaderVisible );\n\ - },\n\ -\n\ - getMasterPageId : function()\n\ - {\n\ - return this.masterPage.id;\n\ - },\n\ -\n\ - getMasterPageElement : function()\n\ - {\n\ - return this.masterPage.element;\n\ - },\n\ -\n\ - getBackground : function()\n\ - {\n\ - return getElementByClassName( this.slideElement, 'Background' );\n\ - },\n\ -\n\ - getMasterPageBackground : function()\n\ - {\n\ - return this.masterPage.background;\n\ - },\n\ -"; - -static const char aSVGScript5[] = -"\ -\n\ - initMasterPage : function()\n\ - {\n\ - var sMasterPageId = this.element.getAttributeNS( NSS['ooo'], aOOOAttrMaster );\n\ - if( !this.theMetaDoc.aMasterPageSet.hasOwnProperty( sMasterPageId ) )\n\ - this.theMetaDoc.aMasterPageSet[ sMasterPageId ] = new MasterPage( sMasterPageId );\n\ - return this.theMetaDoc.aMasterPageSet[ sMasterPageId ];\n\ - },\n\ -\n\ - initVisibilityProperty : function( aVisibilityAttribute, nDefaultValue )\n\ - {\n\ - var nVisibility = nDefaultValue;\n\ - var sVisibility = getOOOAttribute( this.element, aVisibilityAttribute );\n\ - if( sVisibility )\n\ - nVisibility = aVisibilityValue[ sVisibility ];\n\ - return nVisibility;\n\ - },\n\ -\n\ - initSlideNumberField : function()\n\ - {\n\ - return this.theMetaDoc.slideNumberField;\n\ - },\n\ -\n\ - initDateTimeField : function( aOOOAttrDateTimeField )\n\ - {\n\ - var sTextFieldId = getOOOAttribute( this.element, aOOOAttrDateTimeField );\n\ - if( !sTextFieldId ) return null;\n\ -\n\ - var nLength = aOOOElemTextField.length + 1;\n\ - var nIndex = parseInt(sTextFieldId.substring( nLength ) );\n\ - if( typeof nIndex != 'number') return null;\n\ -\n\ - if( !this.theMetaDoc.aTextFieldSet[ nIndex ] )\n\ - {\n\ - var aTextField;\n\ - var aTextFieldElem = document.getElementById( sTextFieldId );\n\ - var sClassName = getClassAttribute( aTextFieldElem );\n\ - if( sClassName == 'FixedDateTimeField' )\n\ - {\n\ - aTextField = new FixedTextField( aTextFieldElem );\n\ - }\n\ - else if( sClassName == 'VariableDateTimeField' )\n\ - {\n\ - aTextField = new VariableDateTimeField( aTextFieldElem );\n\ - }\n\ - else\n\ - {\n\ - aTextField = null;\n\ - }\n\ - this.theMetaDoc.aTextFieldSet[ nIndex ] = aTextField;\n\ - }\n\ - return this.theMetaDoc.aTextFieldSet[ nIndex ];\n\ - },\n\ -\n\ - initFixedTextField : function( aOOOAttribute )\n\ - {\n\ - var sTextFieldId = getOOOAttribute( this.element, aOOOAttribute );\n\ - if( !sTextFieldId ) return null;\n\ -\n\ - var nLength = aOOOElemTextField.length + 1;\n\ - var nIndex = parseInt( sTextFieldId.substring( nLength ) );\n\ - if( typeof nIndex != 'number') return null;\n\ -\n\ - if( !this.theMetaDoc.aTextFieldSet[ nIndex ] )\n\ - {\n\ - var aTextFieldElem = document.getElementById( sTextFieldId );\n\ - this.theMetaDoc.aTextFieldSet[ nIndex ]\n\ - = new FixedTextField( aTextFieldElem );\n\ - }\n\ - return this.theMetaDoc.aTextFieldSet[ nIndex ];\n\ - },\n\ -\n\ - setTextFieldVisibility : function( sClassName, nVisible )\n\ - {\n\ - var aTextField = this.aMPTextFieldSet[ sClassName ];\n\ - var aPlaceholderShape = this.masterPage.aPlaceholderShapeSet[ sClassName ];\n\ - if( !aTextField ) return;\n\ - aTextField.setVisibility( this.nAreMasterObjectsVisible & nVisible, aPlaceholderShape );\n\ - },\n\ -\n\ - getSlideAnimationsRoot : function()\n\ - {\n\ - return this.theMetaDoc.aSlideAnimationsMap[ this.slideId ];\n\ - }\n\ -\n\ - };\n\ -\n\ - function MasterPage( sMasterPageId )\n\ - {\n\ - this.id = sMasterPageId;\n\ - this.element = document.getElementById( this.id );\n\ - assert( this.element, 'MasterPage: master page element <' + this.id + '> not found.' );\n\ - this.background = getElementByClassName( this.element, 'Background' );\n\ - this.backgroundId = this.background.getAttribute( 'id' );\n\ - this.backgroundVisibility = initVisibilityProperty( this.background );\n\ - this.backgroundObjects = getElementByClassName( this.element, 'BackgroundObjects' );\n\ - this.backgroundObjectsId = this.backgroundObjects.getAttribute( 'id' );\n\ - this.backgroundObjectsVisibility = initVisibilityProperty( this.backgroundObjects );\n\ - this.aPlaceholderShapeSet = new Object();\n\ - this.initPlaceholderShapes();\n\ - }\n\ -\n\ - MasterPage.prototype =\n\ - {\n\ - setVisibility : function( nVisibility )\n\ - {\n\ - this.backgroundObjectsVisibility = setElementVisibility( this.backgroundObjects, this.backgroundObjectsVisibility, nVisibility );\n\ - },\n\ -\n\ - setVisibilityBackground : function( nVisibility )\n\ - {\n\ - this.backgroundVisibility = setElementVisibility( this.background, this.backgroundVisibility, nVisibility );\n\ - },\n\ -\n\ - hide : function()\n\ - {\n\ - this.setVisibility( HIDDEN );\n\ - },\n\ -\n\ - show : function()\n\ - {\n\ - this.setVisibility( VISIBLE );\n\ - },\n\ -\n\ - hideBackground : function()\n\ - {\n\ - this.setVisibilityBackground( HIDDEN );\n\ - },\n\ -\n\ - showBackground : function()\n\ - {\n\ - this.setVisibilityBackground( VISIBLE );\n\ - },\n\ -\n\ - initPlaceholderShapes : function()\n\ - {\n\ - this.aPlaceholderShapeSet[ aSlideNumberClassName ] = new PlaceholderShape( this, aSlideNumberClassName );\n\ - this.aPlaceholderShapeSet[ aDateTimeClassName ] = new PlaceholderShape( this, aDateTimeClassName );\n\ - this.aPlaceholderShapeSet[ aFooterClassName ] = new PlaceholderShape( this, aFooterClassName );\n\ - this.aPlaceholderShapeSet[ aHeaderClassName ] = new PlaceholderShape( this, aHeaderClassName );\n\ - }\n\ - };\n\ -\n\ - function PlaceholderShape( aMasterPage, sClassName )\n\ - {\n\ - this.masterPage = aMasterPage;\n\ - this.className = sClassName;\n\ - this.element = null;\n\ - this.textElement = null;\n\ -\n\ - this.init();\n\ - }\n\ -\n\ - PlaceholderShape.prototype.setTextContent = function( sText )\n\ - {\n\ - if( !this.textElement )\n\ - {\n\ - log( 'error: PlaceholderShape.setTextContent: text element is not valid in placeholder of type '\n\ - + this.className + ' that belongs to master slide ' + this.masterPage.id );\n\ - return;\n\ - }\n\ - this.textElement.textContent = sText;\n\ - };\n\ -\n\ - PlaceholderShape.prototype.setVisibility = function( nVisibility )\n\ - {\n\ - this.element.setAttribute( 'visibility', aVisibilityAttributeValue[nVisibility] );\n\ - };\n\ -\n\ - PlaceholderShape.prototype.show = function()\n\ - {\n\ - this.element.setAttribute( 'visibility', 'visible' );\n\ - };\n\ -\n\ - PlaceholderShape.prototype.hide = function()\n\ - {\n\ - this.element.setAttribute( 'visibility', 'hidden' );\n\ - };\n\ -\n\ - PlaceholderShape.prototype.init = function()\n\ - {\n\ - var aShapeElem = getElementByClassName( this.masterPage.backgroundObjects, this.className );\n\ - if( !aShapeElem ) return;\n\ -\n\ - this.element = aShapeElem;\n\ - this.element.setAttribute( 'visibility', 'hidden' );\n\ -\n\ - this.textElement = getElementByClassName( this.element , 'PlaceholderText' );\n\ - if( !this.textElement ) return;\n\ -\n\ -\n\ - var aSVGRectElemSet = this.element.getElementsByTagName( 'rect' );\n\ - if( aSVGRectElemSet.length != 1) return;\n\ -\n\ - var aRect = new Rectangle( aSVGRectElemSet[0] );\n\ -\n\ - var sTextAdjust = getOOOAttribute( this.element, aOOOAttrTextAdjust ) || 'left';\n\ - var sTextAnchor, sX;\n\ - if( sTextAdjust == 'left' )\n\ - {\n\ -"; - -static const char aSVGScript6[] = -"\ - sTextAnchor = 'start';\n\ - sX = String( aRect.left );\n\ - }\n\ - else if( sTextAdjust == 'right' )\n\ - {\n\ - sTextAnchor = 'end';\n\ - sX = String( aRect.right );\n\ - }\n\ - else if( sTextAdjust == 'center' )\n\ - {\n\ - sTextAnchor = 'middle';\n\ - var nMiddle = ( aRect.left + aRect.right ) / 2;\n\ - sX = String( parseInt( String( nMiddle ) ) );\n\ - }\n\ -\n\ -\n\ - this.textElement.setAttribute( 'text-anchor', sTextAnchor );\n\ - this.textElement.setAttribute( 'x', sX );\n\ - };\n\ -\n\ -\n\ - function TextField( aTextFieldElem )\n\ - {\n\ - this.bIsUpdated = false;\n\ - }\n\ -\n\ - TextField.prototype.getShapeElement = function()\n\ - {\n\ - return this.shapeElement;\n\ - };\n\ -\n\ - TextField.prototype.setVisibility = function( nVisibility, aPlaceholderShape )\n\ - {\n\ - if( !this.bIsUpdated )\n\ - {\n\ - if( nVisibility )\n\ - {\n\ - this.update( aPlaceholderShape );\n\ - this.bIsUpdated = true;\n\ - }\n\ - aPlaceholderShape.setVisibility( nVisibility );\n\ - }\n\ - else if( !nVisibility )\n\ - {\n\ - aPlaceholderShape.hide();\n\ - this.bIsUpdated = false;\n\ - }\n\ - };\n\ -\n\ - TextField.prototype.show = function( aPlaceholderShape )\n\ - {\n\ - this.setVisibility( VISIBLE, aPlaceholderShape );\n\ - };\n\ -\n\ - TextField.prototype.hide = function( aPlaceholderShape )\n\ - {\n\ - this.setVisibility( HIDDEN, aPlaceholderShape );\n\ - };\n\ -\n\ -\n\ - function FixedTextField( aTextFieldElem )\n\ - {\n\ - TextField.call( this, aTextFieldElem );\n\ - this.text = aTextFieldElem.textContent;\n\ - }\n\ - extend( FixedTextField, TextField );\n\ -\n\ - FixedTextField.prototype.update = function( aPlaceholderShape )\n\ - {\n\ - aPlaceholderShape.setTextContent( this.text );\n\ - };\n\ -\n\ -\n\ - function VariableDateTimeField( aTextFieldElem )\n\ - {\n\ - VariableDateTimeField.superclass.constructor.call( this, aTextFieldElem );\n\ - this.dateTimeFormat = getOOOAttribute( aTextFieldElem, aOOOAttrDateTimeFormat );\n\ - }\n\ - extend( VariableDateTimeField, TextField );\n\ -\n\ - VariableDateTimeField.prototype.update = function( aPlaceholderShape )\n\ - {\n\ - var sText = this.createDateTimeText( this.dateTimeFormat );\n\ - aPlaceholderShape.setTextContent( sText );\n\ - };\n\ -\n\ - VariableDateTimeField.prototype.createDateTimeText = function( sDateTimeFormat )\n\ - {\n\ - var aDate = Date();\n\ - var sDate = aDate.toLocaleString();\n\ - return sDate;\n\ - };\n\ -\n\ - function SlideNumberField( sPageNumberingType )\n\ - {\n\ - SlideNumberField.superclass.constructor.call( this, null );\n\ - this.pageNumberingType = sPageNumberingType;\n\ - }\n\ - extend( SlideNumberField, TextField );\n\ -\n\ - SlideNumberField.prototype.getNumberingType = function()\n\ - {\n\ - return this.pageNumberingType;\n\ - };\n\ -\n\ - SlideNumberField.prototype.update = function( aPlaceholderShape )\n\ - {\n\ - var sText = this.createSlideNumberText( nCurSlide + 1, this.getNumberingType() );\n\ - aPlaceholderShape.setTextContent( sText );\n\ - };\n\ -\n\ - SlideNumberField.prototype.createSlideNumberText = function( nSlideNumber, sNumberingType )\n\ - {\n\ - return String( nSlideNumber );\n\ - };\n\ -\n\ -\n\ - function SlideIndexPage()\n\ - {\n\ - this.pageElementId = 'slide_index';\n\ - this.pageBgColor = 'rgb(252,252,252)';\n\ - this.pageElement = this.createPageElement();\n\ - assert( this.pageElement, 'SlideIndexPage: pageElement is not valid' );\n\ - this.indexColumns = INDEX_COLUMNS_DEFAULT;\n\ - this.totalThumbnails = this.indexColumns * this.indexColumns;\n\ - this.selectedSlideIndex = nCurSlide;\n\ -\n\ - this.xSpacingFactor = 600/28000;\n\ - this.ySpacingFactor = 450/21000;\n\ - this.xSpacing = WIDTH * this.xSpacingFactor;\n\ - this.ySpacing = HEIGHT * this.ySpacingFactor;\n\ - this.halfBorderWidthFactor = ( 300/28000 ) * ( this.indexColumns / 3 );\n\ - this.halfBorderWidth = WIDTH * this.halfBorderWidthFactor;\n\ - this.borderWidth = 2 * this.halfBorderWidth;\n\ - this.scaleFactor = ( 1 - ( this.indexColumns + 1 ) * this.xSpacingFactor ) /\n\ - ( this.indexColumns * ( 1 + 2 * this.halfBorderWidthFactor ) );\n\ -\n\ - this.thumbnailMouseAreaTemplateId = 'thumbnail_mouse_area';\n\ - this.thumbnailMouseAreaTemplateElement = null;\n\ - this.thumbnailBorderTemplateId = 'thumbnail_border';\n\ - this.thumbnailBorderTemplateElement = null;\n\ - this.createTemplateElements();\n\ -\n\ - this.aThumbnailSet = new Array( this.totalThumbnails );\n\ - for( var i = 0; i < this.totalThumbnails; ++i )\n\ - {\n\ - this.aThumbnailSet[i] = new Thumbnail( this, i );\n\ - this.aThumbnailSet[i].updateView();\n\ - }\n\ -\n\ - this.curThumbnailIndex = this.selectedSlideIndex % this.totalThumbnails;\n\ - this.aThumbnailSet[ this.curThumbnailIndex ].select();\n\ - }\n\ -\n\ -\n\ - SlideIndexPage.prototype.getTotalThumbnails = function()\n\ - {\n\ - return this.totalThumbnails;\n\ - };\n\ -\n\ - SlideIndexPage.prototype.show = function()\n\ - {\n\ - this.pageElement.setAttribute( 'display', 'inherit' );\n\ - };\n\ -\n\ - SlideIndexPage.prototype.hide = function()\n\ - {\n\ - this.pageElement.setAttribute( 'display', 'none' );\n\ - };\n\ -\n\ - SlideIndexPage.prototype.setSelection = function( nIndex )\n\ - {\n\ - nIndex = getSafeIndex( nIndex, 0, this.getTotalThumbnails() - 1 );\n\ - if( this.curThumbnailIndex != nIndex )\n\ - {\n\ - this.aThumbnailSet[ this.curThumbnailIndex ].unselect();\n\ - this.aThumbnailSet[ nIndex ].select();\n\ - this.curThumbnailIndex = nIndex;\n\ - }\n\ - this.selectedSlideIndex = this.aThumbnailSet[ nIndex ].slideIndex;\n\ - };\n\ -\n\ - SlideIndexPage.prototype.createPageElement = function()\n\ - {\n\ - var aPageElement = document.createElementNS( NSS['svg'], 'g' );\n\ - aPageElement.setAttribute( 'id', this.pageElementId );\n\ - aPageElement.setAttribute( 'display', 'none' );\n\ -\n\ - var sPageBgColor = this.pageBgColor + ';';\n\ - var aRectElement = document.createElementNS( NSS['svg'], 'rect' );\n\ - aRectElement.setAttribute( 'x', 0 );\n\ - aRectElement.setAttribute( 'y', 0 );\n\ - aRectElement.setAttribute( 'width', WIDTH );\n\ - aRectElement.setAttribute( 'height', HEIGHT );\n\ - aRectElement.setAttribute( 'style', 'stroke:none;fill:' + sPageBgColor );\n\ -\n\ - aPageElement.appendChild( aRectElement );\n\ - ROOT_NODE.appendChild( aPageElement );\n\ - return( document.getElementById( this.pageElementId ) );\n\ - };\n\ -"; - -static const char aSVGScript7[] = -"\ -\n\ - SlideIndexPage.prototype.createTemplateElements = function()\n\ - {\n\ - var aDefsElement = document.createElementNS( NSS['svg'], 'defs' );\n\ - var aRectElement = document.createElementNS( NSS['svg'], 'rect' );\n\ - aRectElement.setAttribute( 'id', this.thumbnailBorderTemplateId );\n\ - aRectElement.setAttribute( 'x', -this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'y', -this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'rx', this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'ry', this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'width', WIDTH + this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'height', HEIGHT + this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'stroke-width', this.borderWidth );\n\ - aRectElement.setAttribute( 'fill', 'none' );\n\ - aDefsElement.appendChild( aRectElement );\n\ -\n\ - aRectElement = document.createElementNS( NSS['svg'], 'rect' );\n\ - aRectElement.setAttribute( 'id', this.thumbnailMouseAreaTemplateId );\n\ - aRectElement.setAttribute( 'x', 0 );\n\ - aRectElement.setAttribute( 'y', 0 );\n\ - aRectElement.setAttribute( 'width', WIDTH );\n\ - aRectElement.setAttribute( 'height', HEIGHT );\n\ - aRectElement.setAttribute( 'fill', this.pageBgColor );\n\ - aDefsElement.appendChild( aRectElement );\n\ -\n\ - this.pageElement.appendChild( aDefsElement );\n\ -\n\ - this.thumbnailMouseAreaTemplateElement = document.getElementById( this.thumbnailMouseAreaTemplateId );\n\ - this.thumbnailBorderTemplateElement = document.getElementById( this.thumbnailBorderTemplateId );\n\ - };\n\ -\n\ - SlideIndexPage.prototype.decreaseNumberOfColumns = function()\n\ - {\n\ - this.setNumberOfColumns( this.indexColumns - 1 );\n\ - };\n\ -\n\ - SlideIndexPage.prototype.increaseNumberOfColumns = function()\n\ - {\n\ - this.setNumberOfColumns( this.indexColumns + 1 );\n\ - };\n\ -\n\ - SlideIndexPage.prototype.resetNumberOfColumns = function()\n\ - {\n\ - this.setNumberOfColumns( INDEX_COLUMNS_DEFAULT );\n\ - };\n\ -\n\ - SlideIndexPage.prototype.setNumberOfColumns = function( nNumberOfColumns )\n\ - {\n\ - if( this.indexColumns == nNumberOfColumns ) return;\n\ - if( nNumberOfColumns < 2 || nNumberOfColumns > 6 ) return;\n\ -\n\ - var suspendHandle = ROOT_NODE.suspendRedraw(500);\n\ -\n\ - var nOldTotalThumbnails = this.totalThumbnails;\n\ - this.indexColumns = nNumberOfColumns;\n\ - this.totalThumbnails = nNumberOfColumns * nNumberOfColumns;;\n\ -\n\ - this.aThumbnailSet[this.curThumbnailIndex].unselect();\n\ -\n\ - for( var i = this.totalThumbnails; i < nOldTotalThumbnails; ++i )\n\ - {\n\ - this.aThumbnailSet[i].removeElement();\n\ - };\n\ -\n\ - for( var i = nOldTotalThumbnails; i < this.totalThumbnails; ++i )\n\ - {\n\ - this.aThumbnailSet[i] = new Thumbnail( this, i );\n\ - };\n\ -\n\ - this.halfBorderWidthFactor = ( 300/28000 ) * ( this.indexColumns / 3 );\n\ - this.halfBorderWidth = WIDTH * this.halfBorderWidthFactor;\n\ - this.borderWidth = 2 * this.halfBorderWidth;\n\ - this.scaleFactor = ( 1 - ( this.indexColumns + 1 ) * this.xSpacingFactor ) /\n\ - ( this.indexColumns * ( 1 + 2 * this.halfBorderWidthFactor ) );\n\ -\n\ - var aRectElement = this.thumbnailBorderTemplateElement;\n\ - aRectElement.setAttribute( 'x', -this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'y', -this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'rx', this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'ry', this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'width', WIDTH + this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'height', HEIGHT + this.halfBorderWidth );\n\ - aRectElement.setAttribute( 'stroke-width', this.borderWidth );\n\ -\n\ - for( var i = 0; i < this.totalThumbnails; ++i )\n\ - {\n\ - this.aThumbnailSet[i].updateView();\n\ - }\n\ -\n\ - this.curThumbnailIndex = this.selectedSlideIndex % this.totalThumbnails;\n\ - this.aThumbnailSet[this.curThumbnailIndex].select();\n\ -\n\ - INDEX_OFFSET = -1;\n\ - indexSetPageSlide( this.selectedSlideIndex );\n\ -\n\ - ROOT_NODE.unsuspendRedraw( suspendHandle );\n\ - ROOT_NODE.forceRedraw();\n\ - };\n\ -\n\ -\n\ - function Thumbnail( aSlideIndexPage, nIndex )\n\ - {\n\ - this.container = aSlideIndexPage;\n\ - this.index = nIndex;//= getSafeIndex( nIndex, 0, this.container.getTotalThumbnails() );\n\ - this.pageElement = this.container.pageElement;\n\ - this.thumbnailId = 'thumbnail' + this.index;\n\ - this.thumbnailElement = this.createThumbnailElement();\n\ - this.slideElement = getElementByClassName( this.thumbnailElement, 'Slide' );\n\ - this.backgroundElement = getElementByClassName( this.thumbnailElement, 'Background' );\n\ - this.backgroundObjectsElement = getElementByClassName( this.thumbnailElement, 'BackgroundObjects' );\n\ - this.borderElement = getElementByClassName( this.thumbnailElement, 'Border' );\n\ - this.aTransformSet = new Array( 3 );\n\ - this.visibility = VISIBLE;\n\ - this.isSelected = false;\n\ - };\n\ -\n\ - Thumbnail.prototype.sNormalBorderColor = 'rgb(216,216,216)';\n\ - Thumbnail.prototype.sSelectionBorderColor = 'rgb(92,92,255)';\n\ -\n\ - Thumbnail.prototype.removeElement = function()\n\ - {\n\ - if( this.thumbnailElement )\n\ - this.container.pageElement.removeChild( this.thumbnailElement );\n\ - };\n\ -\n\ - Thumbnail.prototype.show = function()\n\ - {\n\ - if( this.visibility == HIDDEN )\n\ - {\n\ - this.thumbnailElement.setAttribute( 'display', 'inherit' );\n\ - this.visibility = VISIBLE;\n\ - }\n\ - };\n\ -\n\ - Thumbnail.prototype.hide = function()\n\ - {\n\ - if( this.visibility == VISIBLE )\n\ - {\n\ - this.thumbnailElement.setAttribute( 'display', 'none' );\n\ - this.visibility = HIDDEN;\n\ - }\n\ - };\n\ -\n\ - Thumbnail.prototype.select = function()\n\ - {\n\ - if( !this.isSelected )\n\ - {\n\ - this.borderElement.setAttribute( 'stroke', this.sSelectionBorderColor );\n\ - this.isSelected = true;\n\ - }\n\ - };\n\ -\n\ - Thumbnail.prototype.unselect = function()\n\ - {\n\ - if( this.isSelected )\n\ - {\n\ - this.borderElement.setAttribute( 'stroke', this.sNormalBorderColor );\n\ - this.isSelected = false;\n\ - }\n\ - };\n\ -\n\ - Thumbnail.prototype.updateView = function()\n\ - {\n\ - this.column = this.index % this.container.indexColumns;\n\ - this.row = ( this.index - this.column ) / this.container.indexColumns;\n\ - this.halfBorderWidth = this.container.halfBorderWidth;\n\ - this.borderWidth = this.container.borderWidth;\n\ - this.width = ( WIDTH + this.borderWidth ) * this.container.scaleFactor;\n\ - this.height = ( HEIGHT + this.borderWidth ) * this.container.scaleFactor;\n\ - this.aTransformSet[2] = 'translate(' + this.halfBorderWidth + ' ' + this.halfBorderWidth + ')';\n\ - this.aTransformSet[1] = 'scale(' + this.container.scaleFactor + ')';\n\ - var sTransformAttrValue = this.computeTransform();\n\ - this.thumbnailElement.setAttribute( 'transform', sTransformAttrValue );\n\ - this.thumbnailElement.setAttribute( 'onmouseover', 'theSlideIndexPage.aThumbnailSet[' + this.index + '].onMouseOver()' );\n\ - };\n\ -\n\ - Thumbnail.prototype.update = function( nIndex )\n\ - {\n\ - if( this.slideIndex == nIndex ) return;\n\ -\n\ - var aMetaSlide = theMetaDoc.aMetaSlideSet[nIndex];\n\ - setNSAttribute( 'xlink', this.slideElement, 'href', '#' + aMetaSlide.slideId );\n\ - if( aMetaSlide.nIsBackgroundVisible )\n\ - {\n\ - setNSAttribute( 'xlink', this.backgroundElement, 'href', '#' + aMetaSlide.masterPage.backgroundId );\n\ - this.backgroundElement.setAttribute( 'visibility', 'inherit' );\n\ - }\n\ - else\n\ - {\n\ - this.backgroundElement.setAttribute( 'visibility', 'hidden' );\n\ - }\n\ - if( aMetaSlide.nAreMasterObjectsVisible )\n\ - {\n\ - setNSAttribute( 'xlink', this.backgroundObjectsElement, 'href', '#' + aMetaSlide.masterPage.backgroundObjectsId );\n\ - this.backgroundObjectsElement.setAttribute( 'visibility', 'inherit' );\n\ - }\n\ - else\n\ - {\n\ - this.backgroundObjectsElement.setAttribute( 'visibility', 'hidden' );\n\ - }\n\ -"; - -static const char aSVGScript8[] = -"\ - this.slideIndex = nIndex;\n\ - };\n\ -\n\ - Thumbnail.prototype.clear = function( nIndex )\n\ - {\n\ - setNSAttribute( 'xlink', this.slideElement, 'href', '' );\n\ - setNSAttribute( 'xlink', this.backgroundElement, 'href', '' );\n\ - setNSAttribute( 'xlink', this.backgroundObjectsElement, 'href', '' );\n\ - };\n\ -\n\ - Thumbnail.prototype.createThumbnailElement = function()\n\ - {\n\ - var aThumbnailElement = document.createElementNS( NSS['svg'], 'g' );\n\ - aThumbnailElement.setAttribute( 'id', this.thumbnailId );\n\ - aThumbnailElement.setAttribute( 'display', 'inherit' );\n\ -\n\ - var aMouseAreaElement = document.createElementNS( NSS['svg'], 'use' );\n\ - setNSAttribute( 'xlink', aMouseAreaElement, 'href', '#' + this.container.thumbnailMouseAreaTemplateId );\n\ - aMouseAreaElement.setAttribute( 'class', 'MouseArea' );\n\ - aThumbnailElement.appendChild( aMouseAreaElement );\n\ -\n\ - var aBackgroundElement = document.createElementNS( NSS['svg'], 'use' );\n\ - setNSAttribute( 'xlink', aBackgroundElement, 'href', '' );\n\ - aBackgroundElement.setAttribute( 'visibility', 'inherit');\n\ - aBackgroundElement.setAttribute( 'class', 'Background' );\n\ - aThumbnailElement.appendChild( aBackgroundElement );\n\ -\n\ - var aBackgroundObjectsElement = document.createElementNS( NSS['svg'], 'use' );\n\ - setNSAttribute( 'xlink', aBackgroundObjectsElement, 'href', '' );\n\ - aBackgroundObjectsElement.setAttribute( 'visibility', 'inherit');\n\ - aBackgroundObjectsElement.setAttribute( 'class', 'BackgroundObjects' );\n\ - aThumbnailElement.appendChild( aBackgroundObjectsElement );\n\ -\n\ - var aSlideElement = document.createElementNS( NSS['svg'], 'use' );\n\ - setNSAttribute( 'xlink', aSlideElement, 'href', '' );\n\ - aSlideElement.setAttribute( 'class', 'Slide' );\n\ - aThumbnailElement.appendChild( aSlideElement );\n\ -\n\ - var aBorderElement = document.createElementNS( NSS['svg'], 'use' );\n\ - setNSAttribute( 'xlink', aBorderElement, 'href', '#' + this.container.thumbnailBorderTemplateId );\n\ - aBorderElement.setAttribute( 'stroke', this.sNormalBorderColor );\n\ - aBorderElement.setAttribute( 'class', 'Border' );\n\ - aThumbnailElement.appendChild( aBorderElement );\n\ -\n\ - this.container.pageElement.appendChild( aThumbnailElement );\n\ - return( document.getElementById( this.thumbnailId ) );\n\ - };\n\ -\n\ - Thumbnail.prototype.computeTransform = function()\n\ - {\n\ - var nXSpacing = this.container.xSpacing;\n\ - var nYSpacing = this.container.ySpacing;\n\ -\n\ - var nXOffset = nXSpacing + ( this.width + nXSpacing ) * this.column;\n\ - var nYOffset = nYSpacing + ( this.height + nYSpacing ) * this.row;\n\ -\n\ - this.aTransformSet[0] = 'translate(' + nXOffset + ' ' + nYOffset + ')';\n\ -\n\ - sTransform = this.aTransformSet.join( ' ' );\n\ -\n\ - return sTransform;\n\ - };\n\ -\n\ - Thumbnail.prototype.onMouseOver = function()\n\ - {\n\ - if( ( currentMode == INDEX_MODE ) && ( this.container.curThumbnailIndex != this.index ) )\n\ - {\n\ - this.container.setSelection( this.index );\n\ - }\n\ - };\n\ -\n\ -\n\ - function init()\n\ - {\n\ - var VIEWBOX = ROOT_NODE.getAttribute('viewBox');\n\ -\n\ - if( VIEWBOX )\n\ - {\n\ - WIDTH = ROOT_NODE.viewBox.animVal.width;\n\ - HEIGHT = ROOT_NODE.viewBox.animVal.height;\n\ - }\n\ -\n\ - var aMetaDocElem = document.getElementById( aOOOElemMetaSlides );\n\ - assert( aMetaDocElem, 'init: meta document element not found' );\n\ - aSlideShow = new SlideShow();\n\ - theMetaDoc = new MetaDocument( aMetaDocElem );\n\ - theSlideIndexPage = new SlideIndexPage();\n\ -\n\ -\n\ - }\n\ -\n\ - function presentationEngineStop()\n\ - {\n\ - alert( 'We are sorry! An unexpected error occurred.\\nThe presentation engine will be stopped' );\n\ - document.onkeydown = null;\n\ - document.onkeypress = null;\n\ - document.onclick = null;\n\ - window.onmousewheel = null;\n\ - }\n\ -\n\ - function assert( condition, message )\n\ - {\n\ - if (!condition)\n\ - {\n\ - presentationEngineStop();\n\ - if (typeof console == 'object')\n\ - console.trace();\n\ - throw new Error( message );\n\ - }\n\ - }\n\ -\n\ - function dispatchEffects(dir)\n\ - {\n\ -\n\ - if( dir == 1 )\n\ - {\n\ - var bRet = aSlideShow.nextEffect();\n\ -\n\ - if( !bRet )\n\ - {\n\ - switchSlide( 1 );\n\ - }\n\ - }\n\ - else\n\ - {\n\ - switchSlide( dir );\n\ - }\n\ - }\n\ -\n\ - function skipEffects(dir)\n\ - {\n\ - switchSlide(dir);\n\ - }\n\ -\n\ - function switchSlide( nOffset, bSkipTransition )\n\ - {\n\ - var nNextSlide = nCurSlide + nOffset;\n\ - aSlideShow.displaySlide( nNextSlide, bSkipTransition );\n\ - }\n\ -\n\ - function displayIndex( offsetNumber )\n\ - {\n\ - var aMetaSlideSet = theMetaDoc.aMetaSlideSet;\n\ - offsetNumber = getSafeIndex( offsetNumber, 0, aMetaSlideSet.length - 1 );\n\ -\n\ - var nTotalThumbnails = theSlideIndexPage.getTotalThumbnails();\n\ - var nEnd = Math.min( offsetNumber + nTotalThumbnails, aMetaSlideSet.length);\n\ -\n\ - var aThumbnailSet = theSlideIndexPage.aThumbnailSet;\n\ - var j = 0;\n\ - for( var i = offsetNumber; i < nEnd; ++i, ++j )\n\ - {\n\ - aThumbnailSet[j].update( i );\n\ - aThumbnailSet[j].show();\n\ - }\n\ - for( ; j < nTotalThumbnails; ++j )\n\ - {\n\ - aThumbnailSet[j].hide();\n\ - }\n\ -\n\ - if (INDEX_OFFSET != offsetNumber)\n\ - INDEX_OFFSET = offsetNumber;\n\ - }\n\ -\n\ -\n\ - function toggleSlideIndex()\n\ - {\n\ - var suspendHandle = ROOT_NODE.suspendRedraw(500);\n\ - var aMetaSlideSet = theMetaDoc.aMetaSlideSet;\n\ -\n\ - if (currentMode == SLIDE_MODE)\n\ - {\n\ - aMetaSlideSet[nCurSlide].hide();\n\ - for( var counter = 0; counter < aMetaSlideSet.length; ++counter )\n\ - {\n\ - checkElemAndSetAttribute( aMetaSlideSet[counter].slideElement, 'visibility', 'inherit' );\n\ - aMetaSlideSet[counter].masterPage.setVisibilityBackground( INHERIT );\n\ - aMetaSlideSet[counter].masterPage.setVisibility( INHERIT );\n\ - }\n\ - INDEX_OFFSET = -1;\n\ - indexSetPageSlide( nCurSlide );\n\ - theSlideIndexPage.show();\n\ - currentMode = INDEX_MODE;\n\ - }\n\ - else if (currentMode == INDEX_MODE)\n\ - {\n\ - theSlideIndexPage.hide();\n\ - var nNewSlide = theSlideIndexPage.selectedSlideIndex;\n\ -\n\ - for( var counter = 0; counter < aMetaSlideSet.length; ++counter )\n\ - {\n\ - var aMetaSlide = aMetaSlideSet[counter];\n\ - aMetaSlide.slideElement.setAttribute( 'visibility', 'hidden' );\n\ - aMetaSlide.masterPage.setVisibilityBackground( HIDDEN );\n\ - aMetaSlide.masterPage.setVisibility( HIDDEN );\n\ - }\n\ -\n\ - aSlideShow.displaySlide( nNewSlide, true );\n\ - currentMode = SLIDE_MODE;\n\ - }\n\ -"; - -static const char aSVGScript9[] = -"\ -\n\ - ROOT_NODE.unsuspendRedraw(suspendHandle);\n\ - ROOT_NODE.forceRedraw();\n\ - }\n\ -\n\ - function abandonIndexMode()\n\ - {\n\ - theSlideIndexPage.selectedSlideIndex = nCurSlide;\n\ - toggleSlideIndex();\n\ - }\n\ -\n\ -\n\ - var CURR_UNIQUE_ID = 0;\n\ -\n\ - function getUniqueId()\n\ - {\n\ - ++CURR_UNIQUE_ID;\n\ - return CURR_UNIQUE_ID;\n\ - }\n\ -\n\ - function mem_fn( sMethodName )\n\ - {\n\ - return function( aObject )\n\ - {\n\ - var aMethod = aObject[ sMethodName ];\n\ - if( aMethod )\n\ - aMethod.call( aObject );\n\ - else\n\ - log( 'method sMethodName not found' );\n\ - };\n\ - }\n\ -\n\ - function bind( aObject, aMethod )\n\ - {\n\ - return function()\n\ - {\n\ - return aMethod.call( aObject, arguments[0] );\n\ - };\n\ - }\n\ -\n\ - function getCurrentSystemTime()\n\ - {\n\ - return ( new Date() ).getTime();\n\ - }\n\ -\n\ - function getSlideAnimationsRoot( sSlideId )\n\ - {\n\ - return theMetaDoc.aSlideAnimationsMap[ sSlideId ];\n\ - }\n\ -\n\ - function getElementChildren( aElement )\n\ - {\n\ - var aChildrenArray = new Array();\n\ -\n\ - var nSize = aElement.childNodes.length;\n\ -\n\ - for( var i = 0; i < nSize; ++i )\n\ - {\n\ - if( aElement.childNodes[i].nodeType == 1 )\n\ - aChildrenArray.push( aElement.childNodes[i] );\n\ - }\n\ -\n\ - return aChildrenArray;\n\ - }\n\ -\n\ - function removeWhiteSpaces( str )\n\ - {\n\ - if( !str )\n\ - return '';\n\ -\n\ - var re = / */;\n\ - var aSplittedString = str.split( re );\n\ - return aSplittedString.join('');\n\ - }\n\ -\n\ - function clamp( nValue, nMinimum, nMaximum )\n\ - {\n\ - if( nValue < nMinimum )\n\ - {\n\ - return nMinimum;\n\ - }\n\ - else if( nValue > nMaximum )\n\ - {\n\ - return nMaximum;\n\ - }\n\ - else\n\ - {\n\ - return nValue;\n\ - }\n\ - }\n\ -\n\ - function makeMatrixString( a, b, c, d, e, f )\n\ - {\n\ - var s = 'matrix(';\n\ - s += a + ', ';\n\ - s += b + ', ';\n\ - s += c + ', ';\n\ - s += d + ', ';\n\ - s += e + ', ';\n\ - s += f + ')';\n\ -\n\ - return s;\n\ - }\n\ -\n\ - function matrixToString( aSVGMatrix )\n\ - {\n\ - return makeMatrixString( aSVGMatrix.a, aSVGMatrix.b, aSVGMatrix.c,\n\ - aSVGMatrix.d, aSVGMatrix.e, aSVGMatrix.f );\n\ - }\n\ -\n\ -\n\ - function numberParser( sValue )\n\ - {\n\ - if( sValue === '.' )\n\ - return undefined;\n\ - var reFloatNumber = /^[+-]?[0-9]*[.]?[0-9]*$/;\n\ -\n\ - if( reFloatNumber.test( sValue ) )\n\ - return parseFloat( sValue );\n\ - else\n\ - return undefined;\n\ - }\n\ -\n\ - function booleanParser( sValue )\n\ - {\n\ - sValue = sValue.toLowerCase();\n\ - if( sValue === 'true' )\n\ - return true;\n\ - else if( sValue === 'false' )\n\ - return false;\n\ - else\n\ - return undefined;\n\ - }\n\ -\n\ - function colorParser( sValue )\n\ - {\n\ -\n\ - function hsl( nHue, nSaturation, nLuminance )\n\ - {\n\ - return new HSLColor( nHue, nSaturation / 100, nLuminance / 100 );\n\ - }\n\ -\n\ - function rgb( nRed, nGreen, nBlue )\n\ - {\n\ - return new RGBColor( nRed / 255, nGreen / 255, nBlue / 255 );\n\ - }\n\ -\n\ - function prgb( nRed, nGreen, nBlue )\n\ - {\n\ - return new RGBColor( nRed / 100, nGreen / 100, nBlue / 100 );\n\ - }\n\ -\n\ - var sCommaPattern = ' *[,] *';\n\ - var sIntegerPattern = '[+-]?[0-9]+';\n\ - var sHexDigitPattern = '[0-9A-Fa-f]';\n\ -\n\ - var sHexColorPattern = '#(' + sHexDigitPattern + '{2})('\n\ - + sHexDigitPattern + '{2})('\n\ - + sHexDigitPattern + '{2})';\n\ -\n\ - var sRGBIntegerPattern = 'rgb[(] *' + sIntegerPattern + sCommaPattern\n\ - + sIntegerPattern + sCommaPattern\n\ - + sIntegerPattern + ' *[)]';\n\ -\n\ - var sRGBPercentPattern = 'rgb[(] *' + sIntegerPattern + '%' + sCommaPattern\n\ - + sIntegerPattern + '%' + sCommaPattern\n\ - + sIntegerPattern + '%' + ' *[)]';\n\ -\n\ - var sHSLPercentPattern = 'hsl[(] *' + sIntegerPattern + sCommaPattern\n\ - + sIntegerPattern + '%' + sCommaPattern\n\ - + sIntegerPattern + '%' + ' *[)]';\n\ -\n\ - var reHexColor = RegExp( sHexColorPattern );\n\ - var reRGBInteger = RegExp( sRGBIntegerPattern );\n\ - var reRGBPercent = RegExp( sRGBPercentPattern );\n\ - var reHSLPercent = RegExp( sHSLPercentPattern );\n\ -\n\ - if( reHexColor.test( sValue ) )\n\ - {\n\ - var aRGBTriple = reHexColor.exec( sValue );\n\ -\n\ - var nRed = parseInt( aRGBTriple[1], 16 ) / 255;\n\ - var nGreen = parseInt( aRGBTriple[2], 16 ) / 255;\n\ - var nBlue = parseInt( aRGBTriple[3], 16 ) / 255;\n\ -\n\ - return new RGBColor( nRed, nGreen, nBlue );\n\ - }\n\ - else if( reHSLPercent.test( sValue ) )\n\ - {\n\ - sValue = sValue.replace( '%', '' ).replace( '%', '' );\n\ - return eval( sValue );\n\ - }\n\ - else if( reRGBInteger.test( sValue ) )\n\ - {\n\ - return eval( sValue );\n\ - }\n\ - else if( reRGBPercent.test( sValue ) )\n\ - {\n\ - sValue = 'p' + sValue.replace( '%', '' ).replace( '%', '' ).replace( '%', '' );\n\ - return eval( sValue );\n\ -"; - -static const char aSVGScript10[] = -"\ - }\n\ - else\n\ - {\n\ - return null;\n\ - }\n\ - }\n\ -\n\ -\n\ - function RGBColor( nRed, nGreen, nBlue )\n\ - {\n\ - this.eColorSpace = COLOR_SPACE_RGB;\n\ - this.nRed = nRed;\n\ - this.nGreen = nGreen;\n\ - this.nBlue = nBlue;\n\ - }\n\ -\n\ -\n\ - RGBColor.prototype.clone = function()\n\ - {\n\ - return new RGBColor( this.nRed, this.nGreen, this.nBlue );\n\ - };\n\ -\n\ - RGBColor.prototype.add = function( aRGBColor )\n\ - {\n\ - this.nRed += aRGBColor.nRed;\n\ - this.nGreen += aRGBColor.nGreen;\n\ - this.nBlue += aRGBColor.nBlue;\n\ - return this;\n\ - };\n\ -\n\ - RGBColor.prototype.scale = function( aT )\n\ - {\n\ - this.nRed *= aT;\n\ - this.nGreen *= aT;\n\ - this.nBlue *= aT;\n\ - return this;\n\ - };\n\ -\n\ - RGBColor.clamp = function( aRGBColor )\n\ - {\n\ - var aClampedRGBColor = new RGBColor( 0, 0, 0 );\n\ -\n\ - aClampedRGBColor.nRed = clamp( aRGBColor.nRed, 0.0, 1.0 );\n\ - aClampedRGBColor.nGreen = clamp( aRGBColor.nGreen, 0.0, 1.0 );\n\ - aClampedRGBColor.nBlue = clamp( aRGBColor.nBlue, 0.0, 1.0 );\n\ -\n\ - return aClampedRGBColor;\n\ - };\n\ -\n\ - RGBColor.prototype.convertToHSL = function()\n\ - {\n\ - var nRed = clamp( this.nRed, 0.0, 1.0 );\n\ - var nGreen = clamp( this.nGreen, 0.0, 1.0 );\n\ - var nBlue = clamp( this.nBlue, 0.0, 1.0 );\n\ -\n\ - var nMax = Math.max( nRed, nGreen, nBlue );\n\ - var nMin = Math.min( nRed, nGreen, nBlue );\n\ - var nDelta = nMax - nMin;\n\ -\n\ - var nLuminance = ( nMax + nMin ) / 2.0;\n\ - var nSaturation = 0.0;\n\ - var nHue = 0.0;\n\ - if( nDelta !== 0 )\n\ - {\n\ - nSaturation = ( nLuminance > 0.5 ) ?\n\ - ( nDelta / ( 2.0 - nMax - nMin) ) :\n\ - ( nDelta / ( nMax + nMin ) );\n\ -\n\ - if( nRed == nMax )\n\ - nHue = ( nGreen - nBlue ) / nDelta;\n\ - else if( nGreen == nMax )\n\ - nHue = 2.0 + ( nBlue - nRed ) / nDelta;\n\ - else if( nBlue == nMax )\n\ - nHue = 4.0 + ( nRed - nGreen ) / nDelta;\n\ -\n\ - nHue *= 60.0;\n\ -\n\ - if( nHue < 0.0 )\n\ - nHue += 360.0;\n\ - }\n\ -\n\ - return new HSLColor( nHue, nSaturation, nLuminance );\n\ -\n\ - };\n\ -\n\ - RGBColor.prototype.toString = function( bClamped )\n\ - {\n\ - var aRGBColor;\n\ - if( bClamped )\n\ - {\n\ - aRGBColor = RGBColor.clamp( this );\n\ - }\n\ - else\n\ - {\n\ - aRGBColor = this;\n\ - }\n\ -\n\ - var nRed = Math.round( aRGBColor.nRed * 255 );\n\ - var nGreen = Math.round( aRGBColor.nGreen * 255 );\n\ - var nBlue = Math.round( aRGBColor.nBlue * 255 );\n\ -\n\ - return ( 'rgb(' + nRed + ',' + nGreen + ',' + nBlue + ')' );\n\ - };\n\ -\n\ - RGBColor.interpolate = function( aStartRGB , aEndRGB, nT )\n\ - {\n\ - var aResult = aStartRGB.clone();\n\ - var aTEndRGB = aEndRGB.clone();\n\ - aResult.scale( 1.0 - nT );\n\ - aTEndRGB.scale( nT );\n\ - aResult.add( aTEndRGB );\n\ -\n\ - return aResult;\n\ - };\n\ -\n\ -\n\ - function HSLColor( nHue, nSaturation, nLuminance )\n\ - {\n\ - this.eColorSpace = COLOR_SPACE_HSL;\n\ - this.nHue = nHue;\n\ - this.nSaturation = nSaturation;\n\ - this.nLuminance = nLuminance;\n\ -\n\ - this.normalizeHue();\n\ - }\n\ -\n\ -\n\ - HSLColor.prototype.clone = function()\n\ - {\n\ - return new HSLColor( this.nHue, this.nSaturation, this.nLuminance );\n\ - };\n\ -\n\ - HSLColor.prototype.add = function( aHSLColor )\n\ - {\n\ - this.nHue += aHSLColor.nHue;\n\ - this.nSaturation += aHSLColor.nSaturation;\n\ - this.nLuminance += aHSLColor.nLuminance;\n\ - this.normalizeHue();\n\ - return this;\n\ - };\n\ -\n\ - HSLColor.prototype.scale = function( aT )\n\ - {\n\ - this.nHue *= aT;\n\ - this.nSaturation *= aT;\n\ - this.nLuminance *= aT;\n\ - this.normalizeHue();\n\ - return this;\n\ - };\n\ -\n\ - HSLColor.clamp = function( aHSLColor )\n\ - {\n\ - var aClampedHSLColor = new HSLColor( 0, 0, 0 );\n\ -\n\ - aClampedHSLColor.nHue = aHSLColor.nHue % 360;\n\ - if( aClampedHSLColor.nHue < 0 )\n\ - aClampedHSLColor.nHue += 360;\n\ - aClampedHSLColor.nSaturation = clamp( aHSLColor.nSaturation, 0.0, 1.0 );\n\ - aClampedHSLColor.nLuminance = clamp( aHSLColor.nLuminance, 0.0, 1.0 );\n\ - };\n\ -\n\ - HSLColor.prototype.normalizeHue = function()\n\ - {\n\ - this.nHue = this.nHue % 360;\n\ - if( this.nHue < 0 ) this.nHue += 360;\n\ - };\n\ -\n\ - HSLColor.prototype.toString = function()\n\ - {\n\ - return 'hsl(' + this.nHue.toFixed( 3 ) + ','\n\ - + this.nSaturation.toFixed( 3 ) + ','\n\ - + this.nLuminance.toFixed( 3 ) + ')';\n\ - };\n\ -\n\ - HSLColor.prototype.convertToRGB = function()\n\ - {\n\ -\n\ - var nHue = this.nHue % 360;\n\ - if( nHue < 0 ) nHue += 360;\n\ - var nSaturation = clamp( this.nSaturation, 0.0, 1.0 );\n\ - var nLuminance = clamp( this.nLuminance, 0.0, 1.0 );\n\ -\n\ -\n\ - if( nSaturation === 0 )\n\ - {\n\ - return new RGBColor( nLuminance, nLuminance, nLuminance );\n\ - }\n\ -\n\ - var nVal1 = ( nLuminance <= 0.5 ) ?\n\ - ( nLuminance * (1.0 + nSaturation) ) :\n\ - ( nLuminance + nSaturation - nLuminance * nSaturation );\n\ -\n\ - var nVal2 = 2.0 * nLuminance - nVal1;\n\ -\n\ - var nRed = HSLColor.hsl2rgbHelper( nVal2, nVal1, nHue + 120 );\n\ - var nGreen = HSLColor.hsl2rgbHelper( nVal2, nVal1, nHue );\n\ - var nBlue = HSLColor.hsl2rgbHelper( nVal2, nVal1, nHue - 120 );\n\ -\n\ - return new RGBColor( nRed, nGreen, nBlue );\n\ - };\n\ -"; - -static const char aSVGScript11[] = -"\ -\n\ - HSLColor.hsl2rgbHelper = function( nValue1, nValue2, nHue )\n\ - {\n\ - nHue = nHue % 360;\n\ - if( nHue < 0 )\n\ - nHue += 360;\n\ -\n\ - if( nHue < 60.0 )\n\ - return nValue1 + ( nValue2 - nValue1 ) * nHue / 60.0;\n\ - else if( nHue < 180.0 )\n\ - return nValue2;\n\ - else if( nHue < 240.0 )\n\ - return ( nValue1 + ( nValue2 - nValue1 ) * ( 240.0 - nHue ) / 60.0 );\n\ - else\n\ - return nValue1;\n\ - };\n\ -\n\ - HSLColor.interpolate = function( aFrom, aTo, nT, bCCW )\n\ - {\n\ - var nS = 1.0 - nT;\n\ -\n\ - var nHue = 0.0;\n\ - if( aFrom.nHue <= aTo.nHue && !bCCW )\n\ - {\n\ - nHue = nS * (aFrom.nHue + 360.0) + nT * aTo.nHue;\n\ - }\n\ - else if( aFrom.nHue > aTo.nHue && bCCW )\n\ - {\n\ - nHue = nS * aFrom.nHue + nT * (aTo.nHue + 360.0);\n\ - }\n\ - else\n\ - {\n\ - nHue = nS * aFrom.nHue + nT * aTo.nHue;\n\ - }\n\ -\n\ - var nSaturation = nS * aFrom.nSaturation + nT * aTo.nSaturation;\n\ - var nLuminance = nS * aFrom.nLuminance + nT * aTo.nLuminance;\n\ -\n\ - return new HSLColor( nHue, nSaturation, nLuminance );\n\ - };\n\ -\n\ -\n\ - var ANIMATION_NODE_CUSTOM = 0;\n\ - var ANIMATION_NODE_PAR = 1;\n\ - var ANIMATION_NODE_SEQ = 2;\n\ - var ANIMATION_NODE_ITERATE = 3;\n\ - var ANIMATION_NODE_ANIMATE = 4;\n\ - var ANIMATION_NODE_SET = 5;\n\ - var ANIMATION_NODE_ANIMATEMOTION = 6;\n\ - var ANIMATION_NODE_ANIMATECOLOR = 7;\n\ - var ANIMATION_NODE_ANIMATETRANSFORM = 8;\n\ - var ANIMATION_NODE_TRANSITIONFILTER = 9;\n\ - var ANIMATION_NODE_AUDIO = 10;\n\ - var ANIMATION_NODE_COMMAND = 11;\n\ -\n\ - aAnimationNodeTypeInMap = {\n\ - 'par' : ANIMATION_NODE_PAR,\n\ - 'seq' : ANIMATION_NODE_SEQ,\n\ - 'iterate' : ANIMATION_NODE_ITERATE,\n\ - 'animate' : ANIMATION_NODE_ANIMATE,\n\ - 'set' : ANIMATION_NODE_SET,\n\ - 'animatemotion' : ANIMATION_NODE_ANIMATEMOTION,\n\ - 'animatecolor' : ANIMATION_NODE_ANIMATECOLOR,\n\ - 'animatetransform' : ANIMATION_NODE_ANIMATETRANSFORM,\n\ - 'transitionfilter' : ANIMATION_NODE_TRANSITIONFILTER\n\ - };\n\ -\n\ -\n\ - function getAnimationElementType( aElement )\n\ - {\n\ - var sName = aElement.localName.toLowerCase();\n\ -\n\ - if( sName && aAnimationNodeTypeInMap[ sName ] )\n\ - return aAnimationNodeTypeInMap[ sName ];\n\ - else\n\ - return ANIMATION_NODE_CUSTOM;\n\ - }\n\ -\n\ -\n\ - var INVALID_NODE = 0;\n\ - var UNRESOLVED_NODE = 1;\n\ - var RESOLVED_NODE = 2;\n\ - var ACTIVE_NODE = 4;\n\ - var FROZEN_NODE = 8;\n\ - var ENDED_NODE = 16;\n\ -\n\ - function getNodeStateName( eNodeState )\n\ - {\n\ - switch( eNodeState )\n\ - {\n\ - case INVALID_NODE:\n\ - return 'INVALID';\n\ - case UNRESOLVED_NODE:\n\ - return 'UNRESOLVED';\n\ - case RESOLVED_NODE:\n\ - return 'RESOLVED';\n\ - case ACTIVE_NODE:\n\ - return 'ACTIVE';\n\ - case FROZEN_NODE:\n\ - return 'FROZEN';\n\ - case ENDED_NODE:\n\ - return 'ENDED';\n\ - default:\n\ - return 'UNKNOWN';\n\ - }\n\ - }\n\ -\n\ -\n\ - IMPRESS_DEFAULT_NODE = 0;\n\ - IMPRESS_ON_CLICK_NODE = 1;\n\ - IMPRESS_WITH_PREVIOUS_NODE = 2;\n\ - IMPRESS_AFTER_PREVIOUS_NODE = 3;\n\ - IMPRESS_MAIN_SEQUENCE_NODE = 4;\n\ - IMPRESS_TIMING_ROOT_NODE = 5;\n\ - IMPRESS_INTERACTIVE_SEQUENCE_NODE = 6;\n\ -\n\ - aImpressNodeTypeInMap = {\n\ - 'on-click' : IMPRESS_ON_CLICK_NODE,\n\ - 'with-previous' : IMPRESS_WITH_PREVIOUS_NODE,\n\ - 'after-previous' : IMPRESS_AFTER_PREVIOUS_NODE,\n\ - 'main-sequence' : IMPRESS_MAIN_SEQUENCE_NODE,\n\ - 'timing-root' : IMPRESS_TIMING_ROOT_NODE,\n\ - 'interactive-sequence' : IMPRESS_INTERACTIVE_SEQUENCE_NODE\n\ - };\n\ -\n\ - aImpressNodeTypeOutMap = [ 'default', 'on-click', 'with-previous', 'after-previous',\n\ - 'main-sequence', 'timing-root', 'interactive-sequence' ];\n\ -\n\ -\n\ - aPresetClassInMap = {};\n\ -\n\ -\n\ - aPresetIdInMap = {};\n\ -\n\ -\n\ - RESTART_MODE_DEFAULT = 0;\n\ - RESTART_MODE_INHERIT = 0;\n\ - RESTART_MODE_ALWAYS = 1;\n\ - RESTART_MODE_WHEN_NOT_ACTIVE = 2;\n\ - RESTART_MODE_NEVER = 3;\n\ -\n\ - aRestartModeInMap = {\n\ - 'inherit' : RESTART_MODE_DEFAULT,\n\ - 'always' : RESTART_MODE_ALWAYS,\n\ - 'whenNotActive' : RESTART_MODE_WHEN_NOT_ACTIVE,\n\ - 'never' : RESTART_MODE_NEVER\n\ - };\n\ -\n\ - aRestartModeOutMap = [ 'inherit','always', 'whenNotActive', 'never' ];\n\ -\n\ -\n\ - var FILL_MODE_DEFAULT = 0;\n\ - var FILL_MODE_INHERIT = 0;\n\ - var FILL_MODE_REMOVE = 1;\n\ - var FILL_MODE_FREEZE = 2;\n\ - var FILL_MODE_HOLD = 3;\n\ - var FILL_MODE_TRANSITION = 4;\n\ - var FILL_MODE_AUTO = 5;\n\ -\n\ - aFillModeInMap = {\n\ - 'inherit' : FILL_MODE_DEFAULT,\n\ - 'remove' : FILL_MODE_REMOVE,\n\ - 'freeze' : FILL_MODE_FREEZE,\n\ - 'hold' : FILL_MODE_HOLD,\n\ - 'transition' : FILL_MODE_TRANSITION,\n\ - 'auto' : FILL_MODE_AUTO\n\ - };\n\ -\n\ - aFillModeOutMap = [ 'inherit', 'remove', 'freeze', 'hold', 'transition', 'auto' ];\n\ -\n\ -\n\ - var ADDITIVE_MODE_BASE = 0;\n\ - var ADDITIVE_MODE_SUM = 1;\n\ - var ADDITIVE_MODE_REPLACE = 2;\n\ - var ADDITIVE_MODE_MULTIPLY = 3;\n\ - var ADDITIVE_MODE_NONE = 4;\n\ -\n\ - aAddittiveModeInMap = {\n\ - 'base' : ADDITIVE_MODE_BASE,\n\ - 'sum' : ADDITIVE_MODE_SUM,\n\ - 'replace' : ADDITIVE_MODE_REPLACE,\n\ - 'multiply' : ADDITIVE_MODE_MULTIPLY,\n\ - 'none' : ADDITIVE_MODE_NONE\n\ - };\n\ -\n\ - aAddittiveModeOutMap = [ 'base', 'sum', 'replace', 'multiply', 'none' ];\n\ -\n\ -\n\ - var ACCUMULATE_MODE_NONE = 0;\n\ - var ACCUMULATE_MODE_SUM = 1;\n\ -\n\ - aAccumulateModeOutMap = [ 'none', 'sum' ];\n\ -\n\ - var CALC_MODE_DISCRETE = 0;\n\ - var CALC_MODE_LINEAR = 1;\n\ - var CALC_MODE_PACED = 2;\n\ - var CALC_MODE_SPLINE = 3;\n\ -\n\ - aCalcModeInMap = {\n\ - 'discrete' : CALC_MODE_DISCRETE,\n\ -"; - -static const char aSVGScript12[] = -"\ - 'linear' : CALC_MODE_LINEAR,\n\ - 'paced' : CALC_MODE_PACED,\n\ - 'spline' : CALC_MODE_SPLINE\n\ - };\n\ -\n\ - aCalcModeOutMap = [ 'discrete', 'linear', 'paced', 'spline' ];\n\ -\n\ -\n\ - var COLOR_SPACE_RGB = 0;\n\ - var COLOR_SPACE_HSL = 1;\n\ -\n\ - aColorSpaceInMap = { 'rgb': COLOR_SPACE_RGB, 'hsl': COLOR_SPACE_HSL };\n\ -\n\ - aColorSpaceOutMap = [ 'rgb', 'hsl' ];\n\ -\n\ -\n\ - var CLOCKWISE = 0;\n\ - var COUNTERCLOCKWISE = 1;\n\ -\n\ - aClockDirectionInMap = { 'clockwise': CLOCKWISE, 'counterclockwise': COUNTERCLOCKWISE };\n\ -\n\ - aClockDirectionOutMap = [ 'clockwise', 'counterclockwise' ];\n\ -\n\ -\n\ - UNKNOWN_PROPERTY = 0;\n\ - NUMBER_PROPERTY = 1;\n\ - ENUM_PROPERTY = 2;\n\ - COLOR_PROPERTY = 3;\n\ - STRING_PROPERTY = 4;\n\ - BOOL_PROPERTY = 5;\n\ -\n\ - aValueTypeOutMap = [ 'unknown', 'number', 'enum', 'color', 'string', 'boolean' ];\n\ -\n\ -\n\ - var aAttributeMap =\n\ - {\n\ - 'height': { 'type': NUMBER_PROPERTY,\n\ - 'get': 'getHeight',\n\ - 'set': 'setHeight',\n\ - 'getmod': 'makeScaler( 1/nHeight )',\n\ - 'setmod': 'makeScaler( nHeight)' },\n\ -\n\ - 'opacity': { 'type': NUMBER_PROPERTY,\n\ - 'get': 'getOpacity',\n\ - 'set': 'setOpacity' },\n\ -\n\ - 'width': { 'type': NUMBER_PROPERTY,\n\ - 'get': 'getWidth',\n\ - 'set': 'setWidth',\n\ - 'getmod': 'makeScaler( 1/nWidth )',\n\ - 'setmod': 'makeScaler( nWidth)' },\n\ -\n\ - 'x': { 'type': NUMBER_PROPERTY,\n\ - 'get': 'getX',\n\ - 'set': 'setX',\n\ - 'getmod': 'makeScaler( 1/nWidth )',\n\ - 'setmod': 'makeScaler( nWidth)' },\n\ -\n\ - 'y': { 'type': NUMBER_PROPERTY,\n\ - 'get': 'getY',\n\ - 'set': 'setY',\n\ - 'getmod': 'makeScaler( 1/nHeight )',\n\ - 'setmod': 'makeScaler( nHeight)' },\n\ -\n\ - 'fill': { 'type': ENUM_PROPERTY,\n\ - 'get': 'getFillStyle',\n\ - 'set': 'setFillStyle' },\n\ -\n\ - 'stroke': { 'type': ENUM_PROPERTY,\n\ - 'get': 'getStrokeStyle',\n\ - 'set': 'setStrokeStyle' },\n\ -\n\ - 'visibility': { 'type': ENUM_PROPERTY,\n\ - 'get': 'getVisibility',\n\ - 'set': 'setVisibility' },\n\ -\n\ - 'fill-color': { 'type': COLOR_PROPERTY,\n\ - 'get': 'getFillColor',\n\ - 'set': 'setFillColor' },\n\ -\n\ - 'stroke-color': { 'type': COLOR_PROPERTY,\n\ - 'get': 'getStrokeColor',\n\ - 'set': 'setStrokeColor' },\n\ -\n\ - 'color': { 'type': COLOR_PROPERTY,\n\ - 'get': 'getFontColor',\n\ - 'set': 'setFontColor' },\n\ -\n\ - };\n\ -\n\ -\n\ - BARWIPE_TRANSITION = 1;\n\ - FADE_TRANSITION = 2; // 37\n\ -\n\ - aTransitionTypeInMap = {\n\ - 'barWipe' : BARWIPE_TRANSITION,\n\ - 'fade' : FADE_TRANSITION\n\ - };\n\ -\n\ - aTransitionTypeOutMap = [ '', 'barWipe', 'fade' ];\n\ -\n\ -\n\ - DEFAULT_TRANS_SUBTYPE = 0;\n\ - LEFTTORIGHT_TRANS_SUBTYPE = 1;\n\ - TOPTOBOTTOM_TRANS_SUBTYPE = 2;\n\ - CROSSFADE_TRANS_SUBTYPE = 3; // 101\n\ -\n\ - aTransitionSubtypeInMap = {\n\ - 'leftToRight' : LEFTTORIGHT_TRANS_SUBTYPE,\n\ - 'topToBottom' : TOPTOBOTTOM_TRANS_SUBTYPE,\n\ - 'crossfade' : CROSSFADE_TRANS_SUBTYPE\n\ - };\n\ -\n\ - aTransitionSubtypeOutMap = [ 'default', 'leftToRight', 'topToBottom', 'crossfade' ];\n\ -\n\ -\n\ - TRANSITION_MODE_IN = 1;\n\ - TRANSITION_MODE_OUT = 0;\n\ -\n\ - aTransitionModeInMap = { 'out': TRANSITION_MODE_OUT, 'in': TRANSITION_MODE_IN };\n\ - aTransitionModeOutMap = [ 'out', 'in' ];\n\ -\n\ -\n\ - var aStateTransitionTable_Never_Freeze =\n\ - [\n\ - INVALID_NODE,\n\ - RESOLVED_NODE | ENDED_NODE, // active successors for UNRESOLVED\n\ - ACTIVE_NODE | ENDED_NODE, // active successors for RESOLVED\n\ - INVALID_NODE,\n\ - FROZEN_NODE | ENDED_NODE, // active successors for ACTIVE: freeze object\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - ENDED_NODE, // active successors for FROZEN: end\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - INVALID_NODE,\n\ - ENDED_NODE // active successors for ENDED:\n\ - ];\n\ -\n\ -\n\ - var aTableGuide =\n\ - [\n\ - null,\n\ - null,\n\ - null,\n\ - aStateTransitionTable_Never_Freeze,\n\ - null,\n\ - null\n\ - ];\n\ -\n\ -\n\ - function getTransitionTable( eRestartMode, eFillMode )\n\ - {\n\ - var nRestartValue = 0; // never\n\ -\n\ - var nFillValue = 1; // frozen\n\ -\n\ - return aTableGuide[ 3*nFillValue + nRestartValue ];\n\ - }\n\ -\n\ -\n\ - var EVENT_TRIGGER_UNKNOWN = 0;\n\ - var EVENT_TRIGGER_ON_SLIDE_BEGIN = 1;\n\ - var EVENT_TRIGGER_ON_SLIDE_END = 2;\n\ - var EVENT_TRIGGER_BEGIN_EVENT = 3;\n\ - var EVENT_TRIGGER_END_EVENT = 4;\n\ - var EVENT_TRIGGER_ON_CLICK = 5;\n\ - var EVENT_TRIGGER_ON_DBL_CLICK = 6;\n\ - var EVENT_TRIGGER_ON_MOUSE_ENTER = 7;\n\ - var EVENT_TRIGGER_ON_MOUSE_LEAVE = 8;\n\ - var EVENT_TRIGGER_ON_NEXT_EFFECT = 9;\n\ - var EVENT_TRIGGER_ON_PREV_EFFECT = 10;\n\ - var EVENT_TRIGGER_REPEAT = 11;\n\ -\n\ - aEventTriggerOutMap = [ 'unknown', 'slideBegin', 'slideEnd', 'begin', 'end', 'click',\n\ - 'doubleClick', 'mouseEnter', 'mouseLeave', 'next', 'previous', 'repeat' ];\n\ -\n\ -\n\ - function getEventTriggerType( sEventTrigger )\n\ - {\n\ - if( sEventTrigger == 'begin' )\n\ - return EVENT_TRIGGER_BEGIN_EVENT;\n\ - else if( sEventTrigger == 'end' )\n\ - return EVENT_TRIGGER_END_EVENT;\n\ - else if( sEventTrigger == 'next' )\n\ - return EVENT_TRIGGER_ON_NEXT_EFFECT;\n\ - else if( sEventTrigger == 'prev' )\n\ - return EVENT_TRIGGER_ON_PREV_EFFECT;\n\ - else if( sEventTrigger == 'click' )\n\ - return EVENT_TRIGGER_ON_CLICK;\n\ - else\n\ - return EVENT_TRIGGER_UNKNOWN;\n\ - }\n\ -\n\ -\n\ -"; - -static const char aSVGScript13[] = -"\ - var UNKNOWN_TIMING = 0;\n\ - var OFFSET_TIMING = 1;\n\ - var WALLCLOCK_TIMING = 2;\n\ - var INDEFINITE_TIMING = 3;\n\ - var EVENT_TIMING = 4;\n\ - var SYNCBASE_TIMING = 5;\n\ - var MEDIA_TIMING = 6;\n\ -\n\ - aTimingTypeOutMap = [ 'unknown', 'offset', 'wallclock', 'indefinite', 'event', 'syncbase', 'media' ];\n\ -\n\ -\n\ - var CHARCODE_PLUS = '+'.charCodeAt(0);\n\ - var CHARCODE_MINUS = '-'.charCodeAt(0);\n\ - var CHARCODE_0 = '0'.charCodeAt(0);\n\ - var CHARCODE_9 = '9'.charCodeAt(0);\n\ -\n\ -\n\ - function Timing( aAnimationNode, sTimingAttribute )\n\ - {\n\ - this.aAnimationNode = aAnimationNode; // the node, the timing attribute belongs to\n\ - this.sTimingDescription = removeWhiteSpaces( sTimingAttribute );\n\ - this.eTimingType = UNKNOWN_TIMING;\n\ - this.nOffset = 0.0; // in seconds\n\ - this.sEventBaseElementId = ''; // the element id for event based timing\n\ - this.eEventType = EVENT_TRIGGER_UNKNOWN; // the event type\n\ - }\n\ -\n\ - Timing.prototype.getAnimationNode = function()\n\ - {\n\ - return this.aAnimationNode;\n\ - };\n\ -\n\ - Timing.prototype.getType = function()\n\ - {\n\ - return this.eTimingType;\n\ - };\n\ -\n\ - Timing.prototype.getOffset = function()\n\ - {\n\ - return this.nOffset;\n\ - };\n\ -\n\ - Timing.prototype.getEventBaseElementId = function()\n\ - {\n\ - return this.sEventBaseElementId;\n\ - };\n\ -\n\ - Timing.prototype.getEventType = function()\n\ - {\n\ - return this.eEventType;\n\ - };\n\ -\n\ - Timing.prototype.parse = function()\n\ - {\n\ - if( !this.sTimingDescription )\n\ - {\n\ - this.eTimingType = OFFSET_TIMING;\n\ - return;\n\ - }\n\ -\n\ - if( this.sTimingDescription == 'indefinite' )\n\ - this.eTimingType = INDEFINITE_TIMING;\n\ - else\n\ - {\n\ - var nFisrtCharCode = this.sTimingDescription.charCodeAt(0);\n\ - var bPositiveOffset = !( nFisrtCharCode == CHARCODE_MINUS );\n\ - if ( ( nFisrtCharCode == CHARCODE_PLUS ) ||\n\ - ( nFisrtCharCode == CHARCODE_MINUS ) ||\n\ - ( ( nFisrtCharCode >= CHARCODE_0 ) && ( nFisrtCharCode <= CHARCODE_9 ) ) )\n\ - {\n\ - var sClockValue\n\ - = ( ( nFisrtCharCode == CHARCODE_PLUS ) || ( nFisrtCharCode == CHARCODE_MINUS ) )\n\ - ? this.sTimingDescription.substr( 1 )\n\ - : this.sTimingDescription;\n\ -\n\ - var TimeInSec = Timing.parseClockValue( sClockValue );\n\ - if( TimeInSec != undefined )\n\ - {\n\ - this.eTimingType = OFFSET_TIMING;\n\ - this.nOffset = bPositiveOffset ? TimeInSec : -TimeInSec;\n\ - }\n\ - }\n\ - else\n\ - {\n\ - var aTimingSplit = new Array();\n\ - bPositiveOffset = true;\n\ - if( this.sTimingDescription.indexOf( '+' ) != -1 )\n\ - {\n\ - aTimingSplit = this.sTimingDescription.split( '+' );\n\ - }\n\ - else if( this.sTimingDescription.indexOf( '-' ) != -1 )\n\ - {\n\ - aTimingSplit = this.sTimingDescription.split( '-' );\n\ - bPositiveOffset = false;\n\ - }\n\ - else\n\ - {\n\ - aTimingSplit[0] = this.sTimingDescription;\n\ - aTimingSplit[1] = '';\n\ - }\n\ -\n\ - if( aTimingSplit[0].indexOf( '.' ) != -1 )\n\ - {\n\ - var aEventSplit = aTimingSplit[0].split( '.' );\n\ - this.sEventBaseElementId = aEventSplit[0];\n\ - this.eEventType = getEventTriggerType( aEventSplit[1] );\n\ - }\n\ - else\n\ - {\n\ - this.eEventType = getEventTriggerType( aTimingSplit[0] );\n\ - }\n\ -\n\ - if( this.eEventType == EVENT_TRIGGER_UNKNOWN )\n\ - return;\n\ -\n\ - if( ( this.eEventType == EVENT_TRIGGER_BEGIN_EVENT ) ||\n\ - ( this.eEventType == EVENT_TRIGGER_END_EVENT ) )\n\ - {\n\ - this.eTimingType = SYNCBASE_TIMING;\n\ - }\n\ - else\n\ - {\n\ - this.eTimingType = EVENT_TIMING;\n\ - }\n\ -\n\ - if( aTimingSplit[1] )\n\ - {\n\ - var sClockValue = aTimingSplit[1];\n\ - var TimeInSec = Timing.parseClockValue( sClockValue );\n\ - if( TimeInSec != undefined )\n\ - {\n\ - this.nOffset = ( bPositiveOffset ) ? TimeInSec : -TimeInSec;\n\ - }\n\ - else\n\ - {\n\ - this.eTimingType = UNKNOWN_TIMING;\n\ - }\n\ -\n\ - }\n\ - }\n\ - }\n\ -\n\ - };\n\ -\n\ - Timing.parseClockValue = function( sClockValue )\n\ - {\n\ - if( !sClockValue )\n\ - return 0.0;\n\ -\n\ - var nTimeInSec = undefined;\n\ -\n\ - var reFullClockValue = /^([0-9]+):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?$/;\n\ - var rePartialClockValue = /^([0-5][0-9]):([0-5][0-9])(.[0-9]+)?$/;\n\ - var reTimecountValue = /^([0-9]+)(.[0-9]+)?(h|min|s|ms)?$/;\n\ -\n\ - if( reFullClockValue.test( sClockValue ) )\n\ - {\n\ - var aClockTimeParts = reFullClockValue.exec( sClockValue );\n\ -\n\ - var nHours = parseInt( aClockTimeParts[1] );\n\ - var nMinutes = parseInt( aClockTimeParts[2] );\n\ - var nSeconds = parseInt( aClockTimeParts[3] );\n\ - if( aClockTimeParts[4] )\n\ - nSeconds += parseFloat( aClockTimeParts[4] );\n\ -\n\ - nTimeInSec = ( ( nHours * 60 ) + nMinutes ) * 60 + nSeconds;\n\ -\n\ - }\n\ - else if( rePartialClockValue.test( sClockValue ) )\n\ - {\n\ - var aClockTimeParts = rePartialClockValue.exec( sClockValue );\n\ -\n\ - var nMinutes = parseInt( aClockTimeParts[1] );\n\ - var nSeconds = parseInt( aClockTimeParts[2] );\n\ - if( aClockTimeParts[3] )\n\ - nSeconds += parseFloat( aClockTimeParts[3] );\n\ -\n\ - nTimeInSec = nMinutes * 60 + nSeconds;\n\ - }\n\ - else if( reTimecountValue.test( sClockValue ) )\n\ - {\n\ - var aClockTimeParts = reTimecountValue.exec( sClockValue );\n\ -\n\ - var nTimecount = parseInt( aClockTimeParts[1] );\n\ - if( aClockTimeParts[2] )\n\ - nTimecount += parseFloat( aClockTimeParts[2] );\n\ -\n\ - if( aClockTimeParts[3] )\n\ - {\n\ - if( aClockTimeParts[3] == 'h' )\n\ - {\n\ - nTimeInSec = nTimecount * 3600;\n\ - }\n\ - else if( aClockTimeParts[3] == 'min' )\n\ - {\n\ - nTimeInSec = nTimecount * 60;\n\ - }\n\ - else if( aClockTimeParts[3] == 's' )\n\ - {\n\ - nTimeInSec = nTimecount;\n\ -"; - -static const char aSVGScript14[] = -"\ - }\n\ - else if( aClockTimeParts[3] == 'ms' )\n\ - {\n\ - nTimeInSec = nTimecount / 1000;\n\ - }\n\ - }\n\ - else\n\ - {\n\ - nTimeInSec = nTimecount;\n\ - }\n\ -\n\ - }\n\ -\n\ - if( nTimeInSec )\n\ - nTimeInSec = parseFloat( nTimeInSec.toFixed( 3 ) );\n\ - return nTimeInSec;\n\ - };\n\ -\n\ - Timing.prototype.info = function( bVerbose )\n\ - {\n\ -\n\ - var sInfo = '';\n\ -\n\ - if( bVerbose )\n\ - {\n\ - sInfo = 'description: ' + this.sTimingDescription + ', ';\n\ -\n\ - sInfo += ', type: ' + aTimingTypeOutMap[ this.getType() ];\n\ - sInfo += ', offset: ' + this.getOffset();\n\ - sInfo += ', event base element id: ' + this.getEventBaseElementId();\n\ - sInfo += ', timing event type: ' + aEventTriggerOutMap[ this.getEventType() ];\n\ - }\n\ - else\n\ - {\n\ - switch( this.getType() )\n\ - {\n\ - case INDEFINITE_TIMING:\n\ - sInfo += 'indefinite';\n\ - break;\n\ - case OFFSET_TIMING:\n\ - sInfo += this.getOffset();\n\ - break;\n\ - case EVENT_TIMING:\n\ - case SYNCBASE_TIMING:\n\ - if( this.getEventBaseElementId() )\n\ - sInfo += this.getEventBaseElementId() + '.';\n\ - sInfo += aEventTriggerOutMap[ this.getEventType() ];\n\ - if( this.getOffset() )\n\ - {\n\ - if( this.getOffset() > 0 )\n\ - sInfo += '+';\n\ - sInfo += this.getOffset();\n\ - }\n\ - }\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function Duration( sDurationAttribute )\n\ - {\n\ - this.bIndefinite = false;\n\ - this.bMedia = false;\n\ - this.nValue = undefined;\n\ - this.bDefined = false;\n\ -\n\ - if( !sDurationAttribute )\n\ - return;\n\ -\n\ - if( sDurationAttribute == 'indefinite' )\n\ - this.bIndefinite = true;\n\ - else if( sDurationAttribute == 'media' )\n\ - this.bMedia = true;\n\ - else\n\ - {\n\ - this.nValue = Timing.parseClockValue( sDurationAttribute );\n\ - if( this.nValue <= 0.0 )\n\ - this.nValue = 0.001; // duration must be always greater than 0\n\ - }\n\ - this.bDefined = true;\n\ - }\n\ -\n\ -\n\ - Duration.prototype.isSet = function()\n\ - {\n\ - return this.bDefined;\n\ - };\n\ -\n\ - Duration.prototype.isIndefinite = function()\n\ - {\n\ - return this.bIndefinite;\n\ - };\n\ -\n\ - Duration.prototype.isMedia = function()\n\ - {\n\ - return this.bMedia;\n\ - };\n\ -\n\ - Duration.prototype.isValue = function()\n\ - {\n\ - return this.nValue != undefined;\n\ - };\n\ -\n\ - Duration.prototype.getValue= function()\n\ - {\n\ - return this.nValue;\n\ - };\n\ -\n\ - Duration.prototype.info= function()\n\ - {\n\ - var sInfo;\n\ -\n\ - if( this.isIndefinite() )\n\ - sInfo = 'indefinite';\n\ - else if( this.isMedia() )\n\ - sInfo = 'media';\n\ - else if( this.getValue() )\n\ - sInfo = this.getValue();\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function AnimationNode()\n\ - {\n\ - }\n\ -\n\ - AnimationNode.prototype.init = function() {};\n\ - AnimationNode.prototype.resolve = function() {};\n\ - AnimationNode.prototype.activate = function() {};\n\ - AnimationNode.prototype.deactivate = function() {};\n\ - AnimationNode.prototype.end = function() {};\n\ - AnimationNode.prototype.getState = function() {};\n\ - AnimationNode.prototype.registerDeactivatingListener = function() {};\n\ - AnimationNode.prototype.notifyDeactivating = function() {};\n\ -\n\ -\n\ - function NodeContext( aSlideShowContext )\n\ - {\n\ - this.aContext = aSlideShowContext;\n\ - this.aAnimationNodeMap = null;\n\ - this.aAnimatedElementMap = null;\n\ - this.aSourceEventElementMap = null;\n\ - this.nStartDelay = 0.0;\n\ - this.bFirstRun = undefined;\n\ - this.aSlideHeight = HEIGHT;\n\ - this.aSlideWidth = WIDTH;\n\ - }\n\ -\n\ -\n\ - NodeContext.prototype.makeSourceEventElement = function( sId, aEventBaseElem )\n\ - {\n\ - if( !aEventBaseElem )\n\ - {\n\ - log( 'NodeContext.makeSourceEventElement: event base element is not valid' );\n\ - return null;\n\ - }\n\ -\n\ - if( !this.aContext.aEventMultiplexer )\n\ - {\n\ - log( 'NodeContext.makeSourceEventElement: event multiplexer not initialized' );\n\ - return null;\n\ - }\n\ -\n\ - if( !this.aAnimationNodeMap[ sId ] )\n\ - {\n\ - this.aAnimationNodeMap[ sId ] = new SourceEventElement( aEventBaseElem, this.aContext.aEventMultiplexer );\n\ - }\n\ - return this.aAnimationNodeMap[ sId ];\n\ - };\n\ -\n\ -\n\ - function StateTransition( aBaseNode )\n\ - {\n\ - this.aNode = aBaseNode;\n\ - this.eToState = INVALID_NODE;\n\ - }\n\ -\n\ - StateTransition.prototype.enter = function( eNodeState, bForce )\n\ - {\n\ - if( !bForce ) bForce = false;\n\ -\n\ - if( this.eToState != INVALID_NODE )\n\ - {\n\ - log( 'StateTransition.enter: commit() before enter()ing again!' );\n\ - return false;\n\ - }\n\ - if( !bForce && !this.aNode.isTransition( this.aNode.getState(), eNodeState ) )\n\ - return false;\n\ -\n\ - if( ( this.aNode.nCurrentStateTransition & eNodeState ) != 0 )\n\ - return false; // already in wanted transition\n\ -\n\ - this.aNode.nCurrentStateTransition |= eNodeState;\n\ - this.eToState = eNodeState;\n\ - return true;\n\ - };\n\ -\n\ - StateTransition.prototype.commit = function()\n\ -"; - -static const char aSVGScript15[] = -"\ - {\n\ - if( this.eToState != INVALID_NODE )\n\ - {\n\ - this.aNode.eCurrentState = this.eToState;\n\ - this.clear();\n\ - }\n\ - };\n\ -\n\ - StateTransition.prototype.clear = function()\n\ - {\n\ - if( this.eToState != INVALID_NODE )\n\ - {\n\ - this.aNode.nCurrentStateTransition &= ~this.eToState;\n\ - this.eToState = INVALID_NODE;\n\ - }\n\ - };\n\ -\n\ -\n\ - function BaseNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - this.nId = getUniqueId();\n\ - this.sClassName = 'BaseNode';\n\ -\n\ - if( !aAnimElem )\n\ - log( 'BaseNode(id:' + this.nId + ') constructor: aAnimElem is not valid' );\n\ -\n\ - if( !aNodeContext )\n\ - log( 'BaseNode(id:' + this.nId + ') constructor: aNodeContext is not valid' );\n\ -\n\ - if( !aNodeContext.aContext )\n\ - log( 'BaseNode(id:' + this.nId + ') constructor: aNodeContext.aContext is not valid' );\n\ -\n\ -\n\ - this.bIsContainer;\n\ - this.aElement = aAnimElem;\n\ - this.aParentNode = aParentNode;\n\ - this.aNodeContext = aNodeContext;\n\ - this.aContext = aNodeContext.aContext;\n\ - this.nStartDelay = aNodeContext.nStartDelay;\n\ - this.eCurrentState = UNRESOLVED_NODE;\n\ - this.nCurrentStateTransition = 0;\n\ - this.aDeactivatingListenerArray = new Array();\n\ - this.aActivationEvent = null;\n\ - this.aDeactivationEvent = null;\n\ -\n\ - this.aBegin = null;\n\ - this.aDuration = null;\n\ - this.aEnd = null;\n\ - this.bMainSequenceRootNode = false;\n\ - this.eFillMode = FILL_MODE_FREEZE;\n\ - this.eRestartMode = RESTART_MODE_NEVER;\n\ - this.nReapeatCount = undefined;\n\ - this.nAccelerate = 0.0;\n\ - this.nDecelerate = 0.0;\n\ - this.bAutoReverse = false;\n\ -\n\ - }\n\ - extend( BaseNode, AnimationNode );\n\ -\n\ -\n\ - BaseNode.prototype.getId = function()\n\ - {\n\ - return this.nId;\n\ - };\n\ -\n\ - BaseNode.prototype.parseElement = function()\n\ - {\n\ - var aAnimElem = this.aElement;\n\ -\n\ - var sIdAttr = aAnimElem.getAttributeNS( NSS['xml'], 'id' );\n\ - if( sIdAttr )\n\ - this.aNodeContext.aAnimationNodeMap[ sIdAttr ] = this;\n\ -\n\ - this.aBegin = null;\n\ - var sBeginAttr = aAnimElem.getAttribute( 'begin' );\n\ - this.aBegin = new Timing( this, sBeginAttr );\n\ - this.aBegin.parse();\n\ -\n\ - this.aEnd = null;\n\ - var sEndAttr = aAnimElem.getAttribute( 'end' );\n\ - if( sEndAttr )\n\ - {\n\ - this.aEnd = new Timing( this, sEndAttr );\n\ - this.aEnd.parse();\n\ - }\n\ -\n\ - this.aDuration = null;\n\ - var sDurAttr = aAnimElem.getAttribute( 'dur' );\n\ - this.aDuration = new Duration( sDurAttr );\n\ - if( !this.aDuration.isSet() )\n\ - {\n\ - if( this.isContainer() )\n\ - this.aDuration = null;\n\ - else\n\ - this.aDuration = new Duration( 'indefinite' );\n\ - }\n\ -\n\ - var sFillAttr = aAnimElem.getAttribute( 'fill' );\n\ - if( sFillAttr && aFillModeInMap[ sFillAttr ])\n\ - this.eFillMode = aFillModeInMap[ sFillAttr ];\n\ - else\n\ - this.eFillMode = FILL_MODE_DEFAULT;\n\ -\n\ - var sRestartAttr = aAnimElem.getAttribute( 'restart' );\n\ - if( sRestartAttr && aRestartModeInMap[ sRestartAttr ] )\n\ - this.eRestartMode = aRestartModeInMap[ sRestartAttr ];\n\ - else\n\ - this.eRestartMode = RESTART_MODE_DEFAULT;\n\ -\n\ - var sRepeatCount = aAnimElem.getAttribute( 'repeatCount' );\n\ - if( !sRepeatCount )\n\ - this.nReapeatCount = 1;\n\ - else\n\ - this.nReapeatCount = parseFloat( sRepeatCount );\n\ - if( ( this.nReapeatCount == NaN ) && ( sRepeatCount != 'indefinite' ) )\n\ - this.nReapeatCount = 1;\n\ -\n\ - this.nAccelerate = 0.0;\n\ - var sAccelerateAttr = aAnimElem.getAttribute( 'accelerate' );\n\ - if( sAccelerateAttr )\n\ - this.nAccelerate = parseFloat( sAccelerateAttr );\n\ - if( this.nAccelerate == NaN )\n\ - this.nAccelerate = 0.0;\n\ -\n\ - this.nDecelerate = 0.0;\n\ - var sDecelerateAttr = aAnimElem.getAttribute( 'decelerate' );\n\ - if( sDecelerateAttr )\n\ - this.nDecelerate = parseFloat( sDecelerateAttr );\n\ - if( this.nDecelerate == NaN )\n\ - this.nDecelerate = 0.0;\n\ -\n\ - this.bAutoreverse = false;\n\ - var sAutoReverseAttr = aAnimElem.getAttribute( 'autoReverse' );\n\ - if( sAutoReverseAttr == 'true' )\n\ - this.bAutoreverse = true;\n\ -\n\ -\n\ - if( this.eFillMode == FILL_MODE_DEFAULT )\n\ - if( this.getParentNode() )\n\ - this.eFillMode = this.getParentNode().getFillMode();\n\ - else\n\ - this.eFillMode = FILL_MODE_AUTO;\n\ -\n\ - if( this.eFillMode == FILL_MODE_AUTO ) // see SMIL recommendation document\n\ - {\n\ - this.eFillMode = ( this.aEnd ||\n\ - ( this.nReapeatCount != 1) ||\n\ - this.aDuration )\n\ - ? FILL_MODE_REMOVE\n\ - : FILL_MODE_FREEZE;\n\ - }\n\ -\n\ - if( this.eRestartMode == RESTART_MODE_DEFAULT )\n\ - if( this.getParentNode() )\n\ - this.eRestartMode = this.getParentNode().getRestartMode();\n\ - else\n\ - this.eRestartMode = RESTART_MODE_NEVER;\n\ -\n\ - if( ( this.nAccelerate + this.nDecelerate ) > 1.0 )\n\ - {\n\ - this.nAccelerate = 0.0;\n\ - this.nDecelerate = 0.0;\n\ - }\n\ -\n\ - this.eFillMode = FILL_MODE_FREEZE;\n\ - this.eRestartMode = RESTART_MODE_NEVER;\n\ - this.aStateTransTable = getTransitionTable( this.getRestartMode(), this.getFillMode() );\n\ -\n\ - return true;\n\ - };\n\ -\n\ - BaseNode.prototype.getParentNode = function()\n\ - {\n\ - return this.aParentNode;\n\ - };\n\ -\n\ - BaseNode.prototype.init = function()\n\ - {\n\ - if( ! this.checkValidNode() )\n\ - return false;\n\ - if( this.aActivationEvent )\n\ - this.aActivationEvent.dispose();\n\ - if( this.aDeactivationEvent )\n\ - this.aDeactivationEvent.dispose();\n\ -\n\ - this.eCurrentState = UNRESOLVED_NODE;\n\ -\n\ - return this.init_st();\n\ - };\n\ -\n\ - BaseNode.prototype.resolve = function()\n\ - {\n\ - if( ! this.checkValidNode() )\n\ - return false;\n\ -\n\ - this.DBG( this.callInfo( 'resolve' ) );\n\ -\n\ - if( this.eCurrentState == RESOLVED_NODE )\n\ - log( 'BaseNode.resolve: already in RESOLVED state' );\n\ -\n\ -"; - -static const char aSVGScript16[] = -"\ - var aStateTrans = new StateTransition( this );\n\ -\n\ - if( aStateTrans.enter( RESOLVED_NODE ) &&\n\ - this.isTransition( RESOLVED_NODE, ACTIVE_NODE ) &&\n\ - this.resolve_st() )\n\ - {\n\ - aStateTrans.commit();\n\ -\n\ - if( this.aActivationEvent )\n\ - {\n\ - this.aActivationEvent.charge();\n\ - }\n\ - else\n\ - {\n\ - this.aActivationEvent = makeDelay( bind( this, this.activate ), this.getBegin().getOffset() + this.nStartDelay );\n\ - }\n\ - registerEvent( this.getBegin(), this.aActivationEvent, this.aNodeContext );\n\ -\n\ - return true;\n\ - }\n\ -\n\ - return false;\n\ - };\n\ -\n\ - BaseNode.prototype.activate = function()\n\ - {\n\ - if( ! this.checkValidNode() )\n\ - return false;\n\ -\n\ - if( this.eCurrentState == ACTIVE_NODE )\n\ - log( 'BaseNode.activate: already in ACTIVE state' );\n\ -\n\ - this.DBG( this.callInfo( 'activate' ), getCurrentSystemTime() );\n\ -\n\ - var aStateTrans = new StateTransition( this );\n\ -\n\ - if( aStateTrans.enter( ACTIVE_NODE ) )\n\ - {\n\ - this.activate_st();\n\ - aStateTrans.commit();\n\ - if( !this.aContext.aEventMultiplexer )\n\ - log( 'BaseNode.activate: this.aContext.aEventMultiplexer is not valid' );\n\ - this.aContext.aEventMultiplexer.notifyEvent( EVENT_TRIGGER_BEGIN_EVENT, this.getId() );\n\ - return true;\n\ - }\n\ - return false;\n\ - };\n\ -\n\ - BaseNode.prototype.deactivate = function()\n\ - {\n\ - if( this.inStateOrTransition( ENDED_NODE | FROZEN_NODE ) || !this.checkValidNode() )\n\ - return;\n\ -\n\ - if( this.isTransition( this.eCurrentState, FROZEN_NODE ) )\n\ - {\n\ - this.DBG( this.callInfo( 'deactivate' ), getCurrentSystemTime() );\n\ -\n\ - var aStateTrans = new StateTransition( this );\n\ - if( aStateTrans.enter( FROZEN_NODE, true /* FORCE */ ) )\n\ - {\n\ - this.deactivate_st();\n\ - aStateTrans.commit();\n\ -\n\ - this.notifyEndListeners();\n\ -\n\ - if( this.aActivationEvent )\n\ - this.aActivationEvent.dispose();\n\ - if( this.aDeactivationEvent )\n\ - this.aDeactivationEvent.dispose();\n\ - }\n\ - }\n\ - else\n\ - {\n\ - this.end();\n\ - }\n\ - };\n\ -\n\ - BaseNode.prototype.end = function()\n\ - {\n\ - var bIsFrozenOrInTransitionToFrozen = this.inStateOrTransition( FROZEN_NODE );\n\ - if( this.inStateOrTransition( ENDED_NODE ) || !this.checkValidNode() )\n\ - return;\n\ -\n\ - if( !(this.isTransition( this.eCurrentState, ENDED_NODE ) ) )\n\ - log( 'BaseNode.end: end state not reachable in transition table' );\n\ -\n\ - this.DBG( this.callInfo( 'end' ), getCurrentSystemTime() );\n\ -\n\ - var aStateTrans = new StateTransition( this );\n\ - if( aStateTrans.enter( ENDED_NODE, true /* FORCE */ ) )\n\ - {\n\ - this.deactivate_st( ENDED_NODE );\n\ - aStateTrans.commit();\n\ -\n\ - if( !bIsFrozenOrInTransitionToFrozen )\n\ - this.notifyEndListeners();\n\ -\n\ - if( this.aActivationEvent )\n\ - this.aActivationEvent.dispose();\n\ - if( this.aDeactivationEvent )\n\ - this.aDeactivationEvent.dispose();\n\ - }\n\ - };\n\ -\n\ - BaseNode.prototype.dispose = function()\n\ - {\n\ - if( this.aActivationEvent )\n\ - this.aActivationEvent.dispose();\n\ - if( this.aDeactivationEvent )\n\ - this.aDeactivationEvent.dispose();\n\ - this.aDeactivatingListenerArray = new Array();\n\ - };\n\ -\n\ - BaseNode.prototype.getState = function()\n\ - {\n\ - return this.eCurrentState;\n\ - };\n\ -\n\ - BaseNode.prototype.registerDeactivatingListener = function( aNotifiee )\n\ - {\n\ - if (! this.checkValidNode())\n\ - return false;\n\ -\n\ - if( !aNotifiee )\n\ - {\n\ - log( 'BaseNode.registerDeactivatingListener(): invalid notifee' );\n\ - return false;\n\ - }\n\ - this.aDeactivatingListenerArray.push( aNotifiee );\n\ -\n\ - return true;\n\ - };\n\ -\n\ - BaseNode.prototype.notifyDeactivating = function( aNotifier )\n\ - {\n\ - assert( ( aNotifier.getState() == FROZEN_NODE ) || ( aNotifier.getState() == ENDED_NODE ),\n\ - 'BaseNode.notifyDeactivating: Notifier node is neither in FROZEN nor in ENDED state' );\n\ - };\n\ -\n\ - BaseNode.prototype.isMainSequenceRootNode = function()\n\ - {\n\ - return this.bMainSequenceRootNode;\n\ - };\n\ -\n\ - BaseNode.prototype.makeDeactivationEvent = function( nDelay )\n\ - {\n\ - if( this.aDeactivationEvent )\n\ - {\n\ - this.aDeactivationEvent.charge();\n\ - }\n\ - else\n\ - {\n\ - if( typeof( nDelay ) == typeof(0) )\n\ - this.aDeactivationEvent = makeDelay( bind( this, this.deactivate ), nDelay );\n\ - else\n\ - this.aDeactivationEvent = null;\n\ - }\n\ - return this.aDeactivationEvent;\n\ - };\n\ -\n\ - BaseNode.prototype.scheduleDeactivationEvent = function( aEvent )\n\ - {\n\ - this.DBG( this.callInfo( 'scheduleDeactivationEvent' ) );\n\ -\n\ - if( !aEvent )\n\ - {\n\ - if( this.getDuration() && this.getDuration().isValue() )\n\ - aEvent = this.makeDeactivationEvent( this.getDuration().getValue() );\n\ - }\n\ - if( aEvent )\n\ - {\n\ - this.aContext.aTimerEventQueue.addEvent( aEvent );\n\ - }\n\ - };\n\ -\n\ - BaseNode.prototype.checkValidNode = function()\n\ - {\n\ - return ( this.eCurrentState != INVALID_NODE );\n\ - };\n\ -\n\ - BaseNode.prototype.init_st = function()\n\ - {\n\ - return true;\n\ - };\n\ -\n\ - BaseNode.prototype.resolve_st = function()\n\ - {\n\ - return true;\n\ - };\n\ -\n\ - BaseNode.prototype.activate_st = function()\n\ - {\n\ - this.scheduleDeactivationEvent();\n\ - };\n\ -\n\ - BaseNode.prototype.deactivate_st = function( aNodeState )\n\ - {\n\ - };\n\ -\n\ - BaseNode.prototype.notifyEndListeners = function()\n\ -"; - -static const char aSVGScript17[] = -"\ - {\n\ - var nDeactivatingListenerCount = this.aDeactivatingListenerArray.length;\n\ -\n\ - for( var i = 0; i < nDeactivatingListenerCount; ++i )\n\ - {\n\ - this.aDeactivatingListenerArray[i].notifyDeactivating( this );\n\ - }\n\ -\n\ - this.aContext.aEventMultiplexer.notifyEvent( EVENT_TRIGGER_END_EVENT, this.getId() );\n\ - };\n\ -\n\ - BaseNode.prototype.getContext = function()\n\ - {\n\ - return this.aContext;\n\ - };\n\ -\n\ - BaseNode.prototype.isTransition = function( eFromState, eToState )\n\ - {\n\ - return ( ( this.aStateTransTable[ eFromState ] & eToState ) != 0 );\n\ - };\n\ -\n\ - BaseNode.prototype.inStateOrTransition = function( nMask )\n\ - {\n\ - return ( ( ( this.eCurrentState & nMask ) != 0 ) || ( ( this.nCurrentStateTransition & nMask ) != 0 ) );\n\ - };\n\ -\n\ - BaseNode.prototype.isContainer = function()\n\ - {\n\ - return this.bIsContainer;\n\ - };\n\ -\n\ - BaseNode.prototype.getBegin = function()\n\ - {\n\ - return this.aBegin;\n\ - };\n\ -\n\ - BaseNode.prototype.getDuration = function()\n\ - {\n\ - return this.aDuration;\n\ - };\n\ -\n\ - BaseNode.prototype.getEnd = function()\n\ - {\n\ - return this.aEnd;\n\ - };\n\ -\n\ - BaseNode.prototype.getFillMode = function()\n\ - {\n\ - return this.eFillMode;\n\ - };\n\ -\n\ - BaseNode.prototype.getRestartMode = function()\n\ - {\n\ - return this.eRestartMode;\n\ - };\n\ -\n\ - BaseNode.prototype.getRepeatCount = function()\n\ - {\n\ - return this.nReapeatCount;\n\ - };\n\ -\n\ - BaseNode.prototype.getAccelerateValue = function()\n\ - {\n\ - return this.nAccelerate;\n\ - };\n\ -\n\ - BaseNode.prototype.getDecelerateValue = function()\n\ - {\n\ - return this.nDecelerate;\n\ - };\n\ -\n\ - BaseNode.prototype.isAutoReverseEnabled = function()\n\ - {\n\ - return this.bAutoreverse;\n\ - };\n\ -\n\ - BaseNode.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = 'class name: ' + this.sClassName;\n\ - sInfo += '; element name: ' + this.aElement.localName;\n\ - sInfo += '; id: ' + this.getId();\n\ - sInfo += '; state: ' + getNodeStateName( this.getState() );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - sInfo += '; is container: ' + this.isContainer();\n\ -\n\ - if( this.getBegin() )\n\ - sInfo += '; begin: ' + this.getBegin().info();\n\ -\n\ - if( this.getDuration() )\n\ - sInfo += '; dur: ' + this.getDuration().info();\n\ -\n\ - if( this.getEnd() )\n\ - sInfo += '; end: ' + this.getEnd().info();\n\ -\n\ - if( this.getFillMode() )\n\ - sInfo += '; fill: ' + aFillModeOutMap[ this.getFillMode() ];\n\ -\n\ - if( this.getRestartMode() )\n\ - sInfo += '; restart: ' + aRestartModeOutMap[ this.getRestartMode() ];\n\ -\n\ - if( this.getRepeatCount() && ( this.getRepeatCount() != 1.0 ) )\n\ - sInfo += '; repeatCount: ' + this.getRepeatCount();\n\ -\n\ - if( this.getAccelerateValue() )\n\ - sInfo += '; accelerate: ' + this.getAccelerateValue();\n\ -\n\ - if( this.getDecelerateValue() )\n\ - sInfo += '; decelerate: ' + this.getDecelerateValue();\n\ -\n\ - if( this.isAutoReverseEnabled() )\n\ - sInfo += '; autoReverse: true';\n\ -\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ - BaseNode.prototype.callInfo = function( sMethodName )\n\ - {\n\ - var sInfo = this.sClassName +\n\ - '( ' + this.getId() +\n\ - ', ' + getNodeStateName( this.getState() ) +\n\ - ' ).' + sMethodName;\n\ - return sInfo;\n\ - };\n\ -\n\ - BaseNode.prototype.DBG = function( sMessage, nTime )\n\ - {\n\ - ANIMDBG.print( sMessage, nTime );\n\ - };\n\ -\n\ -\n\ - function AnimationBaseNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - AnimationBaseNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'AnimationBaseNode';\n\ - this.bIsContainer = false;\n\ - this.aTargetElement = null;\n\ - this.aAnimatedElement = null;\n\ - this.aActivity = null;\n\ -\n\ - this.nMinFrameCount;\n\ - this.eAdditiveMode;\n\ -\n\ - }\n\ - extend( AnimationBaseNode, BaseNode );\n\ -\n\ -\n\ - AnimationBaseNode.prototype.parseElement = function()\n\ - {\n\ - var bRet = AnimationBaseNode.superclass.parseElement.call( this );\n\ -\n\ - var aAnimElem = this.aElement;\n\ -\n\ - this.aTargetElement = null;\n\ - var sTargetElementAttr = aAnimElem.getAttribute( 'targetElement' );\n\ - if( sTargetElementAttr )\n\ - this.aTargetElement = document.getElementById( sTargetElementAttr );\n\ -\n\ - if( !this.aTargetElement )\n\ - {\n\ - this.eCurrentState = INVALID_NODE;\n\ - log( 'AnimationBaseNode.parseElement: target element not found: ' + sTargetElementAttr );\n\ - }\n\ -\n\ - var sAdditiveAttr = aAnimElem.getAttribute( 'additive' );\n\ - if( sAdditiveAttr && aAddittiveModeInMap[sAdditiveAttr] )\n\ - this.eAdditiveMode = aAddittiveModeInMap[sAdditiveAttr];\n\ - else\n\ - this.eAdditiveMode = ADDITIVE_MODE_REPLACE;\n\ -\n\ - this.nMinFrameCount = ( this.getDuration().isValue() )\n\ - ? ( this.getDuration().getValue() * MINIMUM_FRAMES_PER_SECONDS )\n\ - : MINIMUM_FRAMES_PER_SECONDS;\n\ - if( this.nMinFrameCount < 1.0 )\n\ - this.nMinFrameCount = 1;\n\ - else if( this.nMinFrameCount > MINIMUM_FRAMES_PER_SECONDS )\n\ - this.nMinFrameCount = MINIMUM_FRAMES_PER_SECONDS;\n\ -\n\ -\n\ - if( this.aTargetElement )\n\ - {\n\ - if( true && aAnimElem.getAttribute( 'attributeName' ) === 'visibility' )\n\ - {\n\ - if( aAnimElem.getAttribute( 'to' ) === 'visible' )\n\ - this.aTargetElement.setAttribute( 'visibility', 'hidden' );\n\ - }\n\ -\n\ - if( !this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ] )\n\ - {\n\ - this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ]\n\ - = new AnimatedElement( this.aTargetElement );\n\ - }\n\ - this.aAnimatedElement = this.aNodeContext.aAnimatedElementMap[ sTargetElementAttr ];\n\ -\n\ - this.aAnimatedElement.setAdditiveMode( this.eAdditiveMode );\n\ - }\n\ -"; - -static const char aSVGScript18[] = -"\ -\n\ -\n\ - return bRet;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.init_st = function()\n\ - {\n\ - if( this.aActivity )\n\ - this.aActivity.activate( makeEvent( bind( this, this.deactivate ) ) );\n\ - else\n\ - this.aActivity = this.createActivity();\n\ - return true;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.resolve_st = function()\n\ - {\n\ - return true;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.activate_st = function()\n\ - {\n\ - if( this.aActivity )\n\ - {\n\ - this.aActivity.setTargets( this.getAnimatedElement() );\n\ - this.getContext().aActivityQueue.addActivity( this.aActivity );\n\ - }\n\ - else\n\ - {\n\ - AnimationBaseNode.superclass.scheduleDeactivationEvent.call( this );\n\ - }\n\ -\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.deactivate_st = function( eDestState )\n\ - {\n\ - if( eDestState == FROZEN_NODE )\n\ - {\n\ - if( this.aActivity )\n\ - this.aActivity.end();\n\ - }\n\ - if( eDestState == ENDED_NODE )\n\ - {\n\ - if( this.aActivity )\n\ - this.aActivity.dispose();\n\ - }\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.createActivity = function()\n\ - {\n\ - log( 'AnimationBaseNode.createActivity: abstract method called' );\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.fillActivityParams = function()\n\ - {\n\ -\n\ - var nDuration = 0.001;\n\ - if( this.getDuration().isValue() )\n\ - {\n\ - nDuration = this.getDuration().getValue();\n\ - }\n\ - else\n\ - {\n\ - log( 'AnimationBaseNode.fillActivityParams: duration is not a number' );\n\ - }\n\ -\n\ - var aActivityParamSet = new ActivityParamSet();\n\ -\n\ - aActivityParamSet.aEndEvent = makeEvent( bind( this, this.deactivate ) );\n\ - aActivityParamSet.aTimerEventQueue = this.aContext.aTimerEventQueue;\n\ - aActivityParamSet.aActivityQueue = this.aContext.aActivityQueue;\n\ - aActivityParamSet.nMinDuration = nDuration;\n\ - aActivityParamSet.nMinNumberOfFrames = this.getMinFrameCount();\n\ - aActivityParamSet.bAutoReverse = this.isAutoReverseEnabled();\n\ - aActivityParamSet.nRepeatCount = this.getRepeatCount();\n\ - aActivityParamSet.nAccelerationFraction = this.getAccelerateValue();\n\ - aActivityParamSet.nDecelerationFraction = this.getDecelerateValue();\n\ - aActivityParamSet.nSlideWidth = this.aNodeContext.aSlideWidth;\n\ - aActivityParamSet.nSlideHeight = this.aNodeContext.aSlideHeight;\n\ -\n\ - return aActivityParamSet;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.hasPendingAnimation = function()\n\ - {\n\ - return true;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.getTargetElement = function()\n\ - {\n\ - return this.aTargetElement;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.getAnimatedElement = function()\n\ - {\n\ - return this.aAnimatedElement;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.dispose= function()\n\ - {\n\ - if( this.aActivity )\n\ - this.aActivity.dispose();\n\ -\n\ - AnimationBaseNode.superclass.dispose.call( this );\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.getMinFrameCount = function()\n\ - {\n\ - return this.nMinFrameCount;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.getAdditiveMode = function()\n\ - {\n\ - return this.eAdditiveMode;\n\ - };\n\ -\n\ - AnimationBaseNode.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = AnimationBaseNode.superclass.info.call( this, bVerbose );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - if( this.getMinFrameCount() )\n\ - sInfo += '; min frame count: ' + this.getMinFrameCount();\n\ -\n\ - sInfo += '; additive: ' + aAddittiveModeOutMap[ this.getAdditiveMode() ];\n\ -\n\ - if( this.getShape() )\n\ - {\n\ - sElemId = this.getShape().getAttribute( 'id' );\n\ - sInfo += '; targetElement: ' + sElemId;\n\ - }\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function AnimationBaseNode2( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - AnimationBaseNode2.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sAttributeName;\n\ - this.aToValue;\n\ -\n\ - }\n\ - extend( AnimationBaseNode2, AnimationBaseNode );\n\ -\n\ -\n\ - AnimationBaseNode2.prototype.parseElement = function()\n\ - {\n\ - var bRet = AnimationBaseNode2.superclass.parseElement.call( this );\n\ -\n\ - var aAnimElem = this.aElement;\n\ -\n\ - this.sAttributeName = aAnimElem.getAttribute( 'attributeName' );\n\ - if( !this.sAttributeName )\n\ - {\n\ - this.eCurrentState = INVALID_NODE;\n\ - log( 'AnimationBaseNode2.parseElement: target attribute name not found: ' + this.sAttributeName );\n\ - }\n\ -\n\ - this.aToValue = aAnimElem.getAttribute( 'to' );\n\ -\n\ - return bRet;\n\ - };\n\ -\n\ - AnimationBaseNode2.prototype.getAttributeName = function()\n\ - {\n\ - return this.sAttributeName;\n\ - };\n\ -\n\ - AnimationBaseNode2.prototype.getToValue = function()\n\ - {\n\ - return this.aToValue;\n\ - };\n\ -\n\ - AnimationBaseNode2.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = AnimationBaseNode2.superclass.info.call( this, bVerbose );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - if( this.getAttributeName() )\n\ - sInfo += '; attributeName: ' + this.getAttributeName();\n\ -\n\ - if( this.getToValue() )\n\ - sInfo += '; to: ' + this.getToValue();\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function AnimationBaseNode3( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - AnimationBaseNode3.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.eAccumulate;\n\ - this.eCalcMode;\n\ - this.aFromValue;\n\ -"; - -static const char aSVGScript19[] = -"\ - this.aByValue;\n\ - this.aKeyTimes;\n\ - this.aValues;\n\ -\n\ - }\n\ - extend( AnimationBaseNode3, AnimationBaseNode2 );\n\ -\n\ -\n\ - AnimationBaseNode3.prototype.parseElement = function()\n\ - {\n\ - var bRet = AnimationBaseNode3.superclass.parseElement.call( this );\n\ -\n\ - var aAnimElem = this.aElement;\n\ -\n\ - this.eAccumulate = ACCUMULATE_MODE_NONE;\n\ - var sAccumulateAttr = aAnimElem.getAttribute( 'accumulate' );\n\ - if( sAccumulateAttr == 'sum' )\n\ - this.eAccumulate = ACCUMULATE_MODE_SUM;\n\ -\n\ - this.eCalcMode = CALC_MODE_LINEAR;\n\ - var sCalcModeAttr = aAnimElem.getAttribute( 'calcMode' );\n\ - if( sCalcModeAttr && aCalcModeInMap[ sCalcModeAttr ] )\n\ - this.eCalcMode = aCalcModeInMap[ sCalcModeAttr ];\n\ -\n\ - this.aFromValue = aAnimElem.getAttribute( 'from' );\n\ -\n\ - this.aByValue = aAnimElem.getAttribute( 'by' );\n\ -\n\ - this.aKeyTimes = new Array();\n\ - var sKeyTimesAttr = aAnimElem.getAttribute( 'keyTimes' );\n\ - sKeyTimesAttr = removeWhiteSpaces( sKeyTimesAttr );\n\ - if( sKeyTimesAttr )\n\ - {\n\ - var aKeyTimes = sKeyTimesAttr.split( ';' );\n\ - for( var i = 0; i < aKeyTimes.length; ++i )\n\ - this.aKeyTimes.push( parseFloat( aKeyTimes[i] ) );\n\ - }\n\ -\n\ - var sValuesAttr = aAnimElem.getAttribute( 'values' );\n\ - if( sValuesAttr )\n\ - {\n\ - this.aValues = sValuesAttr.split( ';' );\n\ - }\n\ - else\n\ - {\n\ - this.aValues = new Array();\n\ - }\n\ -\n\ - return bRet;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.getAccumulate = function()\n\ - {\n\ - return this.eAccumulate;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.getCalcMode = function()\n\ - {\n\ - return this.eCalcMode;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.getFromValue = function()\n\ - {\n\ - return this.aFromValue;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.getByValue = function()\n\ - {\n\ - return this.aByValue;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.getKeyTimes = function()\n\ - {\n\ - return this.aKeyTimes;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.getValues = function()\n\ - {\n\ - return this.aValues;\n\ - };\n\ -\n\ - AnimationBaseNode3.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = AnimationBaseNode3.superclass.info.call( this, bVerbose );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - if( this.getAccumulate() )\n\ - sInfo += '; accumulate: ' + aAccumulateModeOutMap[ this.getAccumulate() ];\n\ -\n\ - sInfo += '; calcMode: ' + aCalcModeOutMap[ this.getCalcMode() ];\n\ -\n\ - if( this.getFromValue() )\n\ - sInfo += '; from: ' + this.getFromValue();\n\ -\n\ - if( this.getByValue() )\n\ - sInfo += '; by: ' + this.getByValue();\n\ -\n\ - if( this.getKeyTimes().length )\n\ - sInfo += '; keyTimes: ' + this.getKeyTimes().join( ',' );\n\ -\n\ - if( this.getKeyTimes().length )\n\ - sInfo += '; values: ' + this.getValues().join( ',' );\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function BaseContainerNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - BaseContainerNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'BaseContainerNode';\n\ - this.bIsContainer = true;\n\ - this.aChildrenArray = new Array();\n\ - this.nFinishedChildren = 0;\n\ - this.bDurationIndefinite = false;\n\ -\n\ - this.eImpressNodeType = undefined;\n\ - this.ePresetClass = undefined;\n\ - this.ePresetId = undefined;\n\ - }\n\ - extend( BaseContainerNode, BaseNode );\n\ -\n\ -\n\ - BaseContainerNode.prototype.parseElement= function()\n\ - {\n\ - var bRet = BaseContainerNode.superclass.parseElement.call( this );\n\ -\n\ - var aAnimElem = this.aElement;\n\ -\n\ - this.eImpressNodeType = IMPRESS_DEFAULT_NODE;\n\ - var sNodeTypeAttr = aAnimElem.getAttribute( 'node-type' );\n\ - if( sNodeTypeAttr && aImpressNodeTypeInMap[ sNodeTypeAttr ] )\n\ - this.eImpressNodeType = aImpressNodeTypeInMap[ sNodeTypeAttr ];\n\ - this.bMainSequenceRootNode = ( this.eImpressNodeType == IMPRESS_MAIN_SEQUENCE_NODE );\n\ -\n\ - this.ePresetClass = undefined;\n\ - var sPresetClassAttr = aAnimElem.getAttribute( 'preset-class' );\n\ - if( sPresetClassAttr && aPresetClassInMap[ sPresetClassAttr ] )\n\ - this.ePresetClass = aPresetClassInMap[ sPresetClassAttr ];\n\ -\n\ - this.ePresetId = undefined;\n\ - var sPresetIdAttr = aAnimElem.getAttribute( 'preset-id' );\n\ - if( sPresetIdAttr && aPresetIdInMap[ sPresetIdAttr ] )\n\ - this.ePresetId = aPresetIdInMap[ sPresetIdAttr ];\n\ -\n\ -\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - this.aChildrenArray[i].parseElement();\n\ - }\n\ -\n\ -\n\ - this.bDurationIndefinite\n\ - = ( !this.getDuration() || this.getDuration().isIndefinite() ) &&\n\ - ( !this.getEnd() || ( this.getEnd().getType() != OFFSET_TIMING ) );\n\ -\n\ - return bRet;\n\ - };\n\ -\n\ - BaseContainerNode.prototype.appendChildNode = function( aAnimationNode )\n\ - {\n\ - if( ! this.checkValidNode() )\n\ - return ;\n\ -\n\ - if( aAnimationNode.registerDeactivatingListener( this ) )\n\ - this.aChildrenArray.push( aAnimationNode );\n\ - };\n\ -\n\ - BaseContainerNode.prototype.init_st = function()\n\ - {\n\ - this.nFinishedChildren = 0;\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - var nInitChildren = 0;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - if( this.aChildrenArray[i].init() )\n\ - {\n\ - ++nInitChildren;\n\ - }\n\ - }\n\ - return ( nChildrenCount == nInitChildren );\n\ - };\n\ -\n\ - BaseContainerNode.prototype.deactivate_st = function( eDestState )\n\ - {\n\ - if( eDestState == FROZEN_NODE )\n\ - {\n\ - this.forEachChildNode( mem_fn( 'deactivate' ), ~( FROZEN_NODE | ENDED_NODE ) );\n\ - }\n\ - else\n\ - {\n\ - this.forEachChildNode( mem_fn( 'end' ), ~ENDED_NODE );\n\ - }\n\ - };\n\ -\n\ - BaseContainerNode.prototype.hasPendingAnimation = function()\n\ -"; - -static const char aSVGScript20[] = -"\ - {\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - if( this.aChildrenArray[i].hasPendingAnimation() )\n\ - return true;\n\ - }\n\ - return false;\n\ - };\n\ -\n\ - BaseContainerNode.prototype.activate_st = function()\n\ - {\n\ - log( 'BaseContainerNode.activate_st: abstract method called' );\n\ - };\n\ -\n\ - BaseContainerNode.prototype.notifyDeactivating = function( aAnimationNode )\n\ - {\n\ - log( 'BaseContainerNode.notifyDeactivating: abstract method called' );\n\ - };\n\ -\n\ - BaseContainerNode.prototype.isDurationIndefinite = function()\n\ - {\n\ - return this.bDurationIndefinite;\n\ - };\n\ -\n\ - BaseContainerNode.prototype.isChildNode = function( aAnimationNode )\n\ - {\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - if( this.aChildrenArray[i].getId() == aAnimationNode.getId() )\n\ - return true;\n\ - }\n\ - return false;\n\ - };\n\ -\n\ - BaseContainerNode.prototype.notifyDeactivatedChild = function( aChildNode )\n\ - {\n\ - assert( ( aChildNode.getState() == FROZEN_NODE ) || ( aChildNode.getState() == ENDED_NODE ),\n\ - 'BaseContainerNode.notifyDeactivatedChild: passed child node is neither in FROZEN nor in ENDED state' );\n\ -\n\ - assert( this.getState() != INVALID_NODE,\n\ - 'BaseContainerNode.notifyDeactivatedChild: this node is invalid' );\n\ -\n\ - if( !this.isChildNode( aChildNode ) )\n\ - {\n\ - log( 'BaseContainerNode.notifyDeactivatedChild: unknown child notifier!' );\n\ - return false;\n\ - }\n\ -\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ -\n\ - assert( ( this.nFinishedChildren < nChildrenCount ),\n\ - 'BaseContainerNode.notifyDeactivatedChild: assert(this.nFinishedChildren < nChildrenCount) failed' );\n\ -\n\ - ++this.nFinishedChildren;\n\ - var bFinished = ( this.nFinishedChildren >= nChildrenCount );\n\ -\n\ - if( bFinished && this.isDurationIndefinite() )\n\ - {\n\ - this.deactivate();\n\ - }\n\ -\n\ - return bFinished;\n\ - };\n\ -\n\ - BaseContainerNode.prototype.forEachChildNode = function( aFunction, eNodeStateMask )\n\ - {\n\ - if( !eNodeStateMask )\n\ - eNodeStateMask = -1;\n\ -\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - if( ( eNodeStateMask != -1 ) && ( ( this.aChildrenArray[i].getState() & eNodeStateMask ) == 0 ) )\n\ - continue;\n\ - aFunction( this.aChildrenArray[i] );\n\ - }\n\ - };\n\ -\n\ - BaseContainerNode.prototype.dispose = function()\n\ - {\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - this.aChildrenArray[i].dispose();\n\ - }\n\ -\n\ - BaseContainerNode.superclass.dispose.call( this );\n\ - };\n\ -\n\ - BaseContainerNode.prototype.getImpressNodeType = function()\n\ - {\n\ - return this.eImpressNodeType;\n\ - };\n\ -\n\ - BaseContainerNode.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = BaseContainerNode.superclass.info.call( this, bVerbose );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - if( this.getImpressNodeType() )\n\ - sInfo += '; node-type: ' + aImpressNodeTypeOutMap[ this.getImpressNodeType() ];\n\ - }\n\ -\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - sInfo += '\\n';\n\ - sInfo += this.aChildrenArray[i].info( bVerbose );\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ - function ParallelTimeContainer( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - ParallelTimeContainer.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'ParallelTimeContainer';\n\ - }\n\ - extend( ParallelTimeContainer, BaseContainerNode );\n\ -\n\ -\n\ - ParallelTimeContainer.prototype.activate_st = function()\n\ - {\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - var nResolvedChildren = 0;\n\ - for( var i = 0; i < nChildrenCount; ++i )\n\ - {\n\ - if( this.aChildrenArray[i].resolve() )\n\ - {\n\ - ++nResolvedChildren;\n\ - }\n\ - }\n\ -\n\ - if( nChildrenCount != nResolvedChildren )\n\ - {\n\ - log( 'ParallelTimeContainer.activate_st: resolving all children failed' );\n\ - return;\n\ - }\n\ -\n\ -\n\ - if( this.isDurationIndefinite() && ( nChildrenCount == 0 ) )\n\ - {\n\ - this.scheduleDeactivationEvent( this.makeDeactivationEvent( 0.0 ) );\n\ - }\n\ - else\n\ - {\n\ - this.scheduleDeactivationEvent();\n\ - }\n\ - };\n\ -\n\ - ParallelTimeContainer.prototype.notifyDeactivating = function( aAnimationNode )\n\ - {\n\ - this.notifyDeactivatedChild( aAnimationNode );\n\ - };\n\ -\n\ -\n\ - function SequentialTimeContainer( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - SequentialTimeContainer.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'SequentialTimeContainer';\n\ - }\n\ - extend( SequentialTimeContainer, BaseContainerNode );\n\ -\n\ -\n\ - SequentialTimeContainer.prototype.activate_st = function()\n\ - {\n\ - var nChildrenCount = this.aChildrenArray.length;\n\ - for( ; this.nFinishedChildren < nChildrenCount; ++this.nFinishedChildren )\n\ - {\n\ - if( this.resolveChild( this.aChildrenArray[ this.nFinishedChildren ] ) )\n\ - break;\n\ - else\n\ - log( 'SequentialTimeContainer.activate_st: resolving child failed!' );\n\ - }\n\ -\n\ - if( this.isDurationIndefinite() && ( ( nChildrenCount == 0 ) || ( this.nFinishedChildren >= nChildrenCount ) ) )\n\ - {\n\ - this.scheduleDeactivationEvent( this.makeDeactivationEvent( 0.0 ) );\n\ - }\n\ - else\n\ - {\n\ - this.scheduleDeactivationEvent();\n\ - }\n\ - };\n\ -\n\ - SequentialTimeContainer.prototype.notifyDeactivating = function( aNotifier )\n\ - {\n\ - if( this.notifyDeactivatedChild( aNotifier ) )\n\ - return;\n\ -\n\ - assert( this.nFinishedChildren < this.aChildrenArray.length,\n\ - 'SequentialTimeContainer.notifyDeactivating: assertion (this.nFinishedChildren < this.aChildrenArray.length) failed' );\n\ -\n\ - var aNextChild = this.aChildrenArray[ this.nFinishedChildren ];\n\ -\n\ -"; - -static const char aSVGScript21[] = -"\ - assert( aNextChild.getState() == UNRESOLVED_NODE,\n\ - 'SequentialTimeContainer.notifyDeactivating: assertion (aNextChild.getState == UNRESOLVED_NODE) failed' );\n\ -\n\ - if( !this.resolveChild( aNextChild ) )\n\ - {\n\ - this.deactivate();\n\ - }\n\ - };\n\ -\n\ - SequentialTimeContainer.prototype.skipEffect = function( aChildNode )\n\ - {\n\ - };\n\ -\n\ - SequentialTimeContainer.prototype.rewindEffect = function( aChildNode )\n\ - {\n\ - };\n\ -\n\ - SequentialTimeContainer.prototype.resolveChild = function( aChildNode )\n\ - {\n\ - var bResolved = aChildNode.resolve();\n\ -\n\ - if( bResolved && this.isMainSequenceRootNode() )\n\ - {\n\ - }\n\ - return bResolved;\n\ - };\n\ -\n\ -\n\ - function PropertyAnimationNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - PropertyAnimationNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'PropertyAnimationNode';\n\ - }\n\ - extend( PropertyAnimationNode, AnimationBaseNode3 );\n\ -\n\ -\n\ - PropertyAnimationNode.prototype.createActivity = function()\n\ - {\n\ -\n\ -\n\ - var aActivityParamSet = this.fillActivityParams();\n\ -\n\ - var aAnimation = createPropertyAnimation( this.getAttributeName(),\n\ - this.getAnimatedElement(),\n\ - this.aNodeContext.aSlideWidth,\n\ - this.aNodeContext.aSlideHeight );\n\ -\n\ - var aInterpolator = null; // createActivity will compute it;\n\ - return createActivity( aActivityParamSet, this, aAnimation, aInterpolator );\n\ -\n\ - };\n\ -\n\ -\n\ - function AnimationSetNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - AnimationSetNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'AnimationSetNode';\n\ - }\n\ - extend( AnimationSetNode, AnimationBaseNode2 );\n\ -\n\ -\n\ - AnimationSetNode.prototype.createActivity = function()\n\ - {\n\ - var aAnimation = createPropertyAnimation( this.getAttributeName(),\n\ - this.getAnimatedElement(),\n\ - this.aNodeContext.aSlideWidth,\n\ - this.aNodeContext.aSlideHeight );\n\ -\n\ - var aActivityParamSet = this.fillActivityParams();\n\ -\n\ - return new SetActivity( aActivityParamSet, aAnimation, this.getToValue() );\n\ - };\n\ -\n\ -\n\ - function AnimationColorNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - AnimationColorNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'AnimationColorNode';\n\ -\n\ - this.eColorInterpolation;\n\ - this.eColorInterpolationDirection;\n\ - }\n\ - extend( AnimationColorNode, AnimationBaseNode3 );\n\ -\n\ -\n\ - AnimationColorNode.prototype.parseElement = function()\n\ - {\n\ - var bRet = AnimationColorNode.superclass.parseElement.call( this );\n\ -\n\ - var aAnimElem = this.aElement;\n\ -\n\ - this.eColorInterpolation = COLOR_SPACE_RGB;\n\ - var sColorInterpolationAttr = aAnimElem.getAttribute( 'color-interpolation' );\n\ - if( sColorInterpolationAttr && aColorSpaceInMap[ sColorInterpolationAttr ] )\n\ - this.eColorInterpolation = aColorSpaceInMap[ sColorInterpolationAttr ];\n\ -\n\ - this.eColorInterpolationDirection = CLOCKWISE;\n\ - var sColorInterpolationDirectionAttr = aAnimElem.getAttribute( 'color-interpolation-direction' );\n\ - if( sColorInterpolationDirectionAttr && aClockDirectionInMap[ sColorInterpolationDirectionAttr ] )\n\ - this.eColorInterpolationDirection = aClockDirectionInMap[ sColorInterpolationDirectionAttr ];\n\ -\n\ - return bRet;\n\ - };\n\ -\n\ - AnimationColorNode.prototype.createActivity = function()\n\ - {\n\ -\n\ -\n\ - var aActivityParamSet = this.fillActivityParams();\n\ -\n\ - var aAnimation = createPropertyAnimation( this.getAttributeName(),\n\ - this.getAnimatedElement(),\n\ - this.aNodeContext.aSlideWidth,\n\ - this.aNodeContext.aSlideHeight );\n\ -\n\ - var aColorAnimation;\n\ - var aInterpolator;\n\ - if( this.getColorInterpolation() === COLOR_SPACE_HSL )\n\ - {\n\ - ANIMDBG.print( 'AnimationColorNode.createActivity: color space hsl' );\n\ - aColorAnimation = new HSLAnimationWrapper( aAnimation );\n\ - var aInterpolatorMaker = aInterpolatorHandler.getInterpolator( this.getCalcMode(),\n\ - COLOR_PROPERTY,\n\ - COLOR_SPACE_HSL );\n\ - aInterpolator = aInterpolatorMaker( this.getColorInterpolationDirection() );\n\ - }\n\ - else\n\ - {\n\ - ANIMDBG.print( 'AnimationColorNode.createActivity: color space rgb' );\n\ - aColorAnimation = aAnimation;\n\ - aInterpolator = aInterpolatorHandler.getInterpolator( this.getCalcMode(),\n\ - COLOR_PROPERTY,\n\ - COLOR_SPACE_RGB );\n\ - }\n\ -\n\ - return createActivity( aActivityParamSet, this, aColorAnimation, aInterpolator );\n\ -\n\ -\n\ - };\n\ -\n\ - AnimationColorNode.prototype.getColorInterpolation = function()\n\ - {\n\ - return this.eColorInterpolation;\n\ - };\n\ -\n\ - AnimationColorNode.prototype.getColorInterpolationDirection = function()\n\ - {\n\ - return this.eColorInterpolationDirection;\n\ - };\n\ -\n\ - AnimationColorNode.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = AnimationColorNode.superclass.info.call( this, bVerbose );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - sInfo += '; color-interpolation: ' + aColorSpaceOutMap[ this.getColorInterpolation() ];\n\ -\n\ - sInfo += '; color-interpolation-direction: ' + aClockDirectionOutMap[ this.getColorInterpolationDirection() ];\n\ - }\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function AnimationTransitionFilterNode( aAnimElem, aParentNode, aNodeContext )\n\ - {\n\ - AnimationTransitionFilterNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext );\n\ -\n\ - this.sClassName = 'AnimationTransitionFilterNode';\n\ -\n\ - this.eTransitionType;\n\ - this.eTransitionSubType;\n\ - this.bReverseDirection;\n\ - this.eTransitionMode;\n\ - }\n\ - extend( AnimationTransitionFilterNode, AnimationBaseNode );\n\ -\n\ -\n\ - AnimationTransitionFilterNode.prototype.createActivity = function()\n\ - {\n\ - var aActivityParamSet = this.fillActivityParams();\n\ -\n\ - var aAnimation = createPropertyAnimation( 'opacity',\n\ - this.getAnimatedElement(),\n\ - this.aNodeContext.aSlideWidth,\n\ - this.aNodeContext.aSlideHeight );\n\ -\n\ - var eDirection = this.getTransitionMode() ? FORWARD : BACKWARD;\n\ -\n\ - return new SimpleActivity( aActivityParamSet, aAnimation, eDirection );\n\ -\n\ - };\n\ -\n\ - AnimationTransitionFilterNode.prototype.parseElement = function()\n\ - {\n\ - var bRet = AnimationTransitionFilterNode.superclass.parseElement.call( this );\n\ -\n\ -"; - -static const char aSVGScript22[] = -"\ - var aAnimElem = this.aElement;\n\ -\n\ - this.eTransitionType = undefined;\n\ - var sTypeAttr = aAnimElem.getAttribute( 'type' );\n\ - if( sTypeAttr && aTransitionTypeInMap[ sTypeAttr ] )\n\ - {\n\ - this.eTransitionType = aTransitionTypeInMap[ sTypeAttr ];\n\ - }\n\ - else\n\ - {\n\ - this.eCurrentState = INVALID_NODE;\n\ - log( 'AnimationTransitionFilterNode.parseElement: transition type not valid: ' + sTypeAttr );\n\ - }\n\ -\n\ - this.eTransitionSubType = undefined;\n\ - var sSubTypeAttr = aAnimElem.getAttribute( 'subtype' );\n\ - if( sSubTypeAttr && aTransitionSubtypeInMap[ sSubTypeAttr ] )\n\ - {\n\ - this.eTransitionSubType = aTransitionSubtypeInMap[ sSubTypeAttr ];\n\ - }\n\ - else\n\ - {\n\ - this.eCurrentState = INVALID_NODE;\n\ - log( 'AnimationTransitionFilterNode.parseElement: transition subtype not valid: ' + sSubTypeAttr );\n\ - }\n\ -\n\ - this.bReverseDirection = false;\n\ - var sDirectionAttr = aAnimElem.getAttribute( 'direction' );\n\ - if( sDirectionAttr == 'reverse' )\n\ - this.bReverseDirection = true;\n\ -\n\ - this.eTransitionMode = TRANSITION_MODE_IN;\n\ - var sModeAttr = aAnimElem.getAttribute( 'mode' );\n\ - if( sModeAttr === 'out' )\n\ - this.eTransitionMode = TRANSITION_MODE_OUT;\n\ -\n\ - return bRet;\n\ - };\n\ -\n\ - AnimationTransitionFilterNode.prototype.getTransitionType = function()\n\ - {\n\ - return this.eTransitionType;\n\ - };\n\ -\n\ - AnimationTransitionFilterNode.prototype.getTransitionSubType = function()\n\ - {\n\ - return this.eTransitionSubType;\n\ - };\n\ -\n\ - AnimationTransitionFilterNode.prototype.getTransitionMode = function()\n\ - {\n\ - return this.eTransitionMode;\n\ - };\n\ -\n\ - AnimationTransitionFilterNode.prototype.getReverseDirection = function()\n\ - {\n\ - return this.bReverseDirection;\n\ - };\n\ -\n\ - AnimationTransitionFilterNode.prototype.info = function( bVerbose )\n\ - {\n\ - var sInfo = AnimationTransitionFilterNode.superclass.info.call( this, bVerbose );\n\ -\n\ - if( bVerbose )\n\ - {\n\ - sInfo += '; type: ' + aTransitionTypeOutMap[ String( this.getTransitionType() ) ];\n\ -\n\ - sInfo += '; subtype: ' + aTransitionSubtypeOutMap[ this.getTransitionSubType() ];\n\ -\n\ - if( this.getReverseDirection() )\n\ - sInfo += '; direction: reverse';\n\ - }\n\ -\n\ - return sInfo;\n\ - };\n\ -\n\ -\n\ - function createAnimationTree( aRootElement, aNodeContext )\n\ - {\n\ - return createAnimationNode( aRootElement, null, aNodeContext );\n\ - }\n\ -\n\ -\n\ - function createAnimationNode( aElement, aParentNode, aNodeContext )\n\ - {\n\ - assert( aElement, 'createAnimationNode: invalid animation element' );\n\ -\n\ - var eAnimationNodeType = getAnimationElementType( aElement );\n\ -\n\ - var aCreatedNode = null;\n\ - var aCreatedContainer = null;\n\ -\n\ - switch( eAnimationNodeType )\n\ - {\n\ - case ANIMATION_NODE_PAR:\n\ - aCreatedNode = aCreatedContainer =\n\ - new ParallelTimeContainer( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - case ANIMATION_NODE_ITERATE:\n\ - aCreatedNode = aCreatedContainer =\n\ - new ParallelTimeContainer( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - case ANIMATION_NODE_SEQ:\n\ - aCreatedNode = aCreatedContainer =\n\ - new SequentialTimeContainer( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - case ANIMATION_NODE_ANIMATE:\n\ - aCreatedNode = new PropertyAnimationNode( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - case ANIMATION_NODE_SET:\n\ - aCreatedNode = new AnimationSetNode( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - case ANIMATION_NODE_ANIMATEMOTION:\n\ - log( 'createAnimationNode: ANIMATEMOTION not implemented' );\n\ - return null;\n\ - case ANIMATION_NODE_ANIMATECOLOR:\n\ - aCreatedNode = new AnimationColorNode( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - case ANIMATION_NODE_ANIMATETRANSFORM:\n\ - log( 'createAnimationNode: ANIMATETRANSFORM not implemented' );\n\ - return null;\n\ - case ANIMATION_NODE_TRANSITIONFILTER:\n\ - aCreatedNode = new AnimationTransitionFilterNode( aElement, aParentNode, aNodeContext );\n\ - break;\n\ - default:\n\ - log( 'createAnimationNode: invalid Animation Node Type: ' + eAnimationNodeType );\n\ - return null;\n\ - }\n\ -\n\ - if( aCreatedContainer )\n\ - {\n\ - if( eAnimationNodeType == ANIMATION_NODE_ITERATE )\n\ - {\n\ - createIteratedNodes( aElement, aCreatedContainer, aNodeContext );\n\ - }\n\ - else\n\ - {\n\ - var aChildrenArray = getElementChildren( aElement );\n\ - for( var i = 0; i < aChildrenArray.length; ++i )\n\ - {\n\ - if( !createChildNode( aChildrenArray[i], aCreatedContainer, aNodeContext ) )\n\ - {\n\ - return null;\n\ - }\n\ - }\n\ - }\n\ - }\n\ -\n\ - return aCreatedNode;\n\ - }\n\ -\n\ -\n\ - function createChildNode( aElement, aParentNode, aNodeContext )\n\ - {\n\ - var aChildNode = createAnimationNode( aElement, aParentNode, aNodeContext );\n\ -\n\ - if( !aChildNode )\n\ - {\n\ - log( 'createChildNode: child node creation failed' );\n\ - return false;\n\ - }\n\ - else\n\ - {\n\ - aParentNode.appendChildNode( aChildNode );\n\ - return true;\n\ - }\n\ - }\n\ -\n\ -\n\ - function createIteratedNodes( aElement, aContainerNode, aNodeContext )\n\ - {\n\ - }\n\ -\n\ -\n\ - function makeScaler( nScale )\n\ - {\n\ - if( ( typeof( nScale ) !== typeof( 0 ) ) || !isFinite( nScale ) )\n\ - {\n\ - log( 'makeScaler: not valid param passed: ' + nScale );\n\ - return null;\n\ - }\n\ -\n\ - return function( nValue )\n\ - {\n\ - return ( nScale * nValue );\n\ - };\n\ - }\n\ -\n\ -\n\ - function createPropertyAnimation( sAttrName, aAnimatedElement, nWidth, nHeight )\n\ - {\n\ - if( !aAttributeMap[ sAttrName ] )\n\ - {\n\ - log( 'createPropertyAnimation: attribute is unknown' );\n\ - return;\n\ - }\n\ -\n\ -\n\ - var aFunctorSet = aAttributeMap[ sAttrName ];\n\ -\n\ -"; - -static const char aSVGScript23[] = -"\ - var sGetValueMethod = aFunctorSet.get;\n\ - var sSetValueMethod = aFunctorSet.set;\n\ -\n\ - if( !sGetValueMethod || !sSetValueMethod )\n\ - {\n\ - log( 'createPropertyAnimation: attribute is not handled' );\n\ - return;\n\ - }\n\ -\n\ - var aGetModifier = eval( aFunctorSet.getmod );\n\ - var aSetModifier = eval( aFunctorSet.setmod );\n\ -\n\ -\n\ - return new GenericAnimation( bind( aAnimatedElement, aAnimatedElement[ sGetValueMethod ] ),\n\ - bind( aAnimatedElement, aAnimatedElement[ sSetValueMethod ] ),\n\ - aGetModifier,\n\ - aSetModifier);\n\ - }\n\ -\n\ -\n\ - function GenericAnimation( aGetValueFunc, aSetValueFunc, aGetModifier, aSetModifier )\n\ - {\n\ - assert( aGetValueFunc && aSetValueFunc,\n\ - 'GenericAnimation constructor: get value functor and/or set value functor are not valid' );\n\ -\n\ - this.aGetValueFunc = aGetValueFunc;\n\ - this.aSetValueFunc = aSetValueFunc;\n\ - this.aGetModifier = aGetModifier;\n\ - this.aSetModifier = aSetModifier;\n\ - this.aAnimatableElement = null;\n\ - this.bAnimationStarted = false;\n\ - }\n\ -\n\ -\n\ - GenericAnimation.prototype.start = function( aAnimatableElement )\n\ - {\n\ - assert( aAnimatableElement, 'GenericAnimation.start: animatable element is not valid' );\n\ -\n\ - this.aAnimatableElement = aAnimatableElement;\n\ - this.aAnimatableElement.notifyAnimationStart();\n\ -\n\ - if( !this.bAnimationStarted )\n\ - this.bAnimationStarted = true;\n\ - };\n\ -\n\ - GenericAnimation.prototype.end = function()\n\ - {\n\ - if( this.bAnimationStarted )\n\ - this.bAnimationStarted = false;\n\ - };\n\ -\n\ - GenericAnimation.prototype.perform = function( aValue )\n\ - {\n\ - if( this.aSetModifier )\n\ - aValue = this.aSetModifier( aValue );\n\ -\n\ - this.aSetValueFunc( aValue );\n\ - };\n\ -\n\ - GenericAnimation.prototype.getUnderlyingValue = function()\n\ - {\n\ - var aValue = this.aGetValueFunc();\n\ - if( this.aGetModifier )\n\ - aValue = this.aGetModifier( aValue );\n\ - return aValue;\n\ - };\n\ -\n\ -\n\ - function HSLAnimationWrapper( aColorAnimation )\n\ - {\n\ - assert( aColorAnimation,\n\ - 'HSLAnimationWrapper constructor: invalid color animation delegate' );\n\ -\n\ - this.aAnimation = aColorAnimation;\n\ - }\n\ -\n\ -\n\ - HSLAnimationWrapper.prototype.start = function( aAnimatableElement )\n\ - {\n\ - this.aAnimation.start( aAnimatableElement );\n\ - };\n\ -\n\ - HSLAnimationWrapper.prototype.end = function()\n\ - {\n\ - this.aAnimation.end();\n\ - };\n\ - HSLAnimationWrapper.prototype.perform = function( aHSLValue )\n\ - {\n\ - this.aAnimation.perform( aHSLValue.convertToRGB() );\n\ - };\n\ -\n\ - HSLAnimationWrapper.prototype.getUnderlyingValue = function()\n\ - {\n\ - return this.aAnimation.getUnderlyingValue().convertToHSL();\n\ - };\n\ -\n\ -\n\ - function AnimatedElement( aElement )\n\ - {\n\ - if( !aElement )\n\ - {\n\ - log( 'AnimatedElement constructor: element is not valid' );\n\ - }\n\ -\n\ - this.aActiveElement = aElement;\n\ - this.initElement();\n\ -\n\ - this.aBaseBBox = this.aActiveElement.getBBox();\n\ - this.nBaseCenterX = this.aBaseBBox.x + this.aBaseBBox.width / 2;\n\ - this.nBaseCenterY = this.aBaseBBox.y + this.aBaseBBox.height / 2;\n\ - this.nCenterX = this.nBaseCenterX;\n\ - this.nCenterY = this.nBaseCenterY;\n\ - this.nScaleFactorX = 1.0;\n\ - this.nScaleFactorY = 1.0;\n\ -\n\ - this.aPreviousElement = null;\n\ - this.aElementArray = new Array();\n\ - this.nCurrentState = 0;\n\ - this.eAdditiveMode = ADDITIVE_MODE_REPLACE;\n\ - this.bIsUpdated = true;\n\ -\n\ - this.aTMatrix = document.documentElement.createSVGMatrix();\n\ - this.aCTM = document.documentElement.createSVGMatrix();\n\ - this.aICTM = document.documentElement.createSVGMatrix();\n\ - this.setCTM();\n\ -\n\ - this.aElementArray[0] = this.aActiveElement.cloneNode( true );\n\ - }\n\ -\n\ - AnimatedElement.prototype.initElement = function()\n\ - {\n\ - this.aActiveElement.setAttribute( 'transform', makeMatrixString( 1, 0, 0, 1, 0, 0 ) );\n\ - };\n\ -\n\ - AnimatedElement.prototype.getId = function()\n\ - {\n\ - return this.aActiveElement.getAttribute( 'id' );\n\ - };\n\ -\n\ - AnimatedElement.prototype.isUpdated = function()\n\ - {\n\ - return this.bIsUpdated;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getAdditiveMode = function()\n\ - {\n\ - return this.eAdditiveMode;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setAdditiveMode = function( eAdditiveMode )\n\ - {\n\ - this.eAdditiveMode = eAdditiveMode;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setToElement = function( aElement )\n\ - {\n\ - if( !aElement )\n\ - {\n\ - log( 'AnimatedElement(' + this.getId() + ').setToElement: element is not valid' );\n\ - return false;\n\ - }\n\ -\n\ - var aClone = aElement.cloneNode( true );\n\ - this.aPreviousElement = this.aActiveElement.parentNode.replaceChild( aClone, this.aActiveElement );\n\ - this.aActiveElement = aClone;\n\ -\n\ - return true;\n\ - };\n\ -\n\ - AnimatedElement.prototype.notifySlideStart = function()\n\ - {\n\ - this.setToFirst();\n\ - this.DBG( '.notifySlideStart invoked' );\n\ - };\n\ -\n\ - AnimatedElement.prototype.notifyAnimationStart = function()\n\ - {\n\ -\n\ - this.DBG( '.notifyAnimationStart invoked' );\n\ - this.bIsUpdated = false;\n\ - };\n\ -\n\ - AnimatedElement.prototype.notifyAnimationEnd = function()\n\ - {\n\ - };\n\ -\n\ - AnimatedElement.prototype.notifyNextEffectStart = function( nEffectIndex )\n\ - {\n\ - assert( this.nCurrentState === nEffectIndex,\n\ - 'AnimatedElement(' + this.getId() + ').notifyNextEffectStart: assertion (current state == effect index) failed' );\n\ -\n\ - if( this.isUpdated() )\n\ - {\n\ - if( !this.aElementArray[ nEffectIndex ] )\n\ - {\n\ - this.aElementArray[ nEffectIndex ] = this.aElementArray[ this.nCurrentState ];\n\ - this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): new state set to previous one ' );\n\ - }\n\ - }\n\ - else\n\ -"; - -static const char aSVGScript24[] = -"\ - {\n\ - if( !this.aElementArray[ nEffectIndex ] )\n\ - {\n\ - this.aElementArray[ nEffectIndex ] = this.aActiveElement.cloneNode( true );\n\ - this.DBG( '.notifyNextEffectStart(' + nEffectIndex + '): cloned active state ' );\n\ - }\n\ - }\n\ - ++this.nCurrentState;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setToFirst = function()\n\ - {\n\ - this.setTo( 0 );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setToLast = function()\n\ - {\n\ - this.setTo( this.aElementArray.length - 1 );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setTo = function( nEffectIndex )\n\ - {\n\ - var bRet = this.setToElement( this.aElementArray[ nEffectIndex ] );\n\ - if( bRet )\n\ - {\n\ - this.nCurrentState = nEffectIndex;\n\ -\n\ - var aBBox = this.getBBox();\n\ - var aBaseBBox = this.getBaseBBox();\n\ - this.nCenterX = aBBox.x + aBBox.width / 2;\n\ - this.nCenterY = aBBox.y + aBBox.height / 2;\n\ - this.nScaleFactorX = aBBox.width / aBaseBBox.width;\n\ - this.nScaleFactorY = aBBox.height / aBaseBBox.height;\n\ - }\n\ - };\n\ -\n\ - AnimatedElement.prototype.getBaseBBox = function()\n\ - {\n\ - return this.aBaseBBox;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getBaseCenterX = function()\n\ - {\n\ - return this.nBaseCenterX;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getBaseCenterY = function()\n\ - {\n\ - return this.nBaseCenterY;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getBBox = function()\n\ - {\n\ - return this.aActiveElement.parentNode.getBBox();\n\ - };\n\ -\n\ - AnimatedElement.prototype.getX = function()\n\ - {\n\ - return this.nCenterX;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getY = function()\n\ - {\n\ - return this.nCenterY;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getWidth = function()\n\ - {\n\ - return this.nScaleFactorX * this.getBaseBBox().width;\n\ - };\n\ -\n\ - AnimatedElement.prototype.getHeight = function()\n\ - {\n\ - return this.nScaleFactorY * this.getBaseBBox().height;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setCTM = function()\n\ - {\n\ -\n\ - this.aICTM.e = this.getBaseCenterX();\n\ - this.aICTM.f = this.getBaseCenterY();\n\ -\n\ - this.aCTM.e = -this.aICTM.e;\n\ - this.aCTM.f = -this.aICTM.f;\n\ - };\n\ -\n\ - AnimatedElement.prototype.updateTransformAttribute = function()\n\ - {\n\ - this.aTransformAttrList = this.aActiveElement.transform.baseVal;\n\ - this.aTransformAttr = this.aTransformAttrList.getItem( 0 );\n\ - this.aTransformAttr.setMatrix( this.aTMatrix );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setX = function( nXNewPos )\n\ - {\n\ - this.aTransformAttrList = this.aActiveElement.transform.baseVal;\n\ - this.aTransformAttr = this.aTransformAttrList.getItem( 0 );\n\ - this.aTransformAttr.matrix.e += ( nXNewPos - this.getX() );\n\ - this.nCenterX = nXNewPos;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setY = function( nYNewPos )\n\ - {\n\ - this.aTransformAttrList = this.aActiveElement.transform.baseVal;\n\ - this.aTransformAttr = this.aTransformAttrList.getItem( 0 );\n\ - this.aTransformAttr.matrix.f += ( nYNewPos - this.getY() );\n\ - this.nCenterY = nYNewPos;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setWidth = function( nNewWidth )\n\ - {\n\ - var nBaseWidth = this.getBaseBBox().width;\n\ - if( nBaseWidth <= 0 )\n\ - return;\n\ -\n\ - this.nScaleFactorX = nNewWidth / nBaseWidth;\n\ - this.implScale();\n\ - };\n\ -\n\ - AnimatedElement.prototype.setHeight = function( nNewHeight )\n\ - {\n\ - var nBaseHeight = this.getBaseBBox().height;\n\ - if( nBaseHeight <= 0 )\n\ - return;\n\ -\n\ - this.nScaleFactorY = nNewHeight / nBaseHeight;\n\ - this.implScale();\n\ - };\n\ -\n\ - AnimatedElement.prototype.implScale = function( )\n\ - {\n\ - this.aTMatrix = document.documentElement.createSVGMatrix();\n\ - this.aTMatrix.a = this.nScaleFactorX;\n\ - this.aTMatrix.d = this.nScaleFactorY;\n\ - this.aTMatrix = this.aICTM.multiply( this.aTMatrix.multiply( this.aCTM ) );\n\ -\n\ - var nDeltaX = this.getX() - this.getBaseCenterX();\n\ - var nDeltaY = this.getY() - this.getBaseCenterY();\n\ - this.aTMatrix = this.aTMatrix.translate( nDeltaX, nDeltaY );\n\ - this.updateTransformAttribute();\n\ - };\n\ -\n\ - AnimatedElement.prototype.setWidth2 = function( nNewWidth )\n\ - {\n\ - if( nNewWidth < 0 )\n\ - log( 'AnimatedElement(' + this.getId() + ').setWidth: negative width!' );\n\ - if( nNewWidth < 0.001 )\n\ - nNewWidth = 0.001;\n\ -\n\ - this.setCTM();\n\ -\n\ - var nCurWidth = this.getWidth();\n\ - if( nCurWidth <= 0 )\n\ - nCurWidth = 0.001;\n\ -\n\ - var nScaleFactor = nNewWidth / nCurWidth;\n\ - if( nScaleFactor < 1e-5 )\n\ - nScaleFactor = 1e-5;\n\ - this.aTMatrix = document.documentElement.createSVGMatrix();\n\ - this.aTMatrix.a = nScaleFactor;\n\ - this.aTMatrix = this.aICTM.multiply( this.aTMatrix.multiply( this.aCTM ) );\n\ - this.updateTransformAttribute();\n\ - };\n\ -\n\ - AnimatedElement.prototype.setHeight2 = function( nNewHeight )\n\ - {\n\ - ANIMDBG.print( 'AnimatedElement.setHeight: nNewHeight = ' + nNewHeight );\n\ - if( nNewHeight < 0 )\n\ - log( 'AnimatedElement(' + this.getId() + ').setWidth: negative height!' );\n\ - if( nNewHeight < 0.001 )\n\ - nNewHeight = 0.001;\n\ -\n\ - this.setCTM();\n\ -\n\ - var nCurHeight = this.getHeight();\n\ - ANIMDBG.print( 'AnimatedElement.setHeight: nCurHeight = ' + nCurHeight );\n\ - if( nCurHeight <= 0 )\n\ - nCurHeight = 0.001;\n\ -\n\ - var nScaleFactor = nNewHeight / nCurHeight;\n\ - ANIMDBG.print( 'AnimatedElement.setHeight: nScaleFactor = ' + nScaleFactor );\n\ - if( nScaleFactor < 1e-5 )\n\ - nScaleFactor = 1e-5;\n\ - this.aTMatrix = document.documentElement.createSVGMatrix();\n\ - this.aTMatrix.d = nScaleFactor;\n\ - this.aTMatrix = this.aICTM.multiply( this.aTMatrix.multiply( this.aCTM ) );\n\ - this.updateTransformAttribute();\n\ - };\n\ -\n\ - AnimatedElement.prototype.getOpacity = function()\n\ - {\n\ - return this.aActiveElement.getAttribute( 'opacity' );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setOpacity = function( nValue )\n\ - {\n\ - this.aActiveElement.setAttribute( 'opacity', nValue );\n\ - };\n\ -\n\ - AnimatedElement.prototype.getVisibility = function()\n\ -"; - -static const char aSVGScript25[] = -"\ - {\n\ -\n\ - var sVisibilityValue = this.aActiveElement.getAttribute( 'visibility' );\n\ - if( !sVisibilityValue || ( sVisibilityValue === 'inherit' ) )\n\ - return 'visible'; // TODO: look for parent visibility!\n\ - else\n\ - return sVisibilityValue;\n\ - };\n\ -\n\ - AnimatedElement.prototype.setVisibility = function( sValue )\n\ - {\n\ - if( sValue == 'visible' )\n\ - sValue = 'inherit';\n\ - this.aActiveElement.setAttribute( 'visibility', sValue );\n\ - };\n\ -\n\ - AnimatedElement.prototype.getStrokeStyle = function()\n\ - {\n\ - return 'solid';\n\ - };\n\ -\n\ - AnimatedElement.prototype.setStrokeStyle = function( sValue )\n\ - {\n\ - ANIMDBG.print( 'AnimatedElement.setStrokeStyle(' + sValue + ')' );\n\ - };\n\ -\n\ - AnimatedElement.prototype.getFillStyle = function()\n\ - {\n\ - return 'solid';\n\ - };\n\ -\n\ - AnimatedElement.prototype.setFillStyle = function( sValue )\n\ - {\n\ - ANIMDBG.print( 'AnimatedElement.setFillStyle(' + sValue + ')' );\n\ - };\n\ -\n\ - AnimatedElement.prototype.getFillColor = function()\n\ - {\n\ - var aChildSet = getElementChildren( this.aActiveElement );\n\ - var sFillColorValue = '';\n\ - for( var i = 0; i < aChildSet.length; ++i )\n\ - {\n\ - sFillColorValue = aChildSet[i].getAttribute( 'fill' );\n\ - if( sFillColorValue && ( sFillColorValue !== 'none' ) )\n\ - break;\n\ - }\n\ -\n\ - return colorParser( sFillColorValue );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setFillColor = function( aRGBValue )\n\ - {\n\ - assert( aRGBValue instanceof RGBColor,\n\ - 'AnimatedElement.setFillColor: value argument is not an instance of RGBColor' );\n\ -\n\ - var sValue = aRGBValue.toString( true /* clamped values */ );\n\ - var aChildSet = getElementChildren( this.aActiveElement );\n\ -\n\ - var sFillColorValue = '';\n\ - for( var i = 0; i < aChildSet.length; ++i )\n\ - {\n\ - sFillColorValue = aChildSet[i].getAttribute( 'fill' );\n\ - if( sFillColorValue && ( sFillColorValue !== 'none' ) )\n\ - {\n\ - aChildSet[i].setAttribute( 'fill', sValue );\n\ - }\n\ - }\n\ - };\n\ -\n\ - AnimatedElement.prototype.getStrokeColor = function()\n\ - {\n\ - var aChildSet = getElementChildren( this.aActiveElement );\n\ - var sStrokeColorValue = '';\n\ - for( var i = 0; i < aChildSet.length; ++i )\n\ - {\n\ - sStrokeColorValue = aChildSet[i].getAttribute( 'stroke' );\n\ - if( sStrokeColorValue && ( sStrokeColorValue !== 'none' ) )\n\ - break;\n\ - }\n\ -\n\ - return colorParser( sStrokeColorValue );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setStrokeColor = function( aRGBValue )\n\ - {\n\ - assert( aRGBValue instanceof RGBColor,\n\ - 'AnimatedElement.setFillColor: value argument is not an instance of RGBColor' );\n\ -\n\ - var sValue = aRGBValue.toString( true /* clamped values */ );\n\ - var aChildSet = getElementChildren( this.aActiveElement );\n\ -\n\ - var sStrokeColorValue = '';\n\ - for( var i = 0; i < aChildSet.length; ++i )\n\ - {\n\ - sStrokeColorValue = aChildSet[i].getAttribute( 'stroke' );\n\ - if( sStrokeColorValue && ( sStrokeColorValue !== 'none' ) )\n\ - {\n\ - aChildSet[i].setAttribute( 'stroke', sValue );\n\ - }\n\ - }\n\ - };\n\ -\n\ - AnimatedElement.prototype.getFontColor = function()\n\ - {\n\ - return new RGBColor( 0, 0, 0 );\n\ - };\n\ -\n\ - AnimatedElement.prototype.setFontColor = function( sValue )\n\ - {\n\ - ANIMDBG.print( 'AnimatedElement.setFontColor(' + sValue + ')' );\n\ - };\n\ -\n\ - AnimatedElement.prototype.DBG = function( sMessage, nTime )\n\ - {\n\ - aAnimatedElementDebugPrinter.print( 'AnimatedElement(' + this.getId() + ')' + sMessage, nTime );\n\ - };\n\ -\n\ -\n\ - function SlideAnimations( aSlideShowContext )\n\ - {\n\ - this.aContext = new NodeContext( aSlideShowContext );\n\ - this.aAnimationNodeMap = new Object();\n\ - this.aAnimatedElementMap = new Object();\n\ - this.aSourceEventElementMap = new Object();\n\ - this.aNextEffectEventArray = new NextEffectEventArray();\n\ - this.aEventMultiplexer = new EventMultiplexer( aSlideShowContext.aTimerEventQueue );\n\ - this.aRootNode = null;\n\ - this.bElementsParsed = false;\n\ -\n\ - this.aContext.aAnimationNodeMap = this.aAnimationNodeMap;\n\ - this.aContext.aAnimatedElementMap = this.aAnimatedElementMap;\n\ - this.aContext.aSourceEventElementMap = this.aSourceEventElementMap;\n\ - }\n\ -\n\ -\n\ - SlideAnimations.prototype.importAnimations = function( aAnimationRootElement )\n\ - {\n\ - if( !aAnimationRootElement )\n\ - return false;\n\ -\n\ - this.aRootNode = createAnimationTree( aAnimationRootElement, this.aContext );\n\ -\n\ - return ( this.aRootNode ? true : false );\n\ - };\n\ -\n\ - SlideAnimations.prototype.parseElements = function()\n\ - {\n\ - if( !this.aRootNode )\n\ - return false;\n\ -\n\ - if( !this.aRootNode.parseElement() )\n\ - return false;\n\ - else\n\ - this.bElementsParsed = true;\n\ - };\n\ -\n\ - SlideAnimations.prototype.elementsParsed = function()\n\ - {\n\ - return this.bElementsParsed;\n\ - };\n\ -\n\ - SlideAnimations.prototype.isFirstRun = function()\n\ - {\n\ - return this.aContext.bFirstRun;\n\ - };\n\ -\n\ - SlideAnimations.prototype.isAnimated = function()\n\ - {\n\ - if( !this.bElementsParsed )\n\ - return false;\n\ -\n\ - return this.aRootNode.hasPendingAnimation();\n\ - };\n\ -\n\ - SlideAnimations.prototype.start = function()\n\ - {\n\ - if( !this.bElementsParsed )\n\ - return false;\n\ -\n\ - aSlideShow.setSlideEvents( this.aNextEffectEventArray, this.aEventMultiplexer );\n\ -\n\ - if( this.aContext.bFirstRun == undefined )\n\ - this.aContext.bFirstRun = true;\n\ - else if( this.aContext.bFirstRun )\n\ - this.aContext.bFirstRun = false;\n\ -\n\ - if( !this.aRootNode.init() )\n\ - return false;\n\ -\n\ - if( !this.aRootNode.resolve() )\n\ - return false;\n\ -\n\ - return true;\n\ - };\n\ -\n\ - SlideAnimations.prototype.end = function( bLeftEffectsSkipped )\n\ - {\n\ - if( !this.bElementsParsed )\n\ - return; // no animations there\n\ -\n\ -"; - -static const char aSVGScript26[] = -"\ - this.aRootNode.deactivate();\n\ - this.aRootNode.end();\n\ -\n\ - if( bLeftEffectsSkipped && this.isFirstRun() )\n\ - {\n\ - this.aContext.bFirstRun = undefined;\n\ - }\n\ - else if( this.isFirstRun() )\n\ - {\n\ - this.aContext.bFirstRun = false;\n\ - }\n\ -\n\ - };\n\ -\n\ - SlideAnimations.prototype.dispose = function()\n\ - {\n\ - if( this.aRootNode )\n\ - {\n\ - this.aRootNode.dispose();\n\ - }\n\ - };\n\ -\n\ - SlideAnimations.prototype.clearNextEffectEvents = function()\n\ - {\n\ - ANIMDBG.print( 'SlideAnimations.clearNextEffectEvents: current slide: ' + nCurSlide );\n\ - this.aNextEffectEventArray.clear();\n\ - this.aContext.bFirstRun = undefined;\n\ - };\n\ -\n\ -\n\ - function Event()\n\ - {\n\ - this.nId = Event.getUniqueId();\n\ - }\n\ -\n\ -\n\ - Event.CURR_UNIQUE_ID = 0;\n\ -\n\ - Event.getUniqueId = function()\n\ - {\n\ - ++Event.CURR_UNIQUE_ID;\n\ - return Event.CURR_UNIQUE_ID;\n\ - };\n\ -\n\ - Event.prototype.getId = function()\n\ - {\n\ - return this.nId;\n\ - };\n\ -\n\ -\n\ - function DelayEvent( aFunctor, nTimeout )\n\ - {\n\ - DelayEvent.superclass.constructor.call( this );\n\ -\n\ - this.aFunctor = aFunctor;\n\ - this.nTimeout = nTimeout;\n\ - this.bWasFired = false;\n\ - }\n\ - extend( DelayEvent, Event );\n\ -\n\ -\n\ - DelayEvent.prototype.fire = function()\n\ - {\n\ - assert( this.isCharged(), 'DelayEvent.fire: assertion isCharged failed' );\n\ -\n\ - this.bWasFired = true;\n\ - this.aFunctor();\n\ - return true;\n\ - };\n\ -\n\ - DelayEvent.prototype.isCharged = function()\n\ - {\n\ - return !this.bWasFired;\n\ - };\n\ -\n\ - DelayEvent.prototype.getActivationTime = function( nCurrentTime )\n\ - {\n\ - return ( this.nTimeout + nCurrentTime );\n\ - };\n\ -\n\ - DelayEvent.prototype.dispose = function()\n\ - {\n\ - if( this.isCharged() )\n\ - this.bWasFired = true;\n\ - };\n\ -\n\ - DelayEvent.prototype.charge = function()\n\ - {\n\ - if( !this.isCharged() )\n\ - this.bWasFired = false;\n\ - };\n\ -\n\ -\n\ - function makeEvent( aFunctor )\n\ - {\n\ - return new DelayEvent( aFunctor, 0.0 );\n\ - }\n\ -\n\ -\n\ - function makeDelay( aFunctor, nTimeout )\n\ - {\n\ - return new DelayEvent( aFunctor, nTimeout );\n\ - }\n\ -\n\ -\n\ - function registerEvent( aTiming, aEvent, aNodeContext )\n\ - {\n\ - var aSlideShowContext = aNodeContext.aContext;\n\ - var eTimingType = aTiming.getType();\n\ -\n\ - registerEvent.DBG( aTiming );\n\ -\n\ - if( eTimingType == OFFSET_TIMING )\n\ - {\n\ - aSlideShowContext.aTimerEventQueue.addEvent( aEvent );\n\ - }\n\ - else if ( aNodeContext.bFirstRun )\n\ - {\n\ - var aEventMultiplexer = aSlideShowContext.aEventMultiplexer;\n\ - if( !aEventMultiplexer )\n\ - {\n\ - log( 'registerEvent: event multiplexer not initialized' );\n\ - return;\n\ - }\n\ - var aNextEffectEventArray = aSlideShowContext.aNextEffectEventArray;\n\ - if( !aNextEffectEventArray )\n\ - {\n\ - log( 'registerEvent: next effect event array not initialized' );\n\ - return;\n\ - }\n\ - switch( eTimingType )\n\ - {\n\ - case EVENT_TIMING:\n\ - var eEventType = aTiming.getEventType();\n\ - var sEventBaseElemId = aTiming.getEventBaseElementId();\n\ - if( sEventBaseElemId )\n\ - {\n\ - var aEventBaseElem = document.getElementById( sEventBaseElemId );\n\ - if( !aEventBaseElem )\n\ - {\n\ - log( 'generateEvent: EVENT_TIMING: event base element not found: ' + sEventBaseElemId );\n\ - return;\n\ - }\n\ - var aSourceEventElement = aNodeContext.makeSourceEventElement( sEventBaseElemId, aEventBaseElem );\n\ -\n\ - var bEventRegistered = false;\n\ - switch( eEventType )\n\ - {\n\ - case EVENT_TRIGGER_ON_CLICK:\n\ - aEventMultiplexer.registerEvent( eEventType, aSourceEventElement.getId(), aEvent );\n\ - bEventRegistered = true;\n\ - break;\n\ - default:\n\ - log( 'generateEvent: not handled event type: ' + eEventType );\n\ - }\n\ - if( bEventRegistered )\n\ - aSourceEventElement.addEventListener( eEventType );\n\ - }\n\ - else // no base event element present\n\ - {\n\ - switch( eEventType )\n\ - {\n\ - case EVENT_TRIGGER_ON_NEXT_EFFECT:\n\ - aNextEffectEventArray.appendEvent( aEvent );\n\ - break;\n\ - default:\n\ - log( 'generateEvent: not handled event type: ' + eEventType );\n\ - }\n\ - }\n\ - break;\n\ - case SYNCBASE_TIMING:\n\ - var eEventType = aTiming.getEventType();\n\ - var sEventBaseElemId = aTiming.getEventBaseElementId();\n\ - if( sEventBaseElemId )\n\ - {\n\ - var aAnimationNode = aNodeContext.aAnimationNodeMap[ sEventBaseElemId ];\n\ - if( !aAnimationNode )\n\ - {\n\ - log( 'generateEvent: SYNCBASE_TIMING: event base element not found: ' + sEventBaseElemId );\n\ - return;\n\ - }\n\ - aEventMultiplexer.registerEvent( eEventType, aAnimationNode.getId(), aEvent );\n\ - }\n\ - else\n\ - {\n\ - log( 'generateEvent: SYNCBASE_TIMING: event base element not specified' );\n\ - }\n\ - break;\n\ - default:\n\ - log( 'generateEvent: not handled timing type: ' + eTimingType );\n\ - }\n\ - }\n\ - }\n\ -\n\ - registerEvent.DEBUG = aRegisterEventDebugPrinter.isEnabled();\n\ -\n\ - registerEvent.DBG = function( aTiming, nTime )\n\ - {\n\ - if( registerEvent.DEBUG )\n\ - {\n\ -"; - -static const char aSVGScript27[] = -"\ - aRegisterEventDebugPrinter.print( 'registerEvent( timing: ' + aTiming.info() + ' )', nTime );\n\ - }\n\ - };\n\ -\n\ -\n\ - function SourceEventElement( aElement, aEventMulyiplexer )\n\ - {\n\ - this.nId = getUniqueId();\n\ - this.aElement = aElement;\n\ - this.aEventMulyiplexer = aEventMulyiplexer;\n\ - this.aEventListenerStateArray = new Array();\n\ - }\n\ -\n\ -\n\ - SourceEventElement.prototype.getId = function()\n\ - {\n\ - return this.nId;\n\ - };\n\ -\n\ - SourceEventElement.prototype.isEqualTo = function( aSourceEventElement )\n\ - {\n\ - return ( this.getId() == aSourceEventElement.getId() );\n\ - };\n\ -\n\ - SourceEventElement.prototype.onClick = function()\n\ - {\n\ - aEventMulyiplexer.notifyClickEvent( this );\n\ - };\n\ -\n\ - SourceEventElement.prototype.isEventListenerRegistered = function( eEventType )\n\ - {\n\ - return this.aEventListenerStateArray[ eEventType ];\n\ - };\n\ -\n\ - SourceEventElement.prototype.addEventListener = function( eEventType )\n\ - {\n\ - if( !this.aElement )\n\ - return false;\n\ -\n\ - this.aEventListenerStateArray[ eEventType ] = true;\n\ - switch( eEventType )\n\ - {\n\ - case EVENT_TRIGGER_ON_CLICK:\n\ - this.aElement.addEventListener( 'click', this.onClick, false );\n\ - break;\n\ - default:\n\ - log( 'SourceEventElement.addEventListener: not handled event type: ' + eEventType );\n\ - return false;\n\ - }\n\ - return true;\n\ - };\n\ -\n\ - SourceEventElement.prototype.removeEventListener = function( eEventType )\n\ - {\n\ - if( !this.aElement )\n\ - return false;\n\ -\n\ - this.aEventListenerStateArray[ eEventType ] = false;\n\ - switch( eEventType )\n\ - {\n\ - case EVENT_TRIGGER_ON_CLICK:\n\ - this.aElement.removeEventListener( 'click', this.onClick, false );\n\ - break;\n\ - default:\n\ - log( 'SourceEventElement.removeEventListener: not handled event type: ' + eEventType );\n\ - return false;\n\ - }\n\ - return true;\n\ - };\n\ -\n\ -\n\ - function EventMultiplexer( aTimerEventQueue )\n\ - {\n\ - this.aTimerEventQueue = aTimerEventQueue;\n\ - this.aEventMap = new Object();\n\ -\n\ - }\n\ -\n\ -\n\ - EventMultiplexer.prototype.registerEvent = function( eEventType, aNotifierId, aEvent )\n\ - {\n\ - this.DBG( 'registerEvent', eEventType, aNotifierId );\n\ - if( !this.aEventMap[ eEventType ] )\n\ - {\n\ - this.aEventMap[ eEventType ] = new Object();\n\ - }\n\ - if( !this.aEventMap[ eEventType ][ aNotifierId ] )\n\ - {\n\ - this.aEventMap[ eEventType ][ aNotifierId ] = new Array();\n\ - }\n\ - this.aEventMap[ eEventType ][ aNotifierId ].push( aEvent );\n\ - };\n\ -\n\ -\n\ - EventMultiplexer.prototype.notifyEvent = function( eEventType, aNotifierId )\n\ - {\n\ - this.DBG( 'notifyEvent', eEventType, aNotifierId );\n\ - if( this.aEventMap[ eEventType ] )\n\ - {\n\ - if( this.aEventMap[ eEventType ][ aNotifierId ] )\n\ - {\n\ - var aEventArray = this.aEventMap[ eEventType ][ aNotifierId ];\n\ - var nSize = aEventArray.length;\n\ - for( var i = 0; i < nSize; ++i )\n\ - {\n\ - this.aTimerEventQueue.addEvent( aEventArray[i] );\n\ - }\n\ - }\n\ - }\n\ - };\n\ -\n\ - EventMultiplexer.DEBUG = aEventMultiplexerDebugPrinter.isEnabled();\n\ -\n\ - EventMultiplexer.prototype.DBG = function( sMethodName, eEventType, aNotifierId, nTime )\n\ - {\n\ - if( EventMultiplexer.DEBUG )\n\ - {\n\ - var sInfo = 'EventMultiplexer.' + sMethodName;\n\ - sInfo += '( type: ' + aEventTriggerOutMap[ eEventType ];\n\ - sInfo += ', notifier: ' + aNotifierId + ' )';\n\ - aEventMultiplexerDebugPrinter.print( sInfo, nTime );\n\ - }\n\ - };\n\ -\n\ -\n\ - var aInterpolatorHandler = new Object();\n\ -\n\ - aInterpolatorHandler.getInterpolator = function( eCalcMode, eValueType, eValueSubtype )\n\ - {\n\ - var bHasSubtype = ( typeof( eValueSubtype ) === typeof( 0 ) );\n\ -\n\ - if( !bHasSubtype && aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ] )\n\ - {\n\ - return aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ];\n\ - }\n\ - else if( bHasSubtype && aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ][ eValueSubtype ] )\n\ - {\n\ - return aInterpolatorHandler.aLerpFunctorMap[ eCalcMode ][ eValueType ][ eValueSubtype ];\n\ - }\n\ - else\n\ - {\n\ - log( 'aInterpolatorHandler.getInterpolator: not found any valid interpolator for clalc mode '\n\ - + aCalcModeOutMap[eCalcMode] + 'and value type ' + aValueTypeOutMap[eValueType] );\n\ - return null;\n\ - }\n\ - };\n\ -\n\ - aInterpolatorHandler.aLerpFunctorMap = new Array();\n\ - aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_DISCRETE ] = new Array();\n\ - aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ] = new Array();\n\ -\n\ -\n\ - aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ NUMBER_PROPERTY ] =\n\ - function ( nFrom, nTo, nT )\n\ - {\n\ - return ( ( 1.0 - nT )* nFrom + nT * nTo );\n\ - };\n\ -\n\ - aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ COLOR_PROPERTY ] = new Array();\n\ -\n\ - aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ COLOR_PROPERTY ][ COLOR_SPACE_RGB ] =\n\ - function ( nFrom, nTo, nT )\n\ - {\n\ - return RGBColor.interpolate( nFrom, nTo, nT );\n\ - };\n\ -\n\ - aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ COLOR_PROPERTY ][ COLOR_SPACE_HSL ] =\n\ - function ( bCCW )\n\ - {\n\ - return function ( nFrom, nTo, nT )\n\ - {\n\ - return HSLColor.interpolate( nFrom, nTo, nT, bCCW );\n\ - };\n\ - };\n\ -\n\ -\n\ - function KeyStopLerp( aValueList )\n\ - {\n\ - KeyStopLerp.validateInput( aValueList );\n\ -\n\ - this.aKeyStopList = new Array();\n\ - this.nLastIndex = 0;\n\ - this.nKeyStopDistance = aValueList[1] - aValueList[0];\n\ - if( this.nKeyStopDistance <= 0 )\n\ - this.nKeyStopDistance = 0.001;\n\ -\n\ - for( var i = 0; i < aValueList.length; ++i )\n\ - this.aKeyStopList.push( aValueList[i] );\n\ -\n\ - this.nUpperBoundIndex = this.aKeyStopList.length - 2;\n\ - }\n\ -\n\ -\n\ - KeyStopLerp.validateInput = function( aValueList )\n\ - {\n\ - var nSize = aValueList.length;\n\ - assert( nSize > 1, 'KeyStopLerp.validateInput: key stop vector must have two entries or more' );\n\ -\n\ - for( var i = 1; i < nSize; ++i )\n\ - {\n\ -"; - -static const char aSVGScript28[] = -"\ - if( aValueList[i-1] > aValueList[i] )\n\ - log( 'KeyStopLerp.validateInput: time vector is not sorted in ascending order!' );\n\ - }\n\ - };\n\ -\n\ - KeyStopLerp.prototype.reset = function()\n\ - {\n\ - KeyStopLerp.validateInput( this.aKeyStopList );\n\ - this.nLastIndex = 0;\n\ - this.nKeyStopDistance = this.aKeyStopList[1] - this.aKeyStopList[0];\n\ - if( this.nKeyStopDistance <= 0 )\n\ - this.nKeyStopDistance = 0.001;\n\ -\n\ - };\n\ -\n\ - KeyStopLerp.prototype.lerp = function( nAlpha )\n\ - {\n\ - if( nAlpha > this.aKeyStopList[ this.nLastIndex + 1 ] )\n\ - {\n\ - do\n\ - {\n\ - var nIndex = this.nLastIndex + 1;\n\ - this.nLastIndex = clamp( nIndex, 0, this.nUpperBoundIndex );\n\ - this.nKeyStopDistance = this.aKeyStopList[ this.nLastIndex + 1 ] - this.aKeyStopList[ this.nLastIndex ];\n\ - }\n\ - while( ( this.nKeyStopDistance <= 0 ) && ( this.nLastIndex < this.nUpperBoundIndex ) );\n\ - }\n\ -\n\ - var nRawLerp = ( nAlpha - this.aKeyStopList[ this.nLastIndex ] ) / this.nKeyStopDistance;\n\ -\n\ - nRawLerp = clamp( nRawLerp, 0.0, 1.0 );\n\ -\n\ - var aResult = new Object();\n\ - aResult.nIndex = this.nLastIndex;\n\ - aResult.nLerp = nRawLerp;\n\ -\n\ - return aResult;\n\ - };\n\ -\n\ - KeyStopLerp.prototype.lerp_ported = function( nAlpha )\n\ - {\n\ - if( ( this.aKeyStopList[ this.nLastIndex ] < nAlpha ) ||\n\ - ( this.aKeyStopList[ this.nLastIndex + 1 ] >= nAlpha ) )\n\ - {\n\ - var i = 0;\n\ - for( ; i < this.aKeyStopList.length; ++i )\n\ - {\n\ - if( this.aKeyStopList[i] >= nAlpha )\n\ - break;\n\ - }\n\ - if( this.aKeyStopList[i] > nAlpha )\n\ - --i;\n\ - var nIndex = i - 1;\n\ - this.nLastIndex = clamp( nIndex, 0, this.aKeyStopList.length - 2 );\n\ - }\n\ -\n\ - var nRawLerp = ( nAlpha - this.aKeyStopList[ this.nLastIndex ] ) /\n\ - ( this.aKeyStopList[ this.nLastIndex+1 ] - this.aKeyStopList[ this.nLastIndex ] );\n\ -\n\ - nRawLerp = clamp( nRawLerp, 0.0, 1.0 );\n\ -\n\ - var aResult = new Object();\n\ - aResult.nIndex = this.nLastIndex;\n\ - aResult.nLerp = nRawLerp;\n\ -\n\ - return aResult;\n\ - };\n\ -\n\ -\n\ - var aOperatorSetMap = new Array();\n\ -\n\ - aOperatorSetMap[ NUMBER_PROPERTY ] = new Object();\n\ -\n\ - aOperatorSetMap[ NUMBER_PROPERTY ].add = function( a, b )\n\ - {\n\ - return ( a + b );\n\ - };\n\ -\n\ - aOperatorSetMap[ NUMBER_PROPERTY ].scale = function( k, v )\n\ - {\n\ - return ( k * v );\n\ - };\n\ -\n\ - aOperatorSetMap[ COLOR_PROPERTY ] = new Object();\n\ -\n\ - aOperatorSetMap[ COLOR_PROPERTY ].add = function( a, b )\n\ - {\n\ - var c = a.clone();\n\ - c.add( b );\n\ - return c;\n\ - };\n\ -\n\ - aOperatorSetMap[ COLOR_PROPERTY ].scale = function( k, v )\n\ - {\n\ - var r = v.clone();\n\ - r.scale( k );\n\ - return r;\n\ - };\n\ -\n\ -\n\ - function ActivityParamSet()\n\ - {\n\ - this.aEndEvent = null;\n\ - this.aTimerEventQueue = null;\n\ - this.aActivityQueue = null;\n\ - this.nRepeatCount = 1.0;\n\ - this.nAccelerationFraction = 0.0;\n\ - this.nDecelerationFraction = 0.0;\n\ - this.bAutoReverse = false;\n\ - this.nMinDuration = undefined;\n\ - this.nMinNumberOfFrames = MINIMUM_FRAMES_PER_SECONDS;\n\ - this.aDiscreteTimes = new Array();\n\ - }\n\ -\n\ - function AnimationActivity()\n\ - {\n\ - this.nId = AnimationActivity.getUniqueId();\n\ - }\n\ -\n\ -\n\ - AnimationActivity.CURR_UNIQUE_ID = 0;\n\ -\n\ - AnimationActivity.getUniqueId = function()\n\ - {\n\ - ++AnimationActivity.CURR_UNIQUE_ID;\n\ - return AnimationActivity.CURR_UNIQUE_ID;\n\ - };\n\ -\n\ - AnimationActivity.prototype.getId = function()\n\ - {\n\ - return this.nId;\n\ - };\n\ -\n\ -\n\ - function SetActivity( aCommonParamSet, aAnimation, aToAttr )\n\ - {\n\ - SetActivity.superclass.constructor.call( this );\n\ -\n\ - this.aAnimation = aAnimation;\n\ - this.aTargetElement = null;\n\ - this.aEndEvent = aCommonParamSet.aEndEvent;\n\ - this.aTimerEventQueue = aCommonParamSet.aTimerEventQueue;\n\ - this.aToAttr = aToAttr;\n\ - this.bIsActive = true;\n\ - }\n\ - extend( SetActivity, AnimationActivity );\n\ -\n\ -\n\ - SetActivity.prototype.activate = function( aEndEvent )\n\ - {\n\ - this.aEndEvent = aEndEvent;\n\ - this.bIsActive = true;\n\ - };\n\ -\n\ - SetActivity.prototype.dispose = function()\n\ - {\n\ - this.bIsActive = false;\n\ - if( this.aEndEvent && this.aEndEvent.isCharged() )\n\ - this.aEndEvent.dispose();\n\ - };\n\ -\n\ - SetActivity.prototype.calcTimeLag = function()\n\ - {\n\ - return 0.0;\n\ - };\n\ -\n\ - SetActivity.prototype.perform = function()\n\ - {\n\ - if( !this.isActive() )\n\ - return false;\n\ -\n\ - this.bIsActive = false;\n\ -\n\ - if( this.aAnimation && this.aTargetElement )\n\ - {\n\ - this.aAnimation.start( this.aTargetElement );\n\ - this.aAnimation.perform( this.aToAttr );\n\ - this.aAnimation.end();\n\ - }\n\ -\n\ - if( this.aEndEvent )\n\ - this.aTimerEventQueue.addEvent( this.aEndEvent );\n\ -\n\ - };\n\ -\n\ - SetActivity.prototype.isActive = function()\n\ - {\n\ - return this.bIsActive;\n\ - };\n\ -\n\ - SetActivity.prototype.dequeued = function()\n\ - {\n\ - };\n\ -\n\ - SetActivity.prototype.end = function()\n\ - {\n\ - this.perform();\n\ - };\n\ -\n\ - SetActivity.prototype.setTargets = function( aTargetElement )\n\ -"; - -static const char aSVGScript29[] = -"\ - {\n\ - assert( aTargetElement, 'SetActivity.setTargets: target element is not valid' );\n\ - this.aTargetElement = aTargetElement;\n\ - };\n\ -\n\ -\n\ - function ActivityBase( aCommonParamSet )\n\ - {\n\ - ActivityBase.superclass.constructor.call( this );\n\ -\n\ - this.aTargetElement = null;\n\ - this.aEndEvent = aCommonParamSet.aEndEvent;\n\ - this.aTimerEventQueue = aCommonParamSet.aTimerEventQueue;\n\ - this.nRepeats = aCommonParamSet.nRepeatCount;\n\ - this.nAccelerationFraction = aCommonParamSet.nAccelerationFraction;\n\ - this.nDecelerationFraction = aCommonParamSet.nDecelerationFraction;\n\ - this.bAutoReverse = aCommonParamSet.bAutoReverse;\n\ -\n\ - this.bFirstPerformCall = true;\n\ - this.bIsActive = true;\n\ -\n\ - }\n\ - extend( ActivityBase, AnimationActivity );\n\ -\n\ -\n\ - ActivityBase.prototype.activate = function( aEndEvent )\n\ - {\n\ - this.aEndEvent = aEndEvent;\n\ - this.bFirstPerformCall = true;\n\ - this.bIsActive = true;\n\ - };\n\ -\n\ - ActivityBase.prototype.dispose = function()\n\ - {\n\ - this.bIsActive = false;\n\ -\n\ - if( this.aEndEvent )\n\ - this.aEndEvent.dispose();\n\ -\n\ - this.aEndEvent = null;\n\ - };\n\ -\n\ - ActivityBase.prototype.perform = function()\n\ - {\n\ - if( !this.isActive() )\n\ - return false; // no, early exit.\n\ -\n\ - assert( !this.FirstPerformCall, 'ActivityBase.perform: assertion (!this.FirstPerformCall) failed' );\n\ -\n\ - return true;\n\ - };\n\ -\n\ - ActivityBase.prototype.calcTimeLag = function()\n\ - {\n\ - if( this.isActive() && this.bFirstPerformCall )\n\ - {\n\ - this.bFirstPerformCall = false;\n\ -\n\ - this.startAnimation();\n\ - }\n\ - return 0.0;\n\ - };\n\ -\n\ - ActivityBase.prototype.isActive = function()\n\ - {\n\ - return this.bIsActive;\n\ - };\n\ -\n\ - ActivityBase.prototype.isDisposed = function()\n\ - {\n\ - return ( !this.bIsActive && !this.aEndEvent );\n\ - };\n\ -\n\ - ActivityBase.prototype.dequeued = function()\n\ - {\n\ - if( !this.isActive() )\n\ - this.endAnimation();\n\ - };\n\ -\n\ - ActivityBase.prototype.setTargets = function( aTargetElement )\n\ - {\n\ - assert( aTargetElement, 'ActivityBase.setTargets: target element is not valid' );\n\ -\n\ - this.aTargetElement = aTargetElement;\n\ - };\n\ -\n\ - ActivityBase.prototype.startAnimation = function()\n\ - {\n\ - throw ( 'ActivityBase.startAnimation: abstract method invoked' );\n\ - };\n\ -\n\ - ActivityBase.prototype.endAnimation = function()\n\ - {\n\ - throw ( 'ActivityBase.endAnimation: abstract method invoked' );\n\ - };\n\ -\n\ - ActivityBase.prototype.endActivity = function()\n\ - {\n\ - this.bIsActive = false;\n\ -\n\ - if( this.aEndEvent )\n\ - this.aTimerEventQueue.addEvent( this.aEndEvent );\n\ -\n\ - this.aEndEvent = null;\n\ -\n\ - };\n\ -\n\ - ActivityBase.prototype.calcAcceleratedTime = function( nT )\n\ - {\n\ -\n\ -\n\ - nT = clamp( nT, 0.0, 1.0 );\n\ -\n\ - if( ( this.nAccelerationFraction > 0.0 || this.nDecelerationFraction > 0.0 ) &&\n\ - ( this.nAccelerationFraction + this.nDecelerationFraction <= 1.0 ) )\n\ - {\n\ - var nC = 1.0 - 0.5*this.nAccelerationFraction - 0.5*this.nDecelerationFraction;\n\ -\n\ - var nTPrime = 0.0;\n\ -\n\ - if( nT < this.nAccelerationFraction )\n\ - {\n\ - nTPrime += 0.5 * nT * nT / this.nAccelerationFraction; // partial first interval\n\ - }\n\ - else\n\ - {\n\ - nTPrime += 0.5 * this.nAccelerationFraction; // full first interval\n\ -\n\ - if( nT <= ( 1.0 - this.nDecelerationFraction ) )\n\ - {\n\ - nTPrime += nT - this.nAccelerationFraction; // partial second interval\n\ - }\n\ - else\n\ - {\n\ - nTPrime += 1.0 - this.nAccelerationFraction - this.nDecelerationFraction; // full second interval\n\ -\n\ - var nTRelative = nT - 1.0 + this.nDecelerationFraction;\n\ -\n\ - nTPrime += nTRelative - 0.5*nTRelative*nTRelative / this.nDecelerationFraction;\n\ - }\n\ - }\n\ -\n\ - nT = nTPrime / nC;\n\ -\n\ - }\n\ - return nT;\n\ - };\n\ -\n\ - ActivityBase.prototype.getEventQueue = function()\n\ - {\n\ - return this.aTimerEventQueue;\n\ - };\n\ -\n\ - ActivityBase.prototype.getTargetElement = function()\n\ - {\n\ - return this.aTargetElement;\n\ - };\n\ -\n\ - ActivityBase.prototype.isRepeatCountValid = function()\n\ - {\n\ - if( this.nRepeats )\n\ - return true;\n\ - else\n\ - return false;\n\ - };\n\ -\n\ - ActivityBase.prototype.getRepeatCount = function()\n\ - {\n\ - return this.nRepeats;\n\ - };\n\ -\n\ - ActivityBase.prototype.isAutoReverse = function()\n\ - {\n\ - return this.bAutoReverse;\n\ - };\n\ -\n\ - ActivityBase.prototype.end = function()\n\ - {\n\ - if( !this.isActive() || this.isDisposed() )\n\ - return;\n\ -\n\ - if( this.bFirstPerformCall )\n\ - {\n\ - this.bFirstPerformCall = false;\n\ - this.startAnimation();\n\ - }\n\ -\n\ - this.performEnd();\n\ - this.endAnimation();\n\ - this.endActivity();\n\ - };\n\ -\n\ - ActivityBase.prototype.performEnd = function()\n\ - {\n\ - throw ( 'ActivityBase.performEnd: abstract method invoked' );\n\ - };\n\ -\n\ -\n\ - function SimpleContinuousActivityBase( aCommonParamSet )\n\ - {\n\ -"; - -static const char aSVGScript30[] = -"\ - SimpleContinuousActivityBase.superclass.constructor.call( this, aCommonParamSet );\n\ -\n\ - this.aTimer = new ElapsedTime( aCommonParamSet.aActivityQueue.getTimer() );\n\ - this.nMinSimpleDuration = aCommonParamSet.nMinDuration;\n\ - this.nMinNumberOfFrames = aCommonParamSet.nMinNumberOfFrames;\n\ - this.nCurrPerformCalls = 0;\n\ -\n\ - }\n\ - extend( SimpleContinuousActivityBase, ActivityBase );\n\ -\n\ -\n\ - SimpleContinuousActivityBase.prototype.startAnimation = function()\n\ - {\n\ - this.aTimer.reset();\n\ -\n\ - };\n\ -\n\ - SimpleContinuousActivityBase.prototype.calcTimeLag = function()\n\ - {\n\ - SimpleContinuousActivityBase.superclass.calcTimeLag.call( this );\n\ -\n\ - if( !this.isActive() )\n\ - return 0.0;\n\ -\n\ - var nCurrElapsedTime = this.aTimer.getElapsedTime();\n\ -\n\ -\n\ - var nFractionElapsedTime = nCurrElapsedTime / this.nMinSimpleDuration;\n\ -\n\ - var nFractionRequiredCalls = this.nCurrPerformCalls / this.nMinNumberOfFrames;\n\ -\n\ -\n\ - if( nFractionElapsedTime < nFractionRequiredCalls )\n\ - {\n\ - return 0.0;\n\ - }\n\ - else\n\ - {\n\ - return ( ( nFractionElapsedTime - nFractionRequiredCalls ) * this.nMinSimpleDuration );\n\ - }\n\ - };\n\ -\n\ - SimpleContinuousActivityBase.prototype.perform = function()\n\ - {\n\ - if( !SimpleContinuousActivityBase.superclass.perform.call( this ) )\n\ - return false; // done, we're ended\n\ -\n\ - var nCurrElapsedTime = this.aTimer.getElapsedTime();\n\ - var nT = nCurrElapsedTime / this.nMinSimpleDuration;\n\ -\n\ -\n\ - var bActivityEnding = false;\n\ -\n\ - if( this.isRepeatCountValid() )\n\ - {\n\ -\n\ - var nRepeatCount = this.getRepeatCount();\n\ - var nEffectiveRepeat = this.isAutoReverse() ? 2.0 * nRepeatCount : nRepeatCount;\n\ -\n\ - if( nEffectiveRepeat <= nT )\n\ - {\n\ - bActivityEnding = true;\n\ -\n\ - nT = nEffectiveRepeat;\n\ - }\n\ - }\n\ -\n\ -\n\ - var nRepeats;\n\ - var nRelativeSimpleTime;\n\ - if( this.isAutoReverse() )\n\ - {\n\ - nRepeats = Math.floor( nT );\n\ - var nFractionalActiveDuration = nT - nRepeats;\n\ -\n\ - if( nRepeats % 2 )\n\ - {\n\ - nRelativeSimpleTime = 1.0 - nFractionalActiveDuration;\n\ - }\n\ - else\n\ - {\n\ - nRelativeSimpleTime = nFractionalActiveDuration;\n\ - }\n\ -\n\ - nRepeats /= 2;\n\ - }\n\ - else\n\ - {\n\ -\n\ - nRepeats = Math.floor( nT );\n\ - nRelativeSimpleTime = nT - nRepeats;\n\ -\n\ - if( this.isRepeatCountValid() && ( nRepeats >= this.getRepeatCount() ) )\n\ - {\n\ -\n\ - nRelativeSimpleTime = 1.0;\n\ - nRepeats -= 1.0;\n\ - }\n\ - }\n\ -\n\ -\n\ - this.simplePerform( nRelativeSimpleTime, nRepeats );\n\ -\n\ - if( bActivityEnding )\n\ - this.endActivity();\n\ -\n\ - ++this.nCurrPerformCalls;\n\ -\n\ - return this.isActive();\n\ - };\n\ -\n\ - SimpleContinuousActivityBase.prototype.simplePerform = function( nSimpleTime, nRepeatCount )\n\ - {\n\ - throw ( 'SimpleContinuousActivityBase.simplePerform: abstract method invoked' );\n\ - };\n\ -\n\ -\n\ - function ContinuousKeyTimeActivityBase( aCommonParamSet )\n\ - {\n\ - var nSize = aCommonParamSet.aDiscreteTimes.length;\n\ - assert( nSize > 1,\n\ - 'ContinuousKeyTimeActivityBase constructor: assertion (aDiscreteTimes.length > 1) failed' );\n\ -\n\ - assert( aCommonParamSet.aDiscreteTimes[0] == 0.0,\n\ - 'ContinuousKeyTimeActivityBase constructor: assertion (aDiscreteTimes.front() == 0.0) failed' );\n\ -\n\ - assert( aCommonParamSet.aDiscreteTimes[ nSize - 1 ] <= 1.0,\n\ - 'ContinuousKeyTimeActivityBase constructor: assertion (aDiscreteTimes.back() <= 1.0) failed' );\n\ -\n\ - ContinuousKeyTimeActivityBase.superclass.constructor.call( this, aCommonParamSet );\n\ -\n\ - this.aLerper = new KeyStopLerp( aCommonParamSet.aDiscreteTimes );\n\ - }\n\ - extend( ContinuousKeyTimeActivityBase, SimpleContinuousActivityBase );\n\ -\n\ -\n\ - ContinuousKeyTimeActivityBase.prototype.activate = function( aEndElement )\n\ - {\n\ - ContinuousKeyTimeActivityBase.superclass.activate.call( this, aEndElement );\n\ -\n\ - this.aLerper.reset();\n\ - };\n\ -\n\ - ContinuousKeyTimeActivityBase.prototype.performHook = function( nIndex, nFractionalIndex, nRepeatCount )\n\ - {\n\ - throw ( 'ContinuousKeyTimeActivityBase.performHook: abstract method invoked' );\n\ - };\n\ -\n\ - ContinuousKeyTimeActivityBase.prototype.simplePerform = function( nSimpleTime, nRepeatCount )\n\ - {\n\ - var nAlpha = this.calcAcceleratedTime( nSimpleTime );\n\ -\n\ - var aLerpResult = this.aLerper.lerp( nAlpha );\n\ -\n\ - this.performHook( aLerpResult.nIndex, aLerpResult.nLerp, nRepeatCount );\n\ - };\n\ -\n\ -\n\ - function ContinuousActivityBase( aCommonParamSet )\n\ - {\n\ - ContinuousActivityBase.superclass.constructor.call( this, aCommonParamSet );\n\ -\n\ - }\n\ - extend( ContinuousActivityBase, SimpleContinuousActivityBase );\n\ -\n\ -\n\ - ContinuousActivityBase.prototype.performHook = function( nModifiedTime, nRepeatCount )\n\ - {\n\ - throw ( 'ContinuousActivityBase.performHook: abstract method invoked' );\n\ - };\n\ -\n\ - ContinuousActivityBase.prototype.simplePerform = function( nSimpleTime, nRepeatCount )\n\ - {\n\ - this.performHook( this.calcAcceleratedTime( nSimpleTime ), nRepeatCount );\n\ - };\n\ -\n\ -\n\ - function SimpleActivity( aCommonParamSet, aNumberAnimation, eDirection )\n\ - {\n\ - assert( ( eDirection == BACKWARD ) || ( eDirection == FORWARD ),\n\ - 'SimpleActivity constructor: animation direction is not valid' );\n\ -\n\ - assert( aNumberAnimation, 'SimpleActivity constructor: animation object is not valid' );\n\ -\n\ - SimpleActivity.superclass.constructor.call( this, aCommonParamSet );\n\ -\n\ - this.aAnimation = aNumberAnimation;\n\ - this.nDirection = ( eDirection == FORWARD ) ? 1.0 : 0.0;\n\ - }\n\ - extend( SimpleActivity, ContinuousActivityBase );\n\ -\n\ -\n\ - SimpleActivity.prototype.startAnimation = function()\n\ - {\n\ - if( this.isDisposed() || !this.aAnimation )\n\ - return;\n\ -\n\ - ANIMDBG.print( 'SimpleActivity.startAnimation invoked' );\n\ - SimpleActivity.superclass.startAnimation.call( this );\n\ -\n\ -"; - -static const char aSVGScript31[] = -"\ - this.aAnimation.start( this.getTargetElement() );\n\ - };\n\ -\n\ - SimpleActivity.prototype.endAnimation = function()\n\ - {\n\ - if( this.aAnimation )\n\ - this.aAnimation.end();\n\ -\n\ - };\n\ -\n\ - SimpleActivity.prototype.performHook = function( nModifiedTime, nRepeatCount )\n\ - {\n\ -\n\ - if( this.isDisposed() || !this.aAnimation )\n\ - return;\n\ -\n\ - var nT = 1.0 - this.nDirection + nModifiedTime * ( 2.0*this.nDirection - 1.0 );\n\ - this.aAnimation.perform( nT );\n\ - };\n\ -\n\ - SimpleActivity.prototype.performEnd = function()\n\ - {\n\ - if( this.aAnimation )\n\ - this.aAnimation.perform( this.nDirection );\n\ - };\n\ -\n\ -\n\ - function FromToByActivityTemplate( BaseType ) // template parameter\n\ - {\n\ -\n\ - function FromToByActivity( aFromValue, aToValue, aByValue,\n\ - aActivityParamSet, aAnimation,\n\ - aInterpolator, aOperatorSet, bAccumulate )\n\ - {\n\ - assert( aAnimation, 'FromToByActivity constructor: invalid animation object' );\n\ - assert( ( aToValue != undefined ) || ( aByValue != undefined ),\n\ - 'FromToByActivity constructor: one of aToValue or aByValue must be valid' );\n\ -\n\ - FromToByActivity.superclass.constructor.call( this, aActivityParamSet );\n\ -\n\ - this.aFrom = aFromValue;\n\ - this.aTo = aToValue;\n\ - this.aBy = aByValue;\n\ - this.aStartValue;\n\ - this.aEndValue;\n\ - this.aAnimation = aAnimation;\n\ - this.aInterpolator = aInterpolator;\n\ - this.add = aOperatorSet.add;\n\ - this.scale = aOperatorSet.scale;\n\ - this.bDynamicStartValue = false;\n\ - this.bCumulative = bAccumulate;\n\ -\n\ - this.initAnimatedElement();\n\ -\n\ - }\n\ - extend( FromToByActivity, BaseType );\n\ -\n\ - FromToByActivity.prototype.initAnimatedElement = function()\n\ - {\n\ - if( this.aAnimation && this.aFrom )\n\ - this.aAnimation.perform( this.aFrom );\n\ - };\n\ -\n\ - FromToByActivity.prototype.startAnimation = function()\n\ - {\n\ - if( this.isDisposed() || !this.aAnimation )\n\ - {\n\ - log( 'FromToByActivity.startAnimation: activity disposed or not valid animation' );\n\ - return;\n\ - }\n\ -\n\ - FromToByActivity.superclass.startAnimation.call( this );\n\ -\n\ - this.aAnimation.start( this.getTargetElement() );\n\ -\n\ -\n\ - var aAnimationStartValue = this.aAnimation.getUnderlyingValue();\n\ -\n\ - if( this.aFrom )\n\ - {\n\ - if( this.aTo )\n\ - {\n\ - this.aStartValue = this.aFrom;\n\ - this.aEndValue = this.aTo;\n\ - }\n\ - else if( this.aBy )\n\ - {\n\ - this.aStartValue = this.aFrom;\n\ -\n\ - this.aEndValue = this.add( this.aStartValue, this.aBy );\n\ - }\n\ - }\n\ - else\n\ - {\n\ - if( this.aTo )\n\ - {\n\ -\n\ - this.bDynamicStartValue = true;\n\ - this.aEndValue = this.aTo;\n\ - }\n\ - else if( this.aBy )\n\ - {\n\ - this.aStartValue = aAnimationStartValue;\n\ -\n\ - this.aEndValue = this.add( this.aStartValue, this.aBy );\n\ - }\n\ - }\n\ -\n\ - ANIMDBG.print( 'FromToByActivity.startAnimation: aStartValue = ' + this.aStartValue + ', aEndValue = ' + this.aEndValue );\n\ - };\n\ -\n\ - FromToByActivity.prototype.endAnimation = function()\n\ - {\n\ - if( this.aAnimation )\n\ - this.aAnimation.end();\n\ - };\n\ -\n\ - FromToByActivity.prototype.performHook = function( nModifiedTime, nRepeatCount )\n\ - {\n\ - if( this.isDisposed() || !this.aAnimation )\n\ - {\n\ - log( 'FromToByActivity.performHook: activity disposed or not valid animation' );\n\ - return;\n\ - }\n\ -\n\ - var aValue = this.bDynamicStartValue ? this.aAnimation.getUnderlyingValue()\n\ - : this.aStartValue;\n\ -\n\ - aValue = this.aInterpolator( aValue, this.aEndValue, nModifiedTime );\n\ -\n\ - if( this.bCumulative )\n\ - {\n\ - aValue = this.add( this.scale( nRepeatCount, this.aEndValue ), aValue );\n\ - }\n\ -\n\ - this.aAnimation.perform( aValue );\n\ - };\n\ -\n\ - FromToByActivity.prototype.performEnd = function()\n\ - {\n\ - if( this.aAnimation )\n\ - {\n\ - if( this.isAutoreverse() )\n\ - this.aAnimation.perform( this.aStartValue );\n\ - else\n\ - this.aAnimation.perform( this.aEndValue );\n\ - }\n\ - };\n\ -\n\ - FromToByActivity.prototype.dispose = function()\n\ - {\n\ - FromToByActivity.superclass.dispose.call( this );\n\ - };\n\ -\n\ -\n\ - return FromToByActivity;\n\ - }\n\ -\n\ -\n\ - var LinearFromToByActivity = instantiate( FromToByActivityTemplate, ContinuousActivityBase );\n\ -\n\ -\n\ - function ValueListActivityTemplate( BaseType ) // template parameter\n\ - {\n\ -\n\ - function ValueListActivity( aValueList, aActivityParamSet,\n\ - aAnimation, aInterpolator,\n\ - aOperatorSet, bAccumulate )\n\ - {\n\ - assert( aAnimation, 'ValueListActivity constructor: invalid animation object' );\n\ - assert( aValueList.length != 0, 'ValueListActivity: value list is empty' );\n\ -\n\ - ValueListActivity.superclass.constructor.call( this, aActivityParamSet );\n\ -\n\ - this.aValueList = aValueList;\n\ - this.aAnimation = aAnimation;\n\ - this.aInterpolator = aInterpolator;\n\ - this.add = aOperatorSet.add;\n\ - this.scale = aOperatorSet.scale;\n\ - this.bCumulative = bAccumulate;\n\ - this.aLastValue = this.aValueList[ this.aValueList.length - 1 ];\n\ -\n\ - this.initAnimatedElement();\n\ - }\n\ - extend( ValueListActivity, BaseType );\n\ -\n\ - ValueListActivity.prototype.activate = function( aEndEvent )\n\ - {\n\ - ValueListActivity.superclass.activate.call( this, aEndEvent );\n\ - for( var i = 0; i < this.aValueList.length; ++i )\n\ - {\n\ - ANIMDBG.print( 'createValueListActivity: value[' + i + '] = ' + this.aValueList[i] );\n\ - }\n\ -\n\ - this.initAnimatedElement();\n\ - };\n\ -\n\ - ValueListActivity.prototype.initAnimatedElement = function()\n\ - {\n\ - if( this.aAnimation )\n\ -"; - -static const char aSVGScript32[] = -"\ - this.aAnimation.perform( this.aValueList[0] );\n\ - };\n\ -\n\ - ValueListActivity.prototype.startAnimation = function()\n\ - {\n\ - if( this.isDisposed() || !this.aAnimation )\n\ - {\n\ - log( 'ValueListActivity.startAnimation: activity disposed or not valid animation' );\n\ - return;\n\ - }\n\ -\n\ - ValueListActivity.superclass.startAnimation.call( this );\n\ -\n\ - this.aAnimation.start( this.getTargetElement() );\n\ - };\n\ -\n\ - ValueListActivity.prototype.endAnimation = function()\n\ - {\n\ - if( this.aAnimation )\n\ - this.aAnimation.end();\n\ - };\n\ -\n\ - ValueListActivity.prototype.performHook = function( nIndex, nFractionalIndex, nRepeatCount )\n\ - {\n\ - if( this.isDisposed() || !this.aAnimation )\n\ - {\n\ - log( 'ValueListActivity.performHook: activity disposed or not valid animation' );\n\ - return;\n\ - }\n\ -\n\ - assert( ( nIndex + 1 ) < this.aValueList.length,\n\ - 'ValueListActivity.performHook: assertion (nIndex + 1 < this.aValueList.length) failed' );\n\ -\n\ -\n\ - var aValue = this.aInterpolator( this.aValueList[ nIndex ],\n\ - this.aValueList[ nIndex+1 ],\n\ - nFractionalIndex );\n\ -\n\ - if( this.bCumulative )\n\ - {\n\ - aValue = this.add( aValue, this.scale( nRepeatCount, this.aLastValue ) );\n\ - }\n\ - this.aAnimation.perform( aValue );\n\ - };\n\ -\n\ - ValueListActivity.prototype.performEnd = function()\n\ - {\n\ - if( this.aAnimation )\n\ - {\n\ - this.aAnimation.perform( this.aLastValue );\n\ - }\n\ - };\n\ -\n\ - ValueListActivity.prototype.dispose = function()\n\ - {\n\ - ValueListActivity.superclass.dispose.call( this );\n\ - };\n\ -\n\ -\n\ - return ValueListActivity;\n\ - }\n\ -\n\ -\n\ - var LinearValueListActivity = instantiate( ValueListActivityTemplate, ContinuousKeyTimeActivityBase );\n\ -\n\ -\n\ - function createActivity( aActivityParamSet, aAnimationNode, aAnimation, aInterpolator )\n\ - {\n\ - var eCalcMode = aAnimationNode.getCalcMode();\n\ -\n\ - var sAttributeName = aAnimationNode.getAttributeName();\n\ - var aAttributeProp = aAttributeMap[ sAttributeName ];\n\ -\n\ - var eValueType = aAttributeProp[ 'type' ];\n\ - var eValueSubtype = aAttributeProp[ 'subtype' ];\n\ -\n\ - if( ! aInterpolator )\n\ - {\n\ - aInterpolator = aInterpolatorHandler.getInterpolator( eCalcMode,\n\ - eValueType,\n\ - eValueSubtype );\n\ - }\n\ -\n\ - var bAccumulate = ( aAnimationNode.getAccumulate() === ACCUMULATE_MODE_SUM )\n\ - && !( eValueType === BOOL_PROPERTY ||\n\ - eValueType === STRING_PROPERTY ||\n\ - eValueType === ENUM_PROPERTY );\n\ -\n\ -\n\ - aActivityParamSet.aDiscreteTimes = aAnimationNode.getKeyTimes();\n\ -\n\ - var aValueSet = aAnimationNode.getValues();\n\ - var nValueSetSize = aValueSet.length;\n\ -\n\ - if( nValueSetSize != 0 )\n\ - {\n\ -\n\ - if( aActivityParamSet.aDiscreteTimes.length == 0 )\n\ - {\n\ - for( var i = 0; i < nValueSetSize; ++i )\n\ - aActivityParamSet.aDiscreteTimes[i].push( i / nValueSetSize );\n\ - }\n\ -\n\ - switch( eCalcMode )\n\ - {\n\ - case CALC_MODE_DISCRETE:\n\ - log( 'createActivity: discrete calculation case not yet implemented' );\n\ - break;\n\ -\n\ - default:\n\ - log( 'createActivity: unexpected calculation mode: ' + eCalcMode );\n\ - case CALC_MODE_PACED :\n\ - case CALC_MODE_SPLINE :\n\ - case CALC_MODE_LINEAR:\n\ - return createValueListActivity( aActivityParamSet,\n\ - aAnimationNode,\n\ - aAnimation,\n\ - aInterpolator,\n\ - LinearValueListActivity,\n\ - bAccumulate,\n\ - eValueType );\n\ - }\n\ - }\n\ - else\n\ - {\n\ -\n\ - switch( eCalcMode )\n\ - {\n\ - case CALC_MODE_DISCRETE:\n\ - log( 'createActivity: discrete calculation case not yet implemented' );\n\ - break;\n\ -\n\ - default:\n\ - log( 'createActivity: unexpected calculation mode: ' + eCalcMode );\n\ - case CALC_MODE_PACED :\n\ - case CALC_MODE_SPLINE :\n\ - case CALC_MODE_LINEAR:\n\ - return createFromToByActivity( aActivityParamSet,\n\ - aAnimationNode,\n\ - aAnimation,\n\ - aInterpolator,\n\ - LinearFromToByActivity,\n\ - bAccumulate,\n\ - eValueType );\n\ - }\n\ - }\n\ - }\n\ -\n\ -\n\ - function createValueListActivity( aActivityParamSet, aAnimationNode, aAnimation,\n\ - aInterpolator, ClassTemplateInstance, bAccumulate, eValueType )\n\ - {\n\ - var aAnimatedElement = aAnimationNode.getAnimatedElement();\n\ - var aOperatorSet = aOperatorSetMap[ eValueType ];\n\ - assert( aOperatorSet, 'createFromToByActivity: no operator set found' );\n\ -\n\ - var aValueSet = aAnimationNode.getValues();\n\ -\n\ - var aValueList = new Array();\n\ -\n\ - extractAttributeValues( eValueType,\n\ - aValueList,\n\ - aValueSet,\n\ - aAnimatedElement.getBaseBBox(),\n\ - aActivityParamSet.nSlideWidth,\n\ - aActivityParamSet.nSlideHeight );\n\ -\n\ - for( var i = 0; i < aValueList.length; ++i )\n\ - {\n\ - ANIMDBG.print( 'createValueListActivity: value[' + i + '] = ' + aValueList[i] );\n\ - }\n\ -\n\ - return new ClassTemplateInstance( aValueList, aActivityParamSet, aAnimation,\n\ - aInterpolator, aOperatorSet, bAccumulate );\n\ - }\n\ -\n\ -\n\ - function createFromToByActivity( aActivityParamSet, aAnimationNode, aAnimation,\n\ - aInterpolator, ClassTemplateInstance, bAccumulate, eValueType )\n\ - {\n\ -\n\ - var aAnimatedElement = aAnimationNode.getAnimatedElement();\n\ - var aOperatorSet = aOperatorSetMap[ eValueType ];\n\ - assert( aOperatorSet, 'createFromToByActivity: no operator set found' );\n\ -\n\ - var aValueSet = new Array();\n\ - aValueSet[0] = aAnimationNode.getFromValue();\n\ - aValueSet[1] = aAnimationNode.getToValue();\n\ - aValueSet[2] = aAnimationNode.getByValue();\n\ -\n\ - ANIMDBG.print( 'createFromToByActivity: value type: ' + aValueTypeOutMap[eValueType] +\n\ - ', aFrom = ' + aValueSet[0] +\n\ - ', aTo = ' + aValueSet[1] +\n\ - ', aBy = ' + aValueSet[2] );\n\ -\n\ - var aValueList = new Array();\n\ -\n\ - extractAttributeValues( eValueType,\n\ - aValueList,\n\ - aValueSet,\n\ -"; - -static const char aSVGScript33[] = -"\ - aAnimatedElement.getBaseBBox(),\n\ - aActivityParamSet.nSlideWidth,\n\ - aActivityParamSet.nSlideHeight );\n\ -\n\ - ANIMDBG.print( 'createFromToByActivity: ' +\n\ - ', aFrom = ' + aValueList[0] +\n\ - ', aTo = ' + aValueList[1] +\n\ - ', aBy = ' + aValueList[2] );\n\ -\n\ - return new ClassTemplateInstance( aValueList[0], aValueList[1], aValueList[2],\n\ - aActivityParamSet, aAnimation,\n\ - aInterpolator, aOperatorSet, bAccumulate );\n\ - }\n\ -\n\ -\n\ - function extractAttributeValues( eValueType, aValueList, aValueSet, aBBox, nSlideWidth, nSlideHeight )\n\ - {\n\ - switch( eValueType )\n\ - {\n\ - case NUMBER_PROPERTY :\n\ - evalValuesAttribute( aValueList, aValueSet, aBBox, nSlideWidth, nSlideHeight );\n\ - break;\n\ - case BOOL_PROPERTY :\n\ - for( var i = 0; i < aValueSet.length; ++i )\n\ - {\n\ - var aValue = booleanParser( aValueSet[i] );\n\ - aValueList.push( aValue );\n\ - }\n\ - break;\n\ - case STRING_PROPERTY :\n\ - for( var i = 0; i < aValueSet.length; ++i )\n\ - {\n\ - aValueList.push( aValueSet[i] );\n\ - }\n\ - break;\n\ - case ENUM_PROPERTY :\n\ - for( var i = 0; i < aValueSet.length; ++i )\n\ - {\n\ - aValueList.push( aValueSet[i] );\n\ - }\n\ - break;\n\ - case COLOR_PROPERTY :\n\ - for( var i = 0; i < aValueSet.length; ++i )\n\ - {\n\ - var aValue = colorParser( aValueSet[i] );\n\ - aValueList.push( aValue );\n\ - }\n\ - break;\n\ - default:\n\ - log( 'createValueListActivity: unexpeded value type: ' + eValueType );\n\ - }\n\ -\n\ - }\n\ -\n\ - function evalValuesAttribute( aValueList, aValueSet, aBBox, nSlideWidth, nSlideHeight )\n\ - {\n\ - var width = aBBox.width / nSlideWidth;\n\ - var height = aBBox.height / nSlideHeight;\n\ - var x = ( aBBox.x + aBBox.width / 2 ) / nSlideWidth;\n\ - var y = ( aBBox.y + aBBox.height / 2 ) / nSlideHeight;\n\ -\n\ - for( var i = 0; i < aValueSet.length; ++i )\n\ - {\n\ - var aValue = eval( aValueSet[i] );\n\ - aValueList.push( aValue );\n\ - }\n\ - }\n\ -\n\ -\n\ - var BACKWARD = 0;\n\ - var FORWARD = 1;\n\ -\n\ - var MAXIMUM_FRAME_COUNT = 60;\n\ - var MINIMUM_TIMEOUT = 1.0 / MAXIMUM_FRAME_COUNT;\n\ - var MAXIMUM_TIMEOUT = 4.0;\n\ - var MINIMUM_FRAMES_PER_SECONDS = 10;\n\ - var PREFERRED_FRAMES_PER_SECONDS = 50;\n\ - var PREFERRED_FRAME_RATE = 1.0 / PREFERRED_FRAMES_PER_SECONDS;\n\ -\n\ -\n\ - function SlideShow()\n\ - {\n\ - this.aTimer = new ElapsedTime();\n\ - this.aFrameSynchronization = new FrameSynchronization( PREFERRED_FRAME_RATE );\n\ - this.aTimerEventQueue = new TimerEventQueue( this.aTimer );\n\ - this.aActivityQueue = new ActivityQueue( this.aTimer );\n\ - this.aNextEffectEventArray = null;\n\ - this.aEventMultiplexer = null; new EventMultiplexer( this.aTimerEventQueue );\n\ -\n\ - this.aContext = new SlideShowContext( this.aTimerEventQueue, this.aEventMultiplexer,\n\ - this.aNextEffectEventArray, this.aActivityQueue );\n\ - this.nCurrentSlide = 0;\n\ - this.nCurrentEffect = 0;\n\ - this.eDirection = FORWARD;\n\ - this.bIsIdle = true;\n\ - this.bIsEnabled = true;\n\ - }\n\ -\n\ -\n\ - SlideShow.prototype.setSlideEvents = function( aNextEffectEventArray, aEventMultiplexer )\n\ - {\n\ - if( !aNextEffectEventArray )\n\ - log( 'SlideShow.setSlideEvents: aNextEffectEventArray is not valid' );\n\ -\n\ - if( !aEventMultiplexer )\n\ - log( 'SlideShow.setSlideEvents: aEventMultiplexer is not valid' );\n\ -\n\ - this.aContext.aNextEffectEventArray = aNextEffectEventArray;\n\ - this.aNextEffectEventArray = aNextEffectEventArray;\n\ - this.aContext.aEventMultiplexer = aEventMultiplexer;\n\ - this.aEventMultiplexer = aEventMultiplexer;\n\ - this.nCurrentEffect = 0;\n\ - };\n\ -\n\ - SlideShow.prototype.isRunning = function()\n\ - {\n\ - return !this.bIsIdle;\n\ - };\n\ -\n\ - SlideShow.prototype.isEnabled = function()\n\ - {\n\ - return this.bIsEnabled;\n\ - };\n\ -\n\ - SlideShow.prototype.notifyNextEffectStart = function()\n\ - {\n\ - var aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nCurSlide].aSlideAnimationsHandler.aAnimatedElementMap;\n\ - for( sId in aAnimatedElementMap )\n\ - aAnimatedElementMap[ sId ].notifyNextEffectStart( this.nCurrentEffect );\n\ - };\n\ -\n\ - SlideShow.prototype.notifySlideStart = function()\n\ - {\n\ - var aAnimatedElementMap = theMetaDoc.aMetaSlideSet[nCurSlide].aSlideAnimationsHandler.aAnimatedElementMap;\n\ - for( sId in aAnimatedElementMap )\n\ - aAnimatedElementMap[ sId ].notifySlideStart();\n\ - };\n\ -\n\ - SlideShow.prototype.nextEffect = function()\n\ - {\n\ - if( !this.isEnabled() )\n\ - return false;\n\ -\n\ - if( this.isRunning() )\n\ - return true;\n\ -\n\ - if( !this.aNextEffectEventArray )\n\ - return false;\n\ -\n\ - this.notifyNextEffectStart();\n\ -\n\ - if( this.nCurrentEffect >= this.aNextEffectEventArray.size() )\n\ - return false;\n\ -\n\ - this.eDirection = FORWARD;\n\ - this.aNextEffectEventArray.at( this.nCurrentEffect ).fire();\n\ - ++this.nCurrentEffect;\n\ - this.update();\n\ - return true;\n\ - };\n\ -\n\ - SlideShow.prototype.previousEffect = function()\n\ - {\n\ - if( this.nCurrentEffect <= 0 )\n\ - return false;\n\ - this.eDirection = BACKWARD;\n\ - this.aNextEffectEventArray.at( this.nCurrentEffect ).fire();\n\ - --this.nCurrentEffect;\n\ - return true;\n\ - };\n\ -\n\ - SlideShow.prototype.displaySlide = function( nNewSlide, bSkipSlideTransition )\n\ - {\n\ - var aMetaDoc = theMetaDoc;\n\ - var nSlides = aMetaDoc.nNumberOfSlides;\n\ - if( nNewSlide < 0 && nSlides > 0 )\n\ - nNewSlide = nSlides - 1;\n\ - else if( nNewSlide >= nSlides )\n\ - nNewSlide = 0;\n\ -\n\ - if( nNewSlide == nCurSlide )\n\ - {\n\ - var newMetaSlide = aMetaDoc.aMetaSlideSet[nNewSlide];\n\ - newMetaSlide.show();\n\ - return;\n\ - }\n\ - var nOldSlide = nCurSlide;\n\ - nCurSlide = nNewSlide;\n\ -\n\ - var oldMetaSlide = aMetaDoc.aMetaSlideSet[nOldSlide];\n\ - var newMetaSlide = aMetaDoc.aMetaSlideSet[nNewSlide];\n\ -\n\ - if( !this.isEnabled() )\n\ - {\n\ - oldMetaSlide.hide();\n\ - newMetaSlide.show();\n\ - return;\n\ - }\n\ -\n\ - oldMetaSlide.hide();\n\ -"; - -static const char aSVGScript34[] = -"\ - oldMetaSlide.aSlideAnimationsHandler.end( bSkipSlideTransition );\n\ -\n\ - this.aTimerEventQueue.clear();\n\ - this.aActivityQueue.clear();\n\ - this.aNextEffectEventArray = null;\n\ - this.aEventMultiplexer = null;\n\ -\n\ - this.notifySlideStart();\n\ -\n\ - if( !bSkipSlideTransition )\n\ - {\n\ - }\n\ -\n\ - newMetaSlide.show();\n\ - newMetaSlide.aSlideAnimationsHandler.start();\n\ - this.update();\n\ - };\n\ -\n\ - SlideShow.prototype.update = function()\n\ - {\n\ - this.aTimer.holdTimer();\n\ - var suspendHandle = ROOT_NODE.suspendRedraw( PREFERRED_FRAME_RATE * 1000 );\n\ -\n\ - this.aTimerEventQueue.process();\n\ - this.aActivityQueue.process();\n\ -\n\ - this.aFrameSynchronization.synchronize();\n\ -\n\ - ROOT_NODE.unsuspendRedraw(suspendHandle);\n\ - ROOT_NODE.forceRedraw();\n\ - this.aTimer.releaseTimer();\n\ -\n\ - var bActivitiesLeft = ( ! this.aActivityQueue.isEmpty() );\n\ - var bTimerEventsLeft = ( ! this.aTimerEventQueue.isEmpty() );\n\ - var bEventsLeft = ( bActivitiesLeft || bTimerEventsLeft );\n\ -\n\ -\n\ - if( bEventsLeft )\n\ - {\n\ - var nNextTimeout;\n\ - if( bActivitiesLeft )\n\ - {\n\ - nNextTimeout = MINIMUM_TIMEOUT;\n\ - this.aFrameSynchronization.activate();\n\ - }\n\ - else\n\ - {\n\ - nNextTimeout = this.aTimerEventQueue.nextTimeout();\n\ - if( nNextTimeout < MINIMUM_TIMEOUT )\n\ - nNextTimeout = MINIMUM_TIMEOUT;\n\ - else if( nNextTimeout > MAXIMUM_TIMEOUT )\n\ - nNextTimeout = MAXIMUM_TIMEOUT;\n\ - this.aFrameSynchronization.deactivate();\n\ - }\n\ -\n\ - this.bIsIdle = false;\n\ - window.setTimeout( 'aSlideShow.update()', nNextTimeout * 1000 );\n\ - }\n\ - else\n\ - {\n\ - this.bIsIdle = true;\n\ - }\n\ - };\n\ -\n\ - SlideShow.prototype.getContext = function()\n\ - {\n\ - return this.aContext;\n\ - };\n\ -\n\ - var aSlideShow = null;\n\ -\n\ -\n\ - function SlideShowContext( aTimerEventQueue, aEventMultiplexer, aNextEffectEventArray, aActivityQueue)\n\ - {\n\ - this.aTimerEventQueue = aTimerEventQueue;\n\ - this.aEventMultiplexer = aEventMultiplexer;\n\ - this.aNextEffectEventArray = aNextEffectEventArray;\n\ - this.aActivityQueue = aActivityQueue;\n\ - }\n\ -\n\ -\n\ - function FrameSynchronization( nFrameDuration )\n\ - {\n\ - this.nFrameDuration = nFrameDuration;\n\ - this.aTimer = new ElapsedTime();\n\ - this.nNextFrameTargetTime = 0.0;\n\ - this.bIsActive = false;\n\ -\n\ - this.markCurrentFrame();\n\ - }\n\ -\n\ -\n\ - FrameSynchronization.prototype.markCurrentFrame = function()\n\ - {\n\ - this.nNextFrameTargetTime = this.aTimer.getElapsedTime() + this.nFrameDuration;\n\ - };\n\ -\n\ - FrameSynchronization.prototype.synchronize = function()\n\ - {\n\ - if( this.bIsActive )\n\ - {\n\ - while( this.aTimer.getElapsedTime() < this.nNextFrameTargetTime )\n\ - ;\n\ - }\n\ -\n\ - this.markCurrentFrame();\n\ -\n\ - };\n\ -\n\ - FrameSynchronization.prototype.activate = function()\n\ - {\n\ - this.bIsActive = true;\n\ - };\n\ -\n\ - FrameSynchronization.prototype.deactivate = function()\n\ - {\n\ - this.bIsActive = false;\n\ - };\n\ -\n\ -\n\ - function NextEffectEventArray()\n\ - {\n\ - this.aEventArray = new Array();\n\ - }\n\ -\n\ -\n\ - NextEffectEventArray.prototype.size = function()\n\ - {\n\ - return this.aEventArray.length;\n\ - };\n\ -\n\ - NextEffectEventArray.prototype.at = function( nIndex )\n\ - {\n\ - return this.aEventArray[ nIndex ];\n\ - };\n\ -\n\ - NextEffectEventArray.prototype.appendEvent = function( aEvent )\n\ - {\n\ - var nSize = this.size();\n\ - for( var i = 0; i < nSize; ++i )\n\ - {\n\ - if( this.aEventArray[i].getId() == aEvent.getId() )\n\ - {\n\ - aNextEffectEventArrayDebugPrinter.print( 'NextEffectEventArray.appendEvent: event already present' );\n\ - return false;\n\ - }\n\ - }\n\ - this.aEventArray.push( aEvent );\n\ - aNextEffectEventArrayDebugPrinter.print( 'NextEffectEventArray.appendEvent: event appended' );\n\ - return true;\n\ - };\n\ -\n\ - NextEffectEventArray.prototype.clear = function( )\n\ - {\n\ - this.aEventArray = new Array();\n\ - };\n\ -\n\ -\n\ - function TimerEventQueue( aTimer )\n\ - {\n\ - this.aTimer = aTimer;\n\ - this.aEventSet = new PriorityQueue( EventEntry.compare );\n\ - }\n\ -\n\ -\n\ - TimerEventQueue.prototype.addEvent = function( aEvent )\n\ - {\n\ - this.DBG( 'TimerEventQueue.addEvent invoked' );\n\ - if( !aEvent )\n\ - {\n\ - log( 'error: TimerEventQueue.addEvent: null event' );\n\ - return false;\n\ - }\n\ -\n\ - var nTime = aEvent.getActivationTime( this.aTimer.getElapsedTime() );\n\ - var aEventEntry = new EventEntry( aEvent, nTime );\n\ - this.aEventSet.push( aEventEntry );\n\ -\n\ - return true;\n\ - };\n\ -\n\ - TimerEventQueue.prototype.process = function()\n\ - {\n\ - var nCurrentTime = this.aTimer.getElapsedTime();\n\ -\n\ - while( !this.isEmpty() && ( this.aEventSet.top().nActivationTime <= nCurrentTime ) )\n\ - {\n\ - var aEventEntry = this.aEventSet.top();\n\ - this.aEventSet.pop();\n\ -\n\ - var aEvent = aEventEntry.aEvent;\n\ - if( aEvent.isCharged() )\n\ - aEvent.fire();\n\ - }\n\ - };\n\ -\n\ - TimerEventQueue.prototype.isEmpty = function()\n\ - {\n\ - return this.aEventSet.isEmpty();\n\ - };\n\ -"; - -static const char aSVGScript35[] = -"\ -\n\ - TimerEventQueue.prototype.nextTimeout = function()\n\ - {\n\ - var nTimeout = Number.MAX_VALUE;\n\ - var nCurrentTime = this.aTimer.getElapsedTime();\n\ - if( !this.isEmpty() )\n\ - nTimeout = this.aEventSet.top().nActivationTime - nCurrentTime;\n\ - return nTimeout;\n\ - };\n\ -\n\ - TimerEventQueue.prototype.clear = function()\n\ - {\n\ - this.DBG( 'TimerEventQueue.clear invoked' );\n\ - this.aEventSet.clear();\n\ - };\n\ -\n\ - TimerEventQueue.prototype.getTimer = function()\n\ - {\n\ - return this.aTimer;\n\ - };\n\ -\n\ - TimerEventQueue.prototype.DBG = function( sMessage, nTime )\n\ - {\n\ - aTimerEventQueueDebugPrinter.print( sMessage, nTime );\n\ - };\n\ -\n\ -\n\ - TimerEventQueue.prototype.insert = function( aEventEntry )\n\ - {\n\ - var nHoleIndex = this.aEventSet.length;\n\ - var nParent = Math.floor( ( nHoleIndex - 1 ) / 2 );\n\ -\n\ - while( ( nHoleIndex > 0 ) && this.aEventSet[ nParent ].compare( aEventEntry ) )\n\ - {\n\ - this.aEventSet[ nHoleIndex ] = this.aEventSet[ nParent ];\n\ - nHoleIndex = nParent;\n\ - nParent = Math.floor( ( nHoleIndex - 1 ) / 2 );\n\ - }\n\ - this.aEventSet[ nHoleIndex ] = aEventEntry;\n\ - };\n\ -\n\ -\n\ - function EventEntry( aEvent, nTime )\n\ - {\n\ - this.aEvent = aEvent;\n\ - this.nActivationTime = nTime;\n\ - }\n\ -\n\ -\n\ - EventEntry.compare = function( aLhsEventEntry, aRhsEventEntry )\n\ - {\n\ - return ( aLhsEventEntry.nActivationTime > aRhsEventEntry.nActivationTime );\n\ - };\n\ -\n\ -\n\ - function ActivityQueue( aTimer )\n\ - {\n\ - this.aTimer = aTimer;\n\ - this.aCurrentActivityWaitingSet = new Array();\n\ - this.aCurrentActivityReinsertSet = new Array();\n\ - this.aDequeuedActivitySet = new Array();\n\ - }\n\ -\n\ -\n\ - ActivityQueue.prototype.dispose = function()\n\ - {\n\ - var nSize = this.aCurrentActivityWaitingSet.length;\n\ - for( var i = 0; i < nSize; ++i )\n\ - this.aCurrentActivityWaitingSet[i].dispose();\n\ -\n\ - nSize = this.aCurrentActivityReinsertSet.length;\n\ - for( var i = 0; i < nSize; ++i )\n\ - this.aCurrentActivityReinsertSet[i].dispose();\n\ - };\n\ -\n\ - ActivityQueue.prototype.addActivity = function( aActivity )\n\ - {\n\ - if( !aActivity )\n\ - {\n\ - log( 'ActivityQueue.addActivity: activity is not valid' );\n\ - return false;\n\ - }\n\ -\n\ - this.aCurrentActivityWaitingSet.push( aActivity );\n\ - aActivityQueueDebugPrinter.print( 'ActivityQueue.addActivity: activity appended' );\n\ - return true;\n\ - };\n\ -\n\ - ActivityQueue.prototype.process = function()\n\ - {\n\ - var nSize = this.aCurrentActivityWaitingSet.length;\n\ - var nLag = 0.0;\n\ - for( var i = 0; i < nSize; ++i )\n\ - {\n\ - nLag = Math.max( nLag,this.aCurrentActivityWaitingSet[i].calcTimeLag() );\n\ - }\n\ -\n\ - if( nLag > 0.0 )\n\ - this.aTimer.adjustTimer( -nLag, true );\n\ -\n\ -\n\ - while( this.aCurrentActivityWaitingSet.length != 0 )\n\ - {\n\ - var aActivity = this.aCurrentActivityWaitingSet.shift();\n\ - var bReinsert = false;\n\ -\n\ - bReinsert = aActivity.perform();\n\ -\n\ - if( bReinsert )\n\ - {\n\ - this.aCurrentActivityReinsertSet.push( aActivity );\n\ - }\n\ - else\n\ - {\n\ - this.aDequeuedActivitySet.push( aActivity );\n\ - }\n\ - }\n\ -\n\ - if( this.aCurrentActivityReinsertSet.length != 0 )\n\ - {\n\ - this.aCurrentActivityWaitingSet = this.aCurrentActivityReinsertSet;\n\ - this.aCurrentActivityReinsertSet = new Array();\n\ - }\n\ - };\n\ -\n\ - ActivityQueue.prototype.processDequeued = function()\n\ - {\n\ - var nSize = this.aDequeuedActivitySet.length;\n\ - for( var i = 0; i < nSize; ++i )\n\ - this.aDequeuedActivitySet[i].dequeued();\n\ -\n\ - this.aDequeuedActivitySet = new Array();\n\ - };\n\ -\n\ - ActivityQueue.prototype.isEmpty = function()\n\ - {\n\ - return ( ( this.aCurrentActivityWaitingSet.length == 0 ) &&\n\ - ( this.aCurrentActivityReinsertSet.length == 0 ) );\n\ - };\n\ -\n\ - ActivityQueue.prototype.clear = function()\n\ - {\n\ - aActivityQueueDebugPrinter.print( 'ActivityQueue.clear invoked' );\n\ - var nSize = this.aCurrentActivityWaitingSet.length;\n\ - for( var i = 0; i < nSize; ++i )\n\ - this.aCurrentActivityWaitingSet[i].dequeued();\n\ - this.aCurrentActivityWaitingSet = new Array();\n\ -\n\ - nSize = this.aCurrentActivityReinsertSet.length;\n\ - for( var i = 0; i < nSize; ++i )\n\ - this.aCurrentActivityReinsertSet[i].dequeued();\n\ - this.aCurrentActivityReinsertSet = new Array();\n\ - };\n\ -\n\ - ActivityQueue.prototype.getTimer = function()\n\ - {\n\ - return this.aTimer;\n\ - };\n\ -\n\ - ActivityQueue.prototype.size = function()\n\ - {\n\ - return ( this.aCurrentActivityWaitingSet.length +\n\ - this.aCurrentActivityReinsertSet.length +\n\ - this.aDequeuedActivitySet.length );\n\ - };\n\ -\n\ -\n\ - function ElapsedTime( aTimeBase )\n\ - {\n\ - this.aTimeBase = aTimeBase;\n\ - this.nLastQueriedTime = 0.0;\n\ - this.nStartTime = this.getCurrentTime();\n\ - this.nFrozenTime = 0.0;\n\ - this.bInPauseMode = false;\n\ - this.bInHoldMode = false;\n\ - }\n\ -\n\ -\n\ - ElapsedTime.prototype.getTimeBase = function()\n\ - {\n\ - return aTimeBase;\n\ - };\n\ -\n\ - ElapsedTime.prototype.reset = function()\n\ - {\n\ - this.nLastQueriedTime = 0.0;\n\ - this.nStartTime = this.getCurrentTime();\n\ - this.nFrozenTime = 0.0;\n\ - this.bInPauseMode = false;\n\ - this.bInHoldMode = false;\n\ - };\n\ -\n\ - ElapsedTime.prototype.getElapsedTime = function()\n\ - {\n\ - this.nLastQueriedTime = this.getElapsedTimeImpl();\n\ - return this.nLastQueriedTime;\n\ - };\n\ -\n\ - ElapsedTime.prototype.pauseTimer = function()\n\ - {\n\ -"; - -static const char aSVGScript36[] = -"\ - this.nFrozenTime = this.getElapsedTimeImpl();\n\ - this.bInPauseMode = true;\n\ - };\n\ -\n\ - ElapsedTime.prototype.continueTimer = function()\n\ - {\n\ - this.bInPauseMode = false;\n\ -\n\ - var nPauseDuration = this.getElapsedTimeImpl() - this.nFrozenTime;\n\ -\n\ - this.nStartTime += nPauseDuration;\n\ - };\n\ -\n\ - ElapsedTime.prototype.adjustTimer = function( nOffset, bLimitToLastQueriedTime )\n\ - {\n\ - if( bLimitToLastQueriedTime == undefined )\n\ - bLimitToLastQueriedTime = true;\n\ -\n\ - this.nStartTime -= nOffset;\n\ -\n\ - if( this.bInHoldMode || this.bInPauseMode )\n\ - this.nFrozenTime += nOffset;\n\ - };\n\ -\n\ - ElapsedTime.prototype.holdTimer = function()\n\ - {\n\ - this.nFrozenTime = this.getElapsedTimeImpl();\n\ - this.bInHoldMode = true;\n\ - };\n\ -\n\ - ElapsedTime.prototype.releaseTimer = function()\n\ - {\n\ - this.bInHoldMode = false;\n\ - };\n\ -\n\ - ElapsedTime.prototype.getSystemTime = function()\n\ - {\n\ - return ( getCurrentSystemTime() / 1000.0 );\n\ - };\n\ -\n\ - ElapsedTime.prototype.getCurrentTime = function()\n\ - {\n\ - var nCurrentTime;\n\ - if ( !this.aTimeBase )\n\ - {\n\ - nCurrentTime = this.getSystemTime();\n\ - }\n\ - else\n\ - {\n\ - nCurrentTime = this.aTimeBase.getElapsedTimeImpl();\n\ - }\n\ -\n\ - assert( ( typeof( nCurrentTime ) === typeof( 0 ) ) && isFinite( nCurrentTime ),\n\ - 'ElapsedTime.getCurrentTime: assertion failed: nCurrentTime == ' + nCurrentTime );\n\ -\n\ -\n\ - return nCurrentTime;\n\ - };\n\ -\n\ - ElapsedTime.prototype.getElapsedTimeImpl = function()\n\ - {\n\ - if( this.bInHoldMode || this.bInPauseMode )\n\ - {\n\ -\n\ - return this.nFrozenTime;\n\ - }\n\ -\n\ - var nCurTime = this.getCurrentTime();\n\ - return ( nCurTime - this.nStartTime );\n\ - };\n\ -\n\ -\n\ - /*****\n\ - * @libreofficeend\n\ - *\n\ - * Several parts of the above code are the result of the porting,\n\ - * started on August 2011, of the C++ code included in the source files\n\ - * placed under the folder '/slideshow/source' and subfolders.\n\ - * @source http://cgit.freedesktop.org/libreoffice/core/tree/slideshow/source\n\ - *\n\ - */\n\ -\n\ -\n\ -]]>"; - - - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3