From 04feb4a550f979b9a8f15d14902f42ae243b1d23 Mon Sep 17 00:00:00 2001 From: Joffrey <541722+Write@users.noreply.github.com> Date: Sun, 1 Sep 2024 20:15:27 +0200 Subject: [PATCH] Les Echos : Enhance error handling (querySelector). Refactor MutationObservers. (#243) * Enhance error handling (querySelector). Refactor MutationObservers. - Reduce querySelector usage by passing metaElement to isPremium function. - Fix race condition. - Correctly disconnect observer. * Correctly check if metaElement exist in callbackTitle. Rename callbback to callbackDirectAccess to differentiate the two callbackes. Removing useless check in isPremium function * Rename observerTitle to observerDynamicLoading for better readability * LesEchos : Yet another try to fix the race conditions where two buttons are added --- ophirofox/content_scripts/lesechos.js | 59 ++++++++++++++------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/ophirofox/content_scripts/lesechos.js b/ophirofox/content_scripts/lesechos.js index dad48d5..3a06be8 100644 --- a/ophirofox/content_scripts/lesechos.js +++ b/ophirofox/content_scripts/lesechos.js @@ -3,15 +3,13 @@ function extractKeywords() { return titleElem && titleElem.textContent; } -let buttonAdded = false; - async function addEuropresseButton() { - if (!buttonAdded) { + const ophiroBtnPresence = document.querySelector('.ophirofox-europresse'); + if (!ophiroBtnPresence) { const elt = document.querySelector("button[aria-label=Commenter]")?.parentElement?.parentElement; if (elt) { const a = await ophirofoxEuropresseLink(extractKeywords()); elt.appendChild(a); - buttonAdded = true; } } } @@ -23,54 +21,57 @@ async function onLoad() { by a new meta with name ad:postAcces) and add the button (this is the first observer). 2. Or a page is newly routed (for instance, when one goes from the homepage to an article) : - it is detected with the second observer that watches for changes in and reset the button - - we wait for the end of actual loading of the new content by observing <main><meta content>. + - we wait for the end of actual loading of the new content by checking if meta[name="ad:postAccess"] exist. */ - const isPremium = () => { - if (document.querySelector("meta[name='ad:postAccess']").content == 'subscribers') { + const isPremium = (metaElement) => { + if (metaElement.content == 'subscribers') { return true; } return false; }; - const callback = (mutationList, observer) => { - if (document.querySelector('meta[name="ad:postAccess"]')) { - addEuropresseButton(); + // Observer [ Direct URL Access ] + const callbackDirectAccess = (mutationList, observer) => { + const metaElement = document.querySelector('meta[name="ad:postAccess"]'); + if (metaElement) { + if (isPremium(metaElement)) { + addEuropresseButton(); + } observer.disconnect(); return; } for (const mutation of mutationList) { for (const e of mutation.addedNodes) { if (e.name == "ad:postAccess") { - if (isPremium()) + if (isPremium(e)) { addEuropresseButton(); + } + observer.disconnect(); + return; } } } }; - const observer = new MutationObserver(callback); - observer.observe(document.body, { - childList: true - }); - - const observerTitle = new MutationObserver(() => { - buttonAdded = false; - if (isPremium()) - addEuropresseButton(); - }); - - const title = document.querySelector("title") - observerTitle.observe(title, { + const observerDirectAccess = new MutationObserver(callbackDirectAccess); + observerDirectAccess.observe(document.body, { childList: true, subtree: false }); - const observerMain = new MutationObserver(() => { - addEuropresseButton(); - }); - const main = document.querySelector("main meta[content]") - observerMain.observe(main, { + // Observer [ Dynamic page Loading ] + const callbackDynamicLoading = (mutationList, observer) => { + const metaElement = document.querySelector('meta[name="ad:postAccess"]'); + if (metaElement) { + if (isPremium(metaElement)) { + addEuropresseButton(); + } + } + }; + + const observerDynamicLoading = new MutationObserver(callbackDynamicLoading); + observerDynamicLoading.observe(document.querySelector('title'), { childList: true, subtree: false });