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: |
|
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);
+