NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name fragilite
// @author Nicolas Le Gland
// @copyright 2018-2022, nicolaslegland (https://openuserjs.org/users/nicolaslegland)
// @description Fragilité oculaire. Retire les points medians, pour celles-et-ceux qui ne tolèrent pas leur usage en écriture inclusive.
// @downloadURL https://openuserjs.org/src/scripts/nicolaslegland/fragilite.user.js
// @exclude https://openuserjs.org/scripts/nicolaslegland/fragilite/source
// @grant none
// @homepageURL https://openuserjs.org/scripts/nicolaslegland/fragilite
// @icon https://www.w3.org/html/logo/downloads/HTML5_Badge_32.png
// @license GPL-3.0-or-later
// @match *://*/*
// @run-at document-end
// @supportURL https://openuserjs.org/scripts/nicolaslegland/fragilite/issues
// @updateURL https://openuserjs.org/src/scripts/nicolaslegland/fragilite.user.js
// @version 12
// ==/UserScript==
// Find middot
function gFind()
{
// Suspend observer
g_oObserver.disconnect();
window.clearTimeout(g_oTimer);
// Create a document walker
var
l_oNode,
l_oText,
l_oWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, {acceptNode: function (a_oNode)
{
// Skip whitespace and focused element
if (('' === a_oNode.nodeValue.trim()) || (document.activeElement.isContentEditable && document.activeElement.contains(a_oNode)))
{
return NodeFilter.FILTER_SKIP;
}
return NodeFilter.FILTER_ACCEPT;
}
}, false);
// Walk the document
while (null !== (l_oNode = l_oWalker.nextNode()))
{
// Replace text
l_oNode.nodeValue = gReplace(l_oNode.nodeValue);
}
// Restart observer
g_oObserver.observe(document.body,
{
childList: true,
subtree: true,
});
}
// Replace middot
function gReplace(a_sText)
{
// Loop through replacement map
var l_iCount = g_oMap.length;
for (var l_iIndex = 0; l_iCount !== l_iIndex; ++l_iIndex)
{
// Apply one replacement rule
a_sText = a_sText.replace(g_oMap[l_iIndex][0], g_oMap[l_iIndex][1]);
}
return a_sText;
}
// Convert HTML to text
function gText(a_sHTML)
{
// Helper element
var l_oElement = document.createElement("textarea");
l_oElement.innerHTML = a_sHTML;
return l_oElement.value;
}
// Replacement map
var
g_oMap =
[
['([•·.-])(?:e|ine|le|ne|se|te)\\1', ''],
['(.)[•·.-]l?e([ ,s]|$)', '$1$2'],
['eur[•·.-](?:euse|rice)', 'eur'],
['[•·.-](?:te)?(s)(?:\/s)?', '$1'],
]
.map(function (a_oRule)
{
// Convert to a regular expression
a_oRule[0] = new RegExp(gText(a_oRule[0]), 'gi');
a_oRule[1] = gText(a_oRule[1]);
return a_oRule;
}),
// Obverse additions of nodes
g_oObserver = new MutationObserver(function ()
{
// Rearm delayed process
window.clearTimeout(g_oTimer);
g_oTimer = window.setTimeout(gFind, 1000);
}),
// Delay process
g_oTimer = window.setTimeout(gFind, 1000);
// Self test
[
// https://openuserjs.org/scripts/nicolaslegland/fragiliteoculaire
['celles-et-ceux', 'celles-et-ceux'],
// https://www.freenews.fr/freenews-edition-nationale-299/iliad-6/emploi-free-recrute-des-technicien%C2%B7ne%C2%B7s-itinerant%C2%B7e%C2%B7s-resume
['Free recrute des technicien·ne·s itinérant·e·s', 'Free recrute des techniciens itinérants'],
// https://www.gamekult.com/jeux/gran-turismo-sport-3050570077/test.html
['apprenti·e·s pilotes', 'apprentis pilotes'],
['joueur·se·s plus aguerri·e·s', 'joueurs plus aguerris'],
['être prêt·e pour claquer un joli chrono', 'être prêt pour claquer un joli chrono'],
['être amené·e à croiser', 'être amené à croiser'],
['24 concurrent·e·s', '24 concurrents'],
['un·e ou deux potes', 'un ou deux potes'],
['parties entre ami·e·s', 'parties entre amis'],
['comportement des concurrent·e·s', 'comportement des concurrents'],
['étourdi·e·s de la pédale de frein', 'étourdis de la pédale de frein'],
['calmer les ardeurs des malotru·e·s', 'calmer les ardeurs des malotrus'],
['vous êtes impliqué·e·s', 'vous êtes impliqués'],
['des taré·e·s du volant', 'des tarés du volant'],
['vous êtes impliqué·e dans des accidents', 'vous êtes impliqué dans des accidents'],
['donner aux joueur·se·s', 'donner aux joueurs'],
['bousiller les chronos des copain·ine·s', 'bousiller les chronos des copains'],
['animé·e·s par la même passion', 'animés par la même passion'],
['futur·e·s fans', 'futurs fans'],
['néophyte bienvenu·e', 'néophyte bienvenu'],
// https://www.mairie02.paris.fr/ma-mairie/petite-enfance/assistant-e-s-maternel-le-s-agree-e-s-29
['assistant-e-s maternel-le-s agréé-e-s', 'assistants maternels agréés'],
['un-e assistant-e maternel-le agréé-e', 'un assistant maternel agréé'],
['pour être agréé-e, l\'assistant-e maternel-le doit', 'pour être agréé, l\'assistant maternel doit'],
['l\'assistant-e maternel-le doit être affilié-e', 'l\'assistant maternel doit être affilié'],
['emploi d\'un-e assistant-e maternel-le', 'emploi d\'un assistant maternel'],
// https://twitter.com/RocwoSifwedi/status/1565336779145695233
['tou·tes', 'tous'],
['tou•tes', 'tous'],
['tou•tes/s', 'tous'],
['tou•s', 'tous'],
// https://twitter.com/MathisHammel/status/1565332210886258690
['Comme certain·es s\'offusquent', 'Comme certains s\'offusquent'],
['Si vous êtes trop fermé·e d\'esprit', 'Si vous êtes trop fermé d\'esprit'],
['un mini "tou.te.s" ils sont pas prêts pour développeur.euse', 'un mini "tous" ils sont pas prêts pour développeur'],
]
.map(function (a_oTest)
{
// Compare expectations and result
var
l_sSource = gText(a_oTest[0]),
l_sResult = gReplace(l_sSource),
l_sTarget = gText(a_oTest[1]);
if (l_sResult !== l_sTarget)
{
// Log mismatch
console.log('Source: ' + l_sSource);
console.log('Result: ' + l_sResult);
console.log('Target: ' + l_sTarget);
}
});