[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r12259: migrate from branch. Error h
From: |
Rob Savoye |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r12259: migrate from branch. Error handling now works, and remote functions are now accessible to Javascript |
Date: |
Fri, 18 Jun 2010 09:48:04 -0600 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 12259 [merge]
committer: Rob Savoye <address@hidden>
branch nick: trunk
timestamp: Fri 2010-06-18 09:48:04 -0600
message:
migrate from branch. Error handling now works, and remote functions are now
accessible to Javascript
modified:
gui/gnash.cpp
libcore/ExternalInterface.cpp
libcore/ExternalInterface.h
libcore/asobj/flash/external/ExternalInterface_as.cpp
libcore/movie_root.cpp
libcore/movie_root.h
plugin/npapi/callbacks.cpp
plugin/npapi/callbacks.h
plugin/npapi/plugin.cpp
plugin/npapi/plugin.h
plugin/npapi/pluginScriptObject.cpp
plugin/npapi/pluginScriptObject.h
plugin/npapi/scriptable-test.html
testsuite/actionscript.all/ExternalInterface.as
=== modified file 'gui/gnash.cpp'
--- a/gui/gnash.cpp 2010-05-08 21:33:27 +0000
+++ b/gui/gnash.cpp 2010-06-15 16:45:19 +0000
@@ -141,7 +141,7 @@
"URLs\n")
<< _(" -P, --param <param> Set parameter (e.g. "
"\"FlashVars=A=1&b=2\")\n")
- << _(" -F, --fd <fd> Filedescriptor to use for external "
+ << _(" -F, --fd <fd>:<fd> Filedescriptor to use for external "
"communications\n")
#ifdef GNASH_FPS_DEBUG
<< _(" -f, --debug-fps num Print FPS every num seconds (float)\n")
=== modified file 'libcore/ExternalInterface.cpp'
--- a/libcore/ExternalInterface.cpp 2010-06-03 19:29:37 +0000
+++ b/libcore/ExternalInterface.cpp 2010-06-15 16:52:07 +0000
@@ -469,7 +469,7 @@
}
}
- log_debug("Argument is: %s", value.to_string());
+// log_debug("Argument is: %s", value.to_string());
return value;
}
=== modified file 'libcore/ExternalInterface.h'
--- a/libcore/ExternalInterface.h 2010-06-08 14:25:12 +0000
+++ b/libcore/ExternalInterface.h 2010-06-15 16:52:07 +0000
@@ -35,6 +35,7 @@
struct ObjectURI;
class Global_as;
class movie_root;
+class IOChannel;
}
namespace gnash {
=== modified file 'libcore/asobj/flash/external/ExternalInterface_as.cpp'
--- a/libcore/asobj/flash/external/ExternalInterface_as.cpp 2010-06-04
13:14:31 +0000
+++ b/libcore/asobj/flash/external/ExternalInterface_as.cpp 2010-06-18
03:29:25 +0000
@@ -36,6 +36,7 @@
#include "smart_ptr.h" // for boost intrusive_ptr
#include "builtin_function.h" // need builtin_function
#include "GnashException.h" // for ActionException
+#include "URLAccessManager.h"
#include "VM.h"
#include "rc.h"
#include "as_value.h"
@@ -229,11 +230,11 @@
callMethod(&gl, NSV::PROP_AS_SET_PROP_FLAGS, &o, null, 7);
}
+// This adds a function that can be called from javascript.
as_value
externalinterface_addCallback(const fn_call& fn)
{
// GNASH_REPORT_FUNCTION;
-
movie_root& mr = getRoot(fn);
if (mr.getControlFD() <= 0) {
@@ -248,35 +249,44 @@
if (fn.arg(2).is_object()) {
log_debug("adding callback %s", name);
asCallback = (fn.arg(2).to_object(getGlobal(fn)));
- mr.addExternalCallback(name, asCallback.get());
+ mr.addExternalCallback(fn.this_ptr, name, asCallback.get());
}
- return as_value(true);
- }
-
+ }
+
+ // This function doesn't actually have a return value, but we do this
+ // to quiet warnings about not returning anything, as the return
+ // value should never be checked anyway.
return as_value(false);
}
+// This calls a Javascript function in the browser.
as_value
externalinterface_call(const fn_call& fn)
{
// GNASH_REPORT_FUNCTION;
-
movie_root& mr = getRoot(fn);
+ as_value val;
if (fn.nargs >= 2) {
const as_value& methodName_as = fn.arg(0);
const std::string methodName = methodName_as.to_string();
const std::vector<as_value>& args = fn.getArgs();
log_debug("Calling External method \"%s\"", methodName);
- std::string result = mr.callExternalCallback(methodName, args);
- if (result.empty()) {
- return as_value();
+ std::string result = mr.callExternalJavascript(methodName, args);
+ if (!result.empty()) {
+ val = ExternalInterface::parseXML(result);
+ // There was an error trying to Invoke the callback
+ if (result == ExternalInterface::makeString("Error")
+ || (result == ExternalInterface::makeString("SecurityError")))
{
+ val.set_null();
+ }
} else {
- return as_value(result);
+ // We got nothing back from the Invoke, so return an error
+ val.set_null();
}
}
- return as_value();
+ return val;
}
as_value
@@ -286,6 +296,12 @@
movie_root& m = getRoot(fn);
bool mode = false;
+
+ // If we're not running under a browser as a plugin, then just
+ // return, as ExternalInterface is only available as a plugin.
+ if (m.getHostFD() < 0) {
+ return false;
+ }
switch (m.getAllowScriptAccess()) {
case movie_root::SCRIPT_ACCESS_NEVER:
@@ -297,6 +313,7 @@
const std::string& baseurl = m.getOriginalURL();
const int MAXHOSTNAMELEN = 128;
char hostname[MAXHOSTNAMELEN];
+ memset(hostname, 0, MAXHOSTNAMELEN);
if (gethostname(hostname, MAXHOSTNAMELEN) != 0) {
mode = false;
@@ -305,6 +322,10 @@
// The hostname is empty if running the standalone Gnash from
// a terminal, so we can assume the default of sameDomain applies.
URL localPath(hostname, baseurl);
+ // If the URL has a file protocol, then
+ if (URLAccessManager::allow(localPath)) {
+ return as_value(true);
+ }
if (localPath.hostname().empty()) {
mode = false;
} else {
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2010-06-12 01:40:51 +0000
+++ b/libcore/movie_root.cpp 2010-06-18 03:28:37 +0000
@@ -1617,13 +1617,14 @@
if (invoke == 0) {
return false;
}
+
if (invoke->name.empty()) {
return false;
}
log_debug("Processing %s call from the Browser.", invoke->name);
- std::stringstream ss;
+ std::stringstream ss; // ss is the response string
// These are the default methods used by ExternalInterface
if (invoke->name == "Quit") {
@@ -1635,8 +1636,13 @@
// SetVariable doesn't send a response
} else if (invoke->name == "GetVariable") {
// GetVariable sends the value of the variable
+#if 1
as_value val("Hello World");
// FIXME: need to use a real value
+#else
+ as_object::SortedPropertyList props;
+ enumerateProperties(o, props);
+#endif
ss << ExternalInterface::toXML(val);
} else if (invoke->name == "GotoFrame") {
// GotoFrame doesn't send a response
@@ -1670,11 +1676,13 @@
// FIXME: need to use a real value
ss << ExternalInterface::toXML(val);
} else {
- std::map<std::string, as_object *>::const_iterator it;
- for (it=_externalCallbacks.begin(); it != _externalCallbacks.end();
it++) {
- std::string method = it->first;
- log_debug("Checking against method name: %s", method);
- }
+ std::string result = callExternalCallback(invoke->name, invoke->args);
+ if (result == ExternalInterface::makeString("Error")) {
+ return false;
+ } else if (result == ExternalInterface::makeString("SecurityError")) {
+ return false;
+ }
+ return true;
}
if (!ss.str().empty()) {
@@ -1856,31 +1864,139 @@
return 0;
}
-// This calls a JavaScript method in the web page
+/// @example "Internal Gnash message 'addMethod'"
+///
+/// <pre>
+/// <invoke name="addMethod" returntype="xml">
+/// <arguments><string>methodname</string</arguments>
+/// </invoke>
+/// </pre>
+void
+movie_root::addExternalCallback(as_object *obj, const std::string &name,
+ as_object *callback)
+{
+ GNASH_REPORT_FUNCTION;
+
+ _externalCallbacks.push_back(ExternalCallback(obj, name, callback));
+
+ if (_hostfd) {
+ std::vector<as_value> fnargs;
+ fnargs.push_back(name);
+ std::string msg = ExternalInterface::makeInvoke("addMethod", fnargs);
+
+ const size_t ret = ExternalInterface::writeBrowser(_hostfd, msg);
+ if (ret != msg.size()) {
+ log_error(_("Could not write to browser fd #%d: %s"),
+ _hostfd, std::strerror(errno));
+ }
+ }
+}
+
+/// This calls a JavaScript method in the web page
+///
+/// @example "ExternalInterace::call message"
+///
+/// <pre>
+/// <invoke name="methodname" returntype="xml">
+/// <arguments></arguments>
+/// ...
+/// <arguments></arguments>
+/// </invoke>
+///
+/// May return any supported type like Number or String in XML format.
+///
+/// </pre>
+std::string
+movie_root::callExternalJavascript(const std::string &name,
+ const std::vector<as_value> &fnargs)
+{
+ std::string result;
+ ExternalCallbacks::const_iterator it;
+ // If the browser is connected, we send an Invoke message to the
+ // browser.
+ if (_controlfd && _hostfd) {
+ std::string msg = ExternalInterface::makeInvoke(name, fnargs);
+
+ const size_t ret = ExternalInterface::writeBrowser(_hostfd, msg);
+ if (ret != msg.size()) {
+ log_error(_("Could not write to browser fd #%d: %s"),
+ _hostfd, std::strerror(errno));
+ } else {
+ // Now read the response from the browser after it's exectuted
+ // the JavaScript function.
+ result = ExternalInterface::readBrowser(_controlfd);
+ }
+ }
+
+ return result;
+}
+
+// Call one of the registered callbacks, and return the result to
+// Javascript in the browser.
std::string
movie_root::callExternalCallback(const std::string &name,
const std::vector<as_value> &fnargs)
{
-
- if (_hostfd) {
- return std::string();
- }
-
- std::string msg = ExternalInterface::makeInvoke(name, fnargs);
-
- const size_t ret = ExternalInterface::writeBrowser(_hostfd, msg);
- if (ret != msg.size()) {
- log_error(_("Could not write to browser fd #%d: %s"),
- _hostfd, std::strerror(errno));
- return std::string();
- }
-
- std::string result = ExternalInterface::readBrowser(_controlfd);
+ std::string result;
+ ExternalCallbacks::const_iterator it;
+ for (it=_externalCallbacks.begin(); it != _externalCallbacks.end(); it++) {
+ ExternalCallback ec = *it;
+ log_debug("Checking %s against method name: %s", name,
ec.methodName());
+
+ // FIXME: call the AS method here!
+
+ as_value val;
+ if (name == ec.methodName()) {
+ std::string result;
+ val = ec.call(fnargs);
+ }
+
+ if (val.is_null()) {
+ // Return an error
+ result = ExternalInterface::makeString("Error");
+ } else {
+ result = ExternalInterface::toXML(val);
+ }
+
+ // If the browser is connected, we send an Invoke message to the
+ // browser.
+ if (_hostfd) {
+ const size_t ret = ExternalInterface::writeBrowser(_hostfd,
result);
+ if (ret != result.size()) {
+ log_error(_("Could not write to browser fd #%d: %s"),
+ _hostfd, std::strerror(errno));
+ }
+ }
+ }
return result;
}
void
+movie_root::ExternalCallback::setReachable() const
+{
+ _caller->setReachable();
+}
+
+as_value
+movie_root::ExternalCallback::call(const std::vector<as_value>& args)
+{
+ GNASH_REPORT_FUNCTION;
+
+#if 0
+ as_environment env(VM::get());
+ fn_call::Args newargs;
+ as_function *as_func = _callback->to_function();
+ fn_call fn(0, env, newargs);
+
+ as_func->call(fn);
+#endif
+
+ return as_value();
+}
+
+
+void
movie_root::cleanupDisplayList()
{
@@ -2553,3 +2669,7 @@
} // namespace gnash
+// local Variables:
+// mode: C++
+// indent-tabs-mode: nil
+// End:
=== modified file 'libcore/movie_root.h'
--- a/libcore/movie_root.h 2010-06-06 11:27:45 +0000
+++ b/libcore/movie_root.h 2010-06-18 03:29:09 +0000
@@ -164,8 +164,25 @@
SimpleBuffer _buf;
as_object* _obj;
};
-
typedef std::list<LoadCallback> LoadCallbacks;
+
+ class ExternalCallback {
+ public:
+ ExternalCallback(as_object *obj, const std::string &name,
+ as_object *callback)
+ : _name(name),
+ _caller(obj),
+ _callback(callback)
+ {}
+ std::string &methodName() { return _name; };
+ as_value call(const std::vector<as_value>& args);
+ void setReachable() const;
+ private:
+ std::string _name;
+ as_object *_caller;
+ as_object *_callback;
+ };
+ typedef std::list<ExternalCallback> ExternalCallbacks;
typedef std::bitset<key::KEYCOUNT> Keys;
@@ -920,15 +937,16 @@
const RunResources& runResources() const { return _runResources; }
- void addExternalCallback(const std::string &name, as_object *obj)
- {
- _externalCallbacks[name] = obj;
- }
+ void addExternalCallback(as_object *obj, const std::string &name,
+ as_object *callback);
bool processInvoke(ExternalInterface::invoke_t *);
std::string callExternalCallback(const std::string &name,
const std::vector<as_value>& args);
+
+ std::string callExternalJavascript(const std::string &name,
+ const std::vector<as_value>& args);
/// Removes a queued constructor from the execution queue
//
@@ -1141,7 +1159,6 @@
LoadCallbacks _loadCallbacks;
- typedef std::map<std::string, as_object *> ExternalCallbacks;
ExternalCallbacks _externalCallbacks;
typedef std::map<int, Timer*> TimerMap;
=== modified file 'plugin/npapi/callbacks.cpp'
--- a/plugin/npapi/callbacks.cpp 2010-05-31 22:19:55 +0000
+++ b/plugin/npapi/callbacks.cpp 2010-06-18 03:27:56 +0000
@@ -170,14 +170,12 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
- ExternalInterface ei;
-
std::string varname;
if (argCount == 1) {
- std::string str = ei.convertNPVariant(&args[0]);
+ std::string str = ExternalInterface::convertNPVariant(&args[0]);
std::vector<std::string> iargs;
iargs.push_back(str);
- str = ei.makeInvoke("GotoFrame", iargs);
+ str = ExternalInterface::makeInvoke("GotoFrame", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -214,9 +212,8 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 0) {
- ExternalInterface ei;
std::vector<std::string> iargs;
- std::string str = ei.makeInvoke("IsPlaying", iargs);
+ std::string str = ExternalInterface::makeInvoke("IsPlaying", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -233,7 +230,7 @@
return false;
}
- GnashNPVariant value = ei.parseXML(data);
+ GnashNPVariant value = ExternalInterface::parseXML(data);
if (NPVARIANT_TO_BOOLEAN(value.get()) == true) {
BOOLEAN_TO_NPVARIANT(true, *result);
} else {
@@ -268,15 +265,14 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 2) {
- ExternalInterface ei;
// int layer = NPVARIANT_TO_INT32(args[0]);
// std::string url = NPStringToString(NPVARIANT_TO_STRING(args[1]));
- std::string str = ei.convertNPVariant(&args[0]);
+ std::string str = ExternalInterface::convertNPVariant(&args[0]);
std::vector<std::string> iargs;
iargs.push_back(str);
- str = ei.convertNPVariant(&args[1]);
+ str = ExternalInterface::convertNPVariant(&args[1]);
iargs.push_back(str);
- str = ei.makeInvoke("LoadMovie", iargs);
+ str = ExternalInterface::makeInvoke("LoadMovie", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -317,15 +313,14 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 3) {
- ExternalInterface ei;
- std::string str = ei.convertNPVariant(&args[0]);
+ std::string str = ExternalInterface::convertNPVariant(&args[0]);
std::vector<std::string> iargs;
iargs.push_back(str);
- str = ei.convertNPVariant(&args[1]);
- iargs.push_back(str);
- str = ei.convertNPVariant(&args[2]);
- iargs.push_back(str);
- str = ei.makeInvoke("Pan", iargs);
+ str = ExternalInterface::convertNPVariant(&args[1]);
+ iargs.push_back(str);
+ str = ExternalInterface::convertNPVariant(&args[2]);
+ iargs.push_back(str);
+ str = ExternalInterface::makeInvoke("Pan", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -353,13 +348,11 @@
// Receives something like this:
// <number>33</number>
bool
-PercentLoaded (NPObject *npobj, NPIdentifier /* name */, const NPVariant
*/*args */,
- uint32_t argCount, NPVariant *result)
+PercentLoaded (NPObject */* npobj */, NPIdentifier /* name */, const NPVariant
*/*args */,
+ uint32_t /* argCount */, NPVariant *result)
{
// log_debug(__PRETTY_FUNCTION__);
- GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
-
#if 1
static int counter = 0;
// log_error("%s: %d ; %d\n", __FUNCTION__, gpso->getControlFD(), counter);
@@ -371,10 +364,11 @@
}
return true;
#else
+ GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
if (argCount == 0) {
- ExternalInterface ei;
std::vector<std::string> iargs;
- std::string str = ei.makeInvoke("PercentLoaded", iargs);
+ std::string str = ExternalInterface::makeInvoke("PercentLoaded",
iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -424,9 +418,8 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 0) {
- ExternalInterface ei;
std::vector<std::string> iargs;
- std::string str = ei.makeInvoke("Play", iargs);
+ std::string str = ExternalInterface::makeInvoke("Play", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -463,9 +456,8 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 0) {
- ExternalInterface ei;
std::vector<std::string> iargs;
- std::string str = ei.makeInvoke("Rewind", iargs);
+ std::string str = ExternalInterface::makeInvoke("Rewind", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -506,17 +498,16 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 4) {
- ExternalInterface ei;
- std::string str = ei.convertNPVariant(&args[0]);
+ std::string str = ExternalInterface::convertNPVariant(&args[0]);
std::vector<std::string> iargs;
iargs.push_back(str);
- str = ei.convertNPVariant(&args[1]);
- iargs.push_back(str);
- str = ei.convertNPVariant(&args[2]);
- iargs.push_back(str);
- str = ei.convertNPVariant(&args[3]);
- iargs.push_back(str);
- str = ei.makeInvoke("SetZoomRect", iargs);
+ str = ExternalInterface::convertNPVariant(&args[1]);
+ iargs.push_back(str);
+ str = ExternalInterface::convertNPVariant(&args[2]);
+ iargs.push_back(str);
+ str = ExternalInterface::convertNPVariant(&args[3]);
+ iargs.push_back(str);
+ str = ExternalInterface::makeInvoke("SetZoomRect", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -552,9 +543,8 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 0) {
- ExternalInterface ei;
std::vector<std::string> iargs;
- std::string str = ei.makeInvoke("StopPlay", iargs);
+ std::string str = ExternalInterface::makeInvoke("StopPlay", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -593,11 +583,10 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 1) {
- ExternalInterface ei;
- std::string str = ei.convertNPVariant(&args[0]);
+ std::string str = ExternalInterface::convertNPVariant(&args[0]);
std::vector<std::string> iargs;
iargs.push_back(str);
- str = ei.makeInvoke("Zoom", iargs);
+ str = ExternalInterface::makeInvoke("Zoom", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -633,9 +622,8 @@
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
if (argCount == 0) {
- ExternalInterface ei;
std::vector<std::string> iargs;
- std::string str = ei.makeInvoke("TotalFrames", iargs);
+ std::string str = ExternalInterface::makeInvoke("TotalFrames", iargs);
// Write the message to the Control FD.
size_t ret = gpso->writePlayer(str);
@@ -652,7 +640,7 @@
return false;
}
- GnashNPVariant value = ei.parseXML(data);
+ GnashNPVariant value = ExternalInterface::parseXML(data);
if (NPVARIANT_IS_INT32(value.get())) {
value.copy(*result);
} else {
@@ -666,6 +654,82 @@
return false;
}
+// Sends something like this:
+// <invoke name="TestASMethod" returntype="xml">
+// <arguments>
+// <number>123</number>
+// </arguments>
+// </invoke>
+//
+// Receives:
+// An XML response of one of the standard types like Number or String.
+bool
+remoteCallback (NPObject *npobj, NPIdentifier name, const NPVariant *args,
+ uint32_t argCount, NPVariant *result)
+{
+ // log_debug(__PRETTY_FUNCTION__);
+
+ GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
+
+ std::string method;
+
+#if 1
+ if (NPN_IdentifierIsString(name)) {
+ log_debug("Invoking remote Method \"%s\"...",
+ NPN_UTF8FromIdentifier(name));
+ method = NPN_UTF8FromIdentifier(name);
+ } else {
+ log_debug("Invoking remote Method: \"%d\"...",
+ NPN_IntFromIdentifier(name));
+ }
+#endif
+
+ // Build the argument array
+ std::vector<std::string> fnargs;
+ for (uint32_t i=0; i<argCount; ++i) {
+ std::string xml = ExternalInterface::convertNPVariant(&args[i]);
+ fnargs.push_back(xml);
+
+ }
+
+ std::string str = ExternalInterface::makeInvoke(method, fnargs);
+
+ // Write the message to the Control FD.
+ size_t ret = gpso->writePlayer(str);
+ // Unless we wrote the same amount of data as the message contained,
+ // something went wrong.
+ if (ret != str.size()) {
+ log_error("Couldn't invoke %s, network problems.", method);
+ return false;
+ }
+
+ // Have the read function allocate the memory
+ std::string data = gpso->readPlayer();
+ if (data.empty()) {
+ log_error("Couldn't read a response for invoke, network problems.");
+ NULL_TO_NPVARIANT(*result);
+ return false;
+ }
+
+ std::string answer;
+ GnashNPVariant parsed = ExternalInterface::parseXML(data);
+ if (!NPVARIANT_IS_NULL(parsed.get())) {
+ answer = NPStringToString(NPVARIANT_TO_STRING(parsed.get()));
+ }
+ if (answer == "Error") {
+ NULL_TO_NPVARIANT(*result);
+ } else if (answer == "SecurityError") {
+ NULL_TO_NPVARIANT(*result);
+ } else {
+ parsed.copy(*result);
+ }
+
+ // printNPVariant(&parsed.get());
+
+ // Returning false makes Javascript stop executing the script.
+ return true;
+}
+
} // end of gnash namespace
// local Variables:
=== modified file 'plugin/npapi/callbacks.h'
--- a/plugin/npapi/callbacks.h 2010-04-21 19:46:03 +0000
+++ b/plugin/npapi/callbacks.h 2010-06-16 20:02:01 +0000
@@ -287,6 +287,10 @@
const NPVariant *args, uint32_t argCount,
NPVariant *result);
+extern bool remoteCallback (NPObject *npobj, NPIdentifier name,
+ const NPVariant *args, uint32_t argCount,
+ NPVariant *result);
+
#endif // GNASH_PLUGIN_CALLBACKS_H
} // end of gnash namespace
=== modified file 'plugin/npapi/plugin.cpp'
--- a/plugin/npapi/plugin.cpp 2010-06-12 01:40:51 +0000
+++ b/plugin/npapi/plugin.cpp 2010-06-17 20:35:31 +0000
@@ -66,6 +66,7 @@
#include "GnashSystemIOHeaders.h"
#include "StringPredicates.h"
#include "external.h"
+#include "callbacks.h"
#include "npapi.h"
#include "npruntime.h"
#include "npfunctions.h"
@@ -321,6 +322,8 @@
nsPluginInstanceBase *
NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct)
{
+ // gnash::log_debug(__PRETTY_FUNCTION__);
+
if(!aCreateDataStruct) {
return NULL;
}
@@ -358,8 +361,11 @@
_controlfd(-1),
_childpid(0),
_filefd(-1),
- _name()
+ _name(),
+ _scriptObject(0)
{
+ // gnash::log_debug("%s: %x", __PRETTY_FUNCTION__, (void *)this);
+
for (size_t i=0, n=data->argc; i<n; ++i) {
std::string name, val;
gnash::StringNoCaseEqual noCaseCompare;
@@ -378,11 +384,14 @@
_params[name] = val;
}
-
+
+#if 1
if (NPNFuncs.version >= 14) { // since NPAPI start to support
_scriptObject = (GnashPluginScriptObject *)NPNFuncs.createobject(
_instance, GnashPluginScriptObject::marshalGetNPClass());
+ log_debug("SCRIPT OBJECT create: %x, ns: %x", (void *)_scriptObject,
(void *)this);
}
+#endif
return;
}
@@ -535,6 +544,7 @@
NPError
nsPluginInstance::GetValue(NPPVariable aVariable, void *aValue)
{
+
if (aVariable == NPPVpluginScriptableNPObject) {
if (_scriptObject) {
void **v = (void **)aValue;
@@ -545,6 +555,8 @@
}
}
+ // log_debug("SCRIPT OBJECT getValue: %x, ns: %x", (void *)_scriptObject,
(void *)this);
+
return NS_PluginGetValue(aVariable, aValue);
}
@@ -569,6 +581,8 @@
nsPluginInstance::NewStream(NPMIMEType /*type*/, NPStream* stream,
NPBool /*seekable*/, uint16_t* /*stype*/)
{
+ // gnash::log_debug("%s: %x", __PRETTY_FUNCTION__, (void *)this);
+
if (_childpid) {
// Apparently the child process has already been started for this
// plugin instance. It is puzzling that this method gets called
@@ -639,6 +653,7 @@
bool
nsPluginInstance::handlePlayerRequests(GIOChannel* iochan, GIOCondition cond)
{
+ // gnash::log_debug("%s: %d: %x", __PRETTY_FUNCTION__, __LINE__, (void
*)this);
if ( cond & G_IO_HUP ) {
gnash::log_debug("Player control socket hang up");
@@ -658,6 +673,8 @@
// g_io_channel_set_flags(iochan, G_IO_FLAG_NONBLOCK, &error);
size_t retries = 5;
+ gchar* request = 0;
+ gsize requestSize = 0;
do {
// When in non-blocking mode, we'll get several iterations of this
// loop while waiting for data. if data never arrives, we'd be stuck
@@ -667,8 +684,8 @@
return false;
}
error = 0;
- gchar* request = 0;
- gsize requestSize = 0;
+ request = 0;
+ requestSize = 0;
GIOStatus status = g_io_channel_read_line(iochan, &request,
&requestSize, NULL, &error);
switch (status) {
@@ -699,20 +716,21 @@
gnash::log_error("Abnormal status!");
return false;
}
-
- // process request..
- processPlayerRequest(request, requestSize);
- g_free(request);
-
} while (g_io_channel_get_buffer_condition(iochan) & G_IO_IN);
+ // process request..
+ processPlayerRequest(request, requestSize);
+ g_free(request);
+
return true;
-
}
bool
nsPluginInstance::processPlayerRequest(gchar* buf, gsize linelen)
{
+ // gnash::log_debug(__PRETTY_FUNCTION__);
+
+ // log_debug("SCRIPT OBJECT %d: %x", __LINE__, this->getScriptObject());
if ( linelen < 4 ) {
if (buf) {
@@ -725,6 +743,10 @@
ExternalInterface::invoke_t *invoke = ExternalInterface::parseInvoke(buf);
+ if (!invoke->name.empty()) {
+ gnash::log_debug("Requested method is: %s", invoke->name);
+ }
+
// The invoke message is also used for getURL. In this case there are 4
// possible arguments.
if (invoke) {
@@ -786,7 +808,43 @@
NPN_GetURL(_instance, jsurl.str().c_str(), tgt);
return true;
- }
+ } else if (invoke->name == "addMethod") {
+ // Make this flash function accessible to Javascript. The
+ // actual callback lives in libcore/movie_root, but it
+ // needs to be on the list of supported remote methods so
+ // it can be called by Javascript.
+ std::string method = NPStringToString(NPVARIANT_TO_STRING(
+ invoke->args[0].get()));
+ NPIdentifier id = NPN_GetStringIdentifier(method.c_str());
+ // log_debug("SCRIPT OBJECT addMethod: %x, %s", (void
*)_scriptObject, method);
+ this->getScriptObject()->AddMethod(id, remoteCallback);
+ return true;
+ }
+ NPVariant *result = 0;
+ // This is the player invoking a method in Javascript
+ uint32_t count = 0;
+ NPVariant args;
+ if (!invoke->name.empty()) {
+ NPIdentifier id = NPN_GetStringIdentifier(invoke->name.c_str());
+ gnash::log_debug("Invoking JavaScript method %s", invoke->name);
+ NPN_Invoke(_instance, _scriptObject, id, &args, count, result);
+ }
+ // We got a result from invoking the Javascript method
+ std::stringstream ss;
+ if (result) {
+ NPN_ReleaseVariantValue(result);
+ ss << ExternalInterface::convertNPVariant(result);
+ } else {
+ // Send response
+ // FIXME: "securityError" also possible, check domain
+ ss << ExternalInterface::makeString("Error");
+ }
+ size_t ret = _scriptObject->writePlayer(ss.str());
+ if (ret != ss.str().size()) {
+ log_error("Couldn't write the response to Gnash, network
problems.");
+ return false;
+ }
+ return true;
} else {
gnash::log_error("Unknown player request: " + std::string(buf));
return false;
=== modified file 'plugin/npapi/plugin.h'
--- a/plugin/npapi/plugin.h 2010-05-08 21:33:27 +0000
+++ b/plugin/npapi/plugin.h 2010-06-18 15:48:04 +0000
@@ -83,11 +83,11 @@
/// Can the stream be written to yet ?
int32_t WriteReady(NPStream *stream);
int32_t Write(NPStream *stream, int32_t offset, int32_t len, void *buffer);
-#ifdef ENABLE_SCRIPTABLE
NPObject *getScriptableObject();
const char *getEmbedURL() const;
-#endif
-
+
+ GnashPluginScriptObject *getScriptObject() { return _scriptObject; }; //
FIXME: debug only!!!
+
private:
void startProc();
std::vector<std::string> getCmdLine(int hostfd, int controlfd);
@@ -129,9 +129,7 @@
/// Name of the plugin instance element in the dom
std::string _name;
-//#ifdef ENABLE_SCRIPTABLE
GnashPluginScriptObject *_scriptObject;
-//#endif
std::string getCurrentPageURL() const;
};
@@ -142,7 +140,6 @@
// 0: no messages at all
// 1: fatal errors (errors preventing the plugin from working as it should)
// 2: informational messages
-//
#define GNASH_PLUGIN_DEBUG 1
// This following logging code is copied from libbase/log.h, but
=== modified file 'plugin/npapi/pluginScriptObject.cpp'
--- a/plugin/npapi/pluginScriptObject.cpp 2010-06-12 01:10:28 +0000
+++ b/plugin/npapi/pluginScriptObject.cpp 2010-06-17 21:16:54 +0000
@@ -157,7 +157,7 @@
void
GnashPluginScriptObject::initializeIdentifiers()
{
-// log_debug("initializeIdentifiers");
+ // log_debug("initializeIdentifiers");
// NPN_Status(_nppinstance, __FUNCTION__);
@@ -275,6 +275,8 @@
id = NPN_GetStringIdentifier("TotalFrames");
AddMethod(id, TotalFrames);
+ // id = NPN_GetStringIdentifier("TestASMethod");
+ // AddMethod(id, remoteCallback);
};
// Constructor
@@ -282,6 +284,7 @@
: _nppinstance (0)
{
// log_debug(__PRETTY_FUNCTION__);
+
initializeIdentifiers();
_sockfds[READFD] = 0;
@@ -293,6 +296,7 @@
: _nppinstance (npp)
{
// log_debug(__PRETTY_FUNCTION__);
+
initializeIdentifiers();
_sockfds[READFD] = 0;
@@ -373,11 +377,9 @@
const NPVariant *args, uint32_t
argCount,
NPVariant *result)
{
- // log_debug(__PRETTY_FUNCTION__);
-
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
- return gpso->Invoke(name, args, argCount, result);
+ return gpso->Invoke(npobj, name, args, argCount, result);
}
bool
@@ -386,8 +388,6 @@
uint32_t argCount,
NPVariant *result)
{
- // log_debug(__PRETTY_FUNCTION__);
-
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
return gpso->InvokeDefault(args, argCount, result);
@@ -396,8 +396,6 @@
bool
GnashPluginScriptObject::marshalHasProperty (NPObject *npobj, NPIdentifier
name)
{
-// log_debug(__PRETTY_FUNCTION__);
-
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
return gpso->HasProperty(name);
@@ -407,8 +405,6 @@
GnashPluginScriptObject::marshalGetProperty (NPObject *npobj, NPIdentifier
name,
NPVariant *result)
{
-// log_debug(__PRETTY_FUNCTION__);
-
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
return gpso->GetProperty(name, result);
@@ -418,8 +414,6 @@
GnashPluginScriptObject::marshalSetProperty (NPObject *npobj, NPIdentifier
name,
const NPVariant *value)
{
-// log_debug(__PRETTY_FUNCTION__);
-
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
return gpso->SetProperty(name, *value);
}
@@ -427,8 +421,6 @@
bool
GnashPluginScriptObject::marshalRemoveProperty (NPObject *npobj, NPIdentifier
name)
{
-// log_debug(__PRETTY_FUNCTION__);
-
GnashPluginScriptObject *gpso = (GnashPluginScriptObject *)npobj;
return gpso->RemoveProperty(name);
}
@@ -460,8 +452,6 @@
bool
GnashPluginScriptObject::HasProperty(NPIdentifier name)
{
-// log_debug(__PRETTY_FUNCTION__);
-
#if 0
log_debug("Checking for Property \"");
if (NPN_IdentifierIsString(name)) {
@@ -477,8 +467,6 @@
bool
GnashPluginScriptObject::GetProperty(NPIdentifier name, NPVariant *result)
{
- // log_debug(__PRETTY_FUNCTION__);
-
if (NPN_IdentifierIsString(name)) {
log_debug("Getting Property %s\"...", NPN_UTF8FromIdentifier(name));
} else {
@@ -500,8 +488,6 @@
bool
GnashPluginScriptObject::SetProperty(NPIdentifier name, const NPVariant& value)
{
- // log_debug(__PRETTY_FUNCTION__);
-
_properties[name] = value;
return false;
@@ -510,8 +496,6 @@
bool
GnashPluginScriptObject::RemoveProperty(NPIdentifier name)
{
- // log_debug(__PRETTY_FUNCTION__);
-
std::map<NPIdentifier, GnashNPVariant>::iterator it;
it = _properties.find(name);
if (it != _properties.end()) {
@@ -542,8 +526,6 @@
bool
GnashPluginScriptObject::HasMethod(NPIdentifier name)
{
-// log_debug(__PRETTY_FUNCTION__);
-
#if 0
log_debug("Checking for Method \"");
if (NPN_IdentifierIsString(name)) {
@@ -557,27 +539,35 @@
}
bool
-GnashPluginScriptObject::Invoke(NPIdentifier name, const NPVariant *args,
uint32_t argCount, NPVariant *result)
+GnashPluginScriptObject::Invoke(NPObject */* npobj */, NPIdentifier name,
+ const NPVariant *args, uint32_t argCount,
+ NPVariant *result)
{
// log_debug(__PRETTY_FUNCTION__);
-#if 0
- log_debug("Invoking Method \"");
+
+#if 1
if (NPN_IdentifierIsString(name)) {
- log_debug("%s\"...", NPN_UTF8FromIdentifier(name));
+ log_debug("Invoking Method \"%s\"...", NPN_UTF8FromIdentifier(name));
} else {
- log_debug("%d\"...", NPN_IntFromIdentifier(name));
+ log_debug("Invoking Method: \"%d\"...", NPN_IntFromIdentifier(name));
}
+ // log_debug("SCRIPT OBJECT invoke %s: %x", NPN_UTF8FromIdentifier(name),
+ // (void *)npobj);
#endif
std::map<NPIdentifier, NPInvokeFunctionPtr>::iterator it;
it = _methods.find(name);
if (it != _methods.end()) {
- // log_debug(" FOUND");
+ // log_debug("FOUND Method \"%s\"!", NPN_UTF8FromIdentifier(name));
NPInvokeFunctionPtr func = it->second;
return func(NULL, name, args, argCount, result);
+ } else {
+ log_error("Couldn't find Method \"%s\"", NPN_UTF8FromIdentifier(name));
}
return false;
+
+// return NPN_Invoke(_nppinstance, this, name, args, argCount, result);
}
bool
@@ -603,11 +593,10 @@
// log_debug(__PRETTY_FUNCTION__);
#if 0
- log_debug("Adding Method \"");
if (NPN_IdentifierIsString(name)) {
- log_debug("%s\"...", NPN_UTF8FromIdentifier(name));
+ log_debug("Adding Method \"%s\"...", NPN_UTF8FromIdentifier(name));
} else {
- log_debug("%d\"...", NPN_IntFromIdentifier(name));
+ log_debug("Adding Method \"%d\"...", NPN_IntFromIdentifier(name));
}
#endif
@@ -622,7 +611,6 @@
GnashPluginScriptObject::SetVariable(const std::string &name,
const NPVariant& value)
{
- log_debug(__PRETTY_FUNCTION__);
std::vector<std::string> iargs;
std::string str = ExternalInterface::makeString(name);
iargs.push_back(str);
@@ -630,6 +618,8 @@
iargs.push_back(str);
str = ExternalInterface::makeInvoke("SetVariable", iargs);
+ log_debug("Trying to set a value for %s.", name);
+
// Write the message to the Control FD.
size_t ret = writePlayer(str);
// Unless we wrote the same amount of data as the message contained,
@@ -648,8 +638,6 @@
GnashNPVariant
GnashPluginScriptObject::GetVariable(const std::string &name)
{
- log_debug(__PRETTY_FUNCTION__);
-
std::vector<std::string> iargs;
std::string str = ExternalInterface::makeString(name);
iargs.push_back(str);
@@ -780,7 +768,7 @@
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
struct timeval tval;
- tval.tv_sec = 10;
+ tval.tv_sec = 2;
tval.tv_usec = 0;
// log_debug("Waiting for data... ");
if (select(fd+1, &fdset, NULL, NULL, &tval)) {
@@ -791,7 +779,6 @@
ioctlSocket(fd, FIONREAD, &bytes);
#endif
}
-
// No data yet
if (bytes == 0) {
@@ -811,8 +798,6 @@
buf.resize(ret);
}
- std::cout << buf << std::endl;
-
return buf;
}
@@ -827,7 +812,7 @@
// Send a Quit message to the player before closing the pipe.
std::vector<std::string> args;
std::string str = ExternalInterface::makeInvoke("Quit", args);
- size_t ret = writePlayer(fd, str);
+ writePlayer(fd, str);
::shutdown(fd, SHUT_RDWR);
::close(fd);
=== modified file 'plugin/npapi/pluginScriptObject.h'
--- a/plugin/npapi/pluginScriptObject.h 2010-06-01 03:10:58 +0000
+++ b/plugin/npapi/pluginScriptObject.h 2010-06-17 20:35:31 +0000
@@ -131,8 +131,10 @@
bool checkPipe(int fd);
int getReadFD() { return _sockfds[READFD]; };
+ GIOChannel *getReadChannel() { return _iochan[READFD]; };
int getWriteFD() { return _sockfds[WRITEFD]; };
-
+ GIOChannel *getWriteChannel() { return _iochan[WRITEFD]; };
+
// Write to the standalone player over the control socket
int writePlayer(const std::string &data);
int writePlayer(int fd, const std::string &data);
@@ -141,19 +143,21 @@
std::string readPlayer();
std::string readPlayer(int fd);
-protected:
+ bool Invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args,
+ uint32_t argCount, NPVariant *result);
bool AddMethod(NPIdentifier name, NPInvokeFunctionPtr func);
void AddProperty(const std::string &name, const std::string &str);
void AddProperty(const std::string &name, double num);
void AddProperty(const std::string &name, int num);
+protected:
// Internal functions for the API
void Deallocate();
void Invalidate();
bool HasMethod(NPIdentifier name);
- bool Invoke(NPIdentifier name, const NPVariant *args, uint32_t argCount,
NPVariant *result);
- bool InvokeDefault(const NPVariant *args, uint32_t argCount, NPVariant
*result);
+ bool InvokeDefault(const NPVariant *args, uint32_t argCount,
+ NPVariant *result);
bool HasProperty(NPIdentifier name);
bool GetProperty(NPIdentifier name, NPVariant *result);
bool SetProperty(NPIdentifier name, const NPVariant& value);
@@ -161,7 +165,7 @@
bool Enumerate(NPIdentifier **identifier, uint32_t *count);
bool Construct(const NPVariant *data, uint32_t argCount, NPVariant
*result);
- bool handleInvoke(GIOChannel* iochan, GIOCondition cond);
+ bool handleInvoke(GIOChannel *iochan, GIOCondition cond);
/// Process a null-terminated request line
//
=== modified file 'plugin/npapi/scriptable-test.html'
--- a/plugin/npapi/scriptable-test.html 2010-06-01 04:15:48 +0000
+++ b/plugin/npapi/scriptable-test.html 2010-06-17 20:35:31 +0000
@@ -35,11 +35,41 @@
</div>
<div id="content">
- <embed type="application/x-shockwave-flash" width="1" height="1"
hidden="true">
+<!--
+ This next test is a bit hokey, we should really trim down
+ the ExternalInterface test to one that's focused on this
+ web page. But for now, this gives us a resident player that we
+ can bounce XML messages off of.
+
+ To make this work for you, copy testsuite/Dejagnu.swf and
+ testsuite/actionsctiona.all/EsternalInterfce-v8.swf from your build
+ tree to your source tree in plugin/npapi/. You can then attach GDB
+ to the PID of gnash running, letting you debug the processing of
+ XML messages to and from the browser. For this to work the swf
+ files must be in the same directory as the html file.
+
+<param name="allowScriptAccess" value="sameDomain" />
+-->
+<div>
+<object>
+<param name="movie" value="ExternalInterface-v8.swf"
+<param name="allowScriptAccess" value="always" />
+<embed
+src="ExternalInterface-v8.swf"
+quality="high" wmode="transparent" width="640" height="100"
+ type="application/x-shockwave-flash"
+ pluginspage="http://www.getgnash.org">
+</embed>
+</div>
+
+<!--
+ <embed type="application/x-shockwave-flash" width="1" height="1"
hidden="true">
+-->
<ul id="test-actions">
<li><button onclick='ShowVersion()'>Show Version</button></li>
- <li><button onclick='ShowFoobar("barfood")'>Show Foobar</button></li>
+ <li><button onclick='TestJSMethod("foodbar")'>TestJSMethod</button></li>
+ <li><button
onclick='TestASMethodJS("barfood")'>TestASMethodJS</button></li>
<li><button onclick='FlashSetVariable("var1",
"value1")'>SetVariable</button></li>
<li><button onclick='FlashGetVariable("var1")'>GetVariable</button></li>
<li><button onclick='FlashGotoFrame(123)'>GotoFrame</button></li>
@@ -53,7 +83,7 @@
<li><button onclick='FlashStopPlay()'>StopPlay</button></li>
<li><button onclick='FlashZoom(12)'>Zoom</button></li>
<li><button onclick='FlashTotalFrames()'>TotalFrames</button></li>
- <li><button onclick='FlashTestEIMethod()'>TestEIMethod</button></li>
+ <li><button
onclick='FlashTestASMethod("barby")'>FlashTestASMethod</button></li>
</ul>
</div>
@@ -227,48 +257,39 @@
addLog(value);
}
- function FlashTestEIMethod()
+ // This gets call a javascript method
+ function TestJSMethod(msg)
+ {
+ addLog("executed TestJSMethod");
+ }
+
+ function FlashTestASMethod(msg)
{
- var value = embed.TestEIMethod();
- // addLog("TestEIMethod() = " + value);
+ addLog("flashTestASMethod(): enter " + msg);
+ var value = embed.TestASMethod(msg);
addLog(value);
+ embed.SetVariable("variable1", 1.1);
+ addLog("flashTestASMethod(): return");
}
- function ShowFoobar(msg)
+ // This calls a method in gnash
+ function TestASMethodJS(msg)
{
- addLog(embed.SetVariable("foo", "bar"));
- addLog(embed.SetVariable("fuby", 1.1));
- addLog(embed.GetVariable("foo"));
- if (typeof embed.showFoobar === 'function') {
- addLog('Running embed.showFoobar("'+msg+'")');
- addLog(embed.showFoobar(msg));
- } else {
- addLog("Quitting: embed.showFoobar is not a function. Tried
running embed.showFoobar('"+msg+"')");
- }
+ addLog("TestASMethod(): enter " + msg);
+ var value = embed.TestASMethod(msg);
+ addLog(value);
+ embed.SetVariable("variable2", 1.1);
+// if (typeof embed.TestASMethod === 'function') {
+// addLog('Running embed.TestASMethod("'+msg+'")');
+// addLog(embed.TestASMethod(msg));
+// } else {
+// addLog("Quitting: embed.TestASMethod is not a function.");
+// }
+// addLog(embed.GetVariable("$version"));
+ addLog("TestASMethod(): return ");
}
</script>
-<!--
- This next test is a bit hokey, we should really trim down
- the ExternalInterface test sae to e one that's focused on this
- web page. ut for now, this gives us a resident player that we
- can bounce XML messages off of.
-
- To make this work for you, copy testsuite/Dejagnu.swf and
- testsuite/actionsctiona.all/EsternalInterfce-v8.swf from your build
- tree to your source tree in plugin/npapi/. You can then attach GDB
- to the PID of gnash running, letting you debug the processing of
- XML messages to and from the browser.
--->
-<object>
-<param name="movie" value="ExternalInterface-v8.swf"
-<embed
-src="ExternalInterface-v8.swf"
-quality="high" wmode="transparent" width="320" height="240"
- type="application/x-shockwave-flash"
- pluginspage="http://www.getgnash.org">
-</embed>
-
<!--
This causes this page to do an immediate redirect, but at least then
we know this is working.
@@ -283,6 +304,13 @@
</embed>
-->
+<!--
+<a href="javascript:;" onclick="window.open('geturl.swf',
+ '_selfXX',
+ 'width=100,height=100,location=yes,resizable=yes');
+ return false">GetURL test</a>
+-->
+
</body>
</html>
=== modified file 'testsuite/actionscript.all/ExternalInterface.as'
--- a/testsuite/actionscript.all/ExternalInterface.as 2010-06-03 15:07:12
+0000
+++ b/testsuite/actionscript.all/ExternalInterface.as 2010-06-15 16:36:37
+0000
@@ -22,6 +22,8 @@
#include "dejagnu.as"
+flash.system.Security.allowDomain("localhost");
+
ASSetPropFlags (_global, "flash", 0, 5248);
#if OUTPUT_VERSION < 6
@@ -59,34 +61,38 @@
fail("ExternalInterface::available() doesn't exist");
}
-// this should always be true now that Gnash supports this class,
-// and sameDomain is the default when running standalone.
-if (EI.available == false) {
- pass("ExternalInterface::available is correct");
-} else {
- fail("ExternalInterface::available property isn't correct");
-}
-
// Create a test function for the callback
-function TestEIMethod () {
- note("TestEIMethod called!");
+function TestASMethod () {
+ note("TestASMethod called!");
}
-if (EI.addCallback("TestEIMethod", null, TestEIMethod) == false) {
- pass("ExternalInterface::addCallback(\"TestEIMethod\")");
-} else {
- fail("ExternalInterface::addCallback(\"TestEIMethod\")");
-}
+// ExternalInterface::available is always false when run standalone,
+// and true if running under a browser and has allowable access to the
+// resource. So we can't have a test case for this property that works
+// both standalone and online Instead we do depend on it being correct
+// as the ExternalInterface::call() tests require this test case to
+// be run under a browser.
// ::call() calls JavaScript functions in the browser, not in flash,
// so we can't test it when running standalone. So this will always
-// return null.
-var foo = EI.call("TestEIMethod", null);
+// return null unless run from a browser
-if (EI.call("TestEIMethod", null) == null) {
- pass("ExternalInterface::call(\"TestEIMethod\")");
+// This adds a callback that the brower can call from Javascript. This is
+// a bit of a bogus test case, as addCallback() doesn't return anything, but
+// we need to add a method anyway to test being called by Javascript.
+if (EI.addCallback("TestASMethod", null, TestASMethod) == false) {
+ pass("ExternalInterface::addCallback(\"TestASMethod\")");
} else {
- fail("ExternalInterface::call(\"TestEIMethod\")");
+ fail("ExternalInterface::addCallback(\"TestASMethod\")");
+}
+
+if (EI.available == true) {
+ // This test tries to invoke a Javascript method running in the browser
+ if (EI.call("TestJSMethod", "test") == null) {
+ pass("ExternalInterface::call(\"TestJSMethod\") == null");
+ } else {
+ fail("ExternalInterface::call(\"TestJSMethod\") == null");
+ }
}
// The default is false, so if we can set it to true, it worked
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r12259: migrate from branch. Error handling now works, and remote functions are now accessible to Javascript,
Rob Savoye <=