I am attempting to ExternalInterface.call() from inside my SWF.
Note the call comes from inside a SWF I have embedded into another SWF (the _root SWF I have no control over).
Here is my JavaScript:
function player_DoFSCommand(command, args)
{
args = String(args);
command = String(command);
var arrArgs = args.split(g_strDelim);
switch (command)
{
case "CC_ClosePlayer":
console.log("yo");
break;
default:
// alert(command);
break;
}
}
Here is my AS2 code:
import flash.external.ExternalInterface;
var quiz = _root;
quiz.g_mcFrame.mcFinish.swapDepths(quiz.getNextHighestDepth());
quiz.g_mcFrame.mcFinish._visible = false;
quiz.oSlide.m_oInteraction.m_oVariableMgr.m_arrBoolResumeData = false;
var arrVars:Object = quiz.oSlide.m_oActionHandler.m_oFrame.m_oVariableMgr.m_arrVariables;
var args:Array = [
arrVars[2].m_nNumber, // Points awarded
arrVars[3].m_nNumber, // Max points
arrVars[5].m_nNumber, // Pass percentage
arrVars[6].m_nNumber, // Pass points
arrVars[7].m_nNumber, // Score percent
arrVars[10].m_strString // Result
];
ExternalInterface.call('player_DoFSCommand("CC_ClosePlayer", args)');
ExternalInterface.call('console.log("hello")');
The problem is ExternalInterface.call('player_DoFSCommand("CC_ClosePlayer", args)') doesn't work, or atleast "yo" doesn't appear in the console as expected.
The script is definitely loaded by the time the ExternalInterface is called. The second call works and "hello" appears in the console, however the first function doesn't fire.
I can verify the function works by typing directly into the console player_DoFSCommand("CC_ClosePlayer", args) and it logs successfully.
Can you verify that allowScriptAccess is set to true in the embed code?
Try this:
var isAvailable:Boolean = ExternalInterface.available;
trace(isAvailable);
You also want to use ExternalInterface like this, with your arguments passed as the second variable:
ExternalInterface.call("player_DoFSCommand",args);
or
ExternalInterface.call("console.log","testing...");
Related
I have the following code in my SAPUI5 app.
This function is trigger when a button is clicked.
onClear(oEvent){
var source = oEvent.getSource().getText(); //get the text on the button
....
}
In my Unit test I have
QUnit.module('onClear functio test);
Qunit.test('onClear press test', function(assert){
var getSource = sinon.spy();
var getText = sinon.spy();
var oEvent = {getSsource: getSource};
var source = "Clear"; //this is what should be return for this test
//call the function
mainController.onClear(oEvent, source);
}
The error I get is "Unable to get property 'getText' of undefined or null reference"
From SAP API, oEvent.getSource() simply returns a reference to the object triggering the event, in this case a button. During the testing .getSource() doesn't return anything I believe.
So how can make this work? I know I can break down my code into 2 different lines and spy/stub those 2 functions separately but I don't want to do that as the code I have is valid JavaScript code.
Say I have the following broken example function in a google-apps script. The function is intended to be called from a google sheet with a string argument:
function myFunction(input) {
var caps = input.toUpperCase()
var output = caps.substrin(1, 4)
return output
}
While this example script should break on line 3 when you select myFunction and press debug, as there is no such method as "substrin()," it will break on line 2, because you can't put undefined in all caps:
TypeError: Cannot call method "toUpperCase" of undefined. (line 2,
file "Code")
Question:
Is there an official way to pass a string to a google-apps script for testing/debugging without making an additional function
function myOtherFunction() {
myFunction("testString")
}
and debugging that?
The function as you wrote it does need a parameter and there is no way to avoid that except by including a default value in the function itself. See example below
function myFunction(input) {
input= input||'test';
var caps = input.toUpperCase();
var output = caps.substrin(1, 4);
return output;
}
the following code works perfect of Firefox but crashes on Chrome, with the following error: Uncaught TypeError: Property 'pos' of object [object Object] is not a function
Here is the code, with comments:
var CantidadMenu = $('div[class^=container_menu_]').length;
var position = $("#menu_unidades").position();
var IzAdd = 0;
var w = $("#menu_unidades").width();
var h = $("#menu_unidades").height();
for (i=0;i<CantidadMenu;i++){
var pos = 'pos'+(i+1); //I create a variable that will hold a string like: pos1,pos2...
IzAdd = IzAdd+25;
function pos(div){ //on this line I use the variable I created, which crashes on Chrome
var estilo1 = $(div).css({'left':IzAdd+25,'top':position.top+(IzAdd-25)});
return estilo1;
}
pos('.container_menu_'+(i+1));
$('.container_menu_'+(i+1)).css({'z-index':297+i,'width':w,'height':h});
}
Here you define a function named pos:
function pos(div){ //on this line I use the variable I created, which crashes on Chrome
var estilo1 = $(div).css({'left':IzAdd+25,'top':position.top+(IzAdd-25)});
return estilo1;
}
console.log(pos) // function ....
Here you overwrite it with a string:
var pos = 'pos'+(i+1);
console.log(pos) // string....
You should name either the function or the string to something else.
PS: I know that in your code the order is reversed, but function declarations are hoisted to the top of the scope, so the JS interpreter "sees" them in the order i wrote them in: first function, then the string.
PSS: The crash is actually on this line:
pos('.container_menu_'+(i+1));
function pos(div) is the same as var pos = function(div)... (except the former is defined at the parse-time, and the latter at the run-time, but that's irrelevant for your code), so if you expected by defining that pos = 'pos1';, for example, you'd get function pos(div) to become function pos1(div), it won't.
It will just overwrite the pos variable, and it will no longer be a string, but a function.
To fix your code, write a single function at the top of your code, outside of the for loop, add another parameter to it (IzAdd) and make sure you fix the function calls appropriately.
The function should look something like this:
function pos(div, IzAdd){
return $(div).css({'left':IzAdd+25,'top':position.top+(IzAdd-25)});
}
I am stuck with slight problem for a while now : Need to store in state a random number, that would persist to all participants.
alert(delta[random]);
returns value so everything is expected to be ok to this point however that's where mystery starts:
i already tried
$.each(gapi.hangout.data.getKeys(),function(i,o){
alert(o);
});
but it never enters loop. however if I place
alert('dfsdasd');
after submitDelta it works.
last two lines
alert(gapi.hangout.data.getValue(random));
$("#randomNumber").val(gapi.hangout.data.getValue(random));
are dead, no alert with 'undefined' or [object].
function setRandom()
{
var rand = Math.floor(Math.random()*100);
var random = "randomNumber";
var delta = {};
delta[random] = JSON.stringify(rand);
alert(delta[random]);
gapi.hangout.data.submitDelta(delta);
alert(gapi.hangout.data.getValue(random));
$("#randomNumber").val(gapi.hangout.data.getValue(random));
}
i have included
both libraries
src="//talkgadget.google.com/hangouts/_/api/hangout.js?v=1.1"
and src="http://code.jquery.com/jquery-1.7.2.js"
no handler on onStateChanged
what am I doing wrong here?
anytime I touch gapi.hangouts.data it fails.
It looks like there are are two issues here that I see.
The first is that submitDelta is defined as taking two parameters, and you provide only one.
The other issue is that submitDelta() is asynchronous, so you should not expect getValue() or getState() to work immediately after it is called. The best way to handle things in this case is to register for a StateChangedEvent using onStateChanged.add().
So, for example, you might do something like this:
function init(){
gapi.hangout.data.onStateChanged.add( handleChange );
submitRandom();
}
function handleChange( stateChangedEvent ){
var random = "randomNumber";
var val = gapi.hangout.data.getValue(random);
alert(val);
$("#randomNumber").val(val);
}
function submitRandom(){
var rand = Math.floor(Math.random()*100);
var random = "randomNumber";
var delta = {};
delta[random] = JSON.stringify(rand);
alert(delta[random]);
gapi.hangout.data.submitDelta(delta, []);
}
I am making flash player that suppose to be controlled from outside, from javascript.
I need those methods:
Play/Pause and Volume level
I am stuck with volume level... I tried to add this code:
flashMovie.volume = 10;
Where flashMovie is flash instance... And it's show NO ERROR but it's NOT WORKING
I try to make inner AddCall(); and then when it's called to call() from javascript to return sound level.
AS 3:
function setthisvolume()
{
var vlm = ExternalInterface.call('giveMeVolume()');
this.soundTransform.volume = vlm;
}
ExternalInterface.addCallback("setthisvolume", setthisvolume);
JS:
var soundlevel = 10;
function soundlevelset()
{
var flashMovie=getFlashMovieObject("objswf");
flashMovie.setthisvolume();
}
function giveMeVolume()
{
return parseInt(soundlevel);
}
But I am getting this error:
Error calling method on NPObject!
I even tried with setInterval():
AS 3:
function setthisvolume()
{
var vlm = ExternalInterface.call('giveMeVolume()');
this.soundTransform.volume = vlm;
}
setInterval(setthisvolume, 1000);
JS:
var soundlevel = 10;
function giveMeVolume()
{
return parseInt(soundlevel);
}
And it doesn't show any error, but it doesn't work neither...
Did someone work with stuffs like this?
Can someone help me what I am doing wrong here...
Thank you!
Thank you, #someone!
This second option worked okay!
Here is working code:
AS3:
function setthisvolume(vlm)
{
this.soundTransform = new SoundTransform(vlm);
}
ExternalInterface.addCallback("setthisvolume", setthisvolume);
JS:
function getFlashMovieObject(movieName)
{
if (window.document[movieName])
{
return window.document[movieName];
}
if (navigator.appName.indexOf("Microsoft Internet")==-1)
{
if (document.embeds && document.embeds[movieName])
return document.embeds[movieName];
}
else
{
return document.getElementById(movieName);
}
}
var soundlevel = 0.5; // it's 0-1 volume, not 0-100
function soundlevelset()
{
var flashMovie=getFlashMovieObject("objswf");
flashMovie.setthisvolume(parseFloat(soundlevel));
}
When you are using slider each time slider change you need to change soundlevel variable and call soundlevelset();
Hope I helped next one who is starting with this... :)
Thank you!
Try removing the parentheses when calling giveMeVolume, by changing this:
var vlm = ExternalInterface.call('giveMeVolume()');
to this:
var vlm = ExternalInterface.call('giveMeVolume');
If that doesn't work, try passing the volume directly as an argument/parameter, like this (this is probably a better way to do it):
AS3:
function setthisvolume(vlm)
{
this.soundTransform.volume = vlm;
}
ExternalInterface.addCallback("setthisvolume", setthisvolume);
JS:
var soundlevel = 10;
function soundlevelset()
{
var flashMovie=getFlashMovieObject("objswf");
flashMovie.setthisvolume(soundlevel);
}
Code looks reasonable.
Check if you allow Flash to communicate with script There is property when you create Flash object - AllowsScriptAccess - http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7c9b.html .
Check if Falsh is coming from the same domain as HTML page.
For addCallback check if you are getting correct Flash object by Id (the way to create Flash is different in IE/FF, so you may be getting the wrong one).
Check if you have correct SWF file - browser may cache older version... I.e. add element on the Flash control that simply shows static number and make sure it matches to latest one.