I've come up with a workaround using JSON to exchange data between the DS app space and the webview space.
The method is to have this XProcess object (code below) in a script that is loaded by both the app and WebView space.
Each process declares an instance of the object as a global variable, allowing each to Execute() the object methods.
To get information out of the webview, your app calls the Request() method of the webview's XProcess instance. Request() uses Execute() to send structured json data to the webview instance's Receive() method.
The webview's instance calls eval(), then sends the stringified result back to the app's XProcess instance.
So, you can send a string expression via the Request() merhod and have the result via a single function call, e.g.: fs = myXProcess.Request('document.body.style.fontSize');
Declare the method as a variable and for brevity you can use something like: fs = xpReq('document.body.style.fontSize');
I'm fairly new to JS coding, so some of this may seem clumsy or kludgy, and I'm sure there're issues I've overlooked. In particular, the FetchResult() method is a bit concerning in the way it polls for the result in a loop, 'though I haven't struck any problems with it as yet.
function XProcess(hst,nam){
var self=this;
this.reqID=0;
this.Name=undefined;
this.host=undefined;
this.hostName=undefined;
this.results=[];
this.FetchResult=function(rID){
var wait = true;
var tmout = 0;
while (wait) {
for (var i=0; i<self.results.length; i++)
if (self.results[i].reqID == rID) {
var x = self.results[i].result;
self.results.splice( i, 1 );
return x;
wait = false;
}
tmout++;
if (tmout > 99) wait = false;
else app.Wait( 0.01 );
}
return null;
}
this.Receive=function(s){
var obj = JSON.parse(s);
obj.result = eval( obj.request );
var s = JSON.stringify(obj);
app.Execute( obj.clientName + ".SubmitResult(\""
+ s.escString() + "\");" );
}
this.Request=function(r){
var obj={};
obj.clientName=self.Name;
obj.request=r;
obj.result=undefined;
self.reqID++;
obj.reqID = self.reqID;
var s=JSON.stringify(obj);
self.host.Execute( self.hostName + ".Receive(\""
+ s.escString() + "\");" );
return self.FetchResult(obj.reqID);
}
this.SubmitResult=function(r){
var obj = JSON.parse(r);
self.results.push(obj);
}
}
Note that the request string is escaped, so in the above I'm using:
String.prototype.escString=function() {
var s = this.replace(/\\/g, "\\\\");
s = s.replace(/"/g, '\\"');
return s;
}
Declare the instance in the DS app like so:
//Called when application is started.
function OnStart() {
// . . . create components, do stuff . . .
myXProcess = new XProcess();
myXProcess.Name = "myXProcess"; // Sent to the host's instance so that it can call your instance
myXProcess.host = web; // webview object on which to call Execute()
myXProcess.hostName = "wvXProcess"; // The name of the global declared in webview
xpReq = myXProcess.Request; // For convenience, rather than use myXProcess.Request()
// . . . do other stuff . . .
}
Declaration in the webview's OnLoad script thus:
wvXProcess=new XProcess();
wvXProcess.Name="wvXProcess";
And you're basically in business.
Hope this is of interest to someone or maybe even helpful, any comments welcome.
Cheers!