web/data/cubicweb.compat.js
changeset 0 b97547f5f1fa
child 12 95bc1d15349b
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 /* MochiKit -> jQuery compatibility module */
       
     2 
       
     3 function forEach(array, func) {
       
     4     for (var i=0, length=array.length; i<length; i++) {
       
     5 	func(array[i]);
       
     6     }
       
     7 }
       
     8 
       
     9 function getElementsByTagAndClassName(tag, klass, root) {
       
    10     root = root || document;
       
    11     // FIXME root is not used in this compat implementation
       
    12     return jQuery(tag + '.' + klass);
       
    13 }
       
    14 
       
    15 function map(func, array) {
       
    16     // XXX jQUery tends to simplify lists with only one element :
       
    17     // >>> y = ['a:b:c']
       
    18     // >>> jQuery.map(y, function(y) { return y.split(':');})
       
    19     // ["a", "b", "c"]
       
    20     // where I would expect :
       
    21     // [ ["a", "b", "c"] ]
       
    22     // return jQuery.map(array, func);
       
    23     var result = [];
       
    24     for (var i=0,length=array.length;i<length;i++) {
       
    25 	result.push(func(array[i]));
       
    26     }
       
    27     return result;
       
    28 }
       
    29 
       
    30 function findValue(array, element) {
       
    31     return jQuery.inArray(element, array);
       
    32 }
       
    33 
       
    34 function filter(func, array) {
       
    35     return jQuery.grep(array, func);
       
    36 }
       
    37 
       
    38 function noop() {}
       
    39 
       
    40 function addElementClass(node, klass) {
       
    41     jQuery(node).addClass(klass);
       
    42 }
       
    43 
       
    44 function toggleElementClass(node, klass) {
       
    45     jQuery(node).toggleClass(klass);
       
    46 }
       
    47 
       
    48 function removeElementClass(node, klass) {
       
    49     jQuery(node).removeClass(klass);
       
    50 }
       
    51 
       
    52 hasElementClass = jQuery.className.has
       
    53 
       
    54 
       
    55 function partial(func) {
       
    56     var args = sliceList(arguments, 1);
       
    57     return function() {
       
    58 	return func.apply(null, merge(args, arguments));
       
    59     }
       
    60 }
       
    61 
       
    62 
       
    63 function log() {
       
    64     // XXX dummy implementation
       
    65     // console.log.apply(arguments); ???
       
    66     var args = [];
       
    67     for (var i=0; i<arguments.length; i++) {
       
    68 	args.push(arguments[i]);
       
    69     }
       
    70     if (typeof(window) != "undefined" && window.console
       
    71         && window.console.log) {
       
    72 	window.console.log(args.join(' '));
       
    73     }
       
    74 }
       
    75 
       
    76 function getNodeAttribute(node, attribute) {
       
    77     return jQuery(node).attr(attribute);
       
    78 }
       
    79 
       
    80 function isArray(it){ // taken from dojo
       
    81     return it && (it instanceof Array || typeof it == "array");
       
    82 }
       
    83 
       
    84 function isString(it){ // taken from dojo
       
    85     return !!arguments.length && it != null && (typeof it == "string" || it instanceof String);
       
    86 }
       
    87 
       
    88 
       
    89 function isArrayLike(it) { // taken from dojo
       
    90     return (it && it !== undefined &&
       
    91 	    // keep out built-in constructors (Number, String, ...) which have length
       
    92 	    // properties
       
    93 	    !isString(it) && !jQuery.isFunction(it) &&
       
    94 	    !(it.tagName && it.tagName.toLowerCase() == 'form') &&
       
    95 	    (isArray(it) || isFinite(it.length)));
       
    96 }
       
    97 
       
    98 
       
    99 function getNode(node) {
       
   100     if (typeof(node) == 'string') {
       
   101         return document.getElementById(node);
       
   102     }
       
   103     return node;
       
   104 }
       
   105 
       
   106 /* safe version of jQuery('#nodeid') because we use ':' in nodeids
       
   107  * which messes with jQuery selection mechanism
       
   108  */
       
   109 function jqNode(node) {
       
   110     node = getNode(node);
       
   111     if (node) {
       
   112 	return jQuery(node);
       
   113     }
       
   114     return null;
       
   115 }
       
   116 
       
   117 function evalJSON(json) { // trust source
       
   118     return eval("(" + json + ")");
       
   119 }
       
   120 
       
   121 function urlEncode(str) {
       
   122     if (typeof(encodeURIComponent) != "undefined") {
       
   123         return encodeURIComponent(str).replace(/\'/g, '%27');
       
   124     } else {
       
   125         return escape(str).replace(/\+/g, '%2B').replace(/\"/g,'%22').rval.replace(/\'/g, '%27');
       
   126     }
       
   127 }
       
   128 
       
   129 function swapDOM(dest, src) {
       
   130     dest = getNode(dest);
       
   131     var parent = dest.parentNode;
       
   132     if (src) {
       
   133         src = getNode(src);
       
   134         parent.replaceChild(src, dest);
       
   135     } else {
       
   136         parent.removeChild(dest);
       
   137     }
       
   138     return src;
       
   139 }
       
   140 
       
   141 function replaceChildNodes(node/*, nodes...*/) {
       
   142     var elem = getNode(node);
       
   143     arguments[0] = elem;
       
   144     var child;
       
   145     while ((child = elem.firstChild)) {
       
   146         elem.removeChild(child);
       
   147     }
       
   148     if (arguments.length < 2) {
       
   149         return elem;
       
   150     } else {
       
   151 	for (var i=1; i<arguments.length; i++) {
       
   152 	    elem.appendChild(arguments[i]);
       
   153 	}
       
   154 	return elem;
       
   155     }
       
   156 }
       
   157 
       
   158 update = jQuery.extend;
       
   159 
       
   160 
       
   161 function createDomFunction(tag) {
       
   162 
       
   163     function builddom(params, children) {
       
   164 	var node = document.createElement(tag);
       
   165 	for (key in params) {
       
   166 	    var value = params[key];
       
   167 	    if (key.substring(0, 2) == 'on') {
       
   168 		// this is an event handler definition
       
   169 		if (typeof value == 'string') {
       
   170 		    // litteral definition
       
   171 		    value = new Function(value);
       
   172 		}
       
   173 		node[key] = value;
       
   174 	    } else { // normal node attribute
       
   175 		node.setAttribute(key, params[key]);
       
   176 	    }
       
   177 	}
       
   178 	if (children) {
       
   179 	    if (!isArrayLike(children)) {
       
   180 		children = [children];
       
   181 		for (var i=2; i<arguments.length; i++) {
       
   182 		    var arg = arguments[i];
       
   183 		    if (isArray(arg)) {
       
   184 			children = merge(children, arg);
       
   185 		    } else {
       
   186 			children.push(arg);
       
   187 		    }
       
   188 		}
       
   189 	    }
       
   190 	    for (var i=0; i<children.length; i++) {
       
   191 		var child = children[i];
       
   192 		if (typeof child == "string" || typeof child == "number") {
       
   193 		    child = document.createTextNode(child);
       
   194 		}
       
   195 		node.appendChild(child);
       
   196 	    }
       
   197 	}
       
   198 	return node;
       
   199     }
       
   200     return builddom;
       
   201 }
       
   202 
       
   203 A = createDomFunction('a');
       
   204 BUTTON = createDomFunction('button');
       
   205 BR = createDomFunction('br');
       
   206 CANVAS = createDomFunction('canvas');
       
   207 DD = createDomFunction('dd');
       
   208 DIV = createDomFunction('div');
       
   209 DL = createDomFunction('dl');
       
   210 DT = createDomFunction('dt');
       
   211 FIELDSET = createDomFunction('fieldset');
       
   212 FORM = createDomFunction('form');
       
   213 H1 = createDomFunction('H1');
       
   214 H2 = createDomFunction('H2');
       
   215 H3 = createDomFunction('H3');
       
   216 H4 = createDomFunction('H4');
       
   217 H5 = createDomFunction('H5');
       
   218 H6 = createDomFunction('H6');
       
   219 HR = createDomFunction('hr');
       
   220 IMG = createDomFunction('img');
       
   221 INPUT = createDomFunction('input');
       
   222 LABEL = createDomFunction('label');
       
   223 LEGEND = createDomFunction('legend');
       
   224 LI = createDomFunction('li');
       
   225 OL = createDomFunction('ol');
       
   226 OPTGROUP = createDomFunction('optgroup');
       
   227 OPTION = createDomFunction('option');
       
   228 P = createDomFunction('p');
       
   229 PRE = createDomFunction('pre');
       
   230 SELECT = createDomFunction('select');
       
   231 SPAN = createDomFunction('span');
       
   232 STRONG = createDomFunction('strong');
       
   233 TABLE = createDomFunction('table');
       
   234 TBODY = createDomFunction('tbody');
       
   235 TD = createDomFunction('td');
       
   236 TEXTAREA = createDomFunction('textarea');
       
   237 TFOOT = createDomFunction('tfoot');
       
   238 TH = createDomFunction('th');
       
   239 THEAD = createDomFunction('thead');
       
   240 TR = createDomFunction('tr');
       
   241 TT = createDomFunction('tt');
       
   242 UL = createDomFunction('ul');
       
   243 
       
   244 // cubicweb specific
       
   245 IFRAME = createDomFunction('iframe');
       
   246 
       
   247 // dummy ultra minimalist implementation on deferred for jQuery
       
   248 function Deferred() {
       
   249     this.__init__(this);
       
   250 }
       
   251 
       
   252 jQuery.extend(Deferred.prototype, {
       
   253     __init__: function() {
       
   254 	this.onSuccess = [];
       
   255 	this.onFailure = [];
       
   256 	this.req = null;
       
   257     },
       
   258 
       
   259     addCallback: function(callback) {
       
   260 	this.onSuccess.push([callback, sliceList(arguments, 1)]);
       
   261 	return this;
       
   262     },
       
   263 
       
   264     addErrback: function(callback) {
       
   265 	this.onFailure.push([callback, sliceList(arguments, 1)]);
       
   266 	return this;
       
   267     },
       
   268 
       
   269     success: function(result) {
       
   270 	try {
       
   271 	    for (var i=0; i<this.onSuccess.length; i++) {
       
   272 		var callback = this.onSuccess[i][0];
       
   273 		var args = merge([result, this.req], this.onSuccess[i][1]);
       
   274 		callback.apply(null, args);
       
   275 	    }
       
   276 	} catch (error) {
       
   277 	    this.error(this.xhr, null, error);
       
   278 	}
       
   279     },
       
   280 
       
   281     error: function(xhr, status, error) {
       
   282 	for (var i=0; i<this.onFailure.length; i++) {
       
   283 	    var callback = this.onFailure[i][0];
       
   284 	    var args = merge([error, this.req], this.onFailure[i][1]);
       
   285 	    callback.apply(null, args);
       
   286 	}
       
   287     }
       
   288 
       
   289 });
       
   290 
       
   291 
       
   292 /** @id MochiKit.DateTime.toISOTime */
       
   293 toISOTime = function (date, realISO/* = false */) {
       
   294     if (typeof(date) == "undefined" || date === null) {
       
   295         return null;
       
   296     }
       
   297     var hh = date.getHours();
       
   298     var mm = date.getMinutes();
       
   299     var ss = date.getSeconds();
       
   300     var lst = [
       
   301         ((realISO && (hh < 10)) ? "0" + hh : hh),
       
   302         ((mm < 10) ? "0" + mm : mm),
       
   303         ((ss < 10) ? "0" + ss : ss)
       
   304     ];
       
   305     return lst.join(":");
       
   306 };
       
   307 
       
   308 _padTwo = function (n) {
       
   309     return (n > 9) ? n : "0" + n;
       
   310 };
       
   311 
       
   312 /** @id MochiKit.DateTime.toISODate */
       
   313 toISODate = function (date) {
       
   314     if (typeof(date) == "undefined" || date === null) {
       
   315         return null;
       
   316     }
       
   317     return [
       
   318         date.getFullYear(),
       
   319         _padTwo(date.getMonth() + 1),
       
   320         _padTwo(date.getDate())
       
   321     ].join("-");
       
   322 };
       
   323 
       
   324 
       
   325 /** @id MochiKit.DateTime.toISOTimeStamp */
       
   326 toISOTimestamp = function (date, realISO/* = false*/) {
       
   327     if (typeof(date) == "undefined" || date === null) {
       
   328         return null;
       
   329     }
       
   330     var sep = realISO ? "T" : " ";
       
   331     var foot = realISO ? "Z" : "";
       
   332     if (realISO) {
       
   333         date = new Date(date.getTime() + (date.getTimezoneOffset() * 60000));
       
   334     }
       
   335     return toISODate(date) + sep + toISOTime(date, realISO) + foot;
       
   336 };
       
   337 
       
   338 
       
   339 function loadJSON(url, data, type, dataType) {
       
   340     d = new Deferred();
       
   341     jQuery.ajax({
       
   342 	url: url,
       
   343 	type: type,
       
   344 	data: data,
       
   345 	dataType: dataType,
       
   346 
       
   347 	beforeSend: function(xhr) {
       
   348 	    d.req = xhr;
       
   349 	},
       
   350 
       
   351 	success: function(data, status) {
       
   352 	    d.success(data);
       
   353 	},
       
   354 
       
   355 	error: function(xhr, status, error) {
       
   356 	    error = evalJSON(xhr.responseText);
       
   357 	    d.error(xhr, status, error['reason']);
       
   358 	}
       
   359     });
       
   360     return d;
       
   361 }
       
   362 
       
   363 /* depth-first implementation of the nodeWalk function found
       
   364  * in MochiKit.Base
       
   365  * cf. http://mochikit.com/doc/html/MochiKit/Base.html#fn-nodewalk
       
   366  */
       
   367 function nodeWalkDepthFirst(node, visitor) {
       
   368     var children = visitor(node);
       
   369     if (children) {
       
   370 	for(var i=0; i<children.length; i++) {
       
   371 	    nodeWalkDepthFirst(children[i], visitor);
       
   372 	}
       
   373     }
       
   374 }
       
   375 
       
   376 
       
   377 /* Returns true if all the given Array-like or string arguments are not empty (obj.length > 0) */
       
   378 function isNotEmpty(obj) {
       
   379     for (var i = 0; i < arguments.length; i++) {
       
   380         var o = arguments[i];
       
   381         if (!(o && o.length)) {
       
   382             return false;
       
   383         }
       
   384     }
       
   385     return true;
       
   386 }
       
   387 
       
   388 /** this implementation comes from MochiKit  */
       
   389 function formContents(elem/* = document.body */) {
       
   390     var names = [];
       
   391     var values = [];
       
   392     if (typeof(elem) == "undefined" || elem === null) {
       
   393         elem = document.body;
       
   394     } else {
       
   395         elem = getNode(elem);
       
   396     }
       
   397     nodeWalkDepthFirst(elem, function (elem) {
       
   398         var name = elem.name;
       
   399         if (isNotEmpty(name)) {
       
   400             var tagName = elem.tagName.toUpperCase();
       
   401             if (tagName === "INPUT"
       
   402                 && (elem.type == "radio" || elem.type == "checkbox")
       
   403                 && !elem.checked
       
   404                ) {
       
   405                 return null;
       
   406             }
       
   407             if (tagName === "SELECT") {
       
   408                 if (elem.type == "select-one") {
       
   409                     if (elem.selectedIndex >= 0) {
       
   410                         var opt = elem.options[elem.selectedIndex];
       
   411                         var v = opt.value;
       
   412                         if (!v) {
       
   413                             var h = opt.outerHTML;
       
   414                             // internet explorer sure does suck.
       
   415                             if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
       
   416                                 v = opt.text;
       
   417                             }
       
   418                         }
       
   419                         names.push(name);
       
   420                         values.push(v);
       
   421                         return null;
       
   422                     }
       
   423                     // no form elements?
       
   424                     names.push(name);
       
   425                     values.push("");
       
   426                     return null;
       
   427                 } else {
       
   428                     var opts = elem.options;
       
   429                     if (!opts.length) {
       
   430                         names.push(name);
       
   431                         values.push("");
       
   432                         return null;
       
   433                     }
       
   434                     for (var i = 0; i < opts.length; i++) {
       
   435                         var opt = opts[i];
       
   436                         if (!opt.selected) {
       
   437                             continue;
       
   438                         }
       
   439                         var v = opt.value;
       
   440                         if (!v) {
       
   441                             var h = opt.outerHTML;
       
   442                             // internet explorer sure does suck.
       
   443                             if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
       
   444                                 v = opt.text;
       
   445                             }
       
   446                         }
       
   447                         names.push(name);
       
   448                         values.push(v);
       
   449                     }
       
   450                     return null;
       
   451                 }
       
   452             }
       
   453             if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
       
   454                 || tagName === "DIV"
       
   455                ) {
       
   456                 return elem.childNodes;
       
   457             }
       
   458             names.push(name);
       
   459             values.push(elem.value || '');
       
   460             return null;
       
   461         }
       
   462         return elem.childNodes;
       
   463     });
       
   464     return [names, values];
       
   465 }
       
   466 
       
   467 function merge(array1, array2) {
       
   468     var result = [];
       
   469     for (var i=0,length=arguments.length; i<length; i++) {
       
   470 	var array = arguments[i];
       
   471 	for (var j=0,alength=array.length; j<alength; j++) {
       
   472 	    result.push(array[j]);
       
   473 	}
       
   474     }
       
   475     return result;
       
   476 }
       
   477 
       
   478 var KEYS = {
       
   479     KEY_ESC: 27,
       
   480     KEY_ENTER: 13
       
   481 }
       
   482 
       
   483 // XHR = null;
       
   484 // function test() {
       
   485 //     var d = loadJSON('http://crater:9876/json?mode=remote&fname=i18n&pageid=xxx&arg=' + jQuery.toJSON(['modify']));
       
   486 //     d = d.addCallback(function (result, xhr) {
       
   487 // 	XHR = xhr;
       
   488 // 	log('got ajax result 1' + result + xhr);
       
   489 // 	log('got ajax result 1' + xhr);
       
   490 // 	log('got ajax result 1' + xhr + 'arguments =', arguments.length);
       
   491 //     });
       
   492 //     d.addCallback(function (x, req, y, z) {
       
   493 // 	log('callback 2 x =' + x, ' req=', req, 'y =', y, 'z=',z);
       
   494 //     }, 12, 13)
       
   495 //     d.addErrback(function (error, xhr) {
       
   496 // 	XHR = xhr;
       
   497 // 	log('got err', error, ' code =', xhr.status, 'arguments length=', arguments.length);
       
   498 //     })
       
   499 // }
       
   500