Translate DOM Element In WebView To View Coordinates

I set out to figure out how to translate a DOM element in the WebView to a rectangle on the screen. I wanted to display visual cues when clicking on the web page that highlight the DOM element that was clicked.

After about a week of searching, it turns out the answer is pretty simple. The WebView provides a method called elementAtPoint() which takes an NSPoint as it’s parameter. You simply need to intercept a mouse click event and obtain its locationInWindow and pass that to elementAtPoint which will return you an NSDictionary containing several objects. The object you’re interested in can be obtained by calling objectForKey on the NSDictionary passing it the key @”WebElementDOMNode”. Check to see that the object exists and then you can use it. I simply set the returned object to a DOMNode object which contains within it the magic variable called boundingBox. You now have your rectangle and know exactly where on the view the DOM element you clicked is being displayed. Here is some code to demonstrate:

// Inside your mouse click event handler
NSPoint point = [theEvent locationInWindow];
NSDictionary *dict = [webView elementAtPoint:point];
DOMNode *node = [dict objectForKey:@"WebElementDOMNode"];

// Make sure the node is not nil
if( node )
	NSRect rect = [node boundingBox];
	int left = rect.origin.x;
	int top = rect.origin.y;
	int width = rect.size.width;
	int height = rect.size.height;

	// Do something with the coordinates
	// ...

At that point you can do what you would like. I want to draw an overlay rectangle to highlight the DOM element on the screen, but from what I understand, drawing over the WebView may be a bit of a challenge. I’ve experimented with just adding another div with absolute positioning to the DOMDocument to act as my rectangle overlay, but I’ve had some issues with it. I’ll keep you posted here on my progress.

Also, you should probably know that in order to intercept a mouse click when you have a WebView in your window, you’ll have to subclass NSWindow and override - (void)sendEvent:(NSEvent *)theEvent and filter for left mouse clicks. Let me know if you need a further explanation.

Leave a Reply