views:

388

answers:

1
+1  Q: 

xpath greasemonkey

I am trying to modify gmail in a greasemonkey script. Using xpather i can get the xpath expression for the part i am trying to hide. But using following snippet i can not get a match. alert function is never called. Can anyone point me to what am i doing wrong?

var allLinks, thisLink;
allLinks = document.evaluate(
     "//html/body/div[1]/div/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/div[1]/div[1]",
     document,
     null,
     XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
     null);
for (var i = 0; i < allLinks.snapshotLength; i++) {
  thisLink = allLinks.snapshotItem(i);
  alert("found");
}

@Alan Storm

I installed firebug tested the script using console it works but still i can not get it to work under greasemonkey. Greasemonkey still not giving me an alert box. I also tried adding a on load event listener that did not helped either.

+2  A: 

First, a general debugging tip, then a stab at your problem.

Remember that Greasemonkey scripts are just javascript, and you can still use all the Javascript tools avaiable to you to debug your problem. Open up gmail, fire up Firebug, and try running your javascript code directly on the command line (click the upward circle arrow to the right of the console line for a bigger typing area).

When I did the above with your javascript snippet, allLinks.snapshotLength was evaluating to 0, indicating that your xpath expression didn't match anything. This is odd, because when I used XPath Checker, it matched the logo.

Digging in a bit deeper, it looks like gmail's main document is a number of iframes, and the iframes contain the actual application elements. Specifically, there's a frame with an ID of "canvas_frame" which contains the actual DOM for the application interface. When I try

canvas = window.frames[document.getElementById('canvas_frame').name].document;
allLinks = canvas.evaluate(
  "//html/body/div[1]/div/div/div[1]/div/div[3]/div[1]/div[2]/div[2]/div[1]/div[1]",
  canvas,
  null,
  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
  null);

I get a response with a length of 1, which may suit your needs better.

Finally, this isn't required, but your xPath expression looks a little fragile. If gmail changes the document structure even slightly (say, with a wrapper div), your program will break. Consider something like this instead.

<!-- 
all divs on the page that contains an h1 element 
that contains the text "Gmail Logo" 
-->
//div[contains(./h1,"Gmail Logo")]
Alan Storm