(function($){ /* * crayons.js (c) Fil, toggg 2006-2007 -- licence GPL */ // le prototype configuration de Crayons $.prototype.cfgCrayons = function (options) { this.url_crayons_html = options['dir_racine']+'spip.php?action=crayons_html'; this.img = { 'searching':{'txt':'En attente du serveur ...'}, 'edit':{'txt':'Editer'}, 'img-changed':{'txt':'Deja modifie'} }; this.txt = { }; for (opt in options) { this[opt] = options[opt]; } }; $.prototype.cfgCrayons.prototype.mkimg = function(what, extra) { return ''; /* return ''; */ }; $.prototype.cfgCrayons.prototype.iconclick = function(c) { // le + qui passe en prive pour editer tout si classe type--id var link = c.match(/\b(\w+)--(\d+)\b/); link = link ? '' + this.mkimg('edit', ' (' + link[1] + ' ' + link[2] + ')') + '' : ''; var cray = c.match(/\b\w+-(\w+)-\d+\b/); var boite = !cray ? '' : this.mkimg('crayon', ' (' + cray[1] + ')'); return " "; }; function entity2unicode(txt) { var reg = txt.split(/(\d+);/i); for (var i = 1; i < reg.length; i+=2) { reg[i] = String.fromCharCode(parseInt(reg[i])); } return reg.join(''); }; function uniAlert(txt) { alert(entity2unicode(txt)); }; function uniConfirm(txt) { return confirm(entity2unicode(txt)); }; // donne le crayon d'un element $.fn.crayon = function(){ if (this.length) return $( $.map(this, function(a){ return '#'+($(a).find('.crayon-icones').attr('rel')); }) .join(',')); else return $([]); }; // ouvre un crayon $.fn.opencrayon = function(evt, percent) { if (evt && evt.stopPropagation) { evt.stopPropagation(); } return this .each(function(){ // verifier que je suis un crayon if (!$(this).is('.crayon')) return; // voir si je dispose deja du crayon comme voisin if ($(this).is('.crayon-has')) { $(this) .css('visibility','hidden') .crayon() .show(); } // sinon charger le formulaire else { // sauf si je suis deja en train de le charger (lock) if ($(this).find("em.crayon-searching").length) { return; } $(this) .find('>span.crayon-icones span') .append(configCrayons.mkimg('searching')); // icone d'attente var me=this; var params = { 'w': $(this).width(), 'h': $(this).height(), 'wh': window.innerHeight, 'em': $(this).px('fontSize'), // eviter un bug MSIE sur fontSize 'class': me.className, 'color': $(this).css('color'), 'font-size': $(this).px('fontSize'), 'font-family': $(this).css('fontFamily'), 'font-weight': $(this).css('fontWeight'), 'line-height': $(this).css('lineHeight'), 'background-color': $(this).css('backgroundColor'), 'self': configCrayons.self }; if (params['background-color'] == 'transparent' || params['background-color'] == 'rgba(0, 0, 0, 0)') { $(me).parents() .each(function(){ var bg = $(this).css('backgroundColor'); if (bg != 'transparent' && (params['background-color'] == 'transparent' || params['background-color'] == 'rgba(0, 0, 0, 0)')) params['background-color'] = bg; }); } $.post(configCrayons.url_crayons_html, params, function (c) { eval('c = '+c); // JSON $(me) .find("em.crayon-searching") .remove(); if (c.$erreur) { uniAlert(c.$erreur); return false; } id_crayon++; var position = 'absolute'; $(me).parents().each(function(){ if($(this).css("position") == "fixed") position = 'fixed'; }); $(me) .css('visibility','hidden') .addClass('crayon-has') .find('>.crayon-icones') .attr('rel','crayon_'+id_crayon); if ($.browser.msie) $(me).css({'zoom':1}); var pos = $(me).offset({'scroll':false}); $('
') .css({ 'position':position, 'top':pos['top']-1, 'left':pos['left']-1 }) .appendTo('body') .html(c.$html); $(me) .activatecrayon(percent); } ); } }); }; // annule le crayon ouvert (fonction destructive) $.fn.cancelcrayon = function() { this .filter('.crayon-has') .css('visibility','visible') .removeClass('crayon-has') .removeClass('crayon-changed') .crayon() .remove(); return this; }; // masque le crayon ouvert $.fn.hidecrayon = function() { this .filter('.crayon-has') .css('visibility','visible') .crayon() .hide() .removeClass('crayon-hover'); return this; }; // active un crayon qui vient d'etre charge $.fn.activatecrayon = function(percent) { this .crayon() .click(function(e){ e.stopPropagation(); }); this .each(function(){ var me = $(this); var crayon = $(this).crayon(); crayon .find('form') .append( $('') .attr('value',configCrayons.self) ) .ajaxForm({ "dataType":"json", "success": function(d) { me .find("em.crayon-searching") .remove(); if (d.$erreur > '') { if (d.$annuler) { if (d.$erreur > ' ') { uniAlert(d.$erreur); } me .cancelcrayon(); } else { uniAlert(d.$erreur+'\n'+configCrayons.txt.error); crayon .find('form') .css('opacity', 1.0) .find(".crayon-boutons,.resizehandle") .show() .end() .find('.crayon-searching') .remove(); } return false; } // Desactive celui pour qui on vient de recevoir les nouvelles donnees $(me) .cancelcrayon(); // Insere les donnees dans *tous* les elements ayant le meme code $( '.crayon.crayon-autorise.' + me[0].className.match(/crayon ([^ ]+)/)[1] ) .html( d[$('input.crayon-id', crayon).val()] ) .iconecrayon(); }}) .one('submit', function(){ crayon .find('form') .css('opacity', 0.5) .after(configCrayons.mkimg('searching')) // icone d'attente .find(".crayon-boutons,.resizehandle") .hide(); }) // keyup pour les input et textarea ... .keyup(function(e){ crayon .find(".crayon-boutons") .show(); me .addClass('crayon-changed'); e.cancelBubble = true; // ne pas remonter l'evenement vers la page }) // ... change pour les select : ici on submit direct, pourquoi pas .change(function(e){ crayon .find(".crayon-boutons") .show(); me .addClass('crayon-changed'); e.cancelBubble = true; }) .keypress(function(e){ e.cancelBubble = true; }) .find(".crayon-active[@type!=file]") .each(function(n){ // focus pour commencer a taper son texte directement dans le champ // on essaie de positionner la selection (la saisie) au niveau du clic // ne pas le faire sur un input de [@type=file] if (n==0) { this.focus(); // premiere approximation, en fonction de la hauteur du clic var position = parseInt(percent * this.textLength); this.selectionStart=position; this.selectionEnd=position; } }) .keydown(function(e){ if(!e.charCode && e.keyCode == 119 /* F8, windows */) { crayon .find("form.formulaire_crayon") .submit(); } }) .keypress(function(e){ if (e.keyCode == 27) { me .cancelcrayon(); } // Clavier pour sauver if ( (e.ctrlKey && ( /* ctrl-s ou ctrl-maj-S, firefox */ ((e.charCode||e.keyCode) == 115) || ((e.charCode||e.keyCode) == 83)) /* ctrl-s, safari */ || (e.charCode==19 && e.keyCode==19) ) ) { crayon .find("form.formulaire_crayon") .submit(); } var maxh = this.className.match(/\bmaxheight(\d+)?\b/); if (maxh) { maxh = maxh[1] ? parseInt(maxh[1]) : 200; maxh = this.scrollHeight < maxh ? this.scrollHeight : maxh; if (maxh > this.clientHeight) { $(this).css('height', maxh + 'px'); } } }) .end() .find(".crayon-submit") .click(function(e){ e.stopPropagation(); $(this) .parents("form:eq(0)") .submit(); }) .end() .find(".crayon-cancel") .click(function(e){ e.stopPropagation(); me .cancelcrayon(); }) .end() // decaler verticalement si la fenetre d'edition n'est pas visible .each(function(){ var offset = $(this).offset({'scroll':false}); var hauteur = parseInt($(this).css('height')); var scrolltop = $(window).scrollTop(); var h = $(window).height(); if (offset['top'] - 5 <= scrolltop) $(window).scrollTop(offset['top'] - 5); else if (offset['top'] + hauteur - h + 20 > scrolltop) $(window).scrollTop(offset['top'] + hauteur - h + 30); // Si c'est textarea, on essaie de caler verticalement son contenu // et on lui ajoute un resizehandle $("textarea", this) .each(function(){ if (percent && this.scrollHeight > hauteur) { this.scrollTop = this.scrollHeight * percent - hauteur; } }) .resizehandle() // decaler les boutons qui suivent un resizer de 16px vers le haut .next('.resizehandle') .next('.crayon-boutons') .css('margin-top', '-16px'); }) .end(); }); }; // insere les icones dans l'element $.fn.iconecrayon = function(){ return this.each(function() { $(this).prepend(configCrayons.iconclick(this.className)) .find('.crayon-crayon, .crayon-img-changed') // le crayon a clicker lui-meme et sa memoire .click(function(e){ $(this).parents('.crayon:eq(0)').opencrayon(e); }); }); }; // initialise les crayons $.fn.initcrayon = function(){ this .addClass('crayon-autorise') .dblclick(function(e){ $(this).opencrayon(e, // calcul du "percent" du click par rapport a la hauteur totale du div ((e.pageY ? e.pageY : e.clientY) - document.body.scrollTop - this.offsetTop) / this.clientHeight); }) .iconecrayon(); // :hover pour MSIE this.hover( function(){ $(this) .addClass('crayon-hover') .find('>span.crayon-icones') .find('>span>em.crayon-crayon,>span>em.crayon-edit') .show();//'visibility','visible'); },function(){ $(this) .removeClass('crayon-hover') .find('>span.crayon-icones') .find('>span>em.crayon-crayon,>span>em.crayon-edit') .hide();//('visibility','hidden'); } ); return this; }; /* une fonction pour initialiser les crayons dynamiquement */ $.fn.initcrayons = function(){ this .find('.crayon') .not('.crayon-autorise') .filter(configCrayons.droits) .initcrayon(); }; // demarrage $.fn.crayonsstart = function() { if (!configCrayons.droits) return; id_crayon = 0; // global // sortie, demander pour sauvegarde si oubli if (configCrayons.txt.sauvegarder) { $(window).unload(function(e) { var chg = $(".crayon-changed"); if (chg.length && uniConfirm(configCrayons.txt.sauvegarder)) { chg.crayon().find('form').submit(); } }); } // on limite l'init auto aux 1000 premiers crayons // setTimeout sert a passer en execution asynchrone pour confort d'affichage if ((typeof crayons_init_dynamique == 'undefined') || (crayons_init_dynamique==false)) setTimeout(function(){ $(".crayon:lt(1000)") .filter(configCrayons.droits) .initcrayon(); }, 300); // un clic en dehors ferme tous les crayons ouverts ? if (configCrayons.cfg.clickhide) $("html") .click(function(){ $('.crayon-has') .hidecrayon(); }); }; })(jQuery);