tot - Check-in [12]
Not logged in
[Browse]  [Home]  [Login]  [Reports]  [Search]  [Timeline
  [Patchset
Check-in Number: 12
Date: 2007-Mar-13 21:06:44 (local)
2007-Mar-13 20:06:44 (UTC)
User:rse
Branch:
Comment: complete overhaul of the scheduler plugin
Tickets:
Inspections:
Files:
jquery/jquery.schedule.html      5 -> 12
jquery/jquery.schedule.js      11 -> 12
Modified: jquery/jquery.schedule.html
===================================================================
--- jquery/jquery.schedule.html	2007-03-13 17:14:37 UTC (rev 11)
+++ jquery/jquery.schedule.html	2007-03-13 20:06:44 UTC (rev 12)
@@ -10,19 +10,38 @@
     <body>              
         <h1>jQuery Scheduler Plugin Demo</h1>
 
-        <div id="log">(empty log)</div>
-        <div id="test">TEST</div>
+        <div id="log1">(empty log)</div>
+        <div id="test1">TEST</div>
 
         <script type="text/javascript">
-            $(document).ready(
-                function(){
-                    $('#test').click(function () {
-                        $(this).css("color", "blue").schedule("2s", function (x) {
+            $(document).ready(function(){
+                $('#test1').click(function () {
+                    $(this).css("color", "blue").schedule("2s", function (x) {
+                        $(this).css("color", "red");
+                        $("#log1").html("x=|"+x+"|");
+                    }, 42);
+                });
+            });
+        </script>
+
+        <p/>
+
+        <div id="log2">(empty log)</div>
+        <div id="test2">TEST</div>
+
+        <script type="text/javascript">
+            $(document).ready(function(){
+                $('#test2').click(function () {
+                    $(this).css("color", "blue").schedule({
+                        time: "2s",
+                        func: function (x) {
                             $(this).css("color", "red");
-                            $("#log").html("x=|"+x+"|");
-                        }, 42);
+                            $("#log2").html("x=|"+x+"|");
+                        },
+                        args: [ 42 ]
                     });
+                });
             });
-         </script>
+        </script>
     </body>
 </html>

Modified: jquery/jquery.schedule.js
===================================================================
--- jquery/jquery.schedule.js	2007-03-13 17:14:37 UTC (rev 11)
+++ jquery/jquery.schedule.js	2007-03-13 20:06:44 UTC (rev 12)
@@ -24,198 +24,213 @@
  *  </script>
  */
 
-/*  object constructor  */
-jQuery.scheduler = function () {
-    this.bucket = {};
-    return;
-};
+(function($) {
 
-/*  object methods  */
-jQuery.scheduler.prototype = {
-    /*  schedule a task  */
-    schedule: function () {
-        /*  schedule context with default parameters */
-        var ctx = {
-            "_scheduler": this,         /* internal: back-reference to scheduler object */
-            "_handle":    null,         /* internal: unique handle of low-level task */
-            "id":         null,         /* unique identifier of high-level schedule */
-            "time":       1000,         /* time in milliseconds after which the task is run */
-            "repeat":     false,        /* whether schedule should be automatically repeated */
-            "protect":    false,        /* whether schedule should be protected from double scheduling */
-            "obj":        null,         /* function context object ("this") */
-            "func":       function(){}, /* function to call */
-            "args":       []            /* function arguments to pass */
-        };
+    /*  object constructor  */
+    $.scheduler = function () {
+        this.bucket = {};
+        return;
+    };
 
-        /*  helper function for portable checking whether something is a function  */
-	    var isfn = function (fn) {
-            return (
-                   !!fn
-                && typeof fn != "string"
-                && typeof fn[0] == "undefined"
-                && RegExp("function", "i").test(fn + "")
-            );
-	    };
+    /*  object methods  */
+    $.scheduler.prototype = {
+        /*  schedule a task  */
+        schedule: function () {
+            /*  schedule context with default parameters */
+            var ctx = {
+                "id":         null,         /* unique identifier of high-level schedule */
+                "time":       1000,         /* time in milliseconds after which the task is run */
+                "repeat":     false,        /* whether schedule should be automatically repeated */
+                "protect":    false,        /* whether schedule should be protected from double scheduling */
+                "obj":        null,         /* function context object ("this") */
+                "func":       function(){}, /* function to call */
+                "args":       []            /* function arguments to pass */
+            };
 
-        /*  parse arguments into context parameters (part 1/2):
-            support the flexible way of an associated array */
-        var i = 0;
-        if (typeof arguments[i] == "object") {
-            for (var option in arguments[i])
-                if (   typeof ctx[option] != "undefined"
-                    && option.substr(0, 1) != "_")
-                    ctx[option] = arguments[i][option];
-            i++;
-        }
+            /*  helper function: portable checking whether something is a function  */
+            function _isfn (fn) {
+                return (
+                       !!fn
+                    && typeof fn != "string"
+                    && typeof fn[0] == "undefined"
+                    && RegExp("function", "i").test(fn + "")
+                );
+            };
+            
+            /*  parse arguments into context parameters (part 1/4):
+                detect an override object (special case to support jQuery method) */
+            var i = 0;
+            var override = false;
+            if (typeof arguments[i] == "object" && arguments.length > 1) {
+                override = true;
+                i++;
+            }
 
-        /*  parse arguments into context parameters (part 2/2):
-            support: schedule([time [, repeat], ]{{obj, methodname} | func}[, arg, ...]); */
-        if (typeof arguments[i] == "number")
-            ctx["time"] = arguments[i++];
-        if (typeof arguments[i] == "boolean")
-            ctx["repeat"] = arguments[i++];
-        if (typeof arguments[i] == "boolean")
-            ctx["protect"] = arguments[i++];
-        if (   typeof arguments[i] == "object"
-            && typeof arguments[i+1] == "string"
-            && isfn(arguments[i][arguments[i+1]])) {
-            ctx["obj"] = arguments[i++];
-            ctx["func"] = arguments[i++];
-        }
-        else if (typeof arguments[i] != "undefined")
-            ctx["func"] = arguments[i++];
-        while (typeof arguments[i] != "undefined")
-            ctx["args"].push(arguments[i++]);
+            /*  parse arguments into context parameters (part 2/4):
+                support the flexible way of an associated array */
+            if (typeof arguments[i] == "object") {
+                for (var option in arguments[i])
+                    if (typeof ctx[option] != "undefined")
+                        ctx[option] = arguments[i][option];
+                i++;
+            }
 
-        /*  determine time value in milliseconds */
-        var match = String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));
-        if (match && match[0] != "undefined" && match[1] != "undefined")
-            ctx["time"] = String(parseInt(match[1]) *
-                { s: 1000, m: 1000*60, h: 1000*60*60,
-                  d: 1000*60*60*24, w: 1000*60*60*24*7 }[match[2]]);
+            /*  parse arguments into context parameters (part 3/4):
+                support: schedule([time [, repeat], ]{{obj, methodname} | func}[, arg, ...]); */
+            if (   typeof arguments[i] == "number"
+                || (   typeof arguments[i] == "string" 
+                    && arguments[i].match(RegExp("^[0-9]+[smhdw]$"))))
+                ctx["time"] = arguments[i++];
+            if (typeof arguments[i] == "boolean")
+                ctx["repeat"] = arguments[i++];
+            if (typeof arguments[i] == "boolean")
+                ctx["protect"] = arguments[i++];
+            if (   typeof arguments[i] == "object"
+                && typeof arguments[i+1] == "string"
+                && _isfn(arguments[i][arguments[i+1]])) {
+                ctx["obj"] = arguments[i++];
+                ctx["func"] = arguments[i++];
+            }
+            else if (   typeof arguments[i] != "undefined"
+                     && (   _isfn(arguments[i]) 
+                         || typeof arguments[i] == "string"))
+                ctx["func"] = arguments[i++];
+            while (typeof arguments[i] != "undefined")
+                ctx["args"].push(arguments[i++]);
 
-        /*  determine unique identifier of task  */
-        if (ctx["id"] == null)
-            ctx["id"] = (  String(ctx["repeat"])  + ":"
-                         + String(ctx["protect"]) + ":"
-                         + String(ctx["time"])    + ":"
-                         + String(ctx["obj"])     + ":"
-                         + String(ctx["func"])    + ":"
-                         + String(ctx["args"])         );
+            /*  parse arguments into context parameters (part 4/4):
+                apply parameters from override object */
+            if (override) {
+                if (typeof arguments[1] == "object") {
+                    for (var option in arguments[0])
+                        if (   typeof ctx[option] != "undefined"
+                            && typeof arguments[1][option] == "undefined")
+                            ctx[option] = arguments[0][option];
+                }
+                else {
+                    for (var option in arguments[0])
+                        if (typeof ctx[option] != "undefined")
+                            ctx[option] = arguments[0][option];
+                }
+                i++;
+            }
 
-        /*  optionally protect from duplicate calls  */
-        if (ctx["protect"])
-            if (typeof this.bucket[ctx["id"]] != "undefined")
-                return this.bucket[ctx["id"]];
+            /*  annotate context with internals */
+            ctx["_scheduler"] = this; /* internal: back-reference to scheduler object */
+            ctx["_handle"]    = null; /* internal: unique handle of low-level task */
 
-        /*  support execution of methods by name and arbitrary scripts  */
-        if (!isfn(ctx["func"])) {
-            if (   ctx["obj"] != null
-                && typeof ctx["obj"] == "object"
-	            && typeof ctx["func"] == "string"
-                && isfn(ctx["obj"][ctx["func"]]))
-                /*  method by name  */
-                ctx["func"] = ctx["obj"][ctx["func"]];
-            else
-                /*  arbitrary script  */
-                ctx["func"] = eval("function () { " + ctx["func"] + " }");
-        }
+            /*  determine time value in milliseconds */
+            var match = String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));
+            if (match && match[0] != "undefined" && match[1] != "undefined")
+                ctx["time"] = String(parseInt(match[1]) *
+                    { s: 1000, m: 1000*60, h: 1000*60*60,
+                      d: 1000*60*60*24, w: 1000*60*60*24*7 }[match[2]]);
 
-        /*  pass-through to internal scheduling operation  */
-        ctx["_handle"] = this._schedule(ctx);
+            /*  determine unique identifier of task  */
+            if (ctx["id"] == null)
+                ctx["id"] = (  String(ctx["repeat"])  + ":"
+                             + String(ctx["protect"]) + ":"
+                             + String(ctx["time"])    + ":"
+                             + String(ctx["obj"])     + ":"
+                             + String(ctx["func"])    + ":"
+                             + String(ctx["args"])         );
 
-        /*  store context into bucket of scheduler object  */
-        this.bucket[ctx["id"]] = ctx;
+            /*  optionally protect from duplicate calls  */
+            if (ctx["protect"])
+                if (typeof this.bucket[ctx["id"]] != "undefined")
+                    return this.bucket[ctx["id"]];
 
-        /*  return context  */
-        return ctx;
-    },
+            /*  support execution of methods by name and arbitrary scripts  */
+            if (!_isfn(ctx["func"])) {
+                if (   ctx["obj"] != null
+                    && typeof ctx["obj"] == "object"
+                    && typeof ctx["func"] == "string"
+                    && _isfn(ctx["obj"][ctx["func"]]))
+                    /*  method by name  */
+                    ctx["func"] = ctx["obj"][ctx["func"]];
+                else
+                    /*  arbitrary script  */
+                    ctx["func"] = eval("function () { " + ctx["func"] + " }");
+            }
 
-    /*  re-schedule a task  */
-    reschedule: function (ctx) {
-        if (typeof ctx == "string")
-            ctx = this.bucket[ctx];
+            /*  pass-through to internal scheduling operation  */
+            ctx["_handle"] = this._schedule(ctx);
 
-        /*  pass-through to internal scheduling operation  */
-        ctx["_handle"] = this._schedule(ctx);
+            /*  store context into bucket of scheduler object  */
+            this.bucket[ctx["id"]] = ctx;
 
-        /*  return context  */
-        return ctx;
-    },
+            /*  return context  */
+            return ctx;
+        },
 
-    /*  internal scheduling operation  */
-    _schedule: function (ctx) {
-        /*  closure to act as the call trampoline function  */
-        var trampoline = function () {
-            /*  jump into function  */
-            var obj = (ctx["obj"] != null ? ctx["obj"] : ctx);
-            (ctx["func"]).apply(obj, ctx["args"]);
+        /*  re-schedule a task  */
+        reschedule: function (ctx) {
+            if (typeof ctx == "string")
+                ctx = this.bucket[ctx];
 
-            /*  either repeat scheduling and keep in bucket or
-                just stop scheduling and delete from scheduler bucket  */
-            if (   /* not cancelled from inside... */
-                   typeof (ctx["_scheduler"]).bucket[ctx["id"]] != "undefined"
-                && /* ...and repeating requested */
-                   ctx["repeat"])
-                (ctx["_scheduler"])._schedule(ctx);
-            else
-                delete (ctx["_scheduler"]).bucket[ctx["id"]];
-        }
+            /*  pass-through to internal scheduling operation  */
+            ctx["_handle"] = this._schedule(ctx);
 
-        /*  schedule task and return handle  */
-        return setTimeout(trampoline, ctx["time"]);
-    },
+            /*  return context  */
+            return ctx;
+        },
 
-    /*  cancel a scheduled task  */
-    cancel: function (ctx) {
-        if (typeof ctx == "string")
-            ctx = this.bucket[ctx];
+        /*  internal scheduling operation  */
+        _schedule: function (ctx) {
+            /*  closure to act as the call trampoline function  */
+            var trampoline = function () {
+                /*  jump into function  */
+                var obj = (ctx["obj"] != null ? ctx["obj"] : ctx);
+                (ctx["func"]).apply(obj, ctx["args"]);
 
-        /*  cancel scheduled task  */
-        if (typeof ctx == "object") {
-            clearTimeout(ctx["_handle"]);
-            delete this.bucket[ctx["id"]];
-        }
-    }
-};
+                /*  either repeat scheduling and keep in bucket or
+                    just stop scheduling and delete from scheduler bucket  */
+                if (   /* not cancelled from inside... */
+                       typeof (ctx["_scheduler"]).bucket[ctx["id"]] != "undefined"
+                    && /* ...and repeating requested */
+                       ctx["repeat"])
+                    (ctx["_scheduler"])._schedule(ctx);
+                else
+                    delete (ctx["_scheduler"]).bucket[ctx["id"]];
+            }
 
-/* integrate a global instance of the scheduler into the global jQuery object */
-jQuery.extend({
-    scheduler$: new jQuery.scheduler(),
-	schedule:   function () { return jQuery.scheduler$.schedule.apply  (jQuery.scheduler$, arguments) },
-	reschedule: function () { return jQuery.scheduler$.reschedule.apply(jQuery.scheduler$, arguments) },
-	cancel:     function () { return jQuery.scheduler$.cancel.apply    (jQuery.scheduler$, arguments) }
-});
+            /*  schedule task and return handle  */
+            return setTimeout(trampoline, ctx["time"]);
+        },
 
-/* integrate scheduling convinience method into all jQuery objects */
-jQuery.fn.extend({
-	schedule: function () {
-        var a = arguments;
-		return this.each(function () {
-            if (typeof a[0] == "object") {
-                if (typeof a[0].id == "undefined")
-                    a[0].id = this;
-                if (typeof a[0].obj == "undefined")
-                    a[0].obj = this;
-                return jQuery.schedule(a[0]);
+        /*  cancel a scheduled task  */
+        cancel: function (ctx) {
+            if (typeof ctx == "string")
+                ctx = this.bucket[ctx];
+
+            /*  cancel scheduled task  */
+            if (typeof ctx == "object") {
+                clearTimeout(ctx["_handle"]);
+                delete this.bucket[ctx["id"]];
             }
-            else {
-                var time = a[0];
-                var func = a[1];
-                var args = [];
-                for (var i = 2; i < a.length; i++)
-                    args.push(a[i]);
-                return jQuery.schedule({
-                    id:      this,
-                    repeat:  false,
-                    protect: false,
-                    time:    time,
-                    obj:     this,
-                    func:    func,
-                    args:    args
-                });
-           }
-		});
-	}
-});
+        }
+    };
 
+    /* integrate a global instance of the scheduler into the global jQuery object */
+    $.extend({
+        scheduler$: new $.scheduler(),
+        schedule:   function () { return $.scheduler$.schedule.apply  ($.scheduler$, arguments) },
+        reschedule: function () { return $.scheduler$.reschedule.apply($.scheduler$, arguments) },
+        cancel:     function () { return $.scheduler$.cancel.apply    ($.scheduler$, arguments) }
+    });
+
+    /* integrate scheduling convinience method into all jQuery objects */
+    $.fn.extend({
+        schedule: function () {
+            var a = [ {} ];
+            for (var i = 0; i < arguments.length; i++)
+                a.push(arguments[i]);
+            return this.each(function () {
+                a[0] = { "id": this, "obj": this };
+                return $.schedule.apply($, a);
+            });
+        }
+    });
+
+})(jQuery);
+