From 25414a1fee6f511af10ca9adc804be2faea3cef6 Mon Sep 17 00:00:00 2001 From: Valerii Liasotskyi Date: Thu, 29 Feb 2024 15:52:13 +0100 Subject: [PATCH] fix: avoid using deprecated jQuery functions to prepare for jQuery 4 (#779) - some DOM check functions were rewritten to use native DOM API - jquery 3 dependency was removed from package.json --- package.json | 3 --- src/gmail.js | 74 +++++++++++++++++++++++++--------------------------- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 754a870..dc97d47 100755 --- a/package.json +++ b/package.json @@ -22,9 +22,6 @@ "gmail chrome extension", "gmail firefox extension" ], - "dependencies": { - "jquery": "^3.6.1" - }, "devDependencies": { "@types/jquery": "^3.5.14", "eslint": "^8.23.1", diff --git a/src/gmail.js b/src/gmail.js index 96f80a1..6b032d4 100644 --- a/src/gmail.js +++ b/src/gmail.js @@ -18,13 +18,8 @@ var Gmail = function(localJQuery) { } else if (typeof jQuery !== "undefined") { $ = jQuery; } else { - // try load jQuery through node. - try { - $ = require("jquery"); - } - catch(err) { - // else leave $ undefined, which may be fine for some purposes. - } + // leave $ undefined, which may be fine for some purposes. + console.warn("GmailJS: jQuery is not provided in constructor parameters, DOM functions may not work."); } var window_opener = typeof (window) !== "undefined" ? window.opener : null; @@ -42,6 +37,7 @@ var Gmail = function(localJQuery) { } } + /** @type Gmail */ var api = { get : {}, observe : {}, @@ -341,12 +337,12 @@ var Gmail = function(localJQuery) { api.check.is_tabbed_inbox = function() { - return $(".aKh").length === 1; + return document.querySelectorAll(".aKh").length === 1; }; api.check.is_right_side_chat = function() { - var chat = $(".ApVoH"); + var chat = document.querySelectorAll(".ApVoH"); if(chat.length === 0) { return false; } @@ -429,7 +425,7 @@ var Gmail = function(localJQuery) { return false; } - var items = $(".ii.gt .a3s"); + var items = document.querySelectorAll(".ii.gt .a3s"); var ids = []; for(var i=0; i 0; + return document.querySelector(".qh") !== null; }; api.check.is_rapportive_installed = function() { - return $("#rapportive-sidebar").length === 1; + return document.querySelector("#rapportive-sidebar") !== null; }; api.check.is_streak_installed = function() { - return $("[id^='bentoBox'],[id*=' bentoBox'],[class*=' bentoBox'],[class*='bentoBox']").length > 0; + return document.querySelector("[id^='bentoBox'],[id*=' bentoBox'],[class*=' bentoBox'],[class*='bentoBox']") !== null; }; api.check.is_anydo_installed = function() { - return $("[id^='anydo'],[id*=' anydo'],[class*=' anydo'],[class*='anydo']").length > 0; + return document.querySelector("[id^='anydo'],[id*=' anydo'],[class*=' anydo'],[class*='anydo']") !== null; }; api.check.is_boomerang_installed = function() { - return $("[id^='b4g_'],[id*=' b4g_'],[class*=' b4g_'],[class*='b4g_']").length > 0; + return document.querySelector("[id^='b4g_'],[id*=' b4g_'],[class*=' b4g_'],[class*='b4g_']") !== null; }; api.check.is_xobni_installed = function() { - return $("#xobni_frame").length > 0; + return document.querySelector("#xobni_frame") !== null; }; api.check.is_signal_installed = function() { - return $("[id^='Signal'],[id*=' Signal'],[class*=' signal'],[class*='signal']").length > 0; + return document.querySelector("[id^='Signal'],[id*=' Signal'],[class*=' signal'],[class*='signal']") !== null; }; @@ -636,9 +632,9 @@ var Gmail = function(localJQuery) { api.helper.get.navigation_count = function(i18nName) { const title = api.tools.i18n(i18nName); - const dom = $("div[role=navigation]").find("[title*='" + title + "']"); + const dom = document.querySelectorAll("div[role=navigation] [title*='" + title + "']"); - if (dom || dom.length > 0) { + if (dom.length > 0) { // this check should implicitly always be true, but better safe than sorry? if(dom[0].title.indexOf(title) !== -1) { const value = parseInt(dom[0].attributes['aria-label'].value.replace(/[^0-9]/g, "")); @@ -654,7 +650,7 @@ var Gmail = function(localJQuery) { api.get.beta = function() { var features = { - "new_nav_bar" : $("#gbz").length === 0 + "new_nav_bar" : document.querySelector("#gbz") !== null }; return features; @@ -2353,7 +2349,7 @@ var Gmail = function(localJQuery) { // if an object of actions (triggered events of format { event: [response] }) is passed, check if any of these are bound if(typeof action === "object") { var match = false; - $.each(action,function(key,response){ + Object.keys(action).forEach(key => { if(typeof api.tracker.watchdog[type][key] === "object") match = true; }); return match; @@ -2378,7 +2374,7 @@ var Gmail = function(localJQuery) { // loop through applicable types var types = type ? [ type ] : [ "before", "on", "after", "dom" ]; - $.each(types, function(idx, type) { + types.forEach(type => { if(typeof api.tracker.watchdog[type] !== "object") return true; // no callbacks for this type // if action specified, remove any callbacks for this action, otherwise remove all callbacks for all actions @@ -2389,7 +2385,7 @@ var Gmail = function(localJQuery) { delete api.tracker.watchdog[type][action]; } } else { - $.each(api.tracker.watchdog[type], function(act,callbacks) { + Object.keys(api.tracker.watchdog[type]).forEach(act => { if(typeof api.tracker.watchdog[type][act] === "object") { api.tracker.bound[act] -= api.tracker.watchdog[type][act].length; api.tracker.bound[type] -= api.tracker.watchdog[type][act].length; @@ -2407,15 +2403,15 @@ var Gmail = function(localJQuery) { api.observe.trigger = function(type, events, xhr) { if(!events) return false; var fired = false; - $.each(events, function(action,response) { + Object.entries(events).forEach(([action, response]) => { // we have to do this here each time to keep backwards compatibility with old response_callback implementation - response = $.extend([], response); // break the reference so it doesn"t keep growing each trigger + response = [...response]; // break the reference so it doesn"t keep growing each trigger if(type === "after") response.push(xhr.xhrResponse); // backwards compat for after events requires we push onreadystatechange parsed response first response.push(xhr); if(api.observe.bound(action, type)) { fired = true; - $.each(api.tracker.watchdog[type][action], function(idx, callback) { + api.tracker.watchdog[type][action].forEach(callback => { callback.apply(undefined, response); }); } @@ -2437,7 +2433,7 @@ var Gmail = function(localJQuery) { if (!api.tracker.watchdog.dom[observer]) { return; } - $.each(api.tracker.watchdog.dom[observer], function(idx, callback) { + api.tracker.watchdog.dom[observer].forEach(callback => { handler(element, callback); }); }; @@ -2573,9 +2569,9 @@ var Gmail = function(localJQuery) { // map observed classNames to actions api.tracker.dom_observer_map = {}; - $.each(api.tracker.dom_observers, function(act,config){ - if(!$.isArray(config.class)) config.class = [config.class]; - $.each(config.class, function(idx, className) { + Object.entries(api.tracker.dom_observers).forEach(([act, config]) => { + if(!Array.isArray(config.class)) config.class = [config.class]; + config.class.forEach(className => { if (!api.tracker.dom_observer_map[className]) { api.tracker.dom_observer_map[className] = []; } @@ -2607,10 +2603,10 @@ var Gmail = function(localJQuery) { // was an object of arguments passed, or just a className var config = {}; - if (typeof args === "object" && !$.isArray(args)) { + if (typeof args === "object" && !Array.isArray(args)) { // copy over supported config - $.each(["class","selector","sub_selector","handler"], function(idx, arg) { + ["class","selector","sub_selector","handler"].forEach(arg => { if(args[arg]) { config[arg] = args[arg]; } @@ -2663,7 +2659,7 @@ var Gmail = function(localJQuery) { } // support for DOM observers - if($.inArray(action, api.tracker.supported_observers) > -1) { + if(api.tracker.supported_observers.includes(action)) { //console.log("observer found",api.tracker.dom_observers[action]); @@ -2754,7 +2750,7 @@ var Gmail = function(localJQuery) { var cn = target.className || ""; var classes = cn.trim ? cn.trim().split(/\s+/) : []; if(!classes.length) classes.push(""); // if no class, then check for anything observing nodes with no class - $.each(classes, function(idx, className) { + classes.forEach(className => { var observers = dom_observer_map[className]; if (!observers) { return; @@ -4347,11 +4343,11 @@ var Gmail = function(localJQuery) { // if update data has been passeed, loop through & create a new to_wrapper contents if (to_array) { - if (!$.isArray(to_array)) { + if (!Array.isArray(to_array)) { to_array = [to_array]; } var html = []; - $.each(to_array, function(index, obj) { + to_array.forEach(obj => { html.push( $("").attr({ dir: "ltr", email: obj.email, @@ -4424,7 +4420,7 @@ var Gmail = function(localJQuery) { // retrieve & cache the data for this whole thread of emails var data = api.get.email_data(this.id); - $.each(data.threads, function(email_id, email_data) { + Object.entries(data.threads).forEach(([email_id, email_data]) => { api.dom.email_cache[email_id] = email_data; }); }