How to Intercept Clicked Links in Webview

A friend and I are attempting to create an Applescript Studio version of a vanilla applescript application we developed which encodes and decodes input text using the RSA algorithm. The goal of the Applescript Studio version is to produce a more user-fiendly and professional “front-end” to all of the Unix stuff going on in the background. In addition, we are attempting to use a web-based message inbox for every user of our program. This on-line inbox will list for every received message the unencoded sender, date, and subject in a table–with the subject column as a link to the full, encoded message.

The problematic issue is working with the links in the inbox. I have managed to force Webview to launch our URL, however I have no idea how to track the user’s URL location as they navigate their inbox. What I have in mind ideally is for Applescript Studio to catch and report whenever the user opens a link, which would then be followed by:

set theMessageURL to the result as text
do shell script "curl " & theMessageURL & "> tempmessage.txt"

The program would then cat and decode the message the user selected using script I have already written for the vanilla applescript.

Below is the script already in place, which was derived in full from a post on these forums by a certain member whose name I did not jot down but to whom I owe much. Thanks to whomever it was, and my apologies for the incomplete citation.

on awake from nib theObject
	global webView
	if theObject's name is "browser" then
		set webView to theObject
		call method "stringByEvaluatingJavaScriptFromString:" of webView with parameter "location.href='http://www.serveraddress.com/'"
	end if
end awake from nib

I think, based on lots of research on this topic, that I need to use some sort of “setPolicyDelegate,” however I have no idea how to implement such a method.

As for my abilities, I know some applescript, as well as Unix very well, however my Objective-C is not very good.

Many thanks for any help anyone can offer!

Model: MacBook Pro 15’’
AppleScript: 1.10.7
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

Thanks to anyone who read my post, however I figured out how to do this. I did it by making a hidden text field in Interface Builder and binding it as so:
“Value”
“Bind to:WebView”
“Model Key Path:mainFrameURL”

options:
“Continuously Updates Value”

Then a simple

set theURL to the contents of textfield "hiddentextfield" of window "main"

gets me the information I need. Hope this helps someone, and again, thanks for reading.

I thought my solution above was the answer, however I’m only able to acquire the address of the first page webview loads. I’m thinking at the moment that applescript doesn’t recognize contents generated through binding, so any “on changed theObject” handlers don’t quite work like I would expect. So, anyone, help would be greatly appreciated. Basically all I need is for Webview to set the address of any URL clicked on to a variable Applescript can handle. Thanks for reading!

This is my first post on this forum. Thanks to everyone for all solutions i found here so far.
I’m having a problem that looks like the above.
A webviewer is displaying a page that contains a download link to a file. This link does not work, it needs the downloadDelegate stuff i guess, which i don’t understand (yet).
I got as far as binding a text field to the clicked URL, but the “on changed” method does not detect that the contents of this field changes.

zapzapzap:

Well, i could check that variable on idle, but surely there must be a better way to do such a download.
Anyone know how to help?

I solved my problem some time ago, but I don’t quite know if this will help you. This is not my code at all, I believe it is John’s which I somehow managed to get working with my zero knowledge of Objective C. The code can get a page’s source, its title, or its URL with small, clear changes to the call method line. If this doesn’t work or my directions are too vague, I’m more than happy to write better instructions tomorrow. Nonetheless, I’m sure that there is a more efficient way to do this, but this method works very well. Good luck.

This is called in an idle handler in my application, allowing me continual access to the currently displayed web address in the webview, stored in the variable “current_page_url.” The Applescript to get it working, in a webview named “webView,” is:

set current_page_url to (call method "getWebStringURL:" of class "Methods" with parameter webView) as text

In Methods.m


#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>

@interface Methods : NSObject
+(NSString *)getWebStringDisplayed:(WebView *)webView;
+(NSString *)getWebStringSource:(WebView *)webView;
+(NSString *)getWebStringTitle:(WebView *)webView;
+(NSString *)getWebStringURL:(WebView *)webView;
@end

@implementation Methods

+(NSString *)getWebStringDisplayed:(WebView *)webView {
NSString *display = [[(id)[[webView mainFrame] frameView] documentView] string];
if (!display) {
return @"";
}
return display;
}

+(NSString *)getWebStringSource:(WebView *)webView {
NSString *source = [(id <WebDocumentRepresentation>)[[[webView mainFrame] dataSource] representation] documentSource];
if (!source) {
return @"";
}
return source;
}

+(NSString *)getWebStringTitle:(WebView *)webView {
NSString *title = [[[webView mainFrame] dataSource] pageTitle];
if (!title) {
return @"";
}
return title;
}

+(NSString *)getWebStringURL:(WebView *)webView {
NSString *url = [[[[[webView mainFrame] dataSource] request] URL] absoluteString];
if (!url) {
return @"";
}
return url;
}

@end

Thanks for your reaction. Using John’s objective C methods is indeed better than checking that bound hidden text field. But it’s still rather cumbersome to handle this on idle, as you have to keep into account that the webviewer object is not always available and that your application is eating CPU time with every check, even when you are not using the webviewer. I think I’ll change the design of my application and skip the fancy webviewer.
A simple “On Clicked” handler for a webviewer could have solved the whole issue.