Commits

Anonymous committed f10812d

transplanted tests from trunk and modules from trunk r 1561

Comments (0)

Files changed (33)

MochiKit/Async.js

     this.canceller = canceller;
     this.silentlyCancelled = false;
     this.chained = false;
+    this.finalized = false;
 };
 
 MochiKit.Async.Deferred.prototype = {
         ***/
         this.fired = ((res instanceof Error) ? 1 : 0);
         this.results[this.fired] = res;
-        this._fire();
+        if (this.paused === 0) {
+            this._fire();
+        }
     },
 
     _check: function () {
         if (this.chained) {
             throw new Error("Chained Deferreds can not be re-used");
         }
+        if (this.finalized) {
+            throw new Error("Finalized Deferreds can not be re-used");
+        }
         this.chain.push([cb, eb]);
         if (this.fired >= 0) {
             this._fire();
         return this;
     },
 
+    /** @id MochiKit.Async.Deferred.prototype.setFinalizer */
+    setFinalizer: function (fn) {
+        if (this.chained) {
+            throw new Error("Chained Deferreds can not be re-used");
+        }
+        if (this.finalized) {
+            throw new Error("Finalized Deferreds can not be re-used");
+        }
+        if (arguments.length > 1) {
+            fn = MochiKit.Base.partial.apply(null, arguments);
+        }
+        this._finalizer = fn;
+        if (this.fired >= 0) {
+            this._fire();
+        }
+        return this;
+    },
+
     _fire: function () {
         /***
 
                 fired = ((res instanceof Error) ? 1 : 0);
                 if (res instanceof MochiKit.Async.Deferred) {
                     cb = function (res) {
+                        self.paused--;
                         self._resback(res);
-                        self.paused--;
-                        if ((self.paused === 0) && (self.fired >= 0)) {
-                            self._fire();
-                        }
                     };
                     this.paused++;
                 }
         }
         this.fired = fired;
         this.results[fired] = res;
+        if (this.chain.length == 0 && this.paused === 0 && this._finalizer) {
+            this.finalized = true;
+            this._finalizer(res);
+        }
         if (cb && this.paused) {
             // this is for "tail recursion" in case the dependent deferred
             // is already fired
     /** @id MochiKit.Async.wait */
     wait: function (seconds, /* optional */value) {
         var d = new MochiKit.Async.Deferred();
-        var m = MochiKit.Base;
-        if (typeof(value) != 'undefined') {
-            d.addCallback(function () { return value; });
-        }
-        var timeout = setTimeout(
-            m.bind("callback", d),
-            Math.floor(seconds * 1000));
+        var cb = MochiKit.Base.bind("callback", d, value);
+        var timeout = setTimeout(cb, Math.floor(seconds * 1000));
         d.canceller = function () {
             try {
                 clearTimeout(timeout);
             }
             return MochiKit.Base.reprRegistry.match(o);
         } catch (e) {
-            if (typeof(o.NAME) == 'string' && (
-                    o.toString == Function.prototype.toString ||
-                    o.toString == Object.prototype.toString
-                )) {
-                return o.NAME;
+            try {
+                if (typeof(o.NAME) == 'string' && (
+                        o.toString == Function.prototype.toString ||
+                        o.toString == Object.prototype.toString
+                    )) {
+                    return o.NAME;
+                }
+            } catch (ignore) {
             }
         }
         try {
 
 
     /** @id MochiKit.Base.evalJSON */
-    evalJSON: function () {
-        return eval("(" + MochiKit.Base._filterJSON(arguments[0]) + ")");
+    evalJSON: function (jsonText) {
+        return eval("(" + MochiKit.Base._filterJSON(jsonText) + ")");
     },
 
     _filterJSON: function (s) {
         var m = s.match(/^\s*\/\*(.*)\*\/\s*$/);
-        if (m) {
-            return m[1];
-        }
-        return s;
+        return (m) ? m[1] : s;
     },
 
     /** @id MochiKit.Base.serializeJSON */
  * @param {String} version the first version when the source function
  *            was deprecated (e.g. '1.4')
  * @param {Boolean} [exportable] the exportable function flag,
- *            defaults to true
+ *            defaults to false
  */
 MochiKit.Base._deprecated = function (module, name, target, version, exportable) {
     if (typeof(module) === 'string') {
         }
         return MochiKit[targetModule][targetName].apply(this, arguments);
     };
-    if (exportable === false) {
-        func.__export__ = false;
-    }
+    func.__export__ = (exportable === true);
     module[name] = func;
 }
 
     m.noop = m.operator.identity;
 
     // Backwards compat
-    m._deprecated(m, 'forward', 'MochiKit.Base.forwardCall', '1.3', false);
-    m._deprecated(m, 'find', 'MochiKit.Base.findValue', '1.3', false);
+    m._deprecated(m, 'forward', 'MochiKit.Base.forwardCall', '1.3');
+    m._deprecated(m, 'find', 'MochiKit.Base.findValue', '1.3');
 
     if (typeof(encodeURIComponent) != "undefined") {
         /** @id MochiKit.Base.urlEncode */

MochiKit/Color.js

 
     /** @id MochiKit.Color.Color.prototype.isLight */
     isLight: function () {
-        return this.asHSL().b > 0.5;
+        return this.asHSL().l > 0.5;
     },
 
     /** @id MochiKit.Color.Color.prototype.isDark */
             yellow: [1, 1, 0]
         };
 
-        var makeColor = function (name, r, g, b, a) {
-            var rval = this.fromRGB(r, g, b, a);
-            this[name] = function () { return rval; };
-            return rval;
-        };
-
         for (var k in colors) {
             var name = k + "Color";
-            var bindArgs = m.concat(
-                [makeColor, this.Color, name],
-                colors[k]
-            );
-            this.Color[name] = m.bind.apply(null, bindArgs);
+            var value = this.Color.fromRGB.apply(this.Color, colors[k]);
+            this.Color[name] = m.partial(m.operator.identity, value);
         }
 
         var isColor = function () {
                 "for": "htmlFor",
                 "readonly": "readOnly",
                 "colspan": "colSpan",
+                "rowspan": "rowSpan",
                 "bgcolor": "bgColor",
                 "cellspacing": "cellSpacing",
                 "cellpadding": "cellPadding"
 
         // Backwards compatibility aliases
         /** @id MochiKit.DOM.computedStyle  */
-        m._deprecated(this, 'computedStyle', 'MochiKit.Style.getStyle', '1.4');
+        m._deprecated(this, 'computedStyle', 'MochiKit.Style.getStyle', '1.4', true);
         /** @id MochiKit.DOM.elementDimensions  */
         m._deprecated(this, 'elementDimensions', 'MochiKit.Style.getElementDimensions', '1.4');
         /** @id MochiKit.DOM.elementPosition  */

MochiKit/DragAndDrop.js

                                          this.options.selectclass);
         }
         if (this.options.zindex) {
-            this.originalZ = parseInt(MochiKit.Style.getStyle(this.element,
-                                      'z-index') || '0');
+            this.originalZ = MochiKit.Style.getStyle(this.element, 'z-index');
             this.element.style.zIndex = this.options.zindex;
         }
 

MochiKit/Logging.js

         }
         var messages = this.getMessages(howMany);
         if (messages.length) {
-            var lst = map(function (m) {
+            var lst = MochiKit.Base.map(function (m) {
                 return '\n  [' + m.num + '] ' + m.level + ': ' + m.info.join(' ');
             }, messages);
             lst.unshift('LAST ' + messages.length + ' MESSAGES:');

MochiKit/Signal.js

 
         if (this.type() && (
             this.type().indexOf('mouse') === 0 ||
+            this.type().indexOf('drag') === 0 ||
             this.type().indexOf('click') != -1 ||
             this.type() == 'contextmenu')) {
 
                 var o = observers[i];
                 if (o.source === src && o.signal === sig && o.objOrFunc === obj && o.funcOrStr === func) {
                     self._disconnect(o);
-                    if (!self._lock) {
+                    if (self._lock === 0) {
                         observers.splice(i, 1);
                     } else {
                         self._dirty = true;
             var idx = m.findIdentical(observers, ident);
             if (idx >= 0) {
                 self._disconnect(ident);
-                if (!self._lock) {
+                if (self._lock === 0) {
                     observers.splice(idx, 1);
                 } else {
                     self._dirty = true;
         var self = MochiKit.Signal;
         var observers = self._observers;
         var disconnect = self._disconnect;
-        var locked = self._lock;
+        var lock = self._lock;
         var dirty = self._dirty;
         if (typeof(funcOrStr) === 'undefined') {
             funcOrStr = null;
             if (ident.objOrFunc === objOrFunc &&
                     (funcOrStr === null || ident.funcOrStr === funcOrStr)) {
                 disconnect(ident);
-                if (locked) {
+                if (lock === 0) {
+                    observers.splice(i, 1);
+                } else {
                     dirty = true;
-                } else {
-                    observers.splice(i, 1);
                 }
             }
         }
         var disconnect = self._disconnect;
         var observers = self._observers;
         var i, ident;
-        var locked = self._lock;
+        var lock = self._lock;
         var dirty = self._dirty;
         if (signals.length === 0) {
             // disconnect all
                 ident = observers[i];
                 if (ident.source === src) {
                     disconnect(ident);
-                    if (!locked) {
+                    if (lock === 0) {
                         observers.splice(i, 1);
                     } else {
                         dirty = true;
                 ident = observers[i];
                 if (ident.source === src && ident.signal in sigs) {
                     disconnect(ident);
-                    if (!locked) {
+                    if (lock === 0) {
                         observers.splice(i, 1);
                     } else {
                         dirty = true;
         }
         var args = MochiKit.Base.extend(null, arguments, 2);
         var errors = [];
-        self._lock = true;
+        self._lock++;
         for (var i = 0; i < observers.length; i++) {
             var ident = observers[i];
             if (ident.source === src && ident.signal === sig &&
                 }
             }
         }
-        self._lock = false;
-        if (self._dirty) {
+        self._lock--;
+        if (self._lock === 0 && self._dirty) {
             self._dirty = false;
             for (var i = observers.length - 1; i >= 0; i--) {
                 if (!observers[i].connected) {
     var m = MochiKit.Base;
     this._document = document;
     this._window = win;
-    this._lock = false;
+    this._lock = 0;
     this._dirty = false;
 
     try {

MochiKit/Style.js

         }
 
         // Backwards compatibility aliases
-        m._deprecated(this, 'elementPosition', 'MochiKit.Style.getElementPosition', '1.3');
-        m._deprecated(this, 'elementDimensions', 'MochiKit.Style.getElementDimensions', '1.3');
+        m._deprecated(this, 'elementPosition', 'MochiKit.Style.getElementPosition', '1.3', true);
+        m._deprecated(this, 'elementDimensions', 'MochiKit.Style.getElementDimensions', '1.3', true);
 
         this.hideElement = m.partial(this.setDisplayForElement, 'none');
         // TODO: showElement could be improved by using getDefaultDisplay.
 }
 
 /**
- * Splits a text string, applies a function and joins the results
- * back together again. This is a convenience function for calling
- * split(), map() and join() separately. It can be used to easily
- * trim each line in a text string (using the strip function), or to
- * translate a text word-by-word.
+ * Splits a text string using separator as the split point
+ * If max is given, at most max splits are done, giving at most
+ * max + 1 elements in the returned list.
  *
- * @param {Function} func the function to apply
  * @param {String} str the string to split
  * @param {String} [separator] the separator character to use,
  *            defaults to newline
- *
- * @return {String} a string with the joined up results
+ * @param {Int} [max] the maximum number of parts to return
+ * @return {Array} an array of parts of the string
  */
-MochiKit.Text.splitJoin = function (func, str, separator) {
+MochiKit.Text.split = function (str, separator, max) {
     if (str == null || str.length == 0) {
         return str;
     }
     separator = separator || '\n'
-    return MochiKit.Base.map(func, str.split(separator)).join(separator);
+    var bits = str.split(separator);
+    if ((typeof(max) == "undefined") || max >= bits.length-1) {
+        return bits;
+    }
+    bits.splice(max, bits.length, bits.slice(max, bits.length).join(separator))
+    return bits;
+}
+
+/**
+ * Splits a text string using separator as the split point
+ * If max is given, at most max splits are done,
+ * using splits from the right
+ *
+ * @param {String} str the string to split
+ * @param {String} [separator] the separator character to use,
+ *            defaults to newline
+ * @param {Int} [max] the maximum number of parts to return
+ * @return {Array} an array of parts of the string
+ */
+MochiKit.Text.rsplit = function (str, separator, max) {
+    if (str == null || str.length == 0) {
+        return str;
+    }
+    separator = separator || '\n'
+    var bits = str.split(separator);
+    if ((typeof(max) == "undefined") || max >= bits.length-1){
+	return bits;
+    }
+    bits.splice(0, bits.length-max, bits.slice(0, bits.length-max).join(separator))
+    return bits;
 }
 
 /**
  *            LOCALE.en_US
  *
  * @return {String} the formatted output string
+ *
+ * @throws FormatPatternError if the format pattern was invalid
  */
 MochiKit.Text.formatValue = function (spec, value, locale) {
     var self = MochiKit.Text;
     var pos = text.indexOf(":");
     if (pos == 0) {
         info = self._parseFormatFlags(pattern, startPos + 1, endPos);
-        info.path = [0];
+        info.path = [];
     } else if (pos > 0) {
         info = self._parseFormatFlags(pattern, startPos + pos + 1, endPos);
         info.path = text.substring(0, pos).split(".");
     var DIGITS = /^\d+$/;
     for (var i = 0; i < info.path.length; i++) {
         var e = info.path[i];
-        if (typeof(e) == "string") {
-            // TODO: replace with MochiKit.Format.strip?
-            e = e.replace(/^\s+/, "").replace(/\s+$/, "");
-            if (e == "" && info.path.length == 1) {
-                e = 0;
-            } else if (e == "") {
-                var msg = "format value path contains blanks";
-                throw new self.FormatPatternError(pattern, startPos, msg);
-            } else if (DIGITS.test(e)) {
-                e = parseInt(e);
-            }
+        // TODO: replace with MochiKit.Format.strip?
+        e = e.replace(/^\s+/, "").replace(/\s+$/, "");
+        if (e == "" && info.path.length == 1) {
+            e = 0;
+        } else if (e == "") {
+            var msg = "format value path contains blanks";
+            throw new self.FormatPatternError(pattern, startPos, msg);
+        } else if (DIGITS.test(e)) {
+            e = parseInt(e);
         }
         info.path[i] = e;
     }
  * @throws FormatPatternError if the format pattern was invalid
  */
 MochiKit.Text._parseFormatFlags = function (pattern, startPos, endPos) {
-    var self = MochiKit.Text;
+    var update = MochiKit.Base.update;
     var info = { numeric: false, format: "s", width: 0, precision: -1,
                  align: ">", sign: "-", padding: " ", grouping: false };
     // TODO: replace with MochiKit.Format.rstrip?
     var flags = pattern.substring(startPos, endPos).replace(/\s+$/, "");
     while (flags.length > 0) {
-        switch (flags.charAt(0)) {
+        var chr = flags.charAt(0);
+        var nextPos = 1;
+        switch (chr) {
         case ">":
         case "<":
-            info.align = flags.charAt(0);
-            flags = flags.substring(1);
+            update(info, { align: chr });
             break;
         case "+":
         case "-":
         case " ":
-            info.sign = flags.charAt(0);
-            flags = flags.substring(1);
+            update(info, { sign: chr });
             break;
         case ",":
-            info.grouping = true;
-            flags = flags.substring(1);
+            update(info, { grouping: true });
             break;
         case ".":
             var chars = /^\d*/.exec(flags.substring(1))[0];
-            info.precision = parseInt(chars);
-            flags = flags.substring(1 + chars.length);
+            update(info, { precision: parseInt(chars) });
+            nextPos = 1 + chars.length;
             break;
         case "0":
-            info.padding = flags.charAt(0);
-            flags = flags.substring(1);
+            update(info, { padding: chr });
             break;
         case "1":
         case "2":
         case "8":
         case "9":
             var chars = /^\d*/.exec(flags)[0];
-            info.width = parseInt(chars);
-            flags = flags.substring(chars.length);
+            update(info, { width: parseInt(chars) });
+            nextPos = chars.length;
             break;
         case "s":
         case "r":
-            info.format = flags.charAt(0);
-            flags = flags.substring(1);
+            update(info, { format: chr });
             break;
         case "b":
-        case "d":
+            update(info, { numeric: true, format: chr, radix: 2 });
+            break;
         case "o":
+            update(info, { numeric: true, format: chr, radix: 8 });
+            break;
         case "x":
         case "X":
+            update(info, { numeric: true, format: chr, radix: 16 });
+            break;
+        case "d":
         case "f":
         case "%":
-            info.numeric = true;
-            info.format = flags.charAt(0);
-            info.radix = 10;
-            if (info.format === "b") {
-                info.radix = 2;
-            } else if (info.format === "o") {
-                info.radix = 8;
-            } else if (info.format === "x" || info.format === "X") {
-                info.radix = 16;
-            }
-            flags = flags.substring(1);
+            update(info, { numeric: true, format: chr, radix: 10 });
             break;
         default:
-            var msg = "unsupported format flag: " + flags.charAt(0);
-            throw new self.FormatPatternError(pattern, startPos, msg);
+            var msg = "unsupported format flag: " + chr;
+            throw new MochiKit.Text.FormatPatternError(pattern, startPos, msg);
         }
+        flags = flags.substring(nextPos);
     }
     return info;
 }
  * @param {Number} precision the number of precision digits
  */
 MochiKit.Text._truncToPercent = function (value, precision) {
-    // TODO: This can be simplified by using the same helper function
-    //       as roundToFixed now does.
+    // TODO: This can be simplified by using MochiKit.Format._shiftNumber
+    //       as roundToFixed does.
     var str;
     if (precision >= 0) {
         str = MochiKit.Format.roundToFixed(value, precision + 2);
     } else {
         str = (value == null) ? "0" : value.toString();
     }
-    var fracPos = str.indexOf(".");
-    if (fracPos < 0) {
-        str = str + "00";
-    } else if (fracPos + 3 >= str.length) {
-        var fraction = str.substring(fracPos + 1);
-        while (fraction.length < 2) {
-            fraction = fraction + "0";
-        }
-        str = str.substring(0, fracPos) + fraction;
-    } else {
-        var fraction = str.substring(fracPos + 1);
-        str = str.substring(0, fracPos) + fraction.substring(0, 2) +
-              "." + fraction.substring(2);
+    var arr = MochiKit.Text.split(str, ".", 2);
+    var frac = MochiKit.Text.padRight(arr[1], 2, "0");
+    var whole = arr[0] + frac.substring(0, 2);
+    frac = frac.substring(2);
+    while (/^0[0-9]/.test(whole)) {
+        whole = whole.substring(1);
     }
-    while (str.length > 1 && str.charAt(0) == "0" && str.charAt(1) != ".") {
-        str = str.substring(1);
-    }
-    return str;
+    return (frac.length <= 0) ? whole : whole + "." + frac;
 }
 
 /**

MochiKit/Visual.js

    return pos * pos;
 };
 
+/** @id MochiKit.Visual.Transitions.spring */
+MochiKit.Visual.Transitions.spring = function (pos) {
+   return 1 - (Math.cos(pos * 2.5 * Math.PI) * Math.exp(-pos * 6));
+};
+
 /** @id MochiKit.Visual.Transitions.none */
 MochiKit.Visual.Transitions.none = function (pos) {
     return 0;
                     e.finalize();
                 }, this.effects);
                 break;
+            case 'replace':
+                ma(function (e) {
+                    e.cancel();
+                }, this.effects);
+                break;
         }
 
         effect.startOn += timestamp;
             this.event('afterSetup');
         }
         if (this.state == 'running') {
-            if (this.options.transition) {
-                pos = this.options.transition(pos);
+            var trans = this.options.transition;
+            if (typeof(trans) == "string") {
+                trans = MochiKit.Visual.Transitions[trans];
+            }
+            if (typeof(trans) == "function") {
+                pos = trans(pos);
             }
             pos *= (this.options.to - this.options.from);
             pos += this.options.from;
 };
 
 
-/* end of Rico adaptation */
-
-MochiKit.Visual.__new__ = function () {
-    var m = MochiKit.Base;
-
-    // Backwards compatibility aliases
-    m._deprecated(this, 'Color', 'MochiKit.Color.Color', '1.1');
-    m._deprecated(this, 'getElementsComputedStyle', 'MochiKit.Style.getStyle', '1.1');
-
-    m.nameFunctions(this);
-};
-
-MochiKit.Visual.__new__();
-
+MochiKit.Base.nameFunctions(MochiKit.Visual);
 MochiKit.Base._exportSymbols(this, MochiKit.Visual);