X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=www%2Fprive%2Fjavascript%2FajaxCallback.js;h=777a0cbabdb06a01483338c771c8f333efa3e902;hb=4f443dce95ff6f8221c189880a70c74ce1c1f238;hp=118fc314949581cc9eac5f46a082468fd57d6a7f;hpb=a9541742f84ce7e258d46dd8407242289ab2ec72;p=lhc%2Fweb%2Fwww.git diff --git a/www/prive/javascript/ajaxCallback.js b/www/prive/javascript/ajaxCallback.js index 118fc314..777a0cba 100644 --- a/www/prive/javascript/ajaxCallback.js +++ b/www/prive/javascript/ajaxCallback.js @@ -37,6 +37,9 @@ if(!jQuery.spip.load_handlers) { // intercept jQuery.fn.load jQuery.spip.intercepted.load = jQuery.fn.load; jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string") { + return jQuery.spip.intercepted.load.apply( this, arguments ); + } callback = callback || function(){}; @@ -49,6 +52,7 @@ if(!jQuery.spip.load_handlers) { params = null; } } + params = jQuery.extend(params, {triggerAjaxLoad:false}); // prevent $.ajax to triggerAjaxLoad var callback2 = function() {jQuery.spip.log('jQuery.load');jQuery.spip.triggerAjaxLoad(this);callback.apply(this,arguments);}; return jQuery.spip.intercepted.load.apply(this,[url, params, callback2]); }; @@ -75,33 +79,95 @@ if(!jQuery.spip.load_handlers) { // intercept jQuery.ajax jQuery.spip.intercepted.ajax = jQuery.ajax; - jQuery.ajax = function(type) { - var s = jQuery.extend(true, {}, jQuery.ajaxSettings, type); + jQuery.ajax = function(url, settings) { + if (typeof settings == 'undefined') { + settings = {}; + if (typeof url == 'object') { + settings = url; + url = null; + } + } + if (typeof url == 'string') { + settings['url'] = url; + } + // if triggerAjaxLoad is prevented, finish without faking callback + if (settings.data && settings.data['triggerAjaxLoad'] === false) { + settings.data['triggerAjaxLoad'] = null; + return jQuery.spip.intercepted.ajax(settings); + } + var s = jQuery.extend(true, {}, jQuery.ajaxSettings, settings); var callbackContext = s.context || s; try { if (jQuery.ajax.caller==jQuery.spip.intercepted.load || jQuery.ajax.caller==jQuery.spip.intercepted.ajaxSubmit) - return jQuery.spip.intercepted.ajax(type); + return jQuery.spip.intercepted.ajax(settings); } catch (err){} var orig_complete = s.complete || function() {}; - type.complete = function(res,status) { + settings.complete = function(res,status) { // Do not fire OnAjaxLoad if the dataType is not html - var dataType = type.dataType; + var dataType = settings.dataType; var ct = (res && (typeof res.getResponseHeader == 'function')) ? res.getResponseHeader("content-type"): ''; var xml = !dataType && ct && ct.indexOf("xml") >= 0; orig_complete.call( callbackContext, res, status); - if(!dataType && !xml || dataType == "html") { + if((!dataType && !xml) || dataType == "html") { jQuery.spip.log('jQuery.ajax'); if (typeof s.onAjaxLoad=="undefined" || s.onAjaxLoad!=false) jQuery.spip.triggerAjaxLoad(s.ajaxTarget?s.ajaxTarget:document); } }; - return jQuery.spip.intercepted.ajax(type); + return jQuery.spip.intercepted.ajax(settings); }; } +/* jQuery.browser */ +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +// Don't clobber any existing jQuery.browser in case it's different +if ( !jQuery.browser ) { + matched = jQuery.uaMatch( navigator.userAgent ); + browser = {}; + + if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; + } + + // Chrome is Webkit, but Webkit is also Safari. + if ( browser.chrome ) { + browser.webkit = true; + } else if ( browser.webkit ) { + browser.safari = true; + } + + jQuery.browser = browser; +} + +// jQuery.getScript cache par defaut +jQuery.getScript = function(url,callback){ + return $.ajax({ + url: url, + dataType: "script", + success: callback, + cache: true + }); +} + /** * if not fully visible, scroll the page to position * target block at the top of page @@ -136,14 +202,14 @@ jQuery.fn.positionner = function(force, setfocus) { jQuery.spip.virtualbuffer_id='spip_virtualbufferupdate'; jQuery.spip.initReaderBuffer = function(){ if (jQuery('#'+jQuery.spip.virtualbuffer_id).length) return; - jQuery('body').append('

'); + jQuery('body').append('

'); } jQuery.spip.updateReaderBuffer = function(){ var i = jQuery('#'+jQuery.spip.virtualbuffer_id); if (!i.length) return; // incrementons l'input hidden, ce qui a pour effet de forcer le rafraichissement du // buffer du lecteur d'ecran (au moins dans Jaws) - i.attr('value',parseInt(i.attr('value'))+1); + i.val(parseInt(i.val())+1); } jQuery.fn.formulaire_setARIA = function(){ @@ -151,7 +217,9 @@ jQuery.fn.formulaire_setARIA = function(){ // eviter une double execution du js au moment de sa reinsertion dans le DOM par wrap() // cf http://bugs.jquery.com/ticket/7447 this.find('script').remove(); - this.wrap('
'); + this.wrap('
'); + // dans un formulaire, le screen reader relit tout a chaque saisie d'un caractere si on est en aria-live + jQuery('form',this).not('[aria-live]').attr('aria-live','off'); } return this; } @@ -162,33 +230,44 @@ jQuery.fn.formulaire_setARIA = function(){ jQuery.fn.formulaire_dyn_ajax = function(target) { if (this.length) jQuery.spip.initReaderBuffer(); - return this.each(function() { - var scrollwhensubmit = !jQuery(this).is('.noscroll'); + return this.each(function() { + var scrollwhensubmit = !jQuery(this).is('.noscroll'); var cible = target || this; - jQuery(cible).formulaire_setARIA(); + jQuery(cible).formulaire_setARIA(); jQuery('form:not(.noajax):not(.bouton_action_post)', this).each(function(){ var leform = this; var leclk,leclk_x,leclk_y; + var onError = function(xhr, status, error, $form){ + jQuery(leform).ajaxFormUnbind().find('input[name="var_ajax"]').remove(); + var msg = "Erreur"; + if (typeof(error_on_ajaxform)!=="undefined") msg = error_on_ajaxform; + jQuery(leform).prepend("

"+msg+"

").find('.ajax-error').show('fast'); + jQuery(cible).closest('.ariaformprop').endLoading(true); + } jQuery(this).prepend("") .ajaxForm({ beforeSubmit: function(){ // memoriser le bouton clique, en cas de repost non ajax leclk = leform.clk; - if (leclk) { - var n = leclk.name; - if (n && !leclk.disabled && leclk.type == "image") { - leclk_x = leform.clk_x; - leclk_y = leform.clk_y; - } - } + var scrollwhensubmit_button = true; + if (leclk) { + scrollwhensubmit_button = !jQuery(leclk).is('.noscroll'); + var n = leclk.name; + if (n && !leclk.disabled && leclk.type == "image") { + leclk_x = leform.clk_x; + leclk_y = leform.clk_y; + } + } jQuery(cible).wrap('
'); cible = jQuery(cible).parent(); jQuery(cible).closest('.ariaformprop').animateLoading(); - if (scrollwhensubmit) + if (scrollwhensubmit && scrollwhensubmit_button) { jQuery(cible).positionner(false,false); + } }, - success: function(c){ - if (c=='noajax'){ + error: onError, + success: function(c, status, xhr , $form){ + if (c.match(/^\s*noajax\s*$/)){ // le serveur ne veut pas traiter ce formulaire en ajax // on resubmit sans ajax jQuery("input[name=var_ajax]",leform).remove(); @@ -196,8 +275,8 @@ jQuery.fn.formulaire_dyn_ajax = function(target) { // les reinjecter dans le dom sous forme de input hidden // pour que le serveur les recoive if (leclk){ - var n = leclk.name; - if (n && !leclk.disabled) { + var n = leclk.name; + if (n && !leclk.disabled) { jQuery(leform).prepend(""); if (leclk.type == "image") { jQuery(leform).prepend(""); @@ -208,6 +287,8 @@ jQuery.fn.formulaire_dyn_ajax = function(target) { jQuery(leform).ajaxFormUnbind().submit(); } else { + if (!c.length || c.indexOf("ajax-form-is-ok")==-1) + return onError.apply(this,[status, xhr , $form]); // commencons par vider le cache des urls, si jamais un js au retour // essaye tout de suite de suivre un lien en cache // dans le doute sur la validite du cache il vaut mieux l'invalider @@ -271,13 +352,12 @@ jQuery.fn.formulaire_dyn_ajax = function(target) { // a supprimer ? jQuery.spip.updateReaderBuffer(); } - }, - iframe: jQuery.browser.msie + }/*, + iframe: jQuery.browser.msie*/ }) // previent qu'on n'ajaxera pas deux fois le meme formulaire en cas de ajaxload // mais le marquer comme ayant l'ajax au cas ou on reinjecte du contenu ajax dedans - .addClass('noajax hasajax') - ; + .addClass('noajax hasajax'); }); }); } @@ -319,7 +399,7 @@ jQuery.fn.formulaire_activer_verif_auto = function(callback){ .find('form') .attr('data-verifjson','on') .find('input,select,textarea') - .bind('change',check); + .on('change', check); } } jQuery(activer); @@ -386,10 +466,17 @@ jQuery.spip.on_ajax_loaded = function(blocfrag,c,href,history) { history = false; if (history) jQuery.spip.setHistoryState(blocfrag); - - jQuery(blocfrag) - .html(c) - .endLoading(); + + if (jQuery(blocfrag).attr('data-loaded-callback')){ + var callback = eval(jQuery(blocfrag).attr('data-loaded-callback')); + callback.call(blocfrag, c, href, history); + } + else { + jQuery(blocfrag) + .html(c) + .endLoading(); + } + if (typeof href != undefined) jQuery(blocfrag).attr('data-url',href); if (history) { @@ -430,6 +517,9 @@ jQuery.spip.setHistoryState = function(blocfrag){ id:blocfrag.attr('id'), href: href }; + var ajaxid = blocfrag.attr('class').match(/\bajax-id-[\w-]+\b/); + if (ajaxid && ajaxid.length) + state["ajaxid"] = ajaxid[0]; // on remplace la variable qui decrit l'etat courant // initialement vide // -> elle servira a revenir dans l'etat courant @@ -443,12 +533,23 @@ jQuery.spip.pushHistoryState = function(href, title){ } window.onpopstate = function(popState){ - if (popState.state && popState.state.id){ - var blocfrag=jQuery('#'+popState.state.id); - if (blocfrag.length && popState.state.href) { + if (popState.state && popState.state.href){ + var blocfrag=false; + if (popState.state.id){ + blocfrag=jQuery('#'+popState.state.id); + } + if ((!blocfrag || !blocfrag.length) && popState.state.ajaxid){ + blocfrag=jQuery('.ajaxbloc.'+popState.state.ajaxid); + } + if (blocfrag && blocfrag.length==1) { jQuery.spip.ajaxClick(blocfrag,popState.state.href,{history:false}); return true; } + // si on revient apres avoir rompu la chaine ajax, on a pu perdre l'id #ghsidxx ajoute en JS + // dans ce cas on redirige hors ajax + else { + window.location.href = popState.state.href; + } } } @@ -468,7 +569,13 @@ window.onpopstate = function(popState){ */ jQuery.spip.loadAjax = function(blocfrag,url, href, options){ var force = options.force || false; - jQuery(blocfrag).animateLoading(); + if (jQuery(blocfrag).attr('data-loading-callback')){ + var callback = eval(jQuery(blocfrag).attr('data-loading-callback')); + callback.call(blocfrag,url,href,options); + } + else { + jQuery(blocfrag).animateLoading(); + } if (jQuery.spip.preloaded_urls[url] && !force) { // si on est deja en train de charger ce fragment, revenir plus tard if (jQuery.spip.preloaded_urls[url]==""){ @@ -506,10 +613,32 @@ jQuery.spip.loadAjax = function(blocfrag,url, href, options){ * @param string href * @param string ajax_env */ -jQuery.spip.makeAjaxUrl = function(href,ajax_env){ +jQuery.spip.makeAjaxUrl = function(href,ajax_env,origin){ var url = href.split('#'); url[0] = parametre_url(url[0],'var_ajax',1); url[0] = parametre_url(url[0],'var_ajax_env',ajax_env); + + // les arguments de origin qui ne sont pas dans href doivent etre explicitement fournis vides dans url + if (origin){ + var p=origin.indexOf('?'); + if (p!==-1){ + // recuperer la base + var args = origin.substring(p+1).split('&'); + var val; + var arg; + for(var n=0;n"+(url[1]?"":"")) .ajaxForm({ beforeSubmit: function(){ - jQuery(blocfrag).animateLoading().positionner(false); + jQuery(blocfrag).animateLoading(); + if (scrollwhensubmit) { + jQuery(blocfrag).positionner(false); + } }, onAjaxLoad:false, success: function(c){ jQuery.spip.on_ajax_loaded(blocfrag,c); jQuery.spip.preloaded_urls = {}; // on vide le cache des urls car on a fait une action en bdd - }, - iframe: jQuery.browser.msie + }/*, + iframe: jQuery.browser.msie*/ }) - .addClass('bind-ajax') // previent qu'on n'ajaxera pas deux fois le meme formulaire en cas de ajaxload - ; + .addClass('bind-ajax'); // previent qu'on n'ajaxera pas deux fois le meme formulaire en cas de ajaxload }); }); }; @@ -660,6 +798,7 @@ jQuery.fn.followLink = function(){ * @param string ajaxid * @param object options * callback : callback after reloading + * href : url to load instead of origin url * args : {arg:value,...} to pass tu the url * history : bool to specify if navigation history is modified by reload or not (false if not provided) */ @@ -722,16 +861,22 @@ jQuery.fn.endLoading = function(hard) { */ jQuery.fn.animateRemove = function(callback){ if (this.length){ + var me=this; var color = $("
").css('background-color'); - $(this).addClass('remove').css({backgroundColor: color}).animate({opacity: "0.0"}, 'fast',function(){ - $(this).removeClass('remove').css({backgroundColor: ''}); + var sel=$(this); + // if target is a tr, include td childrens cause background color on tr doesn't works in a lot of browsers + if (sel.is('tr')) + sel = sel.add('>td',sel); + sel.addClass('remove').css({backgroundColor: color}).animate({opacity: "0.0"}, 'fast', function(){ + sel.removeClass('remove').css({backgroundColor: ''}); if (callback) - callback.apply(this); + callback.apply(me); }); } return this; // don't break the chain } + /** * animation d'un item que l'on ajoute : * ajout de la classe append @@ -751,7 +896,7 @@ jQuery.fn.animateAppend = function(callback){ var sel=$(this); // if target is a tr, include td childrens cause background color on tr doesn't works in a lot of browsers if (sel.is('tr')) - sel.add('>td',sel); + sel = sel.add('>td',sel); sel.css('opacity','0.0').addClass('append').css({backgroundColor: color}).animate({opacity: "1.0"}, 1000,function(){ sel.animate({backgroundColor: origin}, 3000,function(){ sel.removeClass('append').css({backgroundColor: ''}); @@ -788,7 +933,7 @@ function parametre_url(url,c,v,sep,force_vide){ if (typeof(url) == 'undefined'){ url = ''; } - + var p; // lever l'#ancre var ancre=''; @@ -807,12 +952,13 @@ function parametre_url(url,c,v,sep,force_vide){ if (p>0) a=url.substring(0,p); args = url.substring(p+1).split('&'); } - else - a=url; - var regexp = new RegExp('^(' + c.replace('[]','\[\]') + '\[?\]?)(=.*)?$'); + else + a=url; + var regexp = new RegExp('^(' + c.replace('[]','\\[\\]') + '\\[?\\]?)(=.*)?$'); var ajouts = []; var u = (typeof(v)!=='object')?encodeURIComponent(v):v; var na = []; + var v_read = null; // lire les variables et agir for(var n=0;n2)?r[2].substring(1):''; + // c'est un tableau, on memorise les valeurs + if (r[1].substr(-2) == '[]') { + if (!v_read) v_read = []; + v_read.push((r.length>2 && typeof r[2]!=='undefined')?r[2].substring(1):''); + } + // c'est un scalaire, on retourne direct + else { + return (r.length>2 && typeof r[2]!=='undefined')?r[2].substring(1):''; + } } // suppression else if (!v.length) { } // Ajout. Pour une variable, remplacer au meme endroit, // pour un tableau ce sera fait dans la prochaine boucle - else if (r[1].substring(-2) != '[]') { + else if (r[1].substr(-2) != '[]') { na.push(r[1]+'='+u); ajouts.push(r[1]); } - else na.push(args[n]); + /* Pour les tableaux ont laisse tomber les valeurs de départ, on + remplira à l'étape suivante */ + // else na.push(args[n]); } else na.push(args[n]); } - if (v==null) return v; // rien de trouve + if (v==null) return v_read; // rien de trouve ou un tableau // traiter les parametres pas encore trouves if (v || v.length || force_vide) { ajouts = "="+ajouts.join("=")+"=";