Værktøjskasse: Sådan koder du en browser-udvidelse i en ruf

27. september 2018 kl. 05:10
Værktøjskasse: Sådan koder du en browser-udvidelse i en ruf
Illustration: Version2.
Browser-udvidelser kan tilføje ny funktionalitet til browsere og websider, og så er der efterhånden en standard for teknologien.
Artiklen er ældre end 30 dage
Manglende links i teksten kan sandsynligvis findes i bunden af artiklen.

Browser-udvidelser er små programmer, der kan putte ny funktionalitet i browseren eller manipulere med indholdet af en webside eller webapp. Det skrives med HTML, Javascript og CSS, så det er lige ud af landevejen.

I min browser, som er Firefox, har jeg eksempelvis en udvidelse, hvor jeg kan mærke tekst op med gult, og det bliver hængende til næste gang, jeg besøger siden. Det er smart, når jeg laver research, for så slipper jeg for at printe en masse papir ud. En anden udvidelse kan oversætte til dansk, og så fremdeles.

Her på Version2 har vi udviklet en algoritme, der finder emneord til nye artikler, og det fungerer ved, at brugeren skal klikke på en bookmarklet.

Men det ville nu være smartere, hvis brugeren slap for at skulle klikke på bookmarkletten, og forslagene til emneord i stedet bare dukkede op af sig selv, når brugeren åbner dialogboksen, hvor man vælger emneord.

Artiklen fortsætter efter annoncen

Og mon ikke der er en nem måde at lave en bookmarklet om til browser-udvidelse på? En søgning på nettet fører os til Sandbox.self.li, som kan det, vi leder efter: lave en bookmarklet om til en web-udvidelse.

Vi gør, som der står – trækker vores bookmarklet fra tidligere over i vinduet og klikker på knappen ‘Generate extension.’ Nu downloades en zip-fil. Vi pakker den ud, og så kommer disse filer til syne:

  1. background.js
  2. bookmarklet.js
  3. icon-128.png
  4. icon-16.png
  5. icon-48.png
  6. manifest.json

Vi gennemgår filerne senere. I første skridt vil vi bare tjekke, at det rent faktisk virker. I Firefox indlæser jeg udvidelsen ved at taste about:debugging i adresselinjen. Nu åbnes en side, hvorfra jeg kan indlæse en ‘midlertidig’ browserudvidelse ved at klikke på knappen ‘Indlæs midlertidig tilføjelse.’

(I Chrome skal man benytte ‘burger’-menuen Flere værktøjer > Udvidelser, og så klikke på knappen Udviklertilstand øverst til højre. Derefter indlæses mappen med extension-filerne med knappen ‘Indlæs upakket’ øverst til venstre).

Artiklen fortsætter efter annoncen

Nu dukker der et sort rundt ikon op i browseren, som set herunder, øverst til højre på billedet:

Nu åbner jeg dialogboksen og klikker på det sorte ikon. Så bliver emneordsforslagene markeret i dialogen. Så det virker altså – men lige nu gør den nøjagtigt det samme som bookmarkletten, så der skal flere boller på suppen.

Næste skridt er at skrive noget Javascript-kode, som henter emneord fra serveren på egen hånd, når blot brugeren klikker på den knap, der får dialogboksen frem. Knappen ser sådan ud:

Den nemmeste fremgangsmåde er nok bare at skjule knappen og så tilføje en ny knap, der først klikker på den skjulte knap og derefter kalder vores script. Det ser sådan ud:

  1. var knapholder = document.querySelector("#edit-field-topic-da_chzn");
  2. var knap = knapholder.children[1];
  3. knap.style.visibility = 'hidden';
  4. var nyKnap = document.createElement('span');
  5. nyKnap.innerHTML = "<input class=\"chosen-popup\" value=\"Vælg\" type=\"button\">";
  6. nyKnap.onclick = åbenDialog;
  7. knapholder.insertBefore(nyKnap, knap);
  8.  
  9. function åbenDialog() {
  10. console.log("Enter åbenDialog");
  11. knap.click();
  12. findEmneord();
  13. }

Ligesom i tidligere artikler har vi fundet en CSS-selector, der indeholder knappen. Vi navigerer frem til den i dokument-objektet med linjen knapholder.children[1]. Så skjuler vi knappen ved at sætte property’en style.visibility til ‘hidden’. Så er den væk.

Vi tilføjer nu en knap, der er helt magen til den skjulte knap – men når brugeren klikker på den, kaldes vores egen funktion åbenDialog. Den funktion klikker på den skjulte knap med knap.click og derefter kaldes findEmneord, der blot indeholder koden fra vores bookmarklet.

Vi benytter Firefox’ mini-IDE Kladdeblok til at teste koden med, som da vi udviklede bookmarkletten. Og koden virker minsandten.

Content scripts og background scripts

Så langt, så godt. Nu skal vi have udvidelsen til at afvikle koden, når brugeren kommer ind på siden, altså når siden loades i browseren.

Browserudvidelser har to slags scripts: Content scripts, som afvikles i nogenlunde samme kontekst som den indlæste webside, og background scripts, som afvikles i udvidelsens kontekst.

Artiklen fortsætter efter annoncen

Vores værktøj afvikler scriptet i vores bookmarklet med et background script, men vi vil altså loade koden, når siden er indlæst.

Det gør vi ved at åbne manifest-filen, som er et JSON-dokument. Vi sletter linjen

  1. "background": {"scripts": ["background.js"]},

‐ og tilføjer disse linjer:

  1. "content_scripts": [
  2. {
  3. "matches": ["https://www.version2.dk/node/*/rediger"],
  4. "js": ["content.js"],
  5. "run_at": "document_idle"
  6. }
  7. ],

JSON-koden siger, at content-scriptet skal iværksættes på websider, der matcher url’en i ‘matches’-nøglen (og hvor stjerne betyder ‘alle tegn’), at scriptet der skal afvikles befinder sig i filen content.js, og at det skal afvikles ved ‘document_idle', som er umiddelbart efter at hele websiden er indlæst i browseren.

Vi laver nu en ny tekstfil, som får navnet content.js. I den indsætter vi Javascript-koden ovenfor, som skjuler den rigtige knap og indsætter vores egen knap. Når der klikkes på den, kaldes funktionen findEmneord, som indeholder den kode, vi lavede i sidste artikel.

Nu sletter vi filen background.js – den skal vi ikke bruge mere – og zipper resten af filerne til f.eks. EmneordsExtension.zip.

Testing testing en to tre

Så er det tid til at teste. Vi indlæser udvidelsen på samme måde som før. Så åbner vi en artikel i redigeringsmodus, klikker på knappen – og flux bliver emneordsforslagene malet op med gult. Vi har sparet verden for ét udnødvendigt museklik. Man bliver helt rørstrømsk på egne vegne.

Vi prøver også med Chrome, for det skulle jo helst være platformsuafhængigt. Vi indlæser vores udvidelse i Googles browser, og det virker bare. Dæleme dejligt.

Firefox har glimrende værktøjer til udvikling af Javascript-kode i en extension. Ved at vælge Debug-fanen og klikke på ‘content.js’ under fanen ‘Kilder’ til venstre, bringes content-scriptet frem, og man kan indsætte breakpoints og evaluere udtryk. Det kan være smart, hvis koden ikke spiller.

Et kodeeksempel kan downloades fra Google Drive (som kan sige nogle fjollede ting undervejs, men bare tryk ‘download’ – og det fylder stadig for meget til Gitlab.)

Udvidelsen i download-eksemplet virker dog ikke i Firefox – på trods af, at den ‘rigtige’ udgave, som er syet sammen med vores cms, fungerer upåklageligt. Faktisk kan jeg slet ikke få en udvidelse til bare det mindste i Firefox, hvis den skal afvikles sammen med en lokal side – som i ‘localhost’ eller ‘127.0.0.1.’

Debuggeren siger, at browseren ikke kunne indlæse en 'blob,' et binært objekt, men det passer ikke rigtigt på min situation. Når domænet hedder ‘version2.dk’ går det fint, så måske er det noget sikkerhedsmæssigt. Jeg skal ikke kunne sige det. Men prøv i stedet med Chrome.

Når serveren er oppe og køre, via det medfølgende batch-script, kan en testside tilgås med url'en: https://localhost:8000/apps/emneord/test – hvor man kan indsætte tekst fra en Version2-artikel og få bud på emneord ved hjælp af browserudvidelsen, som også følger med download-eksemplet.

Ingen kommentarer endnu.  Start debatten
Denne artikel er gratis...

...men det er dyrt at lave god journalistik. Derfor beder vi dig overveje at tegne abonnement på Version2.

Digitaliseringen buldrer derudaf, og it-folkene tegner fremtidens Danmark. Derfor er det vigtigere end nogensinde med et kvalificeret bud på, hvordan it bedst kan være med til at udvikle det danske samfund og erhvervsliv.

Og der har aldrig været mere akut brug for en kritisk vagthund, der råber op, når der tages forkerte it-beslutninger.

Den rolle har Version2 indtaget siden 2006 - og det bliver vi ved med.

Debatten
Log ind eller opret en bruger for at deltage i debatten.
settingsDebatindstillinger