Plugin PluXML : C'est en off, mais stylé... [Edit]

Un autre petit plugin vite-fait-sur-le-gaz comme aurait dit San Antonio: cette fois-ci, il s'agit de styler les commentaires et articles offline pour les repérer plus simplement.

icon.png offlineClass

Le plugin se contente d'ajouter une classe de votre choix (à configurer) dans la ligne de tout commentaire ou article hors ligne.

Comme pour le précédent, il injecte un JS qui ajoute la classe au tr qui contient une liste offline.

Une fois activé, configurez le plugin en lui donnant la classe à utiliser ( par exemple «offline» ) puis ajoutez votre css à votre thème.

.offline{ 
    background:rgba(255,0,0,0.2);
    color:rgb(50,0,0);
    font-style: italic;
}
.offline td{
    padding:1em 0;
}

C'est tout. Mais visuellement, c'est autre chose !

[Edit du 02-09]

J'ai ajouté la possibilité de déplacer tout item offline en début de liste quelle que soit sa date... Utile si vous avez tendance à accumuler le boulot en retard au point que certains disparaissent dans la pagination...

Pour récupérer le zip ➜ https://repo.warriordudimanche.net/ZIPFILES/offlineClass.zip

(...)

Plugin PluXML : Empêcher pluXML de virer les backslashes des articles

Ze problaim

Si tu publies des bouts de code sur pluXML, tu as sans doute remarqué que ce dernier est pour le moins psychorigide avec les antislashes: il les vire sans ménagement... pourtant, on aimerait bien qu'il conserve les regex en l'état dans un code par exemple.

Je suis pas stupide, je comprends bien qu'il s'agit là d'un souci de sécurité, mais quand même, ça fait ch***.

Le souci,c'est que pluXML filtre les antislashes dans les $_POST très très tôt dans le code, bien avant tout hook de plugin: il le fait dans le prepend.php de l'admin, ligne 43.

Ben mon con, comment tu vas faire si tu peux pas intervenir en php via un hook pour modifier le $_POST?

Ze solouchonne

Ben tu le modifies en JS dans la page article lors du submit du formulaire

En gros, on remplace les «\» par des «\» dans le chapo et le avant de submit le formulaire. C'est une méthode dont j'ai trouvé l'idée ici https://forum.pluxml.org/discussion/6960/plugin-plx-cssbackslash-pour-ledition-des-fichiers-css

Donc, j'injecte un petit script JS via le hook AdminArticleFoot et il se charge d'intervenir lorsque le navigateur a terminé de créer l'objet formData: c'est d'ailleurs cet évènement qu'on va utiliser dans addEventListener au lieu du submit habituel.

Code du script injecté

(function (){
    let chapo = document.getElementById("id_chapo");
    var content = document.getElementById("id_content");
    var form = document.getElementById("form_article");
    function saveSlashes(str){
        return str.replace(/[\\]/g, '\\$&');
    }
    form.addEventListener('formdata',function(e){
        let formData = e.formData;
        formData.set('chapo', saveSlashes(formData.get('chapo')));
        formData.set('content', saveSlashes(formData.get('content')));
    });

})();

Ze saiquiouriti ?

Niveau sécurité, le plugin n'intervient que sur la page article.php et uniquement sur les champs chapo et content du formulaire. Il ne bloque pas le plxUtils::unSlash($_POST) du prepend.php. Je pense donc qu'il n'ouvre pas de faille majeure.

Ze conclugionne

Ainsi, les antislashes de ce script tiré de l'article sur le bug de mpdération passent enfin sans problème :

Exemple de code problématique

    const PATTERNS = array(
        'arts'          => '#^\D?(\d{4,})\.(?:\w+|\d{3})(?:,\w+|,\d{3})*\.\d{3}\.\d{12}\..*\.xml$#',
        'statiques'     => '#^(\d{3,})\..*\.php$#',
        'commentaires'  => '#^_?\d{4,}\.(?:\d{10,})(?:-\d+)?\.xml$#'
    );

Le zip est à télécharger depuis mon repo : https://repo.warriordudimanche.net/ZIPFILES/ArticleBackslashesKeeper.zip

(...)

document.execCommand - Référence Web API | MDN

https://antoineboursin.fr/courses/creez-un-editeur-de-texte-wysiwyg

La vie est mal faite: je découvre document.execCommand() permettant de faire du richtext dans un élément contentEditable juste quand il est officiellement déclaré obsolète...

