Clean-up the Demo.
[hacks/simpleWebSlides.git] / simpleWebSlides.js
index e592eb8..3e0faf6 100644 (file)
@@ -18,7 +18,40 @@ SWS.Utils = new function () {
         t[i][l] = v;
     };
 
+    self.isEmpty = function (o) {
+        for(var _ in o) return false;
+        return true;
+    };
+
+    self.parseFrameSpec = function (s) {
+        var elems = s.split("_");
+        var result = {};
+        var min_last = 10000;
+        var max_value = -1;
+        for(var i = 0; i < elems.length; i++){
+            var bounds = elems[i].split("-");
+            if (bounds.length > 2 || bounds.length == 0) return {};
+            if (bounds.length == 1) bounds[1] = bounds[0];
+            var a = parseInt(bounds[0]);
+            var b = parseInt(bounds[1])
+            if (!isFinite(a) || !isFinite(b)) return {};
+            a = Math.min(a, 1000); // don't allow more than 1000 frames/slide
+            b = Math.min(b, 1000);
+            if (b > max_value) max_value = b;
+            for (var j = a; j <= b; j++)
+                result[j] = true;
+        };
+        return result;
+    };
+
 
+};
+
+
+
+
+SWS.Templates = new function () {
+    var self = this;
     self.slideActivate = function (o) {
         if (!(o.hasClass("sws-active-slide"))){
             o.removeClass("sws-inactive-slide").addClass("sws-active-slide");
@@ -41,15 +74,19 @@ SWS.Utils = new function () {
         if (!(o.hasClass("sws-active-object"))){
             o.removeClass("sws-inactive-object").addClass("sws-active-object");
             o.css({'visibility':'visible'});
+            return true;
         };
+        return false;
     };
 
     self.objectDeactivate = function (o) {
-        o.css({'visibility':'hidden', 'display':''});
         if (!(o.hasClass("sws-inactive-object"))){
             o.addClass("sws-inactive-object").removeClass("sws-active-object");
+            return true;
         };
+        return false;
     };
+
     self.updateFooter = function (o) {
         var footer = o.find(".sws-footer");
         if (footer.length && (footer.children("*").length == 0)) {
@@ -66,31 +103,70 @@ SWS.Utils = new function () {
     };
     self.updateHeader = function (o) {};
 };
+SWS.ConfigBuilder = function () {
+    var self = this;
+    self['sws-object-activate'] = SWS.Templates.objectActivate;
+    self['sws-object-deactivate'] = SWS.Templates.objectDeactivate;
+    self['sws-slide-change'] = SWS.Templates.slideChange;
+    self['sws-update-footer'] = SWS.Templates.updateFooter;
+    self['sws-update-header'] = SWS.Templates.updateHeader;
+};
+
+SWS.Defaults = new SWS.ConfigBuilder ();
+
+SWS.Config = new SWS.ConfigBuilder ();
 
 
 SWS.Effects = new function () {
     var self = this;
+
     self.objectDeactivateFadeOut = function (o) {
-        o.fadeOut(150, function () { SWS.Utils.objectDeactivate(o)});
+        o.animate({'opacity': '0'}, 150,
+                  function () { SWS.Templates.objectDeactivate(o)});
     };
 
     self.objectActivateFadeIn = function (o) {
-        SWS.Utils.objectActivate(o);
-        o.fadeIn(150);
+
+        if (SWS.Templates.objectActivate(o)){
+            o.animate({'opacity': '1' }, 150);
+        };
+
     };
 
+    self.slideChangeHorizontalFlip = function (from, to){
+        var f = SWS.Presentation.getSlide(from);
+        var t = SWS.Presentation.getSlide(to);
+        f.animate({ 'left': '50%', 'width': '0pt', 'opacity':'0' }, 150,
+                  function  () {
+                      SWS.Templates.slideDeactivate(f);
+                      f.css({'left':'0%', 'width': '100%'});
+                      t.css({ 'left': '50%', 'width': '0pt','opacity':'0' });
+                      SWS.Templates.slideActivate(t);
+                      t.animate({'left':'0%', 'width': '100%','opacity':'1'});
+                  });
+    };
+    self.slideChangeFadeOutIn = function (from, to) {
+        var f = SWS.Presentation.getSlide(from);
+        var t = SWS.Presentation.getSlide(to);
+        f.animate({ 'opacity': '0'}, 150,
+                  function () { SWS.Templates.slideDeactivate(f);
+                                SWS.Templates.slideActivate(t);
+                                t.css('opacity', '0');
+                                t.animate({ 'opacity': '1'}, 150);
+                              });
+    };
     self.slideChangeHorizontalSlide = function (from, to) {
         var f = SWS.Presentation.getSlide(from);
         var t = SWS.Presentation.getSlide(to);
         if (from < to) {
             t.css('left', '100%');
-            SWS.Utils.slideActivate(t);
-            f.animate({ 'left': '-100%' }, 250, function () { SWS.Utils.slideDeactivate(f); });
+            SWS.Templates.slideActivate(t);
+            f.animate({ 'left': '-100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
             t.animate({ 'left': '0%' }, 250);
         } else {
             t.css('left', '-100%');
-            SWS.Utils.slideActivate(t);
-            f.animate({ 'left': '100%' }, 250, function () { SWS.Utils.slideDeactivate(f); });
+            SWS.Templates.slideActivate(t);
+            f.animate({ 'left': '100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
             t.animate({ 'left': '0%' }, 250);
         };
     };
@@ -101,75 +177,34 @@ SWS.Effects = new function () {
         var t = SWS.Presentation.getSlide(to);
         if (from < to) {
             t.css('top', '100%');
-            SWS.Utils.slideActivate(t);
-            f.animate({ 'top': '-100%' }, 250, function () { SWS.Utils.slideDeactivate(f); });
+            SWS.Templates.slideActivate(t);
+            f.animate({ 'top': '-100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
             t.animate({ 'top': '0%' }, 250);
         } else {
             t.css('top', '-100%');
-            SWS.Utils.slideActivate(t);
-            f.animate({ 'top': '100%' }, 250, function () { SWS.Utils.slideDeactivate(f); });
+            SWS.Templates.slideActivate(t);
+            f.animate({ 'top': '100%' }, 250, function () { SWS.Templates.slideDeactivate(f); });
             t.animate({ 'top': '0%' }, 250);
         };
     };
 
 };
 
-/*
-  Representation of intervals of positive integers.
-
-SWS.Interval = new function (init) {
-
-    var self = this;
-    self.data = new Array();
-    self.parseString(s) {
-        var elems = s.split("_");
-        for(var i = 0; i < elems.length; i++){
-            var bounds = elems[i].split("-");
-            if (bounds.length > 2) continue;
-            if (SWS.isUndefined(bounds[1])) bounds[1] = bounds[0];
-            if (!(isFinite(bounds[0]) && isFinite(bounds[1]))) continue;
-
-            self.add(+(bounds[0]), +(bounds[1]));
-        };
-7C
-    };
-    self.add(x, y) {
-        if (SWS.isUndefined(y) && isFinite(x)) self.add(x,x);
-
-
-
-
-    };
-5B
-
-
-    };
-};
-*/
-
 SWS.Presentation = new function () {
 
 
     var self = this;
 
-    var templates = {};
+    //TODO move outside of the Presentation object
 
 
-    //TODO: clean-up;
     var _total_slides;
     var _initialized = false;
-    var _animations_running = false;
+    var _disable_input_events = false;
 
     var _slide_callbacks = new Array ();
 
 
-
-
-    //Public methods
-    self.setTemplate = function (tn, fn) {
-        templates[tn] = fn;
-    };
-
     self.getNumSlides = function () { return _total_slides; };
 
     self.getSlide = function(i) {
@@ -212,23 +247,23 @@ SWS.Presentation = new function () {
     self.lastSlide = function () { return self.getNumSlides() - 1; };
 
     self.refresh = function () {
-        /* block upcoming input event until all animation are finished */
-        _animations_running = true;
+        /* block upcoming input event until all animations are finished */
+        _disable_input_events = true;
 
         var canvas = $(".sws-canvas");
         var from_slide_num = canvas.index($(".sws-active-slide"));
         var to_slide_num = self.getCurrentSlide();
         var watch_slide_anim = false;
         var to_slide = $(canvas[to_slide_num]);
-        var slide_change = !_initialized || (from_slide_num != to_slide_num);
+        var slide_change = (from_slide_num != to_slide_num);
 
         var info = to_slide.data("sws-frame-info");
         if (slide_change) {
             //Launch a slide transition:
-            templates['sws-slide-change'](from_slide_num, to_slide_num);
+            SWS.Config['sws-slide-change'](from_slide_num, to_slide_num);
             watch_slide_anim = true;
-            templates['sws-update-header'](to_slide);
-            templates['sws-update-footer'](to_slide);
+            SWS.Config['sws-update-header'](to_slide);
+            SWS.Config['sws-update-footer'](to_slide);
             for (var i = 0; i < info.callbacks.at_slide.length;i++){
                 info.callbacks.at_slide[i](to_slide);
             };
@@ -238,13 +273,13 @@ SWS.Presentation = new function () {
         var cur = info.current;
         var custom = info.custom;
         var real_slide = to_slide.children(".sws-slide");
-        real_slide.find("*").add(real_slide).each (function (i) {
-            var fcur = "f" + cur;
+
+        to_slide.children(".sws-slide").find("*").andSelf().each(function (i){
             var frameset = $(this).data("sws-frame-set") || {};
-            if (frameset[fcur])
-                templates['sws-object-activate']($(this));
+            if (frameset[cur])
+                SWS.Config['sws-object-activate']($(this));
             else
-                templates['sws-object-deactivate']($(this));
+                SWS.Config['sws-object-deactivate']($(this));
         });
 
         var callbacks;
@@ -259,7 +294,7 @@ SWS.Presentation = new function () {
         };
 
         to_watch.find("*").promise().done(function() {
-            _animations_running = false;
+            _disable_input_events = false;
         });
     };
 
@@ -305,21 +340,23 @@ SWS.Presentation = new function () {
 
     self.previous = function () {
         var i = self.getCurrentFrame();
-        if (i == self.firstFrame())
+        if (i == self.firstFrame()){
             self.previousSlide();
+            self.setCurrentFrame(self.lastFrame());
+        }
         else
             self.previousFrame();
     };
 
     self.inputHandler = function (event) {
-        if (_animations_running) return;
+        if (_disable_input_events) return;
         switch (event.which) {
         case 36:/* Home */
-            self.firstSlide();
+            self.setCurrentSlide(self.firstSlide());
             break;
 
         case 35:/* End */
-            self.lastSlide();
+            self.setCurrentSlide(self.lastSlide());
             break;
 
         case 32: /* space */
@@ -359,24 +396,49 @@ SWS.Presentation = new function () {
         if (SWS.Utils.isUndefined(custom)) {
             custom = new Array ();
         };
+
         for (var i = 0; i < custom.length; i++) {
-            if (isFinite(custom[i].frame))
-                SWS.Utils.push2(callbacks.at_frame, +(custom[i].frame), custom[i].fn);
-            else if (custom[i].frame == "slide")
+            if (isFinite(custom[i].frame)){
+                var num = +(custom[i].frame);
+                if (num > last_frame) last_frame = num;
+                SWS.Utils.push2(callbacks.at_frame, num, custom[i].fn);
+            } else if (custom[i].frame == "slide")
                 callbacks.at_slide.push(custom[i].fn);
+            else {
+                var frame_set = SWS.Utils.parseFrameSpec(custom[i].frame);
+                for(var f in frame_set){
+                    if (f > last_frame) last_frame = f;
+                    SWS.Utils.push2(callbacks.at_frame, +(f), custom[i].fn);
+                };
+            }
         };
 
-        slide.find("*").add(slide).each(function(i) {
-            if ($(this).filter('*[class*="sws-onslide-"]').length) {
-            } else {
-                if ($(this).hasClass("sws-pause"))  cur_frame++;
-                var o = {};
-                for (var j = cur_frame; j <= last_frame; j++)
-                    o[ "f" + j ] = true;
-                $(this).data("sws-frame-set", o);
+        var specials = slide.find('*[class*="sws-onslide-"]').find("*").andSelf();
+        specials.each(function(i) {
+            var cls = $(this).attr('class');
+            var idx = cls.indexOf("sws-onslide-");
+            if (idx >= 0) {
+                var end = cls.indexOf(" ", idx);
+                end = (end == -1) ? cls.length : end;
+                var spec = cls.substring(idx+12, end);
+                var o = SWS.Utils.parseFrameSpec(spec);
+                for(var f in o)
+                    if (f > last_frame) last_frame = f;
+
+                if (!SWS.Utils.isEmpty(o))
+                    $(this).data("sws-frame-set", o);
             };
         });
 
+        slide.find("*").andSelf().not(specials).each(function(i) {
+            if ($(this).hasClass("sws-pause"))  cur_frame++;
+            var o = {};
+            for (var j = cur_frame; j <= last_frame; j++)
+                o[ j ] = true;
+            if (!SWS.Utils.isEmpty(o))
+                $(this).data("sws-frame-set", o);
+        });
+
         canvas.data("sws-frame-info", { current: 0,
                                         last: last_frame,
                                         callbacks: callbacks
@@ -432,10 +494,5 @@ SWS.Presentation = new function () {
 
 
 
-    self.setTemplate('sws-object-activate', SWS.Utils.objectActivate);
-    self.setTemplate('sws-object-deactivate', SWS.Utils.objectDeactivate);
-    self.setTemplate('sws-slide-change', SWS.Utils.slideChange);
-    self.setTemplate('sws-update-footer', SWS.Utils.updateFooter);
-    self.setTemplate('sws-update-header', SWS.Utils.updateHeader);
 
 };