web/data/cubicweb.compat.js
changeset 5658 7b9553a9db65
parent 5186 f3c2cb460ad9
child 5698 5c8fa1650299
--- a/web/data/cubicweb.compat.js	Thu Jun 03 10:17:44 2010 +0200
+++ b/web/data/cubicweb.compat.js	Thu Jun 03 14:51:42 2010 +0200
@@ -1,546 +1,201 @@
-/* MochiKit -> jQuery compatibility module */
-
-function forEach(array, func) {
-    for (var i=0, length=array.length; i<length; i++) {
-	func(array[i]);
-    }
-}
-
-// XXX looks completely unused (candidate for removal)
-function getElementsByTagAndClassName(tag, klass, root) {
-    root = root || document;
-    // FIXME root is not used in this compat implementation
-    return jQuery(tag + '.' + klass);
-}
-
-/* jQUery flattens arrays returned by the mapping function:
-   >>> y = ['a:b:c', 'd:e']
-   >>> jQuery.map(y, function(y) { return y.split(':');})
-   ["a", "b", "c", "d", "e"]
-   // where one would expect:
-   [ ["a", "b", "c"], ["d", "e"] ]
-   XXX why not the same argument order as $.map and forEach ?
-*/
-function map(func, array) {
-    var result = [];
-    for (var i=0, length=array.length;
-         i<length;
-         i++) {
-	result.push(func(array[i]));
-    }
-    return result;
-}
-
-function findValue(array, element) {
-    return jQuery.inArray(element, array);
-}
-
-function filter(func, array) {
-    return jQuery.grep(array, func);
-}
-
-function noop() {}
-
-function addElementClass(node, klass) {
-    jQuery(node).addClass(klass);
-}
-
-// XXX looks completely unused (candidate for removal)
-function toggleElementClass(node, klass) {
-    jQuery(node).toggleClass(klass);
-}
-
-function removeElementClass(node, klass) {
-    jQuery(node).removeClass(klass);
-}
-
-hasElementClass = jQuery.className.has;
+cw.utils.movedToNamespace(['log', 'jqNode', 'getNode', 'evalJSON', 'urlEncode',
+                           'swapDOM'], cw);
+cw.utils.movedToNamespace(['nodeWalkDepthFirst', 'formContents', 'isArray',
+                           'isString', 'isArrayLike', 'sliceList',
+                           'toISOTimestamp'], cw.utils);
 
 
-function partial(func) {
-    var args = sliceList(arguments, 1);
-    return function() {
-	return func.apply(null, merge(args, arguments));
-    };
-}
-
-
-function log() {
-    // XXX dummy implementation
-    // console.log.apply(arguments); ???
-    var args = [];
-    for (var i=0; i<arguments.length; i++) {
-	args.push(arguments[i]);
-    }
-    if (typeof(window) != "undefined" && window.console
-        && window.console.log) {
-	window.console.log(args.join(' '));
-    }
-}
-
-function getNodeAttribute(node, attribute) {
-    return jQuery(node).attr(attribute);
-}
-
-function isArray(it){ // taken from dojo
-    return it && (it instanceof Array || typeof it == "array");
-}
-
-function isString(it){ // taken from dojo
-    return !!arguments.length && it != null && (typeof it == "string" || it instanceof String);
-}
-
-
-function isArrayLike(it) { // taken from dojo
-    return (it && it !== undefined &&
-	    // keep out built-in constructors (Number, String, ...) which have length
-	    // properties
-	    !isString(it) && !jQuery.isFunction(it) &&
-	    !(it.tagName && it.tagName.toLowerCase() == 'form') &&
-	    (isArray(it) || isFinite(it.length)));
-}
-
-
-function getNode(node) {
-    if (typeof(node) == 'string') {
-        return document.getElementById(node);
-    }
-    return node;
-}
-
-/* safe version of jQuery('#nodeid') because we use ':' in nodeids
- * which messes with jQuery selection mechanism
- */
-function jqNode(node) {
-    node = getNode(node);
-    if (node) {
-	return jQuery(node);
-    }
-    return null;
-}
-
-function evalJSON(json) { // trust source
-    return eval("(" + json + ")");
-}
-
-function urlEncode(str) {
-    if (typeof(encodeURIComponent) != "undefined") {
-        return encodeURIComponent(str).replace(/\'/g, '%27');
-    } else {
-        return escape(str).replace(/\+/g, '%2B').replace(/\"/g,'%22').rval.replace(/\'/g, '%27');
-    }
+if ($.noop === undefined) {
+    function noop() {}
+} else {
+    noop = cw.utils.deprecatedFunction(
+        '[3.9] noop() is deprecated, use $.noop() instead (XXX requires jQuery 1.4)',
+        $.noop);
 }
 
-function swapDOM(dest, src) {
-    dest = getNode(dest);
-    var parent = dest.parentNode;
-    if (src) {
-        src = getNode(src);
-        parent.replaceChild(src, dest);
-    } else {
-        parent.removeChild(dest);
+// ========== ARRAY EXTENSIONS ========== ///
+Array.prototype.contains = cw.utils.deprecatedFunction(
+    '[3.9] array.contains(elt) is deprecated, use $.inArray(elt, array) instead',
+    function(element) {
+        return jQuery.inArray(element, this) != - 1;
     }
-    return src;
-}
+);
 
-function replaceChildNodes(node/*, nodes...*/) {
-    var elem = getNode(node);
-    arguments[0] = elem;
-    var child;
-    while ((child = elem.firstChild)) {
-        elem.removeChild(child);
+// ========== END OF ARRAY EXTENSIONS ========== ///
+forEach = cw.utils.deprecatedFunction(
+    '[3.9] forEach() is deprecated, use $.each() instead',
+    function(array, func) {
+        return $.each(array, func);
     }
-    if (arguments.length < 2) {
-        return elem;
-    } else {
-	for (var i=1; i<arguments.length; i++) {
-	    elem.appendChild(arguments[i]);
-	}
-	return elem;
-    }
-}
-
-update = jQuery.extend;
-
-
-function createDomFunction(tag) {
+);
 
-    function builddom(params, children) {
-	var node = document.createElement(tag);
-	for (key in params) {
-	    var value = params[key];
-	    if (key.substring(0, 2) == 'on') {
-		// this is an event handler definition
-		if (typeof value == 'string') {
-		    // litteral definition
-		    value = new Function(value);
-		}
-		node[key] = value;
-	    } else { // normal node attribute
-		jQuery(node).attr(key, params[key]);
-	    }
-	}
-	if (children) {
-	    if (!isArrayLike(children)) {
-		children = [children];
-		for (var i=2; i<arguments.length; i++) {
-		    var arg = arguments[i];
-		    if (isArray(arg)) {
-			children = merge(children, arg);
-		    } else {
-			children.push(arg);
-		    }
-		}
-	    }
-	    for (var i=0; i<children.length; i++) {
-		var child = children[i];
-		if (typeof child == "string" || typeof child == "number") {
-		    child = document.createTextNode(child);
-		}
-		node.appendChild(child);
-	    }
-	}
-	return node;
+/**
+ * .. function:: cw.utils.deprecatedFunction(msg, function)
+ *
+ * jQUery flattens arrays returned by the mapping function:
+ * >>> y = ['a:b:c', 'd:e']
+ * >>> jQuery.map(y, function(y) { return y.split(':');})
+ * ["a", "b", "c", "d", "e"]
+ *  // where one would expect:
+ *  [ ["a", "b", "c"], ["d", "e"] ]
+ *  XXX why not the same argument order as $.map and forEach ?
+ */
+map = cw.utils.deprecatedFunction(
+    '[3.9] map() is deprecated, use $.map instead',
+    function(func, array) {
+        var result = [];
+        for (var i = 0, length = array.length; i < length; i++) {
+            result.push(func(array[i]));
+        }
+        return result;
     }
-    return builddom;
-}
+);
+
+findValue = cw.utils.deprecatedFunction(
+    '[3.9] findValue(array, elt) is deprecated, use $.inArray(elt, array) instead',
+    function(array, element) {
+        return jQuery.inArray(element, array);
+    }
+);
 
-A = createDomFunction('a');
-BUTTON = createDomFunction('button');
-BR = createDomFunction('br');
-CANVAS = createDomFunction('canvas');
-DD = createDomFunction('dd');
-DIV = createDomFunction('div');
-DL = createDomFunction('dl');
-DT = createDomFunction('dt');
-FIELDSET = createDomFunction('fieldset');
-FORM = createDomFunction('form');
-H1 = createDomFunction('H1');
-H2 = createDomFunction('H2');
-H3 = createDomFunction('H3');
-H4 = createDomFunction('H4');
-H5 = createDomFunction('H5');
-H6 = createDomFunction('H6');
-HR = createDomFunction('hr');
-IMG = createDomFunction('img');
-INPUT = createDomFunction('input');
-LABEL = createDomFunction('label');
-LEGEND = createDomFunction('legend');
-LI = createDomFunction('li');
-OL = createDomFunction('ol');
-OPTGROUP = createDomFunction('optgroup');
-OPTION = createDomFunction('option');
-P = createDomFunction('p');
-PRE = createDomFunction('pre');
-SELECT = createDomFunction('select');
-SPAN = createDomFunction('span');
-STRONG = createDomFunction('strong');
-TABLE = createDomFunction('table');
-TBODY = createDomFunction('tbody');
-TD = createDomFunction('td');
-TEXTAREA = createDomFunction('textarea');
-TFOOT = createDomFunction('tfoot');
-TH = createDomFunction('th');
-THEAD = createDomFunction('thead');
-TR = createDomFunction('tr');
-TT = createDomFunction('tt');
-UL = createDomFunction('ul');
+filter = cw.utils.deprecatedFunction(
+    '[3.9] filter(func, array) is deprecated, use $.grep(array, f) instead',
+    function(func, array) {
+        return $.grep(array, func);
+    }
+);
+
+addElementClass = cw.utils.deprecatedFunction(
+    '[3.9] addElementClass(node, cls) is depcreated, use $(node).addClass(cls) instead',
+    function(node, klass) {
+        $(node).addClass(klass);
+    }
+);
+
+removeElementClass = cw.utils.deprecatedFunction(
+    '[3.9] removeElementClass(node, cls) is depcreated, use $(node).removeClass(cls) instead',
+    function(node, klass) {
+        $(node).removeClass(klass);
+    }
+);
 
-// cubicweb specific
-//IFRAME = createDomFunction('iframe');
-function IFRAME(params){
-  if ('name' in params){
-    try {
-      var node = document.createElement('<iframe name="'+params['name']+'">');
-    } catch (ex) {
-      var node = document.createElement('iframe');
-      node.id = node.name = params.name;
+hasElementClass = cw.utils.deprecatedFunction(
+    '[3.9] hasElementClass(node, cls) is depcreated, use $.className.has(node, cls)',
+    function(node, klass) {
+        return $.className.has(node, klass);
+    }
+);
+
+getNodeAttribute = cw.utils.deprecatedFunction(
+    '[3.9] getNodeAttribute(node, attr) is deprecated, use $(node).attr(attr)',
+    function(node, attribute) {
+        return $(node).attr(attribute);
     }
-  }
-  else{
-    var node = document.createElement('iframe');
-  }
-  for (key in params) {
-    if (key != 'name'){
-      var value = params[key];
-      if (key.substring(0, 2) == 'on') {
-	// this is an event handler definition
-	if (typeof value == 'string') {
-	  // litteral definition
-	  value = new Function(value);
-	}
-	node[key] = value;
-      } else { // normal node attribute
-	node.setAttribute(key, params[key]);
-      }
+);
+
+getNode = cw.utils.deprecatedFunction(
+    '[3.9] getNode(nodeid) is deprecated, use $(#nodeid) instead',
+    function(node) {
+        if (typeof node == 'string') {
+            return document.getElementById(node);
+        }
+        return node;
     }
-  }
-  return node;
-}
+);
 
-
-// dummy ultra minimalist implementation on deferred for jQuery
+/**
+ * .. function:: Deferred
+ *
+ * dummy ultra minimalist implementation on deferred for jQuery
+ */
 function Deferred() {
     this.__init__(this);
 }
 
 jQuery.extend(Deferred.prototype, {
     __init__: function() {
-	this._onSuccess = [];
-	this._onFailure = [];
-	this._req = null;
+        this._onSuccess = [];
+        this._onFailure = [];
+        this._req = null;
         this._result = null;
         this._error = null;
     },
 
     addCallback: function(callback) {
         if (this._req.readyState == 4) {
-            if (this._result) { callback.apply(null, this._result, this._req); }
+            if (this._result) {
+                var args = [this._result, this._req];
+                jQuery.merge(args, cw.utils.sliceList(arguments, 1));
+                callback.apply(null, args);
+            }
         }
-        else { this._onSuccess.push([callback, sliceList(arguments, 1)]); }
-	return this;
+        else {
+            this._onSuccess.push([callback, cw.utils.sliceList(arguments, 1)]);
+        }
+        return this;
     },
 
     addErrback: function(callback) {
         if (this._req.readyState == 4) {
-            if (this._error) { callback.apply(null, this._error, this._req); }
+            if (this._error) {
+                callback.apply(null, [this._error, this._req]);
+            }
         }
-        else { this._onFailure.push([callback, sliceList(arguments, 1)]); }
-	return this;
+        else {
+            this._onFailure.push([callback, cw.utils.sliceList(arguments, 1)]);
+        }
+        return this;
     },
 
     success: function(result) {
         this._result = result;
-	try {
-	    for (var i=0; i<this._onSuccess.length; i++) {
-		var callback = this._onSuccess[i][0];
-		var args = merge([result, this._req], this._onSuccess[i][1]);
-		callback.apply(null, args);
-	    }
-	} catch (error) {
-	    this.error(this.xhr, null, error);
-	}
+        try {
+            for (var i = 0; i < this._onSuccess.length; i++) {
+                var callback = this._onSuccess[i][0];
+                var args = [result, this._req];
+                jQuery.merge(args, this._onSuccess[i][1]);
+                callback.apply(null, args);
+            }
+        } catch(error) {
+            this.error(this.xhr, null, error);
+        }
     },
 
     error: function(xhr, status, error) {
         this._error = error;
-	for (var i=0; i<this._onFailure.length; i++) {
-	    var callback = this._onFailure[i][0];
-	    var args = merge([error, this._req], this._onFailure[i][1]);
-	    callback.apply(null, args);
-	}
+        for (var i = 0; i < this._onFailure.length; i++) {
+            var callback = this._onFailure[i][0];
+            var args = [error, this._req];
+            jQuery.merge(args, this._onFailure[i][1]);
+            callback.apply(null, args);
+        }
     }
 
 });
 
-
-/*
- * Asynchronously load an url and return a deferred
- * whose callbacks args are decoded according to
- * the Content-Type response header
- */
-function loadRemote(url, data, reqtype) {
-    var d = new Deferred();
-    jQuery.ajax({
-	url: url,
-	type: reqtype,
-	data: data,
-
-	beforeSend: function(xhr) {
-	    d._req = xhr;
-	},
-
-	success: function(data, status) {
-            if (d._req.getResponseHeader("content-type") == 'application/json') {
-              data = evalJSON(data);
-            }
-	    d.success(data);
-	},
-
-	error: function(xhr, status, error) {
-          try {
-            if (xhr.status == 500) {
-                var reason_dict = evalJSON(xhr.responseText);
-                d.error(xhr, status, reason_dict['reason']);
-                return;
-            }
-          } catch(exc) {
-            log('error with server side error report:' + exc);
-          }
-          d.error(xhr, status, null);
-	}
-    });
-    return d;
-}
-
-
-/** @id MochiKit.DateTime.toISOTime */
-toISOTime = function (date, realISO/* = false */) {
-    if (typeof(date) == "undefined" || date === null) {
-        return null;
-    }
-    var hh = date.getHours();
-    var mm = date.getMinutes();
-    var ss = date.getSeconds();
-    var lst = [
-        ((realISO && (hh < 10)) ? "0" + hh : hh),
-        ((mm < 10) ? "0" + mm : mm),
-        ((ss < 10) ? "0" + ss : ss)
-    ];
-    return lst.join(":");
-};
-
-_padTwo = function (n) {
-    return (n > 9) ? n : "0" + n;
-};
-
-/** @id MochiKit.DateTime.toISODate */
-toISODate = function (date) {
-    if (typeof(date) == "undefined" || date === null) {
-        return null;
-    }
-    return [
-        date.getFullYear(),
-        _padTwo(date.getMonth() + 1),
-        _padTwo(date.getDate())
-    ].join("-");
-};
-
-
-/** @id MochiKit.DateTime.toISOTimeStamp */
-toISOTimestamp = function (date, realISO/* = false*/) {
-    if (typeof(date) == "undefined" || date === null) {
-        return null;
-    }
-    var sep = realISO ? "T" : " ";
-    var foot = realISO ? "Z" : "";
-    if (realISO) {
-        date = new Date(date.getTime() + (date.getTimezoneOffset() * 60000));
-    }
-    return toISODate(date) + sep + toISOTime(date, realISO) + foot;
-};
-
-
-
-/* depth-first implementation of the nodeWalk function found
- * in MochiKit.Base
- * cf. http://mochikit.com/doc/html/MochiKit/Base.html#fn-nodewalk
+/**
+ * The only known usage of KEYS is in the tag cube. Once cubicweb-tag 1.7.0 is out,
+ * this current definition can be removed.
  */
-function nodeWalkDepthFirst(node, visitor) {
-    var children = visitor(node);
-    if (children) {
-	for(var i=0; i<children.length; i++) {
-	    nodeWalkDepthFirst(children[i], visitor);
-	}
-    }
-}
-
-
-/* Returns true if all the given Array-like or string arguments are not empty (obj.length > 0) */
-function isNotEmpty(obj) {
-    for (var i = 0; i < arguments.length; i++) {
-        var o = arguments[i];
-        if (!(o && o.length)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-/** this implementation comes from MochiKit  */
-function formContents(elem/* = document.body */) {
-    var names = [];
-    var values = [];
-    if (typeof(elem) == "undefined" || elem === null) {
-        elem = document.body;
-    } else {
-        elem = getNode(elem);
-    }
-    nodeWalkDepthFirst(elem, function (elem) {
-        var name = elem.name;
-        if (isNotEmpty(name)) {
-            var tagName = elem.tagName.toUpperCase();
-            if (tagName === "INPUT"
-                && (elem.type == "radio" || elem.type == "checkbox")
-                && !elem.checked
-               ) {
-                return null;
-            }
-            if (tagName === "SELECT") {
-                if (elem.type == "select-one") {
-                    if (elem.selectedIndex >= 0) {
-                        var opt = elem.options[elem.selectedIndex];
-                        var v = opt.value;
-                        if (!v) {
-                            var h = opt.outerHTML;
-                            // internet explorer sure does suck.
-                            if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
-                                v = opt.text;
-                            }
-                        }
-                        names.push(name);
-                        values.push(v);
-                        return null;
-                    }
-                    // no form elements?
-                    names.push(name);
-                    values.push("");
-                    return null;
-                } else {
-                    var opts = elem.options;
-                    if (!opts.length) {
-                        names.push(name);
-                        values.push("");
-                        return null;
-                    }
-                    for (var i = 0; i < opts.length; i++) {
-                        var opt = opts[i];
-                        if (!opt.selected) {
-                            continue;
-                        }
-                        var v = opt.value;
-                        if (!v) {
-                            var h = opt.outerHTML;
-                            // internet explorer sure does suck.
-                            if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
-                                v = opt.text;
-                            }
-                        }
-                        names.push(name);
-                        values.push(v);
-                    }
-                    return null;
-                }
-            }
-            if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
-                || tagName === "DIV"
-               ) {
-                return elem.childNodes;
-            }
-            names.push(name);
-            values.push(elem.value || '');
-            return null;
-        }
-        return elem.childNodes;
-    });
-    return [names, values];
-}
-
-function merge(array1, array2) {
-    var result = [];
-    for (var i=0,length=arguments.length; i<length; i++) {
-	var array = arguments[i];
-	for (var j=0,alength=array.length; j<alength; j++) {
-	    result.push(array[j]);
-	}
-    }
-    return result;
-}
-
 var KEYS = {
     KEY_ESC: 27,
     KEY_ENTER: 13
 };
 
+// XXX avoid crashes / backward compat
+CubicWeb = {
+    require: function(module) {},
+    provide: function(module) {}
+};
 
+jQuery(document).ready(function() {
+    jQuery(CubicWeb).trigger('server-response', [false, document]);
+});
 
+// XXX as of 2010-04-07, no known cube uses this
+jQuery(CubicWeb).bind('ajax-loaded', function() {
+    log('[3.7] "ajax-loaded" event is deprecated, use "server-response" instead');
+    jQuery(CubicWeb).trigger('server-response', [false, document]);
+});
+
+CubicWeb.provide('python.js');