Bon, en même temps, sur stackoverflow, the holy baïbol, certains affirment que:

  1. oui, il est obsolète mais n'a pas d'alternative
  2. execCommand semble requis pour tout navigateur prétendant sortir sur le marché,
  3. son implémentation semble sujette à variations selon le navigateur (le fameux internet explorer syndrome de triste mémoire)
Mais merde !  Je fais quoi moi ?!

Javascript: tester la validité des liens d'une page afin de les styler

Petit bout de code fait à la va-vite dans le but de vérifier la validité des liens d'une page. Mon objectif est de pouvoir à terme montrer automatiquement les liens ne répondant plus sur la page où je regroupe les liens de téléchargement illégal

Le bout de code actuel

Dans le code ci-dessous, j'utilise fetch et les promesses pour lancer des requêtes afin de styler les liens testés:

function checkLinks(nodelist){
    function checkUrl(link){
        return fetch(link).then(function(response){     
            return response.status;
        }).catch(function(error){
            return error.status;
        });
    }
    if (!nodelist){
        checkLinks(document.querySelectorAll('.checkLink'));
        return;
    }
    for (let obj of nodelist){
        if (obj.tagName=="A"){
            checkUrl(obj.href).then(function(response){obj.classList.add("status"+response);});
        }else if (obj.hasAttribute("src")){
            checkUrl(obj.src).then(function(response){obj.classList.add("status"+response);});
        }else{
            checkLinks(obj.querySelectorAll("*[href],*[src]"));
        }
    }
}
checkLinks();

Explication rapide

Étape 1

J'ai d'abord fait une fonction qui appelle une URL et renvoie une promesse qui, une fois résolue, renverra le statut de la requête. On y retrouve .then qui renvoie le statut d'une requête qui aboutit et .catch qui renvoie celui d'une requête se soldant par une erreur.

function checkUrl(link){
        return fetch(link).then(function(response){     
            return response.status;
        }).catch(function(error){
            return error.status;
        });
    }

Les plus coquinous d'entre-vous me feront remarquer à juste titre que, vu ce que je renvoie, je pouvais me contenter de

function checkUrl(link){
        return fetch(link).then(function(response){     
            return response.status;
        });
    }

Ceci dit, en prévoyant les deux cas, je m'autorise à gérer le retour différemment selon si ça aboutit ou pas (par exemple retourner «ok200» ou «error404»

Étape 2:

Ce block n'est là que pour simplifier la vie de l'utilisateur en lui évitant de procéder lui-même au querySelectorAll()

if (!nodelist){
        checkLinks(document.querySelectorAll('.checkLink'));
        return;
    }

Étape 3:

Je parcours la nodeList en vérifiant l'URL passée en href (pour les A) ou en src (pour les img par exemple).

Le dernier cas est celui où l'on souhaite vérifier les liens contenus dans un div portant la classe .checkLink : il suffit d'appeler la même fonction de façon récursive en lui fournissant le nodeList des liens contenus das le DIV en question. (ça permet de vérifier un grand nombre de liens sans avoir à leur ajouter individuellement la classe .checkLink, ce qui est particulièrement utile quand on publie des articles en utilisant markdown )

for (let obj of nodelist){
        if (obj.tagName=="A"){
            checkUrl(obj.href).then(function(response){obj.classList.add("status"+response);});
        }else if (obj.hasAttribute("src")){
            checkUrl(obj.src).then(function(response){obj.classList.add("status"+response);});
        }else{
            checkLinks(obj.querySelectorAll("a,img"));
        }
    }

Comment on l'utilise ?

Il suffit de mettre la classe .checkLink à tout objet dont on veut tester les liens et de coller la fonction dans la page puis de l'appeler via un checkLinks(); de bon aloi.

En l'état, la fonction ajoutera une classe .status200 pour les liens ok ou .status404 pour les URL qui ne répondent plus.

Il ne reste plus qu'à styler ces classes en changeant la couleur, le fond ou en ajoutant des emoji avec un petit content. On peut même éventuellement masquer un objet dont l'URL ne répond pas...

Limites

Le script étant en JS, il se heurte évidemment aux règles de la politique CORS: toute requête hors du domaine en cours va échouer à moins de redéfinir le CORS dans le Head de la page via

<meta http-equiv="Content-Security-Policy" content="Content-Security-Policy:..."/>

Licence

Comme d'habitude, il s'agit autant d'un proof of concept que d'une truc utile... en tout cas, n'hésitez pas à en faire rigoureusement ce que vous voulez: c'est cadeau...

