Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get actual JavaScript value in onclick from webbrowser control?

I'm looking for a way to get the JavaScript code defined inside of onclick. I'm using .NET 2.0 C# Visual Studio 2005.

Example:

<span id="foo" onclick+"window.location.href='someURL'>click here</span>

My goal is to get the string "window.location.href='someURL'".

Scenario:

A user clicks on web page element, the tag shown above for instance, inside of WebBrowser control. Then the clicked tag is refereed to HtmlElement object.

In WebBrowser control I then call HtmlElement object's getAttribute("onclick"), it just gives me "System.__ComObject".

I've searched how to deal with it then found that it can be casted then get the value.

if (tag.GetAttribute("onclick").Equals("System.__ComObject"))
{
    Console.WriteLine("dom elem  >>>>>>>>>>> " + tag.DomElement.ToString());
    mshtml.HTMLSpanElementClass span = (mshtml.HTMLSpanElementClass)tag.DomElement;

    Console.WriteLine("js value ===>" + span.onclick);
}

Output:

dom elem  >>>>>>>>>>> mshtml.HTMLSpanElementClass
js value ===> System.__ComObject

As it shown, span.onclick still give me System.__ComObject, what am I doing wrong?

In Why does HtmlElement's GetAttribute() method return “mshtml.HTMLInputElementClass” instead of the attribute's value? this guy said it worked in his case, and I've followed it, but mine is somewhat not working...

UPDATE

Research, research.....

I can add reference VisualBasic.dll to my C# project then call the method to find out who is this System.__ComObject really is.

Console.WriteLine(Microsoft.VisualBasic.Information.TypeName(span.onclick));

Output:

JScriptTypeInfo

It looks like this is a JScript type... how can I access this object?

More detail

The above description is based on my current project. The project is to create something like Selenium IDE. It uses WebBrowser control instead.

Selenium IDE creates 3 different things to record an element in the web document.

1. actionType
2. xpath
3. value

For instance,

type, //input[@id=foo], "hello world"
clickAndWait, //link=login, ""

Selenium IDE recognize page load so it changes actionType between "click" and "clickAndWait". My case, I want to make it simple.

If I click on the element and if it is anchor tag or has page load kind of javascript such as onclick=window.location.href='blah' then I want to set the actionType to "clickAndWait".

like image 206
Meow Avatar asked Jun 03 '11 06:06

Meow


2 Answers

There are number of ways you can do it.

  1. There is an Event object in DOM, which will give you information about which element generated this event.
  2. You can look at here, http://msdn.microsoft.com/en-us/library/ff975965%28v=VS.85%29.aspx
  3. This one is good, you can use this easily, you will get the event object as method parameter which you can investigate parameters to find out the source of the event. http://support.microsoft.com/kb/312777

Another alternative is to use a custom navigation url and act upon it

  1. Override BeforeNavigate event
  2. Check for Navigation url if it contains "mycommand:click" or "mycommand:clickandwait" 3. If it contains any of this, then set cancel as true. (this will stop navigation by browser).
  3. Then you can navigate your webbrowser code from your C# code and pass cancel as true.

Another Alternative method is to use External object, WebBrowser allows you to set an ObjectForScripting which you can access within Javascript of HTML.

ObjectForScripting in .NET 2.0

[ComVisible(true)]
public class MyClass
{
   // can be called from JavaScript
   public void ShowMessageBox(string msg){
       MessageBox.Show(msg);
   }
}

myBrowser.ObjectForScripting = new MyClass(); 
// or you can reuse instance of MyClass

And you can call,

window.external.ShowMessageBox("This was called from JavaScript");
like image 103
Akash Kava Avatar answered Sep 19 '22 17:09

Akash Kava


Cast the element object to mshtml.IHTMLDOMNode, then read the attributes via IHTMLDOMNode.attributes. HtmlElement.GetAttribute is getting the IDispatch interface of the jscript function generated from the embedded attribute.

like image 27
Sheng Jiang 蒋晟 Avatar answered Sep 22 '22 17:09

Sheng Jiang 蒋晟