In QtWebkit, how to set callback property from js to QObject? - javascript

I added an object to the JavaScript context with
addToJavaScriptWindowObject(). Works great. Now I wish to specify a
JavaScript callback function to be called from Qt:
function cb()
{
foo = bar;
}
MyObject.cbfun = cb;
I know it's easy to call the JavaScript function "cb" with evaluateJavaScript(), but that requires a prior knowledge of the callback function name -- this is not what I need
In my Qt object (MyObject) I see the QVariant Q_PROPERTY cbfun is
actually a QVariantMap. How can I call JavaScript function reverenced by
cbfun from my Qt object?

Related

node.js Nan: call JavaScript callback in C++ function

I’m building a node-module wrapper for a C++ library to pass logging information through Nan to JavaScript. For this a NAN_Method is available to register a callback. The callback handler has to register itself as a callback at the C++ library via vlAddLogListener(). The LoggingCallbackHandler receives a message from the library at the function dispatchEvent, a C++ function. If I receive a log, I want to call the JavaScript callback to pass the data on.
The function dispatchEvent isn’t called in a Nan-context and therefore I don’t have a scope/context and no access to v8. How is it possible to call the JavaScript callback?
The code looks like this:
NAN_METHOD(registerLoggingCallback)
{
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Function> fun = info[0].As<v8::Function>();
lch = new LoggingCallbackHandler(isolate, fun);
}
LoggingCallbackHandler::LoggingCallbackHandler(v8::Isolate* isolate, v8::Local<v8::Function> fun) :
_cb(isolate, fun)
{
vlAddLogListener(&LoggingCallbackHandler::dispatchEvent, this);
}
void VL_CALLINGCONVENTION LoggingCallbackHandler::dispatchEvent(const char* eventData, void* clientData)
{
// here I want to process the data and call the JavaScript callback
v8::Local<v8::Function> f = v8::Local<v8::Function>::New(Nan::GetCurrentContext()->Global()->GetIsolate(), _cb);
Nan::MakeCallback(Nan::GetCurrentContext()->Global(), f, argc, argv);
}
Using Nan, you should save the function value using a Nan::Callback inside your registerLoggingCallback function :
Nan::Callback cb;
cb.Reset(info[0].As<v8::Function>());
Store this Nan::Callback inside your class. Modify your dispatchEvent function to use a uv_async_t to schedule a call to your callback to be run in the main thread.
The use of uv_async_t can be simplified using a Nan::AsyncWorker but you may be better off reading the documentation for a better understanding of how that works.
When you actually want to call the callback, you can do:
v8::Local<v8::Value> arg = Nan::Null();
cb.Call(1, &arg);
You can pass more values into the callback by passing an array of v8::Local<v8::Value> as the second parameter and increasing the first parameter accordingly.

Passing parameters to callback function without changing method (Siesta Testing namespace)

Does anyone know how to pass parameters to a callback function that you cannot alter?
So here is the code I'm trying to implement (It is a siesta testing method):
Base.js:
waitForComponentQueryVisible: function (parentNext, parameters) {
var th = this,
query = parameters.query,
scope = th,
callback = callFunct,
timeout = 10000;
//The function inside here (returnToParentTester(parentNext, parameters)) is from Base.js
callFunct = function () {
scope.returnToParentTester(parentNext);
}
this.test.waitForComponentQueryVisible(query, callback, scope, timeout);
},
The problem here is of two parts:
1. I cant get the scope just right so I can use the returnToParentTester method that is found in Base.js
2. I want to pass in parentNext into the method but cannot do that when defining it as a callback
this is the method I need to run as the callback:
Base.js:
returnToParentTester: function (parentNext, parameters) {
debugger;
if (parentNext) {
parentNext.call(undefined, parameters);
} else {
this.test.fail('--Developer Error-- undefined parentNext ' +
'variable. All the chains are going to fail');
}
},
I can't get the scope just right so I can use the returnToParentTester method that is found in Base.js
Use the call method to change the scope:
Base.returnToParentTester.call(myScope)
I want to pass in parentNext into the method but cannot do that when defining it as a callback
Use an anonymous function as a callback and pass parameters within its scope:
$("body").click(function(e){foo(e.target,bar,baz)})
then let it do the work:
function foo(myScope, next1, param1)
{
Base.returnToParentTester.call(myScope, next1, param1)
}
References
Fast JavaScript max/min
Mixins and Constructor Functions
Function.prototype.apply revisited
applyFunctionArguments - argument injection technique in JavaScript
Functional JavaScript, Part 3: .apply(), .call(), and the arguments object

Can a parameter be passed to a function that is set as an object literal value?

I have a function, functionWithDifferentScope, that takes an object, myobject.options, as a parameter. One of the pairs in the options object is a callback which points to a function defined in myObject: myCallback.
What I'm trying to achieve is injection of the myObject namespace into the callback of a function that is defined (by a 3rd party) at the global level.
A simplified example:
var myObject = {
options: {
callback: this.myCallback(this),
...,
},
init: function() {
// functionWithDifferentScope operates in the 'window' context
functionWithDifferentScope(this.options);
},
myCallback: function(namespace) {
// 'this' is window
// 'namespace' is myObject
}
}
myObject.init();
When executing this script, this.myCallback(this) appears to be executed at definition (due to the parenthesis?); as well as once myObject.init(); is caled. During the first executions this is myObject, but subsequent calls through the functionWithDifferentScope identify this as window.
Is there a way to pass the myObject namespace to the myObject.options.callback value as a parameter?
Do you mean this?
var myObject = new (function() {
var t = this;
vac callback = function() {
// t equals to the myObject-instance
// this equals to window
}
this.init = function() {
funcWithDifferencScope(callback);
}
})();
myObject.init();
I think what you are looking for is prototype style "bind"
Basically "this.myCallback(this)" is a call to the function.
this.myCallback is the function itself. (It is an object with the type function).
You can call it using the method 'call' or 'apply' that you can use on functions. Which will call these functions.
See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FFunction%2Fapply
The first argument is the object context to work in. What I think you mean by object namespace.
so: a.callback(5) is the same as a.callback.call(a,5)
However please note that these days if you are working with most javascript libraries you probably have a 'bind' function that will do the work for you.
http://prototypejs.org/doc/latest/language/Function/prototype/bind/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
the idea is that this.callback.bind(this) returns a Function object you can call that will inject the correct context automatically so you can pass the return value of bind alone as a callback and be assured that the method will be executed on the correct object.

Why is this function being called?

I am trying to modify some behavior of a framework's JavaScript. In IE10's developer tools under the View source drop down, there is a folder called Dynamic Scripts. (Maybe someone could explain what Dynamic Scripts are?) And there is the following code under Function code (1089)
This is the code:
function anonymous() {
var f=arguments.callee; return f._func.apply(f._owner, arguments);
}
And the first entry of the call stack is
Function code, Function code (1089), line 2
This line gets executed several times. But I don't know why.
Who calls this line?
The anonymous function call does not mean a function called anonymous. It is actually a name that is used to classify unnamed functions, like this one:
var anUnnamedFunc = function() {
return true;
};
If you referenced this function in a watch or console output, it would be dumped as an anonymous function. To define a function that isn't anonymous, you would use:
var aNamedFunc = function namedFunction() {
return true;
};
The function being called in question, looks a lot like a bind function. That is a wrapper function used to create a function that binds arguments and or context to another function. However, this version uses some sort of private property mechanism to bind arguments:
var bind = function() {
var f = arguments.callee;
return f._func.apply(f._owner, arguments);
};
I actually don't see what this sort of function would be used for, so wonder if it is just an anomaly of the IE debugger. Try using a different browser and see if that function appears in the profile report.

Function context in JavaScript

I want to achieve something similar to this:
A function someFunction has a method .lockThis(<object>) and when first called:
var foreverThis = {};
someFunction.lockThis(foreverThis);
// ... or
// someFunction = someFunction.lockThis(foreverThis);
It will bind this function to the <object> so that the next (or any other) time this function is executed via as-function or as-method call, or via apply/call - it will have initially given <object> as this.
I can, of course, define Function.prototype.lockThis which will call the function via .apply()/call() and specify given object as a context, but then it will still be possible to substitute context of someFunction if someone calls it via apply() as well.
Is there a way to lock function context in JavaScript in a way that it will always have provided object as this without changing the code of the function itself?
That's called bind():
someFunction = someFunction.bind(foreverThis);

Categories