0

I'd like to add an event handler in my C++ code.

I followed document in firebreath.org (Callback from Scripts):

FB::JSObjectPtr doc = m_host->getDOMDocument()->getJSObject();
doc->Invoke("addEventListener", FB::variant_list_of("load", FB::make_callback(this, &mine::foo)));

but seeing following error:

/home/dq/manager/mine.cpp: In member function ‘void mine::init()’:
/home/dq/manager/mine.cpp:284:119: error: no matching function for call to ‘variant_list_of(const char [5], FB::JSAPIPtr)’
/home/dq/manager/mine.cpp:284:119: note: candidates are:
/usr/include/firebreath/ScriptingCore/variant_list.h:122:5: note: FB::detail::VariantListInserter FB::variant_list_of(FB::variant)
/usr/include/firebreath/ScriptingCore/variant_list.h:122:5: note:   candidate expects 1 argument, 2 provided
/usr/include/firebreath/ScriptingCore/variant_list.h:128:5: note: FB::VariantList FB::variant_list_of()
/usr/include/firebreath/ScriptingCore/variant_list.h:128:5: note:   candidate expects 0 arguments, 2 provided
In file included from /home/deqing/manager/mine.h:51:0,
                 from /home/deqing/manager/mine.cpp:37:
/usr/include/firebreath/ScriptingCore/JSCallback.h: In function ‘FB::JSAPIPtr FB::make_callback(const T&, F, bool) [with T = mine*, F = void (mine::*)(), FB::JSAPIPtr = boost::shared_ptr<FB::JSAPI>]’:
/home/dq/manager/mine.cpp:284:118:   instantiated from here
/usr/include/firebreath/ScriptingCore/JSCallback.h:47:107: error: request for member ‘get’ in ‘instance’, which is of    non-class type ‘mine* const’
/usr/include/firebreath/ScriptingCore/JSCallback.h:49:97: error: request for member ‘get’ in ‘instance’, which is of non-class type ‘mine* const’
make[2]: *** [CMakeFiles/mine.dir/manager/mine.cpp.o] Error 1
make[1]: *** [CMakeFiles/mine.dir/all] Error 2
make: *** [all] Error 2

Looking into the implementation of make_callback(), I tried following instead:

FB::JSObjectPtr doc = m_host->getDOMDocument()->getJSObject();
doc->Invoke("addEventListener", FB::variant_list_of("load")(FB::JSAPIPtr(new FB::JSCallback(FB::make_method(this, &mine::foo)))));

Compile passed this time, but my function - mine::foo() is not called with document.load()

By using "Inspect Element" in chrome, in "Event Listeners" I can see a new listener is added for "load". However, the listenerBody is a <JSAPI-Auto Javascript Object>.

I'm afraid this is why mine::foo() is not called, Javascript don't know how to call it because it is not a function, only an object.

Any one know how to get this done?

Another way that I can think of is:

  1. Register a custom event handler
  2. Fire the custom event on init

I'd like to use something like:

registerEventMethod("myevent", &mine::foo);

so that when myevent is fired, mine::foo() can be called.

The question here is, mine::foo is not a JSObjectPtr, so this snippet of code wouldn't work.

What is the proper way to use registerEventMethod() in this case?

Deqing
  • 14,098
  • 15
  • 84
  • 131
  • I have been meaning to figure this out, but haven't yet; however, it is worth knowing that a function *is* an object, and the object you're seeing is probably the correct object. – taxilian Jun 20 '12 at 04:05
  • Thanks @taxilian. I edited my question with another thought, could you shed some light? – Deqing Jun 20 '12 at 08:54

1 Answers1

0

registerEventObject was really never intended to be called manually; it is used by the internal implementations of addEventListener and attachEvent. The purpose is to attach javascript handlers to events in the plugin.

I would recommend you use something like boost's signals and slots to implement your own c++-side event system; FireBreath's stuff was never intended to solve that problem. On the other hand, if you wanted to look at it it would probably be possible to extend FireBreath's functionality to support that and I have it on very good authority that the gatekeeper for FireBreath would probably entertain a pull request to that end. =]

taxilian
  • 14,229
  • 4
  • 34
  • 73
  • Thanks, that make sense. What I'm doing now is to use `registerMethod()` to register a C++ function, and then use `evaluateJavascript()` to call this function. It works this way, the only problem is it has to expose a function to Javascript namespace, which is what I'm not expected. – Deqing Jun 25 '12 at 03:17