Templating in HTML | Kitty Giraudel

L'élément template pour créer des objets à cloner via javascript de façon plus sémantique que via des div cachées.

avantages

  • l'élément template est inerte: les styles ne s'appliquent pas, les images ne se chargent pas
  • pas de content model validation
  • largement supporté (98%)
  • le CSS qui cache un div peut échouer, être désactive ou redéfini ailleurs alors que template est toujours caché
  • les moteurs de recherche peuvent indexer des div cachées, pas les template (à priori)
Via https://nicolas-delsaux.hd.free.fr/Shaarli/?whpPuw

HTML Drag and Drop API - Web APIs | MDN

Merci @Timo pour ce résumé qui explique bien des déboires personnels avec le Drag&drop.

Je me résume ça ici:

  1. un élément acceptera un 👉drop et déclenchera ⚡ondrop si et seulement si l’élément a un ⚡onDragEnter ET un ⚡onDragOver.
  2. 🔧event.target != 🔧event.currentTarget: event.target est l'objet qui reçoit l'événement alors que event.currentTarget est celui quel les gestionnaires d'événements sont attachés et ils peuvent être différents dans le cas d'objets imbriqués.
Via https://lehollandaisvolant.net/?mode=links

GitHub - LeaVerou/md-block: A custom element for rendering stylable (light DOM) Markdown

Un web component pour faire du markdown facilement par Lea Verou. Hop, de côté.

  • Zero dependencies (except marked, obvs, which is only loaded if a <md-block> or <md-span> element is actually used on the page)
  • Styleable with regular selectors, just like the rest of the page
  • Load external Markdown files or render inline content
  • Customize start heading level
  • Also comes with , for lightweight inline markdown
  • Prism is automatically used for syntax highlighting, if included (but can be included dynamically too)

Ha zut, comme dit ici https://bookmarks.ecyseo.net/?sAzyVQ ça ne fonctionne que sous chrome.... Merci copain...

POURQUOI ?! PFFF

GitHub - asvd/microlight: highlights code in any programming language - Le Hollandais Volant

De la «coloration syntaxique» en 2ko ? je prends ! La différenciation se fait en jouant sur l'intensité et le contraste de la couleur de base.

Très joli rendu en tout cas !

via TImo : https://lehollandaisvolant.net/?id=20220226192717

petit outil: Bookmarklet generator 🆕 [EDIT]

Si toi aussi tu veux te faire un petit bookmarklet pour envoyer des données de la page courante vers un autre site, alors tu vas kiffer 😍 parce que ce petit bout de code te permet de le faire sans rien coder 😎.

Heing ?! 🤨

J'explique:

Si on veut pouvoir:

  • rechercher une sélection sur un site particulier (genre sur wikipedia, jeux videos.com, allocine...) ,
  • envoyer le titre de la page en cours et/ou son URL vers un site qui va s'en servir (par exemple pour bookmarker la page en cours),

alors ça peut se faire ici.

Fais voir ?

Voici deux exemples:

Capture du 2022-04-02 11-54-34.png

Capture du 2022-04-02 12-12-53.png

Quid ?

Pour faire simple,

  1. on donne un nom au bookmarklet,
  2. on choisit les données qui doivent être envoyées,
  3. on spécifie l'URL vers laquelle elles doivent être envoyées.

Le bookmarklet est généré en temps réel et une fois les réglages faits, il suffit de glisser-déposer le lien du bas.

J'ai ajouté la possibilité de modifier la variable permettant de passer les données; en effet, duckduckgo utilisera q=[recherche] mais un autre site pourra demander query=[recherche]...

De plus, on peut spécifier de ne pas utiliser le format URL?variable=[donnée] mais URL/[donnée] pour les sites ayant une rewriteurl (comme wikipedia qui exige un format fr.wikipedia.org/wiki/[RECHERCHE] )

Enfin, si vous spécifiez une URL contenant déjà des paramètres GET (comme mespagesquejaime.com/ajouter.php?user=MOI&apikey=321fd5613e32), le script le prendra en compte et les nouveaux paramètres s'ajouteront correctement ( mespagesquejaime.com/ajouter.php?user=MOI&apikey=321fd5613e32&title=mon cul sur la commode&url=www.monculsurlacommode.fr )

Exemple ?

Vous pouvez essayer de générer un bookmarklet pour rechercher directement la sélection sur youtube:

  1. donnez le nom «rechercher sur youtube»
  2. cochez le premier item : «le texte sélectionné» et renommez la variable en «search_query»
  3. remplissez la case URL avec : https://www.youtube.com/results/

