Skip to content

Commit ad21ae8

Browse files
authored
Support de l'icône dans la barre d'adresse (#323)
* Actually add link open in new tab support... * Appliqué stash: Début travaux icones cliquable dans barre de recherche * Full support of dynamic icons in firefox's address bar. New setting to disable icon in address bar. Differentiate browser type for message shown to user in config. * Fix check of settings to hide or show page_action's icon in address bar
1 parent 916d915 commit ad21ae8

File tree

8 files changed

+317
-64
lines changed

8 files changed

+317
-64
lines changed

ophirofox/background.js

Lines changed: 218 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1-
// Variables globales
1+
// ======== VARIABLES GLOBALES ========
22
let ophirofoxSettings;
33
let ophirofoxReadRequest = null;
44
let ophirofoxRequestType = null;
5+
let tabEuropresseData = {};
6+
let premiumUrls = new Map();
57

68
// Configuration des scripts de contenu
79
const europresse_content_script = {
810
css: ["/content_scripts/europresse_article.css"],
911
js: ["/content_scripts/europresse_article.js", "/content_scripts/europresse_search.js"]
1012
};
1113

14+
// ======== FONCTIONS UTILITAIRES ========
15+
16+
/**
17+
* Détermine le type de navigateur utilisé
18+
* @returns {string} - Type de navigateur ('firefox', 'chrome', ou 'unknown')
19+
*/
20+
function getBrowserType() {
21+
if (typeof browser !== "undefined") {
22+
return "firefox";
23+
} else if (typeof chrome !== "undefined") {
24+
return "chrome";
25+
} else {
26+
return "unknown";
27+
}
28+
}
29+
1230
// ======== FONCTIONS DE GESTION DES PARAMÈTRES ========
1331

1432
/**
@@ -29,6 +47,40 @@ function loadSettings() {
2947
});
3048
}
3149

50+
/**
51+
* Charge les données de requête depuis le stockage local
52+
*/
53+
function loadRequestData() {
54+
chrome.storage.local.get(["ophirofox_request_type", "ophirofox_read_request"], function(data) {
55+
ophirofoxRequestType = data.ophirofox_request_type || null;
56+
ophirofoxReadRequest = data.ophirofox_read_request || null;
57+
console.log("Valeurs initiales chargées:", { ophirofoxRequestType, ophirofoxReadRequest });
58+
});
59+
}
60+
61+
/**
62+
* Récupère les paramètres actuels
63+
* @returns {Promise<Object>} - Promesse résolue avec les paramètres
64+
*/
65+
function getSettings() {
66+
return new Promise(resolve => {
67+
chrome.storage.local.get(["ophirofox_settings"], result => {
68+
if (result.ophirofox_settings) {
69+
try {
70+
resolve(typeof result.ophirofox_settings === "string"
71+
? JSON.parse(result.ophirofox_settings)
72+
: result.ophirofox_settings);
73+
} catch (err) {
74+
console.error("Erreur lors du parsing des settings:", err);
75+
resolve({});
76+
}
77+
} else {
78+
resolve({});
79+
}
80+
});
81+
});
82+
}
83+
3284
// ======== FONCTIONS D'INJECTION DE SCRIPTS ========
3385

3486
/**
@@ -107,50 +159,40 @@ async function injectEuropress() {
107159
});
108160
}
109161

110-
// ======== ÉCOUTEURS D'ÉVÉNEMENTS ========
162+
// ======== FONCTIONS DE GESTION DE PAGE ACTION ========
111163

112-
chrome.runtime.onInstalled.addListener(({ reason }) => {
113-
if (reason === "install") {
114-
chrome.runtime.openOptionsPage();
115-
}
116-
loadSettings();
117-
});
118-
119-
chrome.runtime.onStartup.addListener(loadSettings);
120-
chrome.permissions.onAdded.addListener(injectEuropress);
121-
chrome.permissions.onRemoved.addListener(injectEuropress);
122-
123-
chrome.storage.onChanged.addListener((changes, area) => {
124-
if (area === "local" && changes.ophirofox_settings) {
125-
loadSettings();
126-
}
127-
injectEuropress();
128-
});
129-
130-
131-
chrome.storage.onChanged.addListener((changes, area) => {
132-
if (area === "local") {
133-
if (changes.ophirofox_request_type) {
134-
ophirofoxRequestType = changes.ophirofox_request_type.newValue || null;
135-
// console.log("Ophirofox RequestType mis à jour :", ophirofoxRequestType);
136-
}
137-
if (changes.ophirofox_read_request) {
138-
ophirofoxReadRequest = changes.ophirofox_read_request.newValue || null;
139-
// console.log("Ophirofox ReadRequest mis à jour :", ophirofoxReadRequest);
140-
}
141-
}
142-
});
164+
/**
165+
* Met à jour la visibilité de l'icône dans la barre de recherche pour tous les onglets
166+
* @param {boolean} show - Indique si l'icône doit être affichée
167+
*/
168+
function updatePageActionVisibility(show) {
169+
chrome.tabs.query({}, (tabs) => {
170+
tabs.forEach((tab) => {
171+
if (show) {
172+
chrome.pageAction.show(tab.id);
173+
} else {
174+
chrome.pageAction.hide(tab.id);
175+
}
176+
});
177+
});
178+
}
143179

144-
function loadRequestData() {
145-
chrome.storage.local.get(["ophirofox_request_type", "ophirofox_read_request"], function(data) {
146-
ophirofoxRequestType = data.ophirofox_request_type || null;
147-
ophirofoxReadRequest = data.ophirofox_read_request || null;
148-
console.log("Valeurs initiales chargées:", { ophirofoxRequestType, ophirofoxReadRequest });
180+
/**
181+
* Initialise la visibilité de l'icône dans la barre de recherche selon les paramètres
182+
*/
183+
function initializePageAction() {
184+
getSettings().then((settings) => {
185+
updatePageActionVisibility(settings.show_page_action !== false);
149186
});
150187
}
151-
loadRequestData();
152188

153-
// Interception des requêtes HTTP
189+
// ======== INTERCEPTEUR DE REQUÊTES HTTP ========
190+
191+
/**
192+
* Écouteur pour modifier les en-têtes des requêtes HTTP
193+
* @param {Object} details - Détails de la requête
194+
* @returns {Object} - En-têtes modifiés
195+
*/
154196
const listener = function (details) {
155197
const url = new URL(details.url);
156198
const isTargetHost = url.hostname.includes("europresse.com") || url.hostname.includes("eureka.cc");
@@ -183,15 +225,139 @@ const listener = function (details) {
183225
return { requestHeaders: details.requestHeaders };
184226
};
185227

186-
function getBrowserType() {
187-
if (typeof browser !== "undefined") {
188-
return "firefox";
189-
} else if (typeof chrome !== "undefined") {
190-
return "chrome";
191-
} else {
192-
return "unknown";
228+
// ======== ÉCOUTEURS D'ÉVÉNEMENTS ========
229+
230+
// Événements du cycle de vie de l'extension
231+
chrome.runtime.onInstalled.addListener(({ reason }) => {
232+
if (reason === "install") {
233+
chrome.runtime.openOptionsPage();
193234
}
194-
}
235+
loadSettings();
236+
});
237+
238+
chrome.runtime.onStartup.addListener(loadSettings);
239+
240+
// Événements de permissions
241+
chrome.permissions.onAdded.addListener(injectEuropress);
242+
chrome.permissions.onRemoved.addListener(injectEuropress);
243+
244+
// Événements de stockage
245+
chrome.storage.onChanged.addListener((changes, area) => {
246+
if (area === "local") {
247+
if (changes.ophirofox_settings) {
248+
loadSettings();
249+
}
250+
if (changes.ophirofox_request_type) {
251+
ophirofoxRequestType = changes.ophirofox_request_type.newValue || null;
252+
}
253+
if (changes.ophirofox_read_request) {
254+
ophirofoxReadRequest = changes.ophirofox_read_request.newValue || null;
255+
}
256+
}
257+
injectEuropress();
258+
});
259+
260+
// Événements de messages runtime
261+
chrome.runtime.onMessage.addListener(async (message, sender) => {
262+
if (message.action === "updatePageAction") {
263+
updatePageActionVisibility(message.show);
264+
return false;
265+
}
266+
267+
if (!sender.tab) return false;
268+
const tabId = sender.tab.id;
269+
const url = sender.tab.url;
270+
271+
const settings = await getSettings();
272+
273+
if (message.premiumContent === true) {
274+
premiumUrls.set(url, true);
275+
if (settings?.show_page_action !== false) {
276+
chrome.pageAction.show(tabId);
277+
}
278+
} else if (message.premiumContent === false) {
279+
premiumUrls.delete(url);
280+
chrome.pageAction.hide(tabId);
281+
}
282+
283+
if (message.europresseData) {
284+
tabEuropresseData[tabId] = message.europresseData;
285+
}
286+
287+
return false;
288+
});
289+
290+
// Événements d'onglets
291+
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
292+
if (changeInfo.url || changeInfo.status === 'complete') {
293+
const settings = await getSettings();
294+
// console.log("Settings retrieved:", settings);
295+
296+
if (settings?.show_page_action !== false) {
297+
const url = tab.url;
298+
// console.log("Premium URL check:", url, premiumUrls);
299+
if (premiumUrls.has(url)) {
300+
chrome.pageAction.show(tabId);
301+
}
302+
} else {
303+
chrome.pageAction.hide(tabId);
304+
}
305+
}
306+
});
307+
308+
chrome.tabs.onRemoved.addListener((tabId) => {
309+
delete tabEuropresseData[tabId];
310+
});
311+
312+
// Événement de clic sur l'icône dans la barre de recherche
313+
chrome.pageAction.onClicked.addListener(async (tab) => {
314+
const tabId = tab.id;
315+
const data = tabEuropresseData[tabId];
316+
317+
if (data) {
318+
try {
319+
// First, set the keywords (equivalent to onmousedown)
320+
await Promise.all([
321+
chrome.storage.local.set({
322+
"ophirofox_request_type": { 'type': 'read' }
323+
}),
324+
chrome.storage.local.set({
325+
"ophirofox_read_request": {
326+
'search_terms': data.keywords,
327+
'published_time': data.publishedTime
328+
}
329+
})
330+
]);
331+
332+
// Récupérer les paramètres de l'utilisateur
333+
const settings = await getSettings();
334+
335+
// Récupérer la configuration du manifeste
336+
const manifest = chrome.runtime.getManifest();
337+
const partners = manifest.browser_specific_settings.ophirofox_metadata.partners;
338+
339+
// Trouver le partenaire correspondant
340+
const partnerName = settings.partner_name || "Pas d'intermédiaire";
341+
const partner = partners.find(p => p.name === partnerName) || partners[0];
342+
343+
// Utiliser l'AUTH_URL du partenaire
344+
if (partner && partner.AUTH_URL) {
345+
// Respecter le paramètre open_links_new_tab
346+
if (settings.open_links_new_tab) {
347+
chrome.tabs.create({ url: partner.AUTH_URL });
348+
} else {
349+
chrome.tabs.update(tabId, { url: partner.AUTH_URL });
350+
}
351+
} else {
352+
console.error("Aucune AUTH_URL trouvée pour le partenaire:", partnerName);
353+
}
354+
} catch (error) {
355+
console.error("Erreur dans le gestionnaire d'action de page:", error);
356+
}
357+
}
358+
});
359+
360+
// ======== CONFIGURATION DE L'INTERCEPTEUR DE REQUÊTES ========
195361

196362
console.log("L'extension tourne sur :", getBrowserType());
197363

@@ -205,10 +371,11 @@ if (browserType === 'chrome') {
205371
}
206372

207373
chrome.webRequest.onBeforeSendHeaders.addListener(
208-
listener,{ urls: urls }, options
374+
listener, { urls: urls }, options
209375
);
210376

211377
// ======== INITIALISATION ========
212378

213-
// Exécution initiale
214-
injectEuropress();
379+
loadRequestData();
380+
injectEuropress();
381+
initializePageAction();

ophirofox/content_scripts/config.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,23 +69,41 @@ async function getOphirofoxConfig() {
6969
const ophirofox_config = getOphirofoxConfig();
7070

7171
/**
72-
* Crée un lien vers Europresse avec les keywords donnés
73-
* @param {string} keywords - input for Europress search engine
74-
* @param {string} publishedTime - article publication date (i.e. 2024-08-27T18:18:55.663Z or 2024-08-27)
72+
* Crée un lien vers Europresse avec les keywords donnés et gère la logique d'affichage de l'icône
73+
* @param {string} [keywords] - input optionnel pour Europress search engine
74+
* @param {Object} [options] - options additionnelles
75+
* @param {string} [options.publishedTime] - date de publication de l'article (i.e. 2024-08-27T18:18:55.663Z ou 2024-08-27)
76+
* @param {boolean} [options.checkPremium=true] - si true, vérifie et envoie l'état premium au background
7577
* @returns {Promise<HTMLAnchorElement>}
7678
*/
77-
async function ophirofoxEuropresseLink(keywords, { publishedTime } = {}) {
78-
keywords = keywords ? keywords.trim() : document.querySelector("h1").textContent;
79+
async function ophirofoxEuropresseLink(keywords, options = {}) {
80+
const { publishedTime: inputPublishedTime, checkPremium = true } = options;
81+
82+
// Récupération des keywords si non fournis
83+
keywords = keywords ? keywords.trim() : document.querySelector("h1")?.textContent?.trim() || "";
7984

80-
publishedTime = publishedTime || document.querySelector("meta[property='article:published_time'], meta[property='og:article:published_time'], meta[property='date:published_time']")
85+
// Récupération de la date de publication
86+
let publishedTime = inputPublishedTime || document.querySelector("meta[property='article:published_time'], meta[property='og:article:published_time'], meta[property='date:published_time']")
8187
?.getAttribute("content") || '';
88+
8289
let publishedTimeInstance = new Date(publishedTime);
8390

8491
if (!isNaN(publishedTimeInstance)) {
8592
publishedTime = publishedTimeInstance.toISOString().slice(0, 10);
8693
} else {
8794
publishedTime = '';
8895
}
96+
97+
// Envoyer les données au background script si nécessaire
98+
if (checkPremium && keywords) {
99+
chrome.runtime.sendMessage({
100+
premiumContent: true,
101+
europresseData: {
102+
keywords: keywords,
103+
publishedTime: publishedTime
104+
}
105+
});
106+
}
89107

90108
const a = document.createElement("a");
91109
a.textContent = "Lire sur Europresse";
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
.ophirofox-europresse {
22
margin-left: 10px;
3-
}
3+
}
4+
5+
.appconsent_noscroll {
6+
overflow: unset !important;
7+
}

ophirofox/icons/16.png

555 Bytes
Loading

ophirofox/icons/32.png

1.26 KB
Loading

0 commit comments

Comments
 (0)