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ý obsahujeEntityPhoto
! -
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šechimg
prvky, které mají název třídy obsahující podřetězec"EntityPhoto"
(selektor CSSclass*
vybere jakoukoli třídu, která obsahuje zadanou hodnotu kdekoli v názvu třídy). Získáme tak poleimg
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šehofirst-extension
adresář v podadresáři s názvemimages
. -
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 zimg
je na obrázku našeho koťátka! Uděláme to pomocífor
smyčka. Přidejte následující dofirst-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 jehoimg.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
sobserve
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!