Et voilà.

Ajout

Sur l'idée de DukeArt j'ai ajouté la possibilité d'éditer le code (vive contenteditable et obj.toggleAttribute 👍 ) ! Merci the Duke 🤘😎🤘

License

Vous pouvez utiliser librement et l'outil et le code en mode DBAD. Pour le télécharger, c'est par là

Il est possible de l'utiliser sans serveur php vu que c'est du HTML+JS vanilla (mais le script de téléchargement du script ne fonctionnera pas).

Nouveau ! Bloguons JavaScript

J'adore Mastodon : tu suis quelqu'un parce que tu l'as trouvé drôle et tu apprends qu'il a un blog sur le javascript qu'il partage parce que « il se dit qu'il ne doit pas être le seul javascripteur sur la planète.»

Si vous vous dites, mouais encore un blog sur JS, gardez à l'esprit que voilà un bloggueur qui intitule un billet «jQuery doit mourir», qui écrit qu'XMLHttpRequest est «inutilement compliqué» mais que dieu merci on a créé fetch, même si on ne comprend pas toujours bien ce qu'il renvoie...

Et là, je suis certain   que vous allez y jeter   un oeil !
En tout cas, je souhaite   une longue vie à   Blogons javascript !

Developer Tools secrets that shouldn’t be secrets | Christian Heilmann

Donc, pour résumer:

  • pour avoir le nom des variables avec leur valeur, utiliser { }: console.log({var})
  • console.warn(), console.error() et console.info() pour différencier l'aspect du message.
  • console.assert(condition,retour) pour éviter un if (condition){console.log(retour)
  • console.trace() pour remonter la pile d'appels
  • console.group('nom'), console.groupCollapsed('nom') et console.groupEnd('nom') pour regrouper des console log()
  • console.table(array) pour présenter les données sous forme de tableau
  • $(selecteur) est équivalent à document.querySelector(selecteur)
  • $$(selecteur) est équivalent à document.querySelectorAll(selecteur)
Via https://lehollandaisvolant.net/?mode=links

ASTUCE: Body qui apparait après chargement en 2 lignes

Un truc que je teste sur ma page de générateur de comics pour masquer le chargement de la page...

Minimaliste...


/* Dans le Head */
<style type="text/css">body{opacity: 0;transition: opacity 1s}
/* balise body */
<body onload="document.body.style.opacity=1" >

La synthèse vocale en JS: SILENCE DANS LA BIBLIOTHEQUE !

Comme mon cerveau ne cesse jamais vraiment d'avoir des idées et que le confinement est propice aux réflexions, à la créativité et aux projets, j'ai à l'idée de nouvelles applis de travail pour mes élèves.

Hélas, il me faudrait une bibliothèque JS qui me permette de faire de la synthèse vocale.

Mais attention, hein: je suis prof de langue, il me faut donc une synthèse vocale CORRECTE.

A la recherche de la bibliothèque perdue

J'ai eu beau chercher, je n'ai RIEN trouvé pour le moment, car il faut dire que je cherche une bibliothèque:

  • qui fasse bien son boulot: oui parce que la synthèse vocale de l'API native, pardon... je me croirais revenu à mon adolescence quand on faisait mumuse avec la synthèse vocale de l'atariST en écrivant «beesoo» pour obtenir un semblant de trucs vaguement compréhensible bien que particulièrement offensant à toute oreille humaine... Merci de ne pas plaisanter: nous sommes en 2021, j'estime pouvoir compter sur un minimum phonétique.
  • qui n'ait pas besoin d'un framework délirant pour fonctionner (genre REAC, Node.js etc). Si le projet doit embarquer plus de framework que de code natif et qu'il faut passer les six prochains mois à se former, je vois pas l'intérêt: une lib est censée FACILITER de travail.
  • qui n'utilise pas google: je chie à longueur d'année sur le G du gafam, c'est pas pour me précipiter dessus à la moindre déconvenue... ou alors en leur piquant une lib que j'hébergerais par la suite et qui ne fasse AUCUN appel à leurs serveurs.
  • qui soit gratuite: parce que. (oui, j'ai pas d'argument particulier mais j'aime pas payer des entreprises )
  • qui soit pérenne s'il s'agit d'un service tiers, je risque un beau matin d'en être privé sans prévenir et de me retrouver grosjean comme devant.

    Je demande pas grand chose   MERDE  .png

    Quelqu un a une idée     aïe .png

Fil RSS des articles