J'ai voulu mettre en place l'obfuscation de lien dans un menu Magento assez simplement.
La première étape a été assez simple : modification des balises <a> par des <span>, encodage via la fonction php base64_encode de l'url et ajout du javascript coté frontoffice (au clic, on décode l'url en js et on y va !).
Tout fonctionnait très bien, sauf que : le premier clic sur le "lien" ne marchait pas. Il fallait cliquer deux fois pour aller sur la page voulue.
Après être revenu sur le thème Blank de Magento2 en vain, j'ai commencé à parcourir les js component de Magento dans le dossier lib/web à la recherche des modifications d'événements click, mousedown, etc...
C'est finalement le fichier : ...lib/web/jquery-ui-modules/menu.js qui posait problème.
Petit récapitulatif de fonctionnement....
Doc : https://devdocs.magento.com/guides/v2.3/extension-dev-guide/build/di-xml-file.html
<preference for="Magento\Theme\Block\Html\Topmenu" type="FastCooling\Catalog\Block\Html\Topmenu"/>
class Topmenu extends \Magento\Theme\Block\Html\Topmenu
{
.....
$html .= '<span class="atc" data-atc="' . base64_encode($child->getUrl()) . '" ' . $outermostClassCode . '>' . $this->escapeHtml(
$child->getName()
) . '</span>' . $this->_addSubMenu(
$child,
$childLevel,
$childrenWrapClass,
$limit
) . '</li>';
.....
Source du code JS : https://www.410-gone.fr/seo/optimisation-on-site/maillage-interne/cocon-semantique/obfuscation.html
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
var classname = document.getElementsByClassName("atc");
for (var i = 0; i < classname.length; i++) {
//click gauche
classname[i].addEventListener('click', mySEOFunction, false);
//click droit
classname[i].addEventListener('contextmenu', myRightFunction, false);
}
});
//fonction du click gauche
var mySEOFunction = function(event) {
var attribute = this.getAttribute("data-atc");
if(event.ctrlKey) {
var newWindow = window.open(decodeURIComponent(window.atob(attribute)), '_blank');
newWindow.focus();
} else {
document.location.href= decodeURIComponent(window.atob(attribute));
}
};
//fonction du click droit
var myRightFunction = function(event) {
var attribute = this.getAttribute("data-atc");
if(event.ctrlKey) {
var newWindow = window.open(decodeURIComponent(window.atob(attribute)), '_blank');
newWindow.focus();
} else {
window.open(decodeURIComponent(window.atob(attribute)),'_blank');
}
}
</script>
Ajout de la surchage dans le fichier requirejs-config.js de votre thème
Doc : https://devdocs.magento.com/guides/v2.3/javascript-dev-guide/javascript/custom_js.html
map: {
"*": {
"jquery-ui-modules/menu": "js/jquery/ui-modules/menu"
}
}
Copie du fichier menu.js dans votre dossier template app/design/frontend/Vendor/theme/web/js/jquery/ui-modules/menu (selon la surcharge faite dans votre requirejs) et modification du code problématique
focus: function (event, keepActiveItem) {
// If there's already an active item, keep it active
// If not, activate the first item
var item = this.active || this.element.children(".ui-menu-item").eq(0);
if (!keepActiveItem) {
//Désactivation du focus pour permettre le premier clic directement
//this.focus(event, item);
}
},