Opensocial-BR GTUG
10Apr/102

Chamadas em Callback flash por javascript e chamadas javascript no flash e Opensocial

Tem sido uma pergunta um pouco comum na lista de desenvolvimento de Opensocial, o processo de integração entre flash e javascript e javascript e flash. Sim, é totalmente possível realizar a integração - com flash player >= 8:

  • Chamar uma função do flash via javascript;
  • Chamar uma função javascript via flash;

Escrevi flash acima, mas entenda por actionscript. Precisará escrever código em actionscript para poder fazer a comunicação, através de uma interface chamada "ExternalInterface".

Além do correto funcionamento do que você desenvolver em AS3, precisará seguir uma receita de bolo para poder fazer o processo funcionar. Ex:

  • Configurar o crossdomain.xml, ou colocar explicitamente o código de AllowDomain no flash, para não dar problema de security exception;
  • Criar um wrapper javascript para chamar a função do flash, que é diferenciado para Internet Explorer e Firefox;
  • Usar as funções de embedFlash nativas do desenvolvimento em Opensocial (para Orkut), pois farão o tratamento automático, sem necessidade de uso de swfobject e proxy de url;

Exemplo de um código AS3, bem simples, que faz chamada em uma função javascript chamada 'teste' e adiciona um callback 'continuacaoTeste', que chama uma função 'printResult' do AS3.

package
{
	import flash.display.Sprite;
	import flash.external.ExternalInterface;
	import flash.system.Security;
	import flash.text.TextField;

	public class Teste extends Sprite
	{
		public var txt: TextField;

		public function Teste (): void
		{
			Security.allowDomain ('*');
			if (ExternalInterface.available)
			{
				ExternalInterface.call('teste');
				ExternalInterface.addCallback('continuacaoTeste', this.printResult);
			}
		}

		private function printResult (str: String): void
		{
			this.txt.text = str;
		}
	}
}

Note na diretriz Security.allowDomain('*') . Não é o ideal, mas para o caso desse teste bem simples, exclui a necessidade do crossdomain.xml .

Feito o código acima, gere o swf e vamos partir para o código Opensocial necessário para fazer a comunicação flash x javascript.

<?xml version="1.0" encoding="utf-8" ?>
 <Module>
   <ModulePrefs title="OpensocialBR - javascript + flash"
			  description="Exemplo de flash com javascript - opensocial-br"
			  author="Robson Dantas"
			  author_email="robson (at) dxs.com.br"
			  author_location="Sao Paulo, Brazil"
			  screenshot="http://www.opensocial-br.org/logo.jpg"
			  thumbnail="http://www.opensocial-br.org/logo.jpg">
	 <Require feature="opensocial-0.8" />
	 <Require feature="views" />
     <Require feature="flash" />

   </ModulePrefs>

	<Content type="html" view="canvas,profile">
	   <![CDATA[
		<html>
			<head>
				<script type="text/javascript">
					function init()
					{
                        adicionaFlash();
					}

                    function adicionaFlash()
                    {
                        // carrega o flash, no container 'splayer', com 200x200
                        var params={allowscriptaccess:"always", wmode: "window", width: 200, height: 200}
                        gadgets.flash.embedFlash("http://www.opensocial-br.org/exemplo/teste_opensocial.swf", document.getElementById("splayer"), 9, params);
                    }

                    // wrapper para chamar funcao flash
                    function thisMovie(movieName) {
                        if (navigator.appName.indexOf("Microsoft") != -1) {
                            return window[movieName];
                        } else {
                            return document.getElementById(movieName);
                        }
                    }

                    // chamada do flash
                    function teste()
                    {
                        alert("flash chamou a funcao teste");
                    }

                    // javascript que chama o callback do flash
                    function chamaFuncaoFlash()
                    {
                        // notar o 'swfContainer0', que pode ser inspecionado pelo firebug é colocado automaticamente como
                        // swfContainer0 . Pode-se criar um javascript que pegue o próximo child do container 'splayer'

                        thisMovie("swfContainer0").continuacaoTeste("string de teste");
                    }

                    // funcao de carga padrão do opensocial
					gadgets.util.registerOnLoadHandler(init);
				</script>
			</head>
			<body>
                <div id="splayer">flash carrega aqui</div>
				<input type="button" value="callback flash" onclick="chamaFuncaoFlash();">
			</body>
		</html>
		]]>
	</Content>
</Module>

Notas importantes:

  • É necessário usar gadgets.flash.embedFlash para garantir que não exista problemas de segurança;
  • Veja o wrapper "thisMovie". É uma função auxiliar para trazer o id do flash, que não funciona no IE da mesma forma que o firefox;

Caso queira, pode baixar o código fonte:

Referências:

  1. Flash and Everything Else - Guya.net ;
  2. Referência de ExternalInterface - site da Adobe;

Espero que tenha ajudado, e caso tenha alguma dúvida, faça contato no formulário de comentários abaixo.