9 SWS.Utils = new function () {
12 self.isUndefined = function (o) { return typeof o == "undefined"; };
13 self.push2 = function (t, i, v) {
14 if ((typeof t[i]) == 'undefined') {
21 self.isEmpty = function (o) {
22 for(var _ in o) return false;
26 self.parseFrameSpec = function (s) {
27 var elems = s.split("_");
31 for(var i = 0; i < elems.length; i++){
32 var bounds = elems[i].split("-");
33 if (bounds.length > 2 || bounds.length == 0) return {};
34 if (bounds.length == 1) bounds[1] = bounds[0];
35 var a = parseInt(bounds[0]);
36 var b = parseInt(bounds[1])
37 if (!isFinite(a) || !isFinite(b)) return {};
38 a = Math.min(a, 1000); // don't allow more than 1000 frames/slide
39 b = Math.min(b, 1000);
40 if (b > max_value) max_value = b;
41 for (var j = a; j <= b; j++)
53 SWS.Templates = new function () {
55 self.controlPanel = "<div id='sws-control-panel'>\
56 <a onclick='SWS.Presentation.goToSlide(SWS.Presentation.firstSlide());'>◀◀◀</a>\
57 <a onclick='SWS.Presentation.previousSlide();SWS.Presentation.refresh();'>◀◀ </a>\
58 <a onclick='SWS.Presentation.previous();SWS.Presentation.refresh();'>◀</a>\
59 <a onclick='SWS.Presentation.next();SWS.Presentation.refresh();'>▶</a>\
60 <a onclick='SWS.Presentation.nextSlide();SWS.Presentation.refresh();'>▶▶</a>\
61 <a rel='Last slide' onclick='SWS.Presentation.goToSlide(SWS.Presentation.lastSlide());'>▶▶▶</a>\
63 self.slideActivate = function (o) {
64 if (!(o.hasClass("sws-active-slide"))){
65 o.removeClass("sws-inactive-slide").addClass("sws-active-slide");
69 self.slideDeactivate = function (o) {
70 if (!(o.hasClass("sws-inactive-slide"))){
71 o.removeClass("sws-active-slide").addClass("sws-inactive-slide");
75 self.slideChange = function (from, to) {
76 var canvas = $(".sws-canvas");
77 self.slideDeactivate($(canvas[from]));
78 self.slideActivate($(canvas[to]));
81 self.objectActivate = function (o) {
82 if (!(o.hasClass("sws-active-object"))){
83 o.removeClass("sws-inactive-object").addClass("sws-active-object");
84 o.css({'visibility':'visible'});
90 self.objectDeactivate = function (o) {
91 if (!(o.hasClass("sws-inactive-object"))){
92 o.addClass("sws-inactive-object").removeClass("sws-active-object");
98 self.updateFooter = function (o) {
99 var footer = o.find(".sws-footer");
100 if (footer.length && (footer.children("*").length == 0)) {
101 var i = SWS.Presentation.getCurrentSlide();
102 var cur = $( "<span class='sws-current-slide-number'>"
105 var sep = $( "<span class='sws-slide-num-sep' />");
106 var tot = $( "<span class='sws-last-slide-number'>"
107 + (SWS.Presentation.getNumSlides())
109 footer.append(cur).append(sep).append(tot);
112 self.updateHeader = function (o) {};
114 SWS.ConfigBuilder = function () {
116 self['sws-object-activate'] = SWS.Templates.objectActivate;
117 self['sws-object-deactivate'] = SWS.Templates.objectDeactivate;
118 self['sws-slide-change'] = SWS.Templates.slideChange;
119 self['sws-update-footer'] = SWS.Templates.updateFooter;
120 self['sws-update-header'] = SWS.Templates.updateHeader;
123 SWS.Defaults = new SWS.ConfigBuilder ();
125 SWS.Config = new SWS.ConfigBuilder ();
128 SWS.Effects = new function () {
131 self.objectDeactivateFadeOut = function (o) {
132 o.animate({'opacity': '0'}, 200,
133 function () { SWS.Templates.objectDeactivate(o)});
136 self.objectActivateFadeIn = function (o) {
138 if (SWS.Templates.objectActivate(o)){
139 o.animate({'opacity': '1' }, 200);
144 self.slideChangeHorizontalFlip = function (from, to){
145 var f = SWS.Presentation.getSlide(from);
146 var t = SWS.Presentation.getSlide(to);
147 f.animate({ 'left': '50%', 'width': '0pt', 'opacity':'0' }, 150,
149 SWS.Templates.slideDeactivate(f);
150 f.css({'left':'0%', 'width': '100%'});
151 t.css({ 'left': '50%', 'width': '0pt','opacity':'0' });
152 SWS.Templates.slideActivate(t);
153 t.animate({'left':'0%', 'width': '100%','opacity':'1'});
156 self.slideChangeFadeOutIn = function (from, to) {
157 var f = SWS.Presentation.getSlide(from);
158 var t = SWS.Presentation.getSlide(to);
159 f.animate({ 'opacity': '0'}, 150,
160 function () { SWS.Templates.slideDeactivate(f);
161 SWS.Templates.slideActivate(t);
162 t.css('opacity', '0');
163 t.animate({ 'opacity': '1'}, 150);
166 self.slideChangeHorizontalSlide = function (from, to) {
167 var f = SWS.Presentation.getSlide(from);
168 var t = SWS.Presentation.getSlide(to);
170 t.css('left', '100%');
171 SWS.Templates.slideActivate(t);
172 f.animate({ 'left': '-100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
173 t.animate({ 'left': '0%' }, 250);
175 t.css('left', '-100%');
176 SWS.Templates.slideActivate(t);
177 f.animate({ 'left': '100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
178 t.animate({ 'left': '0%' }, 250);
183 self.slideChangeVerticalSlide = function (from, to) {
184 var f = SWS.Presentation.getSlide(from);
185 var t = SWS.Presentation.getSlide(to);
187 t.css('top', '100%');
188 SWS.Templates.slideActivate(t);
189 f.animate({ 'top': '-100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
190 t.animate({ 'top': '0%' }, 250);
192 t.css('top', '-100%');
193 SWS.Templates.slideActivate(t);
194 f.animate({ 'top': '100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
195 t.animate({ 'top': '0%' }, 250);
201 SWS.Presentation = new function () {
206 //TODO move outside of the Presentation object
210 var _initialized = false;
211 var _disable_input_events = false;
213 var _slide_callbacks = new Array ();
216 self.getNumSlides = function () { return _total_slides; };
218 self.getSlide = function(i) {
219 return $($(".sws-canvas")[i]);
222 self.registerCallback = function (i, f) {
223 if (_initialized) return;
224 //jQuery does not seem to work well
227 var slide_num = $(".sws-slide").length - 1;
229 SWS.Utils.push2(_slide_callbacks, slide_num,{ 'fn': f, 'frame': i });
233 if (typeof(Storage)!=="undefined"){
234 self.getCurrentSlide = function () {
235 //unary + casts to integer
236 var i = +(sessionStorage.getItem("current_slide"));
237 if (!(i >= 0 && i < self.getNumSlides())){
244 self.setCurrentSlide = function (i) {
245 sessionStorage.setItem("current_slide", i);
249 var _current_slide = 0;
250 self.getCurrentSlide = function () { return _current_slide; };
251 self.setCurrentSlide = function (i) { _current_slide = i; };
254 self.firstSlide = function () { return 0; };
255 self.lastSlide = function () { return self.getNumSlides() - 1; };
256 self.refresh = function () {
257 /* block upcoming input event until all animations are finished */
258 _disable_input_events = true;
260 var canvas = $(".sws-canvas");
261 var from_slide_num = canvas.index($(".sws-active-slide"));
262 var to_slide_num = self.getCurrentSlide();
263 var watch_slide_anim = false;
264 var to_slide = $(canvas[to_slide_num]);
265 var from_slide = $(canvas[from_slide_num]);
266 var slide_change = (from_slide_num != to_slide_num);
268 var info = to_slide.data("sws-frame-info");
269 SWS.Config['sws-update-header'](to_slide);
270 SWS.Config['sws-update-footer'](to_slide);
273 //Launch a slide transition:
274 SWS.Config['sws-slide-change'](from_slide_num, to_slide_num);
275 watch_slide_anim = true;
276 for (var i = 0; i < info.callbacks.at_slide.length;i++){
277 info.callbacks.at_slide[i](to_slide);
282 var cur = info.current;
283 var custom = info.custom;
284 var real_slide = to_slide.find(".sws-slide");
286 real_slide.find("*").andSelf().each(function (i){
287 var frameset = $(this).data("sws-frame-set") || {};
289 SWS.Config['sws-object-activate']($(this));
291 SWS.Config['sws-object-deactivate']($(this));
295 if (callbacks = info.callbacks.at_frame[self.getCurrentFrame()]){
296 for (var k = 0; k < callbacks.length; k++)
297 callbacks[k]($(to_slide));
300 var all = $(from_slide).add(to_slide);
301 all.find("*").addBack().promise().done(function() {
302 _disable_input_events = false;
306 self.nextSlide = function () {
307 self.setCurrentSlide(Math.min(self.getCurrentSlide()+1,
309 self.setCurrentFrame(self.firstFrame());
312 self.previousSlide = function () {
313 self.setCurrentSlide(Math.max(self.getCurrentSlide()-1,
315 self.setCurrentFrame(self.firstFrame());
318 self.getFrameInfo = function () {
320 var i = self.getCurrentSlide();
321 var canvas = $($(".sws-canvas")[i]);
322 var infos = canvas.data("sws-frame-info");
325 self.getCurrentFrame = function () { return self.getFrameInfo().current; };
326 self.setCurrentFrame = function (i) { self.getFrameInfo().current = i; };
327 self.firstFrame = function () { return 0; };
328 self.lastFrame = function () { return self.getFrameInfo().last; };
330 self.nextFrame = function () {
331 self.setCurrentFrame(Math.min(self.getCurrentFrame()+1,
335 self.previousFrame = function () {
336 self.setCurrentFrame(Math.max(self.getCurrentFrame()-1,
340 self.next = function () {
341 var i = self.getCurrentFrame();
342 if (i == self.lastFrame()) {
344 self.setCurrentFrame(self.firstFrame());
349 self.previous = function () {
350 var i = self.getCurrentFrame();
351 if (i == self.firstFrame()){
352 self.previousSlide();
353 self.setCurrentFrame(self.lastFrame());
356 self.previousFrame();
359 self.goToSlide = function (s, f) {
360 if (SWS.Utils.isUndefined(f))
362 if (!(s >= self.firstSlide() && s <= self.lastSlide())) return;
363 self.setCurrentSlide(s);
364 if (!(f >= self.firstFrame() && f <= self.lastFrame())) f = 0;
365 self.setCurrentFrame(f);
369 self.cycleStyle = function() {
370 var styles = $("head").children('link[rel$="stylesheet"][title]');
371 var j = styles.index(styles.filter(':not(:disabled)'));
372 styles[j].disabled = true;
373 if (++j == styles.length) j = 0;
374 styles[j].disabled = false;
377 self.inputHandler = function (event) {
378 if (_disable_input_events) return;
379 switch (event.which) {
381 self.setCurrentSlide(self.firstSlide());
385 self.setCurrentSlide(self.lastSlide());
393 case 34: /* PgDown */
397 case 8: /* backspace */
403 self.previousSlide();
409 $("#sws-control-panel").toggle();
418 function init_canvas(canvas, custom) {
420 var last_frame = canvas.find(".sws-pause").length;
421 //Add all regular elements to the frame list
422 var slide = $(canvas.find(".sws-slide")[0]);
424 var callbacks = { at_slide : new Array(),
425 at_frame : new Array() }
427 if (SWS.Utils.isUndefined(custom)) {
428 custom = new Array ();
431 for (var i = 0; i < custom.length; i++) {
432 if (isFinite(custom[i].frame)){
433 var num = +(custom[i].frame);
434 if (num > last_frame) last_frame = num;
435 SWS.Utils.push2(callbacks.at_frame, num, custom[i].fn);
436 } else if (custom[i].frame == "slide")
437 callbacks.at_slide.push(custom[i].fn);
439 var frame_set = SWS.Utils.parseFrameSpec(custom[i].frame);
440 for(var f in frame_set){
441 if (f > last_frame) last_frame = f;
442 SWS.Utils.push2(callbacks.at_frame, +(f), custom[i].fn);
449 slide.find('*[class*="sws-onframe-"]').each(function(_){
450 var cls = $(this).attr('class');
451 var idx = cls.indexOf("sws-onframe-");
453 var end = cls.indexOf(" ", idx);
454 end = (end == -1) ? cls.length : end;
455 var spec = cls.substring(idx+12, end);
456 var o = SWS.Utils.parseFrameSpec(spec);
458 if (f > last_frame) last_frame = f;
459 $(this).find("*").andSelf().each(function(_){
460 if (!SWS.Utils.isEmpty(o))
461 $(this).data("sws-frame-set", o);
463 specials.add($(this));
470 slide.find("*").andSelf().not(specials).each(function(i) {
471 if ($(this).hasClass("sws-pause")) cur_frame++;
473 for (var j = cur_frame; j <= last_frame; j++)
475 if (!SWS.Utils.isEmpty(o))
476 $(this).data("sws-frame-set", o);
479 canvas.data("sws-frame-info", { current: 0,
486 self.init = function () {
487 console.log("inited");
488 $(window).bind('storage', function (e) {
492 _total_slides = $(".sws-slide").length;
494 $(document).keydown(self.inputHandler);
495 $("body").append($(SWS.Templates.controlPanel));
496 var cur = self.getCurrentSlide();
497 $(".sws-slide").each (function (i) {
498 var par = $(this).parent();
501 var canvas = $('<div class="sws-canvas"/>');
503 if (!($(this).hasClass("sws-option-noheader"))) {
504 canvas.append($('<div class="sws-header"/><br/>'));
507 var inner = $('<div class="sws-inner-canvas"/>');
508 var content = $('<div class="sws-content"/>');
509 var title = $('<div class="sws-title"/>');
510 var h1 = $(this).children("h1");
515 canvas.append(title);
516 canvas.append($("<br/>"));
517 $(this).find('script[type="text/javascript"]').remove();
518 content.append($(this));
519 inner.append(content);
520 inner.append($('<span class="sws-vertical-align"> </span><br/>'));
521 canvas.append(inner);
523 if (!($(this).hasClass("sws-option-nofooter"))) {
524 canvas.append($('<div class="sws-footer"/>'));
531 .addClass("sws-active-slide")
532 .removeClass("sws-inactive-slide");
535 .addClass("sws-inactive-slide")
536 .removeClass("sws-active-slide");
538 init_canvas(canvas,_slide_callbacks[i]);
541 _slide_callbacks = null; /* avoid a leak */