Psaní prvního výukového programu pro rozšíření prohlížeče – část 2

Tento tutoriál je založen na workshopu, který jsem vedl na konferenci Codeland v NYC v roce 2019.

Pro účely tohoto tutoriálu použijeme Firefox, i když většina konceptů se přenese i do jiných prohlížečů.

Kód tohoto výukového programu naleznete zde

Kde jsme to byli?

V části 1 tohoto tutoriálu jsme vytvořili malé zábavné rozšíření, které vám každých deset minut připomene, abyste opustili Twitter.

Bylo to docela zábavné (a pokud jste jako já, docela užitečné 🤐), ale když přemýšlíte o rozšířeních prohlížeče, pravděpodobně vás napadnou ta, která s webovou stránkou něco dělají. Buď něco přidejte, něco odstraňte nebo změňte vzhled.

V části 2 se zaměříme na tento druh rozšíření.

Manipulovat se svým DOM?

JavaScriptové programy, které provádějí změny na webových stránkách, to dělají pomocí něčeho, co se nazývá DOM Manipulation.

DOM (Domain Object Model) je JavaScriptová reprezentace stránky HTML.

JavaScript má vestavěné funkce pro přidávání, odebírání a jiné provádění změn v modelu DOM, které způsobí, že se změní i základní stránka HTML. Tento proces se nazývá DOM Manipulation.

V našem dalším rozšíření budeme používat DOM Manipulation.

Unbiasify

Jedním z hlavních problémů, kterým čelí proces náboru technologií, je implicitní zaujatost při najímání.

Náboráři obvykle stráví méně než půl minuty prohlížením životopisu a musí dělat spoustu velmi rychlých rozhodnutí v krátkém čase. Za těchto okolností dává smysl, že se náš mozek pokusí použít zkratky a výchozí možnosti, které považuje za „bezpečné“. Problém je v tom, že tyto zkratky nemusí být nutně zakořeněné ve skutečnosti.

Poměrně několik studií prokázalo, že vzhledem ke dvěma identickým životopisům, s jediným rozdílem, že jeden z nich má fotografii a jméno bílého muže a druhý má fotografii a jméno demografické skupiny, která byla tradičně v technologiích nedostatečně zastoupena, životopis bílého muže dostane mnohem více odpovědí než URM.

Není to nutně proto, že se náboroví manažeři ve studiích snažili být rasističtí/sexističtí, je to spíše kvůli implicitním předsudkům, se kterými se všichni rodíme a je velmi těžké je napravit, zvláště pokud si jich nejste vědomi.

(Pokud jste to ještě neudělali, doporučuji vám provést test Implicitní asociace (IAT). Výsledky mi otevírají oči)

Martin Huack vytvořil zajímavé rozšíření pro řešení tohoto problému s názvem Unbiasify. Podívejte se na jejich web a zjistěte, co dělá.

Jeho malou část zrealizujeme. Změníme vzhled LinkedIn tak, aby se nám nezobrazovaly obrázky žádného z našich kandidátů. Místo toho vyměníme profilové obrázky za obrázek koťátka!

(Původní rozšíření Unbiasify vyměňuje profilové obrázky za obyčejný šedý kruh, ale to je nuda. Kromě toho internet nikdy nemůže mít příliš mnoho koťat;)

Začněme!

