You can do what you are describing using Safari's "do JavaScript" command,
but...
1. Your scripts are going to be highly customized (which means that if the web pages you have automated ever change, they will break)
2. You will need to know JavaScript
3. You will need to know Safari's DOM (Document Object Model)
4. You'll have to use some workarounds to get around some limitations in Safari's AppleScript model
I'm going to show you how to use the Do JavaScript command to do an Advanced Search in Google which will ask for search terms and a site to limit the search to, and then perform the search, all by manipulating the DOM on the Advanced Search page. (Probably not terribly effectively -- usually when I write JavaScript, I'm aiming for compatibility, not efficiency, so I may not be making use of shortcuts in Safari's DOM.)
First off: there is no easy way to tell when a page has finished loading. This is because of the way Safari's AppleScript references work. (The things you manipulate to load pages are "Document" objects, but references to Documents change when the URL loaded in the document changes, which means that when you create a new document and then load something, the reference breaks.)
In order to make a new window and keep track of it (for real), the following structure works:
tell application "Safari"
set x to make new document
repeat with y in the windows
if the document of y is x then
set x to the id of y
exit repeat
end if
end repeat
end tell
This will leave the id of the window in the variable x. Since the id does not change over time, that's what you want. Next, you need to load a page and wait for it to finish loading. (If you don't wait, then your scripts won't work.) Unfortunately, Safari has no direct AppleScript access to figure out when a page has finished loading. On the other hand, you can't get the source of a document until it has finished loading, so that makes a reasonable surrogate. (Note, however, that some pages which make heavy use of JavaScript may break this!) Using the variable x from the script above, you can use the following:
tell application "Safari"
set the URL of the document of window id x to "http://www.google.com/advanced_search?hl=en"
set still_loading to true
repeat while still_loading
try
if ((the source of document of window id x) is not "") then
set still_loading to false
else
delay 1
end if
on error
delay 1
end try
end repeat
end tell
This starts the loading process, by setting the URL of the document, and then repeatedly tries to see if the source of the document has a value. At the moment, the comparison to an empty string causes an error while the document is loading. This should not happen, so we catch the error just in case, but also handle it properly in the event Apple fixes this behavior in the future. Either way, as long as we can't get the source, we wait a second before checking again to avoid eating up all the processor time.
When the loop is done, the page has loaded, and it's time to play with it's content. Now, unfortunately for us, Google did not give any of their stuff IDs. When using JavaScript, it's easy to control a form that uses IDs: just use
( document.getElementById( 'theID' ) ).value = desiredValue;
Google decided not to use IDs. Instead they just used names. (Probably makes sense, given that names are required for forms to work and Google has to serve the same pages over and over -- by leaving IDs out, they save a few bytes on each page, and probably several GB over time. But it means we have to loop through every single piece of the form, looking for the part that has the name we want.)
Here's the final part of the AppleScript, which just stuffs a JavaScript into a string and then executes it:
set the_script to "var the_query = window.prompt('What should we search for?', 'Document Object Model');
var the_domain = window.prompt('What site should be searched?', 'developer.apple.com');
var f = (document.forms['f']).elements;
var n = f.length;
var index_number;
for (index_number = 0; index_number < n; i++)
{
if ((f[index_number].name) == 'as_q')
{
f[index_number].value = the_query;
}
if (f[index_number].name == 'as_sitesearch')
{
f[index_number].value = the_domain;
}
}
document.forms['f'].submit();"
tell application "Safari"
activate
do JavaScript the_script in (document of window id x)
end tell
Note that JavaScript can use either '' or "" to indicate a string, while AppleScript uses "". To avoid having to escape quotation marks, use '' inside the script.
(Also note that if you want to get a value from AppleScript into JavaScript, quotation marks are not the only problem. In JavaScript, \n is a new line, etc. For this reason, if you want the user to type something in, it's probably easier to use "window.prompt" inside the JavaScript section; I deliberately gave you two examples of this.)
I don't really know if there are any books on JavaScript I'd recommend wholeheartedly if you don't know the language already, given your specific needs. Most of them can be summed up with either "you only need to understand Internet Explorer for Windows so we won't teach you anything else" or else "we want to use the latest versions of DOM everywhere as well as show off showy stuff, so we're going to write massively long browser-detection scripts near the beginning of this book, and then waste a lot of pages talking about how to work around the massive incompatibilities between the ways different browsers implement their more advanced features". You just want to learn Safari, and even now most books barely mention it. I'd say to just experiment a lot, and search the web for examples. And if there an example gives alternate methods for Windows IE and Netscape/Firefox, the Firefox method is the one you probably want for Safari.
Arrgh! I forgot that the array accessor, [ arrayIndexNumber ] is also the code for italic text if you're using "i" to hold that number. Fixed that by changing the loop variable from "i" to "index_number".