2

I'm working on an update to my "jump-to-anchor" add-on which is a Firefox add-on to let you right-click somewhere in a doc to (hopefully) get the closest anchor above the click point.

After submitting the add-on, I realized I could improve the algorithm by finding the actual text node where clicked, and look up from there (instead of the first children of the current clicked element). However, in my tests (against a page I happened to be reading, https://www.rfc-editor.org/rfc/rfc5323#section-2.3.2 ), the text node grabbed via document.caretPositionFromPoint is higher than expected.

var x = 0, y = 0;
window.addEventListener('click', function (e) {
    if (e.button === 2) { // Avoid grabbing for the actual selection // Doesn't seem to execute on the final context menu click anyways
        x = e.pageX;
        y = e.pageY;
    }
});
self.on('click', function () { // , data
    // I added the next two lines just in case the user clicked off screen
    x = x > window.mozInnerScreenX ? window.mozInnerScreenX : (x < 0 ? 0 : x);
    y = y > window.mozInnerScreenY ? window.mozInnerScreenY : (y < 0 ? 0 : y);
    var caretPosition = document.caretPositionFromPoint(x, y);
    var node = caretPosition.offsetNode;

    // Doesn't grab the right node.nodeValue here always--seems to grab too high up

    // (Then search the node for an anchor, or recursively check the deepest child of the previous element sibling on up and keep looking for previous element siblings.)
});

Sound like a bug?

UPDATE:

Steps to reproduce:

  1. Install the XPI from https://github.com/brettz9/jump-to-anchor/tree/document.caretPositionFromPoint (or use cfx xpi with SDK to install from source)
  2. Go to https://www.rfc-editor.org/rfc/rfc5323#section-2.3.2
  3. Try right-clicking within section 2.3.3 (note: 2.3.3) and see it often go all the way up to the "#page-10" anchor instead of the "#section-2.3.3" anchor.

(In the current code at Github, I have the e.button === 2 check commented out, but the result is the same.)

Community
  • 1
  • 1
Brett Zamir
  • 14,034
  • 6
  • 54
  • 77
  • Do you have a reproducible example, i.e. full source code to your add-on and full, detailed steps-to-reproduce? – nmaier Jun 25 '14 at 08:29
  • Thank you for the reply. I've edited the post to add the link to the full source and I hope detailed enough instructions. – Brett Zamir Jun 25 '14 at 09:43

1 Answers1

2

Turns out that the documentation on MDN is outright wrong. .caretPositionFromPoint expects that you pass coordinates relative to the current viewport.

So you'll have to use e.clientX/e.clientY!

Also, .mozInnerScreenX/Y doesn't do what you might expect it to do. Use window.innerWidth/.innerHeight if you want to check that x and y are valid coordinates within the viewport.

So here is what I tried and what seems to have worked (excerpt):

var x = 0, y = 0;
window.addEventListener('click', function (e) {
        x = e.clientX;
        y = e.clientY;
});
self.on('click', function () { // , data
    x = Math.max(0, Math.min(innerWidth, x));
    y = Math.max(0, Math.min(innerHeight, y));
    var caretPosition = document.caretPositionFromPoint(x, y);
    var node = caretPosition.offsetNode;
    // ...
});
nmaier
  • 32,336
  • 5
  • 63
  • 78
  • Working great, thanks... Unfortunately, I have a new puzzling issue in that the first click on page load doesn't get a click event activated...Ah well, that can be another issue... :) – Brett Zamir Jun 25 '14 at 11:38
  • FTR, the issue is http://stackoverflow.com/questions/24410200/getting-mouse-coordinates-in-sdk-first-time-right-click – Brett Zamir Jul 03 '14 at 00:21
  • For some reason I am gettind `document.caretPositionFromPoint` is not a function with `document.caretPositionFromPoint(mouseX, mouseY)` - why is that? :/ – Stefan Falk Mar 24 '16 at 17:34
  • @StefanFalk That's because `document.caretPositionFromPoint` is not available on every browser. On Safari, you need to use the alternate `document.caretRangeFromPoint`. – Jonny Dec 15 '18 at 14:53