Javascript with COM object - javascript

I am writing an automation script using AHK and have already gone through their forums and live chat to no avail.
My issue is that I am using a COM object to navigate and click things on a webpage. But the navigation menu on the webpage does not change url's when going to another part of the website. Instead they use a "main controller" so the url in the address bar never changes but the webpage does.
I do not have access to the source code but from the element inspector in the web browser I know the name of the javascript function and the arguments it calls to go to the page I want.
I am wondering if there is a way, through the com object or other method, to call the javascript function even though I do not have direct access to the source code?
Thanks for any input.

Yes, of course there is. Just have your script access the address bar and past in the script. E.g.:
javascript:alert("Hello World");
And note, some browsers may strip out the first part and give you back a search result, so you may have to have AHK, after typing/pasting in the command, go back to the beginning and re-type the javascript: part.
Now, whether this works when you call a function up without referencing back to the source, I can't say, but then again, you could have given more details in your post.

Related

How to extract user-visible HTML from a TWebBrowser that's generated by javascript

I'm using Delphi's TWebBrowser component to load up some web pages that I want to parse, and they use javascript (AJAX?) to render the user-visible HTML code. The well-documented methods of extracting the HTML from such pages returns a bunch of javascript rather than what the user sees. There are responses to queries here that go back to 2004 and they all return javascript rather than the user-visible HTML. I've seen a couple that suggest alternate ways to access the data, but I have not been able to get any of them to work, nor am I sure how to adapt the code.
My question is, when I load a web page into a TWebBrowser that's perfectly readable after being rendered inside of the TWebBrowser component, how can I extract the HTML that's ultimately rendered inside of that component that makes it visible, rather than the JS code that generates it?
In my case, I'm trying to load a Google Search Result page, but I've heard this is also an issue in lots of news sites like Wall Street Journal, WAPO, and NYTimes.
var
url: string;
d: OleVariant;
begin
// enter something like "dentist in baltimore" in a Google search,
// then copy the contents of the ADDRESS field that it generates and
// paste it here:
url := '... paste URL Google generates here ...';
WebBrowser1.Navigate2( url, 0 {nav_flags} );
// I have an OnNavigate2 handler here, but I'm guessing this works as well
d := WebBrowser1.Document;
memo1.Lines.Text := d.documentElement.outerHTML;
The problem is, the memo contains ... and it's just a bunch of javascript in the HEAD. There's nothing there that resembles what's visible in the TWebBrowser or browser window that this search actually displays to the user.
Someone in another forum suggested it's a timing issue, and to replace the OnNavigationComplete2 that I'm using with OnDocumentComplete. I've actually never seen or heard of OnDocumentComplete, nor have I seen it used in any examples. Certainly none that have been simplified to show everything inline so there are no timing issues that can occur.
But it turns out that this was the crux of the problem in this case, not outerHTML: you need to call an event that's triggered after all of the javascript has finished running, and I believed that the OnNavigationComplete2 did that. My bad.

Using AJAX only for whole website,optimal or not

I am having a template structure in which there is a single HTML file inside which related HTML & JS files are loaded (using AJAX).
Section are loaded as per User's activity(Page never reloads which kind of is good for user experience).
i.e.
User clicks a menu say "Profile",which causes:
jQuery.load method is used to load a file "/some/path/profile.html".
jQuery.getScript is used in .load() callback to include js files like "some/path/profile.js",The profile js has event handlers for the profile page along with related business logic.
This happens for each menu item/section of the application like "Profile","Files","Dashboard" etc.
It works fast but I am not sure if this is the optimal way to carry this out.
If a User consequently clicks the "Profile" button twice,would the browser
clear up the earlier loaded resources(profile.html,profile.js) first before
loading it afresh?
When user visit a new section say "Dashboard" after visiting "Profile",would
browser again clear out the resources of Profile before loading for
Dashboard?
If not than could this cause some memory related issues with the browser?I searched about this but did not see any related scenarios.
P.S: In this structure often some HTML part is stored in a JS variable to be used further. I read somewhere in SO that it is a bad practice to do so but I was not able to find details regarding it. I assume it should not be a -ve point if the developer is well versed & storing HTML in a JS variable should not be any problem.
Here's my understanding on this:
You have to make sure that you don't send request if clicking on same button at your end.
(Forgot about we are dealing with scripts/HTMl) No caching in the picture
Clearing out resources?, yes it will be removed from DOM if appened in same section. But i guess it's necessary if same placeholder is used for each section content.
If you know that everytime each section will return same template again, you can create a local cache at client side just like memoization to see if template already exists.
Hope this helps.