Poznámka: Pokud nechcete ztratit žádný kód, který jsme napsali v první části, můžete v tomto bodě vytvořit novou větev. Veškerý kód, který jsme napsali, je v tomto repozitáři.

  • První věc, kterou musíme udělat, je přejít na manifest.json a změňte "matches" klíč, který sdělí našemu rozšíření, aby běželo na LinkedIn:
    "content_scripts": [
        {
-            "matches": ["*://*.twitter.com/*"],
+            "matches": ["*://*.linkedin.com/*"],
             "js": ["first-extension.js"]
        }
    ]
  • Pokud znovu načteme naše rozšíření v "about:debugging" a zamíříme na LinkedIn.com, měli bychom tam vidět naše upozornění. Je to jen proto, abychom se ujistili, že vše stále funguje.

  • Pojďme se zbavit veškerého kódu v first-extension.js .

  • Než napíšeme jakýkoli kód, musíme si ujasnit, které části stránky chceme upravit. Vzhledem k tomu, že chceme vyměnit profilové obrázky, musíme přejít na LinkedIn a zjistit, zda najdeme něco, co mají všechny profilové obrázky společného.

  • Pojďme na LinkedIn.com, do vyhledávacího pole zadejte „softwarový inženýr“ a klikněte na kartu „Lidé“. To by nám mělo poskytnout seznam talentovaných softwarových inženýrů. Co chceme udělat, je vyměnit profilové obrázky.

  • Otevřete nástroj "Inspect" (ctrl+shift+i nebo kliknutím pravým tlačítkem na stránku a výběrem "Prozkoumat prvek").

  • Přejděte na jeden z profilových obrázků, měl by vypadat nějak takto:

  • Hledáme název třídy, který mají všechny profilové obrázky společné, ale žádný z ostatních prvků na stránce je nemá.

  • Když si to trochu pohrajeme, zdá se, že název třídy, který chceme, je tento:EntityPhoto-circle-4 .

  • Ve skutečnosti by se zdálo rozumné předpokládat, že vše profilových obrázků na LinkedIn bude sdílet formát EntityPhoto-[shape]-[size] (a abych vám ušetřil námahu, ověřil jsem, že tento předpoklad je správný), to znamená, že nebudeme muset dělat žádnou práci navíc, aby naše rozšíření fungovalo napříč celým LinkedIn! Jediné, co musíme udělat, je najít způsob, jak vybrat všechny obrázky s názvem třídy, který obsahuje EntityPhoto !

  • Pojďme napsat kód, jak to udělat. Přidejte následující do first-extension.js :

let images = document.querySelectorAll('img[class*="EntityPhoto"]')
  • Používáme JavaScript querySelectorAll funkce pro získání všech img prvky, které mají název třídy obsahující podřetězec "EntityPhoto" (selektor CSS class* vybere jakoukoli třídu, která obsahuje zadanou hodnotu kdekoli v názvu třídy). Získáme tak pole img prvky, které jsme přiřadili proměnné images .

  • Další věc, kterou musíme udělat, je vyměnit src atribut našich profilových obrázků (který aktuálně ukazuje na skutečný profilový obrázek) pro obecný obrázek kočky.

  • Můžete použít obrázek své vlastní kočky, nebo můžete použít tento bezplatný obrázek z clipartixu:

  • Ať už se rozhodnete použít jakýkoli obrázek, uložte jej do počítače jako kitten.jpg a vložte jej do našeho first-extension adresář v podadresáři s názvem images .

  • Dále musíme říci našemu rozšíření o našem obrázku kotěte. Přidejte následující pár klíč/hodnota do manifest.json :

    "content_scripts": [
        {
             "matches": ["*://*.linkedin.com/*"],
             "js": ["first-extension.js"]
        }
-   ]
+   ],
+   "web_accessible_resources": ["images/kitten.jpg"]

(Nezapomeňte přidat čárku za "content_scripts" pole)

  • Nyní můžeme iterovat přes images pole, které jsme vytvořili dříve, a ukazuje všechny z img je na obrázku našeho koťátka! Uděláme to pomocí for smyčka. Přidejte následující do first-extension.js :
for (i = 0; i < images.length; i++) {
    images[i].src = browser.runtime.getURL("images/kitten.jpg")
}
  • To, co děláme, je, že procházíme našimi images pole a pro každý obrázek v něm nazýváme jeho img.src atribut a jeho přiřazení k nové URL; URL našeho obrázku kotěte (browser.runtime.getURL součástí je získat kořenovou adresu URL našeho rozšíření, která se mění při každém načtení rozšíření).

  • Nyní jsme připraveni zjistit, zda naše rozšíření funguje! Přejděte na „about:debugging“ a znovu načtěte naše rozšíření, poté se vraťte na LinkedIn a obnovte stránku. Pokud jsme udělali vše správně, mělo by to vypadat nějak takto:

Odstraňování problémů: Pokud se vám nedaří zprovoznit, můžete zkusit porovnat svůj kód s kódem v této větvi.

  • Zdá se, že by to mělo fungovat, ale pokud obnovíte stránku a pokusíte se posunout dolů, možná si všimnete, že ne všechny profilové obrázky se změnily na kočky! Profily ve druhé polovině stránky stále obsahují profilové obrázky!

  • Důvodem je to, že LinkedIn (stejně jako mnoho jiných webových stránek) používá něco, čemu se říká „líné načítání“. Stručně řečeno, aby se ušetřil čas, když se stránky načítají, LinkedIn nenačte celou stránku najednou, načte pouze část stránky a zbytek načte při posouvání dolů. Problém je v tom, že skript v našem rozšíření se spustí pouze jednou, když se stránka načte, takže nic, co na stránce nebylo v době spuštění skriptu, nebude ovlivněno.

  • Můžeme to napravit pomocí relativně nové funkce JavaScriptu nazvané MutationObserver, která „pozoruje“ stránku (nebo její část) pro případné změny nebo „mutace“, a když zaznamená, že se něco mění, provede funkci, která jí byla předána (funkce zpětného volání ).

Poznámka: MutationObserver API je relativně nové a nemusí fungovat ve všech prohlížečích

  • První věc, kterou chceme udělat, je zabalit naši stávající logiku do funkce, abychom ji usnadnili:
+ function imageSubstituter(){
      let images = document.querySelectorAll('img[class*="EntityPhoto"]')

      for (i = 0; i < images.length; i++) {
          images[i].src = browser.runtime.getURL("images/kitten.jpg")
      }
+ }
  • Dále vytvoříme nový MutationObserver objekt a předat mu naši funkci jako zpětné volání:
const observer = new MutationObserver(imageSubstituter)
  • MutationObserver objekt, který jsme vytvořili, má observe funkce, která vyžaduje dva argumenty:prvek DOM k pozorování a některé možnosti konfigurace předané jako objekt JavaScript.

  • Nejprve napíšeme naše možnosti konfigurace:

const config = { childList: true, subtree: true }

To řekne našemu pozorovateli, aby pozoroval nejen prvek, kterému mu říkáme, ale také jakékoli podřízené prvky.

  • Nyní jsme připraveni zavolat našemu observer s observe funkce. Předáme mu k pozorování celé tělo naší stránky HTML, stejně jako možnosti konfigurace, které jsme napsali:
observer.observe(document.body, config)
  • Nyní jsme připraveni zjistit, zda naše vylepšené rozšíření funguje. Přejděte na „about:debugging“, znovu načtěte rozšíření a poté se vraťte na LinkedIn a znovu načtěte stránku. Při posouvání dolů byste měli vidět všechny profilové obrázky až po obrázky koček, když se načítají!

Odstraňování problémů: Pokud rozšíření nefunguje, dvakrát zkontrolujte, zda je vše v pořádku (zkontrolujte kód zde).

Pokud jste si jisti, že jste udělali vše správně a stále nefunguje, je možné, že váš prohlížeč nepodporuje MutationObserver API. Jak již bylo zmíněno, je to relativně nová funkce, která není všeobecně podporována.

Gratulujeme!

Gratulujeme! Nyní jsme vytvořili dvě funkční rozšíření prohlížeče!

Doufám, že jsem vám poskytl dostatek informací, abyste mohli začít pracovat na svém vlastním rozšíření prohlížeče.

Pokud jsem vás inspiroval k vytvoření něčeho úžasného, ​​kontaktujte mě zde nebo na Twitteru a sdílejte, co jste vytvořili!