// 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(){};
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]);
};
// 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
jQuery.spip.virtualbuffer_id='spip_virtualbufferupdate';
jQuery.spip.initReaderBuffer = function(){
if (jQuery('#'+jQuery.spip.virtualbuffer_id).length) return;
- jQuery('body').append('<p style="float:left;width:0;height:0;position:absolute;left:-5000;top:-5000;"><input type="hidden" name="'+jQuery.spip.virtualbuffer_id+'" id="'+jQuery.spip.virtualbuffer_id+'" value="0" /></p>');
+ jQuery('body').append('<p style="float:left;width:0;height:0;position:absolute;left:-5000px;top:-5000px;"><input type="hidden" name="'+jQuery.spip.virtualbuffer_id+'" id="'+jQuery.spip.virtualbuffer_id+'" value="0" /></p>');
}
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(){
// 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('<div class="ariaformprop" aria-live="assertive" aria-atomic="true"></div>');
+ this.wrap('<div class="ariaformprop" aria-live="polite" aria-atomic="true" aria-relevant="additions"></div>');
+ // 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;
}
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("<p class='error ajax-error none'>"+msg+"</p>").find('.ajax-error').show('fast');
+ jQuery(cible).closest('.ariaformprop').endLoading(true);
+ }
jQuery(this).prepend("<input type='hidden' name='var_ajax' value='form' />")
.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('<div />');
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();
// 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("<input type='hidden' name='"+n+"' value='"+leclk.value+"' />");
if (leclk.type == "image") {
jQuery(leform).prepend("<input type='hidden' name='"+n+".x' value='"+leform.clk_x+"' />");
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
// 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');
});
});
}
.find('form')
.attr('data-verifjson','on')
.find('input,select,textarea')
- .bind('change',check);
+ .on('change', check);
}
}
jQuery(activer);
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) {
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
}
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;
+ }
}
}
*/
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]=="<!--loading-->"){
* @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<args.length;n++){
+ arg = args[n].split('=');
+ arg = arg[0];
+ p = arg.indexOf('[');
+ if (p!==-1)
+ arg = arg.substring(0,p);
+ val = parametre_url(href,arg);
+ if (typeof val=="undefined" || val==null)
+ url[0] = url[0] + '&' + arg + '=';
+ }
+ }
+ }
+
if (url[1])
url[0] = parametre_url(url[0],'var_ajax_ancre',url[1]);
return url[0];
* @param object blocfrag
* @param object options
* callback : fonction appelee apres le rechargement
+ * href : url to load instead of origin url
* args : arguments passes a l'url rechargee (permet une modif du contexte)
* history : bool to specify if navigation history is modified by reload or not (false if not provided)
*/
jQuery.spip.ajaxReload = function(blocfrag, options){
var ajax_env = blocfrag.attr('data-ajax-env');
if (!ajax_env || ajax_env==undefined) return;
- var href = blocfrag.attr('data-url') || blocfrag.attr('data-origin');
+ var href = options.href || blocfrag.attr('data-url') || blocfrag.attr('data-origin');
if (href && typeof href != undefined){
- options == options || {};
+ options = options || {};
var callback=options.callback || null;
var history=options.history || false;
var args = options.args || {};
for (var key in args)
href = parametre_url(href,key,args[key]==undefined?'':args[key],'&',args[key]==undefined?false:true);
- var url = jQuery.spip.makeAjaxUrl(href,ajax_env);
+ var url = jQuery.spip.makeAjaxUrl(href,ajax_env,blocfrag.attr('data-origin'));
// recharger sans historisation dans l'url
jQuery.spip.loadAjax(blocfrag, url, href, {force:true, callback:callback, history:history});
return true;
if ((d.getTime()-ajax_confirm_date)<=2)
return false;
}
- var url = jQuery.spip.makeAjaxUrl(href,ajax_env);
+ var url = jQuery.spip.makeAjaxUrl(href,ajax_env,blocfrag.attr('data-origin'));
jQuery.spip.loadAjax(blocfrag, url, href, options);
return false;
}
if (ajaxbloc_selecteur==undefined)
ajaxbloc_selecteur = '.pagination a,a.ajax';
- return this.each(function() {
- // traiter les enfants d'abord :
- // un lien ajax provoque le rechargement
- // du plus petit bloc ajax le contenant
- jQuery('div.ajaxbloc',this).ajaxbloc();
+ return this.each(function() {
+ // traiter les enfants d'abord :
+ // un lien ajax provoque le rechargement
+ // du plus petit bloc ajax le contenant
+ jQuery('div.ajaxbloc',this).ajaxbloc();
var blocfrag = jQuery(this);
var ajax_env = blocfrag.attr('data-ajax-env');
if (!ajax_env || ajax_env==undefined) return;
- blocfrag.not('.bind-ajaxReload').bind('ajaxReload',function(event, options){
- if (jQuery.spip.ajaxReload(blocfrag,options))
+ blocfrag.not('.bind-ajaxReload').on('ajaxReload', function(event, options){
+ if (jQuery.spip.ajaxReload(blocfrag,options))
// don't trig reload of parent blocks
event.stopPropagation();
- }).addClass('bind-ajaxReload');
+ }).addClass('bind-ajaxReload')
+ .attr('aria-live','polite').attr('aria-atomic','true');
+
+ // dans un formulaire, le screen reader relit tout a chaque saisie d'un caractere si on est en aria-live
+ // mettre un aria-live="off" sur les forms inclus dans ce bloc aria-live="polite"
+ jQuery('form',this).not('[aria-live]').attr('aria-live','off');
jQuery(ajaxbloc_selecteur,this).not('.noajax,.bind-ajax')
.click(function(){return jQuery.spip.ajaxClick(blocfrag,this.href,{force:jQuery(this).is('.nocache'),history:!(jQuery(this).is('.nohistory')||jQuery(this).closest('.box_modalbox').length)});})
.addClass('bind-ajax')
.filter('.preload').each(function(){
var href = this.href;
- var url = jQuery.spip.makeAjaxUrl(href,ajax_env);
+ var url = jQuery.spip.makeAjaxUrl(href,ajax_env,blocfrag.attr('data-origin'));
if (!jQuery.spip.preloaded_urls[url]) {
jQuery.spip.preloaded_urls[url] = '<!--loading-->';
jQuery.ajax({url:url,onAjaxLoad:false,success:function(r){jQuery.spip.preloaded_urls[url]=r;},error:function(){jQuery.spip.preloaded_urls[url]='';}});
jQuery('form.bouton_action_post.ajax', this).not('.noajax,.bind-ajax').each(function(){
var leform = this;
var url = jQuery(this).attr('action').split('#');
+ var scrollwhensubmit = (!jQuery(this).is('.noscroll') && !jQuery('.submit',this).is('.noscroll'));
jQuery(this)
.prepend("<input type='hidden' name='var_ajax' value='1' /><input type='hidden' name='var_ajax_env' value='"+(ajax_env)+"' />"+(url[1]?"<input type='hidden' name='var_ajax_ancre' value='"+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
});
});
};
* @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)
*/
*/
jQuery.fn.animateRemove = function(callback){
if (this.length){
+ var me=this;
var color = $("<div class='remove'></div>").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
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: ''});
if (typeof(url) == 'undefined'){
url = '';
}
-
+
var p;
// lever l'#ancre
var ancre='';
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;n<args.length;n++){
var val = args[n];
var r=val.match(regexp);
if (r && r.length){
if (v==null){
- return (r.length>2)?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("=")+"=";