JavaScript, ExtJS 3.0 a Flash

Třetí verze JavaScriptové knihovny ExtJs vyšla loni v červnu. Jedna z nepřehlédnutelných funkcí, uvedených v nové verzi tohoto frameworku, je možnost zobrazovat data v grafech, realizována pomocí technologie Flash. V článku si popíšeme komunikaci mezi Flash objektem, JavaScriptem a ExtJs.

Použité názvy a terminologie

Ujasněme si několik termínů:

  • Adobe Flash je software pro vytváření animací ve formátu SWF pro přehrání v přehrávači Adobe Flash Player.
  • Adobe Flex je je framework pro vytváření aplikací ve formátu SWF pro přehrávač Adobe Flash Player.

Laskavý čtenář jistě pochopí, budu-li pro zjednodušení dále v textu nazývat oboje Flash.

Flash (i Flex) využívá skriptovací jazyk ActionScript, který se v současné době nachází ve třetí verzi, což je nezbytné uvést, vzhledem ke značným odlišnostem od verzí předchozích.

JavaScript a Flash

Pro integraci Flashe s JavaScriptem nalezneme v dokumentaci jazyka Actionscript 3 rozhraní (realizované statickou třídou) flash.external­.ExternalInter­face. Toto rozhraní nám umožňuje zavolat funkci JavaScriptu metodou call anebo naopak definovat jméno metody viditelné v JavaScriptu a její propojení na metodu ve ActionScript objektu pomocí metody addCallback.

Test, zda je externí rozhraní dostupné, se provádí pomocí proměnné available. Tento test je nezbytný pokud budeme Flash spouštět ve Flash Playeru, tak i v prohlížeči.

Registrace metody doAlert, viditelné v JavaScriptu (ActionScript 3)

if (flash.external.ExternalInterface.available) {
    flash.external.ExternalInterface.addCallback('doAlert', doAlert);
}

Tuto metodu je pak možné zavolat takto (JavaScript)

document.getElementById('flashObjectId').doAlert('Zpráva z JavaScriptu')

Volání metody alert v JavaScriptu (ActionScript 3)

if (flash.external.ExternalInterface.available) {
    flash.external.ExternalInterface.call('alert', 'Javascript Alert called form Flash');
}

Alternativou použití tohoto interface je funkce fscommand, podporovaná v nižších verzích Actionscriptu a Flash Playeru, v současné době nedoporučovaná.

ExtJS a Flash

Ext.FlashComponent

ExtJS od verze 3.0 obsahuje třídu Ext.FlashCompo­nent, potomka třídy Ext.BoxComponent. To znamená, že instance této třídy obsahuje metody pro pozicování a nastavení rozměrů komponent, čímž je postaráno o umístění a layout Flashe v rámci okna aplikace. Také to pro nás znamená, že instance bude umět pracovat s událostmi – jelikož je Ext.FlashCompo­nent také potomkem Ext.util.Obser­vable, jak můžeme zjistit pohledem na strom dědičnosti.

Události

Pro zajištění komunikace z Flashe do Javascriptu není nutné předávat data přímým voláním jednotlivých funkcí JavaScriptové aplikace pomocí funkce call. ExtJS totiž z Flash objektu zachycuje události, které pak převádí na události ExtJS (třída Ext.EventObject). Realizuje to singletonem Ext.FlashEventProxy, který najdete v dokumentaci (záhadně) přejmenovaný na  Ext.FlashProxy.

Název metody zpracovávající události (callback) se předává Flash objektu v parametru flashvars v proměnné eventHandler (obvyklou hodnotou je právě Ext.FlashEventProxy.onEvent). Flash dostává zároveň v parametru flashvars proměnnou elementID, obsahující id komponenty ExtJS.

Událost se pak vyvolá metodou call:

flash.external.ExternalInterface.call('Ext.FlashEventProxy.onEvent', id, data);

To vede ke spuštění metody onEvent singletonu Ext.FlashEventProxy. Metoda onEvent najde podle předaného id příslušnou instanci Ext.FlashComponent zavolá její metodu onFlashEvent a předá jí data události. Metoda onFlashEvent způsobí přímo vyvolání události ExtJS. Jméno události je uloženo ve vlastnosti type objektu data. Stručně řečeno, tento mechanismus nám umožňuje jednoduše převádět volání metody z Flashe na události ExtJS.

ExtJS Flash

Aby objekt ExtJS byl schopen rozeznat, že Flash je již inicializován, je třeba vyvolat událost s rezervovaným jménem swfReady, která způsobí inicializaci ExtJS komponenty a zároveň vyvolá událost initialize. Je třeba zmínit, že druhým rezervovaným názvem události je log, jejíž obsluha, jak je patrné při pohledu do kódu metody onFlashEvent třídy Ext.FlashObject , nedělá nic.

Volání metody ve Flashi

Při vykreslení instance Ext.FlashComponent dojde k nastavení vlastnosti swf, která obsahuje referenci na DOM element object. Je-li ve Flashové animaci zaregistrována metoda pomocí addCallback, pak je dostupná právě jako metoda objektu ve vlastnosti  swf.

Metodu doAlert pak zavoláme takto:

this.swf.doAlert(message);

Parametrem metody může být i složitější datová struktura než pouhý textový řetězec, proto je výhodnější využít např. pro nastavení implicitních hodnot Flash objektu volání metody (setteru), než předávat hodnoty přes parametr flashvars, který právě umožňuje předat pouze řetězec znaků.

Příklad

Zmíněné znalosti by nám měly stačit k vytvoření objektu, který bude umět zavolat metodu ve Flashi ( doAlert) a také vyvolat událost ExtJS ( alert).

Budeme vytvářet aplikaci, která po otevření indexové stránky zobrazí dvě tlačítka, jedno v HTML, jedno ve Flashi, kliknutí na „DoAlert“ vyvolá zobrazení message boxu ve Flashi, klinutí na „Call JavaScript method“ naopak zobrazí message box z ExtJS.

ExtJS Flash

Vytvoříme třídu ExtJS, potomka Ext.FlashComponent, obsahující definici metody pro zobrazení zprávy ve Flashi (ExtTest.js)

var ExtTest = Ext.extend(Ext.FlashComponent, {
    url: 'ExampleExtJS.swf',
    doAlert: function(message) {
        this.swf.doAlert(message);
    }
});

Při načtení stránky (index.html) a ExtJS provedeme skript, který nám vytvoří instanci třídy s flashovou animací a tlačítko, při jehož stisknutí pošleme zprávu do Flashe.

Ext.onReady(function() {
    var flashTest = new ExtTest({
        renderTo: Ext.getBody(),
        width: 300,
        height: 200,
        listeners: {
            alert: function(event) {
                Ext.Msg.alert('Message', event.message);
            }
        }
    });

    new Ext.Button({
        renderTo: Ext.getBody(),
        text: 'Do Alert',
        handler: function() {
            flashTest.doAlert('Message form ExtJs')
        }
    });

});

Hlavní soubor flashové části aplikace obsahuje taktéž definici tlačítka, které naopak bude vyvolávat událost ExtJS (Main.mxml)

<?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="creationCompleteHandler()">
    <mx:Button id="button1" label="Call Javascript method" click="clickHandler()" />
    <mx:Script source="script.as"></mx:Script>
</mx:Application>

Action skript flashové komponenty (script.as)

import flash.external.ExternalInterface;

private function creationCompleteHandler():void {
    if (flash.external.ExternalInterface.available) {
        flash.external.ExternalInterface.addCallback('doAlert', doAlert);
    }
    this.addEventListener(Event.ADDED_TO_STAGE, function(): void {
        fireEvent({type: 'swfReady'});
    });
}

private function doAlert(text:String): void {
    mx.controls.Alert.show(text);
}

private function fireEvent(event: Object): void {
    var params : Object = LoaderInfo(this.root.loaderInfo).parameters;
    var eventHandler: String = params.eventHandler;

    if (flash.external.ExternalInterface.available) {
        flash.external.ExternalInterface.call(params.eventHandler, params.elementID, event);
    }
}

private  function clickHandler(): void {
    fireEvent({
        type: 'alert',
        message: 'Message from Flash'
    });
}

Můžete si stáhnout zdrojový kód příkladu, vyžaduje ExtJS.

Co je pod kapotou?

Flash Player běží v Internet Exploreru jako komponenta ActiveX, v ostatních prohlížečích využívá Netscape Plugin Application Programming Interface (NPAPI).

Při volání metody Flashe z JavaScriptu se využívá rozhraní ActiveX/NPAPI pro volání JavaScriptu, toto volání je však ještě zpracováváno dalšími interními funkcemi v JavaScriptu, které přidává Flash Player, lze je rozeznat podle prefixu __flash__. Interní JavaScriptové funkce Flash Playeru slouží k převodu parametrů volání externí JavaScriptové funkce do XML formátu a poté volají interní metodu CallFunction, která zprostředkuje volání příslušné funkce.

Volání metody doAlert můžeme potom lze provést přímým voláním metody  CallFunction:

document.getElementById('flashObjectId').CallFunction("<invoke name="doAlert" returntype="javascript"><arguments><string>Message from JavaScript</string></arguments></invoke>")

Zdroje

Pracuje jako vývojář webových aplikací ve společnosti TopMonks, s.r.o. a specializuje se na JavaScript, AngularJS a EmberJS, hlavně na vývoj uživatelských rozhraní. Je členem kapely Rezatý Rakety. Když nehraje ani neprogramuje, inhaluje výpary při lepení plastikových modelů.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Zatím nebyl přidán žádný komentář, buďte první!

Přidat komentář
Zdroj: https://www.zdrojak.cz/?p=3186