WebView goBack: breaks custom JavaScript objects - javascript

I have a Cocoa app with an embedded WebView. I've set up my delegate to respond to a number of custom Objective-C functions that can be called from JavaScript. For example, in JavaScript I will be able to call something like console.log()
I set the delegate as follows:
- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowObject forFrame:(WebFrame *)frame {
[self.webView.windowScriptObject setValue:self forKey:#"console"];
}
Now when I navigate to another page and then use the back button (via WebView goBack:), the above method is not called and I can't set the console object.
However, the JavaScript object still exists (typeof(console) returns object), but calling any function on it does not have any effect.
First of all, does anybody know why didClearWindowObject: is not called when I invoke goBack:? Any suggestions how I can debug the JavaScript object?

Related

cordova - "x-ms-webview" access dom elements to perform login

Is there any chance to access the dom elements of a "x-ms-webview" ? For my cordova application, I want to use a custom login page. That's why I need to load a webview in the background, access the login fields and "click" the submit button via javascript.
For iOS and the UIWebview this working (I could not believe) really smooth and nice. Is there any chance to realize this for windows 10 as well ? This is what I have so far (not really much):
function onWebviewLoadedLoginPage(ev) {
webview.removeEventListener("MSWebViewDOMContentLoaded", onWebviewLoadedPage);
// --> Here I need to access the dom elements of the loaded webview !?
}
var webview = document.createElement("x-ms-webview");
document.body.appendChild(webview);
webview.addEventListener("MSWebViewDOMContentLoaded", onWebviewLoadedPage);
webview.navigate(url);
In objective-c I can set the login credentials directly to the dom elements quite easy:
NSString* statement = [NSString stringWithFormat:#"document.getElementById('%#').value = '%#'", self->usernameInputFieldId, self->username];
[webView stringByEvaluatingJavaScriptFromString:statement];
Thanks in advance !!!
I can see that you need to execute javascript inside the webview once the content is loaded. In that case, you can use invokeScriptAsync method of the webview element. invokeScriptAsyc accepts two parameters a function's name and that function's parameters. However, It can only call a javascript function that is written inside the webview. However, eval() is used to execute javascript code that is written in form of string. Hence to execute your javascript code your function should be:
function onWebviewLoadedLoginPage(ev) {
webview.removeEventListener("MSWebViewDOMContentLoaded", onWebviewLoadedPage);
// --> Here I need to access the dom elements of the loaded webview !?
var javascriptcode = "document.getElementByID('#myelement')"; // Your javascript code in the form of string
var injectedJavascript = webview.invokeScriptAsync('eval', javascriptcode);
injectedJavascript.start();
}

Basic JQuery syntax: What mechnaic is at work in this small (2 line) piece of JavaScript / JQuery

So here' s the piece of code. I'm very new to JavaScript so don't be afraid to explain the obvious
$(".my-css-class").on("click", function() {
($(this).attr("data-property-1"), $(this).attr("data-property-2"), this);
});
There's an element in the .jsp page that looks like this:
<i class="clickMe"></i>
I know the .jsp creates a link-icon, and that the above JavaScript is an event handler. I know that it passes these 3 values as arguments another JavaScript method:
function doStuff(prop1, prop2, obj) {
if (prop1 == 'foo') {
//do stuff with prop2
}
else{
// do stuff with obj
}
}
It all works fine. What I want to know is what exactly is going on to make it work? I can't find anything in the code that connects what the event-handler returns to the 'doStuff' java-script function.
The names are totally different, so it's not reflection, it can't be parameter matching because there's other functions with the same number and type of parameters in the file, it can't be convention based because it still works if I find/replace the name of the function to gibberish.
I guess basically I'm asking what this line is doing:
($(this).attr("data-property-1"), $(this).attr("data-property-2"), this);
tl;dr: I'm at a loss, I know how the properties get as far as the onClick event-handler's anonymous function - but how does JavaScript know to pass them as arguments the to the doStuff() function?
the onClick event is a standard event triggered on click of any clickable html element and is automatically raised by the DOM.
You are hooking in to this by listening on any matched ".my-css-class" elements for an onClick Event.
The jquery syntax ".on" has been simplified over time and allows you to hook into any number of events like "submit" - OnSubmit event , or "load" - onLoad Event
Wherever your on("click", myFunction) event hook is picked up, your myFunction will execute.
Looking at your second point...
because it still works if I find/replace the name of the function to gibberish.
The DoStuff function will be found and replaced across all files in your site? or page? or open tabs? , so therefore it must exist somewhere as "doStuff(" or "giberish(".
so when you do a global find/replace, do each one slowly, until you locate it.
Finally, when you do a view source in the browser, this should either explicitly show you the doStuff function, or at the very least give you a clue as to satelite files loaded at runtime, where you can go and investigate.
Use firebug in firefox to debug loaded resources; the ".net tab" to view external loaded resources and the html/javascript they might contain. (for example: your master page might be loading in an embeded resource that contains the doStuff method, becuase of a user or server control reference in that master page)
Also have a look at this:
http://www.developerfusion.com/article/139949/debugging-javascript-with-firebug/
You can step through the javascipt piece by peice until it hits the doStuff method.
Just remember to set at least 1 breakpoint ;-)

Cannot Call a Flash Function from Javascript

I've been all over here and can't find an answer. I have a .swf sitting in an HTML page and I am trying to call a function inside of it from javascript. I can talk out from flash to the javascript but I can't get it to talk back in. I know I am targeting the object properly because I use console.log() on it and confirms what it is targeting.
I'm triggering the test from flash, calling a javascript function from inside the .swf, and having that function call the internal Flash function.
Flash Code:
//adds callback
ExternalInterface.addCallback("sendToFlash", flashTalkedTo);
//function called by the callback
public function flashTalkedTo():void{
//runs another function in javascript to log a string
ExternalInterface.call("callMe")
}
//calls javascript that tries to talk to Flash
ExternalInterface.call("catchFromFlash")
Javascript Code:
//function called by Flash that initiates
function catchFromFlash(){
talkToFlash()
}
//function that tries to talk to flash
function talkToFlash(){
document.getElementById('Noodleverse').sendToFlash()
}
//function called by Flash in the end to confirm call made
function callMe(){
console.log("Call Me")
}
Any help works, thanks!
Flash, and plugins in general, are a little bit fiddly. They don't behave quite like normal elements, and their functions don't behave quite like normal functions. For example, you can't save the element into a value and call a function from that. You also need to be careful because in some browsers the object is used and in others the embed is used.
The best way to call a function is to use swfobject (https://code.google.com/p/swfobject/) to abstract everything. Personally though, I use this (based on experience, maybe somebody can offer improvements):
HTML:
<object id="myplugin" ...>
...
<embed name="myplugin" ... />
</object>
JavaScript:
var o1=document.myplugin;
if(o1&&!!o1.myFlashFunction){
return document.myplugin.myFlashFunction(); // DO NOT USE o1 here. It will fail.
}
var o2=window.myplugin;
if(o2&&!!o2.myFlashFunction){
return window.myplugin.myFlashFunction(); // DO NOT USE o2 here
}
The first case (document) is for most new browsers. For example, Chrome will find the embed object. The second (window) is for IE and finds the object (IE, at least old IE, ignores embed). I'm not 100% sure the second is needed, because IE might also work with document, so call that voodoo code. Also window.myplugin will give an array of all matching elements in Chrome, FireFox, etc. (but we expect those to already be taken care of)

How do i add a Javascript object for a User control in ASP.Net

I have a User control and i have a method isDirty() added to this user control.
This user control is used in many places.
How do i access this method using javascript .How do i create a javascript object for this particular user control and then access it with the find method ?
The $find('__The id of the user control ') ?
I tried get null .???
Thanks & Regards,
Francis
js object is created like this:
var myobject = { prop1: 'hello',
prop2: function(){//whatever},
prop3:'yay'};
myobject.prop1; //'hello'
myobject.prop2(); //that's right, it runs that function(){//whatever} in prop2
You cannot access any server side methods with JS directly. Make an AJAX request with a JSON object, parse it in ASP.NET, and in ASP.NET, call your function you want based on what it says in the object.
Flash can use ExternalInterface.addCallback to do a direct JS access but I am not sure ASP.NET has such a thing (and I would strongly recommend against using a "Flash's blackbox JS access" style anyway).
If you already added a JS object to your user control somehow server side by executing javascript, you just access it like this:
myUserControlAssociatedJSObject.myFunction(); //it runs it!

AS3 - ExternalInterface.addCallback, Access of undefined property

I am trying to use javascript to run AS3 functions. When I attempt to compile I'm getting an "Access of undefined property" error message.
I've read a few things online about this but I'm still not understanding it. I want to have the flash file always listening for javascript.
Here is my AS3 code:
ExternalInterface.addCallback("song4", PauseMusicExt);
And my Javascript & HTML:
function returnVar3(song3) { return this[song3]; }
<input type="submit" name="playButton" id="playButton" value="Submit" onClick="returnVar('song3')"/>
Edit: Here is the pauseMusic function:
function pauseMusicExt():void
{
songPosition = channel.position;
channelSilence.stop();
channel.stop();
channel2.stop();
btnPlay.mouseEnabled = true;
}
I'm not sure about the extend of your app but you've got your addCallback function parameters mixed up..
See the doc, the first parameter is the name you want to expose the function as to javascript, the second is the actual internal AS3 function you want to trigger.
So the declaration should likely be something like:
ExternalInterface.addCallback("song4", pauseMusic);
(assuming that your function in the same scope as where you call addCallback)
That statement will create a "song4" method that you can call on your flash dom object
var fl = document.getElementById('myflashobject');
fl.song4()
After there's the issue that pauseMusic want a parameter (looks like you've made it a mouse event handler). You probably want to have a clean method that doesn't require a parameter like an internal as3 event param. Rewrite pauseMusic so it doesn't require it (you might need to create another method to handle the mouse event internally - like onPause(evt:MouseEvent), which then calls pauseMusic.
Edit: I don't know if a lot of people thought about doing that, but you can also totally use external interface to call firebug's console.log function to send messages to Firebug from flash (it's really helpful for debugging ExternalInterface issues, or any other flash problems - see the ExternalInterface.call function)
Hope u want to pause the audio player.
AS code :
ExternalInterface.addCallback("sndToAS",rcvdFmJS);
function rcvdFmJS(val){
if (val == "pause"){
audioPause();
}
}
JS code :
document.getElementById("movie").sndToAS("pause");

Categories