Use Site Property in eSpace Javascript

I included Google Analytics (javascript) in my Outsystems website via de eSpace Javascript. Now I want to place the Analytics Key in my Site Properties so I can update it easily for every environment.
How can I use a Site Property in my Javascript?
You can create a site property to store the Tracking ID.
site Property screenshot
Second, you need to create a webblock with an unescaped expression, and add your javascript this way:
weblock expression screenshot
Finally, you just need to drag you weblock to each webpage you want to track.
cheers,
Vera
As far as I know, you cannot use Site Properties in the eSpace JavaScript window. For that, you have to use an escaped expression on a web screen or web block to add your JavaScript code along with the use of Site Properties.
Since you want the same script on all the web screens, I suggest that you add this expression in the Footer web block, so that it will be automatically added to all the web screens you create.
I can understand your use case. If I read it correctly, you're trying to use some JavaScript in one espace, that would be run in every page load, something like an
onLoad(function(){
// your Google Analytics code, but using the value from the site property
})
And in this way, you would be able to update the site property without the need to republish all consumers. Seems like a nice approach :)
On way to be able to achieve this, would be to have your JavaScript to request the key on the fly to the server side, and maybe cache it.
This can be easier or harder depending on the Platform version you're running... But here's a simple way to achieve it.
Add the site property to the espace. Build a page that has no layout, and in the preparation, add a download widget that only downloads the value of your site property. In the same espace, in the espace JavaScript, add an AJAX request to the page I was referring to before, and when you get the response back, start your Google Analytics code.
To be able to use this in every other espace, and in every page, you still need to reference something from the Google Analytics espace though, so that espace JavaScript is run in every page
Hope it helps :)

Calling javascript href from mojolicious

I've been given permission to scrape a website to build up a database of products. When a button is pressed, a javascript function is called and then altered information is presented to the user (change in colour, price etc..). When trying to scrape the website, I want to be able to predict the changes as if the button was pressed. The element in question is:
<a id="anId" title="title" class="class" data-code="code" href="javascript:aFunction('ctl00$MainContent$ctl00$ctl00$FabricGroups$ctl00$FabricOptions$ctl00$FabricButton','')"></a>
Within mojolicious (I imagine the userAgent class?), how do I print the output of what calling the javascript function would do? Is it possible?
It certainly isn't easy. Perl does not interpret javascript (at least not usually and almost certainly not with a DOM).
That said, I have been working on a project to help this, WHICH IS DEFINITELY NOT READY FOR PRODUCTION, which tests javascript actions by spawning an instance of PhantomJS. Once complete the api intends to be as easy to use as Test::Mojo already is. I will be presenting it at YAPC::NA later in the year (2015).
Update: The module is now on CPAN, called Test::Mojo::Role::Phantom.

Can you determine if a javascript function exist on an aspx page from code behind?

Seems like an easy thing, but no quite so apparently.
I have a look up page that does a complicated search of a database (first name, last_name ...) that is used as a common look up across an application. It run through a colorbox popup and then callsback to a generic js function on the calling page to set the result on the calling page as well as close the popup.
The problem is this requires alot of setup on the calling page, including writing the callback function that sets the values. (I can't modify the lookup page, have to work with it as is)
I've pulled the layout into a user control and now want to push the callback function to the page ONLY if another copy of the function doesn't already exist. This is the question. In my ascx code behind, how can I look to see if the page already contains the js function I"m looking for so that I don't duplicate that function?
Hopefully that's clear as mud. I've been googling this for a while and haven't found anything other than how to use js to determine if a js function exist (not what I need). Any help would be appreciated.
Use the RegisterClientScriptBlock method to add the script to the page:
Page.ClientScript.RegisterClientScriptBock(Page.GetType(), "callback", theScript, true);
The script will only be added to the page as long as there isn't one already added with the same type and name.

Categories