Zastosowanie modułów JavaScript

Moduły JavaScript zostały wprowadzone w Firefoksie 3 (Gecko 1.9) i służą do udostępniania kodu pomiędzy różnymi zakresami kodu uprzywilejowanego. Za pomocą modułów można także utworzyć globalne obiekty typu singleton, co dotychczas wymagało korzystania z obiektów JavaScript XPCOM. Moduł JavaScript to po prostu kod w języku JavaScript, umieszczony w zarejestrowanej lokalizacji. Moduł jest ładowany w ramach określonego zakresu JavaScript, takiego jak skrypt XUL lub skrypt JavaScript XPCOM, za pomocą metody Components.utils.import.

Poniżej przedstawiono przykład prostego modułu JavaScript:

EXPORTED_SYMBOLS = ["foo", "bar"]

function foo() {
  return "foo";
}

var bar = {
  name : "bar",
  size : "3"
};

var dummy = "dummy";

Do tworzenia funkcji, obiektów, stałych oraz dowolnych innych typów obiektów JavaScript stosowana jest zwykła składnia języka JavaScript. W module zdefiniowany jest także specjalny obiekt typu Array o nazwie EXPORTED_SYMBOLS. Każdy element kodu JavaScript umieszczony w tablicy EXPORTED_SYMBOLS zostanie wyeksportowany z modułu i dołączony do zakresu, do którego importowany jest moduł — na przykład:

Components.utils.import("resource://aplikacja/moduly/moj_modul.jsm");

alert(foo());         // wyświetla "foo"
alert(bar.size + 3);  // wyświetla "6"
alert(dummy);         // wyświetla "dummy is not defined", ponieważ zmienna 'dummy' nie została wyeksportowana z modułu

Szczególnie istotną cechą działania metody Components.utils.import jest umieszczanie ładowanych modułów w pamięci podręcznej; przy kolejnych operacjach importu zamiast ładowania nowej wersji modułu używana jest wersja pobrana z pamięci podręcznej. W przypadku wielokrotnego importowania danego modułu jest on współużytkowany. Jakiekolwiek modyfikacje danych, obiektów lub funkcji są dostępne w każdym zakresie, do którego moduł został zaimportowany. Jeżeli na przykład do dwóch różnych zakresów JavaScript zostanie zaimportowany prosty moduł, zmiany dokonane w jednym zakresie będą widoczne w pozostałych zakresach.

Zakres 1:

Components.utils.import("resource://app/modules/moj_modul.jsm");

alert(bar.size + 3);  // wyświetla "6"

bar.size = 10;

Zakres 2:

Components.utils.import("resource://app/modules/moj_modul.jsm");

alert(foo());         // wyświetla "foo"
alert(bar.size + 3);  // wyświetla "13"

Możliwe jest tworzenie obiektów typu singleton, które mogą udostępniać dane do innych okien, skryptów XUL i komponentów XPCOM.

Protokół resource:

W przykładach zastosowania metody Components.utils.import użyto protokołu "resource://". Podstawową składnię adresu URL protokołu resource przedstawiono poniżej:

resource://<alias>/<ścieżka-względna>/<plik.js|jsm>

<alias> jest aliasem lokalizacji; zazwyczaj jest to fizyczna lokalizacją względna wobec aplikacji lub środowiska uruchomieniowego XUL. W środowisku uruchomieniowym XUL istnieją dwa wstępnie zdefiniowane aliasy:

  • app — alias lokalizacji aplikacji XUL.
  • gre — alias lokalizacji środowiska uruchomieniowego XUL.

<ścieżka-względna> może zawierać wiele zagłębień i jest zawsze względna wobec lokalizacji określonej przez <alias>. Typowa ścieżka względna to "modules" — taka nazwa jest używana w środowisku XUL Runner i w programie Firefox. Moduły kodu to pliki JavaScript z rozszerzeniem .js lub .jsm.

Najprostszym sposobem dodania własnych aliasów w rozszerzeniach i aplikacjach XUL jest zarejestrowanie tych aliasów w manifeście chrome za pomocą poniższego kodu:

resource nazwa_aliasu adres/url/plików/

Własne aliasy można także w sposób programowy dodać do protokołu resource, na przykład:

var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);
var resProt = ioService.getProtocolHandler("resource")
                       .QueryInterface(Components.interfaces.nsIResProtocolHandler);

var aliasFile = Components.classes["@mozilla.org/file/local;1"]
                          .createInstance(Components.interfaces.nsILocalFile);
aliasFile.initWithPath("/bezwzględna/ścieżka");

var aliasURI = ioService.newFileURI(aliasFile);
resProt.setSubstitution("mojalias", aliasURI);

// przyjęto założenie, że moduły kodu znajdują się w folderze określonym przez alias, a nie w podfolderach
Components.utils.import("resource://mojalias/plik.jsm");

// ...


Autorzy i etykiety dokumentu

 Autorzy tej strony: teoli, Mgjbot, Flaneur
 Ostatnia aktualizacja: